github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/chain/swarm/pss/client/client_test.go (about) 1 // Copyright 2018 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package client 18 19 import ( 20 "bytes" 21 "context" 22 "flag" 23 "fmt" 24 "math/rand" 25 "os" 26 "testing" 27 "time" 28 29 "github.com/ethereum/go-ethereum/common/hexutil" 30 "github.com/ethereum/go-ethereum/log" 31 "github.com/ethereum/go-ethereum/node" 32 "github.com/ethereum/go-ethereum/p2p" 33 "github.com/ethereum/go-ethereum/p2p/enode" 34 "github.com/ethereum/go-ethereum/p2p/simulations" 35 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 36 "github.com/ethereum/go-ethereum/rpc" 37 "github.com/ethereum/go-ethereum/swarm/network" 38 "github.com/ethereum/go-ethereum/swarm/pss" 39 "github.com/ethereum/go-ethereum/swarm/state" 40 whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" 41 ) 42 43 type protoCtrl struct { 44 C chan bool 45 protocol *pss.Protocol 46 run func(*p2p.Peer, p2p.MsgReadWriter) error 47 } 48 49 var ( 50 debugdebugflag = flag.Bool("vv", false, "veryverbose") 51 debugflag = flag.Bool("v", false, "verbose") 52 w *whisper.Whisper 53 wapi *whisper.PublicWhisperAPI 54 // custom logging 55 psslogmain log.Logger 56 pssprotocols map[string]*protoCtrl 57 sendLimit = uint16(256) 58 ) 59 60 var services = newServices() 61 62 func init() { 63 flag.Parse() 64 rand.Seed(time.Now().Unix()) 65 66 adapters.RegisterServices(services) 67 68 loglevel := log.LvlInfo 69 if *debugflag { 70 loglevel = log.LvlDebug 71 } else if *debugdebugflag { 72 loglevel = log.LvlTrace 73 } 74 75 psslogmain = log.New("psslog", "*") 76 hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) 77 hf := log.LvlFilterHandler(loglevel, hs) 78 h := log.CallerFileHandler(hf) 79 log.Root().SetHandler(h) 80 81 w = whisper.New(&whisper.DefaultConfig) 82 wapi = whisper.NewPublicWhisperAPI(w) 83 84 pssprotocols = make(map[string]*protoCtrl) 85 } 86 87 // ping pong exchange across one expired symkey 88 func TestClientHandshake(t *testing.T) { 89 sendLimit = 3 90 91 clients, err := setupNetwork(2) 92 if err != nil { 93 t.Fatal(err) 94 } 95 96 lpsc, err := NewClientWithRPC(clients[0]) 97 if err != nil { 98 t.Fatal(err) 99 } 100 rpsc, err := NewClientWithRPC(clients[1]) 101 if err != nil { 102 t.Fatal(err) 103 } 104 lpssping := &pss.Ping{ 105 OutC: make(chan bool), 106 InC: make(chan bool), 107 Pong: false, 108 } 109 rpssping := &pss.Ping{ 110 OutC: make(chan bool), 111 InC: make(chan bool), 112 Pong: false, 113 } 114 lproto := pss.NewPingProtocol(lpssping) 115 rproto := pss.NewPingProtocol(rpssping) 116 117 ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) 118 defer cancel() 119 err = lpsc.RunProtocol(ctx, lproto) 120 if err != nil { 121 t.Fatal(err) 122 } 123 err = rpsc.RunProtocol(ctx, rproto) 124 if err != nil { 125 t.Fatal(err) 126 } 127 topic := pss.PingTopic.String() 128 129 var loaddr string 130 err = clients[0].Call(&loaddr, "pss_baseAddr") 131 if err != nil { 132 t.Fatalf("rpc get node 1 baseaddr fail: %v", err) 133 } 134 var roaddr string 135 err = clients[1].Call(&roaddr, "pss_baseAddr") 136 if err != nil { 137 t.Fatalf("rpc get node 2 baseaddr fail: %v", err) 138 } 139 140 var lpubkey string 141 err = clients[0].Call(&lpubkey, "pss_getPublicKey") 142 if err != nil { 143 t.Fatalf("rpc get node 1 pubkey fail: %v", err) 144 } 145 var rpubkey string 146 err = clients[1].Call(&rpubkey, "pss_getPublicKey") 147 if err != nil { 148 t.Fatalf("rpc get node 2 pubkey fail: %v", err) 149 } 150 151 err = clients[0].Call(nil, "pss_setPeerPublicKey", rpubkey, topic, roaddr) 152 if err != nil { 153 t.Fatal(err) 154 } 155 err = clients[1].Call(nil, "pss_setPeerPublicKey", lpubkey, topic, loaddr) 156 if err != nil { 157 t.Fatal(err) 158 } 159 160 time.Sleep(time.Second) 161 162 roaddrbytes, err := hexutil.Decode(roaddr) 163 if err != nil { 164 t.Fatal(err) 165 } 166 err = lpsc.AddPssPeer(rpubkey, roaddrbytes, pss.PingProtocol) 167 if err != nil { 168 t.Fatal(err) 169 } 170 171 time.Sleep(time.Second) 172 173 for i := uint16(0); i <= sendLimit; i++ { 174 lpssping.OutC <- false 175 got := <-rpssping.InC 176 log.Warn("ok", "idx", i, "got", got) 177 time.Sleep(time.Second) 178 } 179 180 rw := lpsc.peerPool[pss.PingTopic][rpubkey] 181 lpsc.RemovePssPeer(rpubkey, pss.PingProtocol) 182 if err := rw.WriteMsg(p2p.Msg{ 183 Size: 3, 184 Payload: bytes.NewReader([]byte("foo")), 185 }); err == nil { 186 t.Fatalf("expected error on write") 187 } 188 } 189 190 func setupNetwork(numnodes int) (clients []*rpc.Client, err error) { 191 nodes := make([]*simulations.Node, numnodes) 192 clients = make([]*rpc.Client, numnodes) 193 if numnodes < 2 { 194 return nil, fmt.Errorf("Minimum two nodes in network") 195 } 196 adapter := adapters.NewSimAdapter(services) 197 net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ 198 ID: "0", 199 DefaultService: "bzz", 200 }) 201 for i := 0; i < numnodes; i++ { 202 nodeconf := adapters.RandomNodeConfig() 203 nodeconf.Services = []string{"bzz", "pss"} 204 nodes[i], err = net.NewNodeWithConfig(nodeconf) 205 if err != nil { 206 return nil, fmt.Errorf("error creating node 1: %v", err) 207 } 208 err = net.Start(nodes[i].ID()) 209 if err != nil { 210 return nil, fmt.Errorf("error starting node 1: %v", err) 211 } 212 if i > 0 { 213 err = net.Connect(nodes[i].ID(), nodes[i-1].ID()) 214 if err != nil { 215 return nil, fmt.Errorf("error connecting nodes: %v", err) 216 } 217 } 218 clients[i], err = nodes[i].Client() 219 if err != nil { 220 return nil, fmt.Errorf("create node 1 rpc client fail: %v", err) 221 } 222 } 223 if numnodes > 2 { 224 err = net.Connect(nodes[0].ID(), nodes[len(nodes)-1].ID()) 225 if err != nil { 226 return nil, fmt.Errorf("error connecting first and last nodes") 227 } 228 } 229 return clients, nil 230 } 231 232 func newServices() adapters.Services { 233 stateStore := state.NewInmemoryStore() 234 kademlias := make(map[enode.ID]*network.Kademlia) 235 kademlia := func(id enode.ID) *network.Kademlia { 236 if k, ok := kademlias[id]; ok { 237 return k 238 } 239 params := network.NewKadParams() 240 params.NeighbourhoodSize = 2 241 params.MaxBinSize = 3 242 params.MinBinSize = 1 243 params.MaxRetries = 1000 244 params.RetryExponent = 2 245 params.RetryInterval = 1000000 246 kademlias[id] = network.NewKademlia(id[:], params) 247 return kademlias[id] 248 } 249 return adapters.Services{ 250 "pss": func(ctx *adapters.ServiceContext) (node.Service, error) { 251 ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) 252 defer cancel() 253 keys, err := wapi.NewKeyPair(ctxlocal) 254 if err != nil { 255 return nil, err 256 } 257 privkey, err := w.GetPrivateKey(keys) 258 if err != nil { 259 return nil, err 260 } 261 psparams := pss.NewPssParams().WithPrivateKey(privkey) 262 pskad := kademlia(ctx.Config.ID) 263 ps, err := pss.NewPss(pskad, psparams) 264 if err != nil { 265 return nil, err 266 } 267 pshparams := pss.NewHandshakeParams() 268 pshparams.SymKeySendLimit = sendLimit 269 err = pss.SetHandshakeController(ps, pshparams) 270 if err != nil { 271 return nil, fmt.Errorf("handshake controller fail: %v", err) 272 } 273 return ps, nil 274 }, 275 "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { 276 addr := network.NewAddr(ctx.Config.Node()) 277 hp := network.NewHiveParams() 278 hp.Discovery = false 279 config := &network.BzzConfig{ 280 OverlayAddr: addr.Over(), 281 UnderlayAddr: addr.Under(), 282 HiveParams: hp, 283 } 284 return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil 285 }, 286 } 287 }