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