github.com/keltia/go-ipfs@v0.3.8-0.20150909044612-210793031c63/util/testutil/gen.go (about) 1 package testutil 2 3 import ( 4 "bytes" 5 "errors" 6 "fmt" 7 "io" 8 "sync" 9 "testing" 10 11 ci "github.com/ipfs/go-ipfs/p2p/crypto" 12 peer "github.com/ipfs/go-ipfs/p2p/peer" 13 u "github.com/ipfs/go-ipfs/util" 14 15 ma "github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr" 16 ) 17 18 // ZeroLocalTCPAddress is the "zero" tcp local multiaddr. This means: 19 // /ip4/127.0.0.1/tcp/0 20 var ZeroLocalTCPAddress ma.Multiaddr 21 22 func init() { 23 // initialize ZeroLocalTCPAddress 24 maddr, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/0") 25 if err != nil { 26 panic(err) 27 } 28 ZeroLocalTCPAddress = maddr 29 } 30 31 func RandTestKeyPair(bits int) (ci.PrivKey, ci.PubKey, error) { 32 return ci.GenerateKeyPairWithReader(ci.RSA, bits, u.NewTimeSeededRand()) 33 } 34 35 func SeededTestKeyPair(seed int64) (ci.PrivKey, ci.PubKey, error) { 36 return ci.GenerateKeyPairWithReader(ci.RSA, 512, u.NewSeededRand(seed)) 37 } 38 39 // RandPeerID generates random "valid" peer IDs. it does not NEED to generate 40 // keys because it is as if we lost the key right away. fine to read randomness 41 // and hash it. to generate proper keys and corresponding PeerID, use: 42 // sk, pk, _ := testutil.RandKeyPair() 43 // id, _ := peer.IDFromPublicKey(pk) 44 func RandPeerID() (peer.ID, error) { 45 buf := make([]byte, 16) 46 if _, err := io.ReadFull(u.NewTimeSeededRand(), buf); err != nil { 47 return "", err 48 } 49 h := u.Hash(buf) 50 return peer.ID(h), nil 51 } 52 53 func RandPeerIDFatal(t testing.TB) peer.ID { 54 p, err := RandPeerID() 55 if err != nil { 56 t.Fatal(err) 57 } 58 return p 59 } 60 61 // RandLocalTCPAddress returns a random multiaddr. it suppresses errors 62 // for nice composability-- do check the address isn't nil. 63 // 64 // Note: for real network tests, use ZeroLocalTCPAddress so the kernel 65 // assigns an unused TCP port. otherwise you may get clashes. This 66 // function remains here so that p2p/net/mock (which does not touch the 67 // real network) can assign different addresses to peers. 68 func RandLocalTCPAddress() ma.Multiaddr { 69 70 // chances are it will work out, but it **might** fail if the port is in use 71 // most ports above 10000 aren't in use by long running processes, so yay. 72 // (maybe there should be a range of "loopback" ports that are guaranteed 73 // to be open for the process, but naturally can only talk to self.) 74 75 lastPort.Lock() 76 if lastPort.port == 0 { 77 lastPort.port = 10000 + SeededRand.Intn(50000) 78 } 79 port := lastPort.port 80 lastPort.port++ 81 lastPort.Unlock() 82 83 addr := fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", port) 84 maddr, _ := ma.NewMultiaddr(addr) 85 return maddr 86 } 87 88 var lastPort = struct { 89 port int 90 sync.Mutex 91 }{} 92 93 // PeerNetParams is a struct to bundle together the four things 94 // you need to run a connection with a peer: id, 2keys, and addr. 95 type PeerNetParams struct { 96 ID peer.ID 97 PrivKey ci.PrivKey 98 PubKey ci.PubKey 99 Addr ma.Multiaddr 100 } 101 102 func (p *PeerNetParams) checkKeys() error { 103 if !p.ID.MatchesPrivateKey(p.PrivKey) { 104 return errors.New("p.ID does not match p.PrivKey") 105 } 106 107 if !p.ID.MatchesPublicKey(p.PubKey) { 108 return errors.New("p.ID does not match p.PubKey") 109 } 110 111 buf := new(bytes.Buffer) 112 buf.Write([]byte("hello world. this is me, I swear.")) 113 b := buf.Bytes() 114 115 sig, err := p.PrivKey.Sign(b) 116 if err != nil { 117 return fmt.Errorf("sig signing failed: %s", err) 118 } 119 120 sigok, err := p.PubKey.Verify(b, sig) 121 if err != nil { 122 return fmt.Errorf("sig verify failed: %s", err) 123 } 124 if !sigok { 125 return fmt.Errorf("sig verify failed: sig invalid") 126 } 127 128 return nil // ok. move along. 129 } 130 131 func RandPeerNetParamsOrFatal(t *testing.T) PeerNetParams { 132 p, err := RandPeerNetParams() 133 if err != nil { 134 t.Fatal(err) 135 return PeerNetParams{} // TODO return nil 136 } 137 return *p 138 } 139 140 func RandPeerNetParams() (*PeerNetParams, error) { 141 var p PeerNetParams 142 var err error 143 p.Addr = ZeroLocalTCPAddress 144 p.PrivKey, p.PubKey, err = RandTestKeyPair(512) 145 if err != nil { 146 return nil, err 147 } 148 p.ID, err = peer.IDFromPublicKey(p.PubKey) 149 if err != nil { 150 return nil, err 151 } 152 if err := p.checkKeys(); err != nil { 153 return nil, err 154 } 155 return &p, nil 156 }