github.com/status-im/status-go@v1.1.0/eth-node/bridge/geth/wakuv2.go (about) 1 package gethbridge 2 3 import ( 4 "context" 5 "crypto/ecdsa" 6 "time" 7 8 "github.com/libp2p/go-libp2p/core/peer" 9 "github.com/multiformats/go-multiaddr" 10 "google.golang.org/protobuf/proto" 11 12 "github.com/waku-org/go-waku/waku/v2/protocol" 13 "github.com/waku-org/go-waku/waku/v2/protocol/store" 14 15 "github.com/ethereum/go-ethereum/common" 16 "github.com/ethereum/go-ethereum/p2p/enode" 17 "github.com/status-im/status-go/connection" 18 "github.com/status-im/status-go/eth-node/types" 19 "github.com/status-im/status-go/wakuv2" 20 wakucommon "github.com/status-im/status-go/wakuv2/common" 21 ) 22 23 type gethWakuV2Wrapper struct { 24 waku *wakuv2.Waku 25 } 26 27 // NewGethWakuWrapper returns an object that wraps Geth's Waku in a types interface 28 func NewGethWakuV2Wrapper(w *wakuv2.Waku) types.Waku { 29 if w == nil { 30 panic("waku cannot be nil") 31 } 32 33 return &gethWakuV2Wrapper{ 34 waku: w, 35 } 36 } 37 38 // GetGethWhisperFrom retrieves the underlying whisper Whisper struct from a wrapped Whisper interface 39 func GetGethWakuV2From(m types.Waku) *wakuv2.Waku { 40 return m.(*gethWakuV2Wrapper).waku 41 } 42 43 func (w *gethWakuV2Wrapper) PublicWakuAPI() types.PublicWakuAPI { 44 return NewGethPublicWakuV2APIWrapper(wakuv2.NewPublicWakuAPI(w.waku)) 45 } 46 47 func (w *gethWakuV2Wrapper) Version() uint { 48 return 2 49 } 50 51 func (w *gethWakuV2Wrapper) PeerCount() int { 52 return w.waku.PeerCount() 53 } 54 55 // DEPRECATED: Not used in WakuV2 56 func (w *gethWakuV2Wrapper) MinPow() float64 { 57 return 0 58 } 59 60 // MaxMessageSize returns the MaxMessageSize set 61 func (w *gethWakuV2Wrapper) MaxMessageSize() uint32 { 62 return w.waku.MaxMessageSize() 63 } 64 65 // DEPRECATED: not used in WakuV2 66 func (w *gethWakuV2Wrapper) BloomFilter() []byte { 67 return nil 68 } 69 70 // GetCurrentTime returns current time. 71 func (w *gethWakuV2Wrapper) GetCurrentTime() time.Time { 72 return w.waku.CurrentTime() 73 } 74 75 func (w *gethWakuV2Wrapper) SubscribeEnvelopeEvents(eventsProxy chan<- types.EnvelopeEvent) types.Subscription { 76 events := make(chan wakucommon.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper 77 go func() { 78 for e := range events { 79 eventsProxy <- *NewWakuV2EnvelopeEventWrapper(&e) 80 } 81 }() 82 83 return NewGethSubscriptionWrapper(w.waku.SubscribeEnvelopeEvents(events)) 84 } 85 86 func (w *gethWakuV2Wrapper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) { 87 return w.waku.GetPrivateKey(id) 88 } 89 90 // AddKeyPair imports a asymmetric private key and returns a deterministic identifier. 91 func (w *gethWakuV2Wrapper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) { 92 return w.waku.AddKeyPair(key) 93 } 94 95 // DeleteKeyPair deletes the key with the specified ID if it exists. 96 func (w *gethWakuV2Wrapper) DeleteKeyPair(keyID string) bool { 97 return w.waku.DeleteKeyPair(keyID) 98 } 99 100 func (w *gethWakuV2Wrapper) AddSymKeyDirect(key []byte) (string, error) { 101 return w.waku.AddSymKeyDirect(key) 102 } 103 104 func (w *gethWakuV2Wrapper) AddSymKeyFromPassword(password string) (string, error) { 105 return w.waku.AddSymKeyFromPassword(password) 106 } 107 108 func (w *gethWakuV2Wrapper) DeleteSymKey(id string) bool { 109 return w.waku.DeleteSymKey(id) 110 } 111 112 func (w *gethWakuV2Wrapper) GetSymKey(id string) ([]byte, error) { 113 return w.waku.GetSymKey(id) 114 } 115 116 func (w *gethWakuV2Wrapper) Subscribe(opts *types.SubscriptionOptions) (string, error) { 117 var ( 118 err error 119 keyAsym *ecdsa.PrivateKey 120 keySym []byte 121 ) 122 123 if opts.SymKeyID != "" { 124 keySym, err = w.GetSymKey(opts.SymKeyID) 125 if err != nil { 126 return "", err 127 } 128 } 129 if opts.PrivateKeyID != "" { 130 keyAsym, err = w.GetPrivateKey(opts.PrivateKeyID) 131 if err != nil { 132 return "", err 133 } 134 } 135 136 f, err := w.createFilterWrapper("", keyAsym, keySym, opts.PubsubTopic, opts.Topics) 137 if err != nil { 138 return "", err 139 } 140 141 id, err := w.waku.Subscribe(GetWakuV2FilterFrom(f)) 142 if err != nil { 143 return "", err 144 } 145 146 f.(*wakuV2FilterWrapper).id = id 147 return id, nil 148 } 149 150 func (w *gethWakuV2Wrapper) GetStats() types.StatsSummary { 151 return w.waku.GetStats() 152 } 153 154 func (w *gethWakuV2Wrapper) GetFilter(id string) types.Filter { 155 return NewWakuV2FilterWrapper(w.waku.GetFilter(id), id) 156 } 157 158 func (w *gethWakuV2Wrapper) Unsubscribe(ctx context.Context, id string) error { 159 return w.waku.Unsubscribe(ctx, id) 160 } 161 162 func (w *gethWakuV2Wrapper) UnsubscribeMany(ids []string) error { 163 return w.waku.UnsubscribeMany(ids) 164 } 165 166 func (w *gethWakuV2Wrapper) createFilterWrapper(id string, keyAsym *ecdsa.PrivateKey, keySym []byte, pubsubTopic string, topics [][]byte) (types.Filter, error) { 167 return NewWakuV2FilterWrapper(&wakucommon.Filter{ 168 KeyAsym: keyAsym, 169 KeySym: keySym, 170 ContentTopics: wakucommon.NewTopicSetFromBytes(topics), 171 PubsubTopic: pubsubTopic, 172 Messages: wakucommon.NewMemoryMessageStore(), 173 }, id), nil 174 } 175 176 func (w *gethWakuV2Wrapper) RequestStoreMessages(ctx context.Context, peerID peer.ID, r types.MessagesRequest, processEnvelopes bool) (types.StoreRequestCursor, int, error) { 177 options := []store.RequestOption{ 178 store.WithPaging(false, uint64(r.Limit)), 179 } 180 181 var cursor []byte 182 if r.StoreCursor != nil { 183 cursor = r.StoreCursor 184 } 185 186 contentTopics := []string{} 187 for _, topic := range r.ContentTopics { 188 contentTopics = append(contentTopics, wakucommon.BytesToTopic(topic).ContentTopic()) 189 } 190 191 query := store.FilterCriteria{ 192 TimeStart: proto.Int64(int64(r.From) * int64(time.Second)), 193 TimeEnd: proto.Int64(int64(r.To) * int64(time.Second)), 194 ContentFilter: protocol.NewContentFilter(w.waku.GetPubsubTopic(r.PubsubTopic), contentTopics...), 195 } 196 197 pbCursor, envelopesCount, err := w.waku.Query(ctx, peerID, query, cursor, options, processEnvelopes) 198 if err != nil { 199 return nil, 0, err 200 } 201 202 if pbCursor != nil { 203 return pbCursor, envelopesCount, nil 204 } 205 206 return nil, envelopesCount, nil 207 } 208 209 func (w *gethWakuV2Wrapper) StartDiscV5() error { 210 return w.waku.StartDiscV5() 211 } 212 213 func (w *gethWakuV2Wrapper) StopDiscV5() error { 214 return w.waku.StopDiscV5() 215 } 216 217 // Subscribe to a pubsub topic, passing an optional public key if the pubsub topic is protected 218 func (w *gethWakuV2Wrapper) SubscribeToPubsubTopic(topic string, optPublicKey *ecdsa.PublicKey) error { 219 return w.waku.SubscribeToPubsubTopic(topic, optPublicKey) 220 } 221 222 func (w *gethWakuV2Wrapper) UnsubscribeFromPubsubTopic(topic string) error { 223 return w.waku.UnsubscribeFromPubsubTopic(topic) 224 } 225 226 func (w *gethWakuV2Wrapper) RetrievePubsubTopicKey(topic string) (*ecdsa.PrivateKey, error) { 227 return w.waku.RetrievePubsubTopicKey(topic) 228 } 229 230 func (w *gethWakuV2Wrapper) StorePubsubTopicKey(topic string, privKey *ecdsa.PrivateKey) error { 231 return w.waku.StorePubsubTopicKey(topic, privKey) 232 } 233 234 func (w *gethWakuV2Wrapper) RemovePubsubTopicKey(topic string) error { 235 return w.waku.RemovePubsubTopicKey(topic) 236 } 237 238 func (w *gethWakuV2Wrapper) AddStorePeer(address multiaddr.Multiaddr) (peer.ID, error) { 239 return w.waku.AddStorePeer(address) 240 } 241 242 func (w *gethWakuV2Wrapper) AddRelayPeer(address multiaddr.Multiaddr) (peer.ID, error) { 243 return w.waku.AddRelayPeer(address) 244 } 245 246 func (w *gethWakuV2Wrapper) Peers() types.PeerStats { 247 return w.waku.Peers() 248 } 249 250 func (w *gethWakuV2Wrapper) DialPeer(address multiaddr.Multiaddr) error { 251 return w.waku.DialPeer(address) 252 } 253 254 func (w *gethWakuV2Wrapper) DialPeerByID(peerID peer.ID) error { 255 return w.waku.DialPeerByID(peerID) 256 } 257 258 func (w *gethWakuV2Wrapper) ListenAddresses() ([]multiaddr.Multiaddr, error) { 259 return w.waku.ListenAddresses(), nil 260 } 261 262 func (w *gethWakuV2Wrapper) RelayPeersByTopic(topic string) (*types.PeerList, error) { 263 return w.waku.RelayPeersByTopic(topic) 264 } 265 266 func (w *gethWakuV2Wrapper) ENR() (*enode.Node, error) { 267 return w.waku.ENR() 268 } 269 270 func (w *gethWakuV2Wrapper) DropPeer(peerID peer.ID) error { 271 return w.waku.DropPeer(peerID) 272 } 273 274 func (w *gethWakuV2Wrapper) ProcessingP2PMessages() bool { 275 return w.waku.ProcessingP2PMessages() 276 } 277 278 func (w *gethWakuV2Wrapper) MarkP2PMessageAsProcessed(hash common.Hash) { 279 w.waku.MarkP2PMessageAsProcessed(hash) 280 } 281 282 func (w *gethWakuV2Wrapper) SubscribeToConnStatusChanges() (*types.ConnStatusSubscription, error) { 283 return w.waku.SubscribeToConnStatusChanges(), nil 284 } 285 286 func (w *gethWakuV2Wrapper) SetCriteriaForMissingMessageVerification(peerID peer.ID, pubsubTopic string, contentTopics []types.TopicType) error { 287 var cTopics []string 288 for _, ct := range contentTopics { 289 cTopics = append(cTopics, wakucommon.TopicType(ct).ContentTopic()) 290 } 291 pubsubTopic = w.waku.GetPubsubTopic(pubsubTopic) 292 w.waku.SetTopicsToVerifyForMissingMessages(peerID, pubsubTopic, cTopics) 293 294 // No err can be be generated by this function. The function returns an error 295 // Just so there's compatibility with GethWakuWrapper from V1 296 return nil 297 } 298 299 func (w *gethWakuV2Wrapper) ConnectionChanged(state connection.State) { 300 w.waku.ConnectionChanged(state) 301 } 302 303 func (w *gethWakuV2Wrapper) ClearEnvelopesCache() { 304 w.waku.ClearEnvelopesCache() 305 } 306 307 type wakuV2FilterWrapper struct { 308 filter *wakucommon.Filter 309 id string 310 } 311 312 // NewWakuFilterWrapper returns an object that wraps Geth's Filter in a types interface 313 func NewWakuV2FilterWrapper(f *wakucommon.Filter, id string) types.Filter { 314 if f.Messages == nil { 315 panic("Messages should not be nil") 316 } 317 318 return &wakuV2FilterWrapper{ 319 filter: f, 320 id: id, 321 } 322 } 323 324 // GetWakuFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface 325 func GetWakuV2FilterFrom(f types.Filter) *wakucommon.Filter { 326 return f.(*wakuV2FilterWrapper).filter 327 } 328 329 // ID returns the filter ID 330 func (w *wakuV2FilterWrapper) ID() string { 331 return w.id 332 } 333 334 func (w *gethWakuV2Wrapper) ConfirmMessageDelivered(hashes []common.Hash) { 335 w.waku.ConfirmMessageDelivered(hashes) 336 } 337 338 func (w *gethWakuV2Wrapper) SetStorePeerID(peerID peer.ID) { 339 w.waku.SetStorePeerID(peerID) 340 } 341 342 func (w *gethWakuV2Wrapper) PeerID() peer.ID { 343 return w.waku.PeerID() 344 } 345 346 func (w *gethWakuV2Wrapper) PingPeer(ctx context.Context, peerID peer.ID) (time.Duration, error) { 347 return w.waku.PingPeer(ctx, peerID) 348 }