From bc271f92ce14d8e80fdc4a49ce67283cc34cb834 Mon Sep 17 00:00:00 2001
From: Alex Sharov <AskAlexSharov@gmail.com>
Date: Sat, 19 Jun 2021 15:21:53 +0700
Subject: [PATCH] To break dependency to db implementation - move all db
 classes to "ethdb/kv" and leave in "ethdb" only interfaces (#2195)

---
 accounts/abi/bind/backends/simulated.go       |   5 +-
 accounts/abi/bind/backends/simulated_test.go  |   3 +-
 cmd/cons/commands/root.go                     |   3 +-
 cmd/evm/internal/t8ntool/execution.go         |   3 +-
 cmd/evm/runner.go                             |   4 +-
 cmd/evm/staterunner.go                        |   4 +-
 cmd/hack/db/lmdb.go                           |  11 +-
 cmd/hack/hack.go                              |  67 ++++-----
 cmd/integration/commands/refetence_db.go      |  15 ++-
 cmd/integration/commands/root.go              |   9 +-
 cmd/integration/commands/snapshot_check.go    |   9 +-
 cmd/integration/commands/state_stages.go      |   3 +-
 cmd/pics/state.go                             |   3 +-
 cmd/rpcdaemon/cli/config.go                   |   5 +-
 .../commands/get_chain_config_test.go         |   4 +-
 cmd/rpctest/rpctest/account_range_verify.go   |   9 +-
 cmd/rpctest/rpctest/fixState.go               |   3 +-
 cmd/rpctest/rpctest/proofs.go                 |   3 +-
 cmd/sentry/download/sentry_test.go            |   5 +-
 cmd/snapshots/debug/debug_test.go             |   9 +-
 .../generator/commands/copy_from_state.go     |   5 +-
 .../commands/generate_body_snapshot.go        |   5 +-
 .../commands/generate_header_snapshot.go      |   6 +-
 .../commands/generate_state_snapshot.go       |   5 +-
 .../commands/verify_state_snapshot.go         |   7 +-
 cmd/snapshots/tracker/commands/root.go        |   3 +-
 cmd/snapshots/utils/utils.go                  |   5 +-
 cmd/state/commands/check_change_sets.go       |   7 +-
 cmd/state/commands/opcode_tracer.go           |   3 +-
 cmd/state/generate/regenerate_tx_lookup.go    |   3 +-
 cmd/state/stats/index_stats.go                |   4 +-
 cmd/state/verify/check_changeset_enc.go       |   4 +-
 cmd/state/verify/check_indexes.go             |   4 +-
 cmd/state/verify/verify_headers_snapshot.go   |   3 +-
 cmd/state/verify/verify_txlookup.go           |   4 +-
 cmd/utils/flags.go                            |   3 +-
 common/changeset/storage_changeset_test.go    |   7 +-
 common/etl/etl_test.go                        |  17 +--
 consensus/clique/clique_test.go               |   3 +-
 consensus/clique/snapshot_test.go             |   6 +-
 consensus/db/db.go                            |   3 +-
 core/block_validator_test.go                  |   6 +-
 core/genesis.go                               |   5 +-
 core/rawdb/accessors_chain_test.go            |  18 +--
 core/rawdb/accessors_indexes_test.go          |   3 +-
 core/rlp_test.go                              |   4 +-
 core/state/database_test.go                   |  27 ++--
 core/state/history_test.go                    |  15 ++-
 core/state/intra_block_state_test.go          |   6 +-
 core/state/state_test.go                      |   7 +-
 core/tx_pool.go                               |   3 +-
 core/tx_pool_test.go                          |  34 ++---
 core/vm/gas_table_test.go                     |   4 +-
 core/vm/runtime/runtime.go                    |   6 +-
 core/vm/runtime/runtime_test.go               |   8 +-
 docs/programmers_guide/db_faq.md              |   2 +-
 eth/ethconfig/config.go                       |   1 -
 eth/fetcher/block_fetcher_test.go             |   6 +-
 eth/filters/bench_test.go                     |   7 +-
 eth/filters/filter_test.go                    |   5 +-
 eth/protocols/eth/handler_test.go             |   3 +-
 eth/stagedsync/stage_bodies.go                |   3 +-
 eth/stagedsync/stage_execute.go               |   5 +-
 eth/stagedsync/stage_execute_test.go          |  14 +-
 eth/stagedsync/stage_hashstate_test.go        |  24 ++--
 eth/stagedsync/stage_indexes_test.go          |   5 +-
 eth/stagedsync/stage_interhashes_test.go      |   5 +-
 eth/stagedsync/stage_log_index_test.go        |   4 +-
 eth/stagedsync/stage_mining_create_block.go   |   3 +-
 eth/stagedsync/stage_mining_finish.go         |   3 +-
 eth/stagedsync/stage_senders_test.go          |   4 +-
 eth/stagedsync/stage_tevm.go                  |   5 +-
 eth/stagedsync/state_test.go                  |  21 +--
 eth/stagedsync/testutil.go                    |   3 +-
 eth/stagedsync/unwind_test.go                 |  16 +--
 eth/tracers/tracers_test.go                   |   6 +-
 ethdb/Readme.md                               |   2 +-
 ethdb/{interface.go => db_interface.go}       |   4 +-
 ethdb/{ => kv}/database_test.go               |  13 +-
 ethdb/{ => kv}/kv_abstract_test.go            |  21 +--
 ethdb/{ => kv}/kv_mdbx.go                     | 116 ++++++++--------
 ethdb/{ => kv}/kv_migrator_test.go            |   7 +-
 ethdb/{ => kv}/kv_remote.go                   |  23 ++--
 ethdb/{ => kv}/kv_snapshot.go                 | 127 +++++++++---------
 ethdb/{ => kv}/kv_snapshot_property_test.go   |  34 ++---
 ethdb/{ => kv}/kv_snapshot_test.go            |  21 +--
 ethdb/{ => kv}/memory_database.go             |  10 +-
 ethdb/{ => kv}/mutation.go                    |  48 +++----
 ethdb/{ => kv}/object_db.go                   |  99 +++++++-------
 ethdb/{ => kv}/tx_db.go                       |  79 +++++------
 ethdb/{kv_abstract.go => kv_interface.go}     |  58 ++++----
 ethdb/kv_util.go                              |  20 +--
 ethdb/rewind.go                               |   1 -
 ethdb/storage_mode_test.go                    |  16 ++-
 migrations/header_prefix_test.go              |   3 +-
 migrations/migrations_test.go                 |  13 +-
 node/node.go                                  |  15 ++-
 p2p/enode/nodedb.go                           |  13 +-
 tests/state_test.go                           |   4 +-
 tests/state_test_util.go                      |   3 +-
 tests/statedb_chain_test.go                   |   4 +-
 tests/vm_test.go                              |   4 +-
 tests/vm_test_util.go                         |   3 +-
 turbo/snapshotsync/postprocessing.go          |   5 +-
 turbo/snapshotsync/postprocessing_test.go     |  15 ++-
 turbo/snapshotsync/server.go                  |   3 +-
 turbo/snapshotsync/snapshot_builder.go        |  15 ++-
 turbo/snapshotsync/snapshot_builder_test.go   |   5 +-
 turbo/snapshotsync/wrapdb.go                  |   7 +-
 turbo/stages/blockchain_test.go               |  21 +--
 turbo/stages/bodydownload/body_test.go        |   4 +-
 turbo/stages/chain_makers_test.go             |   4 +-
 turbo/stages/genesis_test.go                  |   3 +-
 .../stages/headerdownload/header_algo_test.go |   4 +-
 turbo/stages/mock_sentry.go                   |   3 +-
 turbo/stages/stageloop.go                     |   3 +-
 turbo/trie/flatdb_sub_trie_loader_test.go     |  17 +--
 turbo/trie/structural_branch_test.go          |   4 +-
 118 files changed, 764 insertions(+), 685 deletions(-)
 rename ethdb/{interface.go => db_interface.go} (97%)
 rename ethdb/{ => kv}/database_test.go (93%)
 rename ethdb/{ => kv}/kv_abstract_test.go (95%)
 rename ethdb/{ => kv}/kv_mdbx.go (91%)
 rename ethdb/{ => kv}/kv_migrator_test.go (92%)
 rename ethdb/{ => kv}/kv_remote.go (96%)
 rename ethdb/{ => kv}/kv_snapshot.go (85%)
 rename ethdb/{ => kv}/kv_snapshot_property_test.go (96%)
 rename ethdb/{ => kv}/kv_snapshot_test.go (97%)
 rename ethdb/{ => kv}/memory_database.go (89%)
 rename ethdb/{ => kv}/mutation.go (87%)
 rename ethdb/{ => kv}/object_db.go (77%)
 rename ethdb/{ => kv}/tx_db.go (79%)
 rename ethdb/{kv_abstract.go => kv_interface.go} (85%)
 delete mode 100644 ethdb/rewind.go

diff --git a/accounts/abi/bind/backends/simulated.go b/accounts/abi/bind/backends/simulated.go
index ea592e785a..8402dff5b9 100644
--- a/accounts/abi/bind/backends/simulated.go
+++ b/accounts/abi/bind/backends/simulated.go
@@ -42,6 +42,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/eth/filters"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/event"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
@@ -103,7 +104,7 @@ func NewSimulatedBackendWithConfig(alloc core.GenesisAlloc, config *params.Chain
 			return h
 		},
 	}
-	backend.checkTEVM = ethdb.GetCheckTEVM(ethdb.NewObjectDatabase(m.DB))
+	backend.checkTEVM = ethdb.GetCheckTEVM(kv.NewObjectDatabase(m.DB))
 	backend.events = filters.NewEventSystem(&filterBackend{m.DB, backend})
 	backend.emptyPendingBlock()
 	return backend
@@ -165,7 +166,7 @@ func (b *SimulatedBackend) emptyPendingBlock() {
 	b.pendingReceipts = chain.Receipts[0]
 	b.pendingHeader = chain.Headers[0]
 	b.gasPool = new(core.GasPool).AddGas(b.pendingHeader.GasLimit)
-	b.pendingReader = state.NewPlainStateReader(ethdb.NewObjectDatabase(b.m.DB))
+	b.pendingReader = state.NewPlainStateReader(kv.NewObjectDatabase(b.m.DB))
 	b.pendingState = state.New(b.pendingReader)
 }
 
diff --git a/accounts/abi/bind/backends/simulated_test.go b/accounts/abi/bind/backends/simulated_test.go
index 82016c4f93..599ca6916d 100644
--- a/accounts/abi/bind/backends/simulated_test.go
+++ b/accounts/abi/bind/backends/simulated_test.go
@@ -29,6 +29,7 @@ import (
 	"github.com/holiman/uint256"
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
 	ethereum "github.com/ledgerwatch/erigon"
 	"github.com/ledgerwatch/erigon/accounts/abi"
@@ -147,7 +148,7 @@ func TestNewSimulatedBackend(t *testing.T) {
 	}); err != nil {
 		t.Fatal(err)
 	}
-	statedb := state.New(state.NewPlainDBState(ethdb.NewRoTxDb(tx), num))
+	statedb := state.New(state.NewPlainDBState(kv.NewRoTxDb(tx), num))
 	bal := statedb.GetBalance(testAddr)
 	if !bal.Eq(expectedBal) {
 		t.Errorf("expected balance for test address not received. expected: %v actual: %v", expectedBal, bal)
diff --git a/cmd/cons/commands/root.go b/cmd/cons/commands/root.go
index 0c547b466c..339d2b616e 100644
--- a/cmd/cons/commands/root.go
+++ b/cmd/cons/commands/root.go
@@ -7,6 +7,7 @@ import (
 	"github.com/ledgerwatch/erigon/cmd/utils"
 	"github.com/ledgerwatch/erigon/common/paths"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/internal/debug"
 	"github.com/spf13/cobra"
 )
@@ -66,7 +67,7 @@ func openDatabase(path string) ethdb.RwKV {
 }
 
 func openKV(path string, exclusive bool) ethdb.RwKV {
-	opts := ethdb.NewMDBX().Path(path)
+	opts := kv.NewMDBX().Path(path)
 	if exclusive {
 		opts = opts.Exclusive()
 	}
diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go
index 0bb5ef12c1..f13038c63c 100644
--- a/cmd/evm/internal/t8ntool/execution.go
+++ b/cmd/evm/internal/t8ntool/execution.go
@@ -31,6 +31,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/rlp"
@@ -106,7 +107,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig,
 		return h
 	}
 	var (
-		db          = ethdb.NewMemDatabase()
+		db          = kv.NewMemDatabase()
 		ibs         = MakePreState(context.Background(), db, pre.Pre)
 		signer      = types.MakeSigner(chainConfig, pre.Env.Number)
 		gaspool     = new(core.GasPool)
diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go
index 7a7a408bd6..d3229bc93a 100644
--- a/cmd/evm/runner.go
+++ b/cmd/evm/runner.go
@@ -30,6 +30,7 @@ import (
 	"time"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/urfave/cli"
 
 	"github.com/ledgerwatch/erigon/cmd/evm/internal/compiler"
@@ -39,7 +40,6 @@ import (
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/core/vm/runtime"
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
 )
@@ -135,7 +135,7 @@ func runCmd(ctx *cli.Context) error {
 	} else {
 		debugLogger = vm.NewStructLogger(logconfig)
 	}
-	db := ethdb.NewMemDatabase()
+	db := kv.NewMemDatabase()
 	if ctx.GlobalString(GenesisFlag.Name) != "" {
 		gen := readGenesis(ctx.GlobalString(GenesisFlag.Name))
 		_, _, err := gen.Commit(db, false)
diff --git a/cmd/evm/staterunner.go b/cmd/evm/staterunner.go
index c51cd5d7d5..ea0866e6c1 100644
--- a/cmd/evm/staterunner.go
+++ b/cmd/evm/staterunner.go
@@ -27,7 +27,7 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/vm"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/tests"
 	"github.com/ledgerwatch/erigon/turbo/trie"
@@ -97,7 +97,7 @@ func stateTestCmd(ctx *cli.Context) error {
 		Debug:  ctx.GlobalBool(DebugFlag.Name) || ctx.GlobalBool(MachineFlag.Name),
 	}
 	results := make([]StatetestResult, 0, len(tests))
-	db := ethdb.NewMemKV()
+	db := kv.NewMemKV()
 	defer db.Close()
 
 	tx, txErr := db.BeginRw(context.Background())
diff --git a/cmd/hack/db/lmdb.go b/cmd/hack/db/lmdb.go
index a7fb8ce5d7..8c4c8c0aca 100644
--- a/cmd/hack/db/lmdb.go
+++ b/cmd/hack/db/lmdb.go
@@ -17,6 +17,7 @@ import (
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/common/debug"
 	"github.com/ledgerwatch/erigon/ethdb"
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 )
 
@@ -337,20 +338,20 @@ func defragSteps(filename string, bucketsCfg dbutils.BucketsCfg, generateFs ...f
 		return fmt.Errorf("creating temp dir for db visualisation: %w", err)
 	}
 	defer os.RemoveAll(dir)
-	var kv ethdb.RwKV
-	kv, err = ethdb.NewMDBX().Path(dir).WithBucketsConfig(func(dbutils.BucketsCfg) dbutils.BucketsCfg {
+	var db ethdb.RwKV
+	db, err = kv2.NewMDBX().Path(dir).WithBucketsConfig(func(dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return bucketsCfg
 	}).Open()
 	if err != nil {
 		return fmt.Errorf("opening database: %w", err)
 	}
-	defer kv.Close()
+	defer db.Close()
 	for gi, generateF := range generateFs {
 		var display bool
-		if err = kv.Update(context.Background(), func(tx ethdb.RwTx) error {
+		if err = db.Update(context.Background(), func(tx ethdb.RwTx) error {
 			var err1 error
 			//nolint:scopelint
-			display, err1 = generateF(kv, tx)
+			display, err1 = generateF(db, tx)
 			return err1
 		}); err != nil {
 			return fmt.Errorf("generating data in temp db - function %d, file: %s: %w", gi, filename, err)
diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go
index 94b2a2c5ab..81cc8f4761 100644
--- a/cmd/hack/hack.go
+++ b/cmd/hack/hack.go
@@ -22,6 +22,7 @@ import (
 
 	"github.com/RoaringBitmap/roaring/roaring64"
 	"github.com/holiman/uint256"
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/wcharczuk/go-chart"
 	"github.com/wcharczuk/go-chart/util"
 
@@ -326,7 +327,7 @@ func accountSavings(db ethdb.RwKV) (int, int) {
 }
 
 func bucketStats(chaindata string) error {
-	ethDb := ethdb.MustOpenKV(chaindata)
+	ethDb := kv2.MustOpenKV(chaindata)
 	defer ethDb.Close()
 
 	var bucketList []string
@@ -344,7 +345,7 @@ func bucketStats(chaindata string) error {
 
 	fmt.Printf(",BranchPageN,LeafPageN,OverflowN,Entries\n")
 	switch kv := ethDb.(type) {
-	case *ethdb.MdbxKV:
+	case *kv2.MdbxKV:
 		type MdbxStat interface {
 			BucketStat(name string) (*mdbx.Stat, error)
 		}
@@ -576,7 +577,7 @@ func trieChart() {
 }
 
 func dbSlice(chaindata string, bucket string, prefix []byte) {
-	db := ethdb.MustOpenKV(chaindata)
+	db := kv2.MustOpenKV(chaindata)
 	defer db.Close()
 	if err := db.View(context.Background(), func(tx ethdb.Tx) error {
 		c, err := tx.Cursor(bucket)
@@ -646,7 +647,7 @@ func printFullNodeRLPs() {
 
 // Searches 1000 blocks from the given one to try to find the one with the given state root hash
 func testBlockHashes(chaindata string, block int, stateRoot common.Hash) {
-	ethDb := ethdb.MustOpen(chaindata)
+	ethDb := kv2.MustOpen(chaindata)
 	defer ethDb.Close()
 	blocksToSearch := 10000000
 	for i := uint64(block); i < uint64(block+blocksToSearch); i++ {
@@ -665,7 +666,7 @@ func testBlockHashes(chaindata string, block int, stateRoot common.Hash) {
 }
 
 func printCurrentBlockNumber(chaindata string) {
-	ethDb := ethdb.MustOpenKV(chaindata)
+	ethDb := kv2.MustOpenKV(chaindata)
 	defer ethDb.Close()
 	ethDb.View(context.Background(), func(tx ethdb.Tx) error {
 		hash := rawdb.ReadHeadBlockHash(tx)
@@ -676,7 +677,7 @@ func printCurrentBlockNumber(chaindata string) {
 }
 
 func printTxHashes() {
-	db := ethdb.MustOpen(paths.DefaultDataDir() + "/geth/chaindata").RwKV()
+	db := kv2.MustOpen(paths.DefaultDataDir() + "/geth/chaindata").RwKV()
 	defer db.Close()
 	if err := db.View(context.Background(), func(tx ethdb.Tx) error {
 		for b := uint64(0); b < uint64(100000); b++ {
@@ -719,7 +720,7 @@ func invTree(wrong, right, diff string, name string) {
 }
 
 func preimage(chaindata string, image common.Hash) {
-	ethDb := ethdb.MustOpen(chaindata)
+	ethDb := kv2.MustOpen(chaindata)
 	defer ethDb.Close()
 	p, err := ethDb.Get(dbutils.PreimagePrefix, image[:])
 	tool.Check(err)
@@ -728,7 +729,7 @@ func preimage(chaindata string, image common.Hash) {
 
 func printBranches(block uint64) {
 	//ethDb := ethdb.MustOpen("/home/akhounov/.ethereum/geth/chaindata")
-	ethDb := ethdb.MustOpen(paths.DefaultDataDir() + "/testnet/geth/chaindata")
+	ethDb := kv2.MustOpen(paths.DefaultDataDir() + "/testnet/geth/chaindata")
 	defer ethDb.Close()
 	fmt.Printf("All headers at the same height %d\n", block)
 	{
@@ -751,7 +752,7 @@ func printBranches(block uint64) {
 }
 
 func readAccount(chaindata string, account common.Address) error {
-	db := ethdb.MustOpenKV(chaindata)
+	db := kv2.MustOpenKV(chaindata)
 	defer db.Close()
 
 	tx, txErr := db.BeginRo(context.Background())
@@ -785,7 +786,7 @@ func readAccount(chaindata string, account common.Address) error {
 }
 
 func nextIncarnation(chaindata string, addrHash common.Hash) {
-	ethDb := ethdb.MustOpen(chaindata)
+	ethDb := kv2.MustOpen(chaindata)
 	defer ethDb.Close()
 	var found bool
 	var incarnationBytes [common.IncarnationLength]byte
@@ -808,9 +809,9 @@ func nextIncarnation(chaindata string, addrHash common.Hash) {
 }
 
 func repairCurrent() {
-	historyDb := ethdb.MustOpen("/Volumes/tb4/erigon/ropsten/geth/chaindata")
+	historyDb := kv2.MustOpen("/Volumes/tb4/erigon/ropsten/geth/chaindata")
 	defer historyDb.Close()
-	currentDb := ethdb.MustOpen("statedb")
+	currentDb := kv2.MustOpen("statedb")
 	defer currentDb.Close()
 	tool.Check(historyDb.ClearBuckets(dbutils.HashedStorageBucket))
 	tool.Check(historyDb.RwKV().Update(context.Background(), func(tx ethdb.RwTx) error {
@@ -843,7 +844,7 @@ func repairCurrent() {
 }
 
 func dumpStorage() {
-	db := ethdb.MustOpen(paths.DefaultDataDir() + "/geth/chaindata")
+	db := kv2.MustOpen(paths.DefaultDataDir() + "/geth/chaindata")
 	defer db.Close()
 	if err := db.RwKV().View(context.Background(), func(tx ethdb.Tx) error {
 		c, err := tx.Cursor(dbutils.StorageHistoryBucket)
@@ -860,7 +861,7 @@ func dumpStorage() {
 }
 
 func printBucket(chaindata string) {
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 	f, err := os.Create("bucket.txt")
 	tool.Check(err)
@@ -885,7 +886,7 @@ func printBucket(chaindata string) {
 }
 
 func ValidateTxLookups2(chaindata string) {
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 	startTime := time.Now()
 	sigs := make(chan os.Signal, 1)
@@ -1016,7 +1017,7 @@ func (r *Receiver) Result() trie.SubTries {
 }
 
 func regenerate(chaindata string) error {
-	db := ethdb.MustOpenKV(chaindata)
+	db := kv2.MustOpenKV(chaindata)
 	defer db.Close()
 	tx, err := db.BeginRw(context.Background())
 	if err != nil {
@@ -1050,7 +1051,7 @@ func testGetProof(chaindata string, address common.Address, rewind int, regen bo
 	storageKeys := []string{}
 	var m runtime.MemStats
 	runtime.ReadMemStats(&m)
-	db := ethdb.MustOpenKV(chaindata)
+	db := kv2.MustOpenKV(chaindata)
 	defer db.Close()
 	tx, err1 := db.BeginRo(context.Background())
 	if err1 != nil {
@@ -1191,7 +1192,7 @@ func testGetProof(chaindata string, address common.Address, rewind int, regen bo
 }
 
 func dumpState(chaindata string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 	f, err := os.Create("statedump")
 	if err != nil {
@@ -1244,7 +1245,7 @@ func dumpState(chaindata string) error {
 }
 
 func changeSetStats(chaindata string, block1, block2 uint64) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 
 	fmt.Printf("State stats\n")
@@ -1311,7 +1312,7 @@ func changeSetStats(chaindata string, block1, block2 uint64) error {
 
 func searchChangeSet(chaindata string, key []byte, block uint64) error {
 	fmt.Printf("Searching changesets\n")
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 	tx, err1 := db.Begin(context.Background(), ethdb.RW)
 	if err1 != nil {
@@ -1332,7 +1333,7 @@ func searchChangeSet(chaindata string, key []byte, block uint64) error {
 
 func searchStorageChangeSet(chaindata string, key []byte, block uint64) error {
 	fmt.Printf("Searching storage changesets\n")
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 	tx, err1 := db.Begin(context.Background(), ethdb.RW)
 	if err1 != nil {
@@ -1353,7 +1354,7 @@ func searchStorageChangeSet(chaindata string, key []byte, block uint64) error {
 
 func supply(chaindata string) error {
 	startTime := time.Now()
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 	count := 0
 	supply := uint256.NewInt(0)
@@ -1388,7 +1389,7 @@ func supply(chaindata string) error {
 }
 
 func extractCode(chaindata string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 	var contractCount int
 	if err1 := db.RwKV().View(context.Background(), func(tx ethdb.Tx) error {
@@ -1413,7 +1414,7 @@ func extractCode(chaindata string) error {
 }
 
 func iterateOverCode(chaindata string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 	var contractCount int
 	var contractKeyTotalLength int
@@ -1463,7 +1464,7 @@ func mint(chaindata string, block uint64) error {
 	defer f.Close()
 	w := bufio.NewWriter(f)
 	defer w.Flush()
-	db := ethdb.MustOpen(chaindata).RwKV()
+	db := kv2.MustOpen(chaindata).RwKV()
 	defer db.Close()
 	tx, err := db.BeginRw(context.Background())
 	if err != nil {
@@ -1547,7 +1548,7 @@ func mint(chaindata string, block uint64) error {
 }
 
 func extractHashes(chaindata string, blockStep uint64, blockTotal uint64, name string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 
 	f, err := os.Create(fmt.Sprintf("preverified_hashes_%s.go", name))
@@ -1584,7 +1585,7 @@ func extractHashes(chaindata string, blockStep uint64, blockTotal uint64, name s
 }
 
 func extractHeaders(chaindata string, blockStep uint64, blockTotal uint64, name string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 
 	f, err := os.Create(fmt.Sprintf("hard_coded_headers_%s.go", name))
@@ -1651,7 +1652,7 @@ func extractHeaders(chaindata string, blockStep uint64, blockTotal uint64, name
 }
 
 func extractBodies(chaindata string, block uint64) error {
-	db := ethdb.MustOpen(chaindata).RwKV()
+	db := kv2.MustOpen(chaindata).RwKV()
 	defer db.Close()
 	tx, err := db.BeginRo(context.Background())
 	if err != nil {
@@ -1678,7 +1679,7 @@ func extractBodies(chaindata string, block uint64) error {
 
 func fixUnwind(chaindata string) error {
 	contractAddr := common.HexToAddress("0x577a32aa9c40cf4266e49fc1e44c749c356309bd")
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 	i, err := db.GetOne(dbutils.IncarnationMapBucket, contractAddr[:])
 	if err != nil {
@@ -1697,7 +1698,7 @@ func fixUnwind(chaindata string) error {
 }
 
 func snapSizes(chaindata string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv2.MustOpen(chaindata)
 	defer db.Close()
 
 	dbtx, err := db.Begin(context.Background(), ethdb.RO)
@@ -1747,7 +1748,7 @@ func snapSizes(chaindata string) error {
 }
 
 func readCallTraces(chaindata string, block uint64) error {
-	kv := ethdb.MustOpenKV(chaindata)
+	kv := kv2.MustOpenKV(chaindata)
 	defer kv.Close()
 	tx, err := kv.BeginRw(context.Background())
 	if err != nil {
@@ -1793,7 +1794,7 @@ func readCallTraces(chaindata string, block uint64) error {
 }
 
 func fixTd(chaindata string) error {
-	kv := ethdb.MustOpenKV(chaindata)
+	kv := kv2.MustOpenKV(chaindata)
 	defer kv.Close()
 	tx, err := kv.BeginRw(context.Background())
 	if err != nil {
@@ -1849,7 +1850,7 @@ func fixTd(chaindata string) error {
 }
 
 func advanceExec(chaindata string) error {
-	db := ethdb.MustOpenKV(chaindata)
+	db := kv2.MustOpenKV(chaindata)
 	defer db.Close()
 	tx, err := db.BeginRw(context.Background())
 	if err != nil {
diff --git a/cmd/integration/commands/refetence_db.go b/cmd/integration/commands/refetence_db.go
index 64b6e35542..bf2920b9ca 100644
--- a/cmd/integration/commands/refetence_db.go
+++ b/cmd/integration/commands/refetence_db.go
@@ -13,6 +13,7 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/ethdb/mdbx"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/spf13/cobra"
@@ -125,10 +126,10 @@ func init() {
 }
 
 func compareStates(ctx context.Context, chaindata string, referenceChaindata string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv.MustOpen(chaindata)
 	defer db.Close()
 
-	refDB := ethdb.MustOpen(referenceChaindata)
+	refDB := kv.MustOpen(referenceChaindata)
 	defer refDB.Close()
 
 	if err := db.RwKV().View(context.Background(), func(tx ethdb.Tx) error {
@@ -151,10 +152,10 @@ func compareStates(ctx context.Context, chaindata string, referenceChaindata str
 	return nil
 }
 func compareBucketBetweenDatabases(ctx context.Context, chaindata string, referenceChaindata string, bucket string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv.MustOpen(chaindata)
 	defer db.Close()
 
-	refDB := ethdb.MustOpen(referenceChaindata)
+	refDB := kv.MustOpen(referenceChaindata)
 	defer refDB.Close()
 
 	if err := db.RwKV().View(context.Background(), func(tx ethdb.Tx) error {
@@ -249,7 +250,7 @@ func fToMdbx(ctx context.Context, to string) error {
 	}
 	defer file.Close()
 
-	dst := ethdb.NewMDBX().Path(to).MustOpen()
+	dst := kv.NewMDBX().Path(to).MustOpen()
 	dstTx, err1 := dst.BeginRw(ctx)
 	if err1 != nil {
 		return err1
@@ -363,8 +364,8 @@ MainLoop:
 
 func mdbxToMdbx(ctx context.Context, from, to string) error {
 	_ = os.RemoveAll(to)
-	src := ethdb.NewMDBX().Path(from).Flags(func(flags uint) uint { return mdbx.Readonly | mdbx.Accede }).MustOpen()
-	dst := ethdb.NewMDBX().Path(to).MustOpen()
+	src := kv.NewMDBX().Path(from).Flags(func(flags uint) uint { return mdbx.Readonly | mdbx.Accede }).MustOpen()
+	dst := kv.NewMDBX().Path(to).MustOpen()
 	return kv2kv(ctx, src, dst)
 }
 
diff --git a/cmd/integration/commands/root.go b/cmd/integration/commands/root.go
index 922b17ec31..5d014ece32 100644
--- a/cmd/integration/commands/root.go
+++ b/cmd/integration/commands/root.go
@@ -5,6 +5,7 @@ import (
 
 	"github.com/ledgerwatch/erigon/cmd/utils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/internal/debug"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/metrics"
@@ -38,7 +39,7 @@ func RootCommand() *cobra.Command {
 
 func openDB(path string, applyMigrations bool) ethdb.RwKV {
 	label := ethdb.Chain
-	db := ethdb.NewObjectDatabase(openKV(label, path, false))
+	db := kv2.NewObjectDatabase(openKV(label, path, false))
 	if applyMigrations {
 		has, err := migrations.NewMigrator(label).HasPendingMigrations(db.RwKV())
 		if err != nil {
@@ -47,12 +48,12 @@ func openDB(path string, applyMigrations bool) ethdb.RwKV {
 		if has {
 			log.Info("Re-Opening DB in exclusive mode to apply DB migrations")
 			db.Close()
-			db = ethdb.NewObjectDatabase(openKV(label, path, true))
+			db = kv2.NewObjectDatabase(openKV(label, path, true))
 			if err := migrations.NewMigrator(label).Apply(db, datadir); err != nil {
 				panic(err)
 			}
 			db.Close()
-			db = ethdb.NewObjectDatabase(openKV(label, path, false))
+			db = kv2.NewObjectDatabase(openKV(label, path, false))
 		}
 	}
 	metrics.AddCallback(db.RwKV().CollectMetrics)
@@ -60,7 +61,7 @@ func openDB(path string, applyMigrations bool) ethdb.RwKV {
 }
 
 func openKV(label ethdb.Label, path string, exclusive bool) ethdb.RwKV {
-	opts := ethdb.NewMDBX().Path(path).Label(label)
+	opts := kv2.NewMDBX().Path(path).Label(label)
 	if exclusive {
 		opts = opts.Exclusive()
 	}
diff --git a/cmd/integration/commands/snapshot_check.go b/cmd/integration/commands/snapshot_check.go
index 8d40aab551..9fe361c8bf 100644
--- a/cmd/integration/commands/snapshot_check.go
+++ b/cmd/integration/commands/snapshot_check.go
@@ -15,6 +15,7 @@ import (
 	"github.com/ledgerwatch/erigon/eth/stagedsync"
 	"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/ledgerwatch/erigon/turbo/snapshotsync"
 	"github.com/spf13/cobra"
@@ -37,7 +38,7 @@ var cmdSnapshotCheck = &cobra.Command{
 	RunE: func(cmd *cobra.Command, args []string) error {
 		ctx, _ := utils.RootContext()
 		//db to provide headers, blocks, senders ...
-		mainDB, err := ethdb.Open(chaindata, true)
+		mainDB, err := kv2.Open(chaindata, true)
 		if err != nil {
 			return err
 		}
@@ -51,7 +52,7 @@ var cmdSnapshotCheck = &cobra.Command{
 		}
 
 		stateSnapshotPath := filepath.Join(snapshotDir, "state")
-		stateSnapshot := ethdb.NewMDBX().Path(stateSnapshotPath).WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+		stateSnapshot := kv2.NewMDBX().Path(stateSnapshotPath).WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 			return dbutils.BucketsCfg{
 				dbutils.PlainStateBucket:        dbutils.BucketsConfigs[dbutils.PlainStateBucket],
 				dbutils.PlainContractCodeBucket: dbutils.BucketsConfigs[dbutils.PlainContractCodeBucket],
@@ -77,8 +78,8 @@ var cmdSnapshotCheck = &cobra.Command{
 				log.Info("Temp database", "path", path)
 			}
 		}()
-		tmpDb := ethdb.NewMDBX().Path(path).MustOpen()
-		kv := ethdb.NewSnapshotKV().
+		tmpDb := kv2.NewMDBX().Path(path).MustOpen()
+		kv := kv2.NewSnapshotKV().
 			DB(tmpDb).
 			SnapshotDB([]string{dbutils.HeadersBucket, dbutils.HeaderCanonicalBucket, dbutils.HeaderTDBucket, dbutils.BlockBodyPrefix, dbutils.Senders, dbutils.HeadBlockKey, dbutils.HeaderNumberBucket}, mainDB.RwKV()).
 			SnapshotDB([]string{dbutils.PlainStateBucket, dbutils.CodeBucket, dbutils.PlainContractCodeBucket}, stateSnapshot).
diff --git a/cmd/integration/commands/state_stages.go b/cmd/integration/commands/state_stages.go
index 3c9b805daf..098b7b31b8 100644
--- a/cmd/integration/commands/state_stages.go
+++ b/cmd/integration/commands/state_stages.go
@@ -11,6 +11,7 @@ import (
 	"time"
 
 	"github.com/c2h5oh/datasize"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/spf13/cobra"
 
 	"github.com/ledgerwatch/erigon/cmd/utils"
@@ -308,7 +309,7 @@ func syncBySmallSteps(db ethdb.RwKV, miningConfig params.MiningConfig, ctx conte
 
 			miningConfig.Etherbase = nextBlock.Header().Coinbase
 			miningConfig.ExtraData = nextBlock.Header().Extra
-			miningStages, err := mining.Prepare(vmConfig, ethdb.NewObjectDatabase(db), tx, sm, quit, false, miningWorld, nil)
+			miningStages, err := mining.Prepare(vmConfig, kv.NewObjectDatabase(db), tx, sm, quit, false, miningWorld, nil)
 			if err != nil {
 				panic(err)
 			}
diff --git a/cmd/pics/state.go b/cmd/pics/state.go
index 93305d63f1..504cccfb52 100644
--- a/cmd/pics/state.go
+++ b/cmd/pics/state.go
@@ -21,6 +21,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/turbo/stages"
@@ -415,7 +416,7 @@ func initialState1() error {
 		return err
 	}
 
-	emptyKv := ethdb.NewMemKV()
+	emptyKv := kv.NewMemKV()
 	if err = stateDatabaseComparison(emptyKv, m.DB, 0); err != nil {
 		return err
 	}
diff --git a/cmd/rpcdaemon/cli/config.go b/cmd/rpcdaemon/cli/config.go
index 5786b99d9d..0e57b4373f 100644
--- a/cmd/rpcdaemon/cli/config.go
+++ b/cmd/rpcdaemon/cli/config.go
@@ -13,6 +13,7 @@ import (
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/common/paths"
 	"github.com/ledgerwatch/erigon/ethdb"
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/ethdb/remote/remotedbserver"
 	"github.com/ledgerwatch/erigon/gointerfaces"
 	"github.com/ledgerwatch/erigon/internal/debug"
@@ -166,7 +167,7 @@ func RemoteServices(cfg Flags, rootCancel context.CancelFunc) (kv ethdb.RoKV, et
 	// If PrivateApiAddr is checked first, the Chaindata option will never work
 	if cfg.SingleNodeMode {
 		var rwKv ethdb.RwKV
-		rwKv, err = ethdb.NewMDBX().Path(cfg.Chaindata).Readonly().Open()
+		rwKv, err = kv2.NewMDBX().Path(cfg.Chaindata).Readonly().Open()
 		if err != nil {
 			return nil, nil, nil, nil, err
 		}
@@ -187,7 +188,7 @@ func RemoteServices(cfg Flags, rootCancel context.CancelFunc) (kv ethdb.RoKV, et
 		}
 	}
 	if cfg.PrivateApiAddr != "" {
-		remoteKv, err := ethdb.NewRemote(gointerfaces.VersionFromProto(remotedbserver.KvServiceAPIVersion)).Path(cfg.PrivateApiAddr).Open(cfg.TLSCertfile, cfg.TLSKeyFile, cfg.TLSCACert)
+		remoteKv, err := kv2.NewRemote(gointerfaces.VersionFromProto(remotedbserver.KvServiceAPIVersion)).Path(cfg.PrivateApiAddr).Open(cfg.TLSCertfile, cfg.TLSKeyFile, cfg.TLSCACert)
 		if err != nil {
 			return nil, nil, nil, nil, fmt.Errorf("could not connect to remoteKv: %w", err)
 		}
diff --git a/cmd/rpcdaemon/commands/get_chain_config_test.go b/cmd/rpcdaemon/commands/get_chain_config_test.go
index 4645a21e97..6c314310d0 100644
--- a/cmd/rpcdaemon/commands/get_chain_config_test.go
+++ b/cmd/rpcdaemon/commands/get_chain_config_test.go
@@ -5,11 +5,11 @@ import (
 	"testing"
 
 	"github.com/ledgerwatch/erigon/core"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func TestGetChainConfig(t *testing.T) {
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 	config, _, err := core.CommitGenesisBlock(db, core.DefaultGenesisBlock(), false)
 	if err != nil {
 		t.Fatalf("setting up genensis block: %v", err)
diff --git a/cmd/rpctest/rpctest/account_range_verify.go b/cmd/rpctest/rpctest/account_range_verify.go
index 6fdcecb78e..476c1efe15 100644
--- a/cmd/rpctest/rpctest/account_range_verify.go
+++ b/cmd/rpctest/rpctest/account_range_verify.go
@@ -16,6 +16,7 @@ import (
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func CompareAccountRange(erigonURL, gethURL, tmpDataDir, gethDataDir string, blockFrom uint64, notRegenerateGethData bool) {
@@ -30,10 +31,10 @@ func CompareAccountRange(erigonURL, gethURL, tmpDataDir, gethDataDir string, blo
 			log.Fatal(err)
 		}
 	}
-	resultsKV := ethdb.NewMDBX().Path(tmpDataDir).MustOpen()
-	gethKV := ethdb.NewMDBX().Path(gethDataDir).MustOpen()
-	resultsDB := ethdb.NewObjectDatabase(resultsKV)
-	gethResultsDB := ethdb.NewObjectDatabase(gethKV)
+	resultsKV := kv.NewMDBX().Path(tmpDataDir).MustOpen()
+	gethKV := kv.NewMDBX().Path(gethDataDir).MustOpen()
+	resultsDB := kv.NewObjectDatabase(resultsKV)
+	gethResultsDB := kv.NewObjectDatabase(gethKV)
 
 	var client = &http.Client{
 		Timeout: time.Minute * 60,
diff --git a/cmd/rpctest/rpctest/fixState.go b/cmd/rpctest/rpctest/fixState.go
index 1cfd392484..60f9a4fc1e 100644
--- a/cmd/rpctest/rpctest/fixState.go
+++ b/cmd/rpctest/rpctest/fixState.go
@@ -13,11 +13,12 @@ import (
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"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 := ethdb.MustOpen(chaindata).RwKV()
+	db := kv.MustOpen(chaindata).RwKV()
 	defer db.Close()
 	tx, err1 := db.BeginRw(context.Background())
 	if err1 != nil {
diff --git a/cmd/rpctest/rpctest/proofs.go b/cmd/rpctest/rpctest/proofs.go
index 35072cc7d5..dd7eeb0f00 100644
--- a/cmd/rpctest/rpctest/proofs.go
+++ b/cmd/rpctest/rpctest/proofs.go
@@ -6,12 +6,13 @@ import (
 	"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 := ethdb.MustOpen(chaindata)
+	db := kv.MustOpen(chaindata)
 	defer db.Close()
 	tx, err1 := db.Begin(context.Background(), ethdb.RW)
 	if err1 != nil {
diff --git a/cmd/sentry/download/sentry_test.go b/cmd/sentry/download/sentry_test.go
index 350b884d71..44151c4d06 100644
--- a/cmd/sentry/download/sentry_test.go
+++ b/cmd/sentry/download/sentry_test.go
@@ -13,6 +13,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"github.com/ledgerwatch/erigon/eth/protocols/eth"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/gointerfaces"
 	proto_sentry "github.com/ledgerwatch/erigon/gointerfaces/sentry"
 	"github.com/ledgerwatch/erigon/p2p"
@@ -63,8 +64,8 @@ func testForkIDSplit(t *testing.T, protocol uint) {
 			EIP158Block:    big.NewInt(2),
 			ByzantiumBlock: big.NewInt(3),
 		}
-		dbNoFork  = ethdb.NewTestKV(t)
-		dbProFork = ethdb.NewTestKV(t)
+		dbNoFork  = kv.NewTestKV(t)
+		dbProFork = kv.NewTestKV(t)
 
 		gspecNoFork  = &core.Genesis{Config: configNoFork}
 		gspecProFork = &core.Genesis{Config: configProFork}
diff --git a/cmd/snapshots/debug/debug_test.go b/cmd/snapshots/debug/debug_test.go
index b1c46070c5..359d77867c 100644
--- a/cmd/snapshots/debug/debug_test.go
+++ b/cmd/snapshots/debug/debug_test.go
@@ -19,6 +19,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types/accounts"
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/ethdb"
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/rlp"
 )
 
@@ -39,14 +40,14 @@ func TestMatreshkaStream(t *testing.T) {
 	chaindataDir := "/media/b00ris/nvme/fresh_sync/tg/chaindata"
 	tmpDbDir := "/home/b00ris/event_stream"
 
-	chaindata, err := ethdb.Open(chaindataDir, true)
+	chaindata, err := kv2.Open(chaindataDir, true)
 	if err != nil {
 		t.Fatal(err)
 	}
 	//tmpDb:=ethdb.NewMemDatabase()
 	os.RemoveAll(tmpDbDir)
 
-	kv, err := ethdb.NewMDBX().Path(tmpDbDir).WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+	kv, err := kv2.NewMDBX().Path(tmpDbDir).WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		defaultBuckets[AccountDiff] = dbutils.BucketConfigItem{}
 		defaultBuckets[StorageDiff] = dbutils.BucketConfigItem{}
 		defaultBuckets[ContractDiff] = dbutils.BucketConfigItem{}
@@ -66,9 +67,9 @@ func TestMatreshkaStream(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	snkv := ethdb.NewSnapshotKV().DB(kv).SnapshotDB([]string{dbutils.HeadersBucket, dbutils.HeaderCanonicalBucket, dbutils.HeaderTDBucket, dbutils.HeaderNumberBucket, dbutils.BlockBodyPrefix, dbutils.HeadHeaderKey, dbutils.Senders}, chaindata.RwKV()).Open()
+	snkv := kv2.NewSnapshotKV().DB(kv).SnapshotDB([]string{dbutils.HeadersBucket, dbutils.HeaderCanonicalBucket, dbutils.HeaderTDBucket, dbutils.HeaderNumberBucket, dbutils.BlockBodyPrefix, dbutils.HeadHeaderKey, dbutils.Senders}, chaindata.RwKV()).Open()
 	defer snkv.Close()
-	db := ethdb.NewObjectDatabase(snkv)
+	db := kv2.NewObjectDatabase(snkv)
 
 	tx, err := snkv.BeginRw(context.Background())
 	if err != nil {
diff --git a/cmd/snapshots/generator/commands/copy_from_state.go b/cmd/snapshots/generator/commands/copy_from_state.go
index db3a77937b..9ce9425f0f 100644
--- a/cmd/snapshots/generator/commands/copy_from_state.go
+++ b/cmd/snapshots/generator/commands/copy_from_state.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/spf13/cobra"
 )
@@ -31,7 +32,7 @@ var copyFromStateSnapshotCmd = &cobra.Command{
 }
 
 func CopyFromState(ctx context.Context, dbpath string, snapshotPath string, block uint64, snapshotDir, snapshotMode string) error {
-	db, err := ethdb.Open(dbpath, true)
+	db, err := kv.Open(dbpath, true)
 	if err != nil {
 		return err
 	}
@@ -47,7 +48,7 @@ func CopyFromState(ctx context.Context, dbpath string, snapshotPath string, bloc
 	if err != nil {
 		return err
 	}
-	snkv := ethdb.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+	snkv := kv.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return dbutils.BucketsCfg{
 			dbutils.PlainStateBucket:        dbutils.BucketsConfigs[dbutils.PlainStateBucket],
 			dbutils.PlainContractCodeBucket: dbutils.BucketsConfigs[dbutils.PlainContractCodeBucket],
diff --git a/cmd/snapshots/generator/commands/generate_body_snapshot.go b/cmd/snapshots/generator/commands/generate_body_snapshot.go
index c64d3ce821..73e4205f03 100644
--- a/cmd/snapshots/generator/commands/generate_body_snapshot.go
+++ b/cmd/snapshots/generator/commands/generate_body_snapshot.go
@@ -7,6 +7,7 @@ import (
 	"os"
 	"time"
 
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/spf13/cobra"
 
 	"github.com/ledgerwatch/erigon/common"
@@ -34,8 +35,8 @@ var generateBodiesSnapshotCmd = &cobra.Command{
 }
 
 func BodySnapshot(ctx context.Context, dbPath, snapshotPath string, toBlock uint64, snapshotDir string, snapshotMode string) error {
-	kv := ethdb.NewMDBX().Path(dbPath).MustOpen()
-	snKV := ethdb.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+	kv := kv2.NewMDBX().Path(dbPath).MustOpen()
+	snKV := kv2.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return dbutils.BucketsCfg{
 			dbutils.BlockBodyPrefix:          dbutils.BucketConfigItem{},
 			dbutils.BodiesSnapshotInfoBucket: dbutils.BucketConfigItem{},
diff --git a/cmd/snapshots/generator/commands/generate_header_snapshot.go b/cmd/snapshots/generator/commands/generate_header_snapshot.go
index cdaeda1cb7..bf2db7e9c4 100644
--- a/cmd/snapshots/generator/commands/generate_header_snapshot.go
+++ b/cmd/snapshots/generator/commands/generate_header_snapshot.go
@@ -8,12 +8,12 @@ import (
 	"os"
 	"time"
 
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/spf13/cobra"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/core/rawdb"
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/log"
 )
 
@@ -42,9 +42,9 @@ func HeaderSnapshot(ctx context.Context, dbPath, snapshotPath string, toBlock ui
 	if err != nil {
 		return err
 	}
-	kv := ethdb.NewMDBX().Path(dbPath).MustOpen()
+	kv := kv2.NewMDBX().Path(dbPath).MustOpen()
 
-	snKV := ethdb.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+	snKV := kv2.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return dbutils.BucketsCfg{
 			dbutils.HeadersBucket: dbutils.BucketConfigItem{},
 		}
diff --git a/cmd/snapshots/generator/commands/generate_state_snapshot.go b/cmd/snapshots/generator/commands/generate_state_snapshot.go
index ae2c0b7636..9b03134d86 100644
--- a/cmd/snapshots/generator/commands/generate_state_snapshot.go
+++ b/cmd/snapshots/generator/commands/generate_state_snapshot.go
@@ -12,6 +12,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/types/accounts"
 	"github.com/ledgerwatch/erigon/ethdb"
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/turbo/trie"
 	"github.com/spf13/cobra"
 )
@@ -45,8 +46,8 @@ func GenerateStateSnapshot(ctx context.Context, dbPath, snapshotPath string, toB
 	}
 	var kv, snkv ethdb.RwKV
 
-	kv = ethdb.NewMDBX().Path(dbPath).MustOpen()
-	snkv = ethdb.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+	kv = kv2.NewMDBX().Path(dbPath).MustOpen()
+	snkv = kv2.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return dbutils.BucketsCfg{
 			dbutils.PlainStateBucket:        dbutils.BucketConfigItem{},
 			dbutils.PlainContractCodeBucket: dbutils.BucketConfigItem{},
diff --git a/cmd/snapshots/generator/commands/verify_state_snapshot.go b/cmd/snapshots/generator/commands/verify_state_snapshot.go
index ada0255033..66df01036c 100644
--- a/cmd/snapshots/generator/commands/verify_state_snapshot.go
+++ b/cmd/snapshots/generator/commands/verify_state_snapshot.go
@@ -11,6 +11,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"github.com/ledgerwatch/erigon/eth/stagedsync"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/spf13/cobra"
 )
 
@@ -39,18 +40,18 @@ func VerifyStateSnapshot(ctx context.Context, dbPath, snapshotPath string, block
 		return err
 	}
 
-	snkv = ethdb.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+	snkv = kv.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return dbutils.BucketsCfg{
 			dbutils.PlainStateBucket:        dbutils.BucketsConfigs[dbutils.PlainStateBucket],
 			dbutils.PlainContractCodeBucket: dbutils.BucketsConfigs[dbutils.PlainContractCodeBucket],
 			dbutils.CodeBucket:              dbutils.BucketsConfigs[dbutils.CodeBucket],
 		}
 	}).Path(snapshotPath).Readonly().MustOpen()
-	tmpDB = ethdb.NewMDBX().Path(tmpPath).MustOpen()
+	tmpDB = kv.NewMDBX().Path(tmpPath).MustOpen()
 
 	defer os.RemoveAll(tmpPath)
 	defer tmpDB.Close()
-	snkv = ethdb.NewSnapshotKV().SnapshotDB([]string{dbutils.PlainStateBucket, dbutils.PlainContractCodeBucket, dbutils.CodeBucket}, snkv).DB(tmpDB).Open()
+	snkv = kv.NewSnapshotKV().SnapshotDB([]string{dbutils.PlainStateBucket, dbutils.PlainContractCodeBucket, dbutils.CodeBucket}, snkv).DB(tmpDB).Open()
 	tx, err := snkv.BeginRw(context.Background())
 	if err != nil {
 		return err
diff --git a/cmd/snapshots/tracker/commands/root.go b/cmd/snapshots/tracker/commands/root.go
index 5f13bf76f3..8b533ac5d0 100644
--- a/cmd/snapshots/tracker/commands/root.go
+++ b/cmd/snapshots/tracker/commands/root.go
@@ -20,6 +20,7 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/internal/debug"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/spf13/cobra"
@@ -73,7 +74,7 @@ var rootCmd = &cobra.Command{
 	Args:       cobra.ExactArgs(1),
 	ArgAliases: []string{"snapshots dir"},
 	RunE: func(cmd *cobra.Command, args []string) error {
-		db := ethdb.MustOpen(args[0])
+		db := kv.MustOpen(args[0])
 		m := http.NewServeMux()
 		m.Handle("/announce", &Tracker{db: db})
 		m.HandleFunc("/scrape", func(writer http.ResponseWriter, request *http.Request) {
diff --git a/cmd/snapshots/utils/utils.go b/cmd/snapshots/utils/utils.go
index 0bc7148e11..78d88a92ce 100644
--- a/cmd/snapshots/utils/utils.go
+++ b/cmd/snapshots/utils/utils.go
@@ -5,6 +5,7 @@ import (
 	"os"
 
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 var ErrUnsupported error = errors.New("unsupported KV type")
@@ -13,6 +14,6 @@ func RmTmpFiles(snapshotPath string) error {
 	return os.Remove(snapshotPath + "/mdbx.lck")
 }
 
-func OpenSnapshotKV(configsFunc ethdb.BucketConfigsFunc, path string) ethdb.RwKV {
-	return ethdb.NewMDBX().WithBucketsConfig(configsFunc).Path(path).MustOpen()
+func OpenSnapshotKV(configsFunc kv.BucketConfigsFunc, path string) ethdb.RwKV {
+	return kv.NewMDBX().WithBucketsConfig(configsFunc).Path(path).MustOpen()
 }
diff --git a/cmd/state/commands/check_change_sets.go b/cmd/state/commands/check_change_sets.go
index ed9418e2b3..bd2bac4b15 100644
--- a/cmd/state/commands/check_change_sets.go
+++ b/cmd/state/commands/check_change_sets.go
@@ -20,6 +20,7 @@ import (
 	"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"
 )
@@ -64,15 +65,15 @@ func CheckChangeSets(genesis *core.Genesis, blockNum uint64, chaindata string, h
 		interruptCh <- true
 	}()
 
-	kv, err := ethdb.NewMDBX().Path(chaindata).Open()
+	kv, err := kv2.NewMDBX().Path(chaindata).Open()
 	if err != nil {
 		return err
 	}
-	chainDb := ethdb.NewObjectDatabase(kv)
+	chainDb := kv2.NewObjectDatabase(kv)
 	defer chainDb.Close()
 	historyDb := chainDb
 	if chaindata != historyfile {
-		historyDb = ethdb.MustOpen(historyfile)
+		historyDb = kv2.MustOpen(historyfile)
 	}
 	historyTx, err1 := historyDb.RwKV().BeginRo(context.Background())
 	if err1 != nil {
diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go
index 8d3cfa260a..4c3944d72f 100644
--- a/cmd/state/commands/opcode_tracer.go
+++ b/cmd/state/commands/opcode_tracer.go
@@ -24,6 +24,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/core/vm/stack"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/spf13/cobra"
@@ -392,7 +393,7 @@ func OpcodeTracer(genesis *core.Genesis, blockNum uint64, chaindata string, numB
 
 	ot := NewOpcodeTracer(blockNum, saveOpcodes, saveBblocks)
 
-	chainDb := ethdb.MustOpen(chaindata)
+	chainDb := kv.MustOpen(chaindata)
 	defer chainDb.Close()
 	historyDb := chainDb
 	historyTx, err1 := historyDb.Begin(context.Background(), ethdb.RO)
diff --git a/cmd/state/generate/regenerate_tx_lookup.go b/cmd/state/generate/regenerate_tx_lookup.go
index 1504b986dd..0e6e47f53d 100644
--- a/cmd/state/generate/regenerate_tx_lookup.go
+++ b/cmd/state/generate/regenerate_tx_lookup.go
@@ -10,11 +10,12 @@ import (
 	"github.com/ledgerwatch/erigon/eth/stagedsync"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 )
 
 func RegenerateTxLookup(chaindata string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv.MustOpen(chaindata)
 	defer db.Close()
 	if err := db.ClearBuckets(dbutils.TxLookupPrefix); err != nil {
 		return err
diff --git a/cmd/state/stats/index_stats.go b/cmd/state/stats/index_stats.go
index a000e069ee..6d4db70d74 100644
--- a/cmd/state/stats/index_stats.go
+++ b/cmd/state/stats/index_stats.go
@@ -13,11 +13,11 @@ import (
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func IndexStats(chaindata string, indexBucket string, statsFile string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv.MustOpen(chaindata)
 	startTime := time.Now()
 	lenOfKey := common.HashLength
 	if strings.HasPrefix(indexBucket, dbutils.StorageHistoryBucket) {
diff --git a/cmd/state/verify/check_changeset_enc.go b/cmd/state/verify/check_changeset_enc.go
index d843ec0657..a9d4a1ee7a 100644
--- a/cmd/state/verify/check_changeset_enc.go
+++ b/cmd/state/verify/check_changeset_enc.go
@@ -11,7 +11,7 @@ import (
 
 	"github.com/ledgerwatch/erigon/common/changeset"
 	"github.com/ledgerwatch/erigon/common/dbutils"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"golang.org/x/sync/errgroup"
 )
 
@@ -21,7 +21,7 @@ type Walker interface {
 }
 
 func CheckEnc(chaindata string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv.MustOpen(chaindata)
 	defer db.Close()
 	var (
 		currentSize uint64
diff --git a/cmd/state/verify/check_indexes.go b/cmd/state/verify/check_indexes.go
index 14303454bc..a08181609c 100644
--- a/cmd/state/verify/check_indexes.go
+++ b/cmd/state/verify/check_indexes.go
@@ -8,12 +8,12 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/changeset"
 	"github.com/ledgerwatch/erigon/common/dbutils"
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/ethdb/bitmapdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func CheckIndex(ctx context.Context, chaindata string, changeSetBucket string, indexBucket string) error {
-	db := ethdb.MustOpen(chaindata)
+	db := kv.MustOpen(chaindata)
 	defer db.Close()
 	tx, err := db.RwKV().BeginRo(context.Background())
 	if err != nil {
diff --git a/cmd/state/verify/verify_headers_snapshot.go b/cmd/state/verify/verify_headers_snapshot.go
index e3532e2cab..d486312e13 100644
--- a/cmd/state/verify/verify_headers_snapshot.go
+++ b/cmd/state/verify/verify_headers_snapshot.go
@@ -7,12 +7,13 @@ import (
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/rlp"
 )
 
 func HeadersSnapshot(snapshotPath string) error {
-	snKV := ethdb.NewMDBX().Path(snapshotPath).Readonly().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+	snKV := kv.NewMDBX().Path(snapshotPath).Readonly().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return dbutils.BucketsCfg{
 			dbutils.HeadersBucket:             dbutils.BucketConfigItem{},
 			dbutils.HeadersSnapshotInfoBucket: dbutils.BucketConfigItem{},
diff --git a/cmd/state/verify/verify_txlookup.go b/cmd/state/verify/verify_txlookup.go
index cd6cb26513..2e54f12b72 100644
--- a/cmd/state/verify/verify_txlookup.go
+++ b/cmd/state/verify/verify_txlookup.go
@@ -12,12 +12,12 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/core/rawdb"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 )
 
 func ValidateTxLookups(chaindata string) error {
-	db := ethdb.MustOpenKV(chaindata)
+	db := kv.MustOpenKV(chaindata)
 	tx, err := db.BeginRo(context.Background())
 	if err != nil {
 		return err
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 31799418dc..18ef491ffe 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -31,6 +31,7 @@ import (
 	"text/template"
 
 	"github.com/ledgerwatch/erigon/eth/protocols/eth"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/spf13/cobra"
 	"github.com/spf13/pflag"
 	"github.com/urfave/cli"
@@ -1339,7 +1340,7 @@ func SplitTagsFlag(tagsFlag string) map[string]string {
 }
 
 // MakeChainDatabase open a database using the flags passed to the client and will hard crash if it fails.
-func MakeChainDatabase(ctx *cli.Context, stack *node.Node) *ethdb.ObjectDatabase {
+func MakeChainDatabase(ctx *cli.Context, stack *node.Node) *kv.ObjectDatabase {
 	chainDb, err := stack.OpenDatabase(ethdb.Chain, stack.Config().DataDir)
 	if err != nil {
 		Fatalf("Could not open database: %v", err)
diff --git a/common/changeset/storage_changeset_test.go b/common/changeset/storage_changeset_test.go
index 05a2640a17..71f19c86ab 100644
--- a/common/changeset/storage_changeset_test.go
+++ b/common/changeset/storage_changeset_test.go
@@ -11,6 +11,7 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -197,7 +198,7 @@ func TestEncodingStorageNewWithoutNotDefaultIncarnationWalk(t *testing.T) {
 
 func TestEncodingStorageNewWithoutNotDefaultIncarnationFind(t *testing.T) {
 	m := Mapper[storageTable]
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	c, err := tx.CursorDupSort(storageTable)
 	require.NoError(t, err)
@@ -224,7 +225,7 @@ func TestEncodingStorageNewWithoutNotDefaultIncarnationFind(t *testing.T) {
 func TestEncodingStorageNewWithoutNotDefaultIncarnationFindWithoutIncarnation(t *testing.T) {
 	bkt := storageTable
 	m := Mapper[bkt]
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	c, err := tx.CursorDupSort(bkt)
 	require.NoError(t, err)
@@ -378,7 +379,7 @@ func formatTestName(elements, keys int) string {
 func TestMultipleIncarnationsOfTheSameContract(t *testing.T) {
 	bkt := dbutils.StorageChangeSetBucket
 	m := Mapper[bkt]
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	c1, err := tx.CursorDupSort(bkt)
 	require.NoError(t, err)
diff --git a/common/etl/etl_test.go b/common/etl/etl_test.go
index 532ebfa2be..55e786a526 100644
--- a/common/etl/etl_test.go
+++ b/common/etl/etl_test.go
@@ -12,6 +12,7 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/stretchr/testify/assert"
 	"github.com/ugorji/go/codec"
 )
@@ -81,7 +82,7 @@ func TestNextKeyErr(t *testing.T) {
 
 func TestFileDataProviders(t *testing.T) {
 	// test invariant when we go through files (> 1 buffer)
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 	sourceBucket := dbutils.Buckets[0]
 
 	generateTestData(t, tx, sourceBucket, 10)
@@ -112,7 +113,7 @@ func TestFileDataProviders(t *testing.T) {
 
 func TestRAMDataProviders(t *testing.T) {
 	// test invariant when we go through memory (1 buffer)
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 	sourceBucket := dbutils.Buckets[0]
 	generateTestData(t, tx, sourceBucket, 10)
 
@@ -131,7 +132,7 @@ func TestRAMDataProviders(t *testing.T) {
 
 func TestTransformRAMOnly(t *testing.T) {
 	// test invariant when we only have one buffer and it fits into RAM (exactly 1 buffer)
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	tx, err := db.Begin(context.Background(), ethdb.RW)
 	if err != nil {
 		t.Fatal(err)
@@ -156,7 +157,7 @@ func TestTransformRAMOnly(t *testing.T) {
 }
 
 func TestEmptySourceBucket(t *testing.T) {
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	tx, err := db.Begin(context.Background(), ethdb.RW)
 	if err != nil {
 		t.Fatal(err)
@@ -180,7 +181,7 @@ func TestEmptySourceBucket(t *testing.T) {
 
 func TestTransformExtractStartKey(t *testing.T) {
 	// test invariant when we only have one buffer and it fits into RAM (exactly 1 buffer)
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	tx, err := db.Begin(context.Background(), ethdb.RW)
 	if err != nil {
 		t.Fatal(err)
@@ -205,7 +206,7 @@ func TestTransformExtractStartKey(t *testing.T) {
 
 func TestTransformThroughFiles(t *testing.T) {
 	// test invariant when we go through files (> 1 buffer)
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	tx, err := db.Begin(context.Background(), ethdb.RW)
 	if err != nil {
 		t.Fatal(err)
@@ -232,7 +233,7 @@ func TestTransformThroughFiles(t *testing.T) {
 
 func TestTransformDoubleOnExtract(t *testing.T) {
 	// test invariant when extractFunc multiplies the data 2x
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	tx, err := db.Begin(context.Background(), ethdb.RW)
 	if err != nil {
 		t.Fatal(err)
@@ -257,7 +258,7 @@ func TestTransformDoubleOnExtract(t *testing.T) {
 
 func TestTransformDoubleOnLoad(t *testing.T) {
 	// test invariant when loadFunc multiplies the data 2x
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	tx, err := db.Begin(context.Background(), ethdb.RW)
 	if err != nil {
 		t.Fatal(err)
diff --git a/consensus/clique/clique_test.go b/consensus/clique/clique_test.go
index de437572ed..c0795b82a4 100644
--- a/consensus/clique/clique_test.go
+++ b/consensus/clique/clique_test.go
@@ -22,6 +22,7 @@ import (
 	"testing"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/consensus/clique"
@@ -43,7 +44,7 @@ import (
 func TestReimportMirroredState(t *testing.T) {
 	// Initialize a Clique chain with a single signer
 	var (
-		cliqueDB = ethdb.NewTestKV(t)
+		cliqueDB = kv.NewTestKV(t)
 		key, _   = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		addr     = crypto.PubkeyToAddress(key.PublicKey)
 		engine   = clique.New(params.AllCliqueProtocolChanges, params.CliqueSnapshot, cliqueDB)
diff --git a/consensus/clique/snapshot_test.go b/consensus/clique/snapshot_test.go
index b95bb5dbea..f7b0283b35 100644
--- a/consensus/clique/snapshot_test.go
+++ b/consensus/clique/snapshot_test.go
@@ -28,7 +28,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/eth/stagedsync"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/turbo/stages"
 )
@@ -417,7 +417,7 @@ func TestClique(t *testing.T) {
 				Epoch:  tt.epoch,
 			}
 
-			cliqueDB := ethdb.NewTestKV(t)
+			cliqueDB := kv.NewTestKV(t)
 
 			engine := clique.New(&config, params.CliqueSnapshot, cliqueDB)
 			engine.FakeDiff = true
@@ -503,7 +503,7 @@ func TestClique(t *testing.T) {
 			// No failure was produced or requested, generate the final voting snapshot
 			head := chain.Blocks[len(chain.Blocks)-1]
 
-			snap, err := engine.Snapshot(stagedsync.ChainReader{Cfg: config, Db: ethdb.NewObjectDatabase(m.DB)}, head.NumberU64(), head.Hash(), nil)
+			snap, err := engine.Snapshot(stagedsync.ChainReader{Cfg: config, Db: kv.NewObjectDatabase(m.DB)}, head.NumberU64(), head.Hash(), nil)
 			if err != nil {
 				t.Errorf("test %d: failed to retrieve voting snapshot %d(%s): %v",
 					i, head.NumberU64(), head.Hash().Hex(), err)
diff --git a/consensus/db/db.go b/consensus/db/db.go
index e6c12b6525..dad772c5b2 100644
--- a/consensus/db/db.go
+++ b/consensus/db/db.go
@@ -2,10 +2,11 @@ package db
 
 import (
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func OpenDatabase(path string, inmem bool) ethdb.RwKV {
-	opts := ethdb.NewMDBX()
+	opts := kv.NewMDBX()
 	if inmem {
 		opts = opts.InMem()
 	} else {
diff --git a/core/block_validator_test.go b/core/block_validator_test.go
index 96457b20d3..4688bef72b 100644
--- a/core/block_validator_test.go
+++ b/core/block_validator_test.go
@@ -23,7 +23,7 @@ import (
 	"github.com/ledgerwatch/erigon/core"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/eth/stagedsync"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/turbo/stages"
 )
@@ -47,10 +47,10 @@ func TestHeaderVerification(t *testing.T) {
 		for j, valid := range []bool{true, false} {
 			if valid {
 				engine := ethash.NewFaker()
-				err = engine.VerifyHeaders(stagedsync.ChainReader{Cfg: *params.TestChainConfig, Db: ethdb.NewObjectDatabase(m.DB)}, []*types.Header{chain.Headers[i]}, []bool{true})
+				err = engine.VerifyHeaders(stagedsync.ChainReader{Cfg: *params.TestChainConfig, Db: kv.NewObjectDatabase(m.DB)}, []*types.Header{chain.Headers[i]}, []bool{true})
 			} else {
 				engine := ethash.NewFakeFailer(chain.Headers[i].Number.Uint64())
-				err = engine.VerifyHeaders(stagedsync.ChainReader{Cfg: *params.TestChainConfig, Db: ethdb.NewObjectDatabase(m.DB)}, []*types.Header{chain.Headers[i]}, []bool{true})
+				err = engine.VerifyHeaders(stagedsync.ChainReader{Cfg: *params.TestChainConfig, Db: kv.NewObjectDatabase(m.DB)}, []*types.Header{chain.Headers[i]}, []bool{true})
 			}
 			if (err == nil) != valid {
 				t.Errorf("test %d.%d: validity mismatch: have %v, want %v", i, j, err, valid)
diff --git a/core/genesis.go b/core/genesis.go
index b931b1841c..88ce6ee141 100644
--- a/core/genesis.go
+++ b/core/genesis.go
@@ -38,6 +38,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/turbo/trie"
@@ -298,14 +299,14 @@ func (g *Genesis) ToBlock() (*types.Block, *state.IntraBlockState, error) {
 	wg.Add(1)
 	go func() { // we may run inside write tx, can't open 2nd write tx in same goroutine
 		defer wg.Done()
-		tmpDB := ethdb.NewMDBX().InMem().MustOpen()
+		tmpDB := kv.NewMDBX().InMem().MustOpen()
 		defer tmpDB.Close()
 		tx, err := tmpDB.BeginRw(context.Background())
 		if err != nil {
 			panic(err)
 		}
 		defer tx.Rollback()
-		r, w := state.NewDbStateReader(ethdb.WrapIntoTxDB(tx)), state.NewDbStateWriter(ethdb.WrapIntoTxDB(tx), 0)
+		r, w := state.NewDbStateReader(kv.WrapIntoTxDB(tx)), state.NewDbStateWriter(kv.WrapIntoTxDB(tx), 0)
 		statedb = state.New(r)
 		for addr, account := range g.Alloc {
 			balance, _ := uint256.FromBig(account.Balance)
diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go
index 12121f4ffe..93b3099b87 100644
--- a/core/rawdb/accessors_chain_test.go
+++ b/core/rawdb/accessors_chain_test.go
@@ -27,7 +27,7 @@ import (
 	"github.com/ledgerwatch/erigon/common/u256"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/rlp"
 	"github.com/stretchr/testify/require"
@@ -36,7 +36,7 @@ import (
 
 // Tests block header storage and retrieval operations.
 func TestHeaderStorage(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	// Create a test header to move around the database and make sure it's really new
 	header := &types.Header{Number: big.NewInt(42), Extra: []byte("test header")}
@@ -69,7 +69,7 @@ func TestHeaderStorage(t *testing.T) {
 
 // Tests block body storage and retrieval operations.
 func TestBodyStorage(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 	require := require.New(t)
 
 	var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
@@ -124,7 +124,7 @@ func TestBodyStorage(t *testing.T) {
 
 // Tests block storage and retrieval operations.
 func TestBlockStorage(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	// Create a test block to move around the database and make sure it's really new
 	block := types.NewBlockWithHeader(&types.Header{
@@ -179,7 +179,7 @@ func TestBlockStorage(t *testing.T) {
 
 // Tests that partial block contents don't get reassembled into full blocks.
 func TestPartialBlockStorage(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 	block := types.NewBlockWithHeader(&types.Header{
 		Extra:       []byte("test block"),
 		UncleHash:   types.EmptyUncleHash,
@@ -217,7 +217,7 @@ func TestPartialBlockStorage(t *testing.T) {
 
 // Tests block total difficulty storage and retrieval operations.
 func TestTdStorage(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	// Create a test TD to move around the database and make sure it's really new
 	hash, td := common.Hash{}, big.NewInt(314)
@@ -258,7 +258,7 @@ func TestTdStorage(t *testing.T) {
 
 // Tests that canonical numbers can be mapped to hashes and retrieved.
 func TestCanonicalMappingStorage(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	// Create a test canonical number and assinged hash to move around
 	hash, number := common.Hash{0: 0xff}, uint64(314)
@@ -299,7 +299,7 @@ func TestCanonicalMappingStorage(t *testing.T) {
 
 // Tests that head headers and head blocks can be assigned, individually.
 func TestHeadStorage(t *testing.T) {
-	_, db := ethdb.NewTestTx(t)
+	_, db := kv.NewTestTx(t)
 
 	blockHead := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block header")})
 	blockFull := types.NewBlockWithHeader(&types.Header{Extra: []byte("test block full")})
@@ -326,7 +326,7 @@ func TestHeadStorage(t *testing.T) {
 
 // Tests that receipts associated with a single block can be stored and retrieved.
 func TestBlockReceiptStorage(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 	require := require.New(t)
 
 	// Create a live block since we need metadata to reconstruct the receipt
diff --git a/core/rawdb/accessors_indexes_test.go b/core/rawdb/accessors_indexes_test.go
index bd6dd60631..cbb8e6b15e 100644
--- a/core/rawdb/accessors_indexes_test.go
+++ b/core/rawdb/accessors_indexes_test.go
@@ -21,6 +21,7 @@ import (
 	"testing"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/core/types"
@@ -44,7 +45,7 @@ func TestLookupStorage(t *testing.T) {
 
 	for _, tc := range tests {
 		t.Run(tc.name, func(t *testing.T) {
-			_, tx := ethdb.NewTestTx(t)
+			_, tx := kv.NewTestTx(t)
 
 			tx1 := types.NewTransaction(1, common.BytesToAddress([]byte{0x11}), uint256.NewInt(111), 1111, uint256.NewInt(11111), []byte{0x11, 0x11, 0x11})
 			tx2 := types.NewTransaction(2, common.BytesToAddress([]byte{0x22}), uint256.NewInt(222), 2222, uint256.NewInt(22222), []byte{0x22, 0x22, 0x22})
diff --git a/core/rlp_test.go b/core/rlp_test.go
index 92812e0193..1d8c741f76 100644
--- a/core/rlp_test.go
+++ b/core/rlp_test.go
@@ -21,6 +21,7 @@ import (
 	"math/big"
 	"testing"
 
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"golang.org/x/crypto/sha3"
 
 	"github.com/ledgerwatch/erigon/common"
@@ -28,13 +29,12 @@ import (
 	"github.com/ledgerwatch/erigon/consensus/ethash"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/rlp"
 )
 
 func getBlock(transactions int, uncles int, dataSize int) *types.Block {
-	db := ethdb.NewMemKV()
+	db := kv.NewMemKV()
 	defer db.Close()
 	var (
 		aa = common.HexToAddress("0x000000000000000000000000000000000000aaaa")
diff --git a/core/state/database_test.go b/core/state/database_test.go
index 81257c5a34..47c2f1bb23 100644
--- a/core/state/database_test.go
+++ b/core/state/database_test.go
@@ -25,6 +25,7 @@ import (
 	"testing"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/turbo/stages"
 	"github.com/ledgerwatch/erigon/turbo/trie"
 	"github.com/stretchr/testify/assert"
@@ -71,7 +72,7 @@ func TestCreate2Revive(t *testing.T) {
 	)
 
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
@@ -242,7 +243,7 @@ func TestCreate2Polymorth(t *testing.T) {
 		signer = types.LatestSignerForChainID(nil)
 	)
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
@@ -463,7 +464,7 @@ func TestReorgOverSelfDestruct(t *testing.T) {
 	)
 
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
@@ -601,7 +602,7 @@ func TestReorgOverStateChange(t *testing.T) {
 	)
 
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
@@ -745,7 +746,7 @@ func TestCreateOnExistingStorage(t *testing.T) {
 	)
 
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	var err error
@@ -820,7 +821,7 @@ func TestReproduceCrash(t *testing.T) {
 	storageKey2 := common.HexToHash("0x0e4c0e7175f9d22279a4f63ff74f7fa28b7a954a6454debaa62ce43dd9132542")
 	value2 := uint256.NewInt(0x58c00a51)
 
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	tsw := state.NewPlainStateWriter(db, nil, 0)
 	intraBlockState := state.New(state.NewPlainStateReader(db))
 	ctx := context.Background()
@@ -873,7 +874,7 @@ func TestEip2200Gas(t *testing.T) {
 	)
 
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
@@ -959,7 +960,7 @@ func TestWrongIncarnation(t *testing.T) {
 	)
 
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
@@ -1078,7 +1079,7 @@ func TestWrongIncarnation2(t *testing.T) {
 	knownContractAddress := common.HexToAddress("0xdb7d6ab1f17c6b31909ae466702703daef9269cf")
 
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
@@ -1198,7 +1199,7 @@ func TestWrongIncarnation2(t *testing.T) {
 func TestChangeAccountCodeBetweenBlocks(t *testing.T) {
 	contract := common.HexToAddress("0x71dd1027069078091B3ca48093B00E4735B20624")
 
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	r, tsw := state.NewPlainStateReader(db), state.NewPlainStateWriter(db, nil, 0)
 	intraBlockState := state.New(r)
 	ctx := context.Background()
@@ -1240,7 +1241,7 @@ func TestCacheCodeSizeSeparately(t *testing.T) {
 	contract := common.HexToAddress("0x71dd1027069078091B3ca48093B00E4735B20624")
 	//root := common.HexToHash("0xb939e5bcf5809adfb87ab07f0795b05b95a1d64a90f0eddd0c3123ac5b433854")
 
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	r, w := state.NewPlainStateReader(db), state.NewPlainStateWriter(db, nil, 0)
 	intraBlockState := state.New(r)
 	ctx := context.Background()
@@ -1274,7 +1275,7 @@ func TestCacheCodeSizeInTrie(t *testing.T) {
 	contract := common.HexToAddress("0x71dd1027069078091B3ca48093B00E4735B20624")
 	root := common.HexToHash("0xb939e5bcf5809adfb87ab07f0795b05b95a1d64a90f0eddd0c3123ac5b433854")
 
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	r, w := state.NewPlainStateReader(db), state.NewPlainStateWriter(db, nil, 0)
 	intraBlockState := state.New(r)
 	ctx := context.Background()
@@ -1335,7 +1336,7 @@ func TestRecreateAndRewind(t *testing.T) {
 	)
 
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 	contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
 	defer contractBackend.Close()
diff --git a/core/state/history_test.go b/core/state/history_test.go
index d7c1bcff64..eff700a974 100644
--- a/core/state/history_test.go
+++ b/core/state/history_test.go
@@ -19,13 +19,14 @@ import (
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/ethdb/bitmapdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/turbo/trie"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestMutationDeleteTimestamp(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	acc := make([]*accounts.Account, 10)
 	addr := make([]common.Address, 10)
@@ -85,7 +86,7 @@ func TestMutationDeleteTimestamp(t *testing.T) {
 }
 
 func TestMutationCommit(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	numOfAccounts := 5
 	numOfStateKeys := 5
@@ -293,7 +294,7 @@ func randomAccount(t *testing.T) (*accounts.Account, common.Address) {
 */
 
 func TestWalkAsOfStatePlain(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	emptyVal := uint256.NewInt(0)
 	block3Val := uint256.NewInt(0).SetBytes([]byte("block 3"))
@@ -453,7 +454,7 @@ func TestWalkAsOfStatePlain(t *testing.T) {
 }
 
 func TestWalkAsOfUsingFixedBytesStatePlain(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	emptyVal := uint256.NewInt(0)
 	block3Val := uint256.NewInt(0).SetBytes([]byte("block 3"))
@@ -659,7 +660,7 @@ func TestWalkAsOfUsingFixedBytesStatePlain(t *testing.T) {
 }
 
 func TestWalkAsOfAccountPlain(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	emptyValAcc := accounts.NewAccount()
 	emptyVal := make([]byte, emptyValAcc.EncodingLengthForStorage())
@@ -807,7 +808,7 @@ func TestWalkAsOfAccountPlain(t *testing.T) {
 }
 
 func TestWalkAsOfAccountPlain_WithChunks(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	emptyValAcc := accounts.NewAccount()
 	emptyVal := make([]byte, emptyValAcc.EncodingLengthForStorage())
@@ -958,7 +959,7 @@ func TestWalkAsOfAccountPlain_WithChunks(t *testing.T) {
 }
 
 func TestWalkAsOfStoragePlain_WithChunks(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	numOfAccounts := uint8(4)
 	addrs := make([]common.Address, numOfAccounts)
diff --git a/core/state/intra_block_state_test.go b/core/state/intra_block_state_test.go
index 420aac6ed5..cf2e5a8fa2 100644
--- a/core/state/intra_block_state_test.go
+++ b/core/state/intra_block_state_test.go
@@ -30,11 +30,11 @@ import (
 	"testing/quick"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"gopkg.in/check.v1"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/core/types"
-	"github.com/ledgerwatch/erigon/ethdb"
 )
 
 func TestSnapshotRandom(t *testing.T) {
@@ -225,7 +225,7 @@ func (test *snapshotTest) String() string {
 
 func (test *snapshotTest) run() bool {
 	// Run all actions and create snapshots.
-	db := ethdb.NewMemDatabase()
+	db := kv.NewMemDatabase()
 	defer db.Close()
 	var (
 		ds           = NewDbStateReader(db)
@@ -354,7 +354,7 @@ func TestAccessList(t *testing.T) {
 		return common.HexToHash(a)
 	}
 
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	state := New(NewPlainStateReader(db))
 	state.accessList = newAccessList()
 
diff --git a/core/state/state_test.go b/core/state/state_test.go
index b46444321b..24b3519cfe 100644
--- a/core/state/state_test.go
+++ b/core/state/state_test.go
@@ -22,6 +22,7 @@ import (
 	"testing"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	checker "gopkg.in/check.v1"
 
 	"github.com/ledgerwatch/erigon/common"
@@ -101,7 +102,7 @@ func (s *StateSuite) TestDump(c *checker.C) {
 }
 
 func (s *StateSuite) SetUpTest(c *checker.C) {
-	db := ethdb.NewMemDatabase()
+	db := kv.NewMemDatabase()
 	s.db = db
 	s.kv = db.RwKV()
 	s.r = NewDbStateReader(s.db)
@@ -169,7 +170,7 @@ func (s *StateSuite) TestSnapshotEmpty(c *checker.C) {
 // printing/logging in tests (-check.vv does not work)
 func TestSnapshot2(t *testing.T) {
 
-	db := ethdb.NewMemDatabase()
+	db := kv.NewMemDatabase()
 	ctx := context.TODO()
 	w := NewDbStateWriter(db, 0)
 	state := New(NewDbStateReader(db))
@@ -285,7 +286,7 @@ func compareStateObjects(so0, so1 *stateObject, t *testing.T) {
 }
 
 func TestDump(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 	w := NewPlainStateWriter(tx, tx, 0)
 	state := New(NewPlainStateReader(tx))
 
diff --git a/core/tx_pool.go b/core/tx_pool.go
index 67ed2d6e2e..1a4ee78d26 100644
--- a/core/tx_pool.go
+++ b/core/tx_pool.go
@@ -30,6 +30,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/event"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/metrics"
@@ -277,7 +278,7 @@ func NewTxPool(config TxPoolConfig, chainconfig *params.ChainConfig, chaindb eth
 		reorgShutdownCh: make(chan struct{}, 1),
 		gasPrice:        new(uint256.Int).SetUint64(config.PriceLimit),
 		stopCh:          make(chan struct{}),
-		chaindb:         ethdb.NewObjectDatabase(chaindb),
+		chaindb:         kv.NewObjectDatabase(chaindb),
 	}
 	pool.locals = newAccountSet(pool.signer)
 	for _, addr := range pool.config.Locals {
diff --git a/core/tx_pool_test.go b/core/tx_pool_test.go
index b7b873aee9..fba3c9911f 100644
--- a/core/tx_pool_test.go
+++ b/core/tx_pool_test.go
@@ -33,7 +33,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 )
 
@@ -99,7 +99,7 @@ func setupTxPool(t testing.TB) (*TxPool, *ecdsa.PrivateKey) {
 }
 
 func setupTxPoolWithConfig(t testing.TB, config *params.ChainConfig) (*TxPool, *ecdsa.PrivateKey) {
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	key, _ := crypto.GenerateKey()
 	pool := NewTxPool(TestTxPoolConfig, config, db)
@@ -179,7 +179,7 @@ func deriveSender(tx types.Transaction) (common.Address, error) {
 // state reset and tests whether the pending state is in sync with the
 // block head event that initiated the resetState().
 func TestStateChangeDuringTransactionPoolReset(t *testing.T) {
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	var (
 		key, _  = crypto.GenerateKey()
 		address = crypto.PubkeyToAddress(key.PublicKey)
@@ -581,7 +581,7 @@ func TestTransactionDropping(t *testing.T) {
 // postponed back into the future queue to prevent broadcasting them.
 func TestTransactionPostponing(t *testing.T) {
 	// Create the pool to test the postponing with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	pool := NewTxPool(TestTxPoolConfig, params.TestChainConfig, db)
 	if err := pool.Start(1000000000, 0); err != nil {
@@ -790,7 +790,7 @@ func TestTransactionQueueGlobalLimitingNoLocals(t *testing.T) {
 
 func testTransactionQueueGlobalLimiting(t *testing.T, nolocals bool) {
 	// Create the pool to test the limit enforcement with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	config := TestTxPoolConfig
 	config.NoLocals = nolocals
@@ -884,7 +884,7 @@ func testTransactionQueueTimeLimiting(t *testing.T, nolocals bool) {
 	evictionInterval = time.Millisecond * 100
 
 	// Create the pool to test the non-expiration enforcement
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	config := TestTxPoolConfig
 	config.Lifetime = time.Second
@@ -1002,7 +1002,7 @@ func TestTransactionPendingLimiting(t *testing.T) {
 // attacks.
 func TestTransactionPendingGlobalLimiting(t *testing.T) {
 	// Create the pool to test the limit enforcement with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	config := TestTxPoolConfig
 	config.GlobalSlots = config.AccountSlots * 10
@@ -1103,7 +1103,7 @@ func TestTransactionAllowedTxSize(t *testing.T) {
 // Tests that if transactions start being capped, transactions are also removed from 'all'
 func TestTransactionCapClearsFromAll(t *testing.T) {
 	// Create the pool to test the limit enforcement with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	config := TestTxPoolConfig
 	config.AccountSlots = 2
@@ -1139,7 +1139,7 @@ func TestTransactionCapClearsFromAll(t *testing.T) {
 // the transactions are still kept.
 func TestTransactionPendingMinimumAllowance(t *testing.T) {
 	// Create the pool to test the limit enforcement with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	config := TestTxPoolConfig
 	config.GlobalSlots = 1
@@ -1190,7 +1190,7 @@ func TestTransactionPendingMinimumAllowance(t *testing.T) {
 func TestTransactionPoolRepricing(t *testing.T) {
 	t.Skip("deadlock")
 	// Create the pool to test the pricing enforcement with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	pool := NewTxPool(TestTxPoolConfig, params.TestChainConfig, db)
 	if err := pool.Start(1000000000, 0); err != nil {
@@ -1313,7 +1313,7 @@ func TestTransactionPoolRepricing(t *testing.T) {
 // remove local transactions.
 func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
 	// Create the pool to test the pricing enforcement with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	pool := NewTxPool(TestTxPoolConfig, params.TestChainConfig, db)
 	if err := pool.Start(1000000000, 0); err != nil {
@@ -1377,7 +1377,7 @@ func TestTransactionPoolRepricingKeepsLocals(t *testing.T) {
 // Note, local transactions are never allowed to be dropped.
 func TestTransactionPoolUnderpricing(t *testing.T) {
 	// Create the pool to test the pricing enforcement with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	config := TestTxPoolConfig
 	config.GlobalSlots = 2
@@ -1485,7 +1485,7 @@ func TestTransactionPoolUnderpricing(t *testing.T) {
 // back and forth between queued/pending.
 func TestTransactionPoolStableUnderpricing(t *testing.T) {
 	// Create the pool to test the pricing enforcement with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	config := TestTxPoolConfig
 	config.GlobalSlots = 128
@@ -1551,7 +1551,7 @@ func TestTransactionPoolStableUnderpricing(t *testing.T) {
 
 // Tests that the pool rejects duplicate transactions.
 func TestTransactionDeduplication(t *testing.T) {
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	pool := NewTxPool(TestTxPoolConfig, params.TestChainConfig, db)
 	if err := pool.Start(1000000000, 0); err != nil {
@@ -1619,7 +1619,7 @@ func TestTransactionDeduplication(t *testing.T) {
 // price bump required.
 func TestTransactionReplacement(t *testing.T) {
 	// Create the pool to test the pricing enforcement with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	pool := NewTxPool(TestTxPoolConfig, params.TestChainConfig, db)
 	if err := pool.Start(1000000000, 0); err != nil {
@@ -1716,7 +1716,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
 	os.Remove(journal)
 
 	// Create the original pool to inject transaction into the journal
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 
 	config := TestTxPoolConfig
 	config.NoLocals = nolocals
@@ -1845,7 +1845,7 @@ func testTransactionJournaling(t *testing.T, nolocals bool) {
 // pending status of individual transactions.
 func TestTransactionStatusCheck(t *testing.T) {
 	// Create the pool to test the status retrievals with
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	pool := NewTxPool(TestTxPoolConfig, params.TestChainConfig, db)
 	if err := pool.Start(1000000000, 0); err != nil {
diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go
index 2b2432ffd7..585df1ae71 100644
--- a/core/vm/gas_table_test.go
+++ b/core/vm/gas_table_test.go
@@ -27,7 +27,7 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/hexutil"
 	"github.com/ledgerwatch/erigon/core/state"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 )
 
@@ -88,7 +88,7 @@ func TestEIP2200(t *testing.T) {
 
 		t.Run(strconv.Itoa(i), func(t *testing.T) {
 			address := common.BytesToAddress([]byte("contract"))
-			_, tx := ethdb.NewTestTx(t)
+			_, tx := kv.NewTestTx(t)
 
 			s := state.New(state.NewPlainStateReader(tx))
 			s.CreateAccount(address, true)
diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go
index 0446dd880e..ef5edf2d7e 100644
--- a/core/vm/runtime/runtime.go
+++ b/core/vm/runtime/runtime.go
@@ -22,12 +22,12 @@ import (
 	"time"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/crypto"
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/params"
 )
 
@@ -114,7 +114,7 @@ func Execute(code, input []byte, cfg *Config, blockNr uint64) ([]byte, *state.In
 	setDefaults(cfg)
 
 	if cfg.State == nil {
-		db := ethdb.NewMemDatabase()
+		db := kv.NewMemDatabase()
 		defer db.Close()
 		cfg.r = state.NewDbStateReader(db)
 		cfg.w = state.NewDbStateWriter(db, 0)
@@ -152,7 +152,7 @@ func Create(input []byte, cfg *Config, blockNr uint64) ([]byte, common.Address,
 	setDefaults(cfg)
 
 	if cfg.State == nil {
-		db := ethdb.NewMemDatabase()
+		db := kv.NewMemDatabase()
 		defer db.Close()
 		cfg.r = state.NewDbStateReader(db)
 		cfg.w = state.NewDbStateWriter(db, 0)
diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go
index 78b2d1d5c5..627f2d7828 100644
--- a/core/vm/runtime/runtime_test.go
+++ b/core/vm/runtime/runtime_test.go
@@ -31,7 +31,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/core/vm"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 )
 
@@ -103,7 +103,7 @@ func TestExecute(t *testing.T) {
 }
 
 func TestCall(t *testing.T) {
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 	state := state.New(state.NewDbStateReader(db))
 	address := common.HexToAddress("0x0a")
 	state.SetCode(address, []byte{
@@ -159,7 +159,7 @@ func BenchmarkCall(b *testing.B) {
 	}
 }
 func benchmarkEVM_Create(bench *testing.B, code string) {
-	db := ethdb.NewMemDatabase()
+	db := kv.NewMemDatabase()
 	defer db.Close()
 	var (
 		statedb  = state.New(state.NewPlainStateReader(db))
@@ -330,7 +330,7 @@ func TestBlockhash(t *testing.T) {
 func benchmarkNonModifyingCode(gas uint64, code []byte, name string, b *testing.B) { //nolint:unparam
 	cfg := new(Config)
 	setDefaults(cfg)
-	db := ethdb.NewMemDatabase()
+	db := kv.NewMemDatabase()
 	defer db.Close()
 	cfg.State = state.New(state.NewDbStateReader(db))
 	cfg.GasLimit = gas
diff --git a/docs/programmers_guide/db_faq.md b/docs/programmers_guide/db_faq.md
index 1434e0905a..81ac71f57f 100644
--- a/docs/programmers_guide/db_faq.md
+++ b/docs/programmers_guide/db_faq.md
@@ -25,7 +25,7 @@ Erigon uses MDBX storage engine. But most information on the Internet about LMDB
 
 We have Go, Rust and C++ implementations of `RoKV` interface.
 
-Rationale and Architecture of DB interface: [./../../ethdb/Readme.md](./../../ethdb/Readme.md)
+Rationale and Architecture of DB interface: [./../../ethdb/Readme.md](../../ethdb/Readme.md)
 
 MDBX docs: [erthink.github.io/libmdbx/](https://erthink.github.io/libmdbx/)
 and [https://github.com/erthink/libmdbx/blob/master/mdbx.h](https://github.com/erthink/libmdbx/blob/master/mdbx.h)
diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go
index d4a86ba6bd..11a61bc45c 100644
--- a/eth/ethconfig/config.go
+++ b/eth/ethconfig/config.go
@@ -27,7 +27,6 @@ import (
 
 	"github.com/c2h5oh/datasize"
 	"github.com/davecgh/go-spew/spew"
-
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/consensus"
 	"github.com/ledgerwatch/erigon/consensus/clique"
diff --git a/eth/fetcher/block_fetcher_test.go b/eth/fetcher/block_fetcher_test.go
index dbbbb6b054..13da00a43a 100644
--- a/eth/fetcher/block_fetcher_test.go
+++ b/eth/fetcher/block_fetcher_test.go
@@ -25,18 +25,18 @@ import (
 	"time"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/consensus/ethash"
 	"github.com/ledgerwatch/erigon/core"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/params"
 )
 
 var (
-	testdb       = ethdb.NewMemDatabase()
+	testdb       = kv.NewMemDatabase()
 	testKey, _   = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 	testAddress  = crypto.PubkeyToAddress(testKey.PublicKey)
 	genesis      = core.GenesisBlockForTesting(testdb.RwKV(), testAddress, big.NewInt(1000000000))
@@ -48,7 +48,7 @@ var (
 // contains a transaction and every 5th an uncle to allow testing correct block
 // reassembly.
 func makeChain(n int, seed byte, parent *types.Block) ([]common.Hash, map[common.Hash]*types.Block) {
-	db := ethdb.NewMemKV()
+	db := kv.NewMemKV()
 	defer db.Close()
 	core.GenesisBlockForTesting(db, testAddress, big.NewInt(1000000000))
 	chain, err := core.GenerateChain(params.TestChainConfig, parent, ethash.NewFaker(), db, n, func(i int, block *core.BlockGen) {
diff --git a/eth/filters/bench_test.go b/eth/filters/bench_test.go
index 244ce96694..07dd31f5a6 100644
--- a/eth/filters/bench_test.go
+++ b/eth/filters/bench_test.go
@@ -29,6 +29,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func BenchmarkBloomBits512(b *testing.B) {
@@ -65,7 +66,7 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) {
 	benchDataDir := paths.DefaultDataDir() + "/geth/chaindata"
 	b.Log("Running bloombits benchmark   section size:", sectionSize)
 
-	db := ethdb.MustOpen(benchDataDir)
+	db := kv.MustOpen(benchDataDir)
 	head := rawdb.ReadHeadBlockHash(db)
 	if head == (common.Hash{}) {
 		b.Fatalf("chain data not found at %v", benchDataDir)
@@ -126,7 +127,7 @@ func benchmarkBloomBits(b *testing.B, sectionSize uint64) {
 	for i := 0; i < benchFilterCnt; i++ {
 		if i%20 == 0 {
 			db.Close()
-			db = ethdb.MustOpen(benchDataDir)
+			db = kv.MustOpen(benchDataDir)
 			backend = &testBackend{db: db, sections: cnt}
 		}
 		var addr common.Address
@@ -159,7 +160,7 @@ func clearBloomBits(db ethdb.Database) {
 func BenchmarkNoBloomBits(b *testing.B) {
 	benchDataDir := paths.DefaultDataDir() + "/geth/chaindata"
 	fmt.Println("Running benchmark without bloombits")
-	db := ethdb.MustOpen(benchDataDir)
+	db := kv.MustOpen(benchDataDir)
 	head := rawdb.ReadHeadBlockHash(db)
 	if head == (common.Hash{}) {
 		b.Fatalf("chain data not found at %v", benchDataDir)
diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go
index 42e1538b80..e370f905ab 100644
--- a/eth/filters/filter_test.go
+++ b/eth/filters/filter_test.go
@@ -28,6 +28,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 )
 
@@ -41,10 +42,10 @@ func makeReceipt(addr common.Address) *types.Receipt {
 }
 
 func BenchmarkFilters(b *testing.B) {
-	db := ethdb.NewTestKV(b)
+	db := kv.NewTestKV(b)
 	defer db.Close()
 	var (
-		backend = &testBackend{db: ethdb.NewObjectDatabase(db)}
+		backend = &testBackend{db: kv.NewObjectDatabase(db)}
 		key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
 		addr1   = crypto.PubkeyToAddress(key1.PublicKey)
 		addr2   = common.BytesToAddress([]byte("jeff"))
diff --git a/eth/protocols/eth/handler_test.go b/eth/protocols/eth/handler_test.go
index 81cdb41ea1..8081da62cb 100644
--- a/eth/protocols/eth/handler_test.go
+++ b/eth/protocols/eth/handler_test.go
@@ -31,6 +31,7 @@ import (
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/eth/protocols/eth"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/gointerfaces/sentry"
 	"github.com/ledgerwatch/erigon/p2p"
 	"github.com/ledgerwatch/erigon/p2p/enode"
@@ -86,7 +87,7 @@ func newTestBackendWithGenerator(t *testing.T, blocks int, generator func(int, *
 	txconfig.Journal = "" // Don't litter the disk with test journals
 
 	b := &testBackend{
-		db:          ethdb.NewObjectDatabase(m.DB),
+		db:          kv.NewObjectDatabase(m.DB),
 		txpool:      core.NewTxPool(txconfig, m.ChainConfig, m.DB),
 		headBlock:   headBlock,
 		genesis:     m.Genesis,
diff --git a/eth/stagedsync/stage_bodies.go b/eth/stagedsync/stage_bodies.go
index f2930b22c1..7edc3f7506 100644
--- a/eth/stagedsync/stage_bodies.go
+++ b/eth/stagedsync/stage_bodies.go
@@ -11,6 +11,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/metrics"
 	"github.com/ledgerwatch/erigon/params"
@@ -149,7 +150,7 @@ Loop:
 		}
 		d4 += time.Since(start)
 		start = time.Now()
-		cr := ChainReader{Cfg: cfg.chanConfig, Db: ethdb.WrapIntoTxDB(tx)}
+		cr := ChainReader{Cfg: cfg.chanConfig, Db: kv.WrapIntoTxDB(tx)}
 		for i, header := range headers {
 			rawBody := rawBodies[i]
 			blockHeight := header.Number.Uint64()
diff --git a/eth/stagedsync/stage_execute.go b/eth/stagedsync/stage_execute.go
index c6ccaeea0f..0ba6b31fd2 100644
--- a/eth/stagedsync/stage_execute.go
+++ b/eth/stagedsync/stage_execute.go
@@ -10,6 +10,7 @@ import (
 	"time"
 
 	"github.com/c2h5oh/datasize"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/changeset"
@@ -244,7 +245,7 @@ func SpawnExecuteBlocksStage(s *StageState, u Unwinder, tx ethdb.RwTx, toBlock u
 	}
 
 	var batch ethdb.DbWithPendingMutations
-	batch = ethdb.NewBatch(tx)
+	batch = kv.NewBatch(tx)
 	defer batch.Rollback()
 
 	logEvery := time.NewTicker(logInterval)
@@ -310,7 +311,7 @@ Loop:
 				// TODO: This creates stacked up deferrals
 				defer tx.Rollback()
 			}
-			batch = ethdb.NewBatch(tx)
+			batch = kv.NewBatch(tx)
 			// TODO: This creates stacked up deferrals
 			defer batch.Rollback()
 		}
diff --git a/eth/stagedsync/stage_execute_test.go b/eth/stagedsync/stage_execute_test.go
index f9d7c1fd23..12f30ac6b3 100644
--- a/eth/stagedsync/stage_execute_test.go
+++ b/eth/stagedsync/stage_execute_test.go
@@ -5,12 +5,12 @@ import (
 
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func TestUnwindExecutionStagePlainStatic(t *testing.T) {
-	_, tx1 := ethdb.NewTestTx(t)
-	_, tx2 := ethdb.NewTestTx(t)
+	_, tx1 := kv.NewTestTx(t)
+	_, tx2 := kv.NewTestTx(t)
 
 	generateBlocks(t, 1, 50, plainWriterGen(tx1), staticCodeStaticIncarnations)
 	generateBlocks(t, 1, 100, plainWriterGen(tx2), staticCodeStaticIncarnations)
@@ -30,8 +30,8 @@ func TestUnwindExecutionStagePlainStatic(t *testing.T) {
 }
 
 func TestUnwindExecutionStagePlainWithIncarnationChanges(t *testing.T) {
-	_, tx1 := ethdb.NewTestTx(t)
-	_, tx2 := ethdb.NewTestTx(t)
+	_, tx1 := kv.NewTestTx(t)
+	_, tx2 := kv.NewTestTx(t)
 
 	generateBlocks(t, 1, 50, plainWriterGen(tx1), changeCodeWithIncarnations)
 	generateBlocks(t, 1, 100, plainWriterGen(tx2), changeCodeWithIncarnations)
@@ -52,8 +52,8 @@ func TestUnwindExecutionStagePlainWithIncarnationChanges(t *testing.T) {
 
 func TestUnwindExecutionStagePlainWithCodeChanges(t *testing.T) {
 	t.Skip("not supported yet, to be restored")
-	_, tx1 := ethdb.NewTestTx(t)
-	_, tx2 := ethdb.NewTestTx(t)
+	_, tx1 := kv.NewTestTx(t)
+	_, tx2 := kv.NewTestTx(t)
 
 	generateBlocks(t, 1, 50, plainWriterGen(tx1), changeCodeIndepenentlyOfIncarnations)
 	generateBlocks(t, 1, 100, plainWriterGen(tx2), changeCodeIndepenentlyOfIncarnations)
diff --git a/eth/stagedsync/stage_hashstate_test.go b/eth/stagedsync/stage_hashstate_test.go
index 6691c351e4..6ce532c2cb 100644
--- a/eth/stagedsync/stage_hashstate_test.go
+++ b/eth/stagedsync/stage_hashstate_test.go
@@ -5,16 +5,16 @@ import (
 	"errors"
 	"testing"
 
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/stretchr/testify/require"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
-	"github.com/ledgerwatch/erigon/ethdb"
 )
 
 func TestPromoteHashedStateClearState(t *testing.T) {
-	_, tx1 := ethdb.NewTestTx(t)
-	db2, tx2 := ethdb.NewTestTx(t)
+	_, tx1 := kv.NewTestTx(t)
+	db2, tx2 := kv.NewTestTx(t)
 
 	generateBlocks(t, 1, 50, hashedWriterGen(tx1), changeCodeWithIncarnations)
 	generateBlocks(t, 1, 50, plainWriterGen(tx2), changeCodeWithIncarnations)
@@ -28,8 +28,8 @@ func TestPromoteHashedStateClearState(t *testing.T) {
 }
 
 func TestPromoteHashedStateIncremental(t *testing.T) {
-	_, tx1 := ethdb.NewTestTx(t)
-	db2, tx2 := ethdb.NewTestTx(t)
+	_, tx1 := kv.NewTestTx(t)
+	db2, tx2 := kv.NewTestTx(t)
 
 	generateBlocks(t, 1, 50, hashedWriterGen(tx1), changeCodeWithIncarnations)
 	generateBlocks(t, 1, 50, plainWriterGen(tx2), changeCodeWithIncarnations)
@@ -52,8 +52,8 @@ func TestPromoteHashedStateIncremental(t *testing.T) {
 }
 
 func TestPromoteHashedStateIncrementalMixed(t *testing.T) {
-	_, tx1 := ethdb.NewTestTx(t)
-	db2, tx2 := ethdb.NewTestTx(t)
+	_, tx1 := kv.NewTestTx(t)
+	db2, tx2 := kv.NewTestTx(t)
 
 	generateBlocks(t, 1, 100, hashedWriterGen(tx1), changeCodeWithIncarnations)
 	generateBlocks(t, 1, 50, hashedWriterGen(tx2), changeCodeWithIncarnations)
@@ -67,8 +67,8 @@ func TestPromoteHashedStateIncrementalMixed(t *testing.T) {
 }
 
 func TestUnwindHashed(t *testing.T) {
-	_, tx1 := ethdb.NewTestTx(t)
-	db2, tx2 := ethdb.NewTestTx(t)
+	_, tx1 := kv.NewTestTx(t)
+	db2, tx2 := kv.NewTestTx(t)
 
 	generateBlocks(t, 1, 50, hashedWriterGen(tx1), changeCodeWithIncarnations)
 	generateBlocks(t, 1, 50, plainWriterGen(tx2), changeCodeWithIncarnations)
@@ -106,7 +106,7 @@ func TestPromoteIncrementallyShutdown(t *testing.T) {
 			if tc.cancelFuncExec {
 				cancel()
 			}
-			db, tx := ethdb.NewTestTx(t)
+			db, tx := kv.NewTestTx(t)
 			generateBlocks(t, 1, 10, plainWriterGen(tx), changeCodeWithIncarnations)
 			if err := promoteHashedStateIncrementally("logPrefix", &StageState{BlockNumber: 1}, 1, 10, tx, StageHashStateCfg(db, t.TempDir()), ctx.Done()); !errors.Is(err, tc.errExp) {
 				t.Errorf("error does not match expected error while shutdown promoteHashedStateIncrementally, got: %v, expected: %v", err, tc.errExp)
@@ -138,7 +138,7 @@ func TestPromoteHashedStateCleanlyShutdown(t *testing.T) {
 				cancel()
 			}
 
-			db, tx := ethdb.NewTestTx(t)
+			db, tx := kv.NewTestTx(t)
 
 			generateBlocks(t, 1, 10, plainWriterGen(tx), changeCodeWithIncarnations)
 
@@ -172,7 +172,7 @@ func TestUnwindHashStateShutdown(t *testing.T) {
 				cancel()
 			}
 
-			db, tx := ethdb.NewTestTx(t)
+			db, tx := kv.NewTestTx(t)
 
 			generateBlocks(t, 1, 10, plainWriterGen(tx), changeCodeWithIncarnations)
 			cfg := StageHashStateCfg(db, t.TempDir())
diff --git a/eth/stagedsync/stage_indexes_test.go b/eth/stagedsync/stage_indexes_test.go
index 7281785126..bad6f56566 100644
--- a/eth/stagedsync/stage_indexes_test.go
+++ b/eth/stagedsync/stage_indexes_test.go
@@ -14,6 +14,7 @@ import (
 	"github.com/ledgerwatch/erigon/common/changeset"
 	"github.com/ledgerwatch/erigon/common/math"
 	"github.com/ledgerwatch/erigon/ethdb/bitmapdb"
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
@@ -24,7 +25,7 @@ import (
 
 func TestIndexGenerator_GenerateIndex_SimpleCase(t *testing.T) {
 	log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
-	db := ethdb.NewMemDatabase()
+	db := kv2.NewMemDatabase()
 	defer db.Close()
 	kv := db.RwKV()
 	cfg := StageHistoryCfg(db.RwKV(), t.TempDir())
@@ -67,7 +68,7 @@ func TestIndexGenerator_GenerateIndex_SimpleCase(t *testing.T) {
 func TestIndexGenerator_Truncate(t *testing.T) {
 	log.Root().SetHandler(log.LvlFilterHandler(log.LvlInfo, log.StreamHandler(os.Stderr, log.TerminalFormat(true))))
 	buckets := []string{dbutils.AccountChangeSetBucket, dbutils.StorageChangeSetBucket}
-	kv := ethdb.NewTestKV(t)
+	kv := kv2.NewTestKV(t)
 	cfg := StageHistoryCfg(kv, t.TempDir())
 	for i := range buckets {
 		csbucket := buckets[i]
diff --git a/eth/stagedsync/stage_interhashes_test.go b/eth/stagedsync/stage_interhashes_test.go
index 1c970c2daf..fab55e7e49 100644
--- a/eth/stagedsync/stage_interhashes_test.go
+++ b/eth/stagedsync/stage_interhashes_test.go
@@ -8,6 +8,7 @@ import (
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/core/types/accounts"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/turbo/trie"
 
@@ -28,7 +29,7 @@ func addTestAccount(tx ethdb.Putter, hash common.Hash, balance uint64, incarnati
 }
 
 func TestAccountAndStorageTrie(t *testing.T) {
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 
 	hash1 := common.HexToHash("0xB000000000000000000000000000000000000000000000000000000000000000")
 	assert.Nil(t, addTestAccount(tx, hash1, 3*params.Ether, 0))
@@ -118,7 +119,7 @@ func TestAccountAndStorageTrie(t *testing.T) {
 }
 
 func TestAccountTrieAroundExtensionNode(t *testing.T) {
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 
 	acc := accounts.NewAccount()
 	acc.Balance.SetUint64(1 * params.Ether)
diff --git a/eth/stagedsync/stage_log_index_test.go b/eth/stagedsync/stage_log_index_test.go
index 17eb872c25..e2f75ebf6f 100644
--- a/eth/stagedsync/stage_log_index_test.go
+++ b/eth/stagedsync/stage_log_index_test.go
@@ -9,14 +9,14 @@ import (
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/ethdb/bitmapdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/stretchr/testify/require"
 )
 
 func TestLogIndex(t *testing.T) {
 	require := require.New(t)
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 
 	addr1, addr2 := common.HexToAddress("0x0"), common.HexToAddress("0x376c47978271565f56DEB45495afa69E59c16Ab2")
 	topic1, topic2 := common.HexToHash("0x0"), common.HexToHash("0x1234")
diff --git a/eth/stagedsync/stage_mining_create_block.go b/eth/stagedsync/stage_mining_create_block.go
index e5407550c0..da5c37d6f1 100644
--- a/eth/stagedsync/stage_mining_create_block.go
+++ b/eth/stagedsync/stage_mining_create_block.go
@@ -16,6 +16,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/eth/ethutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
 )
@@ -93,7 +94,7 @@ func SpawnMiningCreateBlockStage(s *StageState, tx ethdb.RwTx, cfg MiningCreateB
 	if err != nil {
 		return err
 	}
-	chain := ChainReader{Cfg: cfg.chainConfig, Db: ethdb.WrapIntoTxDB(tx)}
+	chain := ChainReader{Cfg: cfg.chainConfig, Db: kv.WrapIntoTxDB(tx)}
 	var GetBlocksFromHash = func(hash common.Hash, n int) (blocks []*types.Block) {
 		number := rawdb.ReadHeaderNumber(tx, hash)
 		if number == nil {
diff --git a/eth/stagedsync/stage_mining_finish.go b/eth/stagedsync/stage_mining_finish.go
index 524e8558d0..6dbc4c9137 100644
--- a/eth/stagedsync/stage_mining_finish.go
+++ b/eth/stagedsync/stage_mining_finish.go
@@ -6,6 +6,7 @@ import (
 	"github.com/ledgerwatch/erigon/consensus"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
 )
@@ -73,7 +74,7 @@ func SpawnMiningFinishStage(s *StageState, tx ethdb.RwTx, current *miningBlock,
 		"difficulty", block.Difficulty(),
 	)
 
-	chain := ChainReader{Cfg: cfg.chainConfig, Db: ethdb.WrapIntoTxDB(tx)}
+	chain := ChainReader{Cfg: cfg.chainConfig, Db: kv.WrapIntoTxDB(tx)}
 	if err := cfg.engine.Seal(chain, block, cfg.minedBlocksCh, cfg.sealCancel); err != nil {
 		log.Warn("Block sealing failed", "err", err)
 	}
diff --git a/eth/stagedsync/stage_senders_test.go b/eth/stagedsync/stage_senders_test.go
index 93ed9e1480..6ad6e526b0 100644
--- a/eth/stagedsync/stage_senders_test.go
+++ b/eth/stagedsync/stage_senders_test.go
@@ -9,14 +9,14 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestSenders(t *testing.T) {
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	require := require.New(t)
 
 	var testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291")
diff --git a/eth/stagedsync/stage_tevm.go b/eth/stagedsync/stage_tevm.go
index 94e6ccff77..5952630967 100644
--- a/eth/stagedsync/stage_tevm.go
+++ b/eth/stagedsync/stage_tevm.go
@@ -14,6 +14,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types/accounts"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/metrics"
 	"github.com/ledgerwatch/erigon/params"
@@ -216,7 +217,7 @@ func transpileBatch(logPrefix string, s *StageState, fromBlock uint64, toBlock u
 				defer tx.Rollback()
 			}
 
-			batch = ethdb.NewBatch(tx)
+			batch = kv.NewBatch(tx)
 			// TODO: This creates stacked up deferrals
 			defer batch.Rollback()
 
@@ -274,7 +275,7 @@ func SpawnTranspileStage(s *StageState, tx ethdb.RwTx, toBlock uint64, quit <-ch
 	logPrefix := s.state.LogPrefix()
 	log.Info(fmt.Sprintf("[%s] Contract translation", logPrefix), "from", s.BlockNumber, "to", to)
 
-	batch := ethdb.NewBatch(tx)
+	batch := kv.NewBatch(tx)
 	defer batch.Rollback()
 
 	err := common.Stopped(quit)
diff --git a/eth/stagedsync/state_test.go b/eth/stagedsync/state_test.go
index 464b6e67c8..f8c0c5621d 100644
--- a/eth/stagedsync/state_test.go
+++ b/eth/stagedsync/state_test.go
@@ -7,6 +7,7 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/stretchr/testify/assert"
 )
 
@@ -42,7 +43,7 @@ func TestStateStagesSuccess(t *testing.T) {
 		},
 	}
 	state := NewState(s)
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.NoError(t, err)
 
@@ -85,7 +86,7 @@ func TestStateDisabledStages(t *testing.T) {
 		},
 	}
 	state := NewState(s)
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.NoError(t, err)
 
@@ -131,7 +132,7 @@ func TestStateRepeatedStage(t *testing.T) {
 		},
 	}
 	state := NewState(s)
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.NoError(t, err)
 
@@ -175,7 +176,7 @@ func TestStateErroredStage(t *testing.T) {
 	}
 	state := NewState(s)
 	state.unwindOrder = []*Stage{s[0], s[1], s[2]}
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.Equal(t, expectedErr, err)
 
@@ -262,7 +263,7 @@ func TestStateUnwindSomeStagesBehindUnwindPoint(t *testing.T) {
 	}
 	state := NewState(s)
 	state.unwindOrder = []*Stage{s[0], s[1], s[2], s[3]}
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.NoError(t, err)
 
@@ -363,7 +364,7 @@ func TestStateUnwind(t *testing.T) {
 	}
 	state := NewState(s)
 	state.unwindOrder = []*Stage{s[0], s[1], s[2], s[3]}
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.NoError(t, err)
 
@@ -445,7 +446,7 @@ func TestStateUnwindEmptyUnwinder(t *testing.T) {
 	}
 	state := NewState(s)
 	state.unwindOrder = []*Stage{s[0], s[1], s[2]}
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.NoError(t, err)
 
@@ -501,7 +502,7 @@ func TestStateSyncDoTwice(t *testing.T) {
 	}
 
 	state := NewState(s)
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.NoError(t, err)
 
@@ -562,7 +563,7 @@ func TestStateSyncInterruptRestart(t *testing.T) {
 	}
 
 	state := NewState(s)
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.Equal(t, expectedErr, err)
 
@@ -648,7 +649,7 @@ func TestStateSyncInterruptLongUnwind(t *testing.T) {
 	}
 	state := NewState(s)
 	state.unwindOrder = []*Stage{s[0], s[1], s[2]}
-	db, tx := ethdb.NewTestTx(t)
+	db, tx := kv.NewTestTx(t)
 	err := state.Run(db, tx)
 	assert.Error(t, errInterrupted, err)
 
diff --git a/eth/stagedsync/testutil.go b/eth/stagedsync/testutil.go
index 7f233f8954..3a9d998572 100644
--- a/eth/stagedsync/testutil.go
+++ b/eth/stagedsync/testutil.go
@@ -11,6 +11,7 @@ import (
 	"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/stretchr/testify/assert"
 )
 
@@ -65,7 +66,7 @@ type stateWriterGen func(uint64) state.WriterWithChangeSets
 
 func hashedWriterGen(tx ethdb.RwTx) stateWriterGen {
 	return func(blockNum uint64) state.WriterWithChangeSets {
-		return state.NewDbStateWriter(ethdb.WrapIntoTxDB(tx), blockNum)
+		return state.NewDbStateWriter(kv.WrapIntoTxDB(tx), blockNum)
 	}
 }
 
diff --git a/eth/stagedsync/unwind_test.go b/eth/stagedsync/unwind_test.go
index af15b78ef5..2d3d99772f 100644
--- a/eth/stagedsync/unwind_test.go
+++ b/eth/stagedsync/unwind_test.go
@@ -5,12 +5,12 @@ import (
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/stretchr/testify/assert"
 )
 
 func TestUnwindStackLoadFromDb(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	stack := NewPersistentUnwindStack()
 
@@ -34,7 +34,7 @@ func TestUnwindStackLoadFromDb(t *testing.T) {
 }
 
 func TestUnwindStackLoadFromDbAfterDone(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	stack := NewPersistentUnwindStack()
 
@@ -63,7 +63,7 @@ func TestUnwindStackLoadFromDbAfterDone(t *testing.T) {
 }
 
 func TestUnwindStackLoadFromDbNoDone(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	stack := NewPersistentUnwindStack()
 
@@ -90,7 +90,7 @@ func TestUnwindStackLoadFromDbNoDone(t *testing.T) {
 }
 
 func TestUnwindStackPopAndEmpty(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	stack := NewPersistentUnwindStack()
 
@@ -123,7 +123,7 @@ func TestUnwindStackPopAndEmpty(t *testing.T) {
 }
 
 func TestUnwindOverrideWithLower(t *testing.T) {
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 
 	stack := NewPersistentUnwindStack()
 
@@ -146,7 +146,7 @@ func TestUnwindOverrideWithLower(t *testing.T) {
 }
 
 func TestUnwindOverrideWithHigher(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	stack := NewPersistentUnwindStack()
 
@@ -169,7 +169,7 @@ func TestUnwindOverrideWithHigher(t *testing.T) {
 }
 
 func TestUnwindOverrideWithTheSame(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 
 	stack := NewPersistentUnwindStack()
 
diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go
index 0cfdb2067a..af89b561ca 100644
--- a/eth/tracers/tracers_test.go
+++ b/eth/tracers/tracers_test.go
@@ -36,7 +36,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/crypto"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/rlp"
 	"github.com/ledgerwatch/erigon/tests"
@@ -176,7 +176,7 @@ func TestPrestateTracerCreate2(t *testing.T) {
 		Code:    []byte{},
 		Balance: big.NewInt(500000000000000),
 	}
-	statedb, _ := tests.MakePreState(ctx, ethdb.NewTestDB(t), alloc, context.BlockNumber)
+	statedb, _ := tests.MakePreState(ctx, kv.NewTestDB(t), alloc, context.BlockNumber)
 
 	// Create the tracer, the EVM environment and run it
 	tracer, err := New("prestateTracer", txContext)
@@ -254,7 +254,7 @@ func TestCallTracer(t *testing.T) {
 				GasLimit:    uint64(test.Context.GasLimit),
 				CheckTEVM:   func(common.Hash) (bool, error) { return false, nil },
 			}
-			statedb, _ := tests.MakePreState(ctx, ethdb.NewTestDB(t), test.Genesis.Alloc, uint64(test.Context.Number))
+			statedb, _ := tests.MakePreState(ctx, kv.NewTestDB(t), test.Genesis.Alloc, uint64(test.Context.Number))
 
 			// Create the tracer, the EVM environment and run it
 			tracer, err := New("callTracer", txContext)
diff --git a/ethdb/Readme.md b/ethdb/Readme.md
index 6d939a6a3d..84364396eb 100644
--- a/ethdb/Readme.md
+++ b/ethdb/Readme.md
@@ -100,7 +100,7 @@ if err != nil {
 - No internal copies/allocations. It means: 1. app must copy keys/values before put to database. 2. Data after read from db - valid only during current transaction - copy it if plan use data after transaction Commit/Rollback.
 - Methods .Bucket() and .Cursor(), can’t return nil, can't return error.
 - Bucket and Cursor - are interfaces - means different classes can satisfy it: for example `MdbxCursor` and `MdbxDupSortCursor` classes satisfy it. 
-  If your are not familiar with "DupSort" concept, please read [dupsort.md](./../docs/programmers_guide/dupsort.md) first.
+  If your are not familiar with "DupSort" concept, please read [dupsort.md](../docs/programmers_guide/dupsort.md) first.
 
 
 - If Cursor returns err!=nil then key SHOULD be != nil (can be []byte{} for example). 
diff --git a/ethdb/interface.go b/ethdb/db_interface.go
similarity index 97%
rename from ethdb/interface.go
rename to ethdb/db_interface.go
index df9fa6cace..ef924792cd 100644
--- a/ethdb/interface.go
+++ b/ethdb/db_interface.go
@@ -159,7 +159,7 @@ type BucketsMigrator interface {
 	DropBuckets(buckets ...string) error      // drops them, use of them after drop will panic
 }
 
-func getOneWrapper(dat []byte, err error) ([]byte, error) {
+func GetOneWrapper(dat []byte, err error) ([]byte, error) {
 	if err != nil {
 		return nil, err
 	}
@@ -169,4 +169,4 @@ func getOneWrapper(dat []byte, err error) ([]byte, error) {
 	return dat, nil
 }
 
-var errNotSupported = errors.New("not supported")
+var ErrNotSupported = errors.New("not supported")
diff --git a/ethdb/database_test.go b/ethdb/kv/database_test.go
similarity index 93%
rename from ethdb/database_test.go
rename to ethdb/kv/database_test.go
index 524618ee57..486b26b467 100644
--- a/ethdb/database_test.go
+++ b/ethdb/kv/database_test.go
@@ -16,7 +16,7 @@
 
 // +build !js
 
-package ethdb
+package kv
 
 import (
 	"bytes"
@@ -29,6 +29,7 @@ import (
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
+	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -143,7 +144,7 @@ func TestParallelPutGet(t *testing.T) {
 	for i := 0; i < n; i++ {
 		go func(key string) {
 			defer pending.Done()
-			_ = db.Update(context.Background(), func(tx RwTx) error {
+			_ = db.Update(context.Background(), func(tx ethdb.RwTx) error {
 				err := tx.Put(testBucket, []byte(key), []byte("v"+key))
 				if err != nil {
 					panic("put failed: " + err.Error())
@@ -158,7 +159,7 @@ func TestParallelPutGet(t *testing.T) {
 	for i := 0; i < n; i++ {
 		go func(key string) {
 			defer pending.Done()
-			_ = db.View(context.Background(), func(tx Tx) error {
+			_ = db.View(context.Background(), func(tx ethdb.Tx) error {
 				data, err := tx.GetOne(testBucket, []byte(key))
 				if err != nil {
 					panic("get failed: " + err.Error())
@@ -176,7 +177,7 @@ func TestParallelPutGet(t *testing.T) {
 	for i := 0; i < n; i++ {
 		go func(key string) {
 			defer pending.Done()
-			_ = db.Update(context.Background(), func(tx RwTx) error {
+			_ = db.Update(context.Background(), func(tx ethdb.RwTx) error {
 				err := tx.Delete(testBucket, []byte(key), nil)
 				if err != nil {
 					panic("delete failed: " + err.Error())
@@ -191,7 +192,7 @@ func TestParallelPutGet(t *testing.T) {
 	for i := 0; i < n; i++ {
 		go func(key string) {
 			defer pending.Done()
-			_ = db.Update(context.Background(), func(tx RwTx) error {
+			_ = db.Update(context.Background(), func(tx ethdb.RwTx) error {
 				v, err := tx.GetOne(testBucket, []byte(key))
 				if err != nil {
 					panic(err)
@@ -236,7 +237,7 @@ func TestWalk(t *testing.T) {
 		panic(err)
 	}
 	defer c.Close()
-	err = Walk(c, startKey, fixedBits, func(key, val []byte) (bool, error) {
+	err = ethdb.Walk(c, startKey, fixedBits, func(key, val []byte) (bool, error) {
 		gotKeys = append(gotKeys, common.CopyBytes(key))
 		return true, nil
 	})
diff --git a/ethdb/kv_abstract_test.go b/ethdb/kv/kv_abstract_test.go
similarity index 95%
rename from ethdb/kv_abstract_test.go
rename to ethdb/kv/kv_abstract_test.go
index 660695551b..d153970a04 100644
--- a/ethdb/kv_abstract_test.go
+++ b/ethdb/kv/kv_abstract_test.go
@@ -1,4 +1,4 @@
-package ethdb_test
+package kv_test
 
 import (
 	"context"
@@ -9,6 +9,7 @@ import (
 
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/ethdb/remote/remotedbserver"
 	"github.com/ledgerwatch/erigon/gointerfaces"
 	"github.com/ledgerwatch/erigon/gointerfaces/remote"
@@ -117,7 +118,7 @@ func TestManagedTx(t *testing.T) {
 		db := db
 		msg := fmt.Sprintf("%T", db)
 		switch db.(type) {
-		case *ethdb.RemoteKV:
+		case *kv.RemoteKV:
 		default:
 			continue
 		}
@@ -139,7 +140,7 @@ func TestRemoteKvVersion(t *testing.T) {
 	f := func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return defaultBuckets
 	}
-	writeDb := ethdb.NewMDBX().InMem().WithBucketsConfig(f).MustOpen()
+	writeDb := kv.NewMDBX().InMem().WithBucketsConfig(f).MustOpen()
 	defer writeDb.Close()
 	conn := bufconn.Listen(1024 * 1024)
 	grpcServer := grpc.NewServer()
@@ -153,7 +154,7 @@ func TestRemoteKvVersion(t *testing.T) {
 	// Different Major versions
 	v1 := v
 	v1.Major++
-	a, err := ethdb.NewRemote(v1).InMem(conn).Open("", "", "")
+	a, err := kv.NewRemote(v1).InMem(conn).Open("", "", "")
 	if err != nil {
 		t.Fatalf("%v", err)
 	}
@@ -161,7 +162,7 @@ func TestRemoteKvVersion(t *testing.T) {
 	// Different Minor versions
 	v2 := v
 	v2.Minor++
-	_, err = ethdb.NewRemote(v2).InMem(conn).Open("", "", "")
+	_, err = kv.NewRemote(v2).InMem(conn).Open("", "", "")
 	if err != nil {
 		t.Fatalf("%v", err)
 	}
@@ -169,17 +170,17 @@ func TestRemoteKvVersion(t *testing.T) {
 	// Different Patch versions
 	v3 := v
 	v3.Patch++
-	_, err = ethdb.NewRemote(v3).InMem(conn).Open("", "", "")
+	_, err = kv.NewRemote(v3).InMem(conn).Open("", "", "")
 	if err != nil {
 		t.Fatalf("%v", err)
 	}
 	require.False(t, a.EnsureVersionCompatibility())
 }
 
-func setupDatabases(t *testing.T, f ethdb.BucketConfigsFunc) (writeDBs []ethdb.RwKV, readDBs []ethdb.RwKV) {
+func setupDatabases(t *testing.T, f kv.BucketConfigsFunc) (writeDBs []ethdb.RwKV, readDBs []ethdb.RwKV) {
 	writeDBs = []ethdb.RwKV{
-		ethdb.NewMDBX().InMem().WithBucketsConfig(f).MustOpen(),
-		ethdb.NewMDBX().InMem().WithBucketsConfig(f).MustOpen(), // for remote db
+		kv.NewMDBX().InMem().WithBucketsConfig(f).MustOpen(),
+		kv.NewMDBX().InMem().WithBucketsConfig(f).MustOpen(), // for remote db
 	}
 
 	conn := bufconn.Listen(1024 * 1024)
@@ -192,7 +193,7 @@ func setupDatabases(t *testing.T, f ethdb.BucketConfigsFunc) (writeDBs []ethdb.R
 		}
 	}()
 	v := gointerfaces.VersionFromProto(remotedbserver.KvServiceAPIVersion)
-	rdb := ethdb.NewRemote(v).InMem(conn).MustOpen()
+	rdb := kv.NewRemote(v).InMem(conn).MustOpen()
 	readDBs = []ethdb.RwKV{
 		writeDBs[0],
 		writeDBs[1],
diff --git a/ethdb/kv_mdbx.go b/ethdb/kv/kv_mdbx.go
similarity index 91%
rename from ethdb/kv_mdbx.go
rename to ethdb/kv/kv_mdbx.go
index 5fa9a3e4a9..c430eba540 100644
--- a/ethdb/kv_mdbx.go
+++ b/ethdb/kv/kv_mdbx.go
@@ -1,10 +1,11 @@
-package ethdb
+package kv
 
 import (
 	"bytes"
 	"context"
 	"encoding/binary"
 	"fmt"
+	"io/ioutil"
 	"os"
 	"path"
 	"runtime"
@@ -17,6 +18,7 @@ import (
 	"github.com/c2h5oh/datasize"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/common/debug"
+	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/ethdb/mdbx"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/metrics"
@@ -39,12 +41,20 @@ type MdbxOpts struct {
 	bucketsCfg BucketConfigsFunc
 	path       string
 	inMem      bool
-	label      Label // marker to distinct db instances - one process may open many databases. for example to collect metrics of only 1 database
-	verbosity  DBVerbosityLvl
+	label      ethdb.Label // marker to distinct db instances - one process may open many databases. for example to collect metrics of only 1 database
+	verbosity  ethdb.DBVerbosityLvl
 	mapSize    datasize.ByteSize
 	flags      uint
 }
 
+func testKVPath() string {
+	dir, err := ioutil.TempDir(os.TempDir(), "erigon-test-db")
+	if err != nil {
+		panic(err)
+	}
+	return dir
+}
+
 func NewMDBX() MdbxOpts {
 	return MdbxOpts{
 		bucketsCfg: DefaultBucketConfigs,
@@ -52,7 +62,7 @@ func NewMDBX() MdbxOpts {
 	}
 }
 
-func (opts MdbxOpts) Label(label Label) MdbxOpts {
+func (opts MdbxOpts) Label(label ethdb.Label) MdbxOpts {
 	opts.label = label
 	return opts
 }
@@ -86,7 +96,7 @@ func (opts MdbxOpts) Readonly() MdbxOpts {
 	return opts
 }
 
-func (opts MdbxOpts) DBVerbosity(v DBVerbosityLvl) MdbxOpts {
+func (opts MdbxOpts) DBVerbosity(v ethdb.DBVerbosityLvl) MdbxOpts {
 	opts.verbosity = v
 	return opts
 }
@@ -101,7 +111,7 @@ func (opts MdbxOpts) WithBucketsConfig(f BucketConfigsFunc) MdbxOpts {
 	return opts
 }
 
-func (opts MdbxOpts) Open() (RwKV, error) {
+func (opts MdbxOpts) Open() (ethdb.RwKV, error) {
 	if expectMdbxVersionMajor != mdbx.Major || expectMdbxVersionMinor != mdbx.Minor {
 		return nil, fmt.Errorf("unexpected mdbx version: %d.%d, expected %d %d. Please run 'make mdbx'", mdbx.Major, mdbx.Minor, expectMdbxVersionMajor, expectMdbxVersionMinor)
 	}
@@ -127,7 +137,7 @@ func (opts MdbxOpts) Open() (RwKV, error) {
 	if err = env.SetOption(mdbx.OptMaxDB, 100); err != nil {
 		return nil, err
 	}
-	if err = env.SetOption(mdbx.OptMaxReaders, ReadersLimit); err != nil {
+	if err = env.SetOption(mdbx.OptMaxReaders, ethdb.ReadersLimit); err != nil {
 		return nil, err
 	}
 
@@ -220,7 +230,7 @@ func (opts MdbxOpts) Open() (RwKV, error) {
 			if db.buckets[name].IsDeprecated {
 				continue
 			}
-			if err = tx.(BucketMigrator).CreateBucket(name); err != nil {
+			if err = tx.(ethdb.BucketMigrator).CreateBucket(name); err != nil {
 				return nil, err
 			}
 		}
@@ -229,12 +239,12 @@ func (opts MdbxOpts) Open() (RwKV, error) {
 			return nil, err
 		}
 	} else {
-		if err := db.Update(context.Background(), func(tx RwTx) error {
+		if err := db.Update(context.Background(), func(tx ethdb.RwTx) error {
 			for _, name := range buckets {
 				if db.buckets[name].IsDeprecated {
 					continue
 				}
-				if err := tx.(BucketMigrator).CreateBucket(name); err != nil {
+				if err := tx.(ethdb.BucketMigrator).CreateBucket(name); err != nil {
 					return err
 				}
 			}
@@ -286,7 +296,7 @@ func (opts MdbxOpts) Open() (RwKV, error) {
 	return db, nil
 }
 
-func (opts MdbxOpts) MustOpen() RwKV {
+func (opts MdbxOpts) MustOpen() ethdb.RwKV {
 	db, err := opts.Open()
 	if err != nil {
 		panic(fmt.Errorf("fail to open mdbx: %w", err))
@@ -333,25 +343,25 @@ func (db *MdbxKV) CollectMetrics() {
 	if !metrics.Enabled {
 		return
 	}
-	if db.opts.label != Chain {
+	if db.opts.label != ethdb.Chain {
 		return
 	}
 	info, err := db.env.Info()
 	if err != nil {
 		return // ignore error for metrics collection
 	}
-	dbSize.Update(int64(info.Geo.Current))
-	dbPgopsNewly.Update(int64(info.PageOps.Newly))
-	dbPgopsCow.Update(int64(info.PageOps.Cow))
-	dbPgopsClone.Update(int64(info.PageOps.Clone))
-	dbPgopsSplit.Update(int64(info.PageOps.Split))
-	dbPgopsMerge.Update(int64(info.PageOps.Merge))
-	dbPgopsSpill.Update(int64(info.PageOps.Spill))
-	dbPgopsUnspill.Update(int64(info.PageOps.Unspill))
-	dbPgopsWops.Update(int64(info.PageOps.Wops))
+	ethdb.DbSize.Update(int64(info.Geo.Current))
+	ethdb.DbPgopsNewly.Update(int64(info.PageOps.Newly))
+	ethdb.DbPgopsCow.Update(int64(info.PageOps.Cow))
+	ethdb.DbPgopsClone.Update(int64(info.PageOps.Clone))
+	ethdb.DbPgopsSplit.Update(int64(info.PageOps.Split))
+	ethdb.DbPgopsMerge.Update(int64(info.PageOps.Merge))
+	ethdb.DbPgopsSpill.Update(int64(info.PageOps.Spill))
+	ethdb.DbPgopsUnspill.Update(int64(info.PageOps.Unspill))
+	ethdb.DbPgopsWops.Update(int64(info.PageOps.Wops))
 }
 
-func (db *MdbxKV) BeginRo(_ context.Context) (txn Tx, err error) {
+func (db *MdbxKV) BeginRo(_ context.Context) (txn ethdb.Tx, err error) {
 	if db.env == nil {
 		return nil, fmt.Errorf("db closed")
 	}
@@ -373,7 +383,7 @@ func (db *MdbxKV) BeginRo(_ context.Context) (txn Tx, err error) {
 	}, nil
 }
 
-func (db *MdbxKV) BeginRw(_ context.Context) (txn RwTx, err error) {
+func (db *MdbxKV) BeginRw(_ context.Context) (txn ethdb.RwTx, err error) {
 	if db.env == nil {
 		return nil, fmt.Errorf("db closed")
 	}
@@ -400,7 +410,7 @@ type MdbxTx struct {
 	tx               *mdbx.Txn
 	db               *MdbxKV
 	cursors          map[uint64]*mdbx.Cursor
-	statelessCursors map[string]Cursor
+	statelessCursors map[string]ethdb.Cursor
 	readOnly         bool
 	cursorID         uint64
 }
@@ -491,7 +501,7 @@ func (tx *MdbxTx) CollectMetrics() {
 	if !metrics.Enabled {
 		return
 	}
-	if tx.db.opts.label != Chain {
+	if tx.db.opts.label != ethdb.Chain {
 		return
 	}
 	txInfo, err := tx.tx.Info(true)
@@ -499,25 +509,25 @@ func (tx *MdbxTx) CollectMetrics() {
 		return
 	}
 
-	txDirty.Update(int64(txInfo.SpaceDirty))
-	txLimit.Update(int64(tx.db.txSize))
-	txSpill.Update(int64(txInfo.Spill))
-	txUnspill.Update(int64(txInfo.Unspill))
+	ethdb.TxDirty.Update(int64(txInfo.SpaceDirty))
+	ethdb.TxLimit.Update(int64(tx.db.txSize))
+	ethdb.TxSpill.Update(int64(txInfo.Spill))
+	ethdb.TxUnspill.Update(int64(txInfo.Unspill))
 
 	gc, err := tx.BucketStat("gc")
 	if err != nil {
 		return
 	}
-	gcLeafMetric.Update(int64(gc.LeafPages))
-	gcOverflowMetric.Update(int64(gc.OverflowPages))
-	gcPagesMetric.Update(int64((gc.LeafPages + gc.OverflowPages) * tx.db.pageSize / 8))
+	ethdb.GcLeafMetric.Update(int64(gc.LeafPages))
+	ethdb.GcOverflowMetric.Update(int64(gc.OverflowPages))
+	ethdb.GcPagesMetric.Update(int64((gc.LeafPages + gc.OverflowPages) * tx.db.pageSize / 8))
 
 	state, err := tx.BucketStat(dbutils.PlainStateBucket)
 	if err != nil {
 		return
 	}
-	stateLeafMetric.Update(int64(state.LeafPages))
-	stateBranchesMetric.Update(int64(state.BranchPages))
+	ethdb.StateLeafMetric.Update(int64(state.LeafPages))
+	ethdb.StateBranchesMetric.Update(int64(state.BranchPages))
 }
 
 func (tx *MdbxTx) Comparator(bucket string) dbutils.CmpFunc {
@@ -546,7 +556,7 @@ func (tx *MdbxTx) ExistingBuckets() ([]string, error) {
 	return res, nil
 }
 
-func (db *MdbxKV) View(ctx context.Context, f func(tx Tx) error) (err error) {
+func (db *MdbxKV) View(ctx context.Context, f func(tx ethdb.Tx) error) (err error) {
 	if db.env == nil {
 		return fmt.Errorf("db closed")
 	}
@@ -563,7 +573,7 @@ func (db *MdbxKV) View(ctx context.Context, f func(tx Tx) error) (err error) {
 	return f(tx)
 }
 
-func (db *MdbxKV) Update(ctx context.Context, f func(tx RwTx) error) (err error) {
+func (db *MdbxKV) Update(ctx context.Context, f func(tx ethdb.RwTx) error) (err error) {
 	if db.env == nil {
 		return fmt.Errorf("db closed")
 	}
@@ -724,7 +734,7 @@ func (tx *MdbxTx) ClearBucket(bucket string) error {
 
 func (tx *MdbxTx) DropBucket(bucket string) error {
 	if cfg, ok := tx.db.buckets[bucket]; !(ok && cfg.IsDeprecated) {
-		return fmt.Errorf("%w, bucket: %s", ErrAttemptToDeleteNonDeprecatedBucket, bucket)
+		return fmt.Errorf("%w, bucket: %s", ethdb.ErrAttemptToDeleteNonDeprecatedBucket, bucket)
 	}
 
 	return tx.dropEvenIfBucketIsNotDeprecated(bucket)
@@ -767,14 +777,14 @@ func (tx *MdbxTx) Commit() error {
 		return err
 	}
 
-	if tx.db.opts.label == Chain {
-		dbCommitPreparation.Update(latency.Preparation)
-		dbCommitGc.Update(latency.GC)
-		dbCommitAudit.Update(latency.Audit)
-		dbCommitWrite.Update(latency.Write)
-		dbCommitSync.Update(latency.Sync)
-		dbCommitEnding.Update(latency.Ending)
-		dbCommitBigBatchTimer.Update(latency.Whole)
+	if tx.db.opts.label == ethdb.Chain {
+		ethdb.DbCommitPreparation.Update(latency.Preparation)
+		ethdb.DbCommitGc.Update(latency.GC)
+		ethdb.DbCommitAudit.Update(latency.Audit)
+		ethdb.DbCommitWrite.Update(latency.Write)
+		ethdb.DbCommitSync.Update(latency.Sync)
+		ethdb.DbCommitEnding.Update(latency.Ending)
+		ethdb.DbCommitBigBatchTimer.Update(latency.Whole)
 	}
 
 	if latency.Whole > slowTx {
@@ -854,9 +864,9 @@ func (tx *MdbxTx) closeCursors() {
 	tx.statelessCursors = nil
 }
 
-func (tx *MdbxTx) statelessCursor(bucket string) (RwCursor, error) {
+func (tx *MdbxTx) statelessCursor(bucket string) (ethdb.RwCursor, error) {
 	if tx.statelessCursors == nil {
-		tx.statelessCursors = make(map[string]Cursor)
+		tx.statelessCursors = make(map[string]ethdb.Cursor)
 	}
 	c, ok := tx.statelessCursors[bucket]
 	if !ok {
@@ -867,7 +877,7 @@ func (tx *MdbxTx) statelessCursor(bucket string) (RwCursor, error) {
 		}
 		tx.statelessCursors[bucket] = c
 	}
-	return c.(RwCursor), nil
+	return c.(ethdb.RwCursor), nil
 }
 
 func (tx *MdbxTx) Put(bucket string, k, v []byte) error {
@@ -986,7 +996,7 @@ func (tx *MdbxTx) BucketStat(name string) (*mdbx.Stat, error) {
 	return st, nil
 }
 
-func (tx *MdbxTx) RwCursor(bucket string) (RwCursor, error) {
+func (tx *MdbxTx) RwCursor(bucket string) (ethdb.RwCursor, error) {
 	b := tx.db.buckets[bucket]
 	if b.AutoDupSortKeysConversion {
 		return tx.stdCursor(bucket)
@@ -999,11 +1009,11 @@ func (tx *MdbxTx) RwCursor(bucket string) (RwCursor, error) {
 	return tx.stdCursor(bucket)
 }
 
-func (tx *MdbxTx) Cursor(bucket string) (Cursor, error) {
+func (tx *MdbxTx) Cursor(bucket string) (ethdb.Cursor, error) {
 	return tx.RwCursor(bucket)
 }
 
-func (tx *MdbxTx) stdCursor(bucket string) (RwCursor, error) {
+func (tx *MdbxTx) stdCursor(bucket string) (ethdb.RwCursor, error) {
 	b := tx.db.buckets[bucket]
 	c := &MdbxCursor{bucketName: bucket, tx: tx, bucketCfg: b, dbi: mdbx.DBI(tx.db.buckets[bucket].DBI), id: tx.cursorID}
 	tx.cursorID++
@@ -1022,7 +1032,7 @@ func (tx *MdbxTx) stdCursor(bucket string) (RwCursor, error) {
 	return c, nil
 }
 
-func (tx *MdbxTx) RwCursorDupSort(bucket string) (RwCursorDupSort, error) {
+func (tx *MdbxTx) RwCursorDupSort(bucket string) (ethdb.RwCursorDupSort, error) {
 	basicCursor, err := tx.stdCursor(bucket)
 	if err != nil {
 		return nil, err
@@ -1030,7 +1040,7 @@ func (tx *MdbxTx) RwCursorDupSort(bucket string) (RwCursorDupSort, error) {
 	return &MdbxDupSortCursor{MdbxCursor: basicCursor.(*MdbxCursor)}, nil
 }
 
-func (tx *MdbxTx) CursorDupSort(bucket string) (CursorDupSort, error) {
+func (tx *MdbxTx) CursorDupSort(bucket string) (ethdb.CursorDupSort, error) {
 	return tx.RwCursorDupSort(bucket)
 }
 
diff --git a/ethdb/kv_migrator_test.go b/ethdb/kv/kv_migrator_test.go
similarity index 92%
rename from ethdb/kv_migrator_test.go
rename to ethdb/kv/kv_migrator_test.go
index eae2f96a71..ea24ada201 100644
--- a/ethdb/kv_migrator_test.go
+++ b/ethdb/kv/kv_migrator_test.go
@@ -1,4 +1,4 @@
-package ethdb
+package kv
 
 import (
 	"context"
@@ -6,6 +6,7 @@ import (
 	"testing"
 
 	"github.com/ledgerwatch/erigon/common/dbutils"
+	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/stretchr/testify/require"
 )
 
@@ -21,7 +22,7 @@ func TestBucketCRUD(t *testing.T) {
 
 	normalBucket := dbutils.Buckets[15]
 	deprecatedBucket := dbutils.DeprecatedBuckets[0]
-	migrator, ok := tx.(BucketMigrator)
+	migrator, ok := tx.(ethdb.BucketMigrator)
 	if !ok {
 		return
 	}
@@ -42,7 +43,7 @@ func TestBucketCRUD(t *testing.T) {
 	}
 
 	require.True(migrator.ExistsBucket(normalBucket))
-	require.True(errors.Is(migrator.DropBucket(normalBucket), ErrAttemptToDeleteNonDeprecatedBucket))
+	require.True(errors.Is(migrator.DropBucket(normalBucket), ethdb.ErrAttemptToDeleteNonDeprecatedBucket))
 
 	require.False(migrator.ExistsBucket(deprecatedBucket))
 	require.NoError(migrator.CreateBucket(deprecatedBucket))
diff --git a/ethdb/kv_remote.go b/ethdb/kv/kv_remote.go
similarity index 96%
rename from ethdb/kv_remote.go
rename to ethdb/kv/kv_remote.go
index b5d0b027da..4c96c292cd 100644
--- a/ethdb/kv_remote.go
+++ b/ethdb/kv/kv_remote.go
@@ -1,4 +1,4 @@
-package ethdb
+package kv
 
 import (
 	"bytes"
@@ -15,6 +15,7 @@ import (
 
 	"github.com/c2h5oh/datasize"
 	"github.com/ledgerwatch/erigon/common/dbutils"
+	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/gointerfaces"
 	"github.com/ledgerwatch/erigon/gointerfaces/remote"
 	"github.com/ledgerwatch/erigon/log"
@@ -48,7 +49,7 @@ type remoteTx struct {
 	streamCancelFn     context.CancelFunc
 	db                 *RemoteKV
 	cursors            []*remoteCursor
-	statelessCursors   map[string]Cursor
+	statelessCursors   map[string]ethdb.Cursor
 	streamingRequested bool
 }
 
@@ -162,7 +163,7 @@ func (opts remoteOpts) Open(certFile, keyFile, caCert string) (*RemoteKV, error)
 	return db, nil
 }
 
-func (opts remoteOpts) MustOpen() RwKV {
+func (opts remoteOpts) MustOpen() ethdb.RwKV {
 	db, err := opts.Open("", "", "")
 	if err != nil {
 		panic(err)
@@ -214,7 +215,7 @@ func (db *RemoteKV) Close() {
 
 func (db *RemoteKV) CollectMetrics() {}
 
-func (db *RemoteKV) BeginRo(ctx context.Context) (Tx, error) {
+func (db *RemoteKV) BeginRo(ctx context.Context) (ethdb.Tx, error) {
 	streamCtx, streamCancelFn := context.WithCancel(ctx) // We create child context for the stream so we can cancel it to prevent leak
 	stream, err := db.remoteKV.Tx(streamCtx)
 	if err != nil {
@@ -224,11 +225,11 @@ func (db *RemoteKV) BeginRo(ctx context.Context) (Tx, error) {
 	return &remoteTx{ctx: ctx, db: db, stream: stream, streamCancelFn: streamCancelFn}, nil
 }
 
-func (db *RemoteKV) BeginRw(ctx context.Context) (RwTx, error) {
+func (db *RemoteKV) BeginRw(ctx context.Context) (ethdb.RwTx, error) {
 	return nil, fmt.Errorf("remote db provider doesn't support .BeginRw method")
 }
 
-func (db *RemoteKV) View(ctx context.Context, f func(tx Tx) error) (err error) {
+func (db *RemoteKV) View(ctx context.Context, f func(tx ethdb.Tx) error) (err error) {
 	tx, err := db.BeginRo(ctx)
 	if err != nil {
 		return err
@@ -238,7 +239,7 @@ func (db *RemoteKV) View(ctx context.Context, f func(tx Tx) error) (err error) {
 	return f(tx)
 }
 
-func (db *RemoteKV) Update(ctx context.Context, f func(tx RwTx) error) (err error) {
+func (db *RemoteKV) Update(ctx context.Context, f func(tx ethdb.RwTx) error) (err error) {
 	return fmt.Errorf("remote db provider doesn't support .Update method")
 }
 
@@ -266,9 +267,9 @@ func (tx *remoteTx) Rollback() {
 	tx.closeGrpcStream()
 }
 
-func (tx *remoteTx) statelessCursor(bucket string) (Cursor, error) {
+func (tx *remoteTx) statelessCursor(bucket string) (ethdb.Cursor, error) {
 	if tx.statelessCursors == nil {
-		tx.statelessCursors = make(map[string]Cursor)
+		tx.statelessCursors = make(map[string]ethdb.Cursor)
 	}
 	c, ok := tx.statelessCursors[bucket]
 	if !ok {
@@ -371,7 +372,7 @@ func (c *remoteCursor) Prev() ([]byte, []byte, error) {
 	return c.prev()
 }
 
-func (tx *remoteTx) Cursor(bucket string) (Cursor, error) {
+func (tx *remoteTx) Cursor(bucket string) (ethdb.Cursor, error) {
 	b := tx.db.buckets[bucket]
 	c := &remoteCursor{tx: tx, ctx: tx.ctx, bucketName: bucket, bucketCfg: b, stream: tx.stream}
 	tx.cursors = append(tx.cursors, c)
@@ -608,7 +609,7 @@ func (c *remoteCursor) Close() {
 	}
 }
 
-func (tx *remoteTx) CursorDupSort(bucket string) (CursorDupSort, error) {
+func (tx *remoteTx) CursorDupSort(bucket string) (ethdb.CursorDupSort, error) {
 	c, err := tx.Cursor(bucket)
 	if err != nil {
 		return nil, err
diff --git a/ethdb/kv_snapshot.go b/ethdb/kv/kv_snapshot.go
similarity index 85%
rename from ethdb/kv_snapshot.go
rename to ethdb/kv/kv_snapshot.go
index c6a6a155f1..25e12400b8 100644
--- a/ethdb/kv_snapshot.go
+++ b/ethdb/kv/kv_snapshot.go
@@ -1,4 +1,4 @@
-package ethdb
+package kv
 
 import (
 	"bytes"
@@ -10,24 +10,25 @@ import (
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
+	"github.com/ledgerwatch/erigon/ethdb"
 )
 
 var (
-	_ RwKV           = &SnapshotKV{}
-	_ RoKV           = &SnapshotKV{}
-	_ Tx             = &snTX{}
-	_ BucketMigrator = &snTX{}
-	_ RwCursor       = &snCursor{}
-	_ Cursor         = &snCursor{}
+	_ ethdb.RwKV           = &SnapshotKV{}
+	_ ethdb.RoKV           = &SnapshotKV{}
+	_ ethdb.Tx             = &snTX{}
+	_ ethdb.BucketMigrator = &snTX{}
+	_ ethdb.RwCursor       = &snCursor{}
+	_ ethdb.Cursor         = &snCursor{}
 )
 
 type SnapshotUpdater interface {
-	UpdateSnapshots(buckets []string, snapshotKV RoKV, done chan struct{})
-	SnapshotKV(bucket string) RoKV
+	UpdateSnapshots(buckets []string, snapshotKV ethdb.RoKV, done chan struct{})
+	SnapshotKV(bucket string) ethdb.RoKV
 }
 
 type WriteDB interface {
-	WriteDB() RwKV
+	WriteDB() ethdb.RwKV
 }
 
 func NewSnapshotKV() snapshotOpts {
@@ -35,15 +36,15 @@ func NewSnapshotKV() snapshotOpts {
 }
 
 type snapshotData struct {
-	snapshot RoKV
+	snapshot ethdb.RoKV
 	buckets  []string
 }
 type snapshotOpts struct {
-	db        RwKV
+	db        ethdb.RwKV
 	snapshots []snapshotData
 }
 
-func (opts snapshotOpts) SnapshotDB(buckets []string, db RoKV) snapshotOpts {
+func (opts snapshotOpts) SnapshotDB(buckets []string, db ethdb.RoKV) snapshotOpts {
 	opts.snapshots = append(opts.snapshots, snapshotData{
 		buckets:  buckets,
 		snapshot: db,
@@ -51,7 +52,7 @@ func (opts snapshotOpts) SnapshotDB(buckets []string, db RoKV) snapshotOpts {
 	return opts
 }
 
-func (opts snapshotOpts) DB(db RwKV) snapshotOpts {
+func (opts snapshotOpts) DB(db ethdb.RwKV) snapshotOpts {
 	opts.db = db
 	return opts
 }
@@ -70,12 +71,12 @@ func (opts snapshotOpts) Open() *SnapshotKV {
 }
 
 type SnapshotKV struct {
-	db        RwKV
+	db        ethdb.RwKV
 	snapshots map[string]snapshotData
 	mtx       sync.RWMutex
 }
 
-func (s *SnapshotKV) View(ctx context.Context, f func(tx Tx) error) error {
+func (s *SnapshotKV) View(ctx context.Context, f func(tx ethdb.Tx) error) error {
 	snTX, err := s.BeginRo(ctx)
 	if err != nil {
 		return err
@@ -84,7 +85,7 @@ func (s *SnapshotKV) View(ctx context.Context, f func(tx Tx) error) error {
 	return f(snTX)
 }
 
-func (s *SnapshotKV) Update(ctx context.Context, f func(tx RwTx) error) error {
+func (s *SnapshotKV) Update(ctx context.Context, f func(tx ethdb.RwTx) error) error {
 	tx, err := s.BeginRw(ctx)
 	if err != nil {
 		return err
@@ -105,13 +106,13 @@ func (s *SnapshotKV) Close() {
 	}
 }
 
-func (s *SnapshotKV) UpdateSnapshots(buckets []string, snapshotKV RoKV, done chan struct{}) {
+func (s *SnapshotKV) UpdateSnapshots(buckets []string, snapshotKV ethdb.RoKV, done chan struct{}) {
 	sd := snapshotData{
 		buckets:  buckets,
 		snapshot: snapshotKV,
 	}
 
-	toClose := []RoKV{}
+	toClose := []ethdb.RoKV{}
 	var (
 		snData snapshotData
 		ok     bool
@@ -142,10 +143,10 @@ func (s *SnapshotKV) UpdateSnapshots(buckets []string, snapshotKV RoKV, done cha
 	}()
 }
 
-func (s *SnapshotKV) WriteDB() RwKV {
+func (s *SnapshotKV) WriteDB() ethdb.RwKV {
 	return s.db
 }
-func (s *SnapshotKV) SnapshotKV(bucket string) RoKV {
+func (s *SnapshotKV) SnapshotKV(bucket string) ethdb.RoKV {
 	return s.snapshots[bucket].snapshot
 }
 
@@ -153,7 +154,7 @@ func (s *SnapshotKV) CollectMetrics() {
 	s.db.CollectMetrics()
 }
 
-func (s *SnapshotKV) BeginRo(ctx context.Context) (Tx, error) {
+func (s *SnapshotKV) BeginRo(ctx context.Context) (ethdb.Tx, error) {
 	dbTx, err := s.db.BeginRo(ctx)
 	if err != nil {
 		return nil, err
@@ -161,7 +162,7 @@ func (s *SnapshotKV) BeginRo(ctx context.Context) (Tx, error) {
 	return &snTX{
 		dbTX:      dbTx,
 		snapshots: s.copySnapshots(),
-		snTX:      map[string]Tx{},
+		snTX:      map[string]ethdb.Tx{},
 	}, nil
 }
 func (s *SnapshotKV) copySnapshots() map[string]snapshotData {
@@ -174,7 +175,7 @@ func (s *SnapshotKV) copySnapshots() map[string]snapshotData {
 	return mp
 }
 
-func (s *SnapshotKV) BeginRw(ctx context.Context) (RwTx, error) {
+func (s *SnapshotKV) BeginRw(ctx context.Context) (ethdb.RwTx, error) {
 	dbTx, err := s.db.BeginRw(ctx)
 	if err != nil {
 		return nil, err
@@ -182,7 +183,7 @@ func (s *SnapshotKV) BeginRw(ctx context.Context) (RwTx, error) {
 	return &snTX{
 		dbTX:      dbTx,
 		snapshots: s.copySnapshots(),
-		snTX:      map[string]Tx{},
+		snTX:      map[string]ethdb.Tx{},
 	}, nil
 }
 
@@ -193,28 +194,28 @@ func (s *SnapshotKV) AllBuckets() dbutils.BucketsCfg {
 var ErrUnavailableSnapshot = errors.New("unavailable snapshot")
 
 type snTX struct {
-	dbTX      Tx
+	dbTX      ethdb.Tx
 	snapshots map[string]snapshotData
-	snTX      map[string]Tx
+	snTX      map[string]ethdb.Tx
 }
 
 type DBTX interface {
-	DBTX() RwTx
+	DBTX() ethdb.RwTx
 }
 
-func (s *snTX) DBTX() RwTx {
-	return s.dbTX.(RwTx)
+func (s *snTX) DBTX() ethdb.RwTx {
+	return s.dbTX.(ethdb.RwTx)
 }
-func (s *snTX) RwCursor(bucket string) (RwCursor, error) {
+func (s *snTX) RwCursor(bucket string) (ethdb.RwCursor, error) {
 	tx, err := s.getSnapshotTX(bucket)
 	if err != nil && !errors.Is(err, ErrUnavailableSnapshot) {
 		panic(err.Error())
 	}
 	//process only db buckets
 	if errors.Is(err, ErrUnavailableSnapshot) {
-		return s.dbTX.(RwTx).RwCursor(bucket)
+		return s.dbTX.(ethdb.RwTx).RwCursor(bucket)
 	}
-	dbCursor, err := s.dbTX.(RwTx).RwCursor(bucket)
+	dbCursor, err := s.dbTX.(ethdb.RwTx).RwCursor(bucket)
 	if err != nil {
 		return nil, err
 	}
@@ -230,26 +231,26 @@ func (s *snTX) RwCursor(bucket string) (RwCursor, error) {
 }
 
 func (s *snTX) DropBucket(bucket string) error {
-	return s.dbTX.(BucketMigrator).DropBucket(bucket)
+	return s.dbTX.(ethdb.BucketMigrator).DropBucket(bucket)
 }
 
 func (s *snTX) CreateBucket(bucket string) error {
-	return s.dbTX.(BucketMigrator).CreateBucket(bucket)
+	return s.dbTX.(ethdb.BucketMigrator).CreateBucket(bucket)
 }
 
 func (s *snTX) ExistsBucket(bucket string) bool {
-	return s.dbTX.(BucketMigrator).ExistsBucket(bucket)
+	return s.dbTX.(ethdb.BucketMigrator).ExistsBucket(bucket)
 }
 
 func (s *snTX) ClearBucket(bucket string) error {
-	return s.dbTX.(BucketMigrator).ClearBucket(bucket)
+	return s.dbTX.(ethdb.BucketMigrator).ClearBucket(bucket)
 }
 
 func (s *snTX) ExistingBuckets() ([]string, error) {
-	return s.dbTX.(BucketMigrator).ExistingBuckets()
+	return s.dbTX.(ethdb.BucketMigrator).ExistingBuckets()
 }
 
-func (s *snTX) Cursor(bucket string) (Cursor, error) {
+func (s *snTX) Cursor(bucket string) (ethdb.Cursor, error) {
 	tx, err := s.getSnapshotTX(bucket)
 	if err != nil && !errors.Is(err, ErrUnavailableSnapshot) {
 		panic(err.Error())
@@ -272,7 +273,7 @@ func (s *snTX) Cursor(bucket string) (Cursor, error) {
 	}, nil
 }
 
-func (s *snTX) CursorDupSort(bucket string) (CursorDupSort, error) {
+func (s *snTX) CursorDupSort(bucket string) (ethdb.CursorDupSort, error) {
 	tx, err := s.getSnapshotTX(bucket)
 	if err != nil && !errors.Is(err, ErrUnavailableSnapshot) {
 		panic(err.Error())
@@ -299,12 +300,12 @@ func (s *snTX) CursorDupSort(bucket string) (CursorDupSort, error) {
 	}, nil
 }
 
-func (s *snTX) RwCursorDupSort(bucket string) (RwCursorDupSort, error) {
+func (s *snTX) RwCursorDupSort(bucket string) (ethdb.RwCursorDupSort, error) {
 	c, err := s.CursorDupSort(bucket)
 	if err != nil {
 		return nil, err
 	}
-	return c.(RwCursorDupSort), nil
+	return c.(ethdb.RwCursorDupSort), nil
 }
 func (s *snTX) GetOne(bucket string, key []byte) (val []byte, err error) {
 	v, err := s.dbTX.GetOne(bucket, key)
@@ -332,20 +333,22 @@ func (s *snTX) GetOne(bucket string, key []byte) (val []byte, err error) {
 	return v, nil
 }
 
-func (s *snTX) Put(bucket string, k, v []byte) error    { return s.dbTX.(RwTx).Put(bucket, k, v) }
-func (s *snTX) Append(bucket string, k, v []byte) error { return s.dbTX.(RwTx).Append(bucket, k, v) }
+func (s *snTX) Put(bucket string, k, v []byte) error { return s.dbTX.(ethdb.RwTx).Put(bucket, k, v) }
+func (s *snTX) Append(bucket string, k, v []byte) error {
+	return s.dbTX.(ethdb.RwTx).Append(bucket, k, v)
+}
 func (s *snTX) AppendDup(bucket string, k, v []byte) error {
-	return s.dbTX.(RwTx).AppendDup(bucket, k, v)
+	return s.dbTX.(ethdb.RwTx).AppendDup(bucket, k, v)
 }
 func (s *snTX) Delete(bucket string, k, v []byte) error {
-	return s.dbTX.(RwTx).Put(bucket, k, DeletedValue)
+	return s.dbTX.(ethdb.RwTx).Put(bucket, k, DeletedValue)
 }
 
 func (s *snTX) CollectMetrics() {
 	s.dbTX.CollectMetrics()
 }
 
-func (s *snTX) getSnapshotTX(bucket string) (Tx, error) {
+func (s *snTX) getSnapshotTX(bucket string) (ethdb.Tx, error) {
 	tx, ok := s.snTX[bucket]
 	if ok {
 		return tx, nil
@@ -471,7 +474,7 @@ func (s *snTX) Comparator(bucket string) dbutils.CmpFunc {
 }
 
 func (s *snTX) IncrementSequence(bucket string, amount uint64) (uint64, error) {
-	return s.dbTX.(RwTx).IncrementSequence(bucket, amount)
+	return s.dbTX.(ethdb.RwTx).IncrementSequence(bucket, amount)
 }
 
 func (s *snTX) ReadSequence(bucket string) (uint64, error) {
@@ -483,22 +486,22 @@ func (s *snTX) CHandle() unsafe.Pointer {
 }
 
 func (s *snTX) BucketExists(bucket string) (bool, error) {
-	return s.dbTX.(BucketsMigrator).BucketExists(bucket)
+	return s.dbTX.(ethdb.BucketsMigrator).BucketExists(bucket)
 }
 
 func (s *snTX) ClearBuckets(buckets ...string) error {
-	return s.dbTX.(BucketsMigrator).ClearBuckets(buckets...)
+	return s.dbTX.(ethdb.BucketsMigrator).ClearBuckets(buckets...)
 }
 
 func (s *snTX) DropBuckets(buckets ...string) error {
-	return s.dbTX.(BucketsMigrator).DropBuckets(buckets...)
+	return s.dbTX.(ethdb.BucketsMigrator).DropBuckets(buckets...)
 }
 
 var DeletedValue = []byte{0}
 
 type snCursor struct {
-	dbCursor Cursor
-	snCursor Cursor
+	dbCursor ethdb.Cursor
+	snCursor ethdb.Cursor
 
 	currentKey []byte
 }
@@ -529,11 +532,11 @@ func (s *snCursor) First() ([]byte, []byte, error) {
 
 func (s *snCursor) Seek(seek []byte) ([]byte, []byte, error) {
 	dbKey, dbVal, err := s.dbCursor.Seek(seek)
-	if err != nil && !errors.Is(err, ErrKeyNotFound) {
+	if err != nil && !errors.Is(err, ethdb.ErrKeyNotFound) {
 		return nil, nil, err
 	}
 	sndbKey, sndbVal, err := s.snCursor.Seek(seek)
-	if err != nil && !errors.Is(err, ErrKeyNotFound) {
+	if err != nil && !errors.Is(err, ethdb.ErrKeyNotFound) {
 		return nil, nil, err
 	}
 
@@ -725,15 +728,15 @@ func (s *snCursor) Current() ([]byte, []byte, error) {
 }
 
 func (s *snCursor) Put(k, v []byte) error {
-	return s.dbCursor.(RwCursor).Put(k, v)
+	return s.dbCursor.(ethdb.RwCursor).Put(k, v)
 }
 
 func (s *snCursor) Append(k []byte, v []byte) error {
-	return s.dbCursor.(RwCursor).Append(k, v)
+	return s.dbCursor.(ethdb.RwCursor).Append(k, v)
 }
 
 func (s *snCursor) Delete(k, v []byte) error {
-	return s.dbCursor.(RwCursor).Put(k, DeletedValue)
+	return s.dbCursor.(ethdb.RwCursor).Put(k, DeletedValue)
 }
 
 func (s *snCursor) DeleteCurrent() error {
@@ -750,8 +753,8 @@ func (s *snCursor) Close() {
 }
 
 type snCursorDup struct {
-	dbCursorDup   CursorDupSort
-	sndbCursorDup CursorDupSort
+	dbCursorDup   ethdb.CursorDupSort
+	sndbCursorDup ethdb.CursorDupSort
 	snCursor
 }
 
@@ -840,14 +843,14 @@ type KvData struct {
 	V []byte
 }
 
-func GenStateData(data []KvData) (RwKV, error) {
+func GenStateData(data []KvData) (ethdb.RwKV, error) {
 	snapshot := NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return dbutils.BucketsCfg{
 			dbutils.PlainStateBucket: dbutils.BucketConfigItem{},
 		}
 	}).InMem().MustOpen()
 
-	err := snapshot.Update(context.Background(), func(tx RwTx) error {
+	err := snapshot.Update(context.Background(), func(tx ethdb.RwTx) error {
 		c, err := tx.RwCursor(dbutils.PlainStateBucket)
 		if err != nil {
 			return err
diff --git a/ethdb/kv_snapshot_property_test.go b/ethdb/kv/kv_snapshot_property_test.go
similarity index 96%
rename from ethdb/kv_snapshot_property_test.go
rename to ethdb/kv/kv_snapshot_property_test.go
index 870ff1fbfd..b9457dcd95 100644
--- a/ethdb/kv_snapshot_property_test.go
+++ b/ethdb/kv/kv_snapshot_property_test.go
@@ -1,12 +1,14 @@
-package ethdb
+package kv
 
 import (
 	"context"
+	"testing"
+
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
+	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/stretchr/testify/require"
 	"pgregory.net/rapid"
-	"testing"
 )
 
 func TestGetAndPut(t *testing.T) {
@@ -16,14 +18,14 @@ func TestGetAndPut(t *testing.T) {
 
 type getPutkvMachine struct {
 	bucket       string
-	snKV         RwKV
-	modelKV      RwKV
+	snKV         ethdb.RwKV
+	modelKV      ethdb.RwKV
 	snapshotKeys [][20]byte
 	newKeys      [][20]byte
 	allKeys      [][20]byte
 
-	snTX    RwTx
-	modelTX RwTx
+	snTX    ethdb.RwTx
+	modelTX ethdb.RwTx
 }
 
 func (m *getPutkvMachine) Init(t *rapid.T) {
@@ -163,8 +165,8 @@ func (m *getPutkvMachine) Commit(t *rapid.T) {
 
 type getKVMachine struct {
 	bucket        string
-	snKV          RwKV
-	modelKV       RwKV
+	snKV          ethdb.RwKV
+	modelKV       ethdb.RwKV
 	overWriteKeys [][20]byte
 	snKeys        [][20]byte
 	newKeys       [][20]byte
@@ -238,12 +240,12 @@ func (m *getKVMachine) Get(t *rapid.T) {
 		v1, v2     []byte
 		err1, err2 error
 	)
-	err := m.snKV.View(context.Background(), func(tx Tx) error {
+	err := m.snKV.View(context.Background(), func(tx ethdb.Tx) error {
 		v1, err1 = tx.GetOne(m.bucket, key[:])
 		return nil
 	})
 	require.NoError(t, err)
-	err = m.modelKV.View(context.Background(), func(tx Tx) error {
+	err = m.modelKV.View(context.Background(), func(tx ethdb.Tx) error {
 		v2, err2 = tx.GetOne(m.bucket, key[:])
 		return nil
 	})
@@ -264,14 +266,14 @@ func TestCursorWithTX(t *testing.T) {
 
 type cursorKVMachine struct {
 	bucket  string
-	snKV    RwKV
-	modelKV RwKV
+	snKV    ethdb.RwKV
+	modelKV ethdb.RwKV
 
-	snTX    RwTx
-	modelTX RwTx
+	snTX    ethdb.RwTx
+	modelTX ethdb.RwTx
 
-	snCursor    RwCursor
-	modelCursor RwCursor
+	snCursor    ethdb.RwCursor
+	modelCursor ethdb.RwCursor
 
 	snapshotKeys [][20]byte
 	newKeys      [][20]byte
diff --git a/ethdb/kv_snapshot_test.go b/ethdb/kv/kv_snapshot_test.go
similarity index 97%
rename from ethdb/kv_snapshot_test.go
rename to ethdb/kv/kv_snapshot_test.go
index cd6d08b891..bbe258743f 100644
--- a/ethdb/kv_snapshot_test.go
+++ b/ethdb/kv/kv_snapshot_test.go
@@ -1,4 +1,4 @@
-package ethdb
+package kv
 
 import (
 	"bytes"
@@ -9,6 +9,7 @@ import (
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
+	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/stretchr/testify/require"
 )
 
@@ -19,7 +20,7 @@ func TestSnapshot2Get(t *testing.T) {
 		}
 	}).InMem().MustOpen()
 	defer sn1.Close()
-	err := sn1.Update(context.Background(), func(tx RwTx) error {
+	err := sn1.Update(context.Background(), func(tx ethdb.RwTx) error {
 		bucket, err := tx.RwCursor(dbutils.HeadersBucket)
 		if err != nil {
 			return err
@@ -45,7 +46,7 @@ func TestSnapshot2Get(t *testing.T) {
 		}
 	}).InMem().MustOpen()
 	defer sn2.Close()
-	err = sn2.Update(context.Background(), func(tx RwTx) error {
+	err = sn2.Update(context.Background(), func(tx ethdb.RwTx) error {
 		bucket, err := tx.RwCursor(dbutils.BlockBodyPrefix)
 		require.NoError(t, err)
 		innerErr := bucket.Put(dbutils.BlockBodyKey(1, common.Hash{1}), []byte{1})
@@ -64,7 +65,7 @@ func TestSnapshot2Get(t *testing.T) {
 	}
 
 	mainDB := NewTestKV(t)
-	err = mainDB.Update(context.Background(), func(tx RwTx) error {
+	err = mainDB.Update(context.Background(), func(tx ethdb.RwTx) error {
 		bucket, err := tx.RwCursor(dbutils.HeadersBucket)
 		if err != nil {
 			return err
@@ -199,7 +200,7 @@ func TestSnapshot2WritableTxAndGet(t *testing.T) {
 	defer sn1.Close()
 
 	{
-		err := sn1.Update(context.Background(), func(tx RwTx) error {
+		err := sn1.Update(context.Background(), func(tx ethdb.RwTx) error {
 			bucket, err := tx.RwCursor(dbutils.HeadersBucket)
 			require.NoError(t, err)
 			innerErr := bucket.Put(dbutils.HeaderKey(1, common.Hash{1}), []byte{1})
@@ -225,7 +226,7 @@ func TestSnapshot2WritableTxAndGet(t *testing.T) {
 	}).InMem().MustOpen()
 	defer sn2.Close()
 	{
-		err := sn2.Update(context.Background(), func(tx RwTx) error {
+		err := sn2.Update(context.Background(), func(tx ethdb.RwTx) error {
 			bucket, err := tx.RwCursor(dbutils.BlockBodyPrefix)
 			require.NoError(t, err)
 			innerErr := bucket.Put(dbutils.BlockBodyKey(1, common.Hash{1}), []byte{1})
@@ -764,7 +765,7 @@ func TestSnapshot2WritableTxWalkForwardAndBackward(t *testing.T) {
 	}
 
 	i := 0
-	err = Walk(c, []byte{}, 0, func(k, v []byte) (bool, error) {
+	err = ethdb.Walk(c, []byte{}, 0, func(k, v []byte) (bool, error) {
 		checkKV(t, k, v, data[i].K, data[i].V)
 		i++
 		return true, nil
@@ -801,7 +802,7 @@ func TestSnapshot2WalkByEmptyDB(t *testing.T) {
 	require.NoError(t, err)
 
 	i := 0
-	err = Walk(c, []byte{}, 0, func(k, v []byte) (bool, error) {
+	err = ethdb.Walk(c, []byte{}, 0, func(k, v []byte) (bool, error) {
 		checkKV(t, k, v, data[i].K, data[i].V)
 		i++
 		return true, nil
@@ -1073,12 +1074,12 @@ func TestSnapshotUpdateSnapshot(t *testing.T) {
 	}
 }
 
-func printBucket(kv RoKV, bucket string) {
+func printBucket(kv ethdb.RoKV, bucket string) {
 	fmt.Println("+Print bucket", bucket)
 	defer func() {
 		fmt.Println("-Print bucket", bucket)
 	}()
-	err := kv.View(context.Background(), func(tx Tx) error {
+	err := kv.View(context.Background(), func(tx ethdb.Tx) error {
 		c, err := tx.Cursor(bucket)
 		if err != nil {
 			return err
diff --git a/ethdb/memory_database.go b/ethdb/kv/memory_database.go
similarity index 89%
rename from ethdb/memory_database.go
rename to ethdb/kv/memory_database.go
index e835344ad7..baed6707fd 100644
--- a/ethdb/memory_database.go
+++ b/ethdb/kv/memory_database.go
@@ -14,11 +14,13 @@
 // You should have received a copy of the GNU Lesser General Public License
 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 
-package ethdb
+package kv
 
 import (
 	"context"
 	"testing"
+
+	"github.com/ledgerwatch/erigon/ethdb"
 )
 
 func NewMemDatabase() *ObjectDatabase {
@@ -29,11 +31,11 @@ func NewTestDB(t testing.TB) *ObjectDatabase {
 	return NewObjectDatabase(NewTestKV(t))
 }
 
-func NewMemKV() RwKV {
+func NewMemKV() ethdb.RwKV {
 	return NewMDBX().InMem().MustOpen()
 }
 
-func NewTestKV(t testing.TB) RwKV {
+func NewTestKV(t testing.TB) ethdb.RwKV {
 	kv := NewMemKV()
 	switch tt := t.(type) {
 	case *testing.T:
@@ -44,7 +46,7 @@ func NewTestKV(t testing.TB) RwKV {
 	return kv
 }
 
-func NewTestTx(t testing.TB) (RwKV, RwTx) {
+func NewTestTx(t testing.TB) (ethdb.RwKV, ethdb.RwTx) {
 	kv := NewMemKV()
 	switch tt := t.(type) {
 	case *testing.T:
diff --git a/ethdb/mutation.go b/ethdb/kv/mutation.go
similarity index 87%
rename from ethdb/mutation.go
rename to ethdb/kv/mutation.go
index f1651a5d6e..26d2d70165 100644
--- a/ethdb/mutation.go
+++ b/ethdb/kv/mutation.go
@@ -1,4 +1,4 @@
-package ethdb
+package kv
 
 import (
 	"bytes"
@@ -14,17 +14,13 @@ import (
 	"github.com/google/btree"
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
+	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/log"
-	"github.com/ledgerwatch/erigon/metrics"
-)
-
-var (
-	dbCommitBigBatchTimer = metrics.NewRegisteredTimer("db/commit/big_batch", nil)
 )
 
 type mutation struct {
 	puts       *btree.BTree
-	db         Database
+	db         ethdb.Database
 	searchItem MutationItem
 	mu         sync.RWMutex
 	size       int
@@ -36,9 +32,9 @@ type MutationItem struct {
 	value []byte
 }
 
-func NewBatch(tx RwTx) *mutation {
+func NewBatch(tx ethdb.RwTx) *mutation {
 	return &mutation{
-		db:   &TxDb{tx: tx, cursors: map[string]Cursor{}},
+		db:   &TxDb{tx: tx, cursors: map[string]ethdb.Cursor{}},
 		puts: btree.New(32),
 	}
 }
@@ -52,8 +48,8 @@ func (mi *MutationItem) Less(than btree.Item) bool {
 	return bytes.Compare(mi.key, i.key) < 0
 }
 
-func (m *mutation) RwKV() RwKV {
-	if casted, ok := m.db.(HasRwKV); ok {
+func (m *mutation) RwKV() ethdb.RwKV {
+	if casted, ok := m.db.(ethdb.HasRwKV); ok {
 		return casted.RwKV()
 	}
 	return nil
@@ -75,7 +71,7 @@ func (m *mutation) IncrementSequence(bucket string, amount uint64) (res uint64,
 	v, ok := m.getMem(dbutils.Sequence, []byte(bucket))
 	if !ok && m.db != nil {
 		v, err = m.db.Get(dbutils.Sequence, []byte(bucket))
-		if err != nil && !errors.Is(err, ErrKeyNotFound) {
+		if err != nil && !errors.Is(err, ethdb.ErrKeyNotFound) {
 			return 0, err
 		}
 	}
@@ -96,7 +92,7 @@ func (m *mutation) ReadSequence(bucket string) (res uint64, err error) {
 	v, ok := m.getMem(dbutils.Sequence, []byte(bucket))
 	if !ok && m.db != nil {
 		v, err = m.db.Get(dbutils.Sequence, []byte(bucket))
-		if err != nil && !errors.Is(err, ErrKeyNotFound) {
+		if err != nil && !errors.Is(err, ethdb.ErrKeyNotFound) {
 			return 0, err
 		}
 	}
@@ -119,7 +115,7 @@ func (m *mutation) GetOne(table string, key []byte) ([]byte, error) {
 	if m.db != nil {
 		// TODO: simplify when tx can no longer be parent of mutation
 		value, err := m.db.Get(table, key)
-		if err != nil && !errors.Is(err, ErrKeyNotFound) {
+		if err != nil && !errors.Is(err, ethdb.ErrKeyNotFound) {
 			return nil, err
 		}
 
@@ -136,7 +132,7 @@ func (m *mutation) Get(table string, key []byte) ([]byte, error) {
 	}
 
 	if value == nil {
-		return nil, ErrKeyNotFound
+		return nil, ethdb.ErrKeyNotFound
 	}
 
 	return value, nil
@@ -241,9 +237,9 @@ func (m *mutation) RollbackAndBegin(ctx context.Context) error {
 	return nil
 }
 
-func (m *mutation) doCommit(tx RwTx) error {
+func (m *mutation) doCommit(tx ethdb.RwTx) error {
 	var prevTable string
-	var c RwCursor
+	var c ethdb.RwCursor
 	var innerErr error
 	var isEndOfBucket bool
 	logEvery := time.NewTicker(30 * time.Second)
@@ -311,12 +307,12 @@ func (m *mutation) Commit() error {
 	}
 	m.mu.Lock()
 	defer m.mu.Unlock()
-	if tx, ok := m.db.(HasTx); ok {
-		if err := m.doCommit(tx.Tx().(RwTx)); err != nil {
+	if tx, ok := m.db.(ethdb.HasTx); ok {
+		if err := m.doCommit(tx.Tx().(ethdb.RwTx)); err != nil {
 			return err
 		}
 	} else {
-		if err := m.db.(HasRwKV).RwKV().Update(context.Background(), func(tx RwTx) error {
+		if err := m.db.(ethdb.HasRwKV).RwKV().Update(context.Background(), func(tx ethdb.RwTx) error {
 			return m.doCommit(tx)
 		}); err != nil {
 			return err
@@ -355,7 +351,7 @@ func (m *mutation) Close() {
 	m.Rollback()
 }
 
-func (m *mutation) NewBatch() DbWithPendingMutations {
+func (m *mutation) NewBatch() ethdb.DbWithPendingMutations {
 	mm := &mutation{
 		db:   m,
 		puts: btree.New(32),
@@ -363,11 +359,11 @@ func (m *mutation) NewBatch() DbWithPendingMutations {
 	return mm
 }
 
-func (m *mutation) Begin(ctx context.Context, flags TxFlags) (DbWithPendingMutations, error) {
+func (m *mutation) Begin(ctx context.Context, flags ethdb.TxFlags) (ethdb.DbWithPendingMutations, error) {
 	return m.db.Begin(ctx, flags)
 }
 
-func (m *mutation) BeginGetter(ctx context.Context) (GetterTx, error) {
+func (m *mutation) BeginGetter(ctx context.Context) (ethdb.GetterTx, error) {
 	return m.db.BeginGetter(ctx)
 }
 
@@ -377,11 +373,11 @@ func (m *mutation) panicOnEmptyDB() {
 	}
 }
 
-func (m *mutation) MemCopy() Database {
+func (m *mutation) MemCopy() ethdb.Database {
 	m.panicOnEmptyDB()
 	return m.db
 }
 
-func (m *mutation) SetRwKV(kv RwKV) {
-	m.db.(HasRwKV).SetRwKV(kv)
+func (m *mutation) SetRwKV(kv ethdb.RwKV) {
+	m.db.(ethdb.HasRwKV).SetRwKV(kv)
 }
diff --git a/ethdb/object_db.go b/ethdb/kv/object_db.go
similarity index 77%
rename from ethdb/object_db.go
rename to ethdb/kv/object_db.go
index a4540f177a..06727f1e10 100644
--- a/ethdb/object_db.go
+++ b/ethdb/kv/object_db.go
@@ -15,7 +15,7 @@
 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
 
 // Package ethdb defines the interfaces for an Ethereum data store.
-package ethdb
+package kv
 
 import (
 	"bytes"
@@ -25,6 +25,7 @@ import (
 	"github.com/google/btree"
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
+	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/ethdb/mdbx"
 	"github.com/ledgerwatch/erigon/log"
 )
@@ -35,11 +36,11 @@ type DbCopier interface {
 
 // ObjectDatabase - is an object-style interface of DB accessing
 type ObjectDatabase struct {
-	kv RwKV
+	kv ethdb.RwKV
 }
 
 // NewObjectDatabase returns a AbstractDB wrapper.
-func NewObjectDatabase(kv RwKV) *ObjectDatabase {
+func NewObjectDatabase(kv ethdb.RwKV) *ObjectDatabase {
 	return &ObjectDatabase{
 		kv: kv,
 	}
@@ -49,7 +50,7 @@ func MustOpen(path string) *ObjectDatabase {
 	return NewObjectDatabase(MustOpenKV(path))
 }
 
-func MustOpenKV(path string) RwKV {
+func MustOpenKV(path string) ethdb.RwKV {
 	db, err := OpenKV(path, false)
 	if err != nil {
 		panic(err)
@@ -58,19 +59,19 @@ func MustOpenKV(path string) RwKV {
 }
 
 // Open - main method to open database.
-func OpenKV(path string, readOnly bool) (RwKV, error) {
-	var kv RwKV
+func OpenKV(path string, readOnly bool) (ethdb.RwKV, error) {
+	var db ethdb.RwKV
 	var err error
 	opts := NewMDBX().Path(path)
 	if readOnly {
 		opts = opts.Flags(func(flags uint) uint { return flags | mdbx.Readonly })
 	}
-	kv, err = opts.Open()
+	db, err = opts.Open()
 
 	if err != nil {
 		return nil, err
 	}
-	return kv, nil
+	return db, nil
 }
 
 func Open(path string, readOnly bool) (*ObjectDatabase, error) {
@@ -84,7 +85,7 @@ func Open(path string, readOnly bool) (*ObjectDatabase, error) {
 
 // Put inserts or updates a single entry.
 func (db *ObjectDatabase) Put(bucket string, key []byte, value []byte) error {
-	err := db.kv.Update(context.Background(), func(tx RwTx) error {
+	err := db.kv.Update(context.Background(), func(tx ethdb.RwTx) error {
 		return tx.Put(bucket, key, value)
 	})
 	return err
@@ -92,7 +93,7 @@ func (db *ObjectDatabase) Put(bucket string, key []byte, value []byte) error {
 
 // Append appends a single entry to the end of the bucket.
 func (db *ObjectDatabase) Append(bucket string, key []byte, value []byte) error {
-	err := db.kv.Update(context.Background(), func(tx RwTx) error {
+	err := db.kv.Update(context.Background(), func(tx ethdb.RwTx) error {
 		c, err := tx.RwCursor(bucket)
 		if err != nil {
 			return err
@@ -104,7 +105,7 @@ func (db *ObjectDatabase) Append(bucket string, key []byte, value []byte) error
 
 // AppendDup appends a single entry to the end of the bucket.
 func (db *ObjectDatabase) AppendDup(bucket string, key []byte, value []byte) error {
-	err := db.kv.Update(context.Background(), func(tx RwTx) error {
+	err := db.kv.Update(context.Background(), func(tx ethdb.RwTx) error {
 		c, err := tx.RwCursorDupSort(bucket)
 		if err != nil {
 			return err
@@ -116,8 +117,8 @@ func (db *ObjectDatabase) AppendDup(bucket string, key []byte, value []byte) err
 
 // MultiPut - requirements: input must be sorted and without duplicates
 func (db *ObjectDatabase) MultiPut(tuples ...[]byte) (uint64, error) {
-	err := db.kv.Update(context.Background(), func(tx RwTx) error {
-		return MultiPut(tx, tuples...)
+	err := db.kv.Update(context.Background(), func(tx ethdb.RwTx) error {
+		return ethdb.MultiPut(tx, tuples...)
 	})
 	if err != nil {
 		return 0, err
@@ -127,7 +128,7 @@ func (db *ObjectDatabase) MultiPut(tuples ...[]byte) (uint64, error) {
 
 func (db *ObjectDatabase) Has(bucket string, key []byte) (bool, error) {
 	var has bool
-	err := db.kv.View(context.Background(), func(tx Tx) error {
+	err := db.kv.View(context.Background(), func(tx ethdb.Tx) error {
 		v, err := tx.GetOne(bucket, key)
 		if err != nil {
 			return err
@@ -139,14 +140,14 @@ func (db *ObjectDatabase) Has(bucket string, key []byte) (bool, error) {
 }
 
 func (db *ObjectDatabase) IncrementSequence(bucket string, amount uint64) (res uint64, err error) {
-	err = db.kv.Update(context.Background(), func(tx RwTx) error {
+	err = db.kv.Update(context.Background(), func(tx ethdb.RwTx) error {
 		res, err = tx.IncrementSequence(bucket, amount)
 		return err
 	})
 	return res, err
 }
 func (db *ObjectDatabase) ReadSequence(bucket string) (res uint64, err error) {
-	err = db.kv.View(context.Background(), func(tx Tx) error {
+	err = db.kv.View(context.Background(), func(tx ethdb.Tx) error {
 		res, err = tx.ReadSequence(bucket)
 		return err
 	})
@@ -156,7 +157,7 @@ func (db *ObjectDatabase) ReadSequence(bucket string) (res uint64, err error) {
 // Get returns the value for a given key if it's present.
 func (db *ObjectDatabase) GetOne(bucket string, key []byte) ([]byte, error) {
 	var dat []byte
-	err := db.kv.View(context.Background(), func(tx Tx) error {
+	err := db.kv.View(context.Background(), func(tx ethdb.Tx) error {
 		v, err := tx.GetOne(bucket, key)
 		if err != nil {
 			return err
@@ -172,12 +173,12 @@ func (db *ObjectDatabase) GetOne(bucket string, key []byte) ([]byte, error) {
 
 func (db *ObjectDatabase) Get(bucket string, key []byte) ([]byte, error) {
 	dat, err := db.GetOne(bucket, key)
-	return getOneWrapper(dat, err)
+	return ethdb.GetOneWrapper(dat, err)
 }
 
 func (db *ObjectDatabase) Last(bucket string) ([]byte, []byte, error) {
 	var key, value []byte
-	if err := db.kv.View(context.Background(), func(tx Tx) error {
+	if err := db.kv.View(context.Background(), func(tx ethdb.Tx) error {
 		c, err := tx.Cursor(bucket)
 		if err != nil {
 			return err
@@ -197,29 +198,29 @@ func (db *ObjectDatabase) Last(bucket string) ([]byte, []byte, error) {
 }
 
 func (db *ObjectDatabase) Walk(bucket string, startkey []byte, fixedbits int, walker func(k, v []byte) (bool, error)) error {
-	err := db.kv.View(context.Background(), func(tx Tx) error {
+	err := db.kv.View(context.Background(), func(tx ethdb.Tx) error {
 		c, err := tx.Cursor(bucket)
 		if err != nil {
 			return err
 		}
-		return Walk(c, startkey, fixedbits, walker)
+		return ethdb.Walk(c, startkey, fixedbits, walker)
 	})
 	return err
 }
 
 func (db *ObjectDatabase) ForEach(bucket string, fromPrefix []byte, walker func(k, v []byte) error) error {
-	return db.kv.View(context.Background(), func(tx Tx) error {
+	return db.kv.View(context.Background(), func(tx ethdb.Tx) error {
 		return tx.ForEach(bucket, fromPrefix, walker)
 	})
 }
 func (db *ObjectDatabase) ForAmount(bucket string, fromPrefix []byte, amount uint32, walker func(k, v []byte) error) error {
-	return db.kv.View(context.Background(), func(tx Tx) error {
+	return db.kv.View(context.Background(), func(tx ethdb.Tx) error {
 		return tx.ForAmount(bucket, fromPrefix, amount, walker)
 	})
 }
 
 func (db *ObjectDatabase) ForPrefix(bucket string, prefix []byte, walker func(k, v []byte) error) error {
-	return db.kv.View(context.Background(), func(tx Tx) error {
+	return db.kv.View(context.Background(), func(tx ethdb.Tx) error {
 		return tx.ForPrefix(bucket, prefix, walker)
 	})
 }
@@ -227,7 +228,7 @@ func (db *ObjectDatabase) ForPrefix(bucket string, prefix []byte, walker func(k,
 // Delete deletes the key from the queue and database
 func (db *ObjectDatabase) Delete(bucket string, k, v []byte) error {
 	// Execute the actual operation
-	err := db.kv.Update(context.Background(), func(tx RwTx) error {
+	err := db.kv.Update(context.Background(), func(tx ethdb.RwTx) error {
 		return tx.Delete(bucket, k, v)
 	})
 	return err
@@ -235,8 +236,8 @@ func (db *ObjectDatabase) Delete(bucket string, k, v []byte) error {
 
 func (db *ObjectDatabase) BucketExists(name string) (bool, error) {
 	exists := false
-	if err := db.kv.View(context.Background(), func(tx Tx) error {
-		migrator, ok := tx.(BucketMigrator)
+	if err := db.kv.View(context.Background(), func(tx ethdb.Tx) error {
+		migrator, ok := tx.(ethdb.BucketMigrator)
 		if !ok {
 			return fmt.Errorf("%T doesn't implement ethdb.TxMigrator interface", db.kv)
 		}
@@ -251,8 +252,8 @@ func (db *ObjectDatabase) BucketExists(name string) (bool, error) {
 func (db *ObjectDatabase) ClearBuckets(buckets ...string) error {
 	for i := range buckets {
 		name := buckets[i]
-		if err := db.kv.Update(context.Background(), func(tx RwTx) error {
-			migrator, ok := tx.(BucketMigrator)
+		if err := db.kv.Update(context.Background(), func(tx ethdb.RwTx) error {
+			migrator, ok := tx.(ethdb.BucketMigrator)
 			if !ok {
 				return fmt.Errorf("%T doesn't implement ethdb.TxMigrator interface", db.kv)
 			}
@@ -272,8 +273,8 @@ func (db *ObjectDatabase) DropBuckets(buckets ...string) error {
 	for i := range buckets {
 		name := buckets[i]
 		log.Info("Dropping bucket", "name", name)
-		if err := db.kv.Update(context.Background(), func(tx RwTx) error {
-			migrator, ok := tx.(BucketMigrator)
+		if err := db.kv.Update(context.Background(), func(tx ethdb.RwTx) error {
+			migrator, ok := tx.(ethdb.BucketMigrator)
 			if !ok {
 				return fmt.Errorf("%T doesn't implement ethdb.TxMigrator interface", db.kv)
 			}
@@ -294,7 +295,7 @@ func (db *ObjectDatabase) Close() {
 
 func (db *ObjectDatabase) Keys() ([][]byte, error) {
 	var keys [][]byte
-	err := db.kv.View(context.Background(), func(tx Tx) error {
+	err := db.kv.View(context.Background(), func(tx ethdb.Tx) error {
 		for _, name := range dbutils.Buckets {
 			var nameCopy = make([]byte, len(name))
 			copy(nameCopy, name)
@@ -302,7 +303,7 @@ func (db *ObjectDatabase) Keys() ([][]byte, error) {
 			if err != nil {
 				return err
 			}
-			err = ForEach(c, func(k, _ []byte) (bool, error) {
+			err = ethdb.ForEach(c, func(k, _ []byte) (bool, error) {
 				var kCopy = make([]byte, len(k))
 				copy(kCopy, k)
 				keys = append(append(keys, nameCopy), kCopy)
@@ -320,11 +321,11 @@ func (db *ObjectDatabase) Keys() ([][]byte, error) {
 	return keys, err
 }
 
-func (db *ObjectDatabase) RwKV() RwKV {
+func (db *ObjectDatabase) RwKV() ethdb.RwKV {
 	return db.kv
 }
 
-func (db *ObjectDatabase) SetRwKV(kv RwKV) {
+func (db *ObjectDatabase) SetRwKV(kv ethdb.RwKV) {
 	db.kv = kv
 }
 
@@ -338,10 +339,10 @@ func (db *ObjectDatabase) MemCopy() *ObjectDatabase {
 		panic(fmt.Sprintf("MemCopy is not implemented for type %T", t))
 	}
 
-	if err := db.kv.View(context.Background(), func(readTx Tx) error {
+	if err := db.kv.View(context.Background(), func(readTx ethdb.Tx) error {
 		for _, name := range dbutils.Buckets {
 			name := name
-			if err := mem.kv.Update(context.Background(), func(writeTx RwTx) error {
+			if err := mem.kv.Update(context.Background(), func(writeTx ethdb.RwTx) error {
 				newBucketToWrite, err := writeTx.RwCursor(name)
 				if err != nil {
 					return err
@@ -352,7 +353,7 @@ func (db *ObjectDatabase) MemCopy() *ObjectDatabase {
 					return err
 				}
 				defer readC.Close()
-				return ForEach(readC, func(k, v []byte) (bool, error) {
+				return ethdb.ForEach(readC, func(k, v []byte) (bool, error) {
 					if err := newBucketToWrite.Put(common.CopyBytes(k), common.CopyBytes(v)); err != nil {
 						return false, err
 					}
@@ -370,7 +371,7 @@ func (db *ObjectDatabase) MemCopy() *ObjectDatabase {
 	return mem
 }
 
-func (db *ObjectDatabase) NewBatch() DbWithPendingMutations {
+func (db *ObjectDatabase) NewBatch() ethdb.DbWithPendingMutations {
 	m := &mutation{
 		db:   db,
 		puts: btree.New(32),
@@ -378,15 +379,15 @@ func (db *ObjectDatabase) NewBatch() DbWithPendingMutations {
 	return m
 }
 
-func (db *ObjectDatabase) BeginGetter(ctx context.Context) (GetterTx, error) {
+func (db *ObjectDatabase) BeginGetter(ctx context.Context) (ethdb.GetterTx, error) {
 	batch := &TxDb{db: db}
-	if err := batch.begin(ctx, RO); err != nil {
+	if err := batch.begin(ctx, ethdb.RO); err != nil {
 		return batch, err
 	}
 	return batch, nil
 }
 
-func (db *ObjectDatabase) Begin(ctx context.Context, flags TxFlags) (DbWithPendingMutations, error) {
+func (db *ObjectDatabase) Begin(ctx context.Context, flags ethdb.TxFlags) (ethdb.DbWithPendingMutations, error) {
 	batch := &TxDb{db: db}
 	if err := batch.begin(ctx, flags); err != nil {
 		return batch, err
@@ -419,20 +420,10 @@ func (t MultiPutTuples) Swap(i, j int) {
 	t[i3+2], t[j3+2] = t[j3+2], t[i3+2]
 }
 
-func Bytesmask(fixedbits int) (fixedbytes int, mask byte) {
-	fixedbytes = (fixedbits + 7) / 8
-	shiftbits := fixedbits & 7
-	mask = byte(0xff)
-	if shiftbits != 0 {
-		mask = 0xff << (8 - shiftbits)
-	}
-	return fixedbytes, mask
-}
-
-func InspectDatabase(db Database) error {
+func InspectDatabase(db ethdb.Database) error {
 	// FIXME: implement in Erigon
 	// see https://github.com/ethereum/go-ethereum/blob/f5d89cdb72c1e82e9deb54754bef8dd20bf12591/core/rawdb/database.go#L224
-	return errNotSupported
+	return ethdb.ErrNotSupported
 }
 
 func NewDatabaseWithFreezer(db *ObjectDatabase, dir, suffix string) (*ObjectDatabase, error) {
diff --git a/ethdb/tx_db.go b/ethdb/kv/tx_db.go
similarity index 79%
rename from ethdb/tx_db.go
rename to ethdb/kv/tx_db.go
index bfd9e040db..a5bdca3328 100644
--- a/ethdb/tx_db.go
+++ b/ethdb/kv/tx_db.go
@@ -1,20 +1,21 @@
-package ethdb
+package kv
 
 import (
 	"context"
 	"fmt"
 
 	"github.com/google/btree"
+	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/log"
 )
 
 // Implements ethdb.Getter for Tx
 type roTxDb struct {
-	tx  Tx
+	tx  ethdb.Tx
 	top bool
 }
 
-func NewRoTxDb(tx Tx) *roTxDb {
+func NewRoTxDb(tx ethdb.Tx) *roTxDb {
 	return &roTxDb{tx: tx, top: true}
 }
 
@@ -30,7 +31,7 @@ func (m *roTxDb) GetOne(bucket string, key []byte) ([]byte, error) {
 
 func (m *roTxDb) Get(bucket string, key []byte) ([]byte, error) {
 	dat, err := m.GetOne(bucket, key)
-	return getOneWrapper(dat, err)
+	return ethdb.GetOneWrapper(dat, err)
 }
 
 func (m *roTxDb) Has(bucket string, key []byte) (bool, error) {
@@ -50,7 +51,7 @@ func (m *roTxDb) Walk(bucket string, startkey []byte, fixedbits int, walker func
 		return err
 	}
 	defer c.Close()
-	return Walk(c, startkey, fixedbits, walker)
+	return ethdb.Walk(c, startkey, fixedbits, walker)
 }
 
 func (m *roTxDb) ForEach(bucket string, fromPrefix []byte, walker func(k, v []byte) error) error {
@@ -64,7 +65,7 @@ func (m *roTxDb) ForAmount(bucket string, prefix []byte, amount uint32, walker f
 	return m.tx.ForAmount(bucket, prefix, amount, walker)
 }
 
-func (m *roTxDb) BeginGetter(ctx context.Context) (GetterTx, error) {
+func (m *roTxDb) BeginGetter(ctx context.Context) (ethdb.GetterTx, error) {
 	return &roTxDb{tx: m.tx, top: false}, nil
 }
 
@@ -74,12 +75,12 @@ func (m *roTxDb) Rollback() {
 	}
 }
 
-func (m *roTxDb) Tx() Tx {
+func (m *roTxDb) Tx() ethdb.Tx {
 	return m.tx
 }
 
-func NewRwTxDb(tx Tx) *TxDb {
-	return &TxDb{tx: tx, cursors: map[string]Cursor{}}
+func NewRwTxDb(tx ethdb.Tx) *TxDb {
+	return &TxDb{tx: tx, cursors: map[string]ethdb.Cursor{}}
 }
 
 // TxDb - provides Database interface around ethdb.Tx
@@ -88,15 +89,15 @@ func NewRwTxDb(tx Tx) *TxDb {
 // you can put unlimited amount of data into this class
 // Walk and MultiWalk methods - work outside of Tx object yet, will implement it later
 type TxDb struct {
-	db      Database
-	tx      Tx
-	cursors map[string]Cursor
-	txFlags TxFlags
+	db      ethdb.Database
+	tx      ethdb.Tx
+	cursors map[string]ethdb.Cursor
+	txFlags ethdb.TxFlags
 	len     uint64
 }
 
-func WrapIntoTxDB(tx RwTx) *TxDb {
-	return &TxDb{tx: tx, cursors: map[string]Cursor{}}
+func WrapIntoTxDB(tx ethdb.RwTx) *TxDb {
+	return &TxDb{tx: tx, cursors: map[string]ethdb.Cursor{}}
 }
 
 func (m *TxDb) Close() {
@@ -106,11 +107,11 @@ func (m *TxDb) Close() {
 // NewTxDbWithoutTransaction creates TxDb object without opening transaction,
 // such TxDb not usable before .Begin() call on it
 // It allows inject TxDb object into class hierarchy, but open write transaction later
-func NewTxDbWithoutTransaction(db Database, flags TxFlags) DbWithPendingMutations {
+func NewTxDbWithoutTransaction(db ethdb.Database, flags ethdb.TxFlags) ethdb.DbWithPendingMutations {
 	return &TxDb{db: db, txFlags: flags}
 }
 
-func (m *TxDb) Begin(ctx context.Context, flags TxFlags) (DbWithPendingMutations, error) {
+func (m *TxDb) Begin(ctx context.Context, flags ethdb.TxFlags) (ethdb.DbWithPendingMutations, error) {
 	batch := m
 	if m.tx != nil {
 		panic("nested transactions not supported")
@@ -122,19 +123,19 @@ func (m *TxDb) Begin(ctx context.Context, flags TxFlags) (DbWithPendingMutations
 	return batch, nil
 }
 
-func (m *TxDb) BeginGetter(ctx context.Context) (GetterTx, error) {
+func (m *TxDb) BeginGetter(ctx context.Context) (ethdb.GetterTx, error) {
 	batch := m
 	if m.tx != nil {
 		panic("nested transactions not supported")
 	}
 
-	if err := batch.begin(ctx, RO); err != nil {
+	if err := batch.begin(ctx, ethdb.RO); err != nil {
 		return nil, err
 	}
 	return batch, nil
 }
 
-func (m *TxDb) cursor(bucket string) (Cursor, error) {
+func (m *TxDb) cursor(bucket string) (ethdb.Cursor, error) {
 	c, ok := m.cursors[bucket]
 	if !ok {
 		var err error
@@ -148,7 +149,7 @@ func (m *TxDb) cursor(bucket string) (Cursor, error) {
 }
 
 func (m *TxDb) IncrementSequence(bucket string, amount uint64) (res uint64, err error) {
-	return m.tx.(RwTx).IncrementSequence(bucket, amount)
+	return m.tx.(ethdb.RwTx).IncrementSequence(bucket, amount)
 }
 
 func (m *TxDb) ReadSequence(bucket string) (res uint64, err error) {
@@ -161,7 +162,7 @@ func (m *TxDb) Put(bucket string, key []byte, value []byte) error {
 	if err != nil {
 		return err
 	}
-	return c.(RwCursor).Put(key, value)
+	return c.(ethdb.RwCursor).Put(key, value)
 }
 
 func (m *TxDb) Append(bucket string, key []byte, value []byte) error {
@@ -170,7 +171,7 @@ func (m *TxDb) Append(bucket string, key []byte, value []byte) error {
 	if err != nil {
 		return err
 	}
-	return c.(RwCursor).Append(key, value)
+	return c.(ethdb.RwCursor).Append(key, value)
 }
 
 func (m *TxDb) AppendDup(bucket string, key []byte, value []byte) error {
@@ -179,7 +180,7 @@ func (m *TxDb) AppendDup(bucket string, key []byte, value []byte) error {
 	if err != nil {
 		return err
 	}
-	return c.(RwCursorDupSort).AppendDup(key, value)
+	return c.(ethdb.RwCursorDupSort).AppendDup(key, value)
 }
 
 func (m *TxDb) Delete(bucket string, k, v []byte) error {
@@ -188,22 +189,22 @@ func (m *TxDb) Delete(bucket string, k, v []byte) error {
 	if err != nil {
 		return err
 	}
-	return c.(RwCursor).Delete(k, v)
+	return c.(ethdb.RwCursor).Delete(k, v)
 }
 
-func (m *TxDb) NewBatch() DbWithPendingMutations {
+func (m *TxDb) NewBatch() ethdb.DbWithPendingMutations {
 	return &mutation{
 		db:   m,
 		puts: btree.New(32),
 	}
 }
 
-func (m *TxDb) begin(ctx context.Context, flags TxFlags) error {
-	kv := m.db.(HasRwKV).RwKV()
+func (m *TxDb) begin(ctx context.Context, flags ethdb.TxFlags) error {
+	kv := m.db.(ethdb.HasRwKV).RwKV()
 
-	var tx Tx
+	var tx ethdb.Tx
 	var err error
-	if flags&RO != 0 {
+	if flags&ethdb.RO != 0 {
 		tx, err = kv.BeginRo(ctx)
 	} else {
 		tx, err = kv.BeginRw(ctx)
@@ -212,11 +213,11 @@ func (m *TxDb) begin(ctx context.Context, flags TxFlags) error {
 		return err
 	}
 	m.tx = tx
-	m.cursors = make(map[string]Cursor, 16)
+	m.cursors = make(map[string]ethdb.Cursor, 16)
 	return nil
 }
 
-func (m *TxDb) RwKV() RwKV {
+func (m *TxDb) RwKV() ethdb.RwKV {
 	panic("not allowed to get KV interface because you will loose transaction, please use .Tx() method")
 }
 
@@ -240,7 +241,7 @@ func (m *TxDb) GetOne(bucket string, key []byte) ([]byte, error) {
 
 func (m *TxDb) Get(bucket string, key []byte) ([]byte, error) {
 	dat, err := m.GetOne(bucket, key)
-	return getOneWrapper(dat, err)
+	return ethdb.GetOneWrapper(dat, err)
 }
 
 func (m *TxDb) Has(bucket string, key []byte) (bool, error) {
@@ -252,7 +253,7 @@ func (m *TxDb) Has(bucket string, key []byte) (bool, error) {
 }
 
 func (m *TxDb) MultiPut(tuples ...[]byte) (uint64, error) {
-	return 0, MultiPut(m.tx.(RwTx), tuples...)
+	return 0, ethdb.MultiPut(m.tx.(ethdb.RwTx), tuples...)
 }
 
 func (m *TxDb) BatchSize() int {
@@ -278,7 +279,7 @@ func (m *TxDb) Walk(bucket string, startkey []byte, fixedbits int, walker func([
 			m.cursors[bucket] = c
 		}
 	}()
-	return Walk(c, startkey, fixedbits, walker)
+	return ethdb.Walk(c, startkey, fixedbits, walker)
 }
 func (m *TxDb) ForEach(bucket string, fromPrefix []byte, walker func(k, v []byte) error) error {
 	return m.tx.ForEach(bucket, fromPrefix, walker)
@@ -329,7 +330,7 @@ func (m *TxDb) Rollback() {
 	m.len = 0
 }
 
-func (m *TxDb) Tx() Tx {
+func (m *TxDb) Tx() ethdb.Tx {
 	return m.tx
 }
 
@@ -339,7 +340,7 @@ func (m *TxDb) Keys() ([][]byte, error) {
 
 func (m *TxDb) BucketExists(name string) (bool, error) {
 	exists := false
-	migrator, ok := m.tx.(BucketMigrator)
+	migrator, ok := m.tx.(ethdb.BucketMigrator)
 	if !ok {
 		return false, fmt.Errorf("%T doesn't implement ethdb.TxMigrator interface", m.tx)
 	}
@@ -351,7 +352,7 @@ func (m *TxDb) ClearBuckets(buckets ...string) error {
 	for i := range buckets {
 		name := buckets[i]
 
-		migrator, ok := m.tx.(BucketMigrator)
+		migrator, ok := m.tx.(ethdb.BucketMigrator)
 		if !ok {
 			return fmt.Errorf("%T doesn't implement ethdb.TxMigrator interface", m.tx)
 		}
@@ -367,7 +368,7 @@ func (m *TxDb) DropBuckets(buckets ...string) error {
 	for i := range buckets {
 		name := buckets[i]
 		log.Info("Dropping bucket", "name", name)
-		migrator, ok := m.tx.(BucketMigrator)
+		migrator, ok := m.tx.(ethdb.BucketMigrator)
 		if !ok {
 			return fmt.Errorf("%T doesn't implement ethdb.TxMigrator interface", m.tx)
 		}
diff --git a/ethdb/kv_abstract.go b/ethdb/kv_interface.go
similarity index 85%
rename from ethdb/kv_abstract.go
rename to ethdb/kv_interface.go
index ac451f06cb..b1b072263f 100644
--- a/ethdb/kv_abstract.go
+++ b/ethdb/kv_interface.go
@@ -15,34 +15,36 @@ var (
 	ErrAttemptToDeleteNonDeprecatedBucket = errors.New("only buckets from dbutils.DeprecatedBuckets can be deleted")
 	ErrUnknownBucket                      = errors.New("unknown bucket. add it to dbutils.Buckets")
 
-	dbSize    = metrics.GetOrRegisterGauge("db/size", metrics.DefaultRegistry)    //nolint
-	txLimit   = metrics.GetOrRegisterGauge("tx/limit", metrics.DefaultRegistry)   //nolint
-	txSpill   = metrics.GetOrRegisterGauge("tx/spill", metrics.DefaultRegistry)   //nolint
-	txUnspill = metrics.GetOrRegisterGauge("tx/unspill", metrics.DefaultRegistry) //nolint
-	txDirty   = metrics.GetOrRegisterGauge("tx/dirty", metrics.DefaultRegistry)   //nolint
-
-	dbCommitPreparation = metrics.GetOrRegisterTimer("db/commit/preparation", metrics.DefaultRegistry) //nolint
-	dbCommitGc          = metrics.GetOrRegisterTimer("db/commit/gc", metrics.DefaultRegistry)          //nolint
-	dbCommitAudit       = metrics.GetOrRegisterTimer("db/commit/audit", metrics.DefaultRegistry)       //nolint
-	dbCommitWrite       = metrics.GetOrRegisterTimer("db/commit/write", metrics.DefaultRegistry)       //nolint
-	dbCommitSync        = metrics.GetOrRegisterTimer("db/commit/sync", metrics.DefaultRegistry)        //nolint
-	dbCommitEnding      = metrics.GetOrRegisterTimer("db/commit/ending", metrics.DefaultRegistry)      //nolint
-
-	dbPgopsNewly   = metrics.GetOrRegisterGauge("db/pgops/newly", metrics.DefaultRegistry)   //nolint
-	dbPgopsCow     = metrics.GetOrRegisterGauge("db/pgops/cow", metrics.DefaultRegistry)     //nolint
-	dbPgopsClone   = metrics.GetOrRegisterGauge("db/pgops/clone", metrics.DefaultRegistry)   //nolint
-	dbPgopsSplit   = metrics.GetOrRegisterGauge("db/pgops/split", metrics.DefaultRegistry)   //nolint
-	dbPgopsMerge   = metrics.GetOrRegisterGauge("db/pgops/merge", metrics.DefaultRegistry)   //nolint
-	dbPgopsSpill   = metrics.GetOrRegisterGauge("db/pgops/spill", metrics.DefaultRegistry)   //nolint
-	dbPgopsUnspill = metrics.GetOrRegisterGauge("db/pgops/unspill", metrics.DefaultRegistry) //nolint
-	dbPgopsWops    = metrics.GetOrRegisterGauge("db/pgops/wops", metrics.DefaultRegistry)    //nolint
-
-	gcLeafMetric     = metrics.GetOrRegisterGauge("db/gc/leaf", metrics.DefaultRegistry)     //nolint
-	gcOverflowMetric = metrics.GetOrRegisterGauge("db/gc/overflow", metrics.DefaultRegistry) //nolint
-	gcPagesMetric    = metrics.GetOrRegisterGauge("db/gc/pages", metrics.DefaultRegistry)    //nolint
-
-	stateLeafMetric     = metrics.GetOrRegisterGauge("db/state/leaf", metrics.DefaultRegistry)   //nolint
-	stateBranchesMetric = metrics.GetOrRegisterGauge("db/state/branch", metrics.DefaultRegistry) //nolint
+	DbSize    = metrics.GetOrRegisterGauge("db/size", metrics.DefaultRegistry)    //nolint
+	TxLimit   = metrics.GetOrRegisterGauge("tx/limit", metrics.DefaultRegistry)   //nolint
+	TxSpill   = metrics.GetOrRegisterGauge("tx/spill", metrics.DefaultRegistry)   //nolint
+	TxUnspill = metrics.GetOrRegisterGauge("tx/unspill", metrics.DefaultRegistry) //nolint
+	TxDirty   = metrics.GetOrRegisterGauge("tx/dirty", metrics.DefaultRegistry)   //nolint
+
+	DbCommitPreparation = metrics.GetOrRegisterTimer("db/commit/preparation", metrics.DefaultRegistry) //nolint
+	DbCommitGc          = metrics.GetOrRegisterTimer("db/commit/gc", metrics.DefaultRegistry)          //nolint
+	DbCommitAudit       = metrics.GetOrRegisterTimer("db/commit/audit", metrics.DefaultRegistry)       //nolint
+	DbCommitWrite       = metrics.GetOrRegisterTimer("db/commit/write", metrics.DefaultRegistry)       //nolint
+	DbCommitSync        = metrics.GetOrRegisterTimer("db/commit/sync", metrics.DefaultRegistry)        //nolint
+	DbCommitEnding      = metrics.GetOrRegisterTimer("db/commit/ending", metrics.DefaultRegistry)      //nolint
+
+	DbPgopsNewly   = metrics.GetOrRegisterGauge("db/pgops/newly", metrics.DefaultRegistry)   //nolint
+	DbPgopsCow     = metrics.GetOrRegisterGauge("db/pgops/cow", metrics.DefaultRegistry)     //nolint
+	DbPgopsClone   = metrics.GetOrRegisterGauge("db/pgops/clone", metrics.DefaultRegistry)   //nolint
+	DbPgopsSplit   = metrics.GetOrRegisterGauge("db/pgops/split", metrics.DefaultRegistry)   //nolint
+	DbPgopsMerge   = metrics.GetOrRegisterGauge("db/pgops/merge", metrics.DefaultRegistry)   //nolint
+	DbPgopsSpill   = metrics.GetOrRegisterGauge("db/pgops/spill", metrics.DefaultRegistry)   //nolint
+	DbPgopsUnspill = metrics.GetOrRegisterGauge("db/pgops/unspill", metrics.DefaultRegistry) //nolint
+	DbPgopsWops    = metrics.GetOrRegisterGauge("db/pgops/wops", metrics.DefaultRegistry)    //nolint
+
+	GcLeafMetric     = metrics.GetOrRegisterGauge("db/gc/leaf", metrics.DefaultRegistry)     //nolint
+	GcOverflowMetric = metrics.GetOrRegisterGauge("db/gc/overflow", metrics.DefaultRegistry) //nolint
+	GcPagesMetric    = metrics.GetOrRegisterGauge("db/gc/pages", metrics.DefaultRegistry)    //nolint
+
+	StateLeafMetric     = metrics.GetOrRegisterGauge("db/state/leaf", metrics.DefaultRegistry)   //nolint
+	StateBranchesMetric = metrics.GetOrRegisterGauge("db/state/branch", metrics.DefaultRegistry) //nolint
+
+	DbCommitBigBatchTimer = metrics.NewRegisteredTimer("db/commit/big_batch", nil)
 )
 
 type DBVerbosityLvl int8
diff --git a/ethdb/kv_util.go b/ethdb/kv_util.go
index cd7c0fb871..0d89938aaa 100644
--- a/ethdb/kv_util.go
+++ b/ethdb/kv_util.go
@@ -4,8 +4,6 @@ import (
 	"bytes"
 	"errors"
 	"fmt"
-	"io/ioutil"
-	"os"
 	"time"
 
 	"github.com/ledgerwatch/erigon/common"
@@ -127,14 +125,6 @@ func MultiPut(tx RwTx, tuples ...[]byte) error {
 	return nil
 }
 
-func testKVPath() string {
-	dir, err := ioutil.TempDir(os.TempDir(), "erigon-test-db")
-	if err != nil {
-		panic(err)
-	}
-	return dir
-}
-
 // todo: return TEVM code and use it
 func GetCheckTEVM(db KVGetter) func(contractHash common.Hash) (bool, error) {
 	checked := map[common.Hash]struct{}{}
@@ -162,3 +152,13 @@ func GetCheckTEVM(db KVGetter) func(contractHash common.Hash) (bool, error) {
 		return ok, nil
 	}
 }
+
+func Bytesmask(fixedbits int) (fixedbytes int, mask byte) {
+	fixedbytes = (fixedbits + 7) / 8
+	shiftbits := fixedbits & 7
+	mask = byte(0xff)
+	if shiftbits != 0 {
+		mask = 0xff << (8 - shiftbits)
+	}
+	return fixedbytes, mask
+}
diff --git a/ethdb/rewind.go b/ethdb/rewind.go
deleted file mode 100644
index 08df9e8a00..0000000000
--- a/ethdb/rewind.go
+++ /dev/null
@@ -1 +0,0 @@
-package ethdb
diff --git a/ethdb/storage_mode_test.go b/ethdb/storage_mode_test.go
index 2eff2c1a03..7d452b522e 100644
--- a/ethdb/storage_mode_test.go
+++ b/ethdb/storage_mode_test.go
@@ -1,24 +1,26 @@
-package ethdb
+package ethdb_test
 
 import (
 	"reflect"
 	"testing"
 
 	"github.com/davecgh/go-spew/spew"
+	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func TestSetStorageModeIfNotExist(t *testing.T) {
-	_, tx := NewTestTx(t)
-	sm, err := GetStorageModeFromDB(tx)
+	_, tx := kv.NewTestTx(t)
+	sm, err := ethdb.GetStorageModeFromDB(tx)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if !reflect.DeepEqual(sm, StorageMode{Initialised: true}) {
+	if !reflect.DeepEqual(sm, ethdb.StorageMode{Initialised: true}) {
 		t.Fatal()
 	}
 
-	err = SetStorageModeIfNotExist(tx, StorageMode{
+	err = ethdb.SetStorageModeIfNotExist(tx, ethdb.StorageMode{
 		true,
 		true,
 		true,
@@ -30,12 +32,12 @@ func TestSetStorageModeIfNotExist(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	sm, err = GetStorageModeFromDB(tx)
+	sm, err = ethdb.GetStorageModeFromDB(tx)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if !reflect.DeepEqual(sm, StorageMode{
+	if !reflect.DeepEqual(sm, ethdb.StorageMode{
 		true,
 		true,
 		true,
diff --git a/migrations/header_prefix_test.go b/migrations/header_prefix_test.go
index 5550794905..8969a7f5d7 100644
--- a/migrations/header_prefix_test.go
+++ b/migrations/header_prefix_test.go
@@ -10,13 +10,14 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestHeaderPrefix(t *testing.T) {
 	require := require.New(t)
-	db := ethdb.NewTestDB(t)
+	db := kv.NewTestDB(t)
 
 	err := db.RwKV().Update(context.Background(), func(tx ethdb.RwTx) error {
 		err := tx.(ethdb.BucketMigrator).CreateBucket(dbutils.HeaderPrefixOld)
diff --git a/migrations/migrations_test.go b/migrations/migrations_test.go
index a20c03590f..8c39813587 100644
--- a/migrations/migrations_test.go
+++ b/migrations/migrations_test.go
@@ -6,6 +6,7 @@ import (
 	"testing"
 
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/common/etl"
@@ -14,7 +15,7 @@ import (
 )
 
 func TestApplyWithInit(t *testing.T) {
-	require, db := require.New(t), ethdb.NewTestDB(t)
+	require, db := require.New(t), kv.NewTestDB(t)
 	m := []Migration{
 		{
 			"one",
@@ -60,7 +61,7 @@ func TestApplyWithInit(t *testing.T) {
 }
 
 func TestApplyWithoutInit(t *testing.T) {
-	require, db := require.New(t), ethdb.NewTestDB(t)
+	require, db := require.New(t), kv.NewTestDB(t)
 	m := []Migration{
 		{
 			"one",
@@ -113,7 +114,7 @@ func TestApplyWithoutInit(t *testing.T) {
 }
 
 func TestWhenNonFirstMigrationAlreadyApplied(t *testing.T) {
-	require, db := require.New(t), ethdb.NewTestDB(t)
+	require, db := require.New(t), kv.NewTestDB(t)
 	m := []Migration{
 		{
 			"one",
@@ -164,7 +165,7 @@ func TestWhenNonFirstMigrationAlreadyApplied(t *testing.T) {
 }
 
 func TestMarshalStages(t *testing.T) {
-	require, db := require.New(t), ethdb.NewTestDB(t)
+	require, db := require.New(t), kv.NewTestDB(t)
 
 	err := stages.SaveStageProgress(db, stages.Execution, 42)
 	require.NoError(err)
@@ -182,7 +183,7 @@ func TestMarshalStages(t *testing.T) {
 }
 
 func TestValidation(t *testing.T) {
-	require, db := require.New(t), ethdb.NewTestDB(t)
+	require, db := require.New(t), kv.NewTestDB(t)
 	m := []Migration{
 		{
 			Name: "repeated_name",
@@ -213,7 +214,7 @@ func TestValidation(t *testing.T) {
 }
 
 func TestCommitCallRequired(t *testing.T) {
-	require, db := require.New(t), ethdb.NewTestDB(t)
+	require, db := require.New(t), kv.NewTestDB(t)
 	m := []Migration{
 		{
 			Name: "one",
diff --git a/node/node.go b/node/node.go
index 22b424c06a..380c04a611 100644
--- a/node/node.go
+++ b/node/node.go
@@ -29,6 +29,7 @@ import (
 
 	"github.com/ledgerwatch/erigon/common/debug"
 	"github.com/ledgerwatch/erigon/ethdb"
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/migrations"
 	"github.com/ledgerwatch/erigon/p2p"
@@ -505,7 +506,7 @@ func (n *Node) WSEndpoint() string {
 // OpenDatabase opens an existing database with the given name (or creates one if no
 // previous can be found) from within the node's instance directory. If the node is
 // ephemeral, a memory database is returned.
-func (n *Node) OpenDatabase(label ethdb.Label, datadir string) (*ethdb.ObjectDatabase, error) {
+func (n *Node) OpenDatabase(label ethdb.Label, datadir string) (*kv2.ObjectDatabase, error) {
 	n.lock.Lock()
 	defer n.lock.Unlock()
 
@@ -522,18 +523,18 @@ func (n *Node) OpenDatabase(label ethdb.Label, datadir string) (*ethdb.ObjectDat
 	default:
 		name = "test"
 	}
-	var db *ethdb.ObjectDatabase
+	var db *kv2.ObjectDatabase
 	if n.config.DataDir == "" {
-		db = ethdb.NewMemDatabase()
+		db = kv2.NewMemDatabase()
 		n.databases = append(n.databases, db)
 		return db, nil
 	}
 	dbPath := n.config.ResolvePath(name)
 
-	var openFunc func(exclusive bool) (*ethdb.ObjectDatabase, error)
+	var openFunc func(exclusive bool) (*kv2.ObjectDatabase, error)
 	log.Info("Opening Database", "label", name)
-	openFunc = func(exclusive bool) (*ethdb.ObjectDatabase, error) {
-		opts := ethdb.NewMDBX().Path(dbPath).DBVerbosity(n.config.DatabaseVerbosity)
+	openFunc = func(exclusive bool) (*kv2.ObjectDatabase, error) {
+		opts := kv2.NewMDBX().Path(dbPath).DBVerbosity(n.config.DatabaseVerbosity)
 		if exclusive {
 			opts = opts.Exclusive()
 		}
@@ -541,7 +542,7 @@ func (n *Node) OpenDatabase(label ethdb.Label, datadir string) (*ethdb.ObjectDat
 		if err1 != nil {
 			return nil, err1
 		}
-		return ethdb.NewObjectDatabase(kv), nil
+		return kv2.NewObjectDatabase(kv), nil
 	}
 	var err error
 	db, err = openFunc(false)
diff --git a/p2p/enode/nodedb.go b/p2p/enode/nodedb.go
index 9dbbbc4206..3cf545a9c2 100644
--- a/p2p/enode/nodedb.go
+++ b/p2p/enode/nodedb.go
@@ -29,6 +29,7 @@ import (
 	"time"
 
 	"github.com/c2h5oh/datasize"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
@@ -97,7 +98,7 @@ var bucketsConfig = func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 func newMemoryDB() (*DB, error) {
 	db := &DB{quit: make(chan struct{})}
 	var err error
-	db.kv, err = ethdb.NewMDBX().InMem().Label(ethdb.Sentry).WithBucketsConfig(bucketsConfig).Open()
+	db.kv, err = kv.NewMDBX().InMem().Label(ethdb.Sentry).WithBucketsConfig(bucketsConfig).Open()
 	if err != nil {
 		return nil, err
 	}
@@ -107,9 +108,9 @@ func newMemoryDB() (*DB, error) {
 // newPersistentNodeDB creates/opens a persistent node database,
 // also flushing its contents in case of a version mismatch.
 func newPersistentDB(path string) (*DB, error) {
-	var kv ethdb.RwKV
+	var db ethdb.RwKV
 	var err error
-	kv, err = ethdb.NewMDBX().Path(path).Label(ethdb.Sentry).MapSize(64 * datasize.MB).WithBucketsConfig(bucketsConfig).Open()
+	db, err = kv.NewMDBX().Path(path).Label(ethdb.Sentry).MapSize(64 * datasize.MB).WithBucketsConfig(bucketsConfig).Open()
 	if err != nil {
 		return nil, err
 	}
@@ -119,7 +120,7 @@ func newPersistentDB(path string) (*DB, error) {
 	currentVer = currentVer[:binary.PutVarint(currentVer, int64(dbVersion))]
 
 	var blob []byte
-	if err := kv.Update(context.Background(), func(tx ethdb.RwTx) error {
+	if err := db.Update(context.Background(), func(tx ethdb.RwTx) error {
 		c, err := tx.RwCursor(dbutils.InodesBucket)
 		if err != nil {
 			return err
@@ -139,13 +140,13 @@ func newPersistentDB(path string) (*DB, error) {
 		return nil, err
 	}
 	if blob != nil && !bytes.Equal(blob, currentVer) {
-		kv.Close()
+		db.Close()
 		if err := os.Remove(path); err != nil {
 			return nil, err
 		}
 		return newPersistentDB(path)
 	}
-	return &DB{kv: kv, quit: make(chan struct{})}, nil
+	return &DB{kv: db, quit: make(chan struct{})}, nil
 }
 
 // nodeKey returns the database key for a node record.
diff --git a/tests/state_test.go b/tests/state_test.go
index 486f633647..f787ab9835 100644
--- a/tests/state_test.go
+++ b/tests/state_test.go
@@ -26,7 +26,7 @@ import (
 	"testing"
 
 	"github.com/ledgerwatch/erigon/core/vm"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func TestState(t *testing.T) {
@@ -72,7 +72,7 @@ func TestState(t *testing.T) {
 		legacyStateTestDir,
 	} {
 		st.walk(t, dir, func(t *testing.T, name string, test *StateTest) {
-			db := ethdb.NewTestKV(t)
+			db := kv.NewTestKV(t)
 			for _, subtest := range test.Subtests() {
 				subtest := subtest
 				key := fmt.Sprintf("%s/%d", subtest.Fork, subtest.Index)
diff --git a/tests/state_test_util.go b/tests/state_test_util.go
index 351265430e..f1660e3ded 100644
--- a/tests/state_test_util.go
+++ b/tests/state_test_util.go
@@ -35,6 +35,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/rlp"
 	"github.com/ledgerwatch/erigon/turbo/trie"
@@ -178,7 +179,7 @@ func (t *StateTest) Run(ctx context.Context, tx ethdb.RwTx, subtest StateSubtest
 
 // RunNoVerify runs a specific subtest and returns the statedb and post-state root
 func (t *StateTest) RunNoVerify(ctx context.Context, kvtx ethdb.RwTx, subtest StateSubtest, vmconfig vm.Config) (*state.IntraBlockState, common.Hash, error) {
-	tx := ethdb.WrapIntoTxDB(kvtx)
+	tx := kv.WrapIntoTxDB(kvtx)
 	config, eips, err := GetChainConfig(subtest.Fork)
 	if err != nil {
 		return nil, common.Hash{}, UnsupportedForkError{subtest.Fork}
diff --git a/tests/statedb_chain_test.go b/tests/statedb_chain_test.go
index 0b6ffddb78..251ea2c1fa 100644
--- a/tests/statedb_chain_test.go
+++ b/tests/statedb_chain_test.go
@@ -21,6 +21,7 @@ import (
 	"testing"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 
 	"github.com/ledgerwatch/erigon/accounts/abi/bind"
 	"github.com/ledgerwatch/erigon/accounts/abi/bind/backends"
@@ -29,7 +30,6 @@ import (
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/tests/contracts"
 	"github.com/ledgerwatch/erigon/turbo/stages"
@@ -60,7 +60,7 @@ func TestSelfDestructReceive(t *testing.T) {
 	)
 
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	contractBackend := backends.NewSimulatedBackendWithConfig(gspec.Alloc, gspec.Config, gspec.GasLimit)
diff --git a/tests/vm_test.go b/tests/vm_test.go
index fe0647edbe..e63e9eb3b3 100644
--- a/tests/vm_test.go
+++ b/tests/vm_test.go
@@ -21,7 +21,7 @@ import (
 	"testing"
 
 	"github.com/ledgerwatch/erigon/core/vm"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func TestVM(t *testing.T) {
@@ -30,7 +30,7 @@ func TestVM(t *testing.T) {
 	vmt.slow("^vmPerformance")
 	vmt.fails("^vmSystemOperationsTest.json/createNameRegistrator$", "fails without parallel execution")
 
-	db := ethdb.NewTestKV(t)
+	db := kv.NewTestKV(t)
 
 	vmt.walk(t, vmTestDir, func(t *testing.T, name string, test *VMTest) {
 		withTrace(t, test.json.Exec.GasLimit, func(vmconfig vm.Config) error {
diff --git a/tests/vm_test_util.go b/tests/vm_test_util.go
index 8a0093bd40..94ca206b08 100644
--- a/tests/vm_test_util.go
+++ b/tests/vm_test_util.go
@@ -24,6 +24,7 @@ import (
 	"math/big"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/turbo/trie"
 
 	"github.com/ledgerwatch/erigon/common"
@@ -83,7 +84,7 @@ type vmExecMarshaling struct {
 
 func (t *VMTest) Run(tx ethdb.RwTx, vmconfig vm.Config, blockNr uint64) error {
 	ctx := params.MainnetChainConfig.WithEIPsFlags(context.Background(), blockNr)
-	state, err := MakePreState(ctx, ethdb.WrapIntoTxDB(tx), t.json.Pre, blockNr)
+	state, err := MakePreState(ctx, kv.WrapIntoTxDB(tx), t.json.Pre, blockNr)
 	if err != nil {
 		return fmt.Errorf("error in MakePreState: %v", err)
 	}
diff --git a/turbo/snapshotsync/postprocessing.go b/turbo/snapshotsync/postprocessing.go
index 8f21b901b7..896deca5f7 100644
--- a/turbo/snapshotsync/postprocessing.go
+++ b/turbo/snapshotsync/postprocessing.go
@@ -15,6 +15,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/rlp"
 )
@@ -73,7 +74,7 @@ func PostProcessBodies(db ethdb.Database) error {
 	if v > 0 {
 		return nil
 	}
-	err = db.(*ethdb.ObjectDatabase).ClearBuckets(dbutils.TxLookupPrefix)
+	err = db.(*kv.ObjectDatabase).ClearBuckets(dbutils.TxLookupPrefix)
 	if err != nil {
 		return err
 	}
@@ -125,7 +126,7 @@ func PostProcessState(db ethdb.GetterPutter, info *SnapshotsInfo) error {
 		return nil
 	}
 	// clear genesis state
-	err = db.(*ethdb.ObjectDatabase).ClearBuckets(dbutils.PlainStateBucket, dbutils.EthTx)
+	err = db.(*kv.ObjectDatabase).ClearBuckets(dbutils.PlainStateBucket, dbutils.EthTx)
 	if err != nil {
 		return err
 	}
diff --git a/turbo/snapshotsync/postprocessing_test.go b/turbo/snapshotsync/postprocessing_test.go
index 7342cec265..0d01f7bb95 100644
--- a/turbo/snapshotsync/postprocessing_test.go
+++ b/turbo/snapshotsync/postprocessing_test.go
@@ -10,13 +10,14 @@ import (
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/ethdb/mdbx"
 	"github.com/ledgerwatch/erigon/rlp"
 )
 
 func TestHeadersGenerateIndex(t *testing.T) {
 	snPath := t.TempDir()
-	snVK := ethdb.NewMDBX().Path(snPath).MustOpen()
+	snVK := kv.NewMDBX().Path(snPath).MustOpen()
 	defer os.RemoveAll(snPath)
 	headers := generateHeaders(10)
 	err := snVK.Update(context.Background(), func(tx ethdb.RwTx) error {
@@ -50,24 +51,24 @@ func TestHeadersGenerateIndex(t *testing.T) {
 	}
 	snVK.Close()
 
-	db := ethdb.NewMDBX().InMem().WithBucketsConfig(ethdb.DefaultBucketConfigs).MustOpen()
+	db := kv.NewMDBX().InMem().WithBucketsConfig(kv.DefaultBucketConfigs).MustOpen()
 	defer db.Close()
 	//we need genesis
-	err = rawdb.WriteCanonicalHash(ethdb.NewObjectDatabase(db), headers[0].Hash(), headers[0].Number.Uint64())
+	err = rawdb.WriteCanonicalHash(kv.NewObjectDatabase(db), headers[0].Hash(), headers[0].Number.Uint64())
 	if err != nil {
 		t.Fatal(err)
 	}
 	var snKV ethdb.RwKV
-	snKV = ethdb.NewMDBX().Path(snPath).Flags(func(flags uint) uint { return flags | mdbx.Readonly }).WithBucketsConfig(ethdb.DefaultBucketConfigs).MustOpen()
+	snKV = kv.NewMDBX().Path(snPath).Flags(func(flags uint) uint { return flags | mdbx.Readonly }).WithBucketsConfig(kv.DefaultBucketConfigs).MustOpen()
 	defer snKV.Close()
 
-	snKV = ethdb.NewSnapshotKV().SnapshotDB([]string{dbutils.HeadersSnapshotInfoBucket, dbutils.HeadersBucket}, snKV).DB(db).Open()
-	snDb := ethdb.NewObjectDatabase(snKV)
+	snKV = kv.NewSnapshotKV().SnapshotDB([]string{dbutils.HeadersSnapshotInfoBucket, dbutils.HeadersBucket}, snKV).DB(db).Open()
+	snDb := kv.NewObjectDatabase(snKV)
 	err = GenerateHeaderIndexes(context.Background(), snDb)
 	if err != nil {
 		t.Fatal(err)
 	}
-	snDB := ethdb.NewObjectDatabase(snKV)
+	snDB := kv.NewObjectDatabase(snKV)
 	td := big.NewInt(0)
 	for i, header := range headers {
 		td = td.Add(td, header.Difficulty)
diff --git a/turbo/snapshotsync/server.go b/turbo/snapshotsync/server.go
index d89fa9f325..d5e655c456 100644
--- a/turbo/snapshotsync/server.go
+++ b/turbo/snapshotsync/server.go
@@ -9,6 +9,7 @@ import (
 	"github.com/golang/protobuf/ptypes/empty"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 var (
@@ -20,7 +21,7 @@ var (
 )
 
 func NewServer(dir string, seeding bool) (*SNDownloaderServer, error) {
-	db := ethdb.MustOpen(dir + "/db")
+	db := kv.MustOpen(dir + "/db")
 	peerID, err := db.Get(dbutils.BittorrentInfoBucket, []byte(dbutils.BittorrentPeerID))
 	if err != nil && !errors.Is(err, ethdb.ErrKeyNotFound) {
 		return nil, fmt.Errorf("get peer id: %w", err)
diff --git a/turbo/snapshotsync/snapshot_builder.go b/turbo/snapshotsync/snapshot_builder.go
index 60b635a180..76e6df7fc3 100644
--- a/turbo/snapshotsync/snapshot_builder.go
+++ b/turbo/snapshotsync/snapshot_builder.go
@@ -13,6 +13,7 @@ import (
 	"sync/atomic"
 	"time"
 
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 
 	"github.com/anacrolix/torrent/metainfo"
@@ -58,7 +59,7 @@ func (sm *SnapshotMigrator) AsyncStages(migrateToBlock uint64, dbi ethdb.RwKV, r
 		},
 		func(db ethdb.RoKV, tx ethdb.Tx, toBlock uint64) error {
 			//replace snapshot
-			if _, ok := db.(ethdb.SnapshotUpdater); !ok {
+			if _, ok := db.(kv.SnapshotUpdater); !ok {
 				return errors.New("db don't implement snapshotUpdater interface")
 			}
 			snapshotKV, err := OpenHeadersSnapshot(snapshotPath)
@@ -66,7 +67,7 @@ func (sm *SnapshotMigrator) AsyncStages(migrateToBlock uint64, dbi ethdb.RwKV, r
 				return err
 			}
 
-			db.(ethdb.SnapshotUpdater).UpdateSnapshots([]string{dbutils.HeadersBucket}, snapshotKV, sm.replaceChan)
+			db.(kv.SnapshotUpdater).UpdateSnapshots([]string{dbutils.HeadersBucket}, snapshotKV, sm.replaceChan)
 			return nil
 		},
 		func(db ethdb.RoKV, tx ethdb.Tx, toBlock uint64) error {
@@ -300,7 +301,7 @@ func GetSnapshotInfo(db ethdb.RwKV) (uint64, []byte, error) {
 }
 
 func OpenHeadersSnapshot(dbPath string) (ethdb.RwKV, error) {
-	return ethdb.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+	return kv.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return dbutils.BucketsCfg{
 			dbutils.HeadersBucket: dbutils.BucketsConfigs[dbutils.HeadersBucket],
 		}
@@ -314,7 +315,7 @@ func CreateHeadersSnapshot(ctx context.Context, readTX ethdb.Tx, toBlock uint64,
 		return err
 	}
 	var snKV ethdb.RwKV
-	snKV, err = ethdb.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+	snKV, err = kv.NewMDBX().WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 		return dbutils.BucketsCfg{
 			dbutils.HeadersBucket: dbutils.BucketsConfigs[dbutils.HeadersBucket],
 		}
@@ -380,15 +381,15 @@ func GenerateHeadersSnapshot(ctx context.Context, db ethdb.Tx, sntx ethdb.RwTx,
 
 func RemoveHeadersData(db ethdb.RoKV, tx ethdb.RwTx, currentSnapshot, newSnapshot uint64) (err error) {
 	log.Info("Remove data", "from", currentSnapshot, "to", newSnapshot)
-	if _, ok := db.(ethdb.SnapshotUpdater); !ok {
+	if _, ok := db.(kv.SnapshotUpdater); !ok {
 		return errors.New("db don't implement snapshotUpdater interface")
 	}
-	headerSnapshot := db.(ethdb.SnapshotUpdater).SnapshotKV(dbutils.HeadersBucket)
+	headerSnapshot := db.(kv.SnapshotUpdater).SnapshotKV(dbutils.HeadersBucket)
 	if headerSnapshot == nil {
 		log.Info("headerSnapshot is empty")
 		return nil
 	}
-	writeTX := tx.(ethdb.DBTX).DBTX()
+	writeTX := tx.(kv.DBTX).DBTX()
 	c, err := writeTX.RwCursor(dbutils.HeadersBucket)
 	if err != nil {
 		return fmt.Errorf("get headers cursor %w", err)
diff --git a/turbo/snapshotsync/snapshot_builder_test.go b/turbo/snapshotsync/snapshot_builder_test.go
index c7cd3eb4c7..9170229f0a 100644
--- a/turbo/snapshotsync/snapshot_builder_test.go
+++ b/turbo/snapshotsync/snapshot_builder_test.go
@@ -14,6 +14,7 @@ import (
 	"testing"
 	"time"
 
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 
 	"github.com/stretchr/testify/require"
@@ -62,7 +63,7 @@ func TestSnapshotMigratorStage(t *testing.T) {
 	}
 	btCli.trackers = [][]string{}
 
-	db := ethdb.NewSnapshotKV().DB(ethdb.MustOpenKV(path.Join(dir, "chaindata"))).Open()
+	db := kv.NewSnapshotKV().DB(kv.MustOpenKV(path.Join(dir, "chaindata"))).Open()
 	quit := make(chan struct{})
 	defer func() {
 		close(quit)
@@ -407,7 +408,7 @@ func TestSnapshotMigratorStageSyncMode(t *testing.T) {
 	}
 	btCli.trackers = [][]string{}
 
-	db := ethdb.NewSnapshotKV().DB(ethdb.MustOpenKV(path.Join(dir, "chaindata"))).Open()
+	db := kv.NewSnapshotKV().DB(kv.MustOpenKV(path.Join(dir, "chaindata"))).Open()
 	quit := make(chan struct{})
 	defer func() {
 		close(quit)
diff --git a/turbo/snapshotsync/wrapdb.go b/turbo/snapshotsync/wrapdb.go
index 6aed895611..7d07875962 100644
--- a/turbo/snapshotsync/wrapdb.go
+++ b/turbo/snapshotsync/wrapdb.go
@@ -8,6 +8,7 @@ import (
 
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/ethdb"
+	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 )
 
@@ -40,11 +41,11 @@ func WrapBySnapshotsFromDir(kv ethdb.RwKV, snapshotDir string, mode SnapshotMode
 }
 
 func WrapBySnapshotsFromDownloader(kv ethdb.RwKV, snapshots map[SnapshotType]*SnapshotsInfo) (ethdb.RwKV, error) {
-	snKV := ethdb.NewSnapshotKV().DB(kv)
+	snKV := kv2.NewSnapshotKV().DB(kv)
 	for k, v := range snapshots {
 		log.Info("Wrap db by", "snapshot", k.String(), "dir", v.Dbpath)
 		cfg := BucketConfigs[k]
-		snapshotKV, err := ethdb.NewMDBX().Readonly().Path(v.Dbpath).WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
+		snapshotKV, err := kv2.NewMDBX().Readonly().Path(v.Dbpath).WithBucketsConfig(func(defaultBuckets dbutils.BucketsCfg) dbutils.BucketsCfg {
 			return cfg
 		}).Open()
 
@@ -69,7 +70,7 @@ func WrapSnapshots(chainDb ethdb.Database, snapshotsDir string) error {
 	if err != nil && !errors.Is(err, ethdb.ErrKeyNotFound) {
 		return err
 	}
-	snKVOpts := ethdb.NewSnapshotKV().DB(chainDb.(ethdb.HasRwKV).RwKV())
+	snKVOpts := kv2.NewSnapshotKV().DB(chainDb.(ethdb.HasRwKV).RwKV())
 	if len(snapshotBlock) == 8 {
 		snKV, innerErr := OpenHeadersSnapshot(SnapshotName(snapshotsDir, "headers", binary.BigEndian.Uint64(snapshotBlock)))
 		if innerErr != nil {
diff --git a/turbo/stages/blockchain_test.go b/turbo/stages/blockchain_test.go
index 35f924f41c..0de1f20b27 100644
--- a/turbo/stages/blockchain_test.go
+++ b/turbo/stages/blockchain_test.go
@@ -25,6 +25,7 @@ import (
 	"testing"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 
@@ -363,7 +364,7 @@ func testBadHashes(t *testing.T) {
 	t.Skip("to support this error in Erigon")
 	// Create a pristine chain and database
 	m := newCanonical(t, 0)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 	var err error
 
@@ -563,7 +564,7 @@ func TestEIP155Transition(t *testing.T) {
 		}
 	)
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	chain, chainErr := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 4, func(i int, block *core.BlockGen) {
@@ -821,7 +822,7 @@ func TestEIP161AccountRemoval(t *testing.T) {
 		}
 	)
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 3, func(i int, block *core.BlockGen) {
@@ -886,7 +887,7 @@ func TestDoubleAccountRemoval(t *testing.T) {
 		}
 	)
 	m := stages.MockWithGenesis(t, gspec, bankKey)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	var theAddr common.Address
@@ -1279,7 +1280,7 @@ func TestDeleteRecreateSlots(t *testing.T) {
 		},
 	}
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 	chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *core.BlockGen) {
 		b.SetCoinbase(common.Address{1})
@@ -1361,7 +1362,7 @@ func TestDeleteRecreateAccount(t *testing.T) {
 		},
 	}
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *core.BlockGen) {
@@ -1485,7 +1486,7 @@ func TestDeleteRecreateSlotsAcrossManyBlocks(t *testing.T) {
 		},
 	}
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 	var nonce uint64
 
@@ -1672,7 +1673,7 @@ func TestInitThenFailCreateContract(t *testing.T) {
 		},
 	}
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 	nonce := uint64(0)
 
@@ -1746,7 +1747,7 @@ func TestEIP2718Transition(t *testing.T) {
 		}
 	)
 	m := stages.MockWithGenesis(t, gspec, key)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 1, func(i int, b *core.BlockGen) {
@@ -1843,7 +1844,7 @@ func TestEIP1559Transition(t *testing.T) {
 		signer = types.LatestSigner(gspec.Config)
 	)
 	m := stages.MockWithGenesis(t, gspec, key1)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 	defer db.Close()
 
 	chain, err := core.GenerateChain(m.ChainConfig, m.Genesis, m.Engine, m.DB, 501, func(i int, b *core.BlockGen) {
diff --git a/turbo/stages/bodydownload/body_test.go b/turbo/stages/bodydownload/body_test.go
index e02d46e26a..1679e5f31f 100644
--- a/turbo/stages/bodydownload/body_test.go
+++ b/turbo/stages/bodydownload/body_test.go
@@ -4,11 +4,11 @@ import (
 	"testing"
 
 	"github.com/ledgerwatch/erigon/consensus/ethash"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func TestCreateBodyDownload(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 	bd := NewBodyDownload(100, ethash.NewFaker())
 	if _, _, _, err := bd.UpdateFromDb(tx); err != nil {
 		t.Fatalf("update from db: %v", err)
diff --git a/turbo/stages/chain_makers_test.go b/turbo/stages/chain_makers_test.go
index 7b0de2a2f9..965f2bb75d 100644
--- a/turbo/stages/chain_makers_test.go
+++ b/turbo/stages/chain_makers_test.go
@@ -22,13 +22,13 @@ import (
 	"testing"
 
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/turbo/stages"
 
 	"github.com/ledgerwatch/erigon/core"
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
 )
@@ -55,7 +55,7 @@ func TestGenerateChain(t *testing.T) {
 		Alloc:  core.GenesisAlloc{addr1: {Balance: big.NewInt(1000000)}},
 	}
 	m := stages.MockWithGenesis(t, gspec, key1)
-	db := ethdb.NewObjectDatabase(m.DB)
+	db := kv.NewObjectDatabase(m.DB)
 
 	// This call generates a chain of 5 blocks. The function runs for
 	// each block and adds different features to gen based on the
diff --git a/turbo/stages/genesis_test.go b/turbo/stages/genesis_test.go
index 79902c6d24..0212b90f5d 100644
--- a/turbo/stages/genesis_test.go
+++ b/turbo/stages/genesis_test.go
@@ -30,6 +30,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/rlp"
 	"github.com/ledgerwatch/erigon/turbo/stages"
@@ -224,7 +225,7 @@ func TestSetupGenesis(t *testing.T) {
 	for _, test := range tests {
 		test := test
 		t.Run(test.name, func(t *testing.T) {
-			db := ethdb.NewTestKV(t)
+			db := kv.NewTestKV(t)
 			config, genesis, err := test.fn(db)
 			// Check the return values.
 			if !reflect.DeepEqual(err, test.wantErr) {
diff --git a/turbo/stages/headerdownload/header_algo_test.go b/turbo/stages/headerdownload/header_algo_test.go
index 9cc377c3f1..34f1d8ed3c 100644
--- a/turbo/stages/headerdownload/header_algo_test.go
+++ b/turbo/stages/headerdownload/header_algo_test.go
@@ -7,11 +7,11 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/core/rawdb"
 	"github.com/ledgerwatch/erigon/core/types"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 )
 
 func TestInserter1(t *testing.T) {
-	_, tx := ethdb.NewTestTx(t)
+	_, tx := kv.NewTestTx(t)
 	// Set up parent difficulty
 	if err := rawdb.WriteTd(tx, common.Hash{}, 4, big.NewInt(0)); err != nil {
 		t.Fatalf("write parent diff: %v", err)
diff --git a/turbo/stages/mock_sentry.go b/turbo/stages/mock_sentry.go
index e242bc716a..cece5992fc 100644
--- a/turbo/stages/mock_sentry.go
+++ b/turbo/stages/mock_sentry.go
@@ -25,6 +25,7 @@ import (
 	"github.com/ledgerwatch/erigon/eth/protocols/eth"
 	"github.com/ledgerwatch/erigon/eth/stagedsync"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/ethdb/remote/remotedbserver"
 	"github.com/ledgerwatch/erigon/gointerfaces"
 	proto_sentry "github.com/ledgerwatch/erigon/gointerfaces/sentry"
@@ -142,7 +143,7 @@ func MockWithEverything(t *testing.T, gspec *core.Genesis, key *ecdsa.PrivateKey
 	}
 	mock := &MockSentry{
 		t:           t,
-		DB:          ethdb.NewTestKV(t),
+		DB:          kv.NewTestKV(t),
 		tmpdir:      tmpdir,
 		Engine:      engine,
 		ChainConfig: gspec.Config,
diff --git a/turbo/stages/stageloop.go b/turbo/stages/stageloop.go
index 2226d432d9..aed73388ae 100644
--- a/turbo/stages/stageloop.go
+++ b/turbo/stages/stageloop.go
@@ -20,6 +20,7 @@ import (
 	"github.com/ledgerwatch/erigon/eth/stagedsync"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/ledgerwatch/erigon/params"
 	"github.com/ledgerwatch/erigon/turbo/shards"
@@ -146,7 +147,7 @@ func StageLoopStep(
 		return err
 	}
 
-	st, err1 := sync.Prepare(&vm.Config{}, ethdb.NewObjectDatabase(db), nil, sm, ctx.Done(), initialCycle, nil, accumulator)
+	st, err1 := sync.Prepare(&vm.Config{}, kv.NewObjectDatabase(db), nil, sm, ctx.Done(), initialCycle, nil, accumulator)
 	if err1 != nil {
 		return fmt.Errorf("prepare staged sync: %w", err1)
 	}
diff --git a/turbo/trie/flatdb_sub_trie_loader_test.go b/turbo/trie/flatdb_sub_trie_loader_test.go
index c8f3047976..bb211ac8d0 100644
--- a/turbo/trie/flatdb_sub_trie_loader_test.go
+++ b/turbo/trie/flatdb_sub_trie_loader_test.go
@@ -10,6 +10,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/types/accounts"
 	"github.com/ledgerwatch/erigon/crypto"
 	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
@@ -18,7 +19,7 @@ import (
 func TestResolve1(t *testing.T) {
 	t.Skip("weird case of abandoned storage, will handle it later")
 
-	require, assert, db := require.New(t), assert.New(t), ethdb.NewTestDB(t)
+	require, assert, db := require.New(t), assert.New(t), kv.NewTestDB(t)
 	putStorage := func(k string, v string) {
 		err := db.Put(dbutils.HashedAccountsBucket, common.Hex2Bytes(k), common.Hex2Bytes(v))
 		require.NoError(err)
@@ -39,7 +40,7 @@ func TestResolve1(t *testing.T) {
 func TestResolve2(t *testing.T) {
 	t.Skip("weird case of abandoned storage, will handle it later")
 
-	require, assert, db := require.New(t), assert.New(t), ethdb.NewTestDB(t)
+	require, assert, db := require.New(t), assert.New(t), kv.NewTestDB(t)
 	putStorage := func(k string, v string) {
 		err := db.Put(dbutils.HashedAccountsBucket, common.Hex2Bytes(k), common.Hex2Bytes(v))
 		require.NoError(err)
@@ -63,7 +64,7 @@ func TestResolve2(t *testing.T) {
 func TestResolve2Keep(t *testing.T) {
 	t.Skip("weird case of abandoned storage, will handle it later")
 
-	require, assert, db := require.New(t), assert.New(t), ethdb.NewTestDB(t)
+	require, assert, db := require.New(t), assert.New(t), kv.NewTestDB(t)
 	putStorage := func(k string, v string) {
 		err := db.Put(dbutils.HashedAccountsBucket, common.Hex2Bytes(k), common.Hex2Bytes(v))
 		require.NoError(err)
@@ -87,7 +88,7 @@ func TestResolve2Keep(t *testing.T) {
 func TestResolve3Keep(t *testing.T) {
 	t.Skip("weird case of abandoned storage, will handle it later")
 
-	require, assert, db := require.New(t), assert.New(t), ethdb.NewTestDB(t)
+	require, assert, db := require.New(t), assert.New(t), kv.NewTestDB(t)
 	putStorage := func(k string, v string) {
 		err := db.Put(dbutils.HashedAccountsBucket, common.Hex2Bytes(k), common.Hex2Bytes(v))
 		require.NoError(err)
@@ -112,7 +113,7 @@ func TestResolve3Keep(t *testing.T) {
 func TestTrieSubTrieLoader(t *testing.T) {
 	t.Skip("weird case of abandoned storage, will handle it later")
 
-	require, _, db := require.New(t), assert.New(t), ethdb.NewTestDB(t)
+	require, _, db := require.New(t), assert.New(t), kv.NewTestDB(t)
 	putStorage := func(k string, v string) {
 		err := db.Put(dbutils.HashedAccountsBucket, common.Hex2Bytes(k), common.Hex2Bytes(v))
 		require.NoError(err)
@@ -138,7 +139,7 @@ func TestTrieSubTrieLoader(t *testing.T) {
 func TestTwoStorageItems(t *testing.T) {
 	t.Skip("weird case of abandoned storage, will handle it later")
 
-	require, assert, db := require.New(t), assert.New(t), ethdb.NewTestDB(t)
+	require, assert, db := require.New(t), assert.New(t), kv.NewTestDB(t)
 
 	key1 := common.Hex2Bytes("d7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5f5")
 	key2 := common.Hex2Bytes("df6966c971051c3d54ec59162606531493a51404a002842f56009d7e5cf4a8c7f5")
@@ -195,7 +196,7 @@ func TestTwoStorageItems(t *testing.T) {
 
 func TestTwoAccounts(t *testing.T) {
 	t.Skip("to restore with new loader")
-	require, assert, db := require.New(t), assert.New(t), ethdb.NewTestDB(t)
+	require, assert, db := require.New(t), assert.New(t), kv.NewTestDB(t)
 	key1 := common.Hex2Bytes("03601462093b5945d1676df093446790fd31b20e7b12a2e8e5e09d068109616b")
 	acc := accounts.NewAccount()
 	acc.Initialised = true
@@ -231,7 +232,7 @@ func TestTwoAccounts(t *testing.T) {
 }
 
 func TestReturnErrOnWrongRootHash(t *testing.T) {
-	require, db := require.New(t), ethdb.NewTestDB(t)
+	require, db := require.New(t), kv.NewTestDB(t)
 	putAccount := func(k string) {
 		a := accounts.Account{}
 		err := writeAccount(db, common.BytesToHash(common.Hex2Bytes(k)), a)
diff --git a/turbo/trie/structural_branch_test.go b/turbo/trie/structural_branch_test.go
index abb8291ac8..6f65055b3f 100644
--- a/turbo/trie/structural_branch_test.go
+++ b/turbo/trie/structural_branch_test.go
@@ -24,14 +24,14 @@ import (
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
 	"github.com/ledgerwatch/erigon/eth/integrity"
-	"github.com/ledgerwatch/erigon/ethdb"
+	"github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/turbo/trie"
 	"github.com/stretchr/testify/assert"
 	"github.com/stretchr/testify/require"
 )
 
 func TestIHCursor(t *testing.T) {
-	db, require := ethdb.NewTestDB(t), require.New(t)
+	db, require := kv.NewTestDB(t), require.New(t)
 	hash := common.HexToHash(fmt.Sprintf("%064d", 0))
 
 	newV := make([]byte, 0, 1024)
-- 
GitLab