github.com/qri-io/qri@v0.10.1-0.20220104210721-c771715036cb/p2p/test/testable_node_test.go (about) 1 package p2ptest 2 3 import ( 4 "context" 5 "fmt" 6 "time" 7 8 "github.com/qri-io/qri/auth/key" 9 "github.com/qri-io/qri/config" 10 "github.com/qri-io/qri/dsref" 11 "github.com/qri-io/qri/event" 12 "github.com/qri-io/qri/repo" 13 14 libp2p "github.com/libp2p/go-libp2p" 15 connmgr "github.com/libp2p/go-libp2p-connmgr" 16 host "github.com/libp2p/go-libp2p-core/host" 17 net "github.com/libp2p/go-libp2p-core/network" 18 peer "github.com/libp2p/go-libp2p-core/peer" 19 protocol "github.com/libp2p/go-libp2p-core/protocol" 20 pstoremem "github.com/libp2p/go-libp2p-peerstore/pstoremem" 21 ) 22 23 // TestableNode satisfies the TestablePeerNode interface 24 // It is used for testing inside the p2ptest package 25 type TestableNode struct { 26 host host.Host 27 cfg *config.P2P 28 Repo repo.Repo 29 localResolver dsref.Resolver 30 } 31 32 // TestQriProtocolID is the key used to set the stream handler to our 33 // testing protocol 34 const TestQriProtocolID = protocol.ID("/qri/_testing") 35 const TestQriSupportKey = "qri-support-test" 36 const TestQriConnManagerTag = "qri_test" 37 const TestQriConnManagerValue = 6 38 39 var ErrTestQriProtocolNotSupported = fmt.Errorf("test qri protocol not supported") 40 41 // Host returns the node's underlying host 42 func (n *TestableNode) Host() host.Host { 43 return n.host 44 } 45 46 // SimpleAddrInfo returns the PeerInfo of the TestableNode 47 func (n *TestableNode) SimpleAddrInfo() peer.AddrInfo { 48 return peer.AddrInfo{ 49 ID: n.host.ID(), 50 Addrs: n.host.Addrs(), 51 } 52 } 53 54 func (n *TestableNode) TestStreamHandler(s net.Stream) { 55 fmt.Println("stream handler called") 56 } 57 58 // GoOnline assumes the TestNode is not online, it will set 59 // the StreamHandler and updates our profile with the underlying peerIDs 60 func (n *TestableNode) GoOnline(ctx context.Context) error { 61 // add multistream handler for qri protocol to the host 62 // for more info on multistreams check github.com/multformats/go-multistream 63 // Setting the StreamHandler with the TestQriProtocol will let other peers 64 // know that we can speak the TestQriProtocol 65 n.Host().SetStreamHandler(TestQriProtocolID, n.TestStreamHandler) 66 67 p := n.Repo.Profiles().Owner(ctx) 68 p.PeerIDs = []peer.ID{n.host.ID()} 69 70 // update profile with our p2p addresses 71 if err := n.Repo.Profiles().SetOwner(ctx, p); err != nil { 72 return err 73 } 74 75 return nil 76 } 77 78 // NewTestableNode creates a testable node from a repo and a config.P2P 79 // it creates a basic host 80 func NewTestableNode(r repo.Repo, p2pconf *config.P2P, _ event.Publisher) (TestablePeerNode, error) { 81 ctx := context.Background() 82 ps := pstoremem.NewPeerstore() 83 // this is essentially what is located in the p2p.makeBasicHost function 84 pk, err := key.DecodeB64PrivKey(p2pconf.PrivKey) 85 if err != nil { 86 return nil, err 87 } 88 89 pid, err := p2pconf.DecodePeerID() 90 if err != nil { 91 return nil, err 92 } 93 ps.AddPrivKey(pid, pk) 94 ps.AddPubKey(pid, pk.GetPublic()) 95 opts := []libp2p.Option{ 96 libp2p.ListenAddrs(p2pconf.Addrs...), 97 libp2p.Identity(pk), 98 libp2p.Peerstore(ps), 99 libp2p.ConnectionManager(connmgr.NewConnManager(1000, 0, time.Millisecond)), 100 } 101 basicHost, err := libp2p.New(ctx, opts...) 102 if err != nil { 103 return nil, err 104 } 105 localResolver := dsref.SequentialResolver(r.Dscache(), r) 106 return &TestableNode{ 107 host: basicHost, 108 Repo: r, 109 cfg: p2pconf, 110 localResolver: localResolver, 111 }, nil 112 } 113 114 var _ TestablePeerNode = (*TestableNode)(nil) 115 var _ NodeMakerFunc = NewTestableNode