github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/pss/notify/notify_test.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 package notify 10 11 import ( 12 "bytes" 13 "context" 14 "flag" 15 "fmt" 16 "os" 17 "testing" 18 "time" 19 20 "github.com/ethereum/go-ethereum/common/hexutil" 21 "github.com/ethereum/go-ethereum/crypto" 22 "github.com/ethereum/go-ethereum/log" 23 "github.com/ethereum/go-ethereum/node" 24 "github.com/ethereum/go-ethereum/p2p/discover" 25 "github.com/ethereum/go-ethereum/p2p/simulations" 26 "github.com/ethereum/go-ethereum/p2p/simulations/adapters" 27 "github.com/ethereum/go-ethereum/swarm/network" 28 "github.com/ethereum/go-ethereum/swarm/pss" 29 "github.com/ethereum/go-ethereum/swarm/state" 30 whisper "github.com/ethereum/go-ethereum/whisper/whisperv5" 31 ) 32 33 var ( 34 loglevel = flag.Int("l", 3, "loglevel") 35 psses map[string]*pss.Pss 36 w *whisper.Whisper 37 wapi *whisper.PublicWhisperAPI 38 ) 39 40 func init() { 41 flag.Parse() 42 hs := log.StreamHandler(os.Stderr, log.TerminalFormat(true)) 43 hf := log.LvlFilterHandler(log.Lvl(*loglevel), hs) 44 h := log.CallerFileHandler(hf) 45 log.Root().SetHandler(h) 46 47 w = whisper.New(&whisper.DefaultConfig) 48 wapi = whisper.NewPublicWhisperAPI(w) 49 psses = make(map[string]*pss.Pss) 50 } 51 52 // 53 // 54 // 55 // 56 func TestStart(t *testing.T) { 57 adapter := adapters.NewSimAdapter(newServices(false)) 58 net := simulations.NewNetwork(adapter, &simulations.NetworkConfig{ 59 ID: "0", 60 DefaultService: "bzz", 61 }) 62 leftNodeConf := adapters.RandomNodeConfig() 63 leftNodeConf.Services = []string{"bzz", "pss"} 64 leftNode, err := net.NewNodeWithConfig(leftNodeConf) 65 if err != nil { 66 t.Fatal(err) 67 } 68 err = net.Start(leftNode.ID()) 69 if err != nil { 70 t.Fatal(err) 71 } 72 73 rightNodeConf := adapters.RandomNodeConfig() 74 rightNodeConf.Services = []string{"bzz", "pss"} 75 rightNode, err := net.NewNodeWithConfig(rightNodeConf) 76 if err != nil { 77 t.Fatal(err) 78 } 79 err = net.Start(rightNode.ID()) 80 if err != nil { 81 t.Fatal(err) 82 } 83 84 err = net.Connect(rightNode.ID(), leftNode.ID()) 85 if err != nil { 86 t.Fatal(err) 87 } 88 89 leftRpc, err := leftNode.Client() 90 if err != nil { 91 t.Fatal(err) 92 } 93 94 rightRpc, err := rightNode.Client() 95 if err != nil { 96 t.Fatal(err) 97 } 98 99 var leftAddr string 100 err = leftRpc.Call(&leftAddr, "pss_baseAddr") 101 if err != nil { 102 t.Fatal(err) 103 } 104 105 var rightAddr string 106 err = rightRpc.Call(&rightAddr, "pss_baseAddr") 107 if err != nil { 108 t.Fatal(err) 109 } 110 111 var leftPub string 112 err = leftRpc.Call(&leftPub, "pss_getPublicKey") 113 if err != nil { 114 t.Fatal(err) 115 } 116 117 var rightPub string 118 err = rightRpc.Call(&rightPub, "pss_getPublicKey") 119 if err != nil { 120 t.Fatal(err) 121 } 122 123 rsrcName := "foo.eth" 124 rsrcTopic := pss.BytesToTopic([]byte(rsrcName)) 125 126 // 127 time.Sleep(time.Second) 128 129 ctx, cancel := context.WithTimeout(context.Background(), time.Second*2) 130 defer cancel() 131 rmsgC := make(chan *pss.APIMsg) 132 rightSub, err := rightRpc.Subscribe(ctx, "pss", rmsgC, "receive", controlTopic) 133 if err != nil { 134 t.Fatal(err) 135 } 136 defer rightSub.Unsubscribe() 137 138 updateC := make(chan []byte) 139 updateMsg := []byte{} 140 ctrlClient := NewController(psses[rightPub]) 141 ctrlNotifier := NewController(psses[leftPub]) 142 ctrlNotifier.NewNotifier("foo.eth", 2, updateC) 143 144 pubkeybytes, err := hexutil.Decode(leftPub) 145 if err != nil { 146 t.Fatal(err) 147 } 148 pubkey, err := crypto.UnmarshalPubkey(pubkeybytes) 149 if err != nil { 150 t.Fatal(err) 151 } 152 addrbytes, err := hexutil.Decode(leftAddr) 153 if err != nil { 154 t.Fatal(err) 155 } 156 ctrlClient.Subscribe(rsrcName, pubkey, addrbytes, func(s string, b []byte) error { 157 if s != "foo.eth" || !bytes.Equal(updateMsg, b) { 158 t.Fatalf("unexpected result in client handler: '%s':'%x'", s, b) 159 } 160 log.Info("client handler receive", "s", s, "b", b) 161 return nil 162 }) 163 164 var inMsg *pss.APIMsg 165 select { 166 case inMsg = <-rmsgC: 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) 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[discover.NodeID]*network.Kademlia) 215 kademlia := func(id discover.NodeID) *network.Kademlia { 216 if k, ok := kademlias[id]; ok { 217 return k 218 } 219 addr := network.NewAddrFromNodeID(id) 220 params := network.NewKadParams() 221 params.MinProxBinSize = 2 222 params.MaxBinSize = 3 223 params.MinBinSize = 1 224 params.MaxRetries = 1000 225 params.RetryExponent = 2 226 params.RetryInterval = 1000000 227 kademlias[id] = network.NewKademlia(addr.Over(), params) 228 return kademlias[id] 229 } 230 return adapters.Services{ 231 "pss": func(ctx *adapters.ServiceContext) (node.Service, error) { 232 ctxlocal, cancel := context.WithTimeout(context.Background(), time.Second) 233 defer cancel() 234 keys, err := wapi.NewKeyPair(ctxlocal) 235 privkey, err := w.GetPrivateKey(keys) 236 pssp := pss.NewPssParams().WithPrivateKey(privkey) 237 pssp.MsgTTL = time.Second * 30 238 pssp.AllowRaw = allowRaw 239 pskad := kademlia(ctx.Config.ID) 240 ps, err := pss.NewPss(pskad, pssp) 241 if err != nil { 242 return nil, err 243 } 244 // 245 psses[hexutil.Encode(crypto.FromECDSAPub(&privkey.PublicKey))] = ps 246 return ps, nil 247 }, 248 "bzz": func(ctx *adapters.ServiceContext) (node.Service, error) { 249 addr := network.NewAddrFromNodeID(ctx.Config.ID) 250 hp := network.NewHiveParams() 251 hp.Discovery = false 252 config := &network.BzzConfig{ 253 OverlayAddr: addr.Over(), 254 UnderlayAddr: addr.Under(), 255 HiveParams: hp, 256 } 257 return network.NewBzz(config, kademlia(ctx.Config.ID), stateStore, nil, nil), nil 258 }, 259 } 260 }