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. 21
      libethereum/EthereumHost.cpp
  18. 47
      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. 121
      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); QSizeF area(n, n);
QPointF pos(0, 0); 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) for (unsigned i = bg.all().first, ei = bg.all().second; i < ei; ++i)
{ {
@ -63,7 +63,7 @@ void DownloadView::paintEvent(QPaintEvent*)
unsigned h = 0; unsigned h = 0;
m_man->foreachSub([&](DownloadSub const& sub) m_man->foreachSub([&](DownloadSub const& sub)
{ {
if (sub.asked().contains(i)) if (sub.askedContains(i))
s = h; s = h;
h++; h++;
}); });

64
alethzero/Main.ui

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

79
alethzero/MainWin.cpp

@ -25,9 +25,11 @@
#include <QtWidgets/QMessageBox> #include <QtWidgets/QMessageBox>
#include <QtWidgets/QInputDialog> #include <QtWidgets/QInputDialog>
#include <QtWebKitWidgets/QWebFrame> #include <QtWebKitWidgets/QWebFrame>
#include <QtWebKit/QWebSettings>
#include <QtGui/QClipboard> #include <QtGui/QClipboard>
#include <QtCore/QtCore> #include <QtCore/QtCore>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <test/JsonSpiritHeaders.h>
#include <libserpent/funcs.h> #include <libserpent/funcs.h>
#include <libserpent/util.h> #include <libserpent/util.h>
#include <libdevcrypto/FileSystem.h> #include <libdevcrypto/FileSystem.h>
@ -49,6 +51,7 @@ using namespace std;
using namespace dev; using namespace dev;
using namespace dev::p2p; using namespace dev::p2p;
using namespace dev::eth; using namespace dev::eth;
namespace js = json_spirit;
static void initUnits(QComboBox* _b) 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. // NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it.
m_ethereum = new QEthereum(this, ethereum(), owned()); 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(); QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared())); f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
auto qeth = m_ethereum; 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, [=]() connect(ui->webView, &QWebView::loadFinished, [=]()
@ -456,7 +462,7 @@ QString Main::lookup(QString const& _a) const
void Main::on_about_triggered() 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() 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()) if (std::find(m_myKeys.begin(), m_myKeys.end(), k) == m_myKeys.end())
{ {
m_myKeys.append(k); m_myKeys.append(k);
m_keysChanged = true; keysChanged();
update();
} }
else else
QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account."); 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)."); 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() void Main::on_exportKey_triggered()
{ {
if (ui->ourAccounts->currentRow() >= 0 && ui->ourAccounts->currentRow() < m_myKeys.size()) 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->peerCount->setText(QString::fromStdString(toString(ps.size())) + " peer(s)");
ui->peers->clear(); ui->peers->clear();
for (PeerInfo const& i: ps) 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() 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."); statusBar()->showMessage("Couldn't make transaction: no single account contains at least the required amount.");
} }
void Main::keysChanged()
{
onBalancesChange();
}
void Main::on_debug_clicked() void Main::on_debug_clicked()
{ {
debugFinished(); debugFinished();
@ -1581,7 +1638,7 @@ void Main::on_debug_clicked()
void Main::on_create_triggered() void Main::on_create_triggered()
{ {
m_myKeys.append(KeyPair::create()); m_myKeys.append(KeyPair::create());
m_keysChanged = true; keysChanged();
} }
void Main::on_debugStep_triggered() 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() void Main::on_callStack_currentItemChanged()
{ {
updateDebugger(); updateDebugger();

8
alethzero/MainWin.h

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

2
libdevcore/Common.cpp

@ -27,7 +27,7 @@ using namespace dev;
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 Range = std::pair<T, T>;
using Ranges = std::vector<Range>; using Ranges = std::vector<Range>;
RangeMask() {} RangeMask(): m_all(0, 0) {}
RangeMask(T _begin, T _end): m_all(_begin, _end) {} RangeMask(T _begin, T _end): m_all(_begin, _end) {}
RangeMask(Range const& _c): m_all(_c) {} RangeMask(Range const& _c): m_all(_c) {}
@ -150,7 +150,7 @@ public:
bool full() const 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() void clear()
@ -158,6 +158,12 @@ public:
m_ranges.clear(); 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; } std::pair<T, T> const& all() const { return m_all; }
class const_iterator class const_iterator

6
libdevcrypto/Common.cpp

@ -102,3 +102,9 @@ KeyPair::KeyPair(h256 _sec):
cout << "ADR: " << m_address << endl; cout << "ADR: " << m_address << endl;
#endif #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. /// Create a new, randomly generated object.
static KeyPair create(); static KeyPair create();
/// Create from an encrypted seed.
static KeyPair fromEncryptedSeed(bytesConstRef _seed, std::string const& _password);
/// Retrieve the secret key. /// Retrieve the secret key.
Secret const& secret() const { return m_secret; } Secret const& secret() const { return m_secret; }
/// Retrieve the secret key. /// Retrieve the secret key.

5
libdevcrypto/CryptoHeaders.h

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

29
libdevcrypto/SHA3.cpp

@ -72,5 +72,34 @@ h256 sha3(bytesConstRef _input)
return ret; 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; 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_protocolVersion = 33;
const unsigned c_databaseVersion = 1; const unsigned c_databaseVersion = 2;
static const vector<pair<u256, string>> g_units = 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 InvalidUnclesHash: public dev::Exception {};
class InvalidUncle: public dev::Exception {}; class InvalidUncle: public dev::Exception {};
class UncleTooOld: 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 DuplicateUncleNonce: public dev::Exception {};
class InvalidStateRoot: 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()); } }; 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); auto pd = details(bi.parentHash);
if (!pd) if (!pd)
{
cwarn << "Odd: details is returning false despite block known:" << RLP(pd.rlp()); cwarn << "Odd: details is returning false despite block known:" << RLP(pd.rlp());
cwarn << "Block:" << RLP(block(bi.parentHash));
}
// Check it's not crazy // Check it's not crazy
if (bi.timestamp > (u256)time(0)) if (bi.timestamp > (u256)time(0))
@ -479,13 +482,16 @@ bytes BlockChain::block(h256 _hash) const
string d; string d;
m_db->Get(m_readOptions, ldb::Slice((char const*)&_hash, 32), &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); WriteGuard l(x_cache);
m_cache[_hash].resize(d.size()); m_cache[_hash].resize(d.size());
memcpy(m_cache[_hash].data(), d.data(), 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]; return m_cache[_hash];
} }

2
libethereum/DownloadMan.cpp

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

27
libethereum/DownloadMan.h

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

21
libethereum/EthereumHost.cpp

@ -74,13 +74,20 @@ void EthereumHost::noteHavePeerState(EthereumPeer* _who)
{ {
clog(NetAllDetail) << "Have peer state."; clog(NetAllDetail) << "Have peer state.";
// TODO: FIX: BUG: Better state management!
// if already downloading hash-chain, ignore. // if already downloading hash-chain, ignore.
if (m_grabbing != Grabbing::Nothing) if (m_grabbing != Grabbing::Nothing)
{
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."; clog(NetAllDetail) << "Already downloading chain. Just set to help out.";
_who->ensureGettingChain(); _who->ensureGettingChain();
return; return;
} }
m_grabbing = Grabbing::Nothing;
}
// otherwise check to see if we should be downloading... // otherwise check to see if we should be downloading...
_who->tryGrabbingHashChain(); _who->tryGrabbingHashChain();
@ -102,7 +109,7 @@ void EthereumHost::noteHaveChain(EthereumPeer* _from)
if (_from->m_neededBlocks.empty()) if (_from->m_neededBlocks.empty())
{ {
_from->m_grabbing = Grabbing::Nothing; _from->setGrabbing(Grabbing::Nothing);
updateGrabbing(Grabbing::Nothing); updateGrabbing(Grabbing::Nothing);
return; 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)) 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."; clog(NetNote) << "Difficulty of hashchain not HIGHER. Ignoring.";
_from->m_grabbing = Grabbing::Nothing; _from->setGrabbing(Grabbing::Nothing);
updateGrabbing(Grabbing::Nothing); updateGrabbing(Grabbing::Nothing);
return; return;
} }
@ -123,7 +130,7 @@ void EthereumHost::noteHaveChain(EthereumPeer* _from)
m_man.resetToChain(_from->m_neededBlocks); m_man.resetToChain(_from->m_neededBlocks);
m_latestBlockSent = _from->m_latestHash; m_latestBlockSent = _from->m_latestHash;
_from->m_grabbing = Grabbing::Chain; _from->setGrabbing(Grabbing::Chain);
updateGrabbing(Grabbing::Chain); updateGrabbing(Grabbing::Chain);
} }
@ -149,6 +156,7 @@ void EthereumHost::noteDoneBlocks(EthereumPeer* _who)
// Done our chain-get. // Done our chain-get.
clog(NetNote) << "Chain download complete."; clog(NetNote) << "Chain download complete.";
updateGrabbing(Grabbing::Nothing); updateGrabbing(Grabbing::Nothing);
m_man.reset();
} }
if (_who->m_grabbing == Grabbing::Chain) 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."; 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! // TODO: note that peer is BADBADBAD!
updateGrabbing(Grabbing::Nothing); updateGrabbing(Grabbing::Nothing);
m_man.reset();
} }
} }
@ -263,6 +272,12 @@ void EthereumHost::maintainBlocks(BlockQueue& _bq, h256 _currentHash)
++c; ++c;
} }
clog(NetMessageSummary) << "Sending" << c << "new blocks (current is" << _currentHash << ", was" << m_latestBlockSent << ")"; 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); ts.appendList(1 + c).append(BlocksPacket).appendRaw(bs, c);
bytes b; bytes b;
ts.swapOut(b); ts.swapOut(b);

47
libethereum/EthereumPeer.cpp

@ -38,6 +38,7 @@ EthereumPeer::EthereumPeer(Session* _s, HostCapabilityFace* _h):
Capability(_s, _h), Capability(_s, _h),
m_sub(host()->m_man) m_sub(host()->m_man)
{ {
setGrabbing(Grabbing::State);
sendStatus(); sendStatus();
} }
@ -94,7 +95,7 @@ void EthereumPeer::tryGrabbingHashChain()
if (td >= m_totalDifficulty) if (td >= m_totalDifficulty)
{ {
clogS(NetAllDetail) << "No. Our chain is better."; clogS(NetAllDetail) << "No. Our chain is better.";
m_grabbing = Grabbing::Nothing; setGrabbing(Grabbing::Nothing);
return; // All good - we have the better chain. return; // All good - we have the better chain.
} }
@ -103,7 +104,7 @@ void EthereumPeer::tryGrabbingHashChain()
clogS(NetAllDetail) << "Yes. Their chain is better."; clogS(NetAllDetail) << "Yes. Their chain is better.";
host()->updateGrabbing(Grabbing::Hashes); host()->updateGrabbing(Grabbing::Hashes);
m_grabbing = Grabbing::Hashes; setGrabbing(Grabbing::Hashes);
RLPStream s; RLPStream s;
prep(s).appendList(3); prep(s).appendList(3);
s << GetBlockHashesPacket << m_latestHash << c_maxHashesAsk; s << GetBlockHashesPacket << m_latestHash << c_maxHashesAsk;
@ -114,17 +115,17 @@ void EthereumPeer::tryGrabbingHashChain()
void EthereumPeer::giveUpOnFetch() 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. // 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) if (m_grabbing == Grabbing::Chain || m_grabbing == Grabbing::ChainHelper)
{ {
host()->noteDoneBlocks(this); 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. // NOTE: need to notify of giving up on chain-hashes, too, altering state as necessary.
m_sub.doneFetch();
} }
bool EthereumPeer::interpret(RLP const& _r) bool EthereumPeer::interpret(RLP const& _r)
@ -143,11 +144,13 @@ bool EthereumPeer::interpret(RLP const& _r)
if (genesisHash != host()->m_chain.genesisHash()) if (genesisHash != host()->m_chain.genesisHash())
disable("Invalid genesis hash"); disable("Invalid genesis hash");
if (m_protocolVersion != host()->protocolVersion()) else if (m_protocolVersion != host()->protocolVersion())
disable("Invalid protocol version."); disable("Invalid protocol version.");
if (m_networkId != host()->networkId()) else if (m_networkId != host()->networkId())
disable("Invalid network identifier."); disable("Invalid network identifier.");
else if (session()->info().clientVersion.find("/v0.6.9/") != string::npos)
disable("Blacklisted client version.");
else
startInitialSync(); startInitialSync();
break; break;
} }
@ -176,12 +179,12 @@ bool EthereumPeer::interpret(RLP const& _r)
unsigned limit = _r[2].toInt<unsigned>(); unsigned limit = _r[2].toInt<unsigned>();
clogS(NetMessageSummary) << "GetBlockHashes (" << limit << "entries," << later.abridged() << ")"; 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; RLPStream s;
prep(s).appendList(1 + c).append(BlockHashesPacket); prep(s).appendList(1 + c).append(BlockHashesPacket);
h256 p = host()->m_chain.details(later).parent; 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; s << p;
sealAndSend(s); sealAndSend(s);
break; break;
@ -203,7 +206,7 @@ bool EthereumPeer::interpret(RLP const& _r)
for (unsigned i = 1; i < _r.itemCount(); ++i) for (unsigned i = 1; i < _r.itemCount(); ++i)
{ {
auto h = _r[i].toHash<h256>(); auto h = _r[i].toHash<h256>();
if (host()->m_chain.details(h)) if (host()->m_chain.isKnown(h))
{ {
host()->noteHaveChain(this); host()->noteHaveChain(this);
return true; return true;
@ -244,8 +247,9 @@ bool EthereumPeer::interpret(RLP const& _r)
if (_r.itemCount() == 1) if (_r.itemCount() == 1)
{ {
// Couldn't get any from last batch - probably got to this peer's latest block - just give up. // Couldn't get any from last batch - probably got to this peer's latest block - just give up.
m_sub.doneFetch(); if (m_grabbing == Grabbing::Chain || m_grabbing == Grabbing::ChainHelper)
giveUpOnFetch(); giveUpOnFetch();
break;
} }
unsigned used = 0; unsigned used = 0;
@ -263,7 +267,8 @@ bool EthereumPeer::interpret(RLP const& _r)
unsigned unknownParents = 0; unsigned unknownParents = 0;
if (g_logVerbosity >= NetMessageSummary::verbosity) 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()); auto h = BlockInfo::headerHash(_r[i].data());
BlockInfo bi(_r[i].data()); BlockInfo bi(_r[i].data());
@ -281,6 +286,7 @@ bool EthereumPeer::interpret(RLP const& _r)
} }
} }
clogS(NetMessageSummary) << dec << knownParents << "known parents," << unknownParents << "unknown," << used << "used."; clogS(NetMessageSummary) << dec << knownParents << "known parents," << unknownParents << "unknown," << used << "used.";
if (m_grabbing == Grabbing::Chain || m_grabbing == Grabbing::ChainHelper)
continueGettingChain(); continueGettingChain();
break; break;
} }
@ -295,13 +301,18 @@ void EthereumPeer::ensureGettingChain()
if (m_grabbing == Grabbing::ChainHelper) if (m_grabbing == Grabbing::ChainHelper)
return; // Already asked & waiting for some. 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(); continueGettingChain();
} }
void EthereumPeer::continueGettingChain() void EthereumPeer::continueGettingChain()
{ {
if (m_grabbing != Grabbing::Chain) // If we're getting the hashes already, then we shouldn't be asking for the chain.
m_grabbing = Grabbing::ChainHelper; if (m_grabbing == Grabbing::Hashes)
return;
auto blocks = m_sub.nextFetch(c_maxBlocksAsk); auto blocks = m_sub.nextFetch(c_maxBlocksAsk);
@ -317,3 +328,9 @@ void EthereumPeer::continueGettingChain()
else else
giveUpOnFetch(); 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 giveUpOnFetch();
void clearKnownTransactions() { std::lock_guard<std::mutex> l(x_knownTransactions); m_knownTransactions.clear(); } void clearKnownTransactions() { std::lock_guard<std::mutex> l(x_knownTransactions); m_knownTransactions.clear(); }
void setGrabbing(Grabbing _g);
unsigned m_protocolVersion; unsigned m_protocolVersion;
u256 m_networkId; u256 m_networkId;
Grabbing m_grabbing = Grabbing::State; Grabbing m_grabbing;
h256 m_latestHash; ///< Peer's latest block's hash. h256 m_latestHash; ///< Peer's latest block's hash.
u256 m_totalDifficulty; ///< Peer's latest block's total difficulty. 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 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. // we delete it explicitly if we decide we need to revert.
m_newAddress = right160(sha3(rlpList(_sender, m_s.transactionsFrom(_sender) - 1))); 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... // 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. // Execute _init.
m_vm = new VM(_gas); 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>(); set<h256> knownUncles = _bc ? _bc->allUnclesFrom(m_currentBlock.parentHash) : set<h256>();
for (auto const& i: RLP(_block)[2]) 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()); BlockInfo uncle = BlockInfo::fromHeader(i.data());
if (nonces.count(uncle.nonce)) if (nonces.count(uncle.nonce))
throw DuplicateUncleNonce(); throw DuplicateUncleNonce();
@ -585,8 +588,6 @@ u256 State::enact(bytesConstRef _block, BlockChain const* _bc, bool _checkNonce)
BlockInfo uncleParent(_bc->block(uncle.parentHash)); BlockInfo uncleParent(_bc->block(uncle.parentHash));
if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 6) if ((bigint)uncleParent.number < (bigint)m_currentBlock.number - 6)
throw UncleTooOld(); throw UncleTooOld();
if (knownUncles.count(sha3(i.data())))
throw UncleInChain();
uncle.verifyParent(uncleParent); uncle.verifyParent(uncleParent);
} }
@ -725,7 +726,7 @@ void State::commitToMine(BlockChain const& _bc)
auto us = _bc.details(p).children; auto us = _bc.details(p).children;
assert(us.size() >= 1); // must be at least 1 child of our grandparent - it's our own parent! assert(us.size() >= 1); // must be at least 1 child of our grandparent - it's our own parent!
for (auto const& u: us) 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)); BlockInfo ubi(_bc.block(u));
ubi.fillStream(unclesData, true); ubi.fillStream(unclesData, true);
@ -965,7 +966,7 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const
RLP r(i.second); RLP r(i.second);
TrieDB<h256, OverlayDB> storageDB(const_cast<OverlayDB*>(&m_db), r[2].toHash<h256>()); // promise not to alter OverlayDB. 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; } 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; return false;
} }
} }
@ -1132,7 +1133,7 @@ h160 State::create(Address _sender, u256 _endowment, u256 _gasPrice, u256* _gas,
newAddress = (u160)newAddress + 1; newAddress = (u160)newAddress + 1;
// Set up new account... // 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. // Execute init code.
VM vm(*_gas); 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) if (_ext.balance(_ext.myAddress) >= value)
{ {
_ext.subBalance(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 else
m_stack.push_back(0); m_stack.push_back(0);

2
libp2p/Common.h

@ -95,6 +95,8 @@ struct PeerInfo
unsigned short port; unsigned short port;
std::chrono::steady_clock::duration lastPing; std::chrono::steady_clock::duration lastPing;
std::set<std::string> caps; 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_disconnect = std::chrono::steady_clock::time_point::max();
m_connect = std::chrono::steady_clock::now(); 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() Session::~Session()
@ -102,7 +102,7 @@ bool Session::interpret(RLP const& _r)
return false; return false;
} }
try 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 (...) catch (...)
{ {
disconnect(BadProtocol); disconnect(BadProtocol);

4
libp2p/Session.h

@ -71,6 +71,10 @@ public:
void addRating(unsigned _r) { m_rating += _r; } 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: private:
void dropped(); void dropped();
void doRead(); void doRead();

59
libqethereum/QEthereum.cpp

@ -476,6 +476,65 @@ void QEthereum::poll()
emit watchChanged(w); 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 // extra bits needed to link on VS
#ifdef _MSC_VER #ifdef _MSC_VER

55
libqethereum/QEthereum.h

@ -6,9 +6,14 @@
#include <libdevcore/CommonIO.h> #include <libdevcore/CommonIO.h>
#include <libethcore/CommonEth.h> #include <libethcore/CommonEth.h>
namespace dev { namespace eth { namespace dev {
namespace eth {
class Interface; class Interface;
}} }
namespace shh {
class Interface;
}
}
class QJSEngine; class QJSEngine;
class QWebFrame; class QWebFrame;
@ -203,11 +208,51 @@ private:
QList<dev::KeyPair> m_accounts; 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->disconnect(); \
frame->addToJavaScriptWindowObject("env", env, QWebFrame::QtOwnership); \ frame->addToJavaScriptWindowObject("env", env, QWebFrame::QtOwnership); \
frame->addToJavaScriptWindowObject("eth", eth, QWebFrame::ScriptOwnership); \ 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.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.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') }"); \ 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.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.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("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("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("window.onerror = function (errorMsg, url, lineNumber, column, errorObj) { env.warn('Error: ' + errorMsg + ', Script: ' + url + ', Line: ' + lineNumber + ', Column: ' + column + ', StackTrace: ' + String(errorObj)) }"); \ 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) 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 <libp2p/Host.h>
#include <libethereum/Defaults.h> #include <libethereum/Defaults.h>
#include <libethereum/EthereumHost.h> #include <libethereum/EthereumHost.h>
#include <libwhisper/WhisperPeer.h> #include <libwhisper/WhisperHost.h>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::p2p; using namespace dev::p2p;
@ -45,8 +45,8 @@ WebThreeDirect::WebThreeDirect(std::string const& _clientVersion, std::string co
if (_interfaces.count("eth")) if (_interfaces.count("eth"))
m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean)); m_ethereum.reset(new eth::Client(&m_net, _dbPath, _forceClean));
// if (_interfaces.count("shh")) if (_interfaces.count("shh"))
// m_whisper = new eth::Whisper(m_net.get()); m_whisper = m_net.registerCapability<WhisperHost>(new WhisperHost);
} }
WebThreeDirect::~WebThreeDirect() WebThreeDirect::~WebThreeDirect()

6
libwebthree/WebThree.h

@ -32,7 +32,7 @@
#include <libdevcore/Exceptions.h> #include <libdevcore/Exceptions.h>
#include <libp2p/Host.h> #include <libp2p/Host.h>
#include <libwhisper/WhisperPeer.h> #include <libwhisper/WhisperHost.h>
#include <libethereum/Client.h> #include <libethereum/Client.h>
namespace dev namespace dev
@ -74,7 +74,7 @@ public:
// The mainline interfaces: // The mainline interfaces:
eth::Client* ethereum() const { if (!m_ethereum) throw InterfaceNotSupported("eth"); return m_ethereum.get(); } 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"); } bzz::Interface* swarm() const { throw InterfaceNotSupported("bzz"); }
// Misc stuff: // Misc stuff:
@ -118,7 +118,7 @@ private:
std::string m_clientVersion; ///< Our end-application client's name/version. 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<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. 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;
};
}
}

121
libwhisper/WhisperPeer.cpp

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file Whisper.cpp /** @file WhisperPeer.cpp
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2014 * @date 2014
*/ */
@ -23,11 +23,11 @@
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libp2p/All.h> #include <libp2p/All.h>
#include "WhisperHost.h"
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace dev::p2p; using namespace dev::p2p;
using namespace dev::shh; using namespace dev::shh;
#define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] " #define clogS(X) dev::LogOutputStream<X, true>(false) << "| " << std::setw(2) << session()->socketId() << "] "
WhisperPeer::WhisperPeer(Session* _s, HostCapabilityFace* _h): Capability(_s, _h) WhisperPeer::WhisperPeer(Session* _s, HostCapabilityFace* _h): Capability(_s, _h)
@ -92,15 +92,17 @@ void WhisperPeer::sendMessages()
n++; n++;
} }
// pause before sending if no messages to send if (n)
if (!n) {
this_thread::sleep_for(chrono::milliseconds(100));
RLPStream s; RLPStream s;
prep(s); prep(s);
s.appendList(n + 1) << MessagesPacket; s.appendList(n + 1) << MessagesPacket;
s.appendRaw(amalg.out(), n); s.appendRaw(amalg.out(), n);
sealAndSend(s); sealAndSend(s);
}
else
// just pause if no messages to send
this_thread::sleep_for(chrono::milliseconds(100));
} }
void WhisperPeer::noteNewMessage(h256 _h, Message const& _m) void WhisperPeer::noteNewMessage(h256 _h, Message const& _m)
@ -108,110 +110,3 @@ void WhisperPeer::noteNewMessage(h256 _h, Message const& _m)
Guard l(x_unseen); Guard l(x_unseen);
m_unseen[rating(_m)] = _h; 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 You should have received a copy of the GNU General Public License
along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** @file Whisper.h /** @file WhisperPeer.h
* @author Gav Wood <i@gavwood.com> * @author Gav Wood <i@gavwood.com>
* @date 2014 * @date 2014
*/ */
@ -30,6 +30,7 @@
#include <libdevcore/Guards.h> #include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h> #include <libdevcrypto/SHA3.h>
#include "Common.h" #include "Common.h"
#include "Message.h"
namespace dev namespace dev
{ {
@ -41,29 +42,6 @@ using p2p::HostCapabilityFace;
using p2p::HostCapability; using p2p::HostCapability;
using p2p::Capability; 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 class WhisperPeer: public Capability
@ -90,133 +68,5 @@ private:
std::map<unsigned, h256> m_unseen; ///< Rated according to what they want. 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 "All.h"
#include "Common.cpp" #include "Common.cpp"
#include "WhisperPeer.cpp" #include "WhisperPeer.cpp"
#include "WhisperHost.cpp"
#include "Message.cpp"
#include "Interface.cpp"
#endif #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 connectClients(Client& c1, Client& c2)
{ {
(void)c1;
(void)c2;
// TODO: Move to WebThree. eth::Client no longer handles networking. // TODO: Move to WebThree. eth::Client no longer handles networking.
#if 0 #if 0
short c1Port = 20000; short c1Port = 20000;

2
test/rlp.cpp

@ -22,12 +22,12 @@
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include "JsonSpiritHeaders.h"
#include <libdevcore/Log.h> #include <libdevcore/Log.h>
#include <libdevcore/RLP.h> #include <libdevcore/RLP.h>
#include <libdevcore/Common.h> #include <libdevcore/Common.h>
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <algorithm> #include <algorithm>
#include "JsonSpiritHeaders.h"
using namespace std; using namespace std;
using namespace dev; 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. // NOTE: no need to delete as QETH_INSTALL_JS_NAMESPACE adopts it.
m_ethereum = new QEthereum(this, ethereum(), owned()); m_ethereum = new QEthereum(this, ethereum(), owned());
m_whisper = new QWhisper(this, whisper());
QWebFrame* f = ui->webView->page()->mainFrame(); QWebFrame* f = ui->webView->page()->mainFrame();
f->disconnect(SIGNAL(javaScriptWindowObjectCleared())); f->disconnect(SIGNAL(javaScriptWindowObjectCleared()));
auto qeth = m_ethereum; 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, [=]() connect(ui->webView, &QWebView::loadFinished, [=]()
@ -153,6 +155,11 @@ eth::Client* Main::ethereum() const
return m_web3->ethereum(); return m_web3->ethereum();
} }
std::shared_ptr<dev::shh::WhisperHost> Main::whisper() const
{
return m_web3->whisper();
}
void Main::onKeysChanged() void Main::onKeysChanged()
{ {
installBalancesWatch(); installBalancesWatch();
@ -340,7 +347,7 @@ QString Main::lookup(QString const& _a) const
void Main::on_about_triggered() 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() void Main::writeSettings()

8
third/MainWin.h

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

240
windows/LibCryptoPP.vcxproj

@ -19,35 +19,275 @@
</ProjectConfiguration> </ProjectConfiguration>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\..\cryptopp\adler32.cpp" />
<!--<ClCompile Include="..\..\cryptopp\algebra.cpp" />-->
<ClCompile Include="..\..\cryptopp\algparam.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\cpu.cpp" />
<ClCompile Include="..\..\cryptopp\crc.cpp" />
<ClCompile Include="..\..\cryptopp\cryptlib.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\filters.cpp" />
<ClCompile Include="..\..\cryptopp\fips140.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\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\misc.cpp" />
<ClCompile Include="..\..\cryptopp\modes.cpp" />
<ClCompile Include="..\..\cryptopp\mqueue.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\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\rdtables.cpp" />
<ClCompile Include="..\..\cryptopp\regtest.cpp" />
<ClCompile Include="..\..\cryptopp\rijndael.cpp" /> <ClCompile Include="..\..\cryptopp\rijndael.cpp" />
<ClCompile Include="..\..\cryptopp\ripemd.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\sha.cpp" />
<ClCompile Include="..\..\cryptopp\sha3.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>
<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\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\cpu.h" />
<ClInclude Include="..\..\cryptopp\crc.h" />
<ClInclude Include="..\..\cryptopp\cryptlib.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\filters.h" />
<ClInclude Include="..\..\cryptopp\fips140.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\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\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\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\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\rijndael.h" />
<ClInclude Include="..\..\cryptopp\ripemd.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\sha.h" />
<ClInclude Include="..\..\cryptopp\sha3.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>
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\..\cryptopp\x64dll.asm"> <CustomBuild Include="..\..\cryptopp\x64dll.asm">

Loading…
Cancel
Save