code: func (s *Store) parseServiceNodes(tx *memdb.Txn, ws memdb.WatchSet, services structs.ServiceNodes) (structs.ServiceNodes, error) {
  	// We don't want to track an unlimited number of nodes, so we pull a
  	// top-level watch to use as a fallback.
  	allNodes, err := tx.Get("nodes", "id")
  	if err != nil {
  		return nil, fmt.Errorf("failed nodes lookup: %s", err)
  	}
  	allNodesCh := allNodes.WatchCh()
  
  	// Fill in the node data for each service instance.
  	var results structs.ServiceNodes
  	for _, sn := range services {
  		// Note that we have to clone here because we don't want to
  		// modify the node-related fields on the object in the database,
  		// which is what we are referencing.
  		s := sn.PartialClone()
  
  		// Grab the corresponding node record.
  		watchCh, n, err := tx.FirstWatch("nodes", "id", sn.Node)
  		if err != nil {
  			return nil, fmt.Errorf("failed node lookup: %s", err)
  		}
  		ws.AddWithLimit(watchLimit, watchCh, allNodesCh)
  
  		// Populate the node-related fields. The tagged addresses may be
  		// used by agents to perform address translation if they are
  		// configured to do that.
  		node := n.(*structs.Node)
  		s.ID = node.ID
  		s.Address = node.Address
  		s.Datacenter = node.Datacenter
  		s.TaggedAddresses = node.TaggedAddresses
  		s.NodeMeta = node.Meta
  
  		results = append(results, s)
  	}
  	return results, nil
  }
docs: // parseServiceNodes iterates over a services query and fills in the node details,
  // returning a ServiceNodes slice.