From bfd797c3a17782898be4b8d7f24cbb140ea67f46 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Sat, 25 Oct 2014 22:10:53 +0200 Subject: [PATCH] Whisperer in AZ. More Whisper fixups. --- alethzero/Main.ui | 217 ++++++++++++++++++++++++++++++++++++- alethzero/MainWin.cpp | 193 ++++++++++++++++++++++++--------- alethzero/MainWin.h | 4 + libdevcore/Common.cpp | 2 +- libdevcore/FixedHash.h | 2 +- libdevcrypto/EC.cpp | 6 +- libp2p/Host.h | 2 +- libqethereum/QEthereum.cpp | 8 +- libqethereum/QEthereum.h | 4 + libwhisper/WhisperHost.cpp | 6 +- 10 files changed, 385 insertions(+), 59 deletions(-) diff --git a/alethzero/Main.ui b/alethzero/Main.ui index 16dcd8a4c..db246107d 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -6,8 +6,8 @@ 0 0 - 1711 - 1138 + 1617 + 1371 @@ -116,7 +116,7 @@ 0 0 - 1711 + 1617 25 @@ -204,11 +204,18 @@ + + + &Whisper + + + + @@ -1514,6 +1521,205 @@ font-size: 14pt + + + QDockWidget::DockWidgetFeatureMask + + + Whisper + + + 1 + + + + + + + ms + + + 1 + + + 1000 + + + 50 + + + + + + + + 0 + 0 + + + + Topic + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + data + + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + 0 + + + + + + + + 0 + 0 + + + + QFrame::NoFrame + + + 0 + + + + + + + Post + + + + + + + + 0 + 0 + + + + TTL + + + destination + + + + + + + + 0 + 0 + + + + From + + + destination + + + + + + + + 0 + 0 + + + + To + + + destination + + + + + + + false + + + + + + + true + + + + + + + + 0 + 0 + + + + Data + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + data + + + + + + + seconds + + + 5 + + + 259200 + + + + + + + + 0 + 0 + + + + Work to Prove + + + destination + + + + + + &Quit @@ -1801,6 +2007,11 @@ font-size: 14pt Go! + + + New Identity + + diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 9a98f54ee..d4d0b6050 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -146,6 +146,7 @@ Main::Main(QWidget *parent) : auto qeth = m_ethereum; auto qshh = m_whisper; connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, this, qdev, qeth, qshh)); + connect(m_whisper, SIGNAL(idsChanged()), this, SLOT(refreshWhisper())); }); connect(ui->webView, &QWebView::loadFinished, [=]() @@ -332,8 +333,6 @@ void Main::load(QString _s) } } -// env.load("/home/gav/eth/init.eth") - void Main::on_loadJS_triggered() { QString f = QFileDialog::getOpenFileName(this, "Load Javascript", QString(), "Javascript (*.js);;All files (*)"); @@ -388,6 +387,17 @@ void Main::eval(QString const& _js) ui->jsConsole->setHtml(s); } +static Public stringToPublic(QString const& _a) +{ + string sn = _a.toStdString(); + if (_a.size() == sizeof(Public) * 2) + return Public(fromHex(_a.toStdString())); + else if (_a.size() == sizeof(Public) * 2 + 2 && _a.startsWith("0x")) + return Public(fromHex(_a.mid(2).toStdString())); + else + return Public(); +} + QString Main::pretty(dev::Address _a) const { h256 n; @@ -1385,6 +1395,112 @@ void Main::on_destination_currentTextChanged() // updateFee(); } +static bytes dataFromText(QString _s) +{ + bytes ret; + while (_s.size()) + { + QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?"); + QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?"); + QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?"); + if (r.exactMatch(_s)) + { + for (auto i: r.cap(2)) + ret.push_back((byte)i.toLatin1()); + if (r.cap(1) != "$") + for (int i = r.cap(2).size(); i < 32; ++i) + ret.push_back(0); + else + ret.push_back(0); + _s = r.cap(3); + } + else if (d.exactMatch(_s)) + { + u256 v(d.cap(2).toStdString()); + if (d.cap(6) == "szabo") + v *= dev::eth::szabo; + else if (d.cap(5) == "finney") + v *= dev::eth::finney; + else if (d.cap(4) == "ether") + v *= dev::eth::ether; + bytes bs = dev::toCompactBigEndian(v); + if (d.cap(1) != "$") + for (auto i = bs.size(); i < 32; ++i) + ret.push_back(0); + for (auto b: bs) + ret.push_back(b); + _s = d.cap(7); + } + else if (h.exactMatch(_s)) + { + bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString()); + if (h.cap(1) != "$") + for (auto i = bs.size(); i < 32; ++i) + ret.push_back(0); + for (auto b: bs) + ret.push_back(b); + _s = h.cap(5); + } + else + _s = _s.mid(1); + } + return ret; +} + +static shh::Topic topicFromText(QString _s) +{ + shh::BuildTopic ret; + while (_s.size()) + { + QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?"); + QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?"); + QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?"); + bytes part; + if (r.exactMatch(_s)) + { + for (auto i: r.cap(2)) + part.push_back((byte)i.toLatin1()); + if (r.cap(1) != "$") + for (int i = r.cap(2).size(); i < 32; ++i) + part.push_back(0); + else + part.push_back(0); + _s = r.cap(3); + } + else if (d.exactMatch(_s)) + { + u256 v(d.cap(2).toStdString()); + if (d.cap(6) == "szabo") + v *= dev::eth::szabo; + else if (d.cap(5) == "finney") + v *= dev::eth::finney; + else if (d.cap(4) == "ether") + v *= dev::eth::ether; + bytes bs = dev::toCompactBigEndian(v); + if (d.cap(1) != "$") + for (auto i = bs.size(); i < 32; ++i) + part.push_back(0); + for (auto b: bs) + part.push_back(b); + _s = d.cap(7); + } + else if (h.exactMatch(_s)) + { + bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString()); + if (h.cap(1) != "$") + for (auto i = bs.size(); i < 32; ++i) + part.push_back(0); + for (auto b: bs) + part.push_back(b); + _s = h.cap(5); + } + else + _s = _s.mid(1); + ret.shift(part); + } + return ret; +} + void Main::on_data_textChanged() { m_pcWarp.clear(); @@ -1439,54 +1555,7 @@ void Main::on_data_textChanged() } else { - m_data.clear(); - QString s = ui->data->toPlainText(); - while (s.size()) - { - QRegExp r("(@|\\$)?\"([^\"]*)\"(\\s.*)?"); - QRegExp d("(@|\\$)?([0-9]+)(\\s*(ether)|(finney)|(szabo))?(\\s.*)?"); - QRegExp h("(@|\\$)?(0x)?(([a-fA-F0-9])+)(\\s.*)?"); - if (r.exactMatch(s)) - { - for (auto i: r.cap(2)) - m_data.push_back((byte)i.toLatin1()); - if (r.cap(1) != "$") - for (int i = r.cap(2).size(); i < 32; ++i) - m_data.push_back(0); - else - m_data.push_back(0); - s = r.cap(3); - } - else if (d.exactMatch(s)) - { - u256 v(d.cap(2).toStdString()); - if (d.cap(6) == "szabo") - v *= dev::eth::szabo; - else if (d.cap(5) == "finney") - v *= dev::eth::finney; - else if (d.cap(4) == "ether") - v *= dev::eth::ether; - bytes bs = dev::toCompactBigEndian(v); - if (d.cap(1) != "$") - for (auto i = bs.size(); i < 32; ++i) - m_data.push_back(0); - for (auto b: bs) - m_data.push_back(b); - s = d.cap(7); - } - else if (h.exactMatch(s)) - { - bytes bs = fromHex((((h.cap(3).size() & 1) ? "0" : "") + h.cap(3)).toStdString()); - if (h.cap(1) != "$") - for (auto i = bs.size(); i < 32; ++i) - m_data.push_back(0); - for (auto b: bs) - m_data.push_back(b); - s = h.cap(5); - } - else - s = s.mid(1); - } + m_data = dataFromText(ui->data->toPlainText()); ui->code->setHtml(QString::fromStdString(dev::memDump(m_data, 8, true))); if (ethereum()->codeAt(fromString(ui->destination->currentText()), 0).size()) { @@ -2015,6 +2084,30 @@ void Main::updateDebugger() } } +void Main::on_post_clicked() +{ + shh::Message m; + m.setTo(stringToPublic(ui->shhTo->currentText())); + m.setPayload(dataFromText(ui->shhData->toPlainText())); + Public f = stringToPublic(ui->shhFrom->currentText()); + Secret from; + if (m_whisper->ids().count(f)) + from = m_whisper->ids().at(f); + whisper()->inject(m.seal(from, topicFromText(ui->shhTopic->toPlainText()), ui->shhWork->value(), ui->shhTtl->value())); +} + +void Main::on_newIdentity_triggered() +{ + m_whisper->makeIdentity(); +} + +void Main::refreshWhisper() +{ + ui->shhFrom->clear(); + for (auto i: m_whisper->ids()) + ui->shhFrom->addItem(QString::fromStdString(toHex(i.first.ref()))); +} + // extra bits needed to link on VS #ifdef _MSC_VER diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h index aa5fcf572..b8231ddf7 100644 --- a/alethzero/MainWin.h +++ b/alethzero/MainWin.h @@ -149,6 +149,10 @@ private slots: void on_turboMining_triggered(); void on_go_triggered(); void on_importKeyFile_triggered(); + void on_post_clicked(); + void on_newIdentity_triggered(); + + void refreshWhisper(); signals: void poll(); diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp index d9192c79f..97c1d32c7 100644 --- a/libdevcore/Common.cpp +++ b/libdevcore/Common.cpp @@ -27,7 +27,7 @@ using namespace dev; namespace dev { -char const* Version = "0.7.5"; +char const* Version = "0.7.6"; } diff --git a/libdevcore/FixedHash.h b/libdevcore/FixedHash.h index c8d250b35..0032a1314 100644 --- a/libdevcore/FixedHash.h +++ b/libdevcore/FixedHash.h @@ -59,7 +59,7 @@ public: FixedHash() { m_data.fill(0); } /// Construct from another hash, filling with zeroes or cropping as necessary. - template FixedHash(FixedHash const& _h, ConstructFromHashType _t = AlignLeft) { m_data.fill(0); unsigned c = std::min(M, N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i]; } + template explicit FixedHash(FixedHash const& _h, ConstructFromHashType _t = AlignLeft) { m_data.fill(0); unsigned c = std::min(M, N); for (unsigned i = 0; i < c; ++i) m_data[_t == AlignRight ? N - 1 - i : i] = _h[_t == AlignRight ? M - 1 - i : i]; } /// Convert from the corresponding arithmetic type. FixedHash(Arith const& _arith) { toBigEndian(_arith, m_data); } diff --git a/libdevcrypto/EC.cpp b/libdevcrypto/EC.cpp index 75c2fcc3d..7072753b1 100644 --- a/libdevcrypto/EC.cpp +++ b/libdevcrypto/EC.cpp @@ -66,7 +66,11 @@ void dev::crypto::decrypt(Secret const& _k, bytes& io_text) p.resize(d.MaxPlaintextLength(io_text.size())); // todo: use StringSource with _c as input and output. DecodingResult r = d.Decrypt(pp::PRNG(), io_text.data(), clen, p.data()); -// assert(r.messageLength); + if (!r.isValidCoding) + { + io_text.clear(); + return; + } io_text.resize(r.messageLength); io_text = std::move(p); } diff --git a/libp2p/Host.h b/libp2p/Host.h index 34179a3b4..6e60b915e 100644 --- a/libp2p/Host.h +++ b/libp2p/Host.h @@ -203,7 +203,7 @@ private: /// This won't touch alter the blockchain. virtual void doWork(); - std::shared_ptr noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, bool _ready, NodeId _oldId = h256()); + std::shared_ptr noteNode(NodeId _id, bi::tcp::endpoint _a, Origin _o, bool _ready, NodeId _oldId = NodeId()); Nodes potentialPeers(RangeMask const& _known); std::string m_clientVersion; ///< Our version string. diff --git a/libqethereum/QEthereum.cpp b/libqethereum/QEthereum.cpp index 92180817b..535c43325 100644 --- a/libqethereum/QEthereum.cpp +++ b/libqethereum/QEthereum.cpp @@ -707,10 +707,16 @@ QString QWhisper::watchMessages(unsigned _w) } QString QWhisper::newIdentity() +{ + return toQJS(makeIdentity()); +} + +Public QWhisper::makeIdentity() { KeyPair kp = KeyPair::create(); m_ids[kp.pub()] = kp.sec(); - return toQJS(kp.pub()); + emit idsChanged(); + return kp.pub(); } void QWhisper::poll() diff --git a/libqethereum/QEthereum.h b/libqethereum/QEthereum.h index 37f0800cc..9866a4e7a 100644 --- a/libqethereum/QEthereum.h +++ b/libqethereum/QEthereum.h @@ -236,6 +236,9 @@ public: Q_INVOKABLE void clearWatches(); Q_INVOKABLE QString watchMessages(unsigned _w); + dev::Public makeIdentity(); + std::map const& ids() const { return m_ids; } + public slots: /// Check to see if anything has changed, fire off signals if so. /// @note Must be called in the QObject's thread. @@ -243,6 +246,7 @@ public slots: signals: void watchChanged(unsigned _w, QString _envelopeJson); + void idsChanged(); private: std::weak_ptr m_face; diff --git a/libwhisper/WhisperHost.cpp b/libwhisper/WhisperHost.cpp index 26ca3d93b..591574bf0 100644 --- a/libwhisper/WhisperHost.cpp +++ b/libwhisper/WhisperHost.cpp @@ -47,12 +47,16 @@ void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const if (m_messages.count(_m)) { UpgradeGuard ll(l); - m_messages.at(_m).streamOut(_s, true); + auto const& m = m_messages.at(_m); + cnote << "streamOut: " << m.expiry() << m.ttl() << m.topic() << toHex(m.data()); + m.streamOut(_s, true); } } void WhisperHost::inject(Envelope const& _m, WhisperPeer* _p) { + cnote << "inject: " << _m.expiry() << _m.ttl() << _m.topic() << toHex(_m.data()); + if (_m.expiry() <= time(0)) return;