code: func New(services map[string]ServiceFunc) (s *Simulation) {
  	s = &Simulation{
  		buckets:           make(map[enode.ID]*sync.Map),
  		done:              make(chan struct{}),
  		neighbourhoodSize: network.NewKadParams().NeighbourhoodSize,
  	}
  
  	adapterServices := make(map[string]adapters.ServiceFunc, len(services))
  	for name, serviceFunc := range services {
  		// Scope this variables correctly
  		// as they will be in the adapterServices[name] function accessed later.
  		name, serviceFunc := name, serviceFunc
  		s.serviceNames = append(s.serviceNames, name)
  		adapterServices[name] = func(ctx *adapters.ServiceContext) (node.Service, error) {
  			s.mu.Lock()
  			defer s.mu.Unlock()
  			b, ok := s.buckets[ctx.Config.ID]
  			if !ok {
  				b = new(sync.Map)
  			}
  			service, cleanup, err := serviceFunc(ctx, b)
  			if err != nil {
  				return nil, err
  			}
  			if cleanup != nil {
  				s.cleanupFuncs = append(s.cleanupFuncs, cleanup)
  			}
  			s.buckets[ctx.Config.ID] = b
  			return service, nil
  		}
  	}
  
  	s.Net = simulations.NewNetwork(
  		adapters.NewTCPAdapter(adapterServices),
  		&simulations.NetworkConfig{ID: "0"},
  	)
  
  	return s
  }
docs: // New creates a new simulation instance
  // Services map must have unique keys as service names and
  // every ServiceFunc must return a node.Service of the unique type.
  // This restriction is required by node.Node.Start() function
  // which is used to start node.Service returned by ServiceFunc.