From 34689cb3f369ad71164b81d0c05238d78cb67945 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 12 Jan 2015 20:36:45 +0100 Subject: [PATCH] Added manual triggering of filters --- cmd/mist/assets/ext/ethereum.js/lib/web3.js | 2 +- cmd/mist/assets/qml/browser.qml | 9 ++++- event/filter/filter.go | 8 +++++ ui/qt/qwhisper/whisper.go | 4 +++ whisper/whisper.go | 37 +++++++++++++++++---- 5 files changed, 51 insertions(+), 9 deletions(-) diff --git a/cmd/mist/assets/ext/ethereum.js/lib/web3.js b/cmd/mist/assets/ext/ethereum.js/lib/web3.js index 9a85c4d1b..2fe414259 100644 --- a/cmd/mist/assets/ext/ethereum.js/lib/web3.js +++ b/cmd/mist/assets/ext/ethereum.js/lib/web3.js @@ -150,7 +150,7 @@ var shhWatchMethods = function () { return [ { name: 'newFilter', call: 'shh_newFilter' }, { name: 'uninstallFilter', call: 'shh_uninstallFilter' }, - { name: 'getMessage', call: 'shh_getMessages' } + { name: 'getMessages', call: 'shh_getMessages' } ]; }; diff --git a/cmd/mist/assets/qml/browser.qml b/cmd/mist/assets/qml/browser.qml index fcec774a5..7e8ed75bf 100644 --- a/cmd/mist/assets/qml/browser.qml +++ b/cmd/mist/assets/qml/browser.qml @@ -310,7 +310,7 @@ Rectangle { postData(data._id, id); break; - case "eth_messages": + case "eth_filterLogs": require(1); var messages = eth.messages(data.args[0]); @@ -352,6 +352,13 @@ Rectangle { shh.post(params.payload, params.to, params.from, params.topics, params.priority, params.ttl); + break; + + case "shh_getMessages": + require(1); + + shh.trigger(data.args[0]); + break; } } catch(e) { diff --git a/event/filter/filter.go b/event/filter/filter.go index 9817d5782..ca767f413 100644 --- a/event/filter/filter.go +++ b/event/filter/filter.go @@ -68,3 +68,11 @@ out: } } } + +func (self *Filters) Match(a, b Filter) bool { + return reflect.TypeOf(a) == reflect.TypeOf(b) && a.Compare(b) +} + +func (self *Filters) Get(i int) Filter { + return self.watchers[i] +} diff --git a/ui/qt/qwhisper/whisper.go b/ui/qt/qwhisper/whisper.go index 8b4628a1b..becb2a29b 100644 --- a/ui/qt/qwhisper/whisper.go +++ b/ui/qt/qwhisper/whisper.go @@ -84,6 +84,10 @@ func (self *Whisper) Watch(opts map[string]interface{}, view *qml.Common) int { return i } +func (self *Whisper) Trigger(id int) { + go self.Whisper.Trigger(id) +} + func filterFromMap(opts map[string]interface{}) (f whisper.Filter) { if to, ok := opts["to"].(string); ok { f.To = crypto.ToECDSA(fromHex(to)) diff --git a/whisper/whisper.go b/whisper/whisper.go index 3ff4bac5a..bdc69f199 100644 --- a/whisper/whisper.go +++ b/whisper/whisper.go @@ -126,6 +126,20 @@ func (self *Whisper) Watch(opts Filter) int { }) } +func (self *Whisper) Trigger(id int) { + filter := self.filters.Get(id) + if filter != nil { + for _, e := range self.messages { + if msg, key := self.open(e); msg != nil { + f := createFilter(msg, e.Topics, key) + if self.filters.Match(filter, f) { + self.filters.Notify(f, msg) + } + } + } + } +} + // Main handler for passing whisper messages to whisper peer objects func (self *Whisper) msgHandler(peer *p2p.Peer, ws p2p.MsgReadWriter) error { wpeer := NewPeer(self, peer, ws) @@ -227,19 +241,28 @@ func (self *Whisper) envelopes() (envelopes []*Envelope) { } func (self *Whisper) postEvent(envelope *Envelope) { + if message, key := self.open(envelope); message != nil { + self.filters.Notify(createFilter(message, envelope.Topics, key), message) + } +} + +func (self *Whisper) open(envelope *Envelope) (*Message, *ecdsa.PrivateKey) { for _, key := range self.keys { if message, err := envelope.Open(key); err == nil || (err != nil && err == ecies.ErrInvalidPublicKey) { - self.filters.Notify(filter.Generic{ - Str1: string(crypto.FromECDSA(key)), Str2: string(crypto.FromECDSAPub(message.Recover())), - Data: bytesToMap(envelope.Topics), - }, message) - break - } else { - wlogger.Infoln(err) + return message, key } } + + return nil, nil } func (self *Whisper) Protocol() p2p.Protocol { return self.protocol } + +func createFilter(message *Message, topics [][]byte, key *ecdsa.PrivateKey) filter.Filter { + return filter.Generic{ + Str1: string(crypto.FromECDSA(key)), Str2: string(crypto.FromECDSAPub(message.Recover())), + Data: bytesToMap(topics), + } +}