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