code: func main() {
  	flag.Parse()
  
  	// set the log level to Trace
  	log.Root().SetHandler(log.LvlFilterHandler(log.LvlTrace, log.StreamHandler(os.Stderr, log.TerminalFormat(false))))
  
  	// register a single ping-pong service
  	services := map[string]adapters.ServiceFunc{
  		"ping-pong": func(ctx *adapters.ServiceContext) (node.Service, error) {
  			return newPingPongService(ctx.Config.ID), nil
  		},
  	}
  	adapters.RegisterServices(services)
  
  	// create the NodeAdapter
  	var adapter adapters.NodeAdapter
  
  	switch *adapterType {
  
  	case "sim":
  		log.Info("using sim adapter")
  		adapter = adapters.NewSimAdapter(services)
  
  	case "exec":
  		tmpdir, err := ioutil.TempDir("", "p2p-example")
  		if err != nil {
  			log.Crit("error creating temp dir", "err", err)
  		}
  		defer os.RemoveAll(tmpdir)
  		log.Info("using exec adapter", "tmpdir", tmpdir)
  		adapter = adapters.NewExecAdapter(tmpdir)
  
  	default:
  		log.Crit(fmt.Sprintf("unknown node adapter %q", *adapterType))
  	}
  
  	// start the HTTP API
  	log.Info("starting simulation server on 0.0.0.0:8888...")
  	network := simulations.NewNetwork(adapter, &simulations.NetworkConfig{
  		DefaultService: "ping-pong",
  	})
  	if err := http.ListenAndServe(":8888", simulations.NewServer(network)); err != nil {
  		log.Crit("error starting simulation server", "err", err)
  	}
  }
docs: // main() starts a simulation network which contains nodes running a simple
  // ping-pong protocol