diff --git a/cmd/rpcdaemon/commands/trace_adhoc.go b/cmd/rpcdaemon/commands/trace_adhoc.go
index 4793d8551a646424f97aecd0fd9354b30a9bfb37..c6c6c9f4edc1550cc3563f5c1ee985c82d377a98 100644
--- a/cmd/rpcdaemon/commands/trace_adhoc.go
+++ b/cmd/rpcdaemon/commands/trace_adhoc.go
@@ -569,6 +569,7 @@ func (api *TraceAPIImpl) ReplayTransaction(ctx context.Context, txHash common.Ha
 			if traceTypeVmTrace {
 				result.VmTrace = trace.VmTrace
 			}
+
 			return trace, nil
 		}
 	}
@@ -583,46 +584,23 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH
 	}
 	defer tx.Rollback()
 
-	chainConfig, err := api.chainConfig(tx)
-	if err != nil {
-		return nil, err
-	}
-
-	blockNumber, blockHash, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters)
+	blockNumber, _, err := rpchelper.GetBlockNumber(blockNrOrHash, tx, api.filters)
 	if err != nil {
 		return nil, err
 	}
-	block := rawdb.ReadBlock(tx, blockHash, blockNumber)
-	if block == nil {
-		return nil, fmt.Errorf("block %d(%x) not found", blockNumber, blockHash)
-	}
 
-	getHeader := func(hash common.Hash, number uint64) *types.Header {
-		return rawdb.ReadHeader(tx, hash, number)
+	parentNr := blockNumber
+	if parentNr > 0 {
+		parentNr -= 1
 	}
-
-	var stateReader state.StateReader
-	if num, ok := blockNrOrHash.Number(); ok && num == rpc.LatestBlockNumber {
-		stateReader = state.NewPlainStateReader(tx)
-	} else {
-		stateReader = state.NewPlainKvState(tx, blockNumber-1)
+	// Extract transactions from block
+	block, _, bErr := rawdb.ReadBlockByNumberWithSenders(tx, blockNumber)
+	if bErr != nil {
+		return nil, bErr
 	}
-	ibs := state.New(stateReader)
-
-	// Setup context so it may be cancelled the call has completed
-	// or, in case of unmetered gas, setup a context with a timeout.
-	var cancel context.CancelFunc
-	if callTimeout > 0 {
-		ctx, cancel = context.WithTimeout(ctx, callTimeout)
-	} else {
-		ctx, cancel = context.WithCancel(ctx)
+	if block == nil {
+		return nil, fmt.Errorf("could not find block  %d", blockNumber)
 	}
-
-	// Make sure the context is cancelled when the call has completed
-	// this makes sure resources are cleaned up.
-	defer cancel()
-	var traceResults = make([]*TraceCallResult, block.Transactions().Len())
-	traceResult := &TraceCallResult{Trace: []*ParityTrace{}}
 	var traceTypeTrace, traceTypeStateDiff, traceTypeVmTrace bool
 	for _, traceType := range traceTypes {
 		switch traceType {
@@ -636,57 +614,40 @@ func (api *TraceAPIImpl) ReplayBlockTransactions(ctx context.Context, blockNrOrH
 			return nil, fmt.Errorf("unrecognized trace type: %s", traceType)
 		}
 	}
-	var ot OeTracer
-	ot.compat = api.compatibility
-	if traceTypeTrace {
-		ot.r = traceResult
-		ot.traceAddr = []int{}
-	}
 
-	gp := new(core.GasPool)
-	gp.AddGas(block.GasLimit())
+	// Returns an array of trace arrays, one trace array for each transaction
+	traces, err := api.callManyTransactions(ctx, tx, block.Transactions(), block.ParentHash(), rpc.BlockNumber(parentNr), block.Header())
+	if err != nil {
+		return nil, err
+	}
 
 	if traceTypeVmTrace {
 		return nil, fmt.Errorf("vmTrace not implemented yet")
 	}
-	var initialIbs *state.IntraBlockState
 
-	usedGas := new(uint64)
-	var stateWriter state.StateWriter
-	vmConfig := vm.Config{}
-	if traceTypeStateDiff || traceTypeTrace {
-		vmConfig = vm.Config{Debug: traceTypeTrace, Tracer: &ot}
-	}
-	stateWriter = state.NewNoopWriter()
-	var sd *StateDiff
-	for i, txn := range block.Transactions() {
-		if err := common.Stopped(ctx.Done()); err != nil {
-			return nil, err
+	result := make([]*TraceCallResult, len(traces))
+	for i, trace := range traces {
+		tr := &TraceCallResult{}
+		tr.Output = trace.Output
+		if traceTypeTrace {
+			tr.Trace = trace.Trace
 		}
-		ibs.Prepare(txn.Hash(), block.Hash(), i)
 		if traceTypeStateDiff {
-			sdMap := make(map[common.Address]*StateDiffAccount)
-			sd = &StateDiff{sdMap: sdMap}
-			traceResult.StateDiff = sdMap
-			stateWriter = sd
-			initialIbs = ibs.Copy()
+			tr.StateDiff = trace.StateDiff
 		}
-		_, execResult, err := core.ApplyTransaction(chainConfig, getHeader, nil, &block.Header().Coinbase, gp, ibs, stateWriter, block.Header(), txn, usedGas, vmConfig, nil)
-		if err != nil {
-			return nil, fmt.Errorf("could not apply tx %d from block %d [%v]: %w", i, block.NumberU64(), txn.Hash().Hex(), err)
+		if traceTypeVmTrace {
+			tr.VmTrace = trace.VmTrace
 		}
-		traceResult.Output = common.CopyBytes(execResult)
-		if traceTypeStateDiff {
-			sd.CompareStates(initialIbs, ibs)
+		result[i] = tr
+		for _, pt := range tr.Trace {
+			txpos := uint64(i)
+			txhash := block.Transactions()[i].Hash()
+			pt.TransactionHash = &txhash
+			pt.TransactionPosition = &txpos
 		}
-		traceResults[i] = traceResult
 	}
 
-	if traceTypeVmTrace {
-		return nil, fmt.Errorf("vmTrace not implemented yet")
-	}
-
-	return traceResults, nil
+	return result, nil
 }
 
 // Call implements trace_call.
diff --git a/cmd/rpcdaemon/commands/trace_adhoc_test.go b/cmd/rpcdaemon/commands/trace_adhoc_test.go
index 602d45a11c65a9897c1c2333d927c4b23a7f72d2..6c3cb3fedb92364ae000dd8bd905aac44dd12725 100644
--- a/cmd/rpcdaemon/commands/trace_adhoc_test.go
+++ b/cmd/rpcdaemon/commands/trace_adhoc_test.go
@@ -75,7 +75,7 @@ func TestReplayTransaction(t *testing.T) {
 	// Call GetTransactionReceipt for transaction which is not in the database
 	results, err := api.ReplayTransaction(context.Background(), txnHash, []string{"stateDiff"})
 	if err != nil {
-		t.Errorf("calling CallMany: %v", err)
+		t.Errorf("calling ReplayTransaction: %v", err)
 	}
 	require.NotNil(t, results)
 	require.NotNil(t, results.StateDiff)
@@ -92,11 +92,11 @@ func TestReplayBlockTransactions(t *testing.T) {
 	n := rpc.BlockNumber(6)
 	results, err := api.ReplayBlockTransactions(context.Background(), rpc.BlockNumberOrHash{BlockNumber: &n}, []string{"stateDiff"})
 	if err != nil {
-		t.Errorf("calling CallMany: %v", err)
+		t.Errorf("calling ReplayBlockTransactions: %v", err)
 	}
 	require.NotNil(t, results)
 	require.NotNil(t, results[0].StateDiff)
-	addrDiff := results[0].StateDiff[common.HexToAddress("0x0000000000000020000000000000000000000000")]
+	addrDiff := results[0].StateDiff[common.HexToAddress("0x0000000000000001000000000000000000000000")]
 	v := addrDiff.Balance.(map[string]*hexutil.Big)["+"].ToInt().Uint64()
 	require.Equal(t, uint64(1_000_000_000_000_000), v)
 }