github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/swarm/pss/api.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 // 10 // 11 // 12 // 13 // 14 // 15 // 16 // 17 // 18 // 19 // 20 // 21 // 22 // 23 // 24 25 package pss 26 27 import ( 28 "context" 29 "errors" 30 "fmt" 31 32 "github.com/ethereum/go-ethereum/common/hexutil" 33 "github.com/ethereum/go-ethereum/crypto" 34 "github.com/ethereum/go-ethereum/p2p" 35 "github.com/ethereum/go-ethereum/rpc" 36 "github.com/ethereum/go-ethereum/swarm/log" 37 ) 38 39 // 40 // 41 type APIMsg struct { 42 Msg hexutil.Bytes 43 Asymmetric bool 44 Key string 45 } 46 47 // 48 type API struct { 49 *Pss 50 } 51 52 func NewAPI(ps *Pss) *API { 53 return &API{Pss: ps} 54 } 55 56 // 57 // 58 // 59 // 60 // 61 // 62 func (pssapi *API) Receive(ctx context.Context, topic Topic) (*rpc.Subscription, error) { 63 notifier, supported := rpc.NotifierFromContext(ctx) 64 if !supported { 65 return nil, fmt.Errorf("Subscribe not supported") 66 } 67 68 psssub := notifier.CreateSubscription() 69 70 handler := func(msg []byte, p *p2p.Peer, asymmetric bool, keyid string) error { 71 apimsg := &APIMsg{ 72 Msg: hexutil.Bytes(msg), 73 Asymmetric: asymmetric, 74 Key: keyid, 75 } 76 if err := notifier.Notify(psssub.ID, apimsg); err != nil { 77 log.Warn(fmt.Sprintf("notification on pss sub topic rpc (sub %v) msg %v failed!", psssub.ID, msg)) 78 } 79 return nil 80 } 81 82 deregf := pssapi.Register(&topic, handler) 83 go func() { 84 defer deregf() 85 select { 86 case err := <-psssub.Err(): 87 log.Warn(fmt.Sprintf("caught subscription error in pss sub topic %x: %v", topic, err)) 88 case <-notifier.Closed(): 89 log.Warn(fmt.Sprintf("rpc sub notifier closed")) 90 } 91 }() 92 93 return psssub, nil 94 } 95 96 func (pssapi *API) GetAddress(topic Topic, asymmetric bool, key string) (PssAddress, error) { 97 var addr *PssAddress 98 if asymmetric { 99 peer, ok := pssapi.Pss.pubKeyPool[key][topic] 100 if !ok { 101 return nil, fmt.Errorf("pubkey/topic pair %x/%x doesn't exist", key, topic) 102 } 103 addr = peer.address 104 } else { 105 peer, ok := pssapi.Pss.symKeyPool[key][topic] 106 if !ok { 107 return nil, fmt.Errorf("symkey/topic pair %x/%x doesn't exist", key, topic) 108 } 109 addr = peer.address 110 111 } 112 return *addr, nil 113 } 114 115 // 116 func (pssapi *API) BaseAddr() (PssAddress, error) { 117 return PssAddress(pssapi.Pss.BaseAddr()), nil 118 } 119 120 // 121 func (pssapi *API) GetPublicKey() (keybytes hexutil.Bytes) { 122 key := pssapi.Pss.PublicKey() 123 keybytes = crypto.FromECDSAPub(key) 124 return keybytes 125 } 126 127 // 128 func (pssapi *API) SetPeerPublicKey(pubkey hexutil.Bytes, topic Topic, addr PssAddress) error { 129 pk, err := crypto.UnmarshalPubkey(pubkey) 130 if err != nil { 131 return fmt.Errorf("Cannot unmarshal pubkey: %x", pubkey) 132 } 133 err = pssapi.Pss.SetPeerPublicKey(pk, topic, &addr) 134 if err != nil { 135 return fmt.Errorf("Invalid key: %x", pk) 136 } 137 return nil 138 } 139 140 func (pssapi *API) GetSymmetricKey(symkeyid string) (hexutil.Bytes, error) { 141 symkey, err := pssapi.Pss.GetSymmetricKey(symkeyid) 142 return hexutil.Bytes(symkey), err 143 } 144 145 func (pssapi *API) GetSymmetricAddressHint(topic Topic, symkeyid string) (PssAddress, error) { 146 return *pssapi.Pss.symKeyPool[symkeyid][topic].address, nil 147 } 148 149 func (pssapi *API) GetAsymmetricAddressHint(topic Topic, pubkeyid string) (PssAddress, error) { 150 return *pssapi.Pss.pubKeyPool[pubkeyid][topic].address, nil 151 } 152 153 func (pssapi *API) StringToTopic(topicstring string) (Topic, error) { 154 topicbytes := BytesToTopic([]byte(topicstring)) 155 if topicbytes == rawTopic { 156 return rawTopic, errors.New("Topic string hashes to 0x00000000 and cannot be used") 157 } 158 return topicbytes, nil 159 } 160 161 func (pssapi *API) SendAsym(pubkeyhex string, topic Topic, msg hexutil.Bytes) error { 162 return pssapi.Pss.SendAsym(pubkeyhex, topic, msg[:]) 163 } 164 165 func (pssapi *API) SendSym(symkeyhex string, topic Topic, msg hexutil.Bytes) error { 166 return pssapi.Pss.SendSym(symkeyhex, topic, msg[:]) 167 } 168 169 func (pssapi *API) GetPeerTopics(pubkeyhex string) ([]Topic, error) { 170 topics, _, err := pssapi.Pss.GetPublickeyPeers(pubkeyhex) 171 return topics, err 172 173 } 174 175 func (pssapi *API) GetPeerAddress(pubkeyhex string, topic Topic) (PssAddress, error) { 176 return pssapi.Pss.getPeerAddress(pubkeyhex, topic) 177 }