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