diff options
-rw-r--r-- | cmd/mist/assets/qml/views/whisper.qml | 3 | ||||
-rw-r--r-- | event/filter/generic_filter.go | 20 | ||||
-rw-r--r-- | ui/qt/qwhisper/whisper.go | 28 | ||||
-rw-r--r-- | whisper/envelope.go | 6 | ||||
-rw-r--r-- | whisper/util.go | 11 | ||||
-rw-r--r-- | whisper/whisper.go | 4 |
6 files changed, 56 insertions, 16 deletions
diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml index 631f1981e..b50841ba5 100644 --- a/cmd/mist/assets/qml/views/whisper.qml +++ b/cmd/mist/assets/qml/views/whisper.qml @@ -20,6 +20,8 @@ Rectangle { Component.onCompleted: { identity = shh.newIdentity() console.log("New identity:", identity) + + var t = shh.watch({topics: ["chat"]}) } RowLayout { @@ -35,7 +37,6 @@ Rectangle { id: topics placeholderText: "topic1, topic2, topic3, ..." } - Button { text: "Send" onClicked: { diff --git a/event/filter/generic_filter.go b/event/filter/generic_filter.go index b04b4801e..2ce0f0642 100644 --- a/event/filter/generic_filter.go +++ b/event/filter/generic_filter.go @@ -2,19 +2,29 @@ package filter type Generic struct { Str1, Str2, Str3 string + Data map[string]struct{} Fn func(data interface{}) } +// self = registered, f = incoming func (self Generic) Compare(f Filter) bool { + var strMatch, dataMatch = true, true + filter := f.(Generic) - if (len(self.Str1) == 0 || filter.Str1 == self.Str1) && - (len(self.Str2) == 0 || filter.Str2 == self.Str2) && - (len(self.Str3) == 0 || filter.Str3 == self.Str3) { - return true + if (len(self.Str1) > 0 && filter.Str1 != self.Str1) || + (len(self.Str2) > 0 && filter.Str2 != self.Str2) || + (len(self.Str3) > 0 && filter.Str3 != self.Str3) { + strMatch = false + } + + for k, _ := range self.Data { + if _, ok := filter.Data[k]; !ok { + return false + } } - return false + return strMatch && dataMatch } func (self Generic) Trigger(data interface{}) { diff --git a/ui/qt/qwhisper/whisper.go b/ui/qt/qwhisper/whisper.go index 62c4c743b..8f05c0695 100644 --- a/ui/qt/qwhisper/whisper.go +++ b/ui/qt/qwhisper/whisper.go @@ -3,6 +3,7 @@ package qwhisper import ( "fmt" "time" + "unsafe" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethutil" @@ -18,13 +19,22 @@ func fromHex(s string) []byte { } func toHex(b []byte) string { return "0x" + ethutil.Bytes2Hex(b) } +type Watch struct { +} + +func (self *Watch) Arrived(v unsafe.Pointer) { + fmt.Println(v) +} + type Whisper struct { *whisper.Whisper view qml.Object + + watches map[int]*Watch } func New(w *whisper.Whisper) *Whisper { - return &Whisper{w, nil} + return &Whisper{w, nil, make(map[int]*Watch)} } func (self *Whisper) SetView(view qml.Object) { @@ -37,7 +47,7 @@ func (self *Whisper) Post(data string, to, from string, topics []string, pow, tt Ttl: time.Duration(ttl), To: crypto.ToECDSAPub(fromHex(to)), From: crypto.ToECDSA(fromHex(from)), - Topics: whisper.TopicsFromString(topics), + Topics: whisper.TopicsFromString(topics...), }) if err != nil { fmt.Println(err) @@ -60,12 +70,15 @@ func (self *Whisper) HasIdentity(key string) bool { return self.Whisper.HasIdentity(crypto.ToECDSA(fromHex(key))) } -func (self *Whisper) Watch(opts map[string]interface{}) { +func (self *Whisper) Watch(opts map[string]interface{}) *Watch { filter := filterFromMap(opts) filter.Fn = func(msg *whisper.Message) { - // TODO POST TO QT WINDOW + fmt.Println(msg) } - self.Whisper.Watch(filter) + i := self.Whisper.Watch(filter) + self.watches[i] = &Watch{} + + return self.watches[i] } func filterFromMap(opts map[string]interface{}) (f whisper.Filter) { @@ -75,6 +88,11 @@ func filterFromMap(opts map[string]interface{}) (f whisper.Filter) { if from, ok := opts["from"].(string); ok { f.From = crypto.ToECDSAPub(fromHex(from)) } + if topicList, ok := opts["topics"].(*qml.List); ok { + var topics []string + topicList.Convert(&topics) + f.Topics = whisper.TopicsFromString(topics...) + } return } diff --git a/whisper/envelope.go b/whisper/envelope.go index dc8d3cda4..066e20f6a 100644 --- a/whisper/envelope.go +++ b/whisper/envelope.go @@ -74,11 +74,13 @@ func (self *Envelope) Open(prv *ecdsa.PrivateKey) (msg *Message, err error) { message.Flags = data[0] message.Signature = data[1:66] } - message.Payload = data[dataStart:] + + payload := data[dataStart:] if prv != nil { - message.Payload, err = crypto.Decrypt(prv, message.Payload) + message.Payload, err = crypto.Decrypt(prv, payload) switch err { case ecies.ErrInvalidPublicKey: // Payload isn't encrypted + message.Payload = payload return &message, err default: return nil, fmt.Errorf("unable to open envelope. Decrypt failed: %v", err) diff --git a/whisper/util.go b/whisper/util.go index abef1d667..7a222395f 100644 --- a/whisper/util.go +++ b/whisper/util.go @@ -18,10 +18,19 @@ func Topics(data [][]byte) [][]byte { return d } -func TopicsFromString(data []string) [][]byte { +func TopicsFromString(data ...string) [][]byte { d := make([][]byte, len(data)) for i, str := range data { d[i] = hashTopic([]byte(str)) } return d } + +func bytesToMap(s [][]byte) map[string]struct{} { + m := make(map[string]struct{}) + for _, topic := range s { + m[string(topic)] = struct{}{} + } + + return m +} diff --git a/whisper/whisper.go b/whisper/whisper.go index 32e951385..9721ca9f9 100644 --- a/whisper/whisper.go +++ b/whisper/whisper.go @@ -4,7 +4,6 @@ import ( "bytes" "crypto/ecdsa" "errors" - "fmt" "sync" "time" @@ -120,6 +119,7 @@ func (self *Whisper) Watch(opts Filter) int { return self.filters.Install(filter.Generic{ Str1: string(crypto.FromECDSA(opts.To)), Str2: string(crypto.FromECDSAPub(opts.From)), + Data: bytesToMap(opts.Topics), Fn: func(data interface{}) { opts.Fn(data.(*Message)) }, @@ -150,7 +150,6 @@ func (self *Whisper) msgHandler(peer *p2p.Peer, ws p2p.MsgReadWriter) error { continue } - fmt.Println("recv") if err := self.add(envelope); err != nil { // TODO Punish peer here. Invalid envelope. peer.Infoln(err) @@ -233,6 +232,7 @@ func (self *Whisper) postEvent(envelope *Envelope) { // Create a custom filter? self.filters.Notify(filter.Generic{ Str1: string(crypto.FromECDSA(key)), Str2: string(crypto.FromECDSAPub(message.Recover())), + Data: bytesToMap(envelope.Topics), }, message) } else { wlogger.Infoln(err) |