From cad2a1579cdca289db2e1e8e17737317fd5d2af5 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Thu, 23 Oct 2014 12:35:00 +0200 Subject: [PATCH] Topic TopicMAsk builders. --- exp/main.cpp | 6 ++-- libwhisper/Common.cpp | 24 +++++++++++++++ libwhisper/Common.h | 62 +++++++++++++++++++++++++++++++++++++- libwhisper/Interface.h | 22 ++------------ libwhisper/WhisperHost.cpp | 4 +-- libwhisper/WhisperHost.h | 3 +- 6 files changed, 94 insertions(+), 27 deletions(-) diff --git a/exp/main.cpp b/exp/main.cpp index 0717ad051..c1c6139a2 100644 --- a/exp/main.cpp +++ b/exp/main.cpp @@ -102,12 +102,12 @@ int main(int argc, char** argv) if (!remoteHost.empty()) ph.connect(remoteHost, remotePort); - /// Only interested in the packet if the lowest bit is 1 - auto w = wh->installWatch(TopicFilter(TopicMasks({{Topic("0000000000000000000000000000000000000000000000000000000000000001"), Topic("0000000000000000000000000000000000000000000000000000000000000001")}}))); + /// Only interested in odd packets + auto w = wh->installWatch(BuildTopicMask()("odd")); for (int i = 0; ; ++i) { - wh->sendRaw(RLPStream().append(i * i).out(), Topic(u256(i))); + wh->sendRaw(RLPStream().append(i * i).out(), BuildTopic(i)(i % 2 ? "odd" : "even")); for (auto i: wh->checkWatch(w)) { auto p = wh->envelope(i).open().payload(); diff --git a/libwhisper/Common.cpp b/libwhisper/Common.cpp index 52bed0742..e4903821c 100644 --- a/libwhisper/Common.cpp +++ b/libwhisper/Common.cpp @@ -21,8 +21,32 @@ #include "Common.h" +#include using namespace std; using namespace dev; using namespace dev::p2p; using namespace dev::shh; +BuildTopic& BuildTopic::shiftBytes(bytes const& _b) +{ + m_parts.push_back(dev::sha3(_b)); + return *this; +} + +h256 TopicFilter::sha3() const +{ + RLPStream s; + fillStream(s); + return dev::sha3(s.out()); +} + +TopicMask BuildTopicMask::toTopicMask() const +{ + TopicMask ret; + for (auto i = 0; i < 32; ++i) + { + ret.first[i] = m_parts[i * m_parts.size() / 32][i]; + ret.second[i] = m_parts[i * m_parts.size() / 32] ? 255 : 0; + } + return ret; +} diff --git a/libwhisper/Common.h b/libwhisper/Common.h index 49405f00b..1f4c4a17f 100644 --- a/libwhisper/Common.h +++ b/libwhisper/Common.h @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include namespace dev @@ -48,6 +48,8 @@ class WhisperHost; class WhisperPeer; class Whisper; +class Envelope; + enum WhisperPacket { StatusPacket = 0, @@ -59,5 +61,63 @@ enum WhisperPacket using Topic = h256; +class BuildTopic +{ +public: + template BuildTopic(T const& _t) { shift(_t); } + + template BuildTopic& shift(T const& _r) { return shiftBytes(RLPStream().append(_r).out()); } + template BuildTopic& operator()(T const& _t) { return shift(_t); } + + BuildTopic& shiftRaw(h256 const& _part) { m_parts.push_back(_part); return *this; } + + operator Topic() const { return toTopic(); } + Topic toTopic() const { Topic ret; for (auto i = 0; i < 32; ++i) ret[i] = m_parts[i * m_parts.size() / 32][i]; return ret; } + +protected: + BuildTopic() {} + + BuildTopic& shiftBytes(bytes const& _b); + + h256s m_parts; +}; + +using TopicMask = std::pair; +using TopicMasks = std::vector; + +class TopicFilter +{ +public: + TopicFilter() {} + TopicFilter(TopicMask const& _m): m_topicMasks(1, _m) {} + TopicFilter(TopicMasks const& _m): m_topicMasks(_m) {} + TopicFilter(RLP const& _r): m_topicMasks((TopicMasks)_r) {} + + void fillStream(RLPStream& _s) const { _s << m_topicMasks; } + h256 sha3() const; + + bool matches(Envelope const& _m) const; + +private: + TopicMasks m_topicMasks; +}; + +class BuildTopicMask: BuildTopic +{ +public: + BuildTopicMask() { shift(); } + template BuildTopicMask(T const& _t) { shift(_t); } + + template BuildTopicMask& shift(T const& _r) { BuildTopic::shift(_r); return *this; } + BuildTopicMask& shiftRaw(h256 const& _h) { BuildTopic::shiftRaw(_h); return *this; } + BuildTopic& shift() { m_parts.push_back(h256()); return *this; } + + BuildTopicMask& operator()() { shift(); return *this; } + template BuildTopicMask& operator()(T const& _t) { shift(_t); return *this; } + + operator TopicMask() const { return toTopicMask(); } + TopicMask toTopicMask() const; +}; + } } diff --git a/libwhisper/Interface.h b/libwhisper/Interface.h index fda070263..3b2ec7267 100644 --- a/libwhisper/Interface.h +++ b/libwhisper/Interface.h @@ -43,25 +43,6 @@ namespace shh Topic mask; };*/ -using TopicMask = std::pair; -using TopicMasks = std::vector; - -class TopicFilter -{ -public: - TopicFilter() {} - TopicFilter(TopicMasks const& _m): m_topicMasks(_m) {} - TopicFilter(RLP const& _r): m_topicMasks((TopicMasks)_r) {} - - void fillStream(RLPStream& _s) const { _s << m_topicMasks; } - h256 sha3() const { RLPStream s; fillStream(s); return dev::sha3(s.out()); } - - bool matches(Envelope const& _m) const; - -private: - TopicMasks m_topicMasks; -}; - struct InstalledFilter { InstalledFilter(TopicFilter const& _f): filter(_f) {} @@ -86,8 +67,9 @@ public: virtual void inject(Envelope const& _m, WhisperPeer* _from = nullptr) = 0; + unsigned installWatch(TopicMask const& _mask) { return installWatch(TopicFilter(_mask)); } virtual unsigned installWatch(TopicFilter const& _filter) = 0; - virtual unsigned installWatch(h256 _filterId) = 0; + virtual unsigned installWatchOnId(h256 _filterId) = 0; virtual void uninstallWatch(unsigned _watchId) = 0; virtual h256s peekWatch(unsigned _watchId) const = 0; virtual h256s checkWatch(unsigned _watchId) = 0; diff --git a/libwhisper/WhisperHost.cpp b/libwhisper/WhisperHost.cpp index 2f3a21d3e..2d9a5e6b6 100644 --- a/libwhisper/WhisperHost.cpp +++ b/libwhisper/WhisperHost.cpp @@ -87,7 +87,7 @@ void WhisperHost::noteChanged(h256 _messageHash, h256 _filter) } } -unsigned WhisperHost::installWatch(h256 _h) +unsigned WhisperHost::installWatchOnId(h256 _h) { auto ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0; m_watches[ret] = ClientWatch(_h); @@ -104,7 +104,7 @@ unsigned WhisperHost::installWatch(shh::TopicFilter const& _f) if (!m_filters.count(h)) m_filters.insert(make_pair(h, _f)); - return installWatch(h); + return installWatchOnId(h); } void WhisperHost::uninstallWatch(unsigned _i) diff --git a/libwhisper/WhisperHost.h b/libwhisper/WhisperHost.h index cd6746c24..2a8789956 100644 --- a/libwhisper/WhisperHost.h +++ b/libwhisper/WhisperHost.h @@ -50,8 +50,9 @@ public: virtual void inject(Envelope const& _e, WhisperPeer* _from = nullptr); + using Interface::installWatch; virtual unsigned installWatch(TopicFilter const& _filter); - virtual unsigned installWatch(h256 _filterId); + virtual unsigned installWatchOnId(h256 _filterId); virtual void uninstallWatch(unsigned _watchId); virtual h256s peekWatch(unsigned _watchId) const { dev::Guard l(m_filterLock); try { return m_watches.at(_watchId).changes; } catch (...) { return h256s(); } } virtual h256s checkWatch(unsigned _watchId) { dev::Guard l(m_filterLock); h256s ret; try { ret = m_watches.at(_watchId).changes; m_watches.at(_watchId).changes.clear(); } catch (...) {} return ret; }