diff --git a/cmd/rpcdaemon/commands/debug_api.go b/cmd/rpcdaemon/commands/debug_api.go
index 9361c70dd4537bfd7aa2b6b4c23f0593089d01dc..e6a95a729f7edfbfe2c54e5280490e32ba702f02 100644
--- a/cmd/rpcdaemon/commands/debug_api.go
+++ b/cmd/rpcdaemon/commands/debug_api.go
@@ -59,12 +59,7 @@ func (api *PrivateDebugAPIImpl) StorageRangeAt(ctx context.Context, blockHash co
 
 	bc := adapter.NewBlockGetter(tx)
 	cc := adapter.NewChainContext(tx)
-	genesis, err := rawdb.ReadBlockByNumber(ethdb.NewRoTxDb(tx), 0)
-	if err != nil {
-		return StorageRangeResult{}, err
-	}
-	genesisHash := genesis.Hash()
-	chainConfig, err := rawdb.ReadChainConfig(ethdb.NewRoTxDb(tx), genesisHash)
+	chainConfig, err := api.chainConfig(tx)
 	if err != nil {
 		return StorageRangeResult{}, err
 	}
@@ -92,7 +87,7 @@ func (api *PrivateDebugAPIImpl) AccountRange(ctx context.Context, blockNrOrHash
 		if number == rpc.LatestBlockNumber {
 			var err error
 
-			blockNumber, err = stages.GetStageProgress(ethdb.NewRoTxDb(tx), stages.Execution)
+			blockNumber, err = stages.GetStageProgress(tx, stages.Execution)
 			if err != nil {
 				return state.IteratorDump{}, fmt.Errorf("last block has not found: %w", err)
 			}
@@ -126,7 +121,7 @@ func (api *PrivateDebugAPIImpl) AccountRange(ctx context.Context, blockNrOrHash
 		return state.IteratorDump{}, err
 	}
 	if hash != (common.Hash{}) {
-		header := rawdb.ReadHeader(ethdb.NewRoTxDb(tx), hash, blockNumber)
+		header := rawdb.ReadHeader(tx, hash, blockNumber)
 		if header != nil {
 			res.Root = header.Root.String()
 		}
@@ -143,7 +138,7 @@ func (api *PrivateDebugAPIImpl) GetModifiedAccountsByNumber(ctx context.Context,
 	}
 	defer tx.Rollback()
 
-	latestBlock, err := stages.GetStageProgress(ethdb.NewRoTxDb(tx), stages.Finish)
+	latestBlock, err := stages.GetStageProgress(tx, stages.Finish)
 	if err != nil {
 		return nil, err
 	}
@@ -217,12 +212,7 @@ func (api *PrivateDebugAPIImpl) AccountAt(ctx context.Context, blockHash common.
 
 	bc := adapter.NewBlockGetter(tx)
 	cc := adapter.NewChainContext(tx)
-	genesis, err := rawdb.ReadBlockByNumber(ethdb.NewRoTxDb(tx), 0)
-	if err != nil {
-		return nil, err
-	}
-	genesisHash := genesis.Hash()
-	chainConfig, err := rawdb.ReadChainConfig(ethdb.NewRoTxDb(tx), genesisHash)
+	chainConfig, err := api.chainConfig(tx)
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/rpcdaemon/commands/eth_api.go b/cmd/rpcdaemon/commands/eth_api.go
index 1d350a8a1f2d10d8222ad7ef24a1059e6bdc19ed..9ee9880b398cb4952646ac8c3ca48ea47dd9f2f8 100644
--- a/cmd/rpcdaemon/commands/eth_api.go
+++ b/cmd/rpcdaemon/commands/eth_api.go
@@ -114,7 +114,7 @@ func (api *BaseAPI) chainConfigWithGenesis(tx ethdb.Tx) (*params.ChainConfig, *t
 	if err != nil {
 		return nil, nil, err
 	}
-	cc, err := rawdb.ReadChainConfig(ethdb.NewRoTxDb(tx), genesisBlock.Hash())
+	cc, err := rawdb.ReadChainConfig(tx, genesisBlock.Hash())
 	if err != nil {
 		return nil, nil, err
 	}
diff --git a/cmd/rpcdaemon/commands/eth_block.go b/cmd/rpcdaemon/commands/eth_block.go
index ee7664de8d5bd9cb3b9c07a4357d145e9c3c1edc..16380155071c2339f069759b586422b993e51ab5 100644
--- a/cmd/rpcdaemon/commands/eth_block.go
+++ b/cmd/rpcdaemon/commands/eth_block.go
@@ -34,7 +34,7 @@ func (api *APIImpl) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber
 		return nil, nil // not error, see https://github.com/ledgerwatch/turbo-geth/issues/1645
 	}
 
-	td, err := rawdb.ReadTd(ethdb.NewRoTxDb(tx), block.Hash(), blockNum)
+	td, err := rawdb.ReadTd(tx, block.Hash(), blockNum)
 	if err != nil {
 		return nil, err
 	}
@@ -80,7 +80,7 @@ func (api *APIImpl) GetBlockByHash(ctx context.Context, numberOrHash rpc.BlockNu
 	}
 	number := block.NumberU64()
 
-	td, err := rawdb.ReadTd(ethdb.NewRoTxDb(tx), hash, number)
+	td, err := rawdb.ReadTd(tx, hash, number)
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go
index ae37db006602669124dd3a2885f602ac5fb62917..78bc6fa0946de63aec9e77aa992ebb121284463d 100644
--- a/cmd/rpcdaemon/commands/eth_receipts.go
+++ b/cmd/rpcdaemon/commands/eth_receipts.go
@@ -31,7 +31,7 @@ func getReceipts(ctx context.Context, tx ethdb.Tx, chainConfig *params.ChainConf
 	cc := adapter.NewChainContext(tx)
 	bc := adapter.NewBlockGetter(tx)
 	getHeader := func(hash common.Hash, number uint64) *types.Header {
-		return rawdb.ReadHeader(ethdb.NewRoTxDb(tx), hash, number)
+		return rawdb.ReadHeader(tx, hash, number)
 	}
 	_, _, _, ibs, dbstate, err := transactions.ComputeTxEnv(ctx, bc, chainConfig, getHeader, cc.Engine(), tx, hash, 0)
 	if err != nil {
@@ -44,7 +44,7 @@ func getReceipts(ctx context.Context, tx ethdb.Tx, chainConfig *params.ChainConf
 	for i, txn := range block.Transactions() {
 		ibs.Prepare(txn.Hash(), block.Hash(), i)
 
-		header := rawdb.ReadHeader(ethdb.NewRoTxDb(tx), hash, number)
+		header := rawdb.ReadHeader(tx, hash, number)
 		receipt, err := core.ApplyTransaction(chainConfig, getHeader, cc.Engine(), nil, gp, ibs, dbstate, header, txn, usedGas, vm.Config{})
 		if err != nil {
 			return nil, err
@@ -67,7 +67,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([
 	defer tx.Rollback()
 
 	if crit.BlockHash != nil {
-		number := rawdb.ReadHeaderNumber(ethdb.NewRoTxDb(tx), *crit.BlockHash)
+		number := rawdb.ReadHeaderNumber(tx, *crit.BlockHash)
 		if number == nil {
 			return nil, fmt.Errorf("block not found: %x", *crit.BlockHash)
 		}
@@ -135,7 +135,7 @@ func (api *APIImpl) GetLogs(ctx context.Context, crit filters.FilterCriteria) ([
 		return returnLogs(logs), err
 	}
 	for _, blockNToMatch := range blockNumbers.ToArray() {
-		blockHash, err := rawdb.ReadCanonicalHash(ethdb.NewRoTxDb(tx), uint64(blockNToMatch))
+		blockHash, err := rawdb.ReadCanonicalHash(tx, uint64(blockNToMatch))
 		if err != nil {
 			return returnLogs(logs), err
 		}
diff --git a/cmd/rpcdaemon/commands/eth_system.go b/cmd/rpcdaemon/commands/eth_system.go
index f2f6354e2d64fd374c19505d7baec31ce4d644c1..f8577ad2a7862aa622890006c0d1e66f6360e38c 100644
--- a/cmd/rpcdaemon/commands/eth_system.go
+++ b/cmd/rpcdaemon/commands/eth_system.go
@@ -24,7 +24,7 @@ func (api *APIImpl) BlockNumber(ctx context.Context) (hexutil.Uint64, error) {
 		return 0, err
 	}
 	defer tx.Rollback()
-	execution, err := stages.GetStageProgress(ethdb.NewRoTxDb(tx), stages.Finish)
+	execution, err := stages.GetStageProgress(tx, stages.Finish)
 	if err != nil {
 		return 0, err
 	}
@@ -38,12 +38,12 @@ func (api *APIImpl) Syncing(ctx context.Context) (interface{}, error) {
 		return nil, err
 	}
 	defer tx.Rollback()
-	highestBlock, err := stages.GetStageProgress(ethdb.NewRoTxDb(tx), stages.Headers)
+	highestBlock, err := stages.GetStageProgress(tx, stages.Headers)
 	if err != nil {
 		return false, err
 	}
 
-	currentBlock, err := stages.GetStageProgress(ethdb.NewRoTxDb(tx), stages.Finish)
+	currentBlock, err := stages.GetStageProgress(tx, stages.Finish)
 	if err != nil {
 		return false, err
 	}
diff --git a/cmd/rpcdaemon/commands/eth_uncles.go b/cmd/rpcdaemon/commands/eth_uncles.go
index eb02b8f5609f21ac0970d8609800d82d946605c0..f95039a5be3c97737fe07596920f39cde8123ef7 100644
--- a/cmd/rpcdaemon/commands/eth_uncles.go
+++ b/cmd/rpcdaemon/commands/eth_uncles.go
@@ -34,7 +34,7 @@ func (api *APIImpl) GetUncleByBlockNumberAndIndex(ctx context.Context, number rp
 	}
 	hash := block.Hash()
 	additionalFields := make(map[string]interface{})
-	td, err := rawdb.ReadTd(ethdb.NewRoTxDb(tx), block.Hash(), blockNum)
+	td, err := rawdb.ReadTd(tx, block.Hash(), blockNum)
 	if err != nil {
 		return nil, err
 	}
@@ -66,7 +66,7 @@ func (api *APIImpl) GetUncleByBlockHashAndIndex(ctx context.Context, hash common
 	}
 	number := block.NumberU64()
 	additionalFields := make(map[string]interface{})
-	td, err := rawdb.ReadTd(ethdb.NewRoTxDb(tx), hash, number)
+	td, err := rawdb.ReadTd(tx, hash, number)
 	if err != nil {
 		return nil, err
 	}
diff --git a/cmd/rpcdaemon/commands/rpc_block.go b/cmd/rpcdaemon/commands/rpc_block.go
index ffc9dd225294e2a741a8ed9c554c7d8e903ebf6d..52fe7e687268397defe0ebd6cb626c3e8af62093 100644
--- a/cmd/rpcdaemon/commands/rpc_block.go
+++ b/cmd/rpcdaemon/commands/rpc_block.go
@@ -26,7 +26,7 @@ func getBlockNumber(number rpc.BlockNumber, tx ethdb.Tx) (uint64, error) {
 }
 
 func getLatestBlockNumber(tx ethdb.Tx) (uint64, error) {
-	blockNum, err := stages.GetStageProgress(ethdb.NewRoTxDb(tx), stages.Execution)
+	blockNum, err := stages.GetStageProgress(tx, stages.Execution)
 	if err != nil {
 		return 0, fmt.Errorf("getting latest block number: %v", err)
 	}
diff --git a/cmd/rpcdaemon/commands/tg_issuance.go b/cmd/rpcdaemon/commands/tg_issuance.go
index 2bb62371ac501550637fb1468d751bcc369e1054..32244612134fe46658180e93ea51a71c796ea947 100644
--- a/cmd/rpcdaemon/commands/tg_issuance.go
+++ b/cmd/rpcdaemon/commands/tg_issuance.go
@@ -41,12 +41,7 @@ func (api *TgImpl) Issuance(ctx context.Context, blockNr rpc.BlockNumber) (Issua
 	}
 	defer tx.Rollback()
 
-	genesis, err := rawdb.ReadBlockByNumber(ethdb.NewRoTxDb(tx), 0)
-	if err != nil {
-		return Issuance{}, err
-	}
-	genesisHash := genesis.Hash()
-	chainConfig, err := rawdb.ReadChainConfig(ethdb.NewRoTxDb(tx), genesisHash)
+	chainConfig, err := api.chainConfig(tx)
 	if err != nil {
 		return Issuance{}, err
 	}
diff --git a/cmd/rpcdaemon/commands/trace_filtering.go b/cmd/rpcdaemon/commands/trace_filtering.go
index a3d1ee01d041535adc76390cd8ddf824b272f5e8..8636167c818a15c9c622d57e84126b0907188581 100644
--- a/cmd/rpcdaemon/commands/trace_filtering.go
+++ b/cmd/rpcdaemon/commands/trace_filtering.go
@@ -132,7 +132,7 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest) (Pa
 	}
 
 	if req.ToBlock == nil {
-		headNumber := rawdb.ReadHeaderNumber(ethdb.NewRoTxDb(tx), rawdb.ReadHeadHeaderHash(ethdb.NewRoTxDb(tx)))
+		headNumber := rawdb.ReadHeaderNumber(tx, rawdb.ReadHeadHeaderHash(tx))
 		toBlock = *headNumber
 	} else {
 		toBlock = uint64(*req.ToBlock)
@@ -177,7 +177,7 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest) (Pa
 				if err != nil {
 					return nil, err
 				}
-				senders, errSenders := rawdb.ReadSenders(ethdb.NewRoTxDb(tx), block.Hash(), num)
+				senders, errSenders := rawdb.ReadSenders(tx, block.Hash(), num)
 				if errSenders != nil {
 					return nil, errSenders
 				}
@@ -252,12 +252,7 @@ func (api *TraceAPIImpl) Filter(ctx context.Context, req TraceFilterRequest) (Pa
 
 	getter := adapter.NewBlockGetter(tx)
 	chainContext := adapter.NewChainContext(tx)
-	genesis, err := rawdb.ReadBlockByNumber(ethdb.NewRoTxDb(tx), 0)
-	if err != nil {
-		return nil, err
-	}
-	genesisHash := genesis.Hash()
-	chainConfig, err := rawdb.ReadChainConfig(ethdb.NewRoTxDb(tx), genesisHash)
+	chainConfig, err := api.chainConfig(tx)
 	if err != nil {
 		return nil, err
 	}
@@ -361,12 +356,7 @@ func isAddressInFilter(addr *common.Address, filter []*common.Address) bool {
 func (api *TraceAPIImpl) getTransactionTraces(tx ethdb.Tx, ctx context.Context, txHash common.Hash) (ParityTraces, error) {
 	getter := adapter.NewBlockGetter(tx)
 	chainContext := adapter.NewChainContext(tx)
-	genesis, err := rawdb.ReadBlockByNumber(ethdb.NewRoTxDb(tx), 0)
-	if err != nil {
-		return nil, err
-	}
-	genesisHash := genesis.Hash()
-	chainConfig, err := rawdb.ReadChainConfig(ethdb.NewRoTxDb(tx), genesisHash)
+	chainConfig, err := api.chainConfig(tx)
 	if err != nil {
 		return nil, err
 	}
diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go
index ba9bfe3b02fd8cc1a8de3d32c26d790e9ffe31fc..7cdf111fcc8f3f19b723eef3f0a9ea1a20963b74 100644
--- a/core/rawdb/accessors_chain.go
+++ b/core/rawdb/accessors_chain.go
@@ -169,7 +169,7 @@ func HasHeader(db ethdb.Has, hash common.Hash, number uint64) bool {
 }
 
 // ReadHeader retrieves the block header corresponding to the hash.
-func ReadHeader(db ethdb.DatabaseReader, hash common.Hash, number uint64) *types.Header {
+func ReadHeader(db ethdb.KVGetter, hash common.Hash, number uint64) *types.Header {
 	data := ReadHeaderRLP(db, hash, number)
 	if len(data) == 0 {
 		return nil
@@ -344,7 +344,7 @@ func ReadBody(db ethdb.Getter, hash common.Hash, number uint64) *types.Body {
 	return body
 }
 
-func ReadBodyWithoutTransactions(db ethdb.DatabaseReader, hash common.Hash, number uint64) (*types.Body, uint64, uint32) {
+func ReadBodyWithoutTransactions(db ethdb.KVGetter, hash common.Hash, number uint64) (*types.Body, uint64, uint32) {
 	data := ReadStorageBodyRLP(db, hash, number)
 	if len(data) == 0 {
 		return nil, 0, 0
diff --git a/eth/stagedsync/stages/stages.go b/eth/stagedsync/stages/stages.go
index 4bd88358ece29284fde0ab00bd75b92687cb81e0..417a07ed462a092147e8cc1fa58c2df214a654bd 100644
--- a/eth/stagedsync/stages/stages.go
+++ b/eth/stagedsync/stages/stages.go
@@ -68,7 +68,7 @@ var AllStages = []SyncStage{
 }
 
 // GetStageProgress retrieves saved progress of given sync stage from the database
-func GetStageProgress(db ethdb.Getter, stage SyncStage) (uint64, error) {
+func GetStageProgress(db ethdb.KVGetter, stage SyncStage) (uint64, error) {
 	v, err := db.GetOne(dbutils.SyncStageProgress, stage)
 	if err != nil {
 		return 0, err