github.com/Bytom/bytom@v1.1.2-0.20210127130405-ae40204c0b09/p2p/switch_test.go (about)

     1  package p2p
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"sync"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/davecgh/go-spew/spew"
    11  	"github.com/tendermint/go-crypto"
    12  
    13  	cfg "github.com/bytom/bytom/config"
    14  	dbm "github.com/bytom/bytom/database/leveldb"
    15  	"github.com/bytom/bytom/errors"
    16  	conn "github.com/bytom/bytom/p2p/connection"
    17  	"github.com/bytom/bytom/p2p/security"
    18  )
    19  
    20  var (
    21  	testCfg *cfg.Config
    22  )
    23  
    24  func init() {
    25  	testCfg = cfg.DefaultConfig()
    26  }
    27  
    28  /*
    29  Each peer has one `MConnection` (multiplex connection) instance.
    30  
    31  __multiplex__ *noun* a system or signal involving simultaneous transmission of
    32  several messages along a single channel of communication.
    33  
    34  Each `MConnection` handles message transmission on multiple abstract communication
    35  `Channel`s.  Each channel has a globally unique byte id.
    36  The byte id and the relative priorities of each `Channel` are configured upon
    37  initialization of the connection.
    38  
    39  There are two methods for sending messages:
    40  	func (m MConnection) Send(chID byte, msgBytes []byte) bool {}
    41  	func (m MConnection) TrySend(chID byte, msgBytes []byte}) bool {}
    42  
    43  `Send(chID, msgBytes)` is a blocking call that waits until `msg` is
    44  successfully queued for the channel with the given id byte `chID`, or until the
    45  request times out.  The message `msg` is serialized using Go-Amino.
    46  
    47  `TrySend(chID, msgBytes)` is a nonblocking call that returns false if the
    48  channel's queue is full.
    49  
    50  Inbound message bytes are handled with an onReceive callback function.
    51  */
    52  type PeerMessage struct {
    53  	PeerID  string
    54  	Bytes   []byte
    55  	Counter int
    56  }
    57  
    58  type TestReactor struct {
    59  	BaseReactor
    60  
    61  	mtx          sync.Mutex
    62  	channels     []*conn.ChannelDescriptor
    63  	logMessages  bool
    64  	msgsCounter  int
    65  	msgsReceived map[byte][]PeerMessage
    66  }
    67  
    68  func NewTestReactor(channels []*conn.ChannelDescriptor, logMessages bool) *TestReactor {
    69  	tr := &TestReactor{
    70  		channels:     channels,
    71  		logMessages:  logMessages,
    72  		msgsReceived: make(map[byte][]PeerMessage),
    73  	}
    74  	tr.BaseReactor = *NewBaseReactor("TestReactor", tr)
    75  
    76  	return tr
    77  }
    78  
    79  // GetChannels implements Reactor
    80  func (tr *TestReactor) GetChannels() []*conn.ChannelDescriptor {
    81  	return tr.channels
    82  }
    83  
    84  // OnStart implements BaseService
    85  func (tr *TestReactor) OnStart() error {
    86  	tr.BaseReactor.OnStart()
    87  	return nil
    88  }
    89  
    90  // OnStop implements BaseService
    91  func (tr *TestReactor) OnStop() {
    92  	tr.BaseReactor.OnStop()
    93  }
    94  
    95  // AddPeer implements Reactor by sending our state to peer.
    96  func (tr *TestReactor) AddPeer(peer *Peer) error {
    97  	return nil
    98  }
    99  
   100  // RemovePeer implements Reactor by removing peer from the pool.
   101  func (tr *TestReactor) RemovePeer(peer *Peer, reason interface{}) {
   102  }
   103  
   104  // Receive implements Reactor by handling 4 types of messages (look below).
   105  func (tr *TestReactor) Receive(chID byte, peer *Peer, msgBytes []byte) {
   106  	if tr.logMessages {
   107  		tr.mtx.Lock()
   108  		defer tr.mtx.Unlock()
   109  		tr.msgsReceived[chID] = append(tr.msgsReceived[chID], PeerMessage{peer.ID(), msgBytes, tr.msgsCounter})
   110  		tr.msgsCounter++
   111  	}
   112  }
   113  
   114  func initSwitchFunc(sw *Switch) *Switch {
   115  	// Make two reactors of two channels each
   116  	sw.AddReactor("foo", NewTestReactor([]*conn.ChannelDescriptor{
   117  		{ID: byte(0x00), Priority: 10},
   118  		{ID: byte(0x01), Priority: 10},
   119  	}, true))
   120  	sw.AddReactor("bar", NewTestReactor([]*conn.ChannelDescriptor{
   121  		{ID: byte(0x02), Priority: 10},
   122  		{ID: byte(0x03), Priority: 10},
   123  	}, true))
   124  
   125  	return sw
   126  }
   127  
   128  //Test connect self.
   129  func TestFiltersOutItself(t *testing.T) {
   130  	t.Skip("due to fail on mac")
   131  	dirPath, err := ioutil.TempDir(".", "")
   132  	if err != nil {
   133  		t.Fatal(err)
   134  	}
   135  	defer os.RemoveAll(dirPath)
   136  
   137  	testDB := dbm.NewDB("testdb", "leveldb", dirPath)
   138  	cfg := *testCfg
   139  	cfg.DBPath = dirPath
   140  	cfg.P2P.ListenAddress = "127.0.1.1:0"
   141  	swPrivKey := crypto.GenPrivKeyEd25519()
   142  	cfg.P2P.PrivateKey = swPrivKey.String()
   143  	s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc)
   144  	s1.Start()
   145  	defer s1.Stop()
   146  
   147  	rmdirPath, err := ioutil.TempDir(".", "")
   148  	if err != nil {
   149  		t.Fatal(err)
   150  	}
   151  	defer os.RemoveAll(rmdirPath)
   152  
   153  	// simulate s1 having a public key and creating a remote peer with the same key
   154  	rpCfg := *testCfg
   155  	rpCfg.DBPath = rmdirPath
   156  	rp := &remotePeer{PrivKey: s1.nodePrivKey, Config: &rpCfg}
   157  	rp.Start()
   158  	defer rp.Stop()
   159  	if err = s1.DialPeerWithAddress(rp.addr); errors.Root(err) != ErrConnectSelf {
   160  		t.Fatal(err)
   161  	}
   162  
   163  	//S1 dialing itself ip address
   164  	addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr())
   165  
   166  	if err := s1.DialPeerWithAddress(addr); errors.Root(err) != ErrConnectSelf {
   167  		t.Fatal(err)
   168  	}
   169  }
   170  
   171  func TestDialBannedPeer(t *testing.T) {
   172  	t.Skip("due to fail on mac")
   173  	dirPath, err := ioutil.TempDir(".", "")
   174  	if err != nil {
   175  		t.Fatal(err)
   176  	}
   177  	defer os.RemoveAll(dirPath)
   178  
   179  	testDB := dbm.NewDB("testdb", "leveldb", dirPath)
   180  	cfg := *testCfg
   181  	cfg.DBPath = dirPath
   182  	cfg.P2P.ListenAddress = "127.0.1.1:0"
   183  	swPrivKey := crypto.GenPrivKeyEd25519()
   184  	cfg.P2P.PrivateKey = swPrivKey.String()
   185  	s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc)
   186  	s1.Start()
   187  	defer s1.Stop()
   188  
   189  	rmdirPath, err := ioutil.TempDir(".", "")
   190  	if err != nil {
   191  		t.Fatal(err)
   192  	}
   193  	defer os.RemoveAll(rmdirPath)
   194  
   195  	rpCfg := *testCfg
   196  	rpCfg.DBPath = rmdirPath
   197  	rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: &rpCfg}
   198  	rp.Start()
   199  	defer rp.Stop()
   200  	for {
   201  		if ok := s1.security.IsBanned(rp.addr.IP.String(), security.LevelMsgIllegal, "test"); ok {
   202  			break
   203  		}
   204  	}
   205  	if err := s1.DialPeerWithAddress(rp.addr); errors.Root(err) != security.ErrConnectBannedPeer {
   206  		t.Fatal(err)
   207  	}
   208  }
   209  
   210  func TestDuplicateOutBoundPeer(t *testing.T) {
   211  	t.Skip("due to fail on mac")
   212  	dirPath, err := ioutil.TempDir(".", "")
   213  	if err != nil {
   214  		t.Fatal(err)
   215  	}
   216  	defer os.RemoveAll(dirPath)
   217  
   218  	testDB := dbm.NewDB("testdb", "leveldb", dirPath)
   219  	cfg := *testCfg
   220  	cfg.DBPath = dirPath
   221  	cfg.P2P.ListenAddress = "127.0.1.1:0"
   222  	swPrivKey := crypto.GenPrivKeyEd25519()
   223  	cfg.P2P.PrivateKey = swPrivKey.String()
   224  	s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc)
   225  	s1.Start()
   226  	defer s1.Stop()
   227  
   228  	rmdirPath, err := ioutil.TempDir(".", "")
   229  	if err != nil {
   230  		t.Fatal(err)
   231  	}
   232  	defer os.RemoveAll(rmdirPath)
   233  
   234  	rpCfg := *testCfg
   235  	rp := &remotePeer{PrivKey: crypto.GenPrivKeyEd25519(), Config: &rpCfg}
   236  	rp.Start()
   237  	defer rp.Stop()
   238  
   239  	if err = s1.DialPeerWithAddress(rp.addr); err != nil {
   240  		t.Fatal(err)
   241  	}
   242  
   243  	if err = s1.DialPeerWithAddress(rp.addr); errors.Root(err) != ErrDuplicatePeer {
   244  		t.Fatal(err)
   245  	}
   246  }
   247  
   248  func TestDuplicateInBoundPeer(t *testing.T) {
   249  	t.Skip("due to fail on mac")
   250  	dirPath, err := ioutil.TempDir(".", "")
   251  	if err != nil {
   252  		t.Fatal(err)
   253  	}
   254  	defer os.RemoveAll(dirPath)
   255  
   256  	testDB := dbm.NewDB("testdb", "leveldb", dirPath)
   257  	cfg := *testCfg
   258  	cfg.DBPath = dirPath
   259  	cfg.P2P.ListenAddress = "127.0.1.1:0"
   260  	swPrivKey := crypto.GenPrivKeyEd25519()
   261  	cfg.P2P.PrivateKey = swPrivKey.String()
   262  	s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc)
   263  	s1.Start()
   264  	defer s1.Stop()
   265  
   266  	inpCfg := *testCfg
   267  	inp := &inboundPeer{PrivKey: crypto.GenPrivKeyEd25519(), config: &inpCfg}
   268  	addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr())
   269  	if err != nil {
   270  		t.Fatal(err)
   271  	}
   272  	go inp.dial(addr)
   273  
   274  	inp1Cfg := *testCfg
   275  	inp1 := &inboundPeer{PrivKey: inp.PrivKey, config: &inp1Cfg}
   276  	go inp1.dial(addr)
   277  
   278  	time.Sleep(1 * time.Second)
   279  	if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 1 {
   280  		t.Fatal("TestDuplicateInBoundPeer peer size error want 1, got:", outbound, inbound, dialing, spew.Sdump(s1.peers.lookup))
   281  	}
   282  }
   283  
   284  func TestAddInboundPeer(t *testing.T) {
   285  	t.Skip("due to fail on mac")
   286  	dirPath, err := ioutil.TempDir(".", "")
   287  	if err != nil {
   288  		t.Fatal(err)
   289  	}
   290  	defer os.RemoveAll(dirPath)
   291  
   292  	testDB := dbm.NewDB("testdb", "leveldb", dirPath)
   293  	cfg := *testCfg
   294  	cfg.DBPath = dirPath
   295  	cfg.P2P.MaxNumPeers = 2
   296  	cfg.P2P.ListenAddress = "127.0.1.1:0"
   297  	swPrivKey := crypto.GenPrivKeyEd25519()
   298  	cfg.P2P.PrivateKey = swPrivKey.String()
   299  	s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc)
   300  	s1.Start()
   301  	defer s1.Stop()
   302  
   303  	inpCfg := *testCfg
   304  	inpPrivKey := crypto.GenPrivKeyEd25519()
   305  	inpCfg.P2P.PrivateKey = inpPrivKey.String()
   306  	inp := &inboundPeer{PrivKey: inpPrivKey, config: &inpCfg}
   307  	addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr())
   308  	if err != nil {
   309  		t.Fatal(err)
   310  	}
   311  	go inp.dial(addr)
   312  
   313  	rpCfg := *testCfg
   314  	rpPrivKey := crypto.GenPrivKeyEd25519()
   315  	rpCfg.P2P.PrivateKey = rpPrivKey.String()
   316  	rp := &remotePeer{PrivKey: rpPrivKey, Config: &rpCfg}
   317  	rp.Start()
   318  	defer rp.Stop()
   319  
   320  	if err := s1.DialPeerWithAddress(rp.addr); err != nil {
   321  		t.Fatal(err)
   322  	}
   323  
   324  	inp2Cfg := *testCfg
   325  	inp2PrivKey := crypto.GenPrivKeyEd25519()
   326  	inp2Cfg.P2P.PrivateKey = inp2PrivKey.String()
   327  	inp2 := &inboundPeer{PrivKey: inp2PrivKey, config: &inp2Cfg}
   328  
   329  	go inp2.dial(addr)
   330  
   331  	time.Sleep(1 * time.Second)
   332  	if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 2 {
   333  		t.Fatal("TestAddInboundPeer peer size error want 2 got:", spew.Sdump(s1.peers.lookup))
   334  	}
   335  }
   336  
   337  func TestStopPeer(t *testing.T) {
   338  	t.Skip("due to fail on mac")
   339  	dirPath, err := ioutil.TempDir(".", "")
   340  	if err != nil {
   341  		t.Fatal(err)
   342  	}
   343  	defer os.RemoveAll(dirPath)
   344  
   345  	testDB := dbm.NewDB("testdb", "leveldb", dirPath)
   346  	cfg := *testCfg
   347  	cfg.DBPath = dirPath
   348  	cfg.P2P.MaxNumPeers = 2
   349  	cfg.P2P.ListenAddress = "127.0.1.1:0"
   350  	swPrivKey := crypto.GenPrivKeyEd25519()
   351  	cfg.P2P.PrivateKey = swPrivKey.String()
   352  	s1 := MakeSwitch(&cfg, testDB, swPrivKey, initSwitchFunc)
   353  	s1.Start()
   354  	defer s1.Stop()
   355  
   356  	inpCfg := *testCfg
   357  	inpPrivKey := crypto.GenPrivKeyEd25519()
   358  	inpCfg.P2P.PrivateKey = inpPrivKey.String()
   359  	inp := &inboundPeer{PrivKey: inpPrivKey, config: &inpCfg}
   360  	addr := NewNetAddress(s1.listeners[0].(*DefaultListener).NetListener().Addr())
   361  	if err != nil {
   362  		t.Fatal(err)
   363  	}
   364  	go inp.dial(addr)
   365  
   366  	rpCfg := *testCfg
   367  	rpPrivKey := crypto.GenPrivKeyEd25519()
   368  	rpCfg.P2P.PrivateKey = rpPrivKey.String()
   369  	rp := &remotePeer{PrivKey: rpPrivKey, Config: &rpCfg}
   370  	rp.Start()
   371  	defer rp.Stop()
   372  
   373  	if err := s1.DialPeerWithAddress(rp.addr); err != nil {
   374  		t.Fatal(err)
   375  	}
   376  	time.Sleep(1 * time.Second)
   377  	if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 2 {
   378  		t.Fatal("TestStopPeer peer size error want 2,got:", spew.Sdump(s1.peers.lookup))
   379  	}
   380  
   381  	s1.StopPeerGracefully(s1.peers.list[0].Key)
   382  	if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 1 {
   383  		t.Fatal("TestStopPeer peer size error,want 1,got:", spew.Sdump(s1.peers.lookup))
   384  	}
   385  
   386  	s1.StopPeerForError(s1.peers.list[0], "stop for test")
   387  	if _, outbound, inbound, dialing := s1.NumPeers(); outbound+inbound+dialing != 0 {
   388  		t.Fatal("TestStopPeer peer size error,want 0, got:", spew.Sdump(s1.peers.lookup))
   389  	}
   390  }