207 lines
6.5 KiB
Diff
207 lines
6.5 KiB
Diff
diff --git c/whisper/whisperv6/api.go w/whisper/whisperv6/api.go
|
|
index 16db034e1..25c072355 100644
|
|
--- c/whisper/whisperv6/api.go
|
|
+++ w/whisper/whisperv6/api.go
|
|
@@ -246,6 +246,29 @@ type newMessageOverride struct {
|
|
|
|
// Post a message on the Whisper network.
|
|
func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, error) {
|
|
+ env, err := MakeEnvelope(api.w, req)
|
|
+ if err != nil {
|
|
+ return false, err
|
|
+ }
|
|
+ // send to specific node (skip PoW check)
|
|
+ if len(req.TargetPeer) > 0 {
|
|
+ n, err := discover.ParseNode(req.TargetPeer)
|
|
+ if err != nil {
|
|
+ return false, fmt.Errorf("failed to parse target peer: %s", err)
|
|
+ }
|
|
+ return true, api.w.SendP2PMessage(n.ID[:], env)
|
|
+ }
|
|
+
|
|
+ // ensure that the message PoW meets the node's minimum accepted PoW
|
|
+ if req.PowTarget < api.w.MinPow() {
|
|
+ return false, ErrTooLowPoW
|
|
+ }
|
|
+
|
|
+ return true, api.w.Send(env)
|
|
+}
|
|
+
|
|
+// MakeEnvelope create envelopes from request.
|
|
+func MakeEnvelope(w *Whisper, req NewMessage) (*Envelope, error) {
|
|
var (
|
|
symKeyGiven = len(req.SymKeyID) > 0
|
|
pubKeyGiven = len(req.PublicKey) > 0
|
|
@@ -254,7 +277,7 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, er
|
|
|
|
// user must specify either a symmetric or an asymmetric key
|
|
if (symKeyGiven && pubKeyGiven) || (!symKeyGiven && !pubKeyGiven) {
|
|
- return false, ErrSymAsym
|
|
+ return nil, ErrSymAsym
|
|
}
|
|
|
|
params := &MessageParams{
|
|
@@ -268,21 +291,21 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, er
|
|
|
|
// Set key that is used to sign the message
|
|
if len(req.Sig) > 0 {
|
|
- if params.Src, err = api.w.GetPrivateKey(req.Sig); err != nil {
|
|
- return false, err
|
|
+ if params.Src, err = w.GetPrivateKey(req.Sig); err != nil {
|
|
+ return nil, err
|
|
}
|
|
}
|
|
|
|
// Set symmetric key that is used to encrypt the message
|
|
if symKeyGiven {
|
|
if params.Topic == (TopicType{}) { // topics are mandatory with symmetric encryption
|
|
- return false, ErrNoTopics
|
|
+ return nil, ErrNoTopics
|
|
}
|
|
- if params.KeySym, err = api.w.GetSymKey(req.SymKeyID); err != nil {
|
|
- return false, err
|
|
+ if params.KeySym, err = w.GetSymKey(req.SymKeyID); err != nil {
|
|
+ return nil, err
|
|
}
|
|
if !validateDataIntegrity(params.KeySym, aesKeyLength) {
|
|
- return false, ErrInvalidSymmetricKey
|
|
+ return nil, ErrInvalidSymmetricKey
|
|
}
|
|
}
|
|
|
|
@@ -290,36 +313,21 @@ func (api *PublicWhisperAPI) Post(ctx context.Context, req NewMessage) (bool, er
|
|
if pubKeyGiven {
|
|
params.Dst = crypto.ToECDSAPub(req.PublicKey)
|
|
if !ValidatePublicKey(params.Dst) {
|
|
- return false, ErrInvalidPublicKey
|
|
+ return nil, ErrInvalidPublicKey
|
|
}
|
|
}
|
|
|
|
// encrypt and sent message
|
|
whisperMsg, err := NewSentMessage(params)
|
|
if err != nil {
|
|
- return false, err
|
|
+ return nil, err
|
|
}
|
|
|
|
env, err := whisperMsg.Wrap(params)
|
|
if err != nil {
|
|
- return false, err
|
|
+ return nil, err
|
|
}
|
|
-
|
|
- // send to specific node (skip PoW check)
|
|
- if len(req.TargetPeer) > 0 {
|
|
- n, err := discover.ParseNode(req.TargetPeer)
|
|
- if err != nil {
|
|
- return false, fmt.Errorf("failed to parse target peer: %s", err)
|
|
- }
|
|
- return true, api.w.SendP2PMessage(n.ID[:], env)
|
|
- }
|
|
-
|
|
- // ensure that the message PoW meets the node's minimum accepted PoW
|
|
- if req.PowTarget < api.w.MinPow() {
|
|
- return false, ErrTooLowPoW
|
|
- }
|
|
-
|
|
- return true, api.w.Send(env)
|
|
+ return env, nil
|
|
}
|
|
|
|
// UninstallFilter is alias for Unsubscribe
|
|
diff --git c/whisper/whisperv6/events.go w/whisper/whisperv6/events.go
|
|
new file mode 100644
|
|
index 000000000..4f204ab5d
|
|
--- /dev/null
|
|
+++ w/whisper/whisperv6/events.go
|
|
@@ -0,0 +1,23 @@
|
|
+package whisperv6
|
|
+
|
|
+import (
|
|
+ "github.com/ethereum/go-ethereum/common"
|
|
+ "github.com/ethereum/go-ethereum/p2p/discover"
|
|
+)
|
|
+
|
|
+// EventType used to define known envelope events.
|
|
+type EventType string
|
|
+
|
|
+const (
|
|
+ // EventEnvelopeSent fires when envelope was sent to a peer.
|
|
+ EventEnvelopeSent EventType = "envelope.sent"
|
|
+ // EventEnvelopeExpired fires when envelop expired
|
|
+ EventEnvelopeExpired EventType = "envelope.expired"
|
|
+)
|
|
+
|
|
+// EnvelopeEvent used for envelopes events.
|
|
+type EnvelopeEvent struct {
|
|
+ Event EventType
|
|
+ Hash common.Hash
|
|
+ Peer discover.NodeID
|
|
+}
|
|
diff --git c/whisper/whisperv6/peer.go w/whisper/whisperv6/peer.go
|
|
index 6d75290fd..120767c33 100644
|
|
--- c/whisper/whisperv6/peer.go
|
|
+++ w/whisper/whisperv6/peer.go
|
|
@@ -204,6 +204,11 @@ func (peer *Peer) broadcast() error {
|
|
// mark envelopes only if they were successfully sent
|
|
for _, e := range bundle {
|
|
peer.mark(e)
|
|
+ peer.host.envelopeFeed.Send(EnvelopeEvent{
|
|
+ Event: EventEnvelopeSent,
|
|
+ Hash: e.Hash(),
|
|
+ Peer: peer.peer.ID(), // specifically discover.NodeID because it can be pretty printed
|
|
+ })
|
|
}
|
|
|
|
log.Trace("broadcast", "num. messages", len(bundle))
|
|
diff --git c/whisper/whisperv6/whisper.go w/whisper/whisperv6/whisper.go
|
|
index 8bd991a9b..98115b20f 100644
|
|
--- c/whisper/whisperv6/whisper.go
|
|
+++ w/whisper/whisperv6/whisper.go
|
|
@@ -28,6 +28,7 @@ import (
|
|
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/crypto"
|
|
+ "github.com/ethereum/go-ethereum/event"
|
|
"github.com/ethereum/go-ethereum/log"
|
|
"github.com/ethereum/go-ethereum/p2p"
|
|
"github.com/ethereum/go-ethereum/rlp"
|
|
@@ -85,8 +86,10 @@ type Whisper struct {
|
|
statsMu sync.Mutex // guard stats
|
|
stats Statistics // Statistics of whisper node
|
|
|
|
- mailServer MailServer // MailServer interface
|
|
- envelopeTracer EnvelopeTracer // Service collecting envelopes metadata
|
|
+ mailServer MailServer // MailServer interface
|
|
+ envelopeTracer EnvelopeTracer // Service collecting envelopes metadata
|
|
+
|
|
+ envelopeFeed event.Feed
|
|
}
|
|
|
|
// New creates a Whisper client ready to communicate through the Ethereum P2P network.
|
|
@@ -131,6 +134,12 @@ func New(cfg *Config) *Whisper {
|
|
return whisper
|
|
}
|
|
|
|
+// SubscribeEnvelopeEvents subscribes to envelopes feed.
|
|
+// In order to prevent blocking whisper producers events must be amply buffered.
|
|
+func (whisper *Whisper) SubscribeEnvelopeEvents(events chan<- EnvelopeEvent) event.Subscription {
|
|
+ return whisper.envelopeFeed.Subscribe(events)
|
|
+}
|
|
+
|
|
// MinPow returns the PoW value required by this node.
|
|
func (whisper *Whisper) MinPow() float64 {
|
|
val, exist := whisper.settings.Load(minPowIdx)
|
|
@@ -986,6 +995,10 @@ func (whisper *Whisper) expire() {
|
|
hashSet.Each(func(v interface{}) bool {
|
|
sz := whisper.envelopes[v.(common.Hash)].size()
|
|
delete(whisper.envelopes, v.(common.Hash))
|
|
+ whisper.envelopeFeed.Send(EnvelopeEvent{
|
|
+ Hash: v.(common.Hash),
|
|
+ Event: EventEnvelopeExpired,
|
|
+ })
|
|
whisper.stats.messagesCleared++
|
|
whisper.stats.memoryCleared += sz
|
|
whisper.stats.memoryUsed -= sz
|