code: func (s *SimAdapter) NewNode(config *NodeConfig) (Node, error) {
  	s.mtx.Lock()
  	defer s.mtx.Unlock()
  
  	id := config.ID
  	// verify that the node has a private key in the config
  	if config.PrivateKey == nil {
  		return nil, fmt.Errorf("node is missing private key: %s", id)
  	}
  
  	// check a node with the ID doesn't already exist
  	if _, exists := s.nodes[id]; exists {
  		return nil, fmt.Errorf("node already exists: %s", id)
  	}
  
  	// check the services are valid
  	if len(config.Services) == 0 {
  		return nil, errors.New("node must have at least one service")
  	}
  	for _, service := range config.Services {
  		if _, exists := s.services[service]; !exists {
  			return nil, fmt.Errorf("unknown node service %q", service)
  		}
  	}
  
  	err := config.initDummyEnode()
  	if err != nil {
  		return nil, err
  	}
  
  	n, err := node.New(&node.Config{
  		P2P: p2p.Config{
  			PrivateKey:      config.PrivateKey,
  			MaxPeers:        math.MaxInt32,
  			NoDiscovery:     true,
  			Dialer:          s,
  			EnableMsgEvents: config.EnableMsgEvents,
  		},
  		NoUSB:  true,
  		Logger: log.New("node.id", id.String()),
  	})
  	if err != nil {
  		return nil, err
  	}
  
  	simNode := &SimNode{
  		ID:      id,
  		config:  config,
  		node:    n,
  		adapter: s,
  		running: make(map[string]node.Service),
  	}
  	s.nodes[id] = simNode
  	return simNode, nil
  }
docs: // NewNode returns a new SimNode using the given config