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  }