code: func (api *PrivateDebugAPI) TraceChain(ctx context.Context, start, end rpc.BlockNumber, config *TraceConfig) (*rpc.Subscription, error) {
  	// Fetch the block interval that we want to trace
  	var from, to *types.Block
  
  	switch start {
  	case rpc.PendingBlockNumber:
  		from = api.eth.miner.PendingBlock()
  	case rpc.LatestBlockNumber:
  		from = api.eth.blockchain.CurrentBlock()
  	default:
  		from = api.eth.blockchain.GetBlockByNumber(uint64(start))
  	}
  	switch end {
  	case rpc.PendingBlockNumber:
  		to = api.eth.miner.PendingBlock()
  	case rpc.LatestBlockNumber:
  		to = api.eth.blockchain.CurrentBlock()
  	default:
  		to = api.eth.blockchain.GetBlockByNumber(uint64(end))
  	}
  	// Trace the chain if we've found all our blocks
  	if from == nil {
  		return nil, fmt.Errorf("starting block #%d not found", start)
  	}
  	if to == nil {
  		return nil, fmt.Errorf("end block #%d not found", end)
  	}
  	if from.Number().Cmp(to.Number()) >= 0 {
  		return nil, fmt.Errorf("end block (#%d) needs to come after start block (#%d)", end, start)
  	}
  	return api.traceChain(ctx, from, to, config)
  }
docs: // TraceChain returns the structured logs created during the execution of EVM
  // between two blocks (excluding start) and returns them as a JSON object.