func (sw *Switch) OnStart() error {
	sw.BaseService.OnStart()
	for _, reactor := range sw.reactors {
		_, err := reactor.Start()
		if err != nil {
			return err
		}
	}
	for _, peer := range sw.peers.List() {
		sw.startInitPeer(peer)
	}
	for _, listener := range sw.listeners {
		go sw.listenerRoutine(listener)
	}
	return nil
}
Switch.Start() starts all the reactors, peers, and listeners.
package p2p
import (
	"errors"
	"fmt"
	"math/rand"
	"net"
	"time"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	. "github.com/annchain/annchain/module/lib/go-common"
	"github.com/annchain/annchain/module/lib/go-crypto"
)
const (
	_ byte = iota
	ConnActionP2P
	ConnActionGen
)
type Reactor interface {
	Service  
	SetSwitch(*Switch)
	GetChannels() []*ChannelDescriptor
	AddPeer(peer *Peer)
	RemovePeer(peer *Peer, reason interface{})
	Receive(chID byte, peer *Peer, msgBytes []byte)
}
type BaseReactor struct {
	BaseService  
	Switch      *Switch
}
type IPeerErrorReporter interface {
	ReportPeerError(crypto.PubKey, interface{})
}
func NewBaseReactor(logger *zap.Logger, name string, impl Reactor) *BaseReactor {
	return &BaseReactor{
		BaseService: *NewBaseService(logger, name, impl),
		Switch:      nil,
	}
}
func (br *BaseReactor) SetSwitch(sw *Switch) {
	br.Switch = sw
}
func (_ *BaseReactor) GetChannels() []*ChannelDescriptor              { return nil }
func (_ *BaseReactor) AddPeer(peer *Peer)                             {}
func (_ *BaseReactor) RemovePeer(peer *Peer, reason interface{})      {}
func (_ *BaseReactor) Receive(chID byte, peer *Peer, msgBytes []byte) {}
type FilterFunc func(*crypto.PubKeyEd25519) error
type Switch struct {
	BaseService
	config       *viper.Viper
	listeners    []Listener
	reactors     map[string]Reactor
	chDescs      []*ChannelDescriptor
	reactorsByCh map[byte]Reactor
	peers        *PeerSet
	dialing      *CMap
	nodeInfo     *NodeInfo              
	nodePrivKey  crypto.PrivKeyEd25519  
	filterConnByAddr       func(net.Addr) error
	filterConnByPubKey     FilterFunc
	filterConnByRefuselist FilterFunc
	authByCA AuthorizationFunc
	addToRefuselist func([32]byte) error
	logger  *zap.Logger
	slogger *zap.SugaredLogger
	genesisBytes     []byte
	genesisUnmarshal func([]byte) error
	peerErrorReporter IPeerErrorReporter
}
var (
	ErrSwitchDuplicatePeer      = errors.New("Duplicate peer")
	ErrSwitchMaxPeersPerIPRange = errors.New("IP range has too many peers")
)
func NewSwitch(logger *zap.Logger, config *viper.Viper, genesis []byte) *Switch {
	setConfigDefaults(config)
	sw := &Switch{
		config:       config,
		reactors:     make(map[string]Reactor),
		chDescs:      make([]*ChannelDescriptor, 0),
		reactorsByCh: make(map[byte]Reactor),
		peers:        NewPeerSet(),
		dialing:      NewCMap(),
		nodeInfo:     nil,
		logger:       logger,
		slogger:      logger.Sugar(),
		genesisBytes: genesis,
	}
	sw.BaseService = *NewBaseService(logger, "P2P Switch", sw)
	return sw
}
func (sw *Switch) AddReactor(name string, reactor Reactor) Reactor {
	reactorChannels := reactor.GetChannels()
	for _, chDesc := range reactorChannels {
		chID := chDesc.ID
		if sw.reactorsByCh[chID] != nil {
			PanicSanity(fmt.Sprintf("Channel %X has multiple reactors %v & %v", chID, sw.reactorsByCh[chID], reactor))
		}
		sw.chDescs = append(sw.chDescs, chDesc)
		sw.reactorsByCh[chID] = reactor
	}
	sw.reactors[name] = reactor
	reactor.SetSwitch(sw)
	return reactor
}
func (sw *Switch) Reactors() map[string]Reactor {
	return sw.reactors
}
func (sw *Switch) Reactor(name string) Reactor {
	return sw.reactors[name]
}
func (sw *Switch) AddListener(l Listener) {
	sw.listeners = append(sw.listeners, l)
}
func (sw *Switch) Listeners() []Listener {
	return sw.listeners
}
func (sw *Switch) IsListening() bool {
	return len(sw.listeners) > 0
}
func (sw *Switch) SetNodeInfo(nodeInfo *NodeInfo) {
	sw.nodeInfo = nodeInfo
}
func (sw *Switch) NodeInfo() *NodeInfo {
	return sw.nodeInfo
}
func (sw *Switch) NodePrivkey() crypto.PrivKeyEd25519 {
	return sw.nodePrivKey
}
func (sw *Switch) SetRefuseListFilter(cb func(*crypto.PubKeyEd25519) error) {
	sw.filterConnByRefuselist = cb
}
func (sw *Switch) SetPeerErrorReporter(reporter IPeerErrorReporter) {
	sw.peerErrorReporter = reporter
}
func (sw *Switch) SetNodePrivKey(nodePrivKey crypto.PrivKeyEd25519) {
	sw.nodePrivKey = nodePrivKey
	if sw.nodeInfo != nil {
		sw.nodeInfo.PubKey = *(nodePrivKey.PubKey().(*crypto.PubKeyEd25519))
	}
}