From 3563c59b12b0b8b5fd15847bf97d71dfd8416207 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Fri, 17 Apr 2015 16:45:44 +0300 Subject: rpc, whisper, xeth: polish whisper RPC interface --- xeth/whisper.go | 135 ++++++++++++++++++++++---------------------------------- 1 file changed, 53 insertions(+), 82 deletions(-) (limited to 'xeth/whisper.go') diff --git a/xeth/whisper.go b/xeth/whisper.go index 342910b5c..386897f39 100644 --- a/xeth/whisper.go +++ b/xeth/whisper.go @@ -1,7 +1,9 @@ +// Contains the external API to the whisper sub-protocol. + package xeth import ( - "errors" + "fmt" "time" "github.com/ethereum/go-ethereum/common" @@ -12,109 +14,78 @@ import ( var qlogger = logger.NewLogger("XSHH") +// Whisper represents the API wrapper around the internal whisper implementation. type Whisper struct { *whisper.Whisper } +// NewWhisper wraps an internal whisper client into an external API version. func NewWhisper(w *whisper.Whisper) *Whisper { return &Whisper{w} } -func (self *Whisper) Post(payload string, to, from string, topics []string, priority, ttl uint32) error { - if priority == 0 { - priority = 1000 - } - - if ttl == 0 { - ttl = 100 - } - - pk := crypto.ToECDSAPub(common.FromHex(from)) - if key := self.Whisper.GetIdentity(pk); key != nil || len(from) == 0 { - msg := whisper.NewMessage(common.FromHex(payload)) - envelope, err := msg.Wrap(time.Duration(priority*100000), whisper.Options{ - TTL: time.Duration(ttl) * time.Second, - To: crypto.ToECDSAPub(common.FromHex(to)), - From: key, - Topics: whisper.NewTopicsFromStrings(topics...), - }) - - if err != nil { - return err - } - - if err := self.Whisper.Send(envelope); err != nil { - return err - } - } else { - return errors.New("unmatched pub / priv for seal") - } - - return nil -} - +// NewIdentity generates a new cryptographic identity for the client, and injects +// it into the known identities for message decryption. func (self *Whisper) NewIdentity() string { - key := self.Whisper.NewIdentity() - - return common.ToHex(crypto.FromECDSAPub(&key.PublicKey)) + identity := self.Whisper.NewIdentity() + return common.ToHex(crypto.FromECDSAPub(&identity.PublicKey)) } +// HasIdentity checks if the the whisper node is configured with the private key +// of the specified public pair. func (self *Whisper) HasIdentity(key string) bool { return self.Whisper.HasIdentity(crypto.ToECDSAPub(common.FromHex(key))) } -// func (self *Whisper) RemoveIdentity(key string) bool { -// return self.Whisper.RemoveIdentity(crypto.ToECDSAPub(common.FromHex(key))) -// } - -func (self *Whisper) Watch(opts *Options) int { - filter := whisper.Filter{ - To: crypto.ToECDSAPub(common.FromHex(opts.To)), - From: crypto.ToECDSAPub(common.FromHex(opts.From)), - Topics: whisper.NewTopicsFromStrings(opts.Topics...), +// Post injects a message into the whisper network for distribution. +func (self *Whisper) Post(payload string, to, from string, topics []string, priority, ttl uint32) error { + // Construct the whisper message and transmission options + message := whisper.NewMessage(common.FromHex(payload)) + options := whisper.Options{ + To: crypto.ToECDSAPub(common.FromHex(to)), + TTL: time.Duration(ttl) * time.Second, + Topics: whisper.NewTopicsFromStrings(topics...), } - - var i int - filter.Fn = func(msg *whisper.Message) { - opts.Fn(NewWhisperMessage(msg)) + if len(from) != 0 { + if key := self.Whisper.GetIdentity(crypto.ToECDSAPub(common.FromHex(from))); key != nil { + options.From = key + } else { + return fmt.Errorf("unknown identity to send from: %s", from) + } } - - i = self.Whisper.Watch(filter) - - return i -} - -func (self *Whisper) Messages(id int) (messages []WhisperMessage) { - msgs := self.Whisper.Messages(id) - messages = make([]WhisperMessage, len(msgs)) - for i, message := range msgs { - messages[i] = NewWhisperMessage(message) + // Wrap and send the message + pow := time.Duration(priority) * time.Millisecond + envelope, err := message.Wrap(pow, options) + if err != nil { + return err } - - return + if err := self.Whisper.Send(envelope); err != nil { + return err + } + return nil } -type Options struct { - To string - From string - Topics []string - Fn func(msg WhisperMessage) +// Watch installs a new message handler to run in case a matching packet arrives +// from the whisper network. +func (self *Whisper) Watch(to, from string, topics []string, fn func(WhisperMessage)) int { + filter := whisper.Filter{ + To: crypto.ToECDSAPub(common.FromHex(to)), + From: crypto.ToECDSAPub(common.FromHex(from)), + Topics: whisper.NewTopicsFromStrings(topics...), + } + filter.Fn = func(message *whisper.Message) { + fn(NewWhisperMessage(message)) + } + return self.Whisper.Watch(filter) } -type WhisperMessage struct { - ref *whisper.Message - Payload string `json:"payload"` - To string `json:"to"` - From string `json:"from"` - Sent int64 `json:"sent"` -} +// Messages retrieves all the currently pooled messages matching a filter id. +func (self *Whisper) Messages(id int) []WhisperMessage { + pool := self.Whisper.Messages(id) -func NewWhisperMessage(msg *whisper.Message) WhisperMessage { - return WhisperMessage{ - ref: msg, - Payload: common.ToHex(msg.Payload), - From: common.ToHex(crypto.FromECDSAPub(msg.Recover())), - To: common.ToHex(crypto.FromECDSAPub(msg.To)), - Sent: msg.Sent, + messages := make([]WhisperMessage, len(pool)) + for i, message := range pool { + messages[i] = NewWhisperMessage(message) } + return messages } -- cgit v1.2.3 From ae4bfc3cfb3f1debad9dd0211950ce09038ffa90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 21 Apr 2015 18:31:08 +0300 Subject: rpc, ui/qt/qwhisper, whisper, xeth: introduce complex topic filters --- xeth/whisper.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'xeth/whisper.go') diff --git a/xeth/whisper.go b/xeth/whisper.go index 386897f39..25c4af3b1 100644 --- a/xeth/whisper.go +++ b/xeth/whisper.go @@ -67,11 +67,11 @@ func (self *Whisper) Post(payload string, to, from string, topics []string, prio // Watch installs a new message handler to run in case a matching packet arrives // from the whisper network. -func (self *Whisper) Watch(to, from string, topics []string, fn func(WhisperMessage)) int { +func (self *Whisper) Watch(to, from string, topics [][]string, fn func(WhisperMessage)) int { filter := whisper.Filter{ To: crypto.ToECDSAPub(common.FromHex(to)), From: crypto.ToECDSAPub(common.FromHex(from)), - Topics: whisper.NewTopicsFromStrings(topics...), + Topics: whisper.NewTopicFilterFromStrings(topics...), } filter.Fn = func(message *whisper.Message) { fn(NewWhisperMessage(message)) -- cgit v1.2.3 From db615a85ec000dab7f73a6d4b1b46428ba4acdee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 22 Apr 2015 12:50:48 +0300 Subject: ui/qt/qwhisper, whisper, xeth: polish topic filter, fix wildcards --- xeth/whisper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'xeth/whisper.go') diff --git a/xeth/whisper.go b/xeth/whisper.go index 25c4af3b1..36c6ca63f 100644 --- a/xeth/whisper.go +++ b/xeth/whisper.go @@ -71,7 +71,7 @@ func (self *Whisper) Watch(to, from string, topics [][]string, fn func(WhisperMe filter := whisper.Filter{ To: crypto.ToECDSAPub(common.FromHex(to)), From: crypto.ToECDSAPub(common.FromHex(from)), - Topics: whisper.NewTopicFilterFromStrings(topics...), + Topics: whisper.NewFilterTopicsFromStrings(topics...), } filter.Fn = func(message *whisper.Message) { fn(NewWhisperMessage(message)) -- cgit v1.2.3 From 70ded4cbf06d19993d829d843a27002cf181c619 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Wed, 22 Apr 2015 17:25:54 +0300 Subject: xeth: fix un-decoded whisper RPC topic string bug --- xeth/whisper.go | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'xeth/whisper.go') diff --git a/xeth/whisper.go b/xeth/whisper.go index 36c6ca63f..edb62c748 100644 --- a/xeth/whisper.go +++ b/xeth/whisper.go @@ -39,12 +39,17 @@ func (self *Whisper) HasIdentity(key string) bool { // Post injects a message into the whisper network for distribution. func (self *Whisper) Post(payload string, to, from string, topics []string, priority, ttl uint32) error { + // Decode the topic strings + topicsDecoded := make([][]byte, len(topics)) + for i, topic := range topics { + topicsDecoded[i] = common.FromHex(topic) + } // Construct the whisper message and transmission options message := whisper.NewMessage(common.FromHex(payload)) options := whisper.Options{ To: crypto.ToECDSAPub(common.FromHex(to)), TTL: time.Duration(ttl) * time.Second, - Topics: whisper.NewTopicsFromStrings(topics...), + Topics: whisper.NewTopics(topicsDecoded...), } if len(from) != 0 { if key := self.Whisper.GetIdentity(crypto.ToECDSAPub(common.FromHex(from))); key != nil { @@ -68,10 +73,19 @@ func (self *Whisper) Post(payload string, to, from string, topics []string, prio // Watch installs a new message handler to run in case a matching packet arrives // from the whisper network. func (self *Whisper) Watch(to, from string, topics [][]string, fn func(WhisperMessage)) int { + // Decode the topic strings + topicsDecoded := make([][][]byte, len(topics)) + for i, condition := range topics { + topicsDecoded[i] = make([][]byte, len(condition)) + for j, topic := range condition { + topicsDecoded[i][j] = common.FromHex(topic) + } + } + // Assemble and inject the filter into the whisper client filter := whisper.Filter{ To: crypto.ToECDSAPub(common.FromHex(to)), From: crypto.ToECDSAPub(common.FromHex(from)), - Topics: whisper.NewFilterTopicsFromStrings(topics...), + Topics: whisper.NewFilterTopics(topicsDecoded...), } filter.Fn = func(message *whisper.Message) { fn(NewWhisperMessage(message)) -- cgit v1.2.3