Browse Source

Merge branch 'develop' into develop-evmcc

cl-refactor
Paweł Bylica 10 years ago
parent
commit
0c92dc1fbc
  1. 4
      alethzero/DownloadView.cpp
  2. 64
      alethzero/Main.ui
  3. 79
      alethzero/MainWin.cpp
  4. 8
      alethzero/MainWin.h
  5. 2
      libdevcore/Common.cpp
  6. 10
      libdevcore/RangeMask.h
  7. 6
      libdevcrypto/Common.cpp
  8. 3
      libdevcrypto/Common.h
  9. 5
      libdevcrypto/CryptoHeaders.h
  10. 29
      libdevcrypto/SHA3.cpp
  11. 2
      libdevcrypto/SHA3.h
  12. 2
      libethcore/CommonEth.cpp
  13. 2
      libethcore/Exceptions.h
  14. 12
      libethereum/BlockChain.cpp
  15. 2
      libethereum/DownloadMan.cpp
  16. 27
      libethereum/DownloadMan.h
  17. 27
      libethereum/EthereumHost.cpp
  18. 53
      libethereum/EthereumPeer.cpp
  19. 3
      libethereum/EthereumPeer.h
  20. 4
      libethereum/Executive.cpp
  21. 11
      libethereum/State.cpp
  22. 2
      libevm/VM.h
  23. 2
      libp2p/Common.h
  24. 4
      libp2p/Session.cpp
  25. 4
      libp2p/Session.h
  26. 59
      libqethereum/QEthereum.cpp
  27. 55
      libqethereum/QEthereum.h
  28. 6
      libwebthree/WebThree.cpp
  29. 6
      libwebthree/WebThree.h
  30. 47
      libwhisper/Interface.cpp
  31. 132
      libwhisper/Interface.h
  32. 28
      libwhisper/Message.cpp
  33. 63
      libwhisper/Message.h
  34. 123
      libwhisper/WhisperHost.cpp
  35. 77
      libwhisper/WhisperHost.h
  36. 129
      libwhisper/WhisperPeer.cpp
  37. 154
      libwhisper/WhisperPeer.h
  38. 3
      libwhisper/_libwhisper.cpp
  39. 4
      merge.sh
  40. 2
      test/TestHelper.cpp
  41. 2
      test/rlp.cpp
  42. 11
      third/MainWin.cpp
  43. 8
      third/MainWin.h
  44. 240
      windows/LibCryptoPP.vcxproj

4
alethzero/DownloadView.cpp

@ -51,7 +51,7 @@ void DownloadView::paintEvent(QPaintEvent*)
QSizeF area(n, n);
QPointF pos(0, 0);
auto const& bg = m_man->blocksGot();
auto bg = m_man->blocksGot();
for (unsigned i = bg.all().first, ei = bg.all().second; i < ei; ++i)
{
@ -63,7 +63,7 @@ void DownloadView::paintEvent(QPaintEvent*)
unsigned h = 0;
m_man->foreachSub([&](DownloadSub const& sub)
{
if (sub.asked().contains(i))
if (sub.askedContains(i))
s = h;
h++;
});

64
alethzero/Main.ui

@ -130,6 +130,8 @@
<property name="title">
<string>&amp;Network</string>
</property>
<addaction name="go"/>
<addaction name="separator"/>
<addaction name="upnp"/>
<addaction name="usePast"/>
<addaction name="localNetworking"/>
@ -141,15 +143,12 @@
<string>T&amp;ools</string>
</property>
<addaction name="mine"/>
<addaction name="preview"/>
<addaction name="separator"/>
<addaction name="create"/>
<addaction name="importKey"/>
<addaction name="importKeyFile"/>
<addaction name="exportKey"/>
<addaction name="separator"/>
<addaction name="showAll"/>
<addaction name="showAllAccounts"/>
<addaction name="separator"/>
<addaction name="loadJS"/>
</widget>
<widget class="QMenu" name="menu_Help">
@ -162,7 +161,32 @@
<property name="title">
<string>Deb&amp;ug</string>
</property>
<widget class="QMenu" name="menuDump_Trace">
<addaction name="debugDumpState"/>
<addaction name="debugDumpStatePre"/>
<addaction name="separator"/>
<addaction name="paranoia"/>
<addaction name="killBlockchain"/>
<addaction name="inject"/>
<addaction name="forceMining"/>
<addaction name="turboMining"/>
<addaction name="enableOptimizer"/>
<addaction name="separator"/>
<addaction name="usePrivate"/>
</widget>
<widget class="QMenu" name="menu_View">
<property name="title">
<string>&amp;View</string>
</property>
<addaction name="showAll"/>
<addaction name="showAllAccounts"/>
<addaction name="separator"/>
<addaction name="preview"/>
</widget>
<widget class="QMenu" name="menuDebugger">
<property name="title">
<string>D&amp;ebugger</string>
</property>
<widget class="QMenu" name="menu_Dump_Trace">
<property name="title">
<string>&amp;Dump Trace</string>
</property>
@ -171,8 +195,7 @@
<addaction name="dumpTracePretty"/>
</widget>
<addaction name="debugCurrent"/>
<addaction name="debugDumpState"/>
<addaction name="debugDumpStatePre"/>
<addaction name="menu_Dump_Trace"/>
<addaction name="separator"/>
<addaction name="debugStep"/>
<addaction name="debugStepInto"/>
@ -180,20 +203,12 @@
<addaction name="debugStepBack"/>
<addaction name="debugStepBackInto"/>
<addaction name="debugStepBackOut"/>
<addaction name="menuDump_Trace"/>
<addaction name="separator"/>
<addaction name="paranoia"/>
<addaction name="killBlockchain"/>
<addaction name="inject"/>
<addaction name="forceMining"/>
<addaction name="turboMining"/>
<addaction name="enableOptimizer"/>
<addaction name="separator"/>
<addaction name="usePrivate"/>
</widget>
<addaction name="menu_File"/>
<addaction name="menu_View"/>
<addaction name="menu_Network"/>
<addaction name="menu_Tools"/>
<addaction name="menuDebugger"/>
<addaction name="menu_Debug"/>
<addaction name="menu_Help"/>
</widget>
@ -507,8 +522,7 @@
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
<addaction name="net"/>
<addaction name="connect"/>
<addaction name="go"/>
<addaction name="preview"/>
<addaction name="mine"/>
<addaction name="refresh"/>
@ -1521,7 +1535,7 @@ font-size: 14pt</string>
<bool>true</bool>
</property>
<property name="text">
<string>&amp;Preview</string>
<string>&amp;Preview Pending Transactions</string>
</property>
</action>
<action name="debugStep">
@ -1740,6 +1754,16 @@ font-size: 14pt</string>
<string>Enable Local Addresses</string>
</property>
</action>
<action name="importKeyFile">
<property name="text">
<string>Claim Ether Presale &amp;Wallet...</string>
</property>
</action>
<action name="go">
<property name="text">
<string>Go!</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>

79
alethzero/MainWin.cpp

@ -25,9 +25,11 @@
#include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog>
#include <QtWebKitWidgets/QWebFrame>
#include <QtWebKit/QWebSettings>
#include <QtGui/QClipboard>
#include <QtCore/QtCore>
#include <boost/algorithm/string.hpp>
#include <test/JsonSpiritHeaders.h>
#include <libserpent/funcs.h>
#include <libserpent/util.h>
#include <libdevcrypto/FileSystem.h>
@ -49,6 +51,7 @@ using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::eth;
namespace js = json_spirit;
static void initUnits(QComboBox* _b)
{
@ -133,11 +136,14 @@ Main::Main(QWidget *parent) :
{
// NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it.
m_ethereum = new QEthereum(this, ethereum(), owned());
m_whisper = new QWhisper(this, whisper());
QWebSettings::globalSettings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true);
QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
auto qeth = m_ethereum;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, this));
auto qshh = m_whisper;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, qshh, this));
});
connect(ui->webView, &QWebView::loadFinished, [=]()
@ -456,7 +462,7 @@ QString Main::lookup(QString const& _a) const
void Main::on_about_triggered()
{
QMessageBox::about(this, "About AlethZero PoC-" + QString(dev::Version).section('.', 1, 1), QString("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) "\n" DEV_QUOTED(ETH_COMMIT_HASH) + (ETH_CLEAN_REPO ? "\nCLEAN" : "\n+ LOCAL CHANGES") + "\n\nBy Gav Wood, 2014.\nBased on a design by Vitalik Buterin.\n\nThanks to the various contributors including: Alex Leverington, Tim Hughes, caktux, Eric Lombrozo, Marko Simovic.");
QMessageBox::about(this, "About AlethZero PoC-" + QString(dev::Version).section('.', 1, 1), QString("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) "\n" DEV_QUOTED(ETH_COMMIT_HASH) + (ETH_CLEAN_REPO ? "\nCLEAN" : "\n+ LOCAL CHANGES") + "\n\nBy Gav Wood, 2014.\nThis software wouldn't be where it is today without the many leaders & contributors including:\n\nVitalik Buterin, Tim Hughes, caktux, Nick Savers, Eric Lombrozo, Marko Simovic, the many testers and the Berlin \304\220\316\236V team.");
}
void Main::on_paranoia_triggered()
@ -560,8 +566,7 @@ void Main::on_importKey_triggered()
if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end())
{
m_myKeys.append(k);
m_keysChanged = true;
update();
keysChanged();
}
else
QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account.");
@ -570,6 +575,53 @@ void Main::on_importKey_triggered()
QMessageBox::warning(this, "Invalid Entry", "Could not import the secret key; invalid key entered. Make sure it is 64 hex characters (0-9 or A-F).");
}
void Main::on_importKeyFile_triggered()
{
QString s = QFileDialog::getOpenFileName(this, "Import Account", QDir::homePath(), "JSON Files (*.json);;All Files (*)");
try
{
js::mValue val;
json_spirit::read_string(asString(contents(s.toStdString())), val);
auto obj = val.get_obj();
if (obj["encseed"].type() == js::str_type)
{
auto encseed = fromHex(obj["encseed"].get_str());
KeyPair k;
for (bool gotit = false; !gotit;)
{
gotit = true;
k = KeyPair::fromEncryptedSeed(&encseed, QInputDialog::getText(this, "Enter Password", "Enter the wallet's passphrase", QLineEdit::Password).toStdString());
if (obj["ethaddr"].type() == js::str_type)
{
Address a(obj["ethaddr"].get_str());
Address b = k.address();
if (a != b)
{
if (QMessageBox::warning(this, "Password Wrong", "Could not import the secret key: the password you gave appears to be wrong.", QMessageBox::Retry, QMessageBox::Cancel) == QMessageBox::Cancel)
return;
else
gotit = false;
}
}
}
if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end())
{
m_myKeys.append(k);
keysChanged();
}
else
QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account.");
}
else
throw 0;
}
catch (...)
{
QMessageBox::warning(this, "Key File Invalid", "Could not find secret key definition. This is probably not an Ethereum key file.");
}
}
void Main::on_exportKey_triggered()
{
if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size())
@ -691,7 +743,7 @@ void Main::refreshNetwork()
ui->peerCount->setText(QString::fromStdString(toString(ps.size())) + " peer(s)");
ui->peers->clear();
for (PeerInfo const& i: ps)
ui->peers->addItem(QString("%3 ms - %1:%2 - %4 %5").arg(i.host.c_str()).arg(i.port).arg(chrono::duration_cast<chrono::milliseconds>(i.lastPing).count()).arg(i.clientVersion.c_str()).arg(QString::fromStdString(toString(i.caps))));
ui->peers->addItem(QString("[%7] %3 ms - %1:%2 - %4 %5 %6").arg(i.host.c_str()).arg(i.port).arg(chrono::duration_cast<chrono::milliseconds>(i.lastPing).count()).arg(i.clientVersion.c_str()).arg(QString::fromStdString(toString(i.caps))).arg(QString::fromStdString(toString(i.notes))).arg(i.socket));
}
void Main::refreshAll()
@ -1545,6 +1597,11 @@ void Main::on_send_clicked()
statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount.");
}
void Main::keysChanged()
{
onBalancesChange();
}
void Main::on_debug_clicked()
{
debugFinished();
@ -1581,7 +1638,7 @@ void Main::on_debug_clicked()
void Main::on_create_triggered()
{
m_myKeys.append(KeyPair::create());
m_keysChanged = true;
keysChanged();
}
void Main::on_debugStep_triggered()
@ -1689,6 +1746,16 @@ void Main::on_dumpTraceStorage_triggered()
}
}
void Main::on_go_triggered()
{
if (!ui->net->isChecked())
{
ui->net->setChecked(true);
on_net_triggered();
}
web3()->connect(Host::pocHost());
}
void Main::on_callStack_currentItemChanged()
{
updateDebugger();

8
alethzero/MainWin.h

@ -75,7 +75,7 @@ public:
dev::WebThreeDirect* web3() const { return m_webThree.get(); }
dev::eth::Client* ethereum() const { return m_webThree->ethereum(); }
dev::shh::WhisperHost* whisper() const { return m_webThree->whisper(); }
std::shared_ptr<dev::shh::WhisperHost> whisper() const { return m_webThree->whisper(); }
QList<dev::KeyPair> const& owned() const { return m_myKeys; }
@ -147,6 +147,8 @@ private slots:
void on_usePrivate_triggered();
void on_enableOptimizer_triggered();
void on_turboMining_triggered();
void on_go_triggered();
void on_importKeyFile_triggered();
signals:
void poll();
@ -182,6 +184,8 @@ private:
unsigned installWatch(dev::eth::MessageFilter const& _tf, std::function<void()> const& _f);
unsigned installWatch(dev::h256 _tf, std::function<void()> const& _f);
void keysChanged();
void onNewPending();
void onNewBlock();
void onNameRegChange();
@ -219,7 +223,6 @@ private:
QStringList m_servers;
QList<dev::KeyPair> m_myKeys;
QString m_privateChain;
bool m_keysChanged = false;
dev::bytes m_data;
dev::Address m_nameReg;
@ -244,4 +247,5 @@ private:
bool m_logChanged = true;
QEthereum* m_ethereum = nullptr;
QWhisper* m_whisper = nullptr;
};

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
namespace dev
{
char const* Version = "0.6.9";
char const* Version = "0.6.11";
}

10
libdevcore/RangeMask.h

@ -43,7 +43,7 @@ public:
using Range = std::pair<T, T>;
using Ranges = std::vector<Range>;
RangeMask() {}
RangeMask(): m_all(0, 0) {}
RangeMask(T _begin, T _end): m_all(_begin, _end) {}
RangeMask(Range const& _c): m_all(_c) {}
@ -150,7 +150,7 @@ public:
bool full() const
{
return m_ranges.size() == 1 && m_ranges.begin()->first == m_all.first && m_ranges.begin()->second == m_all.second;
return m_all.first == m_all.second || (m_ranges.size() == 1 && m_ranges.begin()->first == m_all.first && m_ranges.begin()->second == m_all.second);
}
void clear()
@ -158,6 +158,12 @@ public:
m_ranges.clear();
}
void reset()
{
m_ranges.clear();
m_all = std::make_pair(0, 0);
}
std::pair<T, T> const& all() const { return m_all; }
class const_iterator

6
libdevcrypto/Common.cpp

@ -102,3 +102,9 @@ KeyPair::KeyPair(h256 _sec):
cout << "ADR: " << m_address << endl;
#endif
}
KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password)
{
return KeyPair(sha3(aesDecrypt(_seed, _password)));
}

3
libdevcrypto/Common.h

@ -63,6 +63,9 @@ public:
/// Create a new, randomly generated object.
static KeyPair create();
/// Create from an encrypted seed.
static KeyPair fromEncryptedSeed(bytesConstRef _seed, std::string const& _password);
/// Retrieve the secret key.
Secret const& secret() const { return m_secret; }
/// Retrieve the secret key.

5
libdevcrypto/CryptoHeaders.h

@ -28,9 +28,14 @@
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
#pragma GCC diagnostic ignored "-Wunused-parameter"
#pragma GCC diagnostic ignored "-Wunused-variable"
#include <sha.h>
#include <sha3.h>
#include <ripemd.h>
#include <aes.h>
#include <pwdbased.h>
#include <modes.h>
#include <filters.h>
#include <secp256k1/secp256k1.h>
#pragma warning(pop)
#pragma GCC diagnostic pop

29
libdevcrypto/SHA3.cpp

@ -72,5 +72,34 @@ h256 sha3(bytesConstRef _input)
return ret;
}
bytes aesDecrypt(bytesConstRef _ivCipher, std::string const& _password, unsigned _rounds, bytesConstRef _salt)
{
bytes pw = asBytes(_password);
if (!_salt.size())
_salt = &pw;
bytes target(64);
CryptoPP::PKCS5_PBKDF2_HMAC<CryptoPP::SHA256>().DeriveKey(target.data(), target.size(), 0, pw.data(), pw.size(), _salt.data(), _salt.size(), _rounds);
try
{
CryptoPP::AES::Decryption aesDecryption(target.data(), 16);
auto cipher = _ivCipher.cropped(16);
auto iv = _ivCipher.cropped(0, 16);
CryptoPP::CBC_Mode_ExternalCipher::Decryption cbcDecryption(aesDecryption, iv.data());
std::string decrypted;
CryptoPP::StreamTransformationFilter stfDecryptor(cbcDecryption, new CryptoPP::StringSink(decrypted));
stfDecryptor.Put(cipher.data(), cipher.size());
stfDecryptor.MessageEnd();
return asBytes(decrypted);
}
catch (exception const& e)
{
cerr << e.what() << endl;
return bytes();
}
}
}
}

2
libdevcrypto/SHA3.h

@ -60,5 +60,7 @@ inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input))
extern h256 EmptySHA3;
bytes aesDecrypt(bytesConstRef _cipher, std::string const& _password, unsigned _rounds = 2000, bytesConstRef _salt = bytesConstRef());
}
}

2
libethcore/CommonEth.cpp

@ -35,7 +35,7 @@ namespace eth
{
const unsigned c_protocolVersion = 33;
const unsigned c_databaseVersion = 1;
const unsigned c_databaseVersion = 2;
static const vector<pair<u256, string>> g_units =
{

2
libethcore/Exceptions.h

@ -25,7 +25,7 @@ class InvalidBlockHeaderFormat: public dev::Exception { public: InvalidBlockHead
class InvalidUnclesHash: public dev::Exception {};
class InvalidUncle: public dev::Exception {};
class UncleTooOld: public dev::Exception {};
class UncleInChain: public dev::Exception {};
class UncleInChain: public dev::Exception { public: UncleInChain(h256Set _uncles, h256 _block): m_uncles(_uncles), m_block(_block) {} h256Set m_uncles; h256 m_block; virtual std::string description() const { return "Uncle in block already mentioned: Uncles " + toString(m_uncles) + " (" + m_block.abridged() + ")"; } };
class DuplicateUncleNonce: public dev::Exception {};
class InvalidStateRoot: public dev::Exception {};
class InvalidTransactionsHash: public dev::Exception { public: InvalidTransactionsHash(h256 _head, h256 _real): m_head(_head), m_real(_real) {} h256 m_head; h256 m_real; virtual std::string description() const { return "Invalid transactions hash: header says: " + toHex(m_head.ref()) + " block is:" + toHex(m_real.ref()); } };

12
libethereum/BlockChain.cpp

@ -276,7 +276,10 @@ h256s BlockChain::import(bytes const& _block, OverlayDB const& _db)
auto pd = details(bi.parentHash);
if (!pd)
{
cwarn << "Odd: details is returning false despite block known:" << RLP(pd.rlp());
cwarn << "Block:" << RLP(block(bi.parentHash));
}
// Check it's not crazy
if (bi.timestamp > (u256)time(0))
@ -479,13 +482,16 @@ bytes BlockChain::block(h256 _hash) const
string d;
m_db->Get(m_readOptions, ldb::Slice((char const*)&_hash, 32), &d);
if (!d.size())
{
cwarn << "Couldn't find requested block:" << _hash.abridged();
return bytes();
}
WriteGuard l(x_cache);
m_cache[_hash].resize(d.size());
memcpy(m_cache[_hash].data(), d.data(), d.size());
if (!d.size())
cwarn << "Couldn't find requested block:" << _hash.abridged();
return m_cache[_hash];
}

2
libethereum/DownloadMan.cpp

@ -50,7 +50,7 @@ h256Set DownloadSub::nextFetch(unsigned _n)
m_indices.clear();
m_remaining.clear();
if (!m_man)
if (!m_man || m_man->chain().empty())
return h256Set();
m_asked = (~(m_man->taken() + m_attempted)).lowest(_n);

27
libethereum/DownloadMan.h

@ -54,6 +54,7 @@ public:
/// Nothing doing here.
void doneFetch() { resetFetch(); }
bool askedContains(unsigned _i) const { Guard l(m_fetch); return m_asked.contains(_i); }
RangeMask<unsigned> const& asked() const { return m_asked; }
RangeMask<unsigned> const& attemped() const { return m_attempted; }
@ -63,13 +64,13 @@ private:
Guard l(m_fetch);
m_remaining.clear();
m_indices.clear();
m_asked.clear();
m_attempted.clear();
m_asked.reset();
m_attempted.reset();
}
DownloadMan* m_man = nullptr;
Mutex m_fetch;
mutable Mutex m_fetch;
h256Set m_remaining;
std::map<h256, unsigned> m_indices;
RangeMask<unsigned> m_asked;
@ -94,6 +95,7 @@ public:
for (auto i: m_subs)
i->resetFetch();
}
WriteGuard l(m_lock);
m_chain.clear();
m_chain.reserve(_chain.size());
for (auto i = _chain.rbegin(); i != _chain.rend(); ++i)
@ -101,8 +103,21 @@ public:
m_blocksGot = RangeMask<unsigned>(0, m_chain.size());
}
void reset()
{
{
ReadGuard l(x_subs);
for (auto i: m_subs)
i->resetFetch();
}
WriteGuard l(m_lock);
m_chain.clear();
m_blocksGot.reset();
}
RangeMask<unsigned> taken(bool _desperate = false) const
{
ReadGuard l(m_lock);
auto ret = m_blocksGot;
if (!_desperate)
{
@ -115,15 +130,17 @@ public:
bool isComplete() const
{
ReadGuard l(m_lock);
return m_blocksGot.full();
}
h256s chain() const { return m_chain; }
h256s chain() const { ReadGuard l(m_lock); return m_chain; }
void foreachSub(std::function<void(DownloadSub const&)> const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); }
unsigned subCount() const { ReadGuard l(x_subs); return m_subs.size(); }
RangeMask<unsigned> blocksGot() const { return m_blocksGot; }
RangeMask<unsigned> blocksGot() const { ReadGuard l(m_lock); return m_blocksGot; }
private:
mutable SharedMutex m_lock;
h256s m_chain;
RangeMask<unsigned> m_blocksGot;

27
libethereum/EthereumHost.cpp

@ -74,12 +74,19 @@ void EthereumHost::noteHavePeerState(EthereumPeer* _who)
{
clog(NetAllDetail) << "Have peer state.";
// TODO: FIX: BUG: Better state management!
// if already downloading hash-chain, ignore.
if (m_grabbing != Grabbing::Nothing)
{
clog(NetAllDetail) << "Already downloading chain. Just set to help out.";
_who->ensureGettingChain();
return;
for (auto const& i: peers())
if (i->cap<EthereumPeer>()->m_grabbing == m_grabbing || m_grabbing == Grabbing::State)
{
clog(NetAllDetail) << "Already downloading chain. Just set to help out.";
_who->ensureGettingChain();
return;
}
m_grabbing = Grabbing::Nothing;
}
// otherwise check to see if we should be downloading...
@ -102,7 +109,7 @@ void EthereumHost::noteHaveChain(EthereumPeer* _from)
if (_from->m_neededBlocks.empty())
{
_from->m_grabbing = Grabbing::Nothing;
_from->setGrabbing(Grabbing::Nothing);
updateGrabbing(Grabbing::Nothing);
return;
}
@ -112,7 +119,7 @@ void EthereumHost::noteHaveChain(EthereumPeer* _from)
if (td < m_chain.details().totalDifficulty || (td == m_chain.details().totalDifficulty && m_chain.currentHash() == _from->m_latestHash))
{
clog(NetNote) << "Difficulty of hashchain not HIGHER. Ignoring.";
_from->m_grabbing = Grabbing::Nothing;
_from->setGrabbing(Grabbing::Nothing);
updateGrabbing(Grabbing::Nothing);
return;
}
@ -123,7 +130,7 @@ void EthereumHost::noteHaveChain(EthereumPeer* _from)
m_man.resetToChain(_from->m_neededBlocks);
m_latestBlockSent = _from->m_latestHash;
_from->m_grabbing = Grabbing::Chain;
_from->setGrabbing(Grabbing::Chain);
updateGrabbing(Grabbing::Chain);
}
@ -149,6 +156,7 @@ void EthereumHost::noteDoneBlocks(EthereumPeer* _who)
// Done our chain-get.
clog(NetNote) << "Chain download complete.";
updateGrabbing(Grabbing::Nothing);
m_man.reset();
}
if (_who->m_grabbing == Grabbing::Chain)
{
@ -156,6 +164,7 @@ void EthereumHost::noteDoneBlocks(EthereumPeer* _who)
clog(NetNote) << "Chain download failed. Peer with blocks didn't have them all. This peer is bad and should be punished.";
// TODO: note that peer is BADBADBAD!
updateGrabbing(Grabbing::Nothing);
m_man.reset();
}
}
@ -263,6 +272,12 @@ void EthereumHost::maintainBlocks(BlockQueue& _bq, h256 _currentHash)
++c;
}
clog(NetMessageSummary) << "Sending" << c << "new blocks (current is" << _currentHash << ", was" << m_latestBlockSent << ")";
if (c > 1000)
{
cwarn << "Gaa this would be an awful lot of new blocks. Not bothering";
return;
}
ts.appendList(1 + c).append(BlocksPacket).appendRaw(bs, c);
bytes b;
ts.swapOut(b);

53
libethereum/EthereumPeer.cpp

@ -38,6 +38,7 @@ EthereumPeer::EthereumPeer(Session* _s, HostCapabilityFace* _h):
Capability(_s, _h),
m_sub(host()->m_man)
{
setGrabbing(Grabbing::State);
sendStatus();
}
@ -94,7 +95,7 @@ void EthereumPeer::tryGrabbingHashChain()
if (td >= m_totalDifficulty)
{
clogS(NetAllDetail) << "No. Our chain is better.";
m_grabbing = Grabbing::Nothing;
setGrabbing(Grabbing::Nothing);
return; // All good - we have the better chain.
}
@ -103,7 +104,7 @@ void EthereumPeer::tryGrabbingHashChain()
clogS(NetAllDetail) << "Yes. Their chain is better.";
host()->updateGrabbing(Grabbing::Hashes);
m_grabbing = Grabbing::Hashes;
setGrabbing(Grabbing::Hashes);
RLPStream s;
prep(s).appendList(3);
s << GetBlockHashesPacket << m_latestHash << c_maxHashesAsk;
@ -114,17 +115,17 @@ void EthereumPeer::tryGrabbingHashChain()
void EthereumPeer::giveUpOnFetch()
{
clogS(NetNote) << "GIVE UP FETCH";
clogS(NetNote) << "Finishing fetch...";
// a bit overkill given that the other nodes may yet have the needed blocks, but better to be safe than sorry.
if (m_grabbing == Grabbing::Chain || m_grabbing == Grabbing::ChainHelper)
{
host()->noteDoneBlocks(this);
m_grabbing = Grabbing::Nothing;
setGrabbing(Grabbing::Nothing);
}
m_sub.doneFetch();
// NOTE: need to notify of giving up on chain-hashes, too, altering state as necessary.
m_sub.doneFetch();
}
bool EthereumPeer::interpret(RLP const& _r)
@ -143,12 +144,14 @@ bool EthereumPeer::interpret(RLP const& _r)
if (genesisHash != host()->m_chain.genesisHash())
disable("Invalid genesis hash");
if (m_protocolVersion != host()->protocolVersion())
else if (m_protocolVersion != host()->protocolVersion())
disable("Invalid protocol version.");
if (m_networkId != host()->networkId())
else if (m_networkId != host()->networkId())
disable("Invalid network identifier.");
startInitialSync();
else if (session()->info().clientVersion.find("/v0.6.9/") != string::npos)
disable("Blacklisted client version.");
else
startInitialSync();
break;
}
case GetTransactionsPacket:
@ -176,12 +179,12 @@ bool EthereumPeer::interpret(RLP const& _r)
unsigned limit = _r[2].toInt<unsigned>();
clogS(NetMessageSummary) << "GetBlockHashes (" << limit << "entries," << later.abridged() << ")";
unsigned c = min<unsigned>(max<unsigned>(1, host()->m_chain.number(later)) - 1, limit);
unsigned c = min<unsigned>(host()->m_chain.number(later), limit);
RLPStream s;
prep(s).appendList(1 + c).append(BlockHashesPacket);
h256 p = host()->m_chain.details(later).parent;
for (unsigned i = 0; i < c; ++i, p = host()->m_chain.details(p).parent)
for (unsigned i = 0; i < c && p; ++i, p = host()->m_chain.details(p).parent)
s << p;
sealAndSend(s);
break;
@ -203,7 +206,7 @@ bool EthereumPeer::interpret(RLP const& _r)
for (unsigned i = 1; i < _r.itemCount(); ++i)
{
auto h = _r[i].toHash<h256>();
if (host()->m_chain.details(h))
if (host()->m_chain.isKnown(h))
{
host()->noteHaveChain(this);
return true;
@ -244,8 +247,9 @@ bool EthereumPeer::interpret(RLP const& _r)
if (_r.itemCount() == 1)
{
// Couldn't get any from last batch - probably got to this peer's latest block - just give up.
m_sub.doneFetch();
giveUpOnFetch();
if (m_grabbing == Grabbing::Chain || m_grabbing == Grabbing::ChainHelper)
giveUpOnFetch();
break;
}
unsigned used = 0;
@ -263,7 +267,8 @@ bool EthereumPeer::interpret(RLP const& _r)
unsigned unknownParents = 0;
if (g_logVerbosity >= NetMessageSummary::verbosity)
{
for (unsigned i = 1; i < _r.itemCount(); ++i)
unsigned ic = _r.itemCount();
for (unsigned i = 1; i < ic; ++i)
{
auto h = BlockInfo::headerHash(_r[i].data());
BlockInfo bi(_r[i].data());
@ -281,7 +286,8 @@ bool EthereumPeer::interpret(RLP const& _r)
}
}
clogS(NetMessageSummary) << dec << knownParents << "known parents," << unknownParents << "unknown," << used << "used.";
continueGettingChain();
if (m_grabbing == Grabbing::Chain || m_grabbing == Grabbing::ChainHelper)
continueGettingChain();
break;
}
default:
@ -295,13 +301,18 @@ void EthereumPeer::ensureGettingChain()
if (m_grabbing == Grabbing::ChainHelper)
return; // Already asked & waiting for some.
// Switch to ChainHelper otherwise, unless we're already the Chain grabber.
if (m_grabbing != Grabbing::Chain)
setGrabbing(Grabbing::ChainHelper);
continueGettingChain();
}
void EthereumPeer::continueGettingChain()
{
if (m_grabbing != Grabbing::Chain)
m_grabbing = Grabbing::ChainHelper;
// If we're getting the hashes already, then we shouldn't be asking for the chain.
if (m_grabbing == Grabbing::Hashes)
return;
auto blocks = m_sub.nextFetch(c_maxBlocksAsk);
@ -317,3 +328,9 @@ void EthereumPeer::continueGettingChain()
else
giveUpOnFetch();
}
void EthereumPeer::setGrabbing(Grabbing _g)
{
m_grabbing = _g;
session()->addNote("grab", _g == Grabbing::Nothing ? "nothing" : _g == Grabbing::State ? "state" : _g == Grabbing::Hashes ? "hashes" : _g == Grabbing::Chain ? "chain" : _g == Grabbing::ChainHelper ? "chainhelper" : "?");
}

3
libethereum/EthereumPeer.h

@ -71,11 +71,12 @@ private:
void giveUpOnFetch();
void clearKnownTransactions() { std::lock_guard<std::mutex> l(x_knownTransactions); m_knownTransactions.clear(); }
void setGrabbing(Grabbing _g);
unsigned m_protocolVersion;
u256 m_networkId;
Grabbing m_grabbing = Grabbing::State;
Grabbing m_grabbing;
h256 m_latestHash; ///< Peer's latest block's hash.
u256 m_totalDifficulty; ///< Peer's latest block's total difficulty.

4
libethereum/Executive.cpp

@ -131,11 +131,9 @@ bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _g
// We can allow for the reverted state (i.e. that with which m_ext is constructed) to contain the m_newAddress, since
// we delete it explicitly if we decide we need to revert.
m_newAddress = right160(sha3(rlpList(_sender, m_s.transactionsFrom(_sender) - 1)));
while (m_s.addressInUse(m_newAddress))
m_newAddress = (u160)m_newAddress + 1;
// Set up new account...
m_s.m_cache[m_newAddress] = AddressState(0, _endowment, h256(), h256());
m_s.m_cache[m_newAddress] = AddressState(0, m_s.balance(m_newAddress) + _endowment, h256(), h256());
// Execute _init.
m_vm = new VM(_gas);

11
libethereum/State.cpp

@ -577,6 +577,9 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
set<h256> knownUncles = _bc ? _bc->allUnclesFrom(m_currentBlock.parentHash) : set<h256>();
for (auto const& i: RLP(_block)[2])
{
if (knownUncles.count(sha3(i.data())))
throw UncleInChain(knownUncles, sha3(i.data()));
BlockInfo uncle = BlockInfo::fromHeader(i.data());
if (nonces.count(uncle.nonce))
throw DuplicateUncleNonce();
@ -585,8 +588,6 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
BlockInfo uncleParent(_bc->block(uncle.parentHash));
if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 6)
throw UncleTooOld();
if (knownUncles.count(sha3(i.data())))
throw UncleInChain();
uncle.verifyParent(uncleParent);
}
@ -725,7 +726,7 @@ void State::commitToMine(BlockChain const& _bc)
auto us = _bc.details(p).children;
assert(us.size() >= 1); // must be at least 1 child of our grandparent - it's our own parent!
for (auto const& u: us)
if (!knownUncles.count(BlockInfo::headerHash(_bc.block(u)))) // ignore any uncles/mainline blocks that we know about. We use header-hash for this.
if (!knownUncles.count(u)) // ignore any uncles/mainline blocks that we know about.
{
BlockInfo ubi(_bc.block(u));
ubi.fillStream(unclesData, true);
@ -965,7 +966,7 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const
RLP r(i.second);
TrieDB<h256, OverlayDB> storageDB(const_cast<OverlayDB*>(&m_db), r[2].toHash<h256>()); // promise not to alter OverlayDB.
for (auto const& j: storageDB) { (void)j; }
if (!e && r[3].toHash<h256>() != EmptySHA3 && m_db.lookup(r[3].toHash<h256>()).empty())
if (!e && r[3].toHash<h256>() && m_db.lookup(r[3].toHash<h256>()).empty())
return false;
}
}
@ -1132,7 +1133,7 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas,
newAddress = (u160)newAddress + 1;
// Set up new account...
m_cache[newAddress] = AddressState(0, _endowment, h256(), h256());
m_cache[newAddress] = AddressState(0, balance(newAddress) + _endowment, h256(), h256());
// Execute init code.
VM vm(*_gas);

2
libevm/VM.h

@ -634,7 +634,7 @@ template <class Ext> dev::bytesConstRef dev::eth::VM::go(Ext& _ext, OnOpFunc con
if (_ext.balance(_ext.myAddress) >= value)
{
_ext.subBalance(value);
m_stack.push_back(_ext.call(receiveAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), &gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, Address(), inst == Instruction::CALL ? receiveAddress : _ext.myAddress));
m_stack.push_back(_ext.call(inst == Instruction::CALL ? receiveAddress : _ext.myAddress, value, bytesConstRef(m_temp.data() + inOff, inSize), &gas, bytesRef(m_temp.data() + outOff, outSize), _onOp, Address(), receiveAddress));
}
else
m_stack.push_back(0);

2
libp2p/Common.h

@ -95,6 +95,8 @@ struct PeerInfo
unsigned short port;
std::chrono::steady_clock::duration lastPing;
std::set<std::string> caps;
unsigned socket;
std::map<std::string, std::string> notes;
};
}

4
libp2p/Session.cpp

@ -40,7 +40,7 @@ Session::Session(Host* _s, bi::tcp::socket _socket, bi::address _peerAddress, un
{
m_disconnect = std::chrono::steady_clock::time_point::max();
m_connect = std::chrono::steady_clock::now();
m_info = PeerInfo({"?", _peerAddress.to_string(), m_listenPort, std::chrono::steady_clock::duration(0)});
m_info = PeerInfo({"?", _peerAddress.to_string(), m_listenPort, std::chrono::steady_clock::duration(0), set<string>(), 0, map<string, string>()});
}
Session::~Session()
@ -102,7 +102,7 @@ bool Session::interpret(RLP const& _r)
return false;
}
try
{ m_info = PeerInfo({clientVersion, m_socket.remote_endpoint().address().to_string(), m_listenPort, std::chrono::steady_clock::duration(), _r[3].toSet<string>()}); }
{ m_info = PeerInfo({clientVersion, m_socket.remote_endpoint().address().to_string(), m_listenPort, std::chrono::steady_clock::duration(), _r[3].toSet<string>(), (unsigned)m_socket.native_handle(), map<string, string>() }); }
catch (...)
{
disconnect(BadProtocol);

4
libp2p/Session.h

@ -71,6 +71,10 @@ public:
void addRating(unsigned _r) { m_rating += _r; }
void addNote(std::string const& _k, std::string const& _v) { m_info.notes[_k] = _v; }
PeerInfo const& info() const { return m_info; }
private:
void dropped();
void doRead();

59
libqethereum/QEthereum.cpp

@ -476,6 +476,65 @@ void QEthereum::poll()
emit watchChanged(w);
}
// TODO: repot and hook all these up.
QWhisper::QWhisper(QObject* _p, std::shared_ptr<dev::shh::Interface> const& _c): QObject(_p), m_face(_c)
{
}
QWhisper::~QWhisper()
{
}
// probably want a better way of doing this. somehow guarantee that the face() will always be available as long as this object is.
struct NoInterface: public Exception {};
std::shared_ptr<dev::shh::Interface> QWhisper::face() const
{
auto ret = m_face.lock();
if (!ret)
throw NoInterface();
return ret;
}
void QWhisper::faceDieing()
{
}
void QWhisper::send(QString /*dev::Address*/ _dest, QString /*ev::KeyPair*/ _from, QString /*dev::h256 const&*/ _topic, QString /*dev::bytes const&*/ _payload)
{
(void)_dest;
(void)_from;
(void)_topic;
(void)_payload;
}
unsigned QWhisper::newWatch(QString _json)
{
(void)_json;
return 0;
}
QString QWhisper::watchMessages(unsigned _w)
{
(void)_w;
return "";
}
void QWhisper::killWatch(unsigned _w)
{
(void)_w;
}
void QWhisper::clearWatches()
{
}
void QWhisper::poll()
{
}
// extra bits needed to link on VS
#ifdef _MSC_VER

55
libqethereum/QEthereum.h

@ -6,9 +6,14 @@
#include <libdevcore/CommonIO.h>
#include <libethcore/CommonEth.h>
namespace dev { namespace eth {
namespace dev {
namespace eth {
class Interface;
}}
}
namespace shh {
class Interface;
}
}
class QJSEngine;
class QWebFrame;
@ -203,11 +208,51 @@ private:
QList<dev::KeyPair> m_accounts;
};
#define QETH_INSTALL_JS_NAMESPACE(frame, eth, env) [frame, eth, env]() \
class QWhisper: public QObject
{
Q_OBJECT
public:
QWhisper(QObject* _p, std::shared_ptr<dev::shh::Interface> const& _c);
virtual ~QWhisper();
std::shared_ptr<dev::shh::Interface> face() const;
void setFace(std::shared_ptr<dev::shh::Interface> const& _c) { m_face = _c; }
/// Call when the face() is going to be deleted to make this object useless but safe.
void faceDieing();
Q_INVOKABLE QWhisper* self() { return this; }
/// Basic message send.
Q_INVOKABLE void send(QString /*dev::Address*/ _dest, QString /*ev::KeyPair*/ _from, QString /*dev::h256 const&*/ _topic, QString /*dev::bytes const&*/ _payload);
// Watches interface
Q_INVOKABLE unsigned newWatch(QString _json);
Q_INVOKABLE QString watchMessages(unsigned _w);
Q_INVOKABLE void killWatch(unsigned _w);
void clearWatches();
public slots:
/// Check to see if anything has changed, fire off signals if so.
/// @note Must be called in the QObject's thread.
void poll();
signals:
void watchChanged(unsigned _w);
private:
std::weak_ptr<dev::shh::Interface> m_face;
std::vector<unsigned> m_watches;
};
#define QETH_INSTALL_JS_NAMESPACE(frame, eth, shh, env) [frame, eth, shh, env]() \
{ \
frame->disconnect(); \
frame->addToJavaScriptWindowObject("env", env, QWebFrame::QtOwnership); \
frame->addToJavaScriptWindowObject("eth", eth, QWebFrame::ScriptOwnership); \
frame->addToJavaScriptWindowObject("shh", eth, QWebFrame::ScriptOwnership); \
frame->evaluateJavaScript("eth.makeWatch = function(a) { var ww = eth.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { eth.killWatch(w); }; ret.changed = function(f) { eth.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(eth.watchMessages(this.w)) }; return ret; }"); \
frame->evaluateJavaScript("eth.watch = function(a) { return eth.makeWatch(JSON.stringify(a)) }"); \
frame->evaluateJavaScript("eth.watchChain = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.watch('chain') INSTEAD.'); return eth.makeWatch('chain') }"); \
@ -224,8 +269,8 @@ private:
frame->evaluateJavaScript("String.prototype.dec = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.toDecimal(this) }"); \
frame->evaluateJavaScript("String.prototype.fix = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.toFixed(this) }"); \
frame->evaluateJavaScript("String.prototype.sha3 = function() { env.warn('THIS CALL IS DEPRECATED. USE eth.* INSTEAD.'); return eth.sha3old(this) }"); \
frame->evaluateJavaScript("console.log = env.note"); \
frame->evaluateJavaScript("window.onerror = function (errorMsg, url, lineNumber, column, errorObj) { env.warn('Error: ' + errorMsg + ', Script: ' + url + ', Line: ' + lineNumber + ', Column: ' + column + ', StackTrace: ' + String(errorObj)) }"); \
frame->evaluateJavaScript("shh.makeWatch = function(a) { var ww = shh.newWatch(a); var ret = { w: ww }; ret.uninstall = function() { shh.killWatch(w); }; ret.changed = function(f) { shh.watchChanged.connect(function(nw) { if (nw == ww) f() }); }; ret.messages = function() { return JSON.parse(shh.watchMessages(this.w)) }; return ret; }"); \
frame->evaluateJavaScript("shh.watch = function(a) { return shh.makeWatch(JSON.stringify(a)) }"); \
}
template <unsigned N> inline boost::multiprecision::number<boost::multiprecision::cpp_int_backend<N * 8, N * 8, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>> toInt(QString const& _s)

6
libwebthree/WebThree.cpp

@ -28,7 +28,7 @@
#include <libp2p/Host.h>
#include <libethereum/Defaults.h>
#include <libethereum/EthereumHost.h>
#include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h>
using namespace std;
using namespace dev;
using namespace dev::p2p;
@ -45,8 +45,8 @@ WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string co
if (_interfaces.count("eth"))
m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean));
// if (_interfaces.count("shh"))
// m_whisper = new eth::Whisper(m_net.get());
if (_interfaces.count("shh"))
m_whisper = m_net.registerCapability<WhisperHost>(new WhisperHost);
}
WebThreeDirect::~WebThreeDirect()

6
libwebthree/WebThree.h

@ -32,7 +32,7 @@
#include <libdevcore/Exceptions.h>
#include <libp2p/Host.h>
#include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h>
#include <libethereum/Client.h>
namespace dev
@ -74,7 +74,7 @@ public:
// The mainline interfaces:
eth::Client* ethereum() const { if (!m_ethereum) throw InterfaceNotSupported("eth"); return m_ethereum.get(); }
shh::WhisperHost* whisper() const { if (!m_whisper) throw InterfaceNotSupported("shh"); return m_whisper.get(); }
std::shared_ptr<shh::WhisperHost> whisper() const { auto w = m_whisper.lock(); if (!w) throw InterfaceNotSupported("shh"); return w; }
bzz::Interface* swarm() const { throw InterfaceNotSupported("bzz"); }
// Misc stuff:
@ -118,7 +118,7 @@ private:
std::string m_clientVersion; ///< Our end-application client's name/version.
std::unique_ptr<eth::Client> m_ethereum; ///< Main interface for Ethereum ("eth") protocol.
std::unique_ptr<shh::WhisperHost> m_whisper; ///< Main interface for Whisper ("shh") protocol.
std::weak_ptr<shh::WhisperHost> m_whisper; ///< Main interface for Whisper ("shh") protocol.
p2p::Host m_net; ///< Should run in background and send us events when blocks found and allow us to send blocks as required.
};

47
libwhisper/Interface.cpp

@ -0,0 +1,47 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Interface.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Interface.h"
#include <libdevcore/Log.h>
#include <libp2p/All.h>
#include "WhisperHost.h"
using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
bool MessageFilter::matches(Message const& _m) const
{
for (auto const& t: m_topicMasks)
{
if (t.first.size() != t.second.size() || _m.topic.size() < t.first.size())
continue;
for (unsigned i = 0; i < t.first.size(); ++i)
if (((t.first[i] ^ _m.topic[i]) & t.second[i]) != 0)
goto NEXT;
return true;
NEXT:;
}
return false;
}

132
libwhisper/Interface.h

@ -0,0 +1,132 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file WhisperHost.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <mutex>
#include <array>
#include <set>
#include <memory>
#include <utility>
#include <libdevcore/RLP.h>
#include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h>
#include "Common.h"
#include "Message.h"
namespace dev
{
namespace shh
{
class MessageFilter
{
public:
MessageFilter() {}
MessageFilter(std::vector<std::pair<bytes, bytes> > const& _m): m_topicMasks(_m) {}
MessageFilter(RLP const& _r): m_topicMasks((std::vector<std::pair<bytes, bytes>>)_r) {}
void fillStream(RLPStream& _s) const { _s << m_topicMasks; }
h256 sha3() const { RLPStream s; fillStream(s); return dev::eth::sha3(s.out()); }
bool matches(Message const& _m) const;
private:
std::vector<std::pair<bytes, bytes> > m_topicMasks;
};
struct InstalledFilter
{
InstalledFilter(MessageFilter const& _f): filter(_f) {}
MessageFilter filter;
unsigned refCount = 1;
};
struct ClientWatch
{
ClientWatch() {}
explicit ClientWatch(h256 _id): id(_id) {}
h256 id;
h256s changes;
};
class Interface
{
public:
virtual ~Interface() {}
virtual void inject(Message const& _m, WhisperPeer* _from = nullptr) = 0;
virtual unsigned installWatch(MessageFilter const& _filter) = 0;
virtual unsigned installWatch(h256 _filterId) = 0;
virtual void uninstallWatch(unsigned _watchId) = 0;
virtual h256s peekWatch(unsigned _watchId) const = 0;
virtual h256s checkWatch(unsigned _watchId) = 0;
virtual Message message(h256 _m) const = 0;
virtual void sendRaw(bytes const& _payload, bytes const& _topic, unsigned _ttl) = 0;
};
struct WatshhChannel: public dev::LogChannel { static const char* name() { return "shh"; } static const int verbosity = 1; };
#define cwatshh dev::LogOutputStream<shh::WatshhChannel, true>()
}
}
/*
namespace std { void swap(shh::Watch& _a, shh::Watch& _b); }
namespace shh
{
class Watch: public boost::noncopyable
{
friend void std::swap(Watch& _a, Watch& _b);
public:
Watch() {}
Watch(Whisper& _c, h256 _f): m_c(&_c), m_id(_c.installWatch(_f)) {}
Watch(Whisper& _c, MessageFilter const& _tf): m_c(&_c), m_id(_c.installWatch(_tf)) {}
~Watch() { if (m_c) m_c->uninstallWatch(m_id); }
bool check() { return m_c ? m_c->checkWatch(m_id) : false; }
bool peek() { return m_c ? m_c->peekWatch(m_id) : false; }
private:
Whisper* m_c;
unsigned m_id;
};
}
namespace shh
{
inline void swap(shh::Watch& _a, shh::Watch& _b)
{
swap(_a.m_c, _b.m_c);
swap(_a.m_id, _b.m_id);
}
}
*/

28
libwhisper/Message.cpp

@ -0,0 +1,28 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Message.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Message.h"
using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "

63
libwhisper/Message.h

@ -0,0 +1,63 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Message.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <mutex>
#include <array>
#include <set>
#include <memory>
#include <utility>
#include <libdevcore/RLP.h>
#include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h>
#include "Common.h"
namespace dev
{
namespace shh
{
struct Message
{
unsigned expiry = 0;
unsigned ttl = 0;
bytes topic; // TODO: change to h256
bytes payload;
Message() {}
Message(unsigned _exp, unsigned _ttl, bytes const& _topic, bytes const& _payload): expiry(_exp), ttl(_ttl), topic(_topic), payload(_payload) {}
Message(RLP const& _m)
{
expiry = _m[0].toInt<unsigned>();
ttl = _m[1].toInt<unsigned>();
topic = _m[2].toBytes();
payload = _m[3].toBytes();
}
operator bool () const { return !!expiry; }
void streamOut(RLPStream& _s) const { _s.appendList(4) << expiry << ttl << topic << payload; }
h256 sha3() const { RLPStream s; streamOut(s); return dev::eth::sha3(s.out()); }
};
}
}

123
libwhisper/WhisperHost.cpp

@ -0,0 +1,123 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file WhisperHost.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "WhisperHost.h"
#include <libdevcore/Log.h>
#include <libp2p/All.h>
using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
WhisperHost::WhisperHost()
{
}
WhisperHost::~WhisperHost()
{
}
void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const
{
UpgradableGuard l(x_messages);
if (m_messages.count(_m))
{
UpgradeGuard ll(l);
m_messages.at(_m).streamOut(_s);
}
}
void WhisperHost::inject(Message const& _m, WhisperPeer* _p)
{
auto h = _m.sha3();
{
UpgradableGuard l(x_messages);
if (m_messages.count(h))
return;
UpgradeGuard ll(l);
m_messages[h] = _m;
}
if (_p)
{
Guard l(m_filterLock);
for (auto const& f: m_filters)
if (f.second.filter.matches(_m))
noteChanged(h, f.first);
}
for (auto& i: peers())
if (i->cap<WhisperPeer>().get() == _p)
i->addRating(1);
else
i->cap<WhisperPeer>()->noteNewMessage(h, _m);
}
void WhisperHost::noteChanged(h256 _messageHash, h256 _filter)
{
for (auto& i: m_watches)
if (i.second.id == _filter)
{
cwatshh << "!!!" << i.first << i.second.id;
i.second.changes.push_back(_messageHash);
}
}
unsigned WhisperHost::installWatch(h256 _h)
{
auto ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0;
m_watches[ret] = ClientWatch(_h);
cwatshh << "+++" << ret << _h;
return ret;
}
unsigned WhisperHost::installWatch(shh::MessageFilter const& _f)
{
Guard l(m_filterLock);
h256 h = _f.sha3();
if (!m_filters.count(h))
m_filters.insert(make_pair(h, _f));
return installWatch(h);
}
void WhisperHost::uninstallWatch(unsigned _i)
{
cwatshh << "XXX" << _i;
Guard l(m_filterLock);
auto it = m_watches.find(_i);
if (it == m_watches.end())
return;
auto id = it->second.id;
m_watches.erase(it);
auto fit = m_filters.find(id);
if (fit != m_filters.end())
if (!--fit->second.refCount)
m_filters.erase(fit);
}

77
libwhisper/WhisperHost.h

@ -0,0 +1,77 @@
/*
This file is part of cpp-ethereum.
cpp-ethereum is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
cpp-ethereum is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file WhisperHost.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#pragma once
#include <mutex>
#include <array>
#include <set>
#include <memory>
#include <utility>
#include <libdevcore/RLP.h>
#include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h>
#include "Common.h"
#include "WhisperPeer.h"
#include "Interface.h"
namespace dev
{
namespace shh
{
class WhisperHost: public HostCapability<WhisperPeer>, public Interface
{
friend class WhisperPeer;
public:
WhisperHost();
virtual ~WhisperHost();
unsigned protocolVersion() const { return 0; }
virtual void inject(Message const& _m, WhisperPeer* _from = nullptr);
virtual unsigned installWatch(MessageFilter const& _filter);
virtual unsigned installWatch(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; }
virtual Message message(h256 _m) const { try { dev::ReadGuard l(x_messages); return m_messages.at(_m); } catch (...) { return Message(); } }
virtual void sendRaw(bytes const& _payload, bytes const& _topic, unsigned _ttl) { inject(Message(time(0) + _ttl, _ttl, _topic, _payload)); }
private:
void streamMessage(h256 _m, RLPStream& _s) const;
void noteChanged(h256 _messageHash, h256 _filter);
mutable dev::SharedMutex x_messages;
std::map<h256, Message> m_messages;
mutable dev::Mutex m_filterLock;
std::map<h256, InstalledFilter> m_filters;
std::map<unsigned, ClientWatch> m_watches;
};
}
}

129
libwhisper/WhisperPeer.cpp

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Whisper.cpp
/** @file WhisperPeer.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
@ -23,11 +23,11 @@
#include <libdevcore/Log.h>
#include <libp2p/All.h>
#include "WhisperHost.h"
using namespace std;
using namespace dev;
using namespace dev::p2p;
using namespace dev::shh;
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
WhisperPeer::WhisperPeer(Session* _s, HostCapabilityFace* _h): Capability(_s, _h)
@ -92,15 +92,17 @@ void WhisperPeer::sendMessages()
n++;
}
// pause before sending if no messages to send
if (!n)
if (n)
{
RLPStream s;
prep(s);
s.appendList(n + 1) << MessagesPacket;
s.appendRaw(amalg.out(), n);
sealAndSend(s);
}
else
// just pause if no messages to send
this_thread::sleep_for(chrono::milliseconds(100));
RLPStream s;
prep(s);
s.appendList(n + 1) << MessagesPacket;
s.appendRaw(amalg.out(), n);
sealAndSend(s);
}
void WhisperPeer::noteNewMessage(h256 _h, Message const& _m)
@ -108,110 +110,3 @@ void WhisperPeer::noteNewMessage(h256 _h, Message const& _m)
Guard l(x_unseen);
m_unseen[rating(_m)] = _h;
}
WhisperHost::WhisperHost()
{
}
WhisperHost::~WhisperHost()
{
}
void WhisperHost::streamMessage(h256 _m, RLPStream& _s) const
{
UpgradableGuard l(x_messages);
if (m_messages.count(_m))
{
UpgradeGuard ll(l);
m_messages.at(_m).streamOut(_s);
}
}
void WhisperHost::inject(Message const& _m, WhisperPeer* _p)
{
auto h = _m.sha3();
{
UpgradableGuard l(x_messages);
if (m_messages.count(h))
return;
UpgradeGuard ll(l);
m_messages[h] = _m;
}
if (_p)
{
Guard l(m_filterLock);
for (auto const& f: m_filters)
if (f.second.filter.matches(_m))
noteChanged(h, f.first);
}
for (auto& i: peers())
if (i->cap<WhisperPeer>().get() == _p)
i->addRating(1);
else
i->cap<WhisperPeer>()->noteNewMessage(h, _m);
}
void WhisperHost::noteChanged(h256 _messageHash, h256 _filter)
{
for (auto& i: m_watches)
if (i.second.id == _filter)
{
cwatshh << "!!!" << i.first << i.second.id;
i.second.changes.push_back(_messageHash);
}
}
bool MessageFilter::matches(Message const& _m) const
{
for (auto const& t: m_topicMasks)
{
if (t.first.size() != t.second.size() || _m.topic.size() < t.first.size())
continue;
for (unsigned i = 0; i < t.first.size(); ++i)
if (((t.first[i] ^ _m.topic[i]) & t.second[i]) != 0)
goto NEXT;
return true;
NEXT:;
}
return false;
}
unsigned WhisperHost::installWatch(h256 _h)
{
auto ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0;
m_watches[ret] = ClientWatch(_h);
cwatshh << "+++" << ret << _h;
return ret;
}
unsigned WhisperHost::installWatch(shh::MessageFilter const& _f)
{
Guard l(m_filterLock);
h256 h = _f.sha3();
if (!m_filters.count(h))
m_filters.insert(make_pair(h, _f));
return installWatch(h);
}
void WhisperHost::uninstallWatch(unsigned _i)
{
cwatshh << "XXX" << _i;
Guard l(m_filterLock);
auto it = m_watches.find(_i);
if (it == m_watches.end())
return;
auto id = it->second.id;
m_watches.erase(it);
auto fit = m_filters.find(id);
if (fit != m_filters.end())
if (!--fit->second.refCount)
m_filters.erase(fit);
}

154
libwhisper/WhisperPeer.h

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/
/** @file Whisper.h
/** @file WhisperPeer.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
@ -30,6 +30,7 @@
#include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h>
#include "Common.h"
#include "Message.h"
namespace dev
{
@ -41,29 +42,6 @@ using p2p::HostCapabilityFace;
using p2p::HostCapability;
using p2p::Capability;
struct Message
{
unsigned expiry = 0;
unsigned ttl = 0;
bytes topic;
bytes payload;
Message() {}
Message(unsigned _exp, unsigned _ttl, bytes const& _topic, bytes const& _payload): expiry(_exp), ttl(_ttl), topic(_topic), payload(_payload) {}
Message(RLP const& _m)
{
expiry = _m[0].toInt<unsigned>();
ttl = _m[1].toInt<unsigned>();
topic = _m[2].toBytes();
payload = _m[3].toBytes();
}
operator bool () const { return !!expiry; }
void streamOut(RLPStream& _s) const { _s.appendList(4) << expiry << ttl << topic << payload; }
h256 sha3() const { RLPStream s; streamOut(s); return dev::eth::sha3(s.out()); }
};
/**
*/
class WhisperPeer: public Capability
@ -90,133 +68,5 @@ private:
std::map<unsigned, h256> m_unseen; ///< Rated according to what they want.
};
class MessageFilter
{
public:
MessageFilter() {}
MessageFilter(std::vector<std::pair<bytes, bytes> > const& _m): m_topicMasks(_m) {}
MessageFilter(RLP const& _r): m_topicMasks((std::vector<std::pair<bytes, bytes>>)_r) {}
void fillStream(RLPStream& _s) const { _s << m_topicMasks; }
h256 sha3() const { RLPStream s; fillStream(s); return dev::eth::sha3(s.out()); }
bool matches(Message const& _m) const;
private:
std::vector<std::pair<bytes, bytes> > m_topicMasks;
};
struct InstalledFilter
{
InstalledFilter(MessageFilter const& _f): filter(_f) {}
MessageFilter filter;
unsigned refCount = 1;
};
struct ClientWatch
{
ClientWatch() {}
explicit ClientWatch(h256 _id): id(_id) {}
h256 id;
h256s changes;
};
class Interface
{
public:
virtual ~Interface() {}
virtual void inject(Message const& _m, WhisperPeer* _from = nullptr) = 0;
virtual unsigned installWatch(MessageFilter const& _filter) = 0;
virtual unsigned installWatch(h256 _filterId) = 0;
virtual void uninstallWatch(unsigned _watchId) = 0;
virtual h256s peekWatch(unsigned _watchId) const = 0;
virtual h256s checkWatch(unsigned _watchId) = 0;
virtual Message message(h256 _m) const = 0;
virtual void sendRaw(bytes const& _payload, bytes const& _topic, unsigned _ttl) = 0;
};
class WhisperHost: public HostCapability<WhisperPeer>, public Interface
{
friend class WhisperPeer;
public:
WhisperHost();
virtual ~WhisperHost();
unsigned protocolVersion() const { return 0; }
void inject(Message const& _m, WhisperPeer* _from = nullptr);
unsigned installWatch(MessageFilter const& _filter);
unsigned installWatch(h256 _filterId);
void uninstallWatch(unsigned _watchId);
h256s peekWatch(unsigned _watchId) const { dev::Guard l(m_filterLock); try { return m_watches.at(_watchId).changes; } catch (...) { return h256s(); } }
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; }
Message message(h256 _m) const { try { dev::ReadGuard l(x_messages); return m_messages.at(_m); } catch (...) { return Message(); } }
void sendRaw(bytes const& _payload, bytes const& _topic, unsigned _ttl) { inject(Message(time(0) + _ttl, _ttl, _topic, _payload)); }
private:
void streamMessage(h256 _m, RLPStream& _s) const;
void noteChanged(h256 _messageHash, h256 _filter);
mutable dev::SharedMutex x_messages;
std::map<h256, Message> m_messages;
mutable dev::Mutex m_filterLock;
std::map<h256, InstalledFilter> m_filters;
std::map<unsigned, ClientWatch> m_watches;
};
struct WatshhChannel: public dev::LogChannel { static const char* name() { return "shh"; } static const int verbosity = 1; };
#define cwatshh dev::LogOutputStream<shh::WatshhChannel, true>()
class Watch;
}
}
/*
namespace std { void swap(shh::Watch& _a, shh::Watch& _b); }
namespace shh
{
class Watch: public boost::noncopyable
{
friend void std::swap(Watch& _a, Watch& _b);
public:
Watch() {}
Watch(Whisper& _c, h256 _f): m_c(&_c), m_id(_c.installWatch(_f)) {}
Watch(Whisper& _c, MessageFilter const& _tf): m_c(&_c), m_id(_c.installWatch(_tf)) {}
~Watch() { if (m_c) m_c->uninstallWatch(m_id); }
bool check() { return m_c ? m_c->checkWatch(m_id) : false; }
bool peek() { return m_c ? m_c->peekWatch(m_id) : false; }
private:
Whisper* m_c;
unsigned m_id;
};
}
namespace shh
{
inline void swap(shh::Watch& _a, shh::Watch& _b)
{
swap(_a.m_c, _b.m_c);
swap(_a.m_id, _b.m_id);
}
}
*/

3
libwhisper/_libwhisper.cpp

@ -2,4 +2,7 @@
#include "All.h"
#include "Common.cpp"
#include "WhisperPeer.cpp"
#include "WhisperHost.cpp"
#include "Message.cpp"
#include "Interface.cpp"
#endif

4
merge.sh

@ -0,0 +1,4 @@
#!/bin/bash
git checkout "$1+" && git merge --no-ff develop && git push && git tag -f $1 && git push --tags -f && git checkout develop

2
test/TestHelper.cpp

@ -42,6 +42,8 @@ void mine(Client& c, int numBlocks)
void connectClients(Client& c1, Client& c2)
{
(void)c1;
(void)c2;
// TODO: Move to WebThree. eth::Client no longer handles networking.
#if 0
short c1Port = 20000;

2
test/rlp.cpp

@ -22,12 +22,12 @@
#include <fstream>
#include <sstream>
#include "JsonSpiritHeaders.h"
#include <libdevcore/Log.h>
#include <libdevcore/RLP.h>
#include <libdevcore/Common.h>
#include <boost/test/unit_test.hpp>
#include <algorithm>
#include "JsonSpiritHeaders.h"
using namespace std;
using namespace dev;

11
third/MainWin.cpp

@ -106,11 +106,13 @@ Main::Main(QWidget *parent) :
{
// NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it.
m_ethereum = new QEthereum(this, ethereum(), owned());
m_whisper = new QWhisper(this, whisper());
QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
auto qeth = m_ethereum;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, this));
auto qshh = m_whisper;
connect(f, &QWebFrame::javaScriptWindowObjectCleared, QETH_INSTALL_JS_NAMESPACE(f, qeth, qshh, this));
});
connect(ui->webView, &QWebView::loadFinished, [=]()
@ -153,6 +155,11 @@ eth::Client* Main::ethereum() const
return m_web3->ethereum();
}
std::shared_ptr<dev::shh::WhisperHost> Main::whisper() const
{
return m_web3->whisper();
}
void Main::onKeysChanged()
{
installBalancesWatch();
@ -340,7 +347,7 @@ QString Main::lookup(QString const& _a) const
void Main::on_about_triggered()
{
QMessageBox::about(this, "About Third PoC-" + QString(dev::Version).section('.', 1, 1), QString("Third/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) "\n" DEV_QUOTED(ETH_COMMIT_HASH) + (ETH_CLEAN_REPO ? "\nCLEAN" : "\n+ LOCAL CHANGES") + "\n\nBy Gav Wood, 2014.\nBased on a design by Vitalik Buterin.\n\nThanks to the various contributors including: Alex Leverington, Tim Hughes, caktux, Eric Lombrozo, Marko Simovic.");
QMessageBox::about(this, "About Third PoC-" + QString(dev::Version).section('.', 1, 1), QString("Third/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM) "\n" DEV_QUOTED(ETH_COMMIT_HASH) + (ETH_CLEAN_REPO ? "\nCLEAN" : "\n+ LOCAL CHANGES") + "\n\nBy Gav Wood, 2014.\nThis software wouldn't be where it is today without the many leaders & contributors including:\n\nVitalik Buterin, Tim Hughes, caktux, Nick Savers, Eric Lombrozo, Marko Simovic, the many testers and the Berlin \304\220\316\236V team.");
}
void Main::writeSettings()

8
third/MainWin.h

@ -41,7 +41,11 @@ namespace eth {
class Client;
class State;
class MessageFilter;
}}
}
namespace shh {
class WhisperHost;
}
}
class QQuickView;
@ -55,6 +59,7 @@ public:
dev::WebThreeDirect* web3() const { return m_web3.get(); }
dev::eth::Client* ethereum() const;
std::shared_ptr<dev::shh::WhisperHost> whisper() const;
QList<dev::KeyPair> const& owned() const { return m_myKeys; }
@ -128,4 +133,5 @@ private:
QNetworkAccessManager m_webCtrl;
QEthereum* m_ethereum = nullptr;
QWhisper* m_whisper = nullptr;
};

240
windows/LibCryptoPP.vcxproj

@ -19,35 +19,275 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\cryptopp\adler32.cpp" />
<!--<ClCompile Include="..\..\cryptopp\algebra.cpp" />-->
<ClCompile Include="..\..\cryptopp\algparam.cpp" />
<ClCompile Include="..\..\cryptopp\arc4.cpp" />
<ClCompile Include="..\..\cryptopp\asn.cpp" />
<ClCompile Include="..\..\cryptopp\authenc.cpp" />
<ClCompile Include="..\..\cryptopp\base32.cpp" />
<ClCompile Include="..\..\cryptopp\base64.cpp" />
<ClCompile Include="..\..\cryptopp\basecode.cpp" />
<ClCompile Include="..\..\cryptopp\bench.cpp" />
<ClCompile Include="..\..\cryptopp\bench2.cpp" />
<ClCompile Include="..\..\cryptopp\bfinit.cpp" />
<ClCompile Include="..\..\cryptopp\blowfish.cpp" />
<ClCompile Include="..\..\cryptopp\blumshub.cpp" />
<ClCompile Include="..\..\cryptopp\camellia.cpp" />
<ClCompile Include="..\..\cryptopp\cast.cpp" />
<ClCompile Include="..\..\cryptopp\casts.cpp" />
<ClCompile Include="..\..\cryptopp\cbcmac.cpp" />
<ClCompile Include="..\..\cryptopp\ccm.cpp" />
<ClCompile Include="..\..\cryptopp\channels.cpp" />
<ClCompile Include="..\..\cryptopp\cmac.cpp" />
<ClCompile Include="..\..\cryptopp\cpu.cpp" />
<ClCompile Include="..\..\cryptopp\crc.cpp" />
<ClCompile Include="..\..\cryptopp\cryptlib.cpp" />
<ClCompile Include="..\..\cryptopp\cryptlib_bds.cpp" />
<ClCompile Include="..\..\cryptopp\datatest.cpp" />
<ClCompile Include="..\..\cryptopp\default.cpp" />
<ClCompile Include="..\..\cryptopp\des.cpp" />
<ClCompile Include="..\..\cryptopp\dessp.cpp" />
<ClCompile Include="..\..\cryptopp\dh.cpp" />
<ClCompile Include="..\..\cryptopp\dh2.cpp" />
<ClCompile Include="..\..\cryptopp\dll.cpp" />
<ClCompile Include="..\..\cryptopp\dlltest.cpp" />
<ClCompile Include="..\..\cryptopp\dsa.cpp" />
<ClCompile Include="..\..\cryptopp\eax.cpp" />
<ClCompile Include="..\..\cryptopp\ec2n.cpp" />
<!--<ClCompile Include="..\..\cryptopp\eccrypto.cpp" />-->
<ClCompile Include="..\..\cryptopp\ecp.cpp" />
<ClCompile Include="..\..\cryptopp\elgamal.cpp" />
<ClCompile Include="..\..\cryptopp\emsa2.cpp" />
<!--<ClCompile Include="..\..\cryptopp\eprecomp.cpp" />-->
<ClCompile Include="..\..\cryptopp\esign.cpp" />
<ClCompile Include="..\..\cryptopp\files.cpp" />
<ClCompile Include="..\..\cryptopp\filters.cpp" />
<ClCompile Include="..\..\cryptopp\fips140.cpp" />
<ClCompile Include="..\..\cryptopp\fipsalgt.cpp" />
<!--<ClCompile Include="..\..\cryptopp\fipstest.cpp" />-->
<ClCompile Include="..\..\cryptopp\gcm.cpp" />
<ClCompile Include="..\..\cryptopp\gf256.cpp" />
<ClCompile Include="..\..\cryptopp\gf2_32.cpp" />
<ClCompile Include="..\..\cryptopp\gf2n.cpp" />
<ClCompile Include="..\..\cryptopp\gfpcrypt.cpp" />
<ClCompile Include="..\..\cryptopp\gost.cpp" />
<ClCompile Include="..\..\cryptopp\gzip.cpp" />
<ClCompile Include="..\..\cryptopp\hex.cpp" />
<ClCompile Include="..\..\cryptopp\hmac.cpp" />
<ClCompile Include="..\..\cryptopp\hrtimer.cpp" />
<ClCompile Include="..\..\cryptopp\ida.cpp" />
<ClCompile Include="..\..\cryptopp\idea.cpp" />
<ClCompile Include="..\..\cryptopp\integer.cpp" />
<ClCompile Include="..\..\cryptopp\iterhash.cpp" />
<ClCompile Include="..\..\cryptopp\luc.cpp" />
<ClCompile Include="..\..\cryptopp\mars.cpp" />
<ClCompile Include="..\..\cryptopp\marss.cpp" />
<ClCompile Include="..\..\cryptopp\md2.cpp" />
<ClCompile Include="..\..\cryptopp\md4.cpp" />
<ClCompile Include="..\..\cryptopp\md5.cpp" />
<ClCompile Include="..\..\cryptopp\misc.cpp" />
<ClCompile Include="..\..\cryptopp\modes.cpp" />
<ClCompile Include="..\..\cryptopp\mqueue.cpp" />
<ClCompile Include="..\..\cryptopp\mqv.cpp" />
<ClCompile Include="..\..\cryptopp\nbtheory.cpp" />
<ClCompile Include="..\..\cryptopp\network.cpp" />
<ClCompile Include="..\..\cryptopp\oaep.cpp" />
<ClCompile Include="..\..\cryptopp\osrng.cpp" />
<ClCompile Include="..\..\cryptopp\panama.cpp" />
<ClCompile Include="..\..\cryptopp\pch.cpp" />
<ClCompile Include="..\..\cryptopp\pkcspad.cpp" />
<!--<ClCompile Include="..\..\cryptopp\polynomi.cpp" />-->
<ClCompile Include="..\..\cryptopp\pssr.cpp" />
<ClCompile Include="..\..\cryptopp\pubkey.cpp" />
<ClCompile Include="..\..\cryptopp\queue.cpp" />
<ClCompile Include="..\..\cryptopp\rabin.cpp" />
<ClCompile Include="..\..\cryptopp\randpool.cpp" />
<ClCompile Include="..\..\cryptopp\rc2.cpp" />
<ClCompile Include="..\..\cryptopp\rc5.cpp" />
<ClCompile Include="..\..\cryptopp\rc6.cpp" />
<ClCompile Include="..\..\cryptopp\rdtables.cpp" />
<ClCompile Include="..\..\cryptopp\regtest.cpp" />
<ClCompile Include="..\..\cryptopp\rijndael.cpp" />
<ClCompile Include="..\..\cryptopp\ripemd.cpp" />
<ClCompile Include="..\..\cryptopp\rng.cpp" />
<ClCompile Include="..\..\cryptopp\rsa.cpp" />
<ClCompile Include="..\..\cryptopp\rw.cpp" />
<ClCompile Include="..\..\cryptopp\safer.cpp" />
<ClCompile Include="..\..\cryptopp\salsa.cpp" />
<ClCompile Include="..\..\cryptopp\seal.cpp" />
<ClCompile Include="..\..\cryptopp\seed.cpp" />
<ClCompile Include="..\..\cryptopp\serpent.cpp" />
<ClCompile Include="..\..\cryptopp\sha.cpp" />
<ClCompile Include="..\..\cryptopp\sha3.cpp" />
<ClCompile Include="..\..\cryptopp\shacal2.cpp" />
<ClCompile Include="..\..\cryptopp\shark.cpp" />
<ClCompile Include="..\..\cryptopp\sharkbox.cpp" />
<!--<ClCompile Include="..\..\cryptopp\simple.cpp" />-->
<ClCompile Include="..\..\cryptopp\skipjack.cpp" />
<!--<ClCompile Include="..\..\cryptopp\socketft.cpp" />-->
<ClCompile Include="..\..\cryptopp\sosemanuk.cpp" />
<ClCompile Include="..\..\cryptopp\square.cpp" />
<ClCompile Include="..\..\cryptopp\squaretb.cpp" />
<!--<ClCompile Include="..\..\cryptopp\strciphr.cpp" />-->
<ClCompile Include="..\..\cryptopp\tea.cpp" />
<ClCompile Include="..\..\cryptopp\test.cpp" />
<ClCompile Include="..\..\cryptopp\tftables.cpp" />
<ClCompile Include="..\..\cryptopp\tiger.cpp" />
<ClCompile Include="..\..\cryptopp\tigertab.cpp" />
<ClCompile Include="..\..\cryptopp\trdlocal.cpp" />
<ClCompile Include="..\..\cryptopp\ttmac.cpp" />
<ClCompile Include="..\..\cryptopp\twofish.cpp" />
<ClCompile Include="..\..\cryptopp\validat1.cpp" />
<ClCompile Include="..\..\cryptopp\validat2.cpp" />
<ClCompile Include="..\..\cryptopp\validat3.cpp" />
<ClCompile Include="..\..\cryptopp\vmac.cpp" />
<ClCompile Include="..\..\cryptopp\wait.cpp" />
<ClCompile Include="..\..\cryptopp\wake.cpp" />
<ClCompile Include="..\..\cryptopp\whrlpool.cpp" />
<ClCompile Include="..\..\cryptopp\winpipes.cpp" />
<ClCompile Include="..\..\cryptopp\xtr.cpp" />
<ClCompile Include="..\..\cryptopp\xtrcrypt.cpp" />
<ClCompile Include="..\..\cryptopp\zdeflate.cpp" />
<ClCompile Include="..\..\cryptopp\zinflate.cpp" />
<ClCompile Include="..\..\cryptopp\zlib.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\cryptopp\3way.h" />
<ClInclude Include="..\..\cryptopp\adler32.h" />
<ClInclude Include="..\..\cryptopp\aes.h" />
<ClInclude Include="..\..\cryptopp\algebra.h" />
<ClInclude Include="..\..\cryptopp\algparam.h" />
<ClInclude Include="..\..\cryptopp\arc4.h" />
<ClInclude Include="..\..\cryptopp\argnames.h" />
<ClInclude Include="..\..\cryptopp\asn.h" />
<ClInclude Include="..\..\cryptopp\authenc.h" />
<ClInclude Include="..\..\cryptopp\base32.h" />
<ClInclude Include="..\..\cryptopp\base64.h" />
<ClInclude Include="..\..\cryptopp\basecode.h" />
<ClInclude Include="..\..\cryptopp\bench.h" />
<ClInclude Include="..\..\cryptopp\blowfish.h" />
<ClInclude Include="..\..\cryptopp\blumshub.h" />
<ClInclude Include="..\..\cryptopp\camellia.h" />
<ClInclude Include="..\..\cryptopp\cast.h" />
<ClInclude Include="..\..\cryptopp\cbcmac.h" />
<ClInclude Include="..\..\cryptopp\ccm.h" />
<ClInclude Include="..\..\cryptopp\channels.h" />
<ClInclude Include="..\..\cryptopp\cmac.h" />
<ClInclude Include="..\..\cryptopp\config.h" />
<ClInclude Include="..\..\cryptopp\cpu.h" />
<ClInclude Include="..\..\cryptopp\crc.h" />
<ClInclude Include="..\..\cryptopp\cryptlib.h" />
<ClInclude Include="..\..\cryptopp\default.h" />
<ClInclude Include="..\..\cryptopp\des.h" />
<ClInclude Include="..\..\cryptopp\dh.h" />
<ClInclude Include="..\..\cryptopp\dh2.h" />
<ClInclude Include="..\..\cryptopp\dll.h" />
<ClInclude Include="..\..\cryptopp\dmac.h" />
<ClInclude Include="..\..\cryptopp\dsa.h" />
<ClInclude Include="..\..\cryptopp\eax.h" />
<ClInclude Include="..\..\cryptopp\ec2n.h" />
<ClInclude Include="..\..\cryptopp\eccrypto.h" />
<ClInclude Include="..\..\cryptopp\ecp.h" />
<ClInclude Include="..\..\cryptopp\elgamal.h" />
<ClInclude Include="..\..\cryptopp\emsa2.h" />
<ClInclude Include="..\..\cryptopp\eprecomp.h" />
<ClInclude Include="..\..\cryptopp\esign.h" />
<ClInclude Include="..\..\cryptopp\factory.h" />
<ClInclude Include="..\..\cryptopp\files.h" />
<ClInclude Include="..\..\cryptopp\filters.h" />
<ClInclude Include="..\..\cryptopp\fips140.h" />
<ClInclude Include="..\..\cryptopp\fltrimpl.h" />
<ClInclude Include="..\..\cryptopp\gcm.h" />
<ClInclude Include="..\..\cryptopp\gf256.h" />
<ClInclude Include="..\..\cryptopp\gf2_32.h" />
<ClInclude Include="..\..\cryptopp\gf2n.h" />
<ClInclude Include="..\..\cryptopp\gfpcrypt.h" />
<ClInclude Include="..\..\cryptopp\gost.h" />
<ClInclude Include="..\..\cryptopp\gzip.h" />
<ClInclude Include="..\..\cryptopp\hex.h" />
<ClInclude Include="..\..\cryptopp\hmac.h" />
<ClInclude Include="..\..\cryptopp\hrtimer.h" />
<ClInclude Include="..\..\cryptopp\ida.h" />
<ClInclude Include="..\..\cryptopp\idea.h" />
<ClInclude Include="..\..\cryptopp\integer.h" />
<ClInclude Include="..\..\cryptopp\iterhash.h" />
<!--<ClInclude Include="..\..\cryptopp\lubyrack.h" />-->
<ClInclude Include="..\..\cryptopp\luc.h" />
<ClInclude Include="..\..\cryptopp\mars.h" />
<ClInclude Include="..\..\cryptopp\md2.h" />
<ClInclude Include="..\..\cryptopp\md4.h" />
<ClInclude Include="..\..\cryptopp\md5.h" />
<!--<ClInclude Include="..\..\cryptopp\mdc.h" />-->
<ClInclude Include="..\..\cryptopp\misc.h" />
<ClInclude Include="..\..\cryptopp\modarith.h" />
<ClInclude Include="..\..\cryptopp\modes.h" />
<ClInclude Include="..\..\cryptopp\modexppc.h" />
<ClInclude Include="..\..\cryptopp\mqueue.h" />
<ClInclude Include="..\..\cryptopp\mqv.h" />
<ClInclude Include="..\..\cryptopp\nbtheory.h" />
<ClInclude Include="..\..\cryptopp\network.h" />
<ClInclude Include="..\..\cryptopp\nr.h" />
<ClInclude Include="..\..\cryptopp\oaep.h" />
<ClInclude Include="..\..\cryptopp\oids.h" />
<ClInclude Include="..\..\cryptopp\osrng.h" />
<ClInclude Include="..\..\cryptopp\panama.h" />
<ClInclude Include="..\..\cryptopp\pch.h" />
<ClInclude Include="..\..\cryptopp\pkcspad.h" />
<ClInclude Include="..\..\cryptopp\polynomi.h" />
<ClInclude Include="..\..\cryptopp\pssr.h" />
<ClInclude Include="..\..\cryptopp\pubkey.h" />
<ClInclude Include="..\..\cryptopp\pwdbased.h" />
<ClInclude Include="..\..\cryptopp\queue.h" />
<ClInclude Include="..\..\cryptopp\rabin.h" />
<ClInclude Include="..\..\cryptopp\randpool.h" />
<ClInclude Include="..\..\cryptopp\rc2.h" />
<ClInclude Include="..\..\cryptopp\rc5.h" />
<ClInclude Include="..\..\cryptopp\rc6.h" />
<ClInclude Include="..\..\cryptopp\resource.h" />
<ClInclude Include="..\..\cryptopp\rijndael.h" />
<ClInclude Include="..\..\cryptopp\ripemd.h" />
<ClInclude Include="..\..\cryptopp\rng.h" />
<ClInclude Include="..\..\cryptopp\rsa.h" />
<ClInclude Include="..\..\cryptopp\rw.h" />
<ClInclude Include="..\..\cryptopp\safer.h" />
<ClInclude Include="..\..\cryptopp\salsa.h" />
<ClInclude Include="..\..\cryptopp\seal.h" />
<ClInclude Include="..\..\cryptopp\secblock.h" />
<ClInclude Include="..\..\cryptopp\seckey.h" />
<ClInclude Include="..\..\cryptopp\seed.h" />
<ClInclude Include="..\..\cryptopp\serpent.h" />
<!--<ClInclude Include="..\..\cryptopp\serpentp.h" />-->
<ClInclude Include="..\..\cryptopp\sha.h" />
<ClInclude Include="..\..\cryptopp\sha3.h" />
<ClInclude Include="..\..\cryptopp\shacal2.h" />
<ClInclude Include="..\..\cryptopp\shark.h" />
<ClInclude Include="..\..\cryptopp\simple.h" />
<ClInclude Include="..\..\cryptopp\skipjack.h" />
<ClInclude Include="..\..\cryptopp\smartptr.h" />
<ClInclude Include="..\..\cryptopp\socketft.h" />
<ClInclude Include="..\..\cryptopp\sosemanuk.h" />
<ClInclude Include="..\..\cryptopp\square.h" />
<ClInclude Include="..\..\cryptopp\stdcpp.h" />
<ClInclude Include="..\..\cryptopp\strciphr.h" />
<ClInclude Include="..\..\cryptopp\tea.h" />
<ClInclude Include="..\..\cryptopp\tiger.h" />
<ClInclude Include="..\..\cryptopp\trdlocal.h" />
<ClInclude Include="..\..\cryptopp\trunhash.h" />
<ClInclude Include="..\..\cryptopp\ttmac.h" />
<ClInclude Include="..\..\cryptopp\twofish.h" />
<ClInclude Include="..\..\cryptopp\validate.h" />
<ClInclude Include="..\..\cryptopp\vmac.h" />
<ClInclude Include="..\..\cryptopp\wait.h" />
<ClInclude Include="..\..\cryptopp\wake.h" />
<ClInclude Include="..\..\cryptopp\whrlpool.h" />
<ClInclude Include="..\..\cryptopp\winpipes.h" />
<ClInclude Include="..\..\cryptopp\words.h" />
<ClInclude Include="..\..\cryptopp\xtr.h" />
<ClInclude Include="..\..\cryptopp\xtrcrypt.h" />
<ClInclude Include="..\..\cryptopp\zdeflate.h" />
<ClInclude Include="..\..\cryptopp\zinflate.h" />
<ClInclude Include="..\..\cryptopp\zlib.h" />
</ItemGroup>
<ItemGroup>
<CustomBuild Include="..\..\cryptopp\x64dll.asm">

Loading…
Cancel
Save