-
Notifications
You must be signed in to change notification settings - Fork 241
/
whisper.go
207 lines (170 loc) · 6.1 KB
/
whisper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
package gethbridge
import (
"crypto/ecdsa"
"time"
"github.com/status-im/status-go/eth-node/types"
"github.com/status-im/status-go/whisper/v6"
)
type gethWhisperWrapper struct {
whisper *whisper.Whisper
}
// NewGethWhisperWrapper returns an object that wraps Geth's Whisper in a types interface
func NewGethWhisperWrapper(w *whisper.Whisper) types.Whisper {
if w == nil {
panic("w cannot be nil")
}
return &gethWhisperWrapper{
whisper: w,
}
}
// GetGethWhisperFrom retrieves the underlying whisper Whisper struct from a wrapped Whisper interface
func GetGethWhisperFrom(m types.Whisper) *whisper.Whisper {
return m.(*gethWhisperWrapper).whisper
}
func (w *gethWhisperWrapper) PublicWhisperAPI() types.PublicWhisperAPI {
return NewGethPublicWhisperAPIWrapper(whisper.NewPublicWhisperAPI(w.whisper))
}
// MinPow returns the PoW value required by this node.
func (w *gethWhisperWrapper) MinPow() float64 {
return w.whisper.MinPow()
}
// BloomFilter returns the aggregated bloom filter for all the topics of interest.
// The nodes are required to send only messages that match the advertised bloom filter.
// If a message does not match the bloom, it will tantamount to spam, and the peer will
// be disconnected.
func (w *gethWhisperWrapper) BloomFilter() []byte {
return w.whisper.BloomFilter()
}
// GetCurrentTime returns current time.
func (w *gethWhisperWrapper) GetCurrentTime() time.Time {
return w.whisper.GetCurrentTime()
}
// SetTimeSource assigns a particular source of time to a whisper object.
func (w *gethWhisperWrapper) SetTimeSource(timesource func() time.Time) {
w.whisper.SetTimeSource(timesource)
}
func (w *gethWhisperWrapper) SubscribeEnvelopeEvents(eventsProxy chan<- types.EnvelopeEvent) types.Subscription {
events := make(chan whisper.EnvelopeEvent, 100) // must be buffered to prevent blocking whisper
go func() {
for e := range events {
eventsProxy <- *NewWhisperEnvelopeEventWrapper(&e)
}
}()
return NewGethSubscriptionWrapper(w.whisper.SubscribeEnvelopeEvents(events))
}
func (w *gethWhisperWrapper) GetPrivateKey(id string) (*ecdsa.PrivateKey, error) {
return w.whisper.GetPrivateKey(id)
}
// AddKeyPair imports a asymmetric private key and returns a deterministic identifier.
func (w *gethWhisperWrapper) AddKeyPair(key *ecdsa.PrivateKey) (string, error) {
return w.whisper.AddKeyPair(key)
}
// DeleteKeyPair deletes the key with the specified ID if it exists.
func (w *gethWhisperWrapper) DeleteKeyPair(keyID string) bool {
return w.whisper.DeleteKeyPair(keyID)
}
// DeleteKeyPairs removes all cryptographic identities known to the node
func (w *gethWhisperWrapper) DeleteKeyPairs() error {
return w.whisper.DeleteKeyPairs()
}
func (w *gethWhisperWrapper) AddSymKeyDirect(key []byte) (string, error) {
return w.whisper.AddSymKeyDirect(key)
}
func (w *gethWhisperWrapper) AddSymKeyFromPassword(password string) (string, error) {
return w.whisper.AddSymKeyFromPassword(password)
}
func (w *gethWhisperWrapper) DeleteSymKey(id string) bool {
return w.whisper.DeleteSymKey(id)
}
func (w *gethWhisperWrapper) GetSymKey(id string) ([]byte, error) {
return w.whisper.GetSymKey(id)
}
func (w *gethWhisperWrapper) Subscribe(opts *types.SubscriptionOptions) (string, error) {
var (
err error
keyAsym *ecdsa.PrivateKey
keySym []byte
)
if opts.SymKeyID != "" {
keySym, err = w.GetSymKey(opts.SymKeyID)
if err != nil {
return "", err
}
}
if opts.PrivateKeyID != "" {
keyAsym, err = w.GetPrivateKey(opts.PrivateKeyID)
if err != nil {
return "", err
}
}
f, err := w.createFilterWrapper("", keyAsym, keySym, opts.PoW, opts.Topics)
if err != nil {
return "", err
}
id, err := w.whisper.Subscribe(GetWhisperFilterFrom(f))
if err != nil {
return "", err
}
f.(*whisperFilterWrapper).id = id
return id, nil
}
func (w *gethWhisperWrapper) GetFilter(id string) types.Filter {
return NewWhisperFilterWrapper(w.whisper.GetFilter(id), id)
}
func (w *gethWhisperWrapper) Unsubscribe(id string) error {
return w.whisper.Unsubscribe(id)
}
func (w *gethWhisperWrapper) createFilterWrapper(id string, keyAsym *ecdsa.PrivateKey, keySym []byte, pow float64, topics [][]byte) (types.Filter, error) {
return NewWhisperFilterWrapper(&whisper.Filter{
KeyAsym: keyAsym,
KeySym: keySym,
PoW: pow,
AllowP2P: true,
Topics: topics,
Messages: whisper.NewMemoryMessageStore(),
}, id), nil
}
func (w *gethWhisperWrapper) SendMessagesRequest(peerID []byte, r types.MessagesRequest) error {
return w.whisper.SendMessagesRequest(peerID, whisper.MessagesRequest{
ID: r.ID,
From: r.From,
To: r.To,
Limit: r.Limit,
Cursor: r.Cursor,
Bloom: r.Bloom,
})
}
// RequestHistoricMessages sends a message with p2pRequestCode to a specific peer,
// which is known to implement MailServer interface, and is supposed to process this
// request and respond with a number of peer-to-peer messages (possibly expired),
// which are not supposed to be forwarded any further.
// The whisper protocol is agnostic of the format and contents of envelope.
func (w *gethWhisperWrapper) RequestHistoricMessagesWithTimeout(peerID []byte, envelope types.Envelope, timeout time.Duration) error {
return w.whisper.RequestHistoricMessagesWithTimeout(peerID, envelope.Unwrap().(*whisper.Envelope), timeout)
}
// SyncMessages can be sent between two Mail Servers and syncs envelopes between them.
func (w *gethWhisperWrapper) SyncMessages(peerID []byte, req types.SyncMailRequest) error {
return w.whisper.SyncMessages(peerID, *GetGethSyncMailRequestFrom(&req))
}
type whisperFilterWrapper struct {
filter *whisper.Filter
id string
}
// NewWhisperFilterWrapper returns an object that wraps Geth's Filter in a types interface
func NewWhisperFilterWrapper(f *whisper.Filter, id string) types.Filter {
if f.Messages == nil {
panic("Messages should not be nil")
}
return &whisperFilterWrapper{
filter: f,
id: id,
}
}
// GetWhisperFilterFrom retrieves the underlying whisper Filter struct from a wrapped Filter interface
func GetWhisperFilterFrom(f types.Filter) *whisper.Filter {
return f.(*whisperFilterWrapper).filter
}
// ID returns the filter ID
func (w *whisperFilterWrapper) ID() string {
return w.id
}