Browse Source

New Whisper protocol - uint32s for topics.

cl-refactor
Gav Wood 10 years ago
parent
commit
9a97e73933
  1. 2
      alethzero/MainWin.cpp
  2. 6
      libdevcore/RLP.h
  3. 6
      libjsqrc/main.js
  4. 3
      libweb3jsonrpc/WebThreeStubServer.cpp
  5. 35
      libwhisper/Common.cpp
  6. 8
      libwhisper/Common.h
  7. 7
      libwhisper/Interface.cpp
  8. 2
      libwhisper/Interface.h
  9. 4
      libwhisper/Message.cpp
  10. 13
      libwhisper/Message.h
  11. 7
      libwhisper/WhisperHost.cpp

2
alethzero/MainWin.cpp

@ -2218,7 +2218,7 @@ void Main::refreshWhispers()
time_t ex = e.expiry();
QString t(ctime(&ex));
t.chop(1);
QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topic()).c_str()).arg(msg);
QString item = QString("[%1 - %2s] *%3 %5 %4").arg(t).arg(e.ttl()).arg(e.workProved()).arg(toString(e.topics()).c_str()).arg(msg);
ui->whispers->addItem(item);
}
}

6
libdevcore/RLP.h

@ -159,7 +159,11 @@ public:
/// Best-effort conversion operators.
explicit operator std::string() const { return toString(); }
explicit operator RLPs() const { return toList(); }
explicit operator byte() const { return toInt<byte>(); }
explicit operator uint8_t() const { return toInt<uint8_t>(); }
explicit operator uint16_t() const { return toInt<uint16_t>(); }
explicit operator uint32_t() const { return toInt<uint32_t>(); }
explicit operator uint64_t() const { return toInt<uint64_t>(); }
explicit operator u160() const { return toInt<u160>(); }
explicit operator u256() const { return toInt<u256>(); }
explicit operator bigint() const { return toInt<bigint>(); }
template <unsigned _N> explicit operator FixedHash<_N>() const { return toHash<FixedHash<_N>>(); }

6
libjsqrc/main.js

@ -410,8 +410,10 @@
};
Filter.prototype.trigger = function(messages) {
for(var i = 0; i < this.callbacks.length; i++) {
this.callbacks[i].call(this, messages);
if (!(messages instanceof Array) || messages.length) {
for(var i = 0; i < this.callbacks.length; i++) {
this.callbacks[i].call(this, messages);
}
}
};

3
libweb3jsonrpc/WebThreeStubServer.cpp

@ -268,7 +268,8 @@ static Json::Value toJson(h256 const& _h, shh::Envelope const& _e, shh::Message
res["sent"] = (int)_e.sent();
res["ttl"] = (int)_e.ttl();
res["workProved"] = (int)_e.workProved();
res["topic"] = toJS(_e.topic());
for (auto const& t: _e.topics())
res["topics"].append(toJS((u256)t));
res["payload"] = toJS(_m.payload());
res["from"] = toJS(_m.from());
res["to"] = toJS(_m.to());

35
libwhisper/Common.cpp

@ -22,11 +22,21 @@
#include "Common.h"
#include <libdevcrypto/SHA3.h>
#include "Message.h"
using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
Topic BuildTopic::toTopic() const
{
Topic ret;
ret.reserve(m_parts.size());
for (auto const& h: m_parts)
ret.push_back((TopicPart)u256(h));
return ret;
}
BuildTopic& BuildTopic::shiftBytes(bytes const& _b)
{
m_parts.push_back(dev::sha3(_b));
@ -40,19 +50,32 @@ h256 TopicFilter::sha3() const
return dev::sha3(s.out());
}
bool TopicFilter::matches(Envelope const& _e) const
{
for (TopicMask const& t: m_topicMasks)
{
if (_e.topics().size() == t.size())
for (unsigned i = 0; i < t.size(); ++i)
if (((t[i].first ^ _e.topics()[i]) & t[i].second) != 0)
goto NEXT_TOPICMASK;
return true;
NEXT_TOPICMASK:;
}
return false;
}
TopicMask BuildTopicMask::toTopicMask() const
{
TopicMask ret;
if (m_parts.size())
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;
}
ret.reserve(m_parts.size());
for (auto const& h: m_parts)
ret.push_back(make_pair((TopicPart)u256(h), h ? ~(uint32_t)0 : 0));
return ret;
}
/*
web3.shh.watch({}).arrived(function(m) { env.note("New message:\n"+JSON.stringify(m)); })
k = web3.shh.newIdentity()
web3.shh.post({from: k, topic: web3.fromAscii("test"), payload: web3.fromAscii("Hello world!")})
*/

8
libwhisper/Common.h

@ -59,7 +59,9 @@ enum WhisperPacket
PacketCount
};
using Topic = h256;
using TopicPart = uint32_t;
using Topic = std::vector<TopicPart>;
class BuildTopic
{
@ -73,7 +75,7 @@ public:
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; }
Topic toTopic() const;
protected:
BuildTopic& shiftBytes(bytes const& _b);
@ -81,7 +83,7 @@ protected:
h256s m_parts;
};
using TopicMask = std::pair<Topic, Topic>;
using TopicMask = std::vector<std::pair<TopicPart, TopicPart>>;
using TopicMasks = std::vector<TopicMask>;
class TopicFilter

7
libwhisper/Interface.cpp

@ -34,10 +34,7 @@ using namespace dev::shh;
#endif
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
bool TopicFilter::matches(Envelope const& _e) const
unsigned Interface::installWatch(TopicMask const& _mask)
{
for (TopicMask const& t: m_topicMasks)
if (((t.first ^ _e.topic()) & t.second) == 0)
return true;
return false;
return installWatch(TopicFilter(_mask));
}

2
libwhisper/Interface.h

@ -69,7 +69,7 @@ public:
virtual void inject(Envelope const& _m, WhisperPeer* _from = nullptr) = 0;
unsigned installWatch(TopicMask const& _mask) { return installWatch(TopicFilter(_mask)); }
unsigned installWatch(TopicMask const& _mask);
virtual unsigned installWatch(TopicFilter const& _filter) = 0;
virtual unsigned installWatchOnId(h256 _filterId) = 0;
virtual void uninstallWatch(unsigned _watchId) = 0;

4
libwhisper/Message.cpp

@ -97,7 +97,7 @@ Message Envelope::open(Secret const& _s) const
unsigned Envelope::workProved() const
{
h256 d[2];
d[0] = sha3NoNonce();
d[0] = sha3(WithoutNonce);
d[1] = m_nonce;
return dev::sha3(bytesConstRef(d[0].data(), 64)).firstBitSet();
}
@ -106,7 +106,7 @@ void Envelope::proveWork(unsigned _ms)
{
// PoW
h256 d[2];
d[0] = sha3NoNonce();
d[0] = sha3(WithoutNonce);
uint32_t& n = *(uint32_t*)&(d[1][28]);
unsigned bestBitSet = 0;
bytesConstRef chuck(d[0].data(), 64);

13
libwhisper/Message.h

@ -39,6 +39,12 @@ namespace shh
class Message;
enum IncludeNonce
{
WithoutNonce = 0,
WithNonce = 1
};
class Envelope
{
friend class Message;
@ -56,14 +62,13 @@ public:
operator bool() const { return !!m_expiry; }
void streamRLP(RLPStream& _s, bool _withNonce) const { _s.appendList(_withNonce ? 5 : 4) << m_expiry << m_ttl << m_topic << m_data; if (_withNonce) _s << m_nonce; }
h256 sha3() const { RLPStream s; streamRLP(s, true); return dev::sha3(s.out()); }
h256 sha3NoNonce() const { RLPStream s; streamRLP(s, false); return dev::sha3(s.out()); }
void streamRLP(RLPStream& _s, IncludeNonce _withNonce = WithNonce) const { _s.appendList(_withNonce ? 5 : 4) << m_expiry << m_ttl << m_topic << m_data; if (_withNonce) _s << m_nonce; }
h256 sha3(IncludeNonce _withNonce = WithNonce) const { RLPStream s; streamRLP(s, _withNonce); return dev::sha3(s.out()); }
unsigned sent() const { return m_expiry - m_ttl; }
unsigned expiry() const { return m_expiry; }
unsigned ttl() const { return m_ttl; }
Topic const& topic() const { return m_topic; }
Topic const& topics() const { return m_topic; }
bytes const& data() const { return m_data; }
Message open(Secret const& _s = Secret()) const;

7
libwhisper/WhisperHost.cpp

@ -21,6 +21,7 @@
#include "WhisperHost.h"
#include <libdevcore/CommonIO.h>
#include <libdevcore/Log.h>
#include <libp2p/All.h>
using namespace std;
@ -48,14 +49,14 @@ void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const
{
UpgradeGuard ll(l);
auto const& m = m_messages.at(_m);
cnote << "streamRLP: " << m.expiry() << m.ttl() << m.topic() << toHex(m.data());
m.streamRLP(_s, true);
cnote << "streamRLP: " << m.expiry() << m.ttl() << m.topics() << toHex(m.data());
m.streamRLP(_s);
}
}
void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p)
{
cnote << "inject: " << _m.expiry() << _m.ttl() << _m.topic() << toHex(_m.data());
cnote << "inject: " << _m.expiry() << _m.ttl() << _m.topics() << toHex(_m.data());
if (_m.expiry() <= time(0))
return;

Loading…
Cancel
Save