github.com/codingfuture/orig-energi3@v0.8.4/swarm/pss/notify/notify_test.go (about) 1 // Copyright 2018 The Energi Core Authors 2 // Copyright 2018 The go-ethereum Authors 3 // This file is part of the Energi Core library. 4 // 5 // The Energi Core library is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Lesser General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // The Energi Core library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Lesser General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public License 16 // along with the Energi Core library. If not, see <http://www.gnu.org/licenses/>. 17 18 package notify 19 20 import ( 21 "bytes" 22 "context" 23 "flag" 24 "fmt" 25 "os" 26 "testing" 27 "time" 28 29 "github.com/ethereum/go-ethereum/common/hexutil" 30 "github.com/ethereum/go-ethereum/crypto" 31 "github.com/ethereum/go-ethereum/log" 32 "github.com/ethereum/go-ethereum/node" 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/swarm/network" 37 "github.com/ethereum/go-ethereum/swarm/pss" 38 "github.com/ethereum/go-ethereum/swarm/state" 39 whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" 40 ) 41 42 var ( 43 loglevel = flag.Int("l", 3, "loglevel") 44 psses map[string]*pss.Pss 45 w *whisper.Whisper 46 wapi *whisper.PublicWhisperAPI 47 ) 48 49 func init() { 50 testing.Init() 51 flag.Parse() 52 hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) 53 hf := log.LvlFilterHandler(log.Lvl(*loglevel), hs) 54 h := log.CallerFileHandler(hf) 55 log.Root().SetHandler(h) 56 57 w = whisper.New(&whisper.DefaultConfig) 58 wapi = whisper.NewPublicWhisperAPI(w) 59 psses = make(map[string]*pss.Pss) 60 } 61 62 // Creates a client node and notifier node 63 // Client sends pss notifications requests 64 // notifier sends initial notification with symmetric key, and 65 // second notification symmetrically encrypted 66 func TestStart(t *testing.T) { 67 adapter := adapters.NewSimAdapter(newServices(false)) 68 net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ 69 ID: "0", 70 DefaultService: "bzz", 71 }) 72 leftNodeConf := adapters.RandomNodeConfig() 73 leftNodeConf.Services = []string{"bzz", "pss"} 74 leftNode, err := net.NewNodeWithConfig(leftNodeConf) 75 if err != nil { 76 t.Fatal(err) 77 } 78 err = net.Start(leftNode.ID()) 79 if err != nil { 80 t.Fatal(err) 81 } 82 83 rightNodeConf := adapters.RandomNodeConfig() 84 rightNodeConf.Services = []string{"bzz", "pss"} 85 rightNode, err := net.NewNodeWithConfig(rightNodeConf) 86 if err != nil { 87 t.Fatal(err) 88 } 89 err = net.Start(rightNode.ID()) 90 if err != nil { 91 t.Fatal(err) 92 } 93 94 err = net.Connect(rightNode.ID(), leftNode.ID()) 95 if err != nil { 96 t.Fatal(err) 97 } 98 99 leftRpc, err := leftNode.Client() 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 rightRpc, err := rightNode.Client() 105 if err != nil { 106 t.Fatal(err) 107 } 108 109 var leftAddr string 110 err = leftRpc.Call(&leftAddr, "pss_baseAddr") 111 if err != nil { 112 t.Fatal(err) 113 } 114 115 var rightAddr string 116 err = rightRpc.Call(&rightAddr, "pss_baseAddr") 117 if err != nil { 118 t.Fatal(err) 119 } 120 121 var leftPub string 122 err = leftRpc.Call(&leftPub, "pss_getPublicKey") 123 if err != nil { 124 t.Fatal(err) 125 } 126 127 var rightPub string 128 err = rightRpc.Call(&rightPub, "pss_getPublicKey") 129 if err != nil { 130 t.Fatal(err) 131 } 132 133 rsrcName := "foo.eth" 134 rsrcTopic := pss.BytesToTopic([]byte(rsrcName)) 135 136 // wait for kademlia table to populate 137 time.Sleep(time.Second) 138 139 ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) 140 defer cancel() 141 rmsgC := make(chan *pss.APIMsg) 142 rightSub, err := rightRpc.Subscribe(ctx, "pss", rmsgC, "receive", controlTopic, false, false) 143 if err != nil { 144 t.Fatal(err) 145 } 146 defer rightSub.Unsubscribe() 147 148 updateC := make(chan []byte) 149 updateMsg := []byte{} 150 ctrlClient := NewController(psses[rightPub]) 151 ctrlNotifier := NewController(psses[leftPub]) 152 ctrlNotifier.NewNotifier("foo.eth", 2, updateC) 153 154 pubkeybytes, err := hexutil.Decode(leftPub) 155 if err != nil { 156 t.Fatal(err) 157 } 158 pubkey, err := crypto.UnmarshalPubkey(pubkeybytes) 159 if err != nil { 160 t.Fatal(err) 161 } 162 addrbytes, err := hexutil.Decode(leftAddr) 163 if err != nil { 164 t.Fatal(err) 165 } 166 ctrlClient.Subscribe(rsrcName, pubkey, addrbytes, func(s string, b []byte) error { 167 if s != "foo.eth" || !bytes.Equal(updateMsg, b) { 168 t.Fatalf("unexpected result in client handler: '%s':'%x'", s, b) 169 } 170 log.Info("client handler receive", "s", s, "b", b) 171 return nil 172 }) 173 174 var inMsg *pss.APIMsg 175 select { 176 case inMsg = <-rmsgC: 177 case <-ctx.Done(): 178 t.Fatal(ctx.Err()) 179 } 180 181 dMsg, err := NewMsgFromPayload(inMsg.Msg) 182 if err != nil { 183 t.Fatal(err) 184 } 185 if dMsg.namestring != rsrcName { 186 t.Fatalf("expected name '%s', got '%s'", rsrcName, dMsg.namestring) 187 } 188 if !bytes.Equal(dMsg.Payload[:len(updateMsg)], updateMsg) { 189 t.Fatalf("expected payload first %d bytes '%x', got '%x'", len(updateMsg), updateMsg, dMsg.Payload[:len(updateMsg)]) 190 } 191 if len(updateMsg)+symKeyLength != len(dMsg.Payload) { 192 t.Fatalf("expected payload length %d, have %d", len(updateMsg)+symKeyLength, len(dMsg.Payload)) 193 } 194 195 rightSubUpdate, err := rightRpc.Subscribe(ctx, "pss", rmsgC, "receive", rsrcTopic, false, false) 196 if err != nil { 197 t.Fatal(err) 198 } 199 defer rightSubUpdate.Unsubscribe() 200 201 updateMsg = []byte("plugh") 202 updateC <- updateMsg 203 select { 204 case inMsg = <-rmsgC: 205 case <-ctx.Done(): 206 log.Error("timed out waiting for msg", "topic", fmt.Sprintf("%x", rsrcTopic)) 207 t.Fatal(ctx.Err()) 208 } 209 dMsg, err = NewMsgFromPayload(inMsg.Msg) 210 if err != nil { 211 t.Fatal(err) 212 } 213 if dMsg.namestring != rsrcName { 214 t.Fatalf("expected name %s, got %s", rsrcName, dMsg.namestring) 215 } 216 if !bytes.Equal(dMsg.Payload, updateMsg) { 217 t.Fatalf("expected payload '%x', got '%x'", updateMsg, dMsg.Payload) 218 } 219 220 } 221 222 func newServices(allowRaw bool) adapters.Services { 223 stateStore := state.NewInmemoryStore() 224 kademlias := make(map[enode.ID]*network.Kademlia) 225 kademlia := func(id enode.ID) *network.Kademlia { 226 if k, ok := kademlias[id]; ok { 227 return k 228 } 229 params := network.NewKadParams() 230 params.NeighbourhoodSize = 2 231 params.MaxBinSize = 3 232 params.MinBinSize = 1 233 params.MaxRetries = 1000 234 params.RetryExponent = 2 235 params.RetryInterval = 1000000 236 kademlias[id] = network.NewKademlia(id[:], params) 237 return kademlias[id] 238 } 239 return adapters.Services{ 240 "pss": func(ctx *adapters.ServiceContext) (node.Service, error) { 241 ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) 242 defer cancel() 243 keys, err := wapi.NewKeyPair(ctxlocal) 244 if err != nil { 245 return nil, err 246 } 247 privkey, err := w.GetPrivateKey(keys) 248 if err != nil { 249 return nil, err 250 } 251 pssp := pss.NewPssParams().WithPrivateKey(privkey) 252 pssp.MsgTTL = time.Second * 30 253 pssp.AllowRaw = allowRaw 254 pskad := kademlia(ctx.Config.ID) 255 ps, err := pss.NewPss(pskad, pssp) 256 if err != nil { 257 return nil, err 258 } 259 //psses[common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey))] = ps 260 psses[hexutil.Encode(crypto.FromECDSAPub(&privkey.PublicKey))] = ps 261 return ps, nil 262 }, 263 "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { 264 addr := network.NewAddr(ctx.Config.Node()) 265 hp := network.NewHiveParams() 266 hp.Discovery = false 267 config := &network.BzzConfig{ 268 OverlayAddr: addr.Over(), 269 UnderlayAddr: addr.Under(), 270 HiveParams: hp, 271 } 272 return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil 273 }, 274 } 275 }