package p2p import ( "fmt" "net" "testing" "time" cfg "github.com/vapor/config" "github.com/vapor/consensus" conn "github.com/vapor/p2p/connection" "github.com/vapor/p2p/signlib" "github.com/vapor/version" ) const testCh = 0x01 func TestPeerBasic(t *testing.T) { privKey, err := signlib.NewPrivKey() if err != nil { t.Fatal(err) } // simulate remote peer rp := &remotePeer{PrivKey: privKey, Config: testCfg} rp.Start() defer rp.Stop() p, err := createOutboundPeerAndPerformHandshake(rp.Addr(), cfg.DefaultP2PConfig()) if err != nil { t.Fatal(err) } _, err = p.Start() if err != nil { t.Fatal(err) } defer p.Stop() } func TestPeerSend(t *testing.T) { config := testCfg privKey, err := signlib.NewPrivKey() if err != nil { t.Fatal(err) } // simulate remote peer rp := &remotePeer{PrivKey: privKey, Config: config} rp.Start() defer rp.Stop() p, err := createOutboundPeerAndPerformHandshake(rp.Addr(), config.P2P) if err != nil { t.Fatal(err) } _, err = p.Start() if err != nil { t.Fatal(err) } defer p.Stop() if ok := p.CanSend(testCh); !ok { t.Fatal("TestPeerSend send err") } if ok := p.TrySend(testCh, []byte("test date")); !ok { t.Fatal("TestPeerSend try send err") } } func createOutboundPeerAndPerformHandshake( addr *NetAddress, config *cfg.P2PConfig, ) (*Peer, error) { chDescs := []*conn.ChannelDescriptor{ {ID: testCh, Priority: 1}, } reactorsByCh := map[byte]Reactor{testCh: NewTestReactor(chDescs, true)} privKey, err := signlib.NewPrivKey() if err != nil { return nil, err } peerConfig := DefaultPeerConfig(config) pc, err := newOutboundPeerConn(addr, privKey, peerConfig) if err != nil { return nil, err } nodeInfo, err := pc.HandshakeTimeout(&NodeInfo{ Moniker: "host_peer", Network: "testing", Version: "123.123.123", }, 5*time.Second) if err != nil { fmt.Println(err) return nil, err } p := newPeer(pc, nodeInfo, reactorsByCh, chDescs, nil, false) return p, nil } type remotePeer struct { PrivKey signlib.PrivKey Config *cfg.Config addr *NetAddress quit chan struct{} listenAddr string } func (rp *remotePeer) Addr() *NetAddress { return rp.addr } func (rp *remotePeer) Start() { if rp.listenAddr == "" { rp.listenAddr = "127.0.0.1:0" } l, e := net.Listen("tcp", rp.listenAddr) // any available address if e != nil { fmt.Println("net.Listen tcp :0:", e) } rp.addr = NewNetAddress(l.Addr()) rp.quit = make(chan struct{}) go rp.accept(l) } func (rp *remotePeer) Stop() { close(rp.quit) } func (rp *remotePeer) accept(l net.Listener) { conns := []net.Conn{} for { conn, err := l.Accept() if err != nil { fmt.Println("Failed to accept conn:", err) } pc, err := newInboundPeerConn(conn, rp.PrivKey, rp.Config.P2P) if err != nil { fmt.Println("Failed to create a peer:", err) } _, err = pc.HandshakeTimeout(&NodeInfo{ PubKey: rp.PrivKey.XPub().String(), Moniker: "remote_peer", Network: rp.Config.ChainID, Version: version.Version, ListenAddr: l.Addr().String(), ServiceFlag: consensus.DefaultServices, }, 5*time.Second) if err != nil { fmt.Println("Failed to perform handshake:", err) } conns = append(conns, conn) select { case <-rp.quit: for _, conn := range conns { if err := conn.Close(); err != nil { fmt.Println(err) } } return default: } } } type inboundPeer struct { PrivKey signlib.PrivKey config *cfg.Config } func (ip *inboundPeer) dial(addr *NetAddress) { pc, err := newOutboundPeerConn(addr, ip.PrivKey, DefaultPeerConfig(ip.config.P2P)) if err != nil { fmt.Println("newOutboundPeerConn:", err) return } _, err = pc.HandshakeTimeout(&NodeInfo{ PubKey: ip.PrivKey.XPub().String(), Moniker: "remote_peer", Network: ip.config.ChainID, Version: version.Version, ListenAddr: addr.String(), }, 5*time.Second) if err != nil { fmt.Println("Failed to perform handshake:", err) return } time.AfterFunc(10*time.Second, pc.CloseConn) }