github.com/jincm/wesharechain@v0.0.0-20210122032815-1537409ce26a/chain/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/ethereum/go-ethereum/common/hexutil" 13 "github.com/ethereum/go-ethereum/crypto" 14 "github.com/ethereum/go-ethereum/log" 15 "github.com/ethereum/go-ethereum/node" 16 "github.com/ethereum/go-ethereum/p2p/enode" 17 "github.com/ethereum/go-ethereum/p2p/simulations" 18 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 19 "github.com/ethereum/go-ethereum/swarm/network" 20 "github.com/ethereum/go-ethereum/swarm/pss" 21 "github.com/ethereum/go-ethereum/swarm/state" 22 whisper "github.com/ethereum/go-ethereum/whisper/whisperv6" 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 defer net.Shutdown() 55 leftNodeConf := adapters.RandomNodeConfig() 56 leftNodeConf.Services = []string{"bzz", "pss"} 57 leftNode, err := net.NewNodeWithConfig(leftNodeConf) 58 if err != nil { 59 t.Fatal(err) 60 } 61 err = net.Start(leftNode.ID()) 62 if err != nil { 63 t.Fatal(err) 64 } 65 66 rightNodeConf := adapters.RandomNodeConfig() 67 rightNodeConf.Services = []string{"bzz", "pss"} 68 rightNode, err := net.NewNodeWithConfig(rightNodeConf) 69 if err != nil { 70 t.Fatal(err) 71 } 72 err = net.Start(rightNode.ID()) 73 if err != nil { 74 t.Fatal(err) 75 } 76 77 err = net.Connect(rightNode.ID(), leftNode.ID()) 78 if err != nil { 79 t.Fatal(err) 80 } 81 82 leftRpc, err := leftNode.Client() 83 if err != nil { 84 t.Fatal(err) 85 } 86 87 rightRpc, err := rightNode.Client() 88 if err != nil { 89 t.Fatal(err) 90 } 91 92 var leftAddr string 93 err = leftRpc.Call(&leftAddr, "pss_baseAddr") 94 if err != nil { 95 t.Fatal(err) 96 } 97 98 var rightAddr string 99 err = rightRpc.Call(&rightAddr, "pss_baseAddr") 100 if err != nil { 101 t.Fatal(err) 102 } 103 104 var leftPub string 105 err = leftRpc.Call(&leftPub, "pss_getPublicKey") 106 if err != nil { 107 t.Fatal(err) 108 } 109 110 var rightPub string 111 err = rightRpc.Call(&rightPub, "pss_getPublicKey") 112 if err != nil { 113 t.Fatal(err) 114 } 115 116 rsrcName := "foo.eth" 117 rsrcTopic := pss.BytesToTopic([]byte(rsrcName)) 118 119 // wait for kademlia table to populate 120 time.Sleep(time.Second) 121 122 ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) 123 defer cancel() 124 rmsgC := make(chan *pss.APIMsg) 125 rightSub, err := rightRpc.Subscribe(ctx, "pss", rmsgC, "receive", controlTopic, false, false) 126 if err != nil { 127 t.Fatal(err) 128 } 129 defer rightSub.Unsubscribe() 130 131 updateC := make(chan []byte) 132 var updateMsg []byte 133 ctrlClient := NewController(psses[rightPub]) 134 ctrlNotifier := NewController(psses[leftPub]) 135 ctrlNotifier.NewNotifier("foo.eth", 2, updateC) 136 137 pubkeybytes, err := hexutil.Decode(leftPub) 138 if err != nil { 139 t.Fatal(err) 140 } 141 pubkey, err := crypto.UnmarshalPubkey(pubkeybytes) 142 if err != nil { 143 t.Fatal(err) 144 } 145 addrbytes, err := hexutil.Decode(leftAddr) 146 if err != nil { 147 t.Fatal(err) 148 } 149 150 copyOfUpdateMsg := make([]byte, len(updateMsg)) 151 copy(copyOfUpdateMsg, updateMsg) 152 ctrlClientError := make(chan error, 1) 153 ctrlClient.Subscribe(rsrcName, pubkey, addrbytes, func(s string, b []byte) error { 154 if s != "foo.eth" || !bytes.Equal(copyOfUpdateMsg, b) { 155 ctrlClientError <- fmt.Errorf("unexpected result in client handler: '%s':'%x'", s, b) 156 } else { 157 log.Info("client handler receive", "s", s, "b", b) 158 } 159 return nil 160 }) 161 162 var inMsg *pss.APIMsg 163 select { 164 case inMsg = <-rmsgC: 165 case err := <-ctrlClientError: 166 t.Fatal(err) 167 case <-ctx.Done(): 168 t.Fatal(ctx.Err()) 169 } 170 171 dMsg, err := NewMsgFromPayload(inMsg.Msg) 172 if err != nil { 173 t.Fatal(err) 174 } 175 if dMsg.namestring != rsrcName { 176 t.Fatalf("expected name '%s', got '%s'", rsrcName, dMsg.namestring) 177 } 178 if !bytes.Equal(dMsg.Payload[:len(updateMsg)], updateMsg) { 179 t.Fatalf("expected payload first %d bytes '%x', got '%x'", len(updateMsg), updateMsg, dMsg.Payload[:len(updateMsg)]) 180 } 181 if len(updateMsg)+symKeyLength != len(dMsg.Payload) { 182 t.Fatalf("expected payload length %d, have %d", len(updateMsg)+symKeyLength, len(dMsg.Payload)) 183 } 184 185 rightSubUpdate, err := rightRpc.Subscribe(ctx, "pss", rmsgC, "receive", rsrcTopic, false, false) 186 if err != nil { 187 t.Fatal(err) 188 } 189 defer rightSubUpdate.Unsubscribe() 190 191 updateMsg = []byte("plugh") 192 updateC <- updateMsg 193 select { 194 case inMsg = <-rmsgC: 195 case <-ctx.Done(): 196 log.Error("timed out waiting for msg", "topic", fmt.Sprintf("%x", rsrcTopic)) 197 t.Fatal(ctx.Err()) 198 } 199 dMsg, err = NewMsgFromPayload(inMsg.Msg) 200 if err != nil { 201 t.Fatal(err) 202 } 203 if dMsg.namestring != rsrcName { 204 t.Fatalf("expected name %s, got %s", rsrcName, dMsg.namestring) 205 } 206 if !bytes.Equal(dMsg.Payload, updateMsg) { 207 t.Fatalf("expected payload '%x', got '%x'", updateMsg, dMsg.Payload) 208 } 209 210 } 211 212 func newServices(allowRaw bool) adapters.Services { 213 stateStore := state.NewInmemoryStore() 214 kademlias := make(map[enode.ID]*network.Kademlia) 215 kademlia := func(id enode.ID) *network.Kademlia { 216 if k, ok := kademlias[id]; ok { 217 return k 218 } 219 params := network.NewKadParams() 220 params.NeighbourhoodSize = 2 221 params.MaxBinSize = 3 222 params.MinBinSize = 1 223 params.MaxRetries = 1000 224 params.RetryExponent = 2 225 params.RetryInterval = 1000000 226 kademlias[id] = network.NewKademlia(id[:], params) 227 return kademlias[id] 228 } 229 return adapters.Services{ 230 "pss": func(ctx *adapters.ServiceContext) (node.Service, error) { 231 ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) 232 defer cancel() 233 keys, err := wapi.NewKeyPair(ctxlocal) 234 if err != nil { 235 return nil, err 236 } 237 privkey, err := w.GetPrivateKey(keys) 238 if err != nil { 239 return nil, err 240 } 241 pssp := pss.NewPssParams().WithPrivateKey(privkey) 242 pssp.MsgTTL = time.Second * 30 243 pssp.AllowRaw = allowRaw 244 pskad := kademlia(ctx.Config.ID) 245 ps, err := pss.NewPss(pskad, pssp) 246 if err != nil { 247 return nil, err 248 } 249 //psses[common.ToHex(crypto.FromECDSAPub(&privkey.PublicKey))] = ps 250 psses[hexutil.Encode(crypto.FromECDSAPub(&privkey.PublicKey))] = ps 251 return ps, nil 252 }, 253 "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { 254 addr := network.NewAddr(ctx.Config.Node()) 255 hp := network.NewHiveParams() 256 hp.Discovery = false 257 config := &network.BzzConfig{ 258 OverlayAddr: addr.Over(), 259 UnderlayAddr: addr.Under(), 260 HiveParams: hp, 261 } 262 return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil 263 }, 264 } 265 }