Browse Source

Merge remote-tracking branch 'up/develop' into bugFix

Conflicts:
	mix/CodeModel.cpp
cl-refactor
yann300 10 years ago
parent
commit
f5ef8df702
  1. 2
      abi/main.cpp
  2. 2
      alethzero/DappLoader.cpp
  3. 6
      alethzero/DownloadView.cpp
  4. 8
      alethzero/MainWin.cpp
  5. 2
      alethzero/NatspecHandler.cpp
  6. 2
      eth/main.cpp
  7. 27
      ethminer/MinerAux.h
  8. 2
      ethminer/main.cpp
  9. 2
      evmjit/libevmjit-cpp/Env.cpp
  10. 2
      evmjit/libevmjit-cpp/JitVM.cpp
  11. 38
      exp/main.cpp
  12. 5
      libdevcore/Common.h
  13. 2
      libdevcore/CommonData.cpp
  14. 2
      libdevcore/CommonData.h
  15. 4
      libdevcore/FileSystem.cpp
  16. 0
      libdevcore/FileSystem.h
  17. 440
      libdevcore/Hash.cpp
  18. 38
      libdevcore/Hash.h
  19. 0
      libdevcore/MemoryDB.cpp
  20. 0
      libdevcore/MemoryDB.h
  21. 223
      libdevcore/SHA3.cpp
  22. 37
      libdevcore/SHA3.h
  23. 0
      libdevcore/TrieCommon.cpp
  24. 0
      libdevcore/TrieCommon.h
  25. 0
      libdevcore/TrieDB.cpp
  26. 3
      libdevcore/TrieDB.h
  27. 64
      libdevcore/TrieHash.cpp
  28. 15
      libdevcore/TrieHash.h
  29. 360
      libdevcore/picosha2.h
  30. 32
      libdevcrypto/AES.cpp
  31. 5
      libdevcrypto/AES.h
  32. 5
      libdevcrypto/Common.cpp
  33. 2
      libdevcrypto/CryptoPP.h
  34. 4
      libdevcrypto/ECDHE.cpp
  35. 2
      libdevcrypto/OverlayDB.h
  36. 129
      libdevcrypto/SHA3.cpp
  37. 4
      libdevcrypto/SecretStore.cpp
  38. 2
      libdevcrypto/SecretStore.h
  39. 15
      libethash-cl/ethash_cl_miner.cpp
  40. 2
      libethcore/ABI.h
  41. 16
      libethcore/BlockInfo.cpp
  42. 2
      libethcore/Common.cpp
  43. 14
      libethcore/Ethash.cpp
  44. 1
      libethcore/Ethash.h
  45. 10
      libethcore/EthashAux.cpp
  46. 2
      libethcore/EthashAux.h
  47. 2
      libethcore/ICAP.cpp
  48. 10
      libethcore/Miner.h
  49. 4
      libethereum/Account.h
  50. 8
      libethereum/BlockChain.cpp
  51. 2
      libethereum/BlockQueue.h
  52. 7
      libethereum/CachedAddressState.cpp
  53. 2
      libethereum/CanonBlockChain.cpp
  54. 20
      libethereum/Client.cpp
  55. 5
      libethereum/Client.h
  56. 2
      libethereum/Defaults.cpp
  57. 36
      libethereum/Executive.cpp
  58. 1
      libethereum/Executive.h
  59. 10
      libethereum/ExtVM.cpp
  60. 2
      libethereum/ExtVM.h
  61. 7
      libethereum/KeyManager.cpp
  62. 12
      libethereum/KeyManager.h
  63. 2
      libethereum/LogFilter.cpp
  64. 15
      libethereum/Precompiled.cpp
  65. 22
      libethereum/State.cpp
  66. 3
      libethereum/State.h
  67. 2
      libethereum/Transaction.h
  68. 2
      libethereum/Utility.cpp
  69. 16
      libevm/ExtVMFace.h
  70. 2
      libevm/SmartVM.cpp
  71. 6
      libevm/SmartVM.h
  72. 40
      libevm/VM.cpp
  73. 10
      libevm/VM.h
  74. 9
      libevm/VMFace.h
  75. 2
      libevmasm/CommonSubexpressionEliminator.cpp
  76. 2
      libevmasm/KnownState.cpp
  77. 2
      libp2p/Host.cpp
  78. 2
      libp2p/UDP.h
  79. 2
      libsolidity/AST.cpp
  80. 2
      libsolidity/CompilerStack.cpp
  81. 2
      libsolidity/ExpressionCompiler.cpp
  82. 2
      libsolidity/Types.cpp
  83. 2
      libtestutils/Common.cpp
  84. 2
      libweb3jsonrpc/WebThreeStubServer.cpp
  85. 2
      libwhisper/Common.cpp
  86. 2
      libwhisper/Interface.h
  87. 2
      libwhisper/Message.h
  88. 2
      libwhisper/WhisperHost.h
  89. 2
      libwhisper/WhisperPeer.h
  90. 68
      mix/CodeModel.cpp
  91. 44
      mix/CodeModel.h
  92. 2
      mix/FileIo.cpp
  93. 2
      mix/QFunctionDefinition.cpp
  94. 15
      mix/qml/Application.qml
  95. 12
      mix/qml/CodeEditorView.qml
  96. 1
      mix/qml/StatesComboBox.qml
  97. 1
      mix/qml/StatusPane.qml
  98. 15
      mix/qml/WebCodeEditor.qml
  99. 6
      mix/qml/html/cm/solarized.css
  100. 107
      mix/qml/html/codeeditor.js

2
abi/main.cpp

@ -26,7 +26,7 @@
#include "../test/JsonSpiritHeaders.h"
#include <libdevcore/CommonIO.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libethereum/Client.h>
using namespace std;
using namespace dev;

2
alethzero/DappLoader.cpp

@ -29,7 +29,7 @@
#include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libethcore/CommonJS.h>
#include <libethereum/Client.h>
#include <libwebthree/WebThree.h>

6
alethzero/DownloadView.cpp

@ -52,7 +52,10 @@ void DownloadView::paintEvent(QPaintEvent*)
QPointF pos(0, 0);
auto bg = m_man->blocksGot();
unsigned subCount = m_man->subCount();
if (subCount == 0)
return;
unsigned dh = 360 / subCount;
for (unsigned i = bg.all().first, ei = bg.all().second; i < ei; ++i)
{
int s = -2;
@ -68,7 +71,6 @@ void DownloadView::paintEvent(QPaintEvent*)
h++;
});
}
unsigned dh = 360 / m_man->subCount();
if (s == -2)
p.fillRect(QRectF(QPointF(pos) + QPointF(3 * area.width() / 8, 3 * area.height() / 8), area / 4), Qt::black);
else if (s == -1)

8
alethzero/MainWin.cpp

@ -44,7 +44,7 @@
#include <libserpent/funcs.h>
#include <libserpent/util.h>
#endif
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include <libethcore/CommonJS.h>
#include <libethcore/EthashAux.h>
#include <libethcore/ICAP.h>
@ -1166,10 +1166,10 @@ void Main::on_turboMining_triggered()
void Main::refreshBlockChain()
{
if (!ui->blocks->isVisible())
if (!ui->blocks->isVisible() && isVisible())
return;
DEV_TIMED_FUNCTION;
DEV_TIMED_FUNCTION_ABOVE(500);
cwatch << "refreshBlockChain()";
// TODO: keep the same thing highlighted.
@ -1353,7 +1353,7 @@ void Main::timerEvent(QTimerEvent*)
auto ls = ethereum()->checkWatchSafe(i.first);
if (ls.size())
{
cnote << "FIRING WATCH" << i.first << ls.size();
// cnote << "FIRING WATCH" << i.first << ls.size();
i.second(ls);
}
}

2
alethzero/NatspecHandler.cpp

@ -27,7 +27,7 @@
#include <libdevcore/CommonData.h>
#include <libdevcore/Exceptions.h>
#include <libdevcore/Log.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libethereum/Defaults.h>
using namespace dev;

2
eth/main.cpp

@ -29,7 +29,7 @@
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include <libevmcore/Instruction.h>
#include <libdevcore/StructuredLogger.h>
#include <libethcore/ProofOfWork.h>

27
ethminer/MinerAux.h

@ -31,11 +31,11 @@
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include <libevmcore/Instruction.h>
#include <libdevcore/StructuredLogger.h>
#include <libethcore/Exceptions.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/EthashAux.h>
#include <libethcore/Farm.h>
@ -174,6 +174,10 @@ public:
m_minerType = MinerType::GPU;
miningThreads = 1;
}
else if (arg == "--no-precompute")
{
precompute = false;
}
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
{
string m = boost::to_lower_copy(string(argv[++i]));
@ -268,6 +272,7 @@ public:
<< "Work farming mode:" << endl
<< " -F,--farm <url> Put into mining farm mode with the work server at URL (default: http://127.0.0.1:8545)" << endl
<< " --farm-recheck <n> Leave n ms between checks for changed work (default: 500)." << endl
<< " --no-precompute Don't precompute the next epoch's DAG." << endl
#endif
<< "Ethash verify mode:" << endl
<< " -w,--check-pow <headerHash> <seedHash> <difficulty> <nonce> Check PoW credentials for validity." << endl
@ -388,7 +393,7 @@ private:
(void)_m;
(void)_remote;
(void)_recheckPeriod;
#if ETH_JSONRPC || !ETH_TRUE
#if ETH_JSONRPC || !ETH_TRUE
jsonrpc::HttpClient client(_remote);
Farm rpc(client);
@ -399,7 +404,7 @@ private:
f.startGPU();
ProofOfWork::WorkPackage current;
EthashAux::FullType dag;
EthashAux::FullType dag;
while (true)
try
{
@ -418,9 +423,13 @@ private:
cnote << "Getting work package...";
Json::Value v = rpc.eth_getWork();
h256 hh(v[0].asString());
h256 newSeedHash(v[1].asString());
if (!(dag = EthashAux::full(newSeedHash, true)))
BOOST_THROW_EXCEPTION(DAGCreationFailure());
h256 newSeedHash(v[1].asString());
if (current.seedHash != newSeedHash)
cnote << "Grabbing DAG for" << newSeedHash;
if (!(dag = EthashAux::full(newSeedHash, true, [&](unsigned _pc){ cout << "\rCreating DAG. " << _pc << "% done..." << flush; return 0; })))
BOOST_THROW_EXCEPTION(DAGCreationFailure());
if (precompute)
EthashAux::computeFull(sha3(newSeedHash), true);
if (hh != current.headerHash)
{
current.headerHash = hh;
@ -459,7 +468,7 @@ private:
cerr << "JSON-RPC problem. Probably couldn't connect. Retrying in " << i << "... \r";
cerr << endl;
}
#endif
#endif
exit(0);
}
@ -484,5 +493,5 @@ private:
/// Farm params
string farmURL = "http://127.0.0.1:8545";
unsigned farmRecheckPeriod = 500;
bool precompute = true;
};

2
ethminer/main.cpp

@ -27,7 +27,7 @@
#include <signal.h>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/trim_all.hpp>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include "MinerAux.h"
using namespace std;
using namespace dev;

2
evmjit/libevmjit-cpp/Env.cpp

@ -1,6 +1,6 @@
#pragma GCC diagnostic ignored "-Wconversion"
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libevmcore/Params.h>
#include <libevm/ExtVMFace.h>
#include <evmjit/DataTypes.h>

2
evmjit/libevmjit-cpp/JitVM.cpp

@ -4,7 +4,7 @@
#include "JitVM.h"
#include <libdevcore/Log.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libevm/VM.h>
#include <libevm/VMFactory.h>
#include <evmjit/libevmjit/ExecutionEngine.h>

38
exp/main.cpp

@ -34,6 +34,9 @@
#include <functional>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
#include <libdevcore/TrieDB.h>
#include <libdevcore/TrieHash.h>
/*
#include <libdevcore/RangeMask.h>
#include <libdevcore/Log.h>
#include <libdevcore/Common.h>
@ -41,12 +44,11 @@
#include <libdevcore/RLP.h>
#include <libdevcore/TransientDirectory.h>
#include <libdevcore/CommonIO.h>
#include <libdevcrypto/TrieDB.h>
#include <libdevcrypto/SecretStore.h>
#include <libp2p/All.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/Farm.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include <libethereum/All.h>
#include <libethereum/KeyManager.h>
#include <libethereum/AccountDiff.h>
@ -55,17 +57,43 @@
#include <liblll/All.h>
#include <libwhisper/WhisperPeer.h>
#include <libwhisper/WhisperHost.h>
#include <test/JsonSpiritHeaders.h>
#include <test/JsonSpiritHeaders.h>*/
using namespace std;
using namespace dev;
using namespace dev::eth;
/*using namespace dev::eth;
using namespace dev::p2p;
using namespace dev::shh;
namespace js = json_spirit;
namespace fs = boost::filesystem;
*/
#if 1
int main()
{
cdebug << "EXP";
vector<bytes> data;
for (unsigned i = 0; i < 10000; ++i)
data.push_back(rlp(i));
h256 ret;
DEV_TIMED(triedb)
{
MemoryDB mdb;
GenericTrieDB<MemoryDB> t(&mdb);
t.init();
unsigned i = 0;
for (auto const& d: data)
t.insert(rlp(i++), d);
ret = t.root();
}
cdebug << ret;
DEV_TIMED(hash256)
ret = orderedTrieRoot(data);
cdebug << ret;
}
#elif 0
int main()
{
KeyManager keyman;

5
libdevcore/Common.h

@ -86,8 +86,9 @@ extern const u256 UndefinedU256;
// Map types.
using StringMap = std::map<std::string, std::string>;
using BytesMap = std::map<bytes, bytes>;
using u256Map = std::map<u256, u256>;
using HexMap = std::map<bytes, std::string>;
using HexMap = std::map<bytes, bytes>;
// Hash types.
using StringHashMap = std::unordered_map<std::string, std::string>;
@ -200,7 +201,7 @@ private:
#endif
#define DEV_TIMED_ABOVE(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(#S, MS), true); __eth_t.second; __eth_t.second = false)
#define DEV_TIMED_SCOPE_ABOVE(S) ::dev::TimerHelper __eth_t(S, MS)
#define DEV_TIMED_SCOPE_ABOVE(S, MS) ::dev::TimerHelper __eth_t(S, MS)
#if WIN32
#define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__FUNCSIG__, MS)
#else

2
libdevcore/CommonData.cpp

@ -115,7 +115,7 @@ bytes dev::fromHex(std::string const& _s, WhenError _throw)
return ret;
}
bytes dev::asNibbles(std::string const& _s)
bytes dev::asNibbles(bytesConstRef const& _s)
{
std::vector<uint8_t> ret;
ret.reserve(_s.size() * 2);

2
libdevcore/CommonData.h

@ -95,7 +95,7 @@ inline bytes asBytes(std::string const& _b)
/// Converts a string into the big-endian base-16 stream of integers (NOT ASCII).
/// @example asNibbles("A")[0] == 4 && asNibbles("A")[1] == 1
bytes asNibbles(std::string const& _s);
bytes asNibbles(bytesConstRef const& _s);
// Big-endian to/from host endian conversion functions.

4
libdevcrypto/FileSystem.cpp → libdevcore/FileSystem.cpp

@ -22,8 +22,8 @@
*/
#include "FileSystem.h"
#include <libdevcore/Common.h>
#include <libdevcore/Log.h>
#include "Common.h"
#include "Log.h"
#if defined(_WIN32)
#include <shlobj.h>

0
libdevcrypto/FileSystem.h → libdevcore/FileSystem.h

440
libdevcore/Hash.cpp

@ -0,0 +1,440 @@
/*
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 Hash.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "Hash.h"
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "picosha2.h"
using namespace std;
using namespace dev;
namespace dev
{
h256 sha256(bytesConstRef _input)
{
h256 ret;
picosha2::hash256(_input.begin(), _input.end(), ret.data(), ret.data() + 32);
return ret;
}
namespace rmd160
{
/********************************************************************\
*
* FILE: rmd160.h
* FILE: rmd160.c
*
* CONTENTS: Header file for a sample C-implementation of the
* RIPEMD-160 hash-function.
* TARGET: any computer with an ANSI C compiler
*
* AUTHOR: Antoon Bosselaers, ESAT-COSIC
* DATE: 1 March 1996
* VERSION: 1.0
*
* Copyright (c) Katholieke Universiteit Leuven
* 1996, All Rights Reserved
*
\********************************************************************/
// Adapted into "header-only" format by Gav Wood.
/* macro definitions */
#define RMDsize 160
/* collect four bytes into one word: */
#define BYTES_TO_DWORD(strptr) \
(((uint32_t) *((strptr)+3) << 24) | \
((uint32_t) *((strptr)+2) << 16) | \
((uint32_t) *((strptr)+1) << 8) | \
((uint32_t) *(strptr)))
/* ROL(x, n) cyclically rotates x over n bits to the left */
/* x must be of an unsigned 32 bits type and 0 <= n < 32. */
#define ROL(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* the five basic functions F(), G() and H() */
#define F(x, y, z) ((x) ^ (y) ^ (z))
#define G(x, y, z) (((x) & (y)) | (~(x) & (z)))
#define H(x, y, z) (((x) | ~(y)) ^ (z))
#define I(x, y, z) (((x) & (z)) | ((y) & ~(z)))
#define J(x, y, z) ((x) ^ ((y) | ~(z)))
/* the ten basic operations FF() through III() */
#define FF(a, b, c, d, e, x, s) {\
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define GG(a, b, c, d, e, x, s) {\
(a) += G((b), (c), (d)) + (x) + 0x5a827999UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define HH(a, b, c, d, e, x, s) {\
(a) += H((b), (c), (d)) + (x) + 0x6ed9eba1UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define II(a, b, c, d, e, x, s) {\
(a) += I((b), (c), (d)) + (x) + 0x8f1bbcdcUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define JJ(a, b, c, d, e, x, s) {\
(a) += J((b), (c), (d)) + (x) + 0xa953fd4eUL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define FFF(a, b, c, d, e, x, s) {\
(a) += F((b), (c), (d)) + (x);\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define GGG(a, b, c, d, e, x, s) {\
(a) += G((b), (c), (d)) + (x) + 0x7a6d76e9UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define HHH(a, b, c, d, e, x, s) {\
(a) += H((b), (c), (d)) + (x) + 0x6d703ef3UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define III(a, b, c, d, e, x, s) {\
(a) += I((b), (c), (d)) + (x) + 0x5c4dd124UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
#define JJJ(a, b, c, d, e, x, s) {\
(a) += J((b), (c), (d)) + (x) + 0x50a28be6UL;\
(a) = ROL((a), (s)) + (e);\
(c) = ROL((c), 10);\
}
void MDinit(uint32_t *MDbuf)
{
MDbuf[0] = 0x67452301UL;
MDbuf[1] = 0xefcdab89UL;
MDbuf[2] = 0x98badcfeUL;
MDbuf[3] = 0x10325476UL;
MDbuf[4] = 0xc3d2e1f0UL;
return;
}
/********************************************************************/
void MDcompress(uint32_t *MDbuf, uint32_t *X)
{
uint32_t aa = MDbuf[0], bb = MDbuf[1], cc = MDbuf[2],
dd = MDbuf[3], ee = MDbuf[4];
uint32_t aaa = MDbuf[0], bbb = MDbuf[1], ccc = MDbuf[2],
ddd = MDbuf[3], eee = MDbuf[4];
/* round 1 */
FF(aa, bb, cc, dd, ee, X[ 0], 11);
FF(ee, aa, bb, cc, dd, X[ 1], 14);
FF(dd, ee, aa, bb, cc, X[ 2], 15);
FF(cc, dd, ee, aa, bb, X[ 3], 12);
FF(bb, cc, dd, ee, aa, X[ 4], 5);
FF(aa, bb, cc, dd, ee, X[ 5], 8);
FF(ee, aa, bb, cc, dd, X[ 6], 7);
FF(dd, ee, aa, bb, cc, X[ 7], 9);
FF(cc, dd, ee, aa, bb, X[ 8], 11);
FF(bb, cc, dd, ee, aa, X[ 9], 13);
FF(aa, bb, cc, dd, ee, X[10], 14);
FF(ee, aa, bb, cc, dd, X[11], 15);
FF(dd, ee, aa, bb, cc, X[12], 6);
FF(cc, dd, ee, aa, bb, X[13], 7);
FF(bb, cc, dd, ee, aa, X[14], 9);
FF(aa, bb, cc, dd, ee, X[15], 8);
/* round 2 */
GG(ee, aa, bb, cc, dd, X[ 7], 7);
GG(dd, ee, aa, bb, cc, X[ 4], 6);
GG(cc, dd, ee, aa, bb, X[13], 8);
GG(bb, cc, dd, ee, aa, X[ 1], 13);
GG(aa, bb, cc, dd, ee, X[10], 11);
GG(ee, aa, bb, cc, dd, X[ 6], 9);
GG(dd, ee, aa, bb, cc, X[15], 7);
GG(cc, dd, ee, aa, bb, X[ 3], 15);
GG(bb, cc, dd, ee, aa, X[12], 7);
GG(aa, bb, cc, dd, ee, X[ 0], 12);
GG(ee, aa, bb, cc, dd, X[ 9], 15);
GG(dd, ee, aa, bb, cc, X[ 5], 9);
GG(cc, dd, ee, aa, bb, X[ 2], 11);
GG(bb, cc, dd, ee, aa, X[14], 7);
GG(aa, bb, cc, dd, ee, X[11], 13);
GG(ee, aa, bb, cc, dd, X[ 8], 12);
/* round 3 */
HH(dd, ee, aa, bb, cc, X[ 3], 11);
HH(cc, dd, ee, aa, bb, X[10], 13);
HH(bb, cc, dd, ee, aa, X[14], 6);
HH(aa, bb, cc, dd, ee, X[ 4], 7);
HH(ee, aa, bb, cc, dd, X[ 9], 14);
HH(dd, ee, aa, bb, cc, X[15], 9);
HH(cc, dd, ee, aa, bb, X[ 8], 13);
HH(bb, cc, dd, ee, aa, X[ 1], 15);
HH(aa, bb, cc, dd, ee, X[ 2], 14);
HH(ee, aa, bb, cc, dd, X[ 7], 8);
HH(dd, ee, aa, bb, cc, X[ 0], 13);
HH(cc, dd, ee, aa, bb, X[ 6], 6);
HH(bb, cc, dd, ee, aa, X[13], 5);
HH(aa, bb, cc, dd, ee, X[11], 12);
HH(ee, aa, bb, cc, dd, X[ 5], 7);
HH(dd, ee, aa, bb, cc, X[12], 5);
/* round 4 */
II(cc, dd, ee, aa, bb, X[ 1], 11);
II(bb, cc, dd, ee, aa, X[ 9], 12);
II(aa, bb, cc, dd, ee, X[11], 14);
II(ee, aa, bb, cc, dd, X[10], 15);
II(dd, ee, aa, bb, cc, X[ 0], 14);
II(cc, dd, ee, aa, bb, X[ 8], 15);
II(bb, cc, dd, ee, aa, X[12], 9);
II(aa, bb, cc, dd, ee, X[ 4], 8);
II(ee, aa, bb, cc, dd, X[13], 9);
II(dd, ee, aa, bb, cc, X[ 3], 14);
II(cc, dd, ee, aa, bb, X[ 7], 5);
II(bb, cc, dd, ee, aa, X[15], 6);
II(aa, bb, cc, dd, ee, X[14], 8);
II(ee, aa, bb, cc, dd, X[ 5], 6);
II(dd, ee, aa, bb, cc, X[ 6], 5);
II(cc, dd, ee, aa, bb, X[ 2], 12);
/* round 5 */
JJ(bb, cc, dd, ee, aa, X[ 4], 9);
JJ(aa, bb, cc, dd, ee, X[ 0], 15);
JJ(ee, aa, bb, cc, dd, X[ 5], 5);
JJ(dd, ee, aa, bb, cc, X[ 9], 11);
JJ(cc, dd, ee, aa, bb, X[ 7], 6);
JJ(bb, cc, dd, ee, aa, X[12], 8);
JJ(aa, bb, cc, dd, ee, X[ 2], 13);
JJ(ee, aa, bb, cc, dd, X[10], 12);
JJ(dd, ee, aa, bb, cc, X[14], 5);
JJ(cc, dd, ee, aa, bb, X[ 1], 12);
JJ(bb, cc, dd, ee, aa, X[ 3], 13);
JJ(aa, bb, cc, dd, ee, X[ 8], 14);
JJ(ee, aa, bb, cc, dd, X[11], 11);
JJ(dd, ee, aa, bb, cc, X[ 6], 8);
JJ(cc, dd, ee, aa, bb, X[15], 5);
JJ(bb, cc, dd, ee, aa, X[13], 6);
/* parallel round 1 */
JJJ(aaa, bbb, ccc, ddd, eee, X[ 5], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[14], 9);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 7], 9);
JJJ(ccc, ddd, eee, aaa, bbb, X[ 0], 11);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 9], 13);
JJJ(aaa, bbb, ccc, ddd, eee, X[ 2], 15);
JJJ(eee, aaa, bbb, ccc, ddd, X[11], 15);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 4], 5);
JJJ(ccc, ddd, eee, aaa, bbb, X[13], 7);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 6], 7);
JJJ(aaa, bbb, ccc, ddd, eee, X[15], 8);
JJJ(eee, aaa, bbb, ccc, ddd, X[ 8], 11);
JJJ(ddd, eee, aaa, bbb, ccc, X[ 1], 14);
JJJ(ccc, ddd, eee, aaa, bbb, X[10], 14);
JJJ(bbb, ccc, ddd, eee, aaa, X[ 3], 12);
JJJ(aaa, bbb, ccc, ddd, eee, X[12], 6);
/* parallel round 2 */
III(eee, aaa, bbb, ccc, ddd, X[ 6], 9);
III(ddd, eee, aaa, bbb, ccc, X[11], 13);
III(ccc, ddd, eee, aaa, bbb, X[ 3], 15);
III(bbb, ccc, ddd, eee, aaa, X[ 7], 7);
III(aaa, bbb, ccc, ddd, eee, X[ 0], 12);
III(eee, aaa, bbb, ccc, ddd, X[13], 8);
III(ddd, eee, aaa, bbb, ccc, X[ 5], 9);
III(ccc, ddd, eee, aaa, bbb, X[10], 11);
III(bbb, ccc, ddd, eee, aaa, X[14], 7);
III(aaa, bbb, ccc, ddd, eee, X[15], 7);
III(eee, aaa, bbb, ccc, ddd, X[ 8], 12);
III(ddd, eee, aaa, bbb, ccc, X[12], 7);
III(ccc, ddd, eee, aaa, bbb, X[ 4], 6);
III(bbb, ccc, ddd, eee, aaa, X[ 9], 15);
III(aaa, bbb, ccc, ddd, eee, X[ 1], 13);
III(eee, aaa, bbb, ccc, ddd, X[ 2], 11);
/* parallel round 3 */
HHH(ddd, eee, aaa, bbb, ccc, X[15], 9);
HHH(ccc, ddd, eee, aaa, bbb, X[ 5], 7);
HHH(bbb, ccc, ddd, eee, aaa, X[ 1], 15);
HHH(aaa, bbb, ccc, ddd, eee, X[ 3], 11);
HHH(eee, aaa, bbb, ccc, ddd, X[ 7], 8);
HHH(ddd, eee, aaa, bbb, ccc, X[14], 6);
HHH(ccc, ddd, eee, aaa, bbb, X[ 6], 6);
HHH(bbb, ccc, ddd, eee, aaa, X[ 9], 14);
HHH(aaa, bbb, ccc, ddd, eee, X[11], 12);
HHH(eee, aaa, bbb, ccc, ddd, X[ 8], 13);
HHH(ddd, eee, aaa, bbb, ccc, X[12], 5);
HHH(ccc, ddd, eee, aaa, bbb, X[ 2], 14);
HHH(bbb, ccc, ddd, eee, aaa, X[10], 13);
HHH(aaa, bbb, ccc, ddd, eee, X[ 0], 13);
HHH(eee, aaa, bbb, ccc, ddd, X[ 4], 7);
HHH(ddd, eee, aaa, bbb, ccc, X[13], 5);
/* parallel round 4 */
GGG(ccc, ddd, eee, aaa, bbb, X[ 8], 15);
GGG(bbb, ccc, ddd, eee, aaa, X[ 6], 5);
GGG(aaa, bbb, ccc, ddd, eee, X[ 4], 8);
GGG(eee, aaa, bbb, ccc, ddd, X[ 1], 11);
GGG(ddd, eee, aaa, bbb, ccc, X[ 3], 14);
GGG(ccc, ddd, eee, aaa, bbb, X[11], 14);
GGG(bbb, ccc, ddd, eee, aaa, X[15], 6);
GGG(aaa, bbb, ccc, ddd, eee, X[ 0], 14);
GGG(eee, aaa, bbb, ccc, ddd, X[ 5], 6);
GGG(ddd, eee, aaa, bbb, ccc, X[12], 9);
GGG(ccc, ddd, eee, aaa, bbb, X[ 2], 12);
GGG(bbb, ccc, ddd, eee, aaa, X[13], 9);
GGG(aaa, bbb, ccc, ddd, eee, X[ 9], 12);
GGG(eee, aaa, bbb, ccc, ddd, X[ 7], 5);
GGG(ddd, eee, aaa, bbb, ccc, X[10], 15);
GGG(ccc, ddd, eee, aaa, bbb, X[14], 8);
/* parallel round 5 */
FFF(bbb, ccc, ddd, eee, aaa, X[12] , 8);
FFF(aaa, bbb, ccc, ddd, eee, X[15] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[10] , 12);
FFF(ddd, eee, aaa, bbb, ccc, X[ 4] , 9);
FFF(ccc, ddd, eee, aaa, bbb, X[ 1] , 12);
FFF(bbb, ccc, ddd, eee, aaa, X[ 5] , 5);
FFF(aaa, bbb, ccc, ddd, eee, X[ 8] , 14);
FFF(eee, aaa, bbb, ccc, ddd, X[ 7] , 6);
FFF(ddd, eee, aaa, bbb, ccc, X[ 6] , 8);
FFF(ccc, ddd, eee, aaa, bbb, X[ 2] , 13);
FFF(bbb, ccc, ddd, eee, aaa, X[13] , 6);
FFF(aaa, bbb, ccc, ddd, eee, X[14] , 5);
FFF(eee, aaa, bbb, ccc, ddd, X[ 0] , 15);
FFF(ddd, eee, aaa, bbb, ccc, X[ 3] , 13);
FFF(ccc, ddd, eee, aaa, bbb, X[ 9] , 11);
FFF(bbb, ccc, ddd, eee, aaa, X[11] , 11);
/* combine results */
ddd += cc + MDbuf[1]; /* final result for MDbuf[0] */
MDbuf[1] = MDbuf[2] + dd + eee;
MDbuf[2] = MDbuf[3] + ee + aaa;
MDbuf[3] = MDbuf[4] + aa + bbb;
MDbuf[4] = MDbuf[0] + bb + ccc;
MDbuf[0] = ddd;
return;
}
void MDfinish(uint32_t *MDbuf, byte const *strptr, uint32_t lswlen, uint32_t mswlen)
{
unsigned int i; /* counter */
uint32_t X[16]; /* message words */
memset(X, 0, 16*sizeof(uint32_t));
/* put bytes from strptr into X */
for (i=0; i<(lswlen&63); i++) {
/* byte i goes into word X[i div 4] at pos. 8*(i mod 4) */
X[i>>2] ^= (uint32_t) *strptr++ << (8 * (i&3));
}
/* append the bit m_n == 1 */
X[(lswlen>>2)&15] ^= (uint32_t)1 << (8*(lswlen&3) + 7);
if ((lswlen & 63) > 55) {
/* length goes to next block */
MDcompress(MDbuf, X);
memset(X, 0, 16*sizeof(uint32_t));
}
/* append length in bits*/
X[14] = lswlen << 3;
X[15] = (lswlen >> 29) | (mswlen << 3);
MDcompress(MDbuf, X);
return;
}
#undef ROL
#undef F
#undef G
#undef H
#undef I
#undef J
#undef FF
#undef GG
#undef HH
#undef II
#undef JJ
#undef FFF
#undef GGG
#undef HHH
#undef III
#undef JJJ
}
/*
* @returns RMD(_input)
*/
h160 ripemd160(bytesConstRef _input)
{
h160 hashcode;
uint32_t buffer[RMDsize / 32]; // contains (A, B, C, D(, E))
uint32_t current[16]; // current 16-word chunk
// initialize
rmd160::MDinit(buffer);
byte const* message = _input.data();
uint32_t remaining = _input.size(); // # of bytes not yet processed
// process message in 16x 4-byte chunks
for (; remaining >= 64; remaining -= 64)
{
for (unsigned i = 0; i < 16; i++)
{
current[i] = BYTES_TO_DWORD(message);
message += 4;
}
rmd160::MDcompress(buffer, current);
}
// length mod 64 bytes left
// finish:
rmd160::MDfinish(buffer, message, _input.size(), 0);
for (unsigned i = 0; i < RMDsize / 8; i += 4)
{
hashcode[i] = buffer[i >> 2]; // implicit cast to byte
hashcode[i + 1] = (buffer[i >> 2] >> 8); //extracts the 8 least
hashcode[i + 2] = (buffer[i >> 2] >> 16); // significant bits.
hashcode[i + 3] = (buffer[i >> 2] >> 24);
}
return hashcode;
}
#undef BYTES_TO_DWORD
#undef RMDsize
}

38
libdevcore/Hash.h

@ -0,0 +1,38 @@
/*
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 Hash.h
* @author Gav Wood <i@gavwood.com>
* @date 2014
*
* The FixedHash fixed-size "hash" container type.
*/
#pragma once
#include <string>
#include <libdevcore/FixedHash.h>
#include <libdevcore/vector_ref.h>
#include "SHA3.h"
namespace dev
{
h256 sha256(bytesConstRef _input);
h160 ripemd160(bytesConstRef _input);
}

0
libdevcrypto/MemoryDB.cpp → libdevcore/MemoryDB.cpp

0
libdevcrypto/MemoryDB.h → libdevcore/MemoryDB.h

223
libdevcore/SHA3.cpp

@ -0,0 +1,223 @@
/*
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 SHA3.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "SHA3.h"
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <libdevcore/RLP.h>
#include "picosha2.h"
using namespace std;
using namespace dev;
namespace dev
{
h256 EmptySHA3 = sha3(bytesConstRef());
h256 EmptyListSHA3 = sha3(rlpList());
namespace keccak
{
/** libkeccak-tiny
*
* A single-file implementation of SHA-3 and SHAKE.
*
* Implementor: David Leon Gil
* License: CC0, attribution kindly requested. Blame taken too,
* but not liability.
*/
#define decshake(bits) \
int shake##bits(uint8_t*, size_t, const uint8_t*, size_t);
#define decsha3(bits) \
int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t);
decshake(128)
decshake(256)
decsha3(224)
decsha3(256)
decsha3(384)
decsha3(512)
/******** The Keccak-f[1600] permutation ********/
/*** Constants. ***/
static const uint8_t rho[24] = \
{ 1, 3, 6, 10, 15, 21,
28, 36, 45, 55, 2, 14,
27, 41, 56, 8, 25, 43,
62, 18, 39, 61, 20, 44};
static const uint8_t pi[24] = \
{10, 7, 11, 17, 18, 3,
5, 16, 8, 21, 24, 4,
15, 23, 19, 13, 12, 2,
20, 14, 22, 9, 6, 1};
static const uint64_t RC[24] = \
{1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
/*** Helper macros to unroll the permutation. ***/
#define rol(x, s) (((x) << s) | ((x) >> (64 - s)))
#define REPEAT6(e) e e e e e e
#define REPEAT24(e) REPEAT6(e e e e)
#define REPEAT5(e) e e e e e
#define FOR5(v, s, e) \
v = 0; \
REPEAT5(e; v += s;)
/*** Keccak-f[1600] ***/
static inline void keccakf(void* state) {
uint64_t* a = (uint64_t*)state;
uint64_t b[5] = {0};
uint64_t t = 0;
uint8_t x, y;
for (int i = 0; i < 24; i++) {
// Theta
FOR5(x, 1,
b[x] = 0;
FOR5(y, 5,
b[x] ^= a[x + y]; ))
FOR5(x, 1,
FOR5(y, 5,
a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))
// Rho and pi
t = a[1];
x = 0;
REPEAT24(b[0] = a[pi[x]];
a[pi[x]] = rol(t, rho[x]);
t = b[0];
x++; )
// Chi
FOR5(y,
5,
FOR5(x, 1,
b[x] = a[y + x];)
FOR5(x, 1,
a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))
// Iota
a[0] ^= RC[i];
}
}
/******** The FIPS202-defined functions. ********/
/*** Some helper macros. ***/
#define _(S) do { S } while (0)
#define FOR(i, ST, L, S) \
_(for (size_t i = 0; i < L; i += ST) { S; })
#define mkapply_ds(NAME, S) \
static inline void NAME(uint8_t* dst, \
const uint8_t* src, \
size_t len) { \
FOR(i, 1, len, S); \
}
#define mkapply_sd(NAME, S) \
static inline void NAME(const uint8_t* src, \
uint8_t* dst, \
size_t len) { \
FOR(i, 1, len, S); \
}
mkapply_ds(xorin, dst[i] ^= src[i]) // xorin
mkapply_sd(setout, dst[i] = src[i]) // setout
#define P keccakf
#define Plen 200
// Fold P*F over the full blocks of an input.
#define foldP(I, L, F) \
while (L >= rate) { \
F(a, I, rate); \
P(a); \
I += rate; \
L -= rate; \
}
/** The sponge-based hash construction. **/
static inline int hash(uint8_t* out, size_t outlen,
const uint8_t* in, size_t inlen,
size_t rate, uint8_t delim) {
if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
return -1;
}
uint8_t a[Plen] = {0};
// Absorb input.
foldP(in, inlen, xorin);
// Xor in the DS and pad frame.
a[inlen] ^= delim;
a[rate - 1] ^= 0x80;
// Xor in the last block.
xorin(a, in, inlen);
// Apply P
P(a);
// Squeeze output.
foldP(out, outlen, setout);
setout(a, out, outlen);
memset(a, 0, 200);
return 0;
}
/*** Helper macros to define SHA3 and SHAKE instances. ***/
#define defshake(bits) \
int shake##bits(uint8_t* out, size_t outlen, \
const uint8_t* in, size_t inlen) { \
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x1f); \
}
#define defsha3(bits) \
int sha3_##bits(uint8_t* out, size_t outlen, \
const uint8_t* in, size_t inlen) { \
if (outlen > (bits/8)) { \
return -1; \
} \
return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \
}
/*** FIPS202 SHAKE VOFs ***/
defshake(128)
defshake(256)
/*** FIPS202 SHA3 FOFs ***/
defsha3(224)
defsha3(256)
defsha3(384)
defsha3(512)
}
h256 sha3(bytesConstRef _input)
{
// FIXME: What with unaligned memory?
h256 ret;
keccak::sha3_256(ret.data(), 32, _input.data(), _input.size());
// keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size());
return ret;
}
}

37
libdevcrypto/SHA3.h → libdevcore/SHA3.h

@ -32,46 +32,29 @@ namespace dev
// SHA-3 convenience routines.
/// Calculate SHA3-256 hash of the given input and load it into the given output.
void sha3(bytesConstRef _input, bytesRef _output);
/// Calculate SHA3-256 hash of the given input, possibly interpreting it as nibbles, and return the hash as a string filled with binary data.
std::string sha3(std::string const& _input, bool _isNibbles);
/// Calculate SHA3-256 hash of the given input, returning as a byte array.
bytes sha3Bytes(bytesConstRef _input);
/// Calculate SHA3-256 hash of the given input (presented as a binary string), returning as a byte array.
inline bytes sha3Bytes(std::string const& _input) { return sha3Bytes((std::string*)&_input); }
/// Calculate SHA3-256 hash of the given input, returning as a byte array.
inline bytes sha3Bytes(bytes const& _input) { return sha3Bytes((bytes*)&_input); }
/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.
h256 sha3(bytesConstRef _input);
/// Calculate SHA3-256 hash of the given input and load it into the given output.
inline void sha3(bytesConstRef _input, bytesRef _output) { sha3(_input).ref().populate(_output); }
/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.
inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef((bytes*)&_input)); }
inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef(&_input)); }
/// Calculate SHA3-256 hash of the given input (presented as a binary-filled string), returning as a 256-bit hash.
inline h256 sha3(std::string const& _input) { return sha3(bytesConstRef(_input)); }
/// Calculate SHA3-256 MAC
void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output);
/// Calculate SHA3-256 hash of the given input (presented as a FixedHash), returns a 256-bit hash.
template<unsigned N> inline h256 sha3(FixedHash<N> const& _input) { return sha3(_input.ref()); }
extern h256 EmptySHA3;
extern h256 EmptyListSHA3;
// Other crypto convenience routines
/// Calculate SHA3-256 hash of the given input, possibly interpreting it as nibbles, and return the hash as a string filled with binary data.
inline std::string sha3(std::string const& _input, bool _isNibbles) { return asString((_isNibbles ? sha3(fromHex(_input)) : sha3(bytesConstRef(&_input))).asBytes()); }
bytes aesDecrypt(bytesConstRef _cipher, std::string const& _password, unsigned _rounds = 2000, bytesConstRef _salt = bytesConstRef());
/// Calculate SHA3-256 MAC
inline void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output) { sha3(_secret.toBytes() + _plain.toBytes()).ref().populate(_output); }
void sha256(bytesConstRef _input, bytesRef _output);
extern h256 EmptySHA3;
void ripemd160(bytesConstRef _input, bytesRef _output);
extern h256 EmptyListSHA3;
}

0
libdevcrypto/TrieCommon.cpp → libdevcore/TrieCommon.cpp

0
libdevcrypto/TrieCommon.h → libdevcore/TrieCommon.h

0
libdevcrypto/TrieDB.cpp → libdevcore/TrieDB.cpp

3
libdevcrypto/TrieDB.h → libdevcore/TrieDB.h

@ -30,9 +30,8 @@
#include <libdevcore/Common.h>
#include <libdevcore/Log.h>
#include <libdevcore/Exceptions.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "MemoryDB.h"
#include "OverlayDB.h"
#include "TrieCommon.h"
namespace ldb = leveldb;

64
libdevcrypto/TrieHash.cpp → libdevcore/TrieHash.cpp

@ -20,9 +20,9 @@
*/
#include "TrieHash.h"
#include <libdevcrypto/TrieCommon.h>
#include <libdevcrypto/TrieDB.h> // @TODO replace ASAP!
#include <libdevcrypto/SHA3.h>
#include <libdevcore/TrieCommon.h>
#include <libdevcore/TrieDB.h> // @TODO replace ASAP!
#include <libdevcore/SHA3.h>
#include <libethcore/Common.h>
using namespace std;
using namespace dev;
@ -158,74 +158,40 @@ void hash256aux(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_i
}
}
h256 hash256(StringMap const& _s)
{
// build patricia tree.
if (_s.empty())
return sha3(rlp(""));
HexMap hexMap;
for (auto i = _s.rbegin(); i != _s.rend(); ++i)
hexMap[asNibbles(i->first)] = i->second;
RLPStream s;
hash256rlp(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s);
return sha3(s.out());
}
bytes rlp256(StringMap const& _s)
bytes rlp256(BytesMap const& _s)
{
// build patricia tree.
if (_s.empty())
return rlp("");
HexMap hexMap;
for (auto i = _s.rbegin(); i != _s.rend(); ++i)
hexMap[asNibbles(i->first)] = i->second;
hexMap[asNibbles(bytesConstRef(&i->first))] = i->second;
RLPStream s;
hash256aux(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s);
hash256rlp(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s);
return s.out();
}
h256 hash256(u256Map const& _s)
h256 hash256(BytesMap const& _s)
{
// build patricia tree.
if (_s.empty())
return sha3(rlp(""));
HexMap hexMap;
for (auto i = _s.rbegin(); i != _s.rend(); ++i)
hexMap[asNibbles(toBigEndianString(i->first))] = asString(rlp(i->second));
RLPStream s;
hash256rlp(hexMap, hexMap.cbegin(), hexMap.cend(), 0, s);
return sha3(s.out());
return sha3(rlp256(_s));
}
/*h256 orderedTrieRoot(std::vector<bytes> const& _data)
h256 orderedTrieRoot(std::vector<bytes> const& _data)
{
StringMap m;
BytesMap m;
unsigned j = 0;
for (auto i: _data)
m[asString(rlp(j++))] = asString(i);
m[rlp(j++)] = i;
return hash256(m);
}*/
h256 orderedTrieRoot(std::vector<bytesConstRef> const& _data)
{
MemoryDB db;
GenericTrieDB<MemoryDB> t(&db);
t.init();
unsigned j = 0;
for (auto i: _data)
t.insert(rlp(j++), i.toBytes());
return t.root();
}
h256 orderedTrieRoot(std::vector<bytes> const& _data)
h256 orderedTrieRoot(std::vector<bytesConstRef> const& _data)
{
MemoryDB db;
GenericTrieDB<MemoryDB> t(&db);
t.init();
BytesMap m;
unsigned j = 0;
for (auto i: _data)
t.insert(rlp(j++), i);
return t.root();
m[rlp(j++)] = i.toBytes();
return hash256(m);
}
}

15
libdevcrypto/TrieHash.h → libdevcore/TrieHash.h

@ -27,21 +27,18 @@
namespace dev
{
bytes rlp256(StringMap const& _s);
h256 hash256(StringMap const& _s);
h256 hash256(u256Map const& _s);
bytes rlp256(BytesMap const& _s);
h256 hash256(BytesMap const& _s);
/*h256 orderedTrieRoot(std::vector<bytes> const& _data);
h256 orderedTrieRoot(std::vector<bytes> const& _data);
template <class T, class U> inline h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue)
{
StringMap m;
BytesMap m;
for (unsigned i = 0; i < _itemCount; ++i)
m[asString(_getKey(i))] = asString(_getValue(i));
m[_getKey(i)] = _getValue(i);
return hash256(m);
}*/
using bytesMap = std::unordered_map<bytes, bytes>;
}
h256 orderedTrieRoot(std::vector<bytesConstRef> const& _data);
h256 orderedTrieRoot(std::vector<bytes> const& _data);

360
libdevcore/picosha2.h

@ -0,0 +1,360 @@
/*
The MIT License (MIT)
Copyright (C) 2014 okdshin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
*/
#ifndef PICOSHA2_H
#define PICOSHA2_H
//picosha2:20140213
#include <cstdint>
#include <iostream>
#include <vector>
#include <iterator>
#include <cassert>
#include <sstream>
#include <algorithm>
namespace picosha2
{
namespace detail
{
inline uint8_t mask_8bit(uint8_t x){
return x&0xff;
}
inline uint32_t mask_32bit(uint32_t x){
return x&0xffffffff;
}
static const uint32_t add_constant[64] = {
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
};
static const uint32_t initial_message_digest[8] = {
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
};
inline uint32_t ch(uint32_t x, uint32_t y, uint32_t z){
return (x&y)^((~x)&z);
}
inline uint32_t maj(uint32_t x, uint32_t y, uint32_t z){
return (x&y)^(x&z)^(y&z);
}
inline uint32_t rotr(uint32_t x, std::size_t n){
assert(n < 32);
return mask_32bit((x>>n)|(x<<(32-n)));
}
inline uint32_t bsig0(uint32_t x){
return rotr(x, 2)^rotr(x, 13)^rotr(x, 22);
}
inline uint32_t bsig1(uint32_t x){
return rotr(x, 6)^rotr(x, 11)^rotr(x, 25);
}
inline uint32_t shr(uint32_t x, std::size_t n){
assert(n < 32);
return x >> n;
}
inline uint32_t ssig0(uint32_t x){
return rotr(x, 7)^rotr(x, 18)^shr(x, 3);
}
inline uint32_t ssig1(uint32_t x){
return rotr(x, 17)^rotr(x, 19)^shr(x, 10);
}
template<typename RaIter1, typename RaIter2>
void hash256_block(RaIter1 message_digest, RaIter2 first, RaIter2 last){
(void)last; // FIXME: check this is valid
uint32_t w[64];
std::fill(w, w+64, 0);
for(std::size_t i = 0; i < 16; ++i){
w[i] = (static_cast<uint32_t>(mask_8bit(*(first+i*4)))<<24)
|(static_cast<uint32_t>(mask_8bit(*(first+i*4+1)))<<16)
|(static_cast<uint32_t>(mask_8bit(*(first+i*4+2)))<<8)
|(static_cast<uint32_t>(mask_8bit(*(first+i*4+3))));
}
for(std::size_t i = 16; i < 64; ++i){
w[i] = mask_32bit(ssig1(w[i-2])+w[i-7]+ssig0(w[i-15])+w[i-16]);
}
uint32_t a = *message_digest;
uint32_t b = *(message_digest+1);
uint32_t c = *(message_digest+2);
uint32_t d = *(message_digest+3);
uint32_t e = *(message_digest+4);
uint32_t f = *(message_digest+5);
uint32_t g = *(message_digest+6);
uint32_t h = *(message_digest+7);
for(std::size_t i = 0; i < 64; ++i){
uint32_t temp1 = h+bsig1(e)+ch(e,f,g)+add_constant[i]+w[i];
uint32_t temp2 = bsig0(a)+maj(a,b,c);
h = g;
g = f;
f = e;
e = mask_32bit(d+temp1);
d = c;
c = b;
b = a;
a = mask_32bit(temp1+temp2);
}
*message_digest += a;
*(message_digest+1) += b;
*(message_digest+2) += c;
*(message_digest+3) += d;
*(message_digest+4) += e;
*(message_digest+5) += f;
*(message_digest+6) += g;
*(message_digest+7) += h;
for(std::size_t i = 0; i < 8; ++i){
*(message_digest+i) = mask_32bit(*(message_digest+i));
}
}
}//namespace detail
template<typename InIter>
void output_hex(InIter first, InIter last, std::ostream& os){
os.setf(std::ios::hex, std::ios::basefield);
while(first != last){
os.width(2);
os.fill('0');
os << static_cast<unsigned int>(*first);
++first;
}
os.setf(std::ios::dec, std::ios::basefield);
}
template<typename InIter>
void bytes_to_hex_string(InIter first, InIter last, std::string& hex_str){
std::ostringstream oss;
output_hex(first, last, oss);
hex_str.assign(oss.str());
}
template<typename InContainer>
void bytes_to_hex_string(const InContainer& bytes, std::string& hex_str){
bytes_to_hex_string(bytes.begin(), bytes.end(), hex_str);
}
template<typename InIter>
std::string bytes_to_hex_string(InIter first, InIter last){
std::string hex_str;
bytes_to_hex_string(first, last, hex_str);
return hex_str;
}
template<typename InContainer>
std::string bytes_to_hex_string(const InContainer& bytes){
std::string hex_str;
bytes_to_hex_string(bytes, hex_str);
return hex_str;
}
class hash256_one_by_one {
public:
hash256_one_by_one(){
init();
}
void init(){
buffer_.clear();
std::fill(data_length_digits_, data_length_digits_+4, 0);
std::copy(detail::initial_message_digest, detail::initial_message_digest+8, h_);
}
template<typename RaIter>
void process(RaIter first, RaIter last){
add_to_data_length(std::distance(first, last));
std::copy(first, last, std::back_inserter(buffer_));
std::size_t i = 0;
for(;i+64 <= buffer_.size(); i+=64){
detail::hash256_block(h_, buffer_.begin()+i, buffer_.begin()+i+64);
}
buffer_.erase(buffer_.begin(), buffer_.begin()+i);
}
void finish(){
uint8_t temp[64];
std::fill(temp, temp+64, 0);
std::size_t remains = buffer_.size();
std::copy(buffer_.begin(), buffer_.end(), temp);
temp[remains] = 0x80;
if(remains > 55){
std::fill(temp+remains+1, temp+64, 0);
detail::hash256_block(h_, temp, temp+64);
std::fill(temp, temp+64-4, 0);
}
else {
std::fill(temp+remains+1, temp+64-4, 0);
}
write_data_bit_length(&(temp[56]));
detail::hash256_block(h_, temp, temp+64);
}
template<typename OutIter>
void get_hash_bytes(OutIter first, OutIter last)const{
for(const uint32_t* iter = h_; iter != h_+8; ++iter){
for(std::size_t i = 0; i < 4 && first != last; ++i){
*(first++) = detail::mask_8bit(static_cast<uint8_t>((*iter >> (24-8*i))));
}
}
}
private:
void add_to_data_length(uint32_t n) {
uint32_t carry = 0;
data_length_digits_[0] += n;
for(std::size_t i = 0; i < 4; ++i) {
data_length_digits_[i] += carry;
if(data_length_digits_[i] >= 65536u) {
data_length_digits_[i] -= 65536u;
carry = 1;
}
else {
break;
}
}
}
void write_data_bit_length(uint8_t* begin) {
uint32_t data_bit_length_digits[4];
std::copy(
data_length_digits_, data_length_digits_+4,
data_bit_length_digits
);
// convert byte length to bit length (multiply 8 or shift 3 times left)
uint32_t carry = 0;
for(std::size_t i = 0; i < 4; ++i) {
uint32_t before_val = data_bit_length_digits[i];
data_bit_length_digits[i] <<= 3;
data_bit_length_digits[i] |= carry;
data_bit_length_digits[i] &= 65535u;
carry = (before_val >> (16-3)) & 65535u;
}
// write data_bit_length
for(int i = 3; i >= 0; --i) {
(*begin++) = static_cast<uint8_t>(data_bit_length_digits[i] >> 8);
(*begin++) = static_cast<uint8_t>(data_bit_length_digits[i]);
}
}
std::vector<uint8_t> buffer_;
uint32_t data_length_digits_[4]; //as 64bit integer (16bit x 4 integer)
uint32_t h_[8];
};
inline void get_hash_hex_string(const hash256_one_by_one& hasher, std::string& hex_str){
uint8_t hash[32];
hasher.get_hash_bytes(hash, hash+32);
return bytes_to_hex_string(hash, hash+32, hex_str);
}
inline std::string get_hash_hex_string(const hash256_one_by_one& hasher){
std::string hex_str;
get_hash_hex_string(hasher, hex_str);
return hex_str;
}
template<typename RaIter, typename OutIter>
void hash256(RaIter first, RaIter last, OutIter first2, OutIter last2){
hash256_one_by_one hasher;
//hasher.init();
hasher.process(first, last);
hasher.finish();
hasher.get_hash_bytes(first2, last2);
}
template<typename RaIter, typename OutContainer>
void hash256(RaIter first, RaIter last, OutContainer& dst){
hash256(first, last, dst.begin(), dst.end());
}
template<typename RaContainer, typename OutIter>
void hash256(const RaContainer& src, OutIter first, OutIter last){
hash256(src.begin(), src.end(), first, last);
}
template<typename RaContainer, typename OutContainer>
void hash256(const RaContainer& src, OutContainer& dst){
hash256(src.begin(), src.end(), dst.begin(), dst.end());
}
template<typename RaIter>
void hash256_hex_string(RaIter first, RaIter last, std::string& hex_str){
uint8_t hashed[32];
hash256(first, last, hashed, hashed+32);
std::ostringstream oss;
output_hex(hashed, hashed+32, oss);
hex_str.assign(oss.str());
}
template<typename RaIter>
std::string hash256_hex_string(RaIter first, RaIter last){
std::string hex_str;
hash256_hex_string(first, last, hex_str);
return hex_str;
}
inline void hash256_hex_string(const std::string& src, std::string& hex_str){
hash256_hex_string(src.begin(), src.end(), hex_str);
}
template<typename RaContainer>
void hash256_hex_string(const RaContainer& src, std::string& hex_str){
hash256_hex_string(src.begin(), src.end(), hex_str);
}
template<typename RaContainer>
std::string hash256_hex_string(const RaContainer& src){
return hash256_hex_string(src.begin(), src.end());
}
}//namespace picosha2
#endif //PICOSHA2_H

32
libdevcrypto/AES.cpp

@ -19,9 +19,9 @@
* @date 2014
*/
#include "CryptoPP.h"
#include "AES.h"
#include <libdevcore/Common.h>
#include "CryptoPP.h"
using namespace std;
using namespace dev;
using namespace dev::crypto;
@ -58,3 +58,31 @@ size_t Stream::streamOut(bytes&)
return 0;
}
bytes dev::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();
}
}

5
libdevcrypto/AES.h

@ -86,4 +86,7 @@ private:
}
}
}
bytes aesDecrypt(bytesConstRef _cipher, std::string const& _password, unsigned _rounds = 2000, bytesConstRef _salt = bytesConstRef());
}

5
libdevcrypto/Common.cpp

@ -26,8 +26,9 @@
#include <thread>
#include <mutex>
#include <libdevcore/Guards.h>
#include "SHA3.h"
#include "FileSystem.h"
#include <libdevcore/SHA3.h>
#include <libdevcore/FileSystem.h>
#include "AES.h"
#include "CryptoPP.h"
using namespace std;
using namespace dev;

2
libdevcrypto/CryptoPP.h

@ -49,7 +49,7 @@
#include <cryptopp/dsa.h>
#pragma warning(pop)
#pragma GCC diagnostic pop
#include "SHA3.h"
#include <libdevcore/SHA3.h>
#include "Common.h"
namespace dev

4
libdevcrypto/ECDHE.cpp

@ -19,9 +19,9 @@
* @date 2014
*/
#include "SHA3.h"
#include "CryptoPP.h"
#include "ECDHE.h"
#include <libdevcore/SHA3.h>
#include "CryptoPP.h"
using namespace std;
using namespace dev;

2
libdevcrypto/OverlayDB.h

@ -29,7 +29,7 @@
#include <memory>
#include <libdevcore/Common.h>
#include <libdevcore/Log.h>
#include "MemoryDB.h"
#include <libdevcore/MemoryDB.h>
namespace ldb = leveldb;
namespace dev

129
libdevcrypto/SHA3.cpp

@ -1,129 +0,0 @@
/*
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 SHA3.cpp
* @author Gav Wood <i@gavwood.com>
* @date 2014
*/
#include "SHA3.h"
#include <libdevcore/RLP.h>
#include "CryptoPP.h"
using namespace std;
using namespace dev;
namespace dev
{
h256 EmptySHA3 = sha3(bytesConstRef());
h256 EmptyListSHA3 = sha3(rlpList());
std::string sha3(std::string const& _input, bool _hex)
{
if (!_hex)
{
string ret(32, '\0');
sha3(bytesConstRef((byte const*)_input.data(), _input.size()), bytesRef((byte*)ret.data(), 32));
return ret;
}
uint8_t buf[32];
sha3(bytesConstRef((byte const*)_input.data(), _input.size()), bytesRef((byte*)&(buf[0]), 32));
std::string ret(64, '\0');
for (unsigned int i = 0; i < 32; i++)
sprintf((char*)(ret.data())+i*2, "%02x", buf[i]);
return ret;
}
void sha3(bytesConstRef _input, bytesRef _output)
{
CryptoPP::SHA3_256 ctx;
ctx.Update((byte*)_input.data(), _input.size());
assert(_output.size() >= 32);
ctx.Final(_output.data());
}
void ripemd160(bytesConstRef _input, bytesRef _output)
{
CryptoPP::RIPEMD160 ctx;
ctx.Update((byte*)_input.data(), _input.size());
assert(_output.size() >= 32);
ctx.Final(_output.data());
}
void sha256(bytesConstRef _input, bytesRef _output)
{
CryptoPP::SHA256 ctx;
ctx.Update((byte*)_input.data(), _input.size());
assert(_output.size() >= 32);
ctx.Final(_output.data());
}
bytes sha3Bytes(bytesConstRef _input)
{
bytes ret(32);
sha3(_input, &ret);
return ret;
}
h256 sha3(bytesConstRef _input)
{
h256 ret;
sha3(_input, bytesRef(&ret[0], 32));
return ret;
}
void sha3mac(bytesConstRef _secret, bytesConstRef _plain, bytesRef _output)
{
CryptoPP::SHA3_256 ctx;
assert(_secret.size() > 0);
ctx.Update((byte*)_secret.data(), _secret.size());
ctx.Update((byte*)_plain.data(), _plain.size());
assert(_output.size() >= 32);
ctx.Final(_output.data());
}
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();
}
}
}

4
libdevcrypto/SecretStore.cpp

@ -25,9 +25,9 @@
#include <boost/filesystem.hpp>
#include <libdevcore/Log.h>
#include <libdevcore/Guards.h>
#include <libdevcore/SHA3.h>
#include <libdevcore/FileSystem.h>
#include <test/JsonSpiritHeaders.h>
#include "SHA3.h"
#include "FileSystem.h"
using namespace std;
using namespace dev;
namespace js = json_spirit;

2
libdevcrypto/SecretStore.h

@ -24,8 +24,8 @@
#include <functional>
#include <mutex>
#include <libdevcore/FixedHash.h>
#include <libdevcore/FileSystem.h>
#include "Common.h"
#include "FileSystem.h"
namespace dev
{

15
libethash-cl/ethash_cl_miner.cpp

@ -206,14 +206,15 @@ bool ethash_cl_miner::init(uint8_t const* _dag, uint64_t _dagSize, unsigned work
m_header = cl::Buffer(m_context, CL_MEM_READ_ONLY, 32);
// compute dag on CPU
{
try {
m_queue.enqueueWriteBuffer(m_dag, CL_TRUE, 0, _dagSize, _dag);
// if this throws then it's because we probably need to subdivide the dag uploads for compatibility
// void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, _dagSize);
// memcpying 1GB: horrible... really. horrible. but necessary since we can't mmap *and* gpumap.
// _fillDAG(dag_ptr);
// m_queue.enqueueUnmapMemObject(m_dag, dag_ptr);
}
catch (...)
{
// didn't work. shitty driver. try allocating in CPU RAM and manually memcpying it.
void* dag_ptr = m_queue.enqueueMapBuffer(m_dag, true, m_opencl_1_1 ? CL_MAP_WRITE : CL_MAP_WRITE_INVALIDATE_REGION, 0, _dagSize);
memcpy(dag_ptr, _dag, _dagSize);
m_queue.enqueueUnmapMemObject(m_dag, dag_ptr);
}
// create mining buffers

2
libethcore/ABI.h

@ -24,7 +24,7 @@
#include <libdevcore/Common.h>
#include <libdevcore/FixedHash.h>
#include <libdevcore/CommonData.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
namespace dev
{

16
libethcore/BlockInfo.cpp

@ -21,8 +21,8 @@
#include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/TrieDB.h>
#include <libdevcrypto/TrieHash.h>
#include <libdevcore/TrieDB.h>
#include <libdevcore/TrieHash.h>
#include <libethcore/Common.h>
#include <libethcore/Params.h>
#include "EthashAux.h"
@ -191,22 +191,12 @@ void BlockInfo::populate(bytesConstRef _block, Strictness _s, h256 const& _h)
struct BlockInfoDiagnosticsChannel: public LogChannel { static const char* name() { return EthBlue "" EthWhite ""; } static const int verbosity = 9; };
template <class T, class U> h256 trieRootOver(unsigned _itemCount, T const& _getKey, U const& _getValue)
{
MemoryDB db;
GenericTrieDB<MemoryDB> t(&db);
t.init();
for (unsigned i = 0; i < _itemCount; ++i)
t.insert(_getKey(i), _getValue(i));
return t.root();
}
void BlockInfo::verifyInternals(bytesConstRef _block) const
{
RLP root(_block);
auto txList = root[1];
auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i){ return rlp(i); }, [&](unsigned i){ return txList[i].data(); });
auto expectedRoot = trieRootOver(txList.itemCount(), [&](unsigned i){ return rlp(i); }, [&](unsigned i){ return txList[i].data().toBytes(); });
clog(BlockInfoDiagnosticsChannel) << "Expected trie root:" << toString(expectedRoot);
if (transactionsRoot != expectedRoot)

2
libethcore/Common.cpp

@ -23,7 +23,7 @@
#include <random>
#include <boost/algorithm/string/case_conv.hpp>
#include <libdevcore/Base64.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "Exceptions.h"
#include "ProofOfWork.h"
using namespace std;

14
libethcore/Ethash.cpp

@ -34,7 +34,7 @@
#include <libdevcore/Common.h>
#include <libdevcore/CommonIO.h>
#include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include <libethash/ethash.h>
#include <libethash/internal.h>
#if ETH_ETHASHCL || !ETH_TRUE
@ -75,6 +75,13 @@ Ethash::WorkPackage Ethash::package(BlockInfo const& _bi)
return ret;
}
void Ethash::ensurePrecomputed(unsigned _number)
{
if (_number % ETHASH_EPOCH_LENGTH > ETHASH_EPOCH_LENGTH * 9 / 10)
// 90% of the way to the new epoch
EthashAux::computeFull(EthashAux::seedHash(_number + ETHASH_EPOCH_LENGTH), true);
}
void Ethash::prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f)
{
EthashAux::full(_header.seedHash(), true, _f);
@ -306,6 +313,7 @@ void Ethash::GPUMiner::workLoop()
cnote << "workLoop" << !!m_miner << m_minerSeed << w.seedHash;
if (!m_miner || m_minerSeed != w.seedHash)
{
cnote << "Initialising miner...";
m_minerSeed = w.seedHash;
delete m_miner;
@ -333,9 +341,9 @@ void Ethash::GPUMiner::workLoop()
uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192);
m_miner->search(w.headerHash.data(), upper64OfBoundary, *m_hook);
}
catch (...)
catch (cl::Error const& _e)
{
cwarn << "Error GPU mining. GPU memory fragmentation?";
cwarn << "Error GPU mining: " << _e.what() << "(" << _e.err() << ")";
}
}

1
libethcore/Ethash.h

@ -74,6 +74,7 @@ public:
static std::string name();
static unsigned revision();
static void prep(BlockInfo const& _header, std::function<int(unsigned)> const& _f = std::function<int(unsigned)>());
static void ensurePrecomputed(unsigned _number);
static bool verify(BlockInfo const& _header);
static bool preVerify(BlockInfo const& _header);
static WorkPackage package(BlockInfo const& _header);

10
libethcore/EthashAux.cpp

@ -31,8 +31,8 @@
#include <libdevcore/Guards.h>
#include <libdevcore/Log.h>
#include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/SHA3.h>
#include <libdevcore/FileSystem.h>
#include <libethash/internal.h>
#include "BlockInfo.h"
#include "Exceptions.h"
@ -167,7 +167,7 @@ EthashAux::FullType EthashAux::full(h256 const& _seedHash, bool _createIfMissing
return ret;
}
if (_createIfMissing || computeFull(_seedHash) == 100)
if (_createIfMissing || computeFull(_seedHash, false) == 100)
{
s_dagCallback = _f;
cnote << "Loading from libethash...";
@ -183,7 +183,7 @@ EthashAux::FullType EthashAux::full(h256 const& _seedHash, bool _createIfMissing
#define DEV_IF_THROWS(X) try { X; } catch (...)
unsigned EthashAux::computeFull(h256 const& _seedHash)
unsigned EthashAux::computeFull(h256 const& _seedHash, bool _createIfMissing)
{
Guard l(get()->x_fulls);
uint64_t blockNumber;
@ -199,7 +199,7 @@ unsigned EthashAux::computeFull(h256 const& _seedHash)
return 100;
}
if (!get()->m_fullGenerator || !get()->m_fullGenerator->joinable())
if (_createIfMissing && (!get()->m_fullGenerator || !get()->m_fullGenerator->joinable()))
{
get()->m_fullProgress = 0;
get()->m_generatingFullNumber = blockNumber / ETHASH_EPOCH_LENGTH * ETHASH_EPOCH_LENGTH;

2
libethcore/EthashAux.h

@ -71,7 +71,7 @@ public:
static const uint64_t NotGenerating = (uint64_t)-1;
/// Kicks off generation of DAG for @a _seedHash and @returns false or @returns true if ready.
static unsigned computeFull(h256 const& _seedHash);
static unsigned computeFull(h256 const& _seedHash, bool _createIfMissing = true);
/// Information on the generation progress.
static std::pair<uint64_t, unsigned> fullGeneratingProgress() { return std::make_pair(get()->m_generatingFullNumber, get()->m_fullProgress); }
/// Kicks off generation of DAG for @a _blocknumber and blocks until ready; @returns result or empty pointer if not existing and _createIfMissing is false.

2
libethcore/ICAP.cpp

@ -23,7 +23,7 @@
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/algorithm/string.hpp>
#include <libdevcore/Base64.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "Exceptions.h"
#include "ABI.h"
using namespace std;

10
libethcore/Miner.h

@ -107,12 +107,10 @@ public:
}
if (!!_work)
{
boost::timer t;
pause();
cdebug << "pause took" << t.elapsed();
t.restart();
kickOff();
cdebug << "kickOff took" << t.elapsed();
DEV_TIMED_ABOVE(pause, 250)
pause();
DEV_TIMED_ABOVE(kickOff, 250)
kickOff();
}
else if (!_work && !!old)
pause();

4
libethereum/Account.h

@ -23,8 +23,8 @@
#include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/TrieDB.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/TrieDB.h>
#include <libdevcore/SHA3.h>
namespace dev
{

8
libethereum/BlockChain.cpp

@ -33,7 +33,7 @@
#include <libdevcore/Assertions.h>
#include <libdevcore/RLP.h>
#include <libdevcore/StructuredLogger.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include <libethcore/Exceptions.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/BlockInfo.h>
@ -96,7 +96,7 @@ ldb::Slice dev::eth::toSlice(h256 const& _h, unsigned _sub)
#endif
}
#if ETH_DEBUG
#if ETH_DEBUG&&0
static const chrono::system_clock::duration c_collectionDuration = chrono::seconds(15);
static const unsigned c_collectionQueueSize = 2;
static const unsigned c_maxCacheSize = 1024 * 1024 * 1;
@ -318,7 +318,9 @@ tuple<h256s, h256s, bool> BlockChain::sync(BlockQueue& _bq, OverlayDB const& _st
try
{
// Nonce & uncle nonces already verified thread at this point.
auto r = import(block.first, block.second, _stateDB, ImportRequirements::Default & ~ImportRequirements::ValidNonce & ~ImportRequirements::CheckUncles);
ImportRoute r;
DEV_TIMED_ABOVE(Block import, 500)
r = import(block.first, block.second, _stateDB, ImportRequirements::Default & ~ImportRequirements::ValidNonce & ~ImportRequirements::CheckUncles);
fresh += r.first;
dead += r.second;
}

2
libethereum/BlockQueue.h

@ -94,7 +94,7 @@ public:
void retryAllUnknown();
/// Get information on the items queued.
std::pair<unsigned, unsigned> items() const { ReadGuard l(m_lock); return std::make_pair(m_verified.size(), m_unknown.size()); }
std::pair<unsigned, unsigned> items() const { ReadGuard l(m_lock); return std::make_pair(m_readySet.size(), m_unknownSet.size()); }
/// Clear everything.
void clear() { WriteGuard l(m_lock); DEV_INVARIANT_CHECK; Guard l2(m_verification); m_readySet.clear(); m_drainingSet.clear(); m_verified.clear(); m_unverified.clear(); m_unknownSet.clear(); m_unknown.clear(); m_future.clear(); }

7
libethereum/CachedAddressState.cpp

@ -21,8 +21,9 @@
#include "CachedAddressState.h"
#include <libdevcore/TrieDB.h>
#include <libdevcrypto/Common.h>
#include <libdevcrypto/TrieDB.h>
#include <libdevcrypto/OverlayDB.h>
#include "Account.h"
using namespace std;
using namespace dev;
@ -57,8 +58,8 @@ std::unordered_map<u256, u256> CachedAddressState::storage() const
if (m_r)
{
SecureTrieDB<h256, OverlayDB> memdb(const_cast<OverlayDB*>(m_o), m_r[2].toHash<h256>()); // promise we won't alter the overlay! :)
// for (auto const& j: memdb)
// ret[j.first] = RLP(j.second).toInt<u256>();
for (auto const& j: memdb)
ret[j.first] = RLP(j.second).toInt<u256>();
}
if (m_s)
for (auto const& j: m_s->storageOverlay())

2
libethereum/CanonBlockChain.cpp

@ -25,7 +25,7 @@
#include <boost/filesystem.hpp>
#include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include <libethcore/Exceptions.h>
#include <libethcore/ProofOfWork.h>
#include <libethcore/BlockInfo.h>

20
libethereum/Client.cpp

@ -172,6 +172,7 @@ Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _for
m_preMine(m_stateDB, BaseState::CanonGenesis),
m_postMine(m_stateDB)
{
m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30);
m_tqReady = m_tq.onReady([=](){ this->onTransactionQueueReady(); }); // TODO: should read m_tq->onReady(thisThread, syncTransactionQueue);
m_bqReady = m_bq.onReady([=](){ this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue);
m_farm.onSolutionFound([=](ProofOfWork::Solution const& s){ return this->submitWork(s); });
@ -197,6 +198,7 @@ Client::Client(p2p::Host* _extNet, std::shared_ptr<GasPricer> _gp, std::string c
m_preMine(m_stateDB),
m_postMine(m_stateDB)
{
m_lastGetWork = std::chrono::system_clock::now() - chrono::seconds(30);
m_tqReady = m_tq.onReady([=](){ this->onTransactionQueueReady(); }); // TODO: should read m_tq->onReady(thisThread, syncTransactionQueue);
m_bqReady = m_bq.onReady([=](){ this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue);
m_farm.onSolutionFound([=](ProofOfWork::Solution const& s){ return this->submitWork(s); });
@ -453,8 +455,15 @@ ProofOfWork::WorkPackage Client::getWork()
{
// lock the work so a later submission isn't invalidated by processing a transaction elsewhere.
// this will be reset as soon as a new block arrives, allowing more transactions to be processed.
bool oldShould = shouldServeWork();
m_lastGetWork = chrono::system_clock::now();
m_remoteWorking = true;
// if this request has made us bother to serve work, prep it now.
if (!oldShould && shouldServeWork())
onPostStateChanged();
else
// otherwise, set this to true so that it gets prepped next time.
m_remoteWorking = true;
return ProofOfWork::package(m_miningInfo);
}
@ -484,7 +493,7 @@ void Client::syncBlockQueue()
cwork << "BQ ==> CHAIN ==> STATE";
{
tie(ir.first, ir.second, m_syncBlockQueue) = m_bc.sync(m_bq, m_stateDB, 10);
tie(ir.first, ir.second, m_syncBlockQueue) = m_bc.sync(m_bq, m_stateDB, rand() % 90 + 10);
if (ir.first.empty())
return;
}
@ -607,7 +616,8 @@ bool Client::remoteActive() const
void Client::onPostStateChanged()
{
cnote << "Post state changed";
if (isMining() || remoteActive())
if (m_bq.items().first == 0 && (isMining() || remoteActive()))
{
cnote << "Restarting mining...";
DEV_WRITE_GUARDED(x_working)
@ -619,6 +629,8 @@ void Client::onPostStateChanged()
m_miningInfo = m_postMine.info();
}
m_farm.setWork(m_miningInfo);
Ethash::ensurePrecomputed(m_bc.number());
}
m_remoteWorking = false;
}
@ -636,7 +648,7 @@ void Client::noteChanged(h256Hash const& _filters)
{
Guard l(x_filtersWatches);
if (_filters.size())
filtersStreamOut(cnote << "noteChanged:", _filters);
filtersStreamOut(cwatch << "noteChanged:", _filters);
// accrue all changes left in each filter into the watches.
for (auto& w: m_watches)
if (_filters.count(w.second.id))

5
libethereum/Client.h

@ -274,6 +274,9 @@ private:
/// Ticks various system-level objects.
void tick();
/// @returns true only if it's worth bothering to prep the mining block.
bool shouldServeWork() const { return m_bq.items().first == 0 && (isMining() || remoteActive()); }
VersionChecker m_vc; ///< Dummy object to check & update the protocol version.
CanonBlockChain m_bc; ///< Maintains block database.
BlockQueue m_bq; ///< Maintains a list of incoming blocks not yet on the blockchain (to be imported).
@ -289,7 +292,7 @@ private:
BlockInfo m_miningInfo; ///< The header we're attempting to mine on (derived from m_postMine).
bool remoteActive() const; ///< Is there an active and valid remote worker?
bool m_remoteWorking = false; ///< Has the remote worker recently been reset?
std::chrono::system_clock::time_point m_lastGetWork = std::chrono::system_clock::time_point::min(); ///< Is there an active and valid remote worker?
std::chrono::system_clock::time_point m_lastGetWork; ///< Is there an active and valid remote worker?
std::weak_ptr<EthereumHost> m_host; ///< Our Ethereum Host. Don't do anything if we can't lock.

2
libethereum/Defaults.cpp

@ -21,7 +21,7 @@
#include "Defaults.h"
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
using namespace std;
using namespace dev;
using namespace dev::eth;

36
libethereum/Executive.cpp

@ -159,6 +159,42 @@ bool Executive::call(Address _receiveAddress, Address _codeAddress, Address _sen
return !m_ext;
}
bool Executive::call(CallParameters const& _p, u256 const& _gasPrice, Address const& _origin)
{
m_isCreation = false;
// cnote << "Transferring" << formatBalance(_value) << "to receiver.";
auto it = !(_p.codeAddress & ~h160(0xffffffff)) ? precompiled().find((unsigned)(u160)_p.codeAddress) : precompiled().end();
if (it != precompiled().end())
{
bigint g = it->second.gas(_p.data);
if (_p.gas < g)
{
m_endGas = 0;
m_excepted = TransactionException::OutOfGasBase;
// Bail from exception.
return true; // true actually means "all finished - nothing more to be done regarding go().
}
else
{
m_endGas = (u256)(_p.gas - g);
m_precompiledOut = it->second.exec(_p.data);
m_out = &m_precompiledOut;
}
}
else if (m_s.addressHasCode(_p.codeAddress))
{
m_vm = VMFactory::create(_p.gas);
bytes const& c = m_s.code(_p.codeAddress);
m_ext = make_shared<ExtVM>(m_s, m_lastHashes, _p.receiveAddress, _p.senderAddress, _origin, _p.value, _gasPrice, _p.data, &c, m_depth);
}
else
m_endGas = _p.gas;
m_s.transferBalance(_p.senderAddress, _p.receiveAddress, _p.value);
return !m_ext;
}
bool Executive::create(Address _sender, u256 _endowment, u256 _gasPrice, u256 _gas, bytesConstRef _init, Address _origin)
{
m_isCreation = true;

1
libethereum/Executive.h

@ -95,6 +95,7 @@ public:
/// Set up the executive for evaluating a bare CALL (message call) operation.
/// @returns false iff go() must be called (and thus a VM execution in required).
bool call(Address _myAddress, Address _codeAddress, Address _txSender, u256 _txValue, u256 _gasPrice, bytesConstRef _txData, u256 _gas, Address _originAddress);
bool call(CallParameters const& _cp, u256 const& _gasPrice, Address const& _origin);
/// Finalise an operation through accruing the substate into the parent context.
void accrueSubState(SubState& _parentContext);

10
libethereum/ExtVM.cpp

@ -26,16 +26,16 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
bool ExtVM::call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp, Address _myAddressOverride, Address _codeAddressOverride)
bool ExtVM::call(CallParameters& _p)
{
Executive e(m_s, lastHashes, depth + 1);
if (!e.call(_receiveAddress, _codeAddressOverride, _myAddressOverride ? _myAddressOverride : myAddress, _txValue, gasPrice, _txData, io_gas, origin))
if (!e.call(_p, gasPrice, origin))
{
e.go(_onOp);
e.go(_p.onOp);
e.accrueSubState(sub);
}
io_gas = e.endGas();
e.out().copyTo(_out);
_p.gas = e.endGas();
e.out().copyTo(_p.out);
return !e.excepted();
}

2
libethereum/ExtVM.h

@ -58,7 +58,7 @@ public:
virtual h160 create(u256 _endowment, u256& io_gas, bytesConstRef _code, OnOpFunc const& _onOp = {}) override final;
/// Create a new message call. Leave _myAddressOverride as the default to use the present address as caller.
virtual bool call(Address _receiveAddress, u256 _txValue, bytesConstRef _txData, u256& io_gas, bytesRef _out, OnOpFunc const& _onOp = {}, Address _myAddressOverride = {}, Address _codeAddressOverride = {}) override final;
virtual bool call(CallParameters& _params) override final;
/// Read address's balance.
virtual u256 balance(Address _a) override final { return m_s.balance(_a); }

7
libethereum/KeyManager.cpp

@ -61,12 +61,17 @@ bool KeyManager::load(std::string const& _pass)
if (version == 1)
{
for (auto const& i: s[1])
{
m_keyInfo[m_addrLookup[(Address)i[0]] = (h128)i[1]] = KeyInfo((h256)i[2], (std::string)i[3]);
cdebug << toString((Address)i[0]) << toString((h128)i[1]) << toString((h256)i[2]) << (std::string)i[3];
}
for (auto const& i: s[2])
m_passwordInfo[(h256)i[0]] = (std::string)i[1];
m_password = (string)s[3];
}
m_cachedPasswords[hashPassword(m_password)] = m_password;
m_cachedPasswords[hashPassword(defaultPassword())] = defaultPassword();
return true;
}
catch (...) {
@ -210,4 +215,6 @@ void KeyManager::write(h128 const& _key, std::string const& _keysFile) const
writeFile(_keysFile, encryptSymNoAuth(_key, h128(), &s.out()));
m_key = _key;
m_cachedPasswords[hashPassword(defaultPassword())] = defaultPassword();
}

12
libethereum/KeyManager.h

@ -24,7 +24,7 @@
#include <functional>
#include <mutex>
#include <libdevcrypto/SecretStore.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
namespace dev
{
@ -75,10 +75,11 @@ public:
Address address(h128 const& _uuid) const;
h128 import(Secret const& _s, std::string const& _info, std::string const& _pass, std::string const& _passInfo);
h128 import(Secret const& _s, std::string const& _info) { return import(_s, _info, m_password, std::string()); }
h128 import(Secret const& _s, std::string const& _info) { return import(_s, _info, defaultPassword(), std::string()); }
SecretStore& store() { return m_store; }
void importExisting(h128 const& _uuid, std::string const& _info, std::string const& _pass, std::string const& _passInfo);
void importExisting(h128 const& _uuid, std::string const& _info) { importExisting(_uuid, _info, defaultPassword(), std::string()); }
Secret secret(Address const& _address, std::function<std::string()> const& _pass = DontKnowThrow) const;
Secret secret(h128 const& _uuid, std::function<std::string()> const& _pass = DontKnowThrow) const;
@ -87,6 +88,7 @@ public:
void kill(Address const& _a);
private:
std::string defaultPassword() const { return asString(m_key.ref()); }
h256 hashPassword(std::string const& _pass) const;
// Only use if previously loaded ok.
@ -103,7 +105,11 @@ private:
// Passwords that we're storing.
mutable std::unordered_map<h256, std::string> m_cachedPasswords;
// The default password for keys in the keystore - protected by the master password.
// DEPRECATED.
// Used to be the default password for keys in the keystore, stored in the keys file.
// Now the default password is based off the key of the keys file directly, so this is redundant
// except for the fact that people have existing keys stored with it. Leave for now until/unless
// we have an upgrade strategy.
std::string m_password;
SecretStore m_store;

2
libethereum/LogFilter.cpp

@ -21,7 +21,7 @@
#include "LogFilter.h"
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "State.h"
using namespace std;
using namespace dev;

15
libethereum/Precompiled.cpp

@ -21,7 +21,9 @@
#include "Precompiled.h"
#include <libdevcrypto/SHA3.h>
#include <libdevcore/Log.h>
#include <libdevcore/SHA3.h>
#include <libdevcore/Hash.h>
#include <libdevcrypto/Common.h>
#include <libethcore/Common.h>
#include <libevmcore/Params.h>
@ -61,19 +63,12 @@ static bytes ecrecoverCode(bytesConstRef _in)
static bytes sha256Code(bytesConstRef _in)
{
bytes ret(32);
sha256(_in, &ret);
return ret;
return sha256(_in).asBytes();
}
static bytes ripemd160Code(bytesConstRef _in)
{
bytes ret(32);
ripemd160(_in, &ret);
// leaves the 20-byte hash left-aligned. we want it right-aligned:
memmove(ret.data() + 12, ret.data(), 20);
memset(ret.data(), 0, 12);
return ret;
return h256(ripemd160(_in), h256::AlignRight).asBytes();
}
static bytes identityCode(bytesConstRef _in)

22
libethereum/State.cpp

@ -29,7 +29,7 @@
#include <libdevcore/CommonIO.h>
#include <libdevcore/Assertions.h>
#include <libdevcore/StructuredLogger.h>
#include <libdevcrypto/TrieHash.h>
#include <libdevcore/TrieHash.h>
#include <libevmcore/Instruction.h>
#include <libethcore/Exceptions.h>
#include <libevm/VMFactory.h>
@ -840,16 +840,8 @@ void State::commitToMine(BlockChain const& _bc)
}
}
// TODO: move over to using TrieHash
MemoryDB tm;
GenericTrieDB<MemoryDB> transactionsTrie(&tm);
transactionsTrie.init();
MemoryDB rm;
GenericTrieDB<MemoryDB> receiptsTrie(&rm);
receiptsTrie.init();
BytesMap transactionsMap;
BytesMap receiptsMap;
RLPStream txs;
txs.appendList(m_transactions.size());
@ -861,11 +853,11 @@ void State::commitToMine(BlockChain const& _bc)
RLPStream receiptrlp;
m_receipts[i].streamRLP(receiptrlp);
receiptsTrie.insert(&k.out(), &receiptrlp.out());
receiptsMap.insert(std::make_pair(k.out(), receiptrlp.out()));
RLPStream txrlp;
m_transactions[i].streamRLP(txrlp);
transactionsTrie.insert(&k.out(), &txrlp.out());
transactionsMap.insert(std::make_pair(k.out(), txrlp.out()));
txs.appendRaw(txrlp.out());
}
@ -874,8 +866,8 @@ void State::commitToMine(BlockChain const& _bc)
RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles);
m_currentBlock.transactionsRoot = transactionsTrie.root();
m_currentBlock.receiptsRoot = receiptsTrie.root();
m_currentBlock.transactionsRoot = hash256(transactionsMap);
m_currentBlock.receiptsRoot = hash256(receiptsMap);
m_currentBlock.logBloom = logBloom();
m_currentBlock.sha3Uncles = sha3(m_currentUncles);

3
libethereum/State.h

@ -25,7 +25,8 @@
#include <unordered_map>
#include <libdevcore/Common.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/TrieDB.h>
#include <libdevcore/TrieDB.h>
#include <libdevcrypto/OverlayDB.h>
#include <libethcore/Exceptions.h>
#include <libethcore/BlockInfo.h>
#include <libethcore/ProofOfWork.h>

2
libethereum/Transaction.h

@ -22,7 +22,7 @@
#pragma once
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libethcore/Common.h>
#include <libevmcore/Params.h>
namespace dev

2
libethereum/Utility.cpp

@ -23,7 +23,7 @@
#include <boost/regex.hpp>
#include <libethcore/Common.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
using namespace std;
using namespace dev;
using namespace dev::eth;

16
libevm/ExtVMFace.h

@ -26,7 +26,7 @@
#include <libdevcore/Common.h>
#include <libdevcore/CommonData.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libevmcore/Instruction.h>
#include <libethcore/Common.h>
#include <libethcore/BlockInfo.h>
@ -108,6 +108,18 @@ using LastHashes = std::vector<h256>;
using OnOpFunc = std::function<void(uint64_t /*steps*/, Instruction /*instr*/, bigint /*newMemSize*/, bigint /*gasCost*/, VM*, ExtVMFace const*)>;
struct CallParameters
{
Address senderAddress;
Address codeAddress;
Address receiveAddress;
u256 gas;
u256 value;
bytesConstRef data;
bytesRef out;
OnOpFunc onOp;
};
/**
* @brief Interface and null implementation of the class for specifying VM externalities.
*/
@ -153,7 +165,7 @@ public:
virtual h160 create(u256, u256&, bytesConstRef, OnOpFunc const&) { return h160(); }
/// Make a new message call.
virtual bool call(Address, u256, bytesConstRef, u256&, bytesRef, OnOpFunc const&, Address, Address) { return false; }
virtual bool call(CallParameters&) { return false; }
/// Revert any changes made (by any of the other calls).
virtual void log(h256s&& _topics, bytesConstRef _data) { sub.logs.push_back(LogEntry(myAddress, std::move(_topics), _data.toBytes())); }

2
libevm/SmartVM.cpp

@ -21,7 +21,7 @@
#include "SmartVM.h"
#include <unordered_map>
#include <libdevcore/Log.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <evmjit/JIT.h>
#include <evmjit/libevmjit-cpp/Utils.h>
#include "VMFactory.h"

6
libevm/SmartVM.h

@ -31,12 +31,16 @@ namespace eth
class SmartVM: public VMFace
{
public:
SmartVM(u256 _gas): VMFace(_gas) {}
SmartVM(u256 const& _gas): m_gas(_gas) {}
virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final;
void reset(u256 const& _gas = 0) noexcept override { m_gas = _gas; }
u256 gas() const noexcept override { return (u256)m_gas; }
private:
std::unique_ptr<VMFace> m_selectedVM;
bigint m_gas;
};
}

40
libevm/VM.cpp

@ -25,9 +25,9 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
void VM::reset(u256 _gas) noexcept
void VM::reset(u256 const& _gas) noexcept
{
VMFace::reset(_gas);
m_gas = _gas;
m_curPC = 0;
m_jumpDests.clear();
}
@ -56,6 +56,8 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
{
m_stack.reserve((unsigned)c_stackLimit);
unique_ptr<CallParameters> callParams;
static const array<InstructionMetric, 256> c_metrics = metrics();
auto memNeed = [](u256 _offset, dev::u256 _size) { return _size ? (bigint)_offset + _size : (bigint)0; };
@ -206,7 +208,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
BOOST_THROW_EXCEPTION(OutOfGas());
}
m_gas = (u256)((bigint)m_gas - runGas);
m_gas -= runGas;
if (newTempSize > m_temp.size())
m_temp.resize((size_t)newTempSize);
@ -565,7 +567,7 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
m_stack.push_back(m_temp.size());
break;
case Instruction::GAS:
m_stack.push_back(m_gas);
m_stack.push_back((u256)m_gas);
break;
case Instruction::JUMPDEST:
break;
@ -614,7 +616,11 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
m_stack.pop_back();
if (_ext.balance(_ext.myAddress) >= endowment && _ext.depth < 1024)
m_stack.push_back((u160)_ext.create(endowment, m_gas, bytesConstRef(m_temp.data() + initOff, initSize), _onOp));
{
u256 g(m_gas);
m_stack.push_back((u160)_ext.create(endowment, g, bytesConstRef(m_temp.data() + initOff, initSize), _onOp));
m_gas = g;
}
else
m_stack.push_back(0);
break;
@ -622,13 +628,16 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
case Instruction::CALL:
case Instruction::CALLCODE:
{
u256 gas = m_stack.back();
if (!callParams)
callParams.reset(new CallParameters);
callParams->gas = m_stack.back();
if (m_stack[m_stack.size() - 3] > 0)
gas += c_callStipend;
callParams->gas += c_callStipend;
m_stack.pop_back();
Address receiveAddress = asAddress(m_stack.back());
callParams->receiveAddress = asAddress(m_stack.back());
m_stack.pop_back();
u256 value = m_stack.back();
callParams->value = m_stack.back();
m_stack.pop_back();
unsigned inOff = (unsigned)m_stack.back();
@ -640,12 +649,19 @@ bytesConstRef VM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
unsigned outSize = (unsigned)m_stack.back();
m_stack.pop_back();
if (_ext.balance(_ext.myAddress) >= value && _ext.depth < 1024)
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, {}, receiveAddress));
if (_ext.balance(_ext.myAddress) >= callParams->value && _ext.depth < 1024)
{
callParams->onOp = _onOp;
callParams->senderAddress = _ext.myAddress;
callParams->codeAddress = inst == Instruction::CALL ? callParams->receiveAddress : callParams->senderAddress;
callParams->data = bytesConstRef(m_temp.data() + inOff, inSize);
callParams->out = bytesRef(m_temp.data() + outOff, outSize);
m_stack.push_back(_ext.call(*callParams));
}
else
m_stack.push_back(0);
m_gas += gas;
m_gas += callParams->gas;
break;
}
case Instruction::RETURN:

10
libevm/VM.h

@ -25,7 +25,7 @@
#include <libdevcore/Exceptions.h>
#include <libethcore/Common.h>
#include <libevmcore/Instruction.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libethcore/BlockInfo.h>
#include <libevmcore/Params.h>
#include "VMFace.h"
@ -52,8 +52,6 @@ inline u256 fromAddress(Address _a)
class VM: public VMFace
{
public:
virtual void reset(u256 _gas = 0) noexcept override final;
virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final;
void require(u256 _n, u256 _d) { if (m_stack.size() < _n) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(StackUnderflow() << RequirementError((bigint)_n, (bigint)m_stack.size())); } if (m_stack.size() - _n + _d > c_stackLimit) { if (m_onFail) m_onFail(); BOOST_THROW_EXCEPTION(OutOfStack() << RequirementError((bigint)(_d - _n), (bigint)m_stack.size())); } }
@ -64,17 +62,21 @@ public:
bytes const& memory() const { return m_temp; }
u256s const& stack() const { return m_stack; }
void reset(u256 const& _gas = 0) noexcept override;
u256 gas() const noexcept override { return (u256)m_gas; }
private:
friend class VMFactory;
/// Construct VM object.
explicit VM(u256 _gas): VMFace(_gas) {}
explicit VM(u256 _gas): m_gas(_gas) {}
u256 m_curPC = 0;
bytes m_temp;
u256s m_stack;
std::set<u256> m_jumpDests;
std::function<void()> m_onFail;
bigint m_gas = 0;
};
}

9
libevm/VMFace.h

@ -38,18 +38,15 @@ struct StackUnderflow: virtual VMException {};
class VMFace
{
public:
explicit VMFace(u256 _gas): m_gas(_gas) {}
VMFace() = default;
virtual ~VMFace() = default;
VMFace(VMFace const&) = delete;
VMFace& operator=(VMFace const&) = delete;
virtual void reset(u256 _gas = 0) noexcept { m_gas = _gas; }
u256 gas() const noexcept { return m_gas; }
virtual void reset(u256 const& _gas = 0) noexcept = 0;
virtual u256 gas() const noexcept = 0;
virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) = 0;
protected:
u256 m_gas = 0;
};
}

2
libevmasm/CommonSubexpressionEliminator.cpp

@ -23,7 +23,7 @@
#include <functional>
#include <boost/range/adaptor/reversed.hpp>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libevmasm/CommonSubexpressionEliminator.h>
#include <libevmasm/AssemblyItem.h>

2
libevmasm/KnownState.cpp

@ -23,7 +23,7 @@
#include "KnownState.h"
#include <functional>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libevmasm/AssemblyItem.h>
using namespace std;

2
libp2p/Host.cpp

@ -31,7 +31,7 @@
#include <libdevcore/CommonIO.h>
#include <libdevcore/StructuredLogger.h>
#include <libethcore/Exceptions.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include "Session.h"
#include "Common.h"
#include "Capability.h"

2
libp2p/UDP.h

@ -29,7 +29,7 @@
#include <libdevcore/Guards.h>
#include <libdevcrypto/Common.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libdevcore/Log.h>
#include <libdevcore/RLP.h>
#include "Common.h"

2
libsolidity/AST.cpp

@ -28,7 +28,7 @@
#include <libsolidity/Exceptions.h>
#include <libsolidity/AST_accept.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
using namespace std;

2
libsolidity/CompilerStack.cpp

@ -31,7 +31,7 @@
#include <libsolidity/CompilerStack.h>
#include <libsolidity/InterfaceHandler.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
using namespace std;

2
libsolidity/ExpressionCompiler.cpp

@ -24,7 +24,7 @@
#include <numeric>
#include <boost/range/adaptor/reversed.hpp>
#include <libdevcore/Common.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libsolidity/AST.h>
#include <libsolidity/ExpressionCompiler.h>
#include <libsolidity/CompilerContext.h>

2
libsolidity/Types.cpp

@ -25,7 +25,7 @@
#include <boost/range/adaptor/reversed.hpp>
#include <libdevcore/CommonIO.h>
#include <libdevcore/CommonData.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libsolidity/Utils.h>
#include <libsolidity/AST.h>

2
libtestutils/Common.cpp

@ -23,7 +23,7 @@
#include <boost/filesystem.hpp>
#include <libdevcore/CommonData.h>
#include <libdevcore/CommonIO.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include "Common.h"
using namespace std;

2
libweb3jsonrpc/WebThreeStubServer.cpp

@ -26,7 +26,7 @@
#include <boost/filesystem.hpp>
#include <libwebthree/WebThree.h>
#include <libdevcrypto/FileSystem.h>
#include <libdevcore/FileSystem.h>
#include "WebThreeStubServer.h"
using namespace std;

2
libwhisper/Common.cpp

@ -21,7 +21,7 @@
#include "Common.h"
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "Message.h"
using namespace std;
using namespace dev;

2
libwhisper/Interface.h

@ -29,7 +29,7 @@
#include <libdevcore/RLP.h>
#include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "Common.h"
#include "Message.h"

2
libwhisper/Message.h

@ -30,7 +30,7 @@
#include <libdevcore/RLP.h>
#include <libdevcore/Guards.h>
#include <libdevcrypto/Common.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "Common.h"
namespace dev

2
libwhisper/WhisperHost.h

@ -30,7 +30,7 @@
#include <libdevcore/RLP.h>
#include <libdevcore/Worker.h>
#include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "Common.h"
#include "WhisperPeer.h"
#include "Interface.h"

2
libwhisper/WhisperPeer.h

@ -29,7 +29,7 @@
#include <libdevcore/RLP.h>
#include <libdevcore/Guards.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "Common.h"
#include "Message.h"

68
mix/CodeModel.cpp

@ -33,6 +33,8 @@
#include <libsolidity/CompilerStack.h>
#include <libsolidity/SourceReferenceFormatter.h>
#include <libsolidity/InterfaceHandler.h>
#include <libsolidity/StructuralGasEstimator.h>
#include <libsolidity/SourceReferenceFormatter.h>
#include <libevmcore/Instruction.h>
#include <libethcore/CommonJS.h>
#include "QContractDefinition.h"
@ -50,6 +52,7 @@ const std::set<std::string> c_predefinedContracts =
namespace
{
using namespace dev::eth;
using namespace dev::solidity;
class CollectLocalsVisitor: public ASTConstVisitor
@ -305,6 +308,7 @@ void CodeModel::runCompilationJob(int _jobId)
}
}
cs.compile(false);
gasEstimation(cs);
collectContracts(cs, sourceNames);
}
catch (dev::Exception const& _exception)
@ -350,6 +354,44 @@ QVariantMap CodeModel::resolveCompilationErrorLocation(CompilerStack const& _com
return error;
}
void CodeModel::gasEstimation(solidity::CompilerStack const& _cs)
{
if (m_gasCostsMaps)
m_gasCostsMaps->deleteLater();
m_gasCostsMaps = new GasMapWrapper(this);
for (std::string n: _cs.getContractNames())
{
ContractDefinition const& contractDefinition = _cs.getContractDefinition(n);
QString sourceName = QString::fromStdString(*contractDefinition.getLocation().sourceName);
if (!m_gasCostsMaps->contains(sourceName))
m_gasCostsMaps->insert(sourceName, QVariantList());
if (!contractDefinition.isFullyImplemented())
continue;
dev::solidity::SourceUnit const& sourceUnit = _cs.getAST(*contractDefinition.getLocation().sourceName);
AssemblyItems const* items = _cs.getRuntimeAssemblyItems(n);
StructuralGasEstimator estimator;
std::map<ASTNode const*, GasMeter::GasConsumption> gasCosts = estimator.breakToStatementLevel(estimator.performEstimation(*items, std::vector<ASTNode const*>({&sourceUnit})), {&sourceUnit});
for (auto gasItem = gasCosts.begin(); gasItem != gasCosts.end(); ++gasItem)
{
SourceLocation const& location = gasItem->first->getLocation();
GasMeter::GasConsumption cost = gasItem->second;
std::stringstream v;
v << cost.value;
m_gasCostsMaps->push(sourceName, location.start, location.end, QString::fromStdString(v.str()), cost.isInfinite);
}
}
}
QVariantList CodeModel::gasCostByDocumentId(QString const& _documentId) const
{
if (m_gasCostsMaps)
return m_gasCostsMaps->gasCostsByDocId(_documentId);
else
return QVariantList();
}
void CodeModel::collectContracts(dev::solidity::CompilerStack const& _cs, std::vector<std::string> const& _sourceNames)
{
Guard pl(x_pendingContracts);
@ -539,3 +581,29 @@ QString CodeModel::resolveFunctionName(dev::SourceLocation const& _location)
}
return QString();
}
void GasMapWrapper::push(QString _source, int _start, int _end, QString _value, bool _isInfinite)
{
GasMap* gas = new GasMap(_start, _end, _value, _isInfinite, this);
m_gasMaps.find(_source).value().push_back(QVariant::fromValue(gas));
}
bool GasMapWrapper::contains(QString _key)
{
return m_gasMaps.contains(_key);
}
void GasMapWrapper::insert(QString _source, QVariantList _variantList)
{
m_gasMaps.insert(_source, _variantList);
}
QVariantList GasMapWrapper::gasCostsByDocId(QString _source)
{
auto gasIter = m_gasMaps.find(_source);
if (gasIter != m_gasMaps.end())
return gasIter.value();
else
return QVariantList();
}

44
mix/CodeModel.h

@ -32,6 +32,7 @@
#include <libdevcore/Guards.h>
#include <libevmasm/Assembly.h>
#include "SolidityType.h"
#include "QBigInt.h"
class QTextDocument;
@ -127,6 +128,42 @@ struct SourceMap
};
using SourceMaps = QMap<QString, SourceMap>; //by source id
using GasCostsMaps = QMap<QString, QVariantList>; //gas cost by contract name
class GasMapWrapper: public QObject
{
Q_OBJECT
Q_PROPERTY(GasCostsMaps gasMaps MEMBER m_gasMaps CONSTANT)
public:
GasMapWrapper(QObject* _parent): QObject(_parent){}
void push(QString _source, int _start, int _end, QString _value, bool _isInfinite);
bool contains(QString _key);
void insert(QString _source, QVariantList _variantList);
QVariantList gasCostsByDocId(QString _source);
private:
GasCostsMaps m_gasMaps;
};
class GasMap: public QObject
{
Q_OBJECT
Q_PROPERTY(int start MEMBER m_start CONSTANT)
Q_PROPERTY(int end MEMBER m_end CONSTANT)
Q_PROPERTY(QString gas MEMBER m_gas CONSTANT)
Q_PROPERTY(bool isInfinite MEMBER m_isInfinite CONSTANT)
public:
GasMap(int _start, int _end, QString _gas, bool _isInfinite, QObject* _parent): QObject(_parent), m_start(_start), m_end(_end), m_gas(_gas), m_isInfinite(_isInfinite) {}
int m_start;
int m_end;
QString m_gas;
bool m_isInfinite;
};
/// Code compilation model. Compiles contracts in background an provides compiled contract data
class CodeModel: public QObject
@ -168,6 +205,10 @@ public:
bool isContractOrFunctionLocation(dev::SourceLocation const& _location);
/// Get funciton name by location
QString resolveFunctionName(dev::SourceLocation const& _location);
/// Gas estimation for compiled sources
void gasEstimation(solidity::CompilerStack const& _cs);
/// Gas cost by doc id
Q_INVOKABLE QVariantList gasCostByDocumentId(QString const& _documentId) const;
signals:
/// Emited on compilation state change
@ -204,6 +245,7 @@ private:
mutable dev::Mutex x_contractMap;
ContractMap m_contractMap;
SourceMaps m_sourceMaps;
GasMapWrapper* m_gasCostsMaps = 0;
std::unique_ptr<CodeHighlighterSettings> m_codeHighlighterSettings;
QThread m_backgroundThread;
BackgroundWorker m_backgroundWorker;
@ -217,3 +259,5 @@ private:
}
}
//Q_DECLARE_METATYPE(dev::mix::GasMap)

2
mix/FileIo.cpp

@ -34,7 +34,7 @@
#include <libdevcrypto/CryptoPP.h>
#include <libdevcrypto/Common.h>
#include <libdevcore/RLP.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include "FileIo.h"
using namespace dev;

2
mix/QFunctionDefinition.cpp

@ -20,7 +20,7 @@
*/
#include <libsolidity/AST.h>
#include <libdevcrypto/SHA3.h>
#include <libdevcore/SHA3.h>
#include <libdevcore/Exceptions.h>
#include "QVariableDeclaration.h"
#include "QFunctionDefinition.h"

15
mix/qml/Application.qml

@ -116,6 +116,10 @@ ApplicationWindow {
MenuSeparator {}
MenuItem { action: toggleAssemblyDebuggingAction }
}
Menu {
title: qsTr("Tools")
MenuItem { action: gasEstimationAction }
}
Menu {
title: qsTr("Windows")
MenuItem { action: openNextDocumentAction }
@ -409,4 +413,15 @@ ApplicationWindow {
mainContent.codeEditor.goToCompilationError();
}
}
Action {
id: gasEstimationAction
text: qsTr("Display gas estimation")
shortcut: "Ctrl+G"
checkable: true
onTriggered:
{
mainContent.codeEditor.displayGasEstimation(checked);
}
}
}

12
mix/qml/CodeEditorView.qml

@ -168,6 +168,13 @@ Item {
editors.itemAt(i).item.setFontSize(size);
}
function displayGasEstimation(checked)
{
var editor = getEditor(currentDocumentId);
if (editor)
editor.displayGasEstimation(checked);
}
Component.onCompleted: projectModel.codeEditor = codeEditorView;
Connections {
@ -177,6 +184,10 @@ Item {
}
onCompilationComplete: {
sourceInError = "";
var gasCosts = codeModel.gasCostByDocumentId(currentDocumentId);
var editor = getEditor(currentDocumentId);
if (editor)
editor.setGasCosts(gasCosts);
}
}
@ -280,6 +291,7 @@ Item {
messageDialog.doc = editorListModel.get(index);
messageDialog.open();
}
loader.item.displayGasEstimation(gasEstimationAction.checked);
}
}
Component.onCompleted: {

1
mix/qml/StatesComboBox.qml

@ -23,7 +23,6 @@
import QtQuick 2.0
import QtQuick.Controls 1.0
import QtQuick.Layouts 1.1
import QtGraphicalEffects 1.0
import org.ethereum.qml.InverseMouseArea 1.0
Rectangle {

1
mix/qml/StatusPane.qml

@ -3,7 +3,6 @@ import QtQuick.Controls 1.1
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.3
import org.ethereum.qml.InverseMouseArea 1.0
import QtGraphicalEffects 1.0
import "js/ErrorLocationFormater.js" as ErrorLocationFormater
import "."

15
mix/qml/WebCodeEditor.qml

@ -83,6 +83,16 @@ Item {
editorBrowser.runJavaScript("setFontSize(" + size + ")", function(result) {});
}
function setGasCosts(gasCosts) {
if (initialized && editorBrowser)
editorBrowser.runJavaScript("setGasCosts('" + JSON.stringify(gasCosts) + "')", function(result) {});
}
function displayGasEstimation(show) {
if (initialized && editorBrowser)
editorBrowser.runJavaScript("displayGasEstimation('" + show + "')", function(result) {});
}
Clipboard
{
id: clipboard
@ -134,7 +144,12 @@ Item {
function compilationComplete()
{
if (editorBrowser)
{
editorBrowser.runJavaScript("compilationComplete()", function(result) { });
parent.displayGasEstimation(gasEstimationAction.checked);
}
}
function compilationError(error, firstLocation, secondLocations)

6
mix/qml/html/cm/solarized.css

@ -189,3 +189,9 @@ view-port
}
span.CodeMirror-selectedtext { color: #586e75 !important; }
/* Gas Costs */
.CodeMirror-gasCosts {
border-bottom: double 1px #2aa198;
}

107
mix/qml/html/codeeditor.js

@ -208,5 +208,112 @@ setFontSize = function(size)
editor.refresh();
}
makeGasCostMarker = function(value) {
var marker = document.createElement("div");
marker.style.color = "#822";
marker.innerHTML = value;
marker.className = "CodeMirror-errorannotation-context";
return marker;
};
var gasCosts = null;
setGasCosts = function(_gasCosts)
{
gasCosts = JSON.parse(_gasCosts);
if (showingGasEstimation)
{
displayGasEstimation(false);
displayGasEstimation(true);
}
}
var showingGasEstimation = false;
var gasMarkText = [];
var gasMarkRef = {};
displayGasEstimation = function(show)
{
show = JSON.parse(show);
showingGasEstimation = show;
if (show)
{
var maxGas = 20000;
var step = colorGradient.length / maxGas; // 20000 max gas
clearGasMark();
gasMarkText = [];
gasMarkRef = {};
for (var i in gasCosts)
{
if (gasCosts[i].gas !== "0")
{
var color;
var colorIndex = Math.round(step * gasCosts[i].gas);
if (gasCosts[i].isInfinite || colorIndex > colorGradient.length)
color = colorGradient[colorGradient.length - 1];
else
color = colorGradient[colorIndex];
var className = "CodeMirror-gasCosts" + i;
var line = editor.posFromIndex(gasCosts[i].start)
gasMarkText.push(editor.markText(line, editor.posFromIndex(gasCosts[i].end), { inclusiveLeft: true, inclusiveRight: true, handleMouseEvents: true, className: className, css: "background-color:" + color }));
gasMarkRef[className] = { line: line.line, value: gasCosts[i] };
}
}
CodeMirror.on(editor.getWrapperElement(), "mouseover", listenMouseOver);
}
else
{
CodeMirror.off(editor.getWrapperElement(), "mouseover", listenMouseOver);
clearGasMark();
if (gasAnnotation)
{
gasAnnotation.clear();
gasAnnotation = null;
}
}
}
function clearGasMark()
{
if (gasMarkText)
for (var k in gasMarkText)
gasMarkText[k].clear();
}
var gasAnnotation;
function listenMouseOver(e)
{
var node = e.target || e.srcElement;
if (node)
{
if (node.className && node.className.indexOf("CodeMirror-gasCosts") !== -1)
{
if (gasAnnotation)
gasAnnotation.clear();
var cl = getGasCostClass(node);
var gasTitle = gasMarkRef[cl].value.isInfinite ? "infinite" : gasMarkRef[cl].value.gas;
gasTitle = gasTitle + " gas";
gasAnnotation = editor.addLineWidget(gasMarkRef[cl].line + 1, makeGasCostMarker(gasTitle), { coverGutter: false, above: true });
}
else if (gasAnnotation)
{
gasAnnotation.clear();
gasAnnotation = null;
}
}
}
function getGasCostClass(node)
{
var classes = node.className.split(" ");
for (var k in classes)
{
if (classes[k].indexOf("CodeMirror-gasCosts") !== -1)
return classes[k];
}
return "";
}
// blue => red ["#1515ED", "#1714EA", "#1914E8", "#1B14E6", "#1D14E4", "#1F14E2", "#2214E0", "#2414DE", "#2614DC", "#2813DA", "#2A13D8", "#2D13D6", "#2F13D4", "#3113D2", "#3313D0", "#3513CE", "#3713CC", "#3A12CA", "#3C12C8", "#3E12C6", "#4012C4", "#4212C2", "#4512C0", "#4712BE", "#4912BC", "#4B11BA", "#4D11B8", "#4F11B6", "#5211B4", "#5411B2", "#5611B0", "#5811AE", "#5A11AC", "#5D11AA", "#5F10A7", "#6110A5", "#6310A3", "#6510A1", "#67109F", "#6A109D", "#6C109B", "#6E1099", "#700F97", "#720F95", "#750F93", "#770F91", "#790F8F", "#7B0F8D", "#7D0F8B", "#7F0F89", "#820E87", "#840E85", "#860E83", "#880E81", "#8A0E7F", "#8D0E7D", "#8F0E7B", "#910E79", "#930D77", "#950D75", "#970D73", "#9A0D71", "#9C0D6F", "#9E0D6D", "#A00D6B", "#A20D69", "#A50D67", "#A70C64", "#A90C62", "#AB0C60", "#AD0C5E", "#AF0C5C", "#B20C5A", "#B40C58", "#B60C56", "#B80B54", "#BA0B52", "#BD0B50", "#BF0B4E", "#C10B4C", "#C30B4A", "#C50B48", "#C70B46", "#CA0A44", "#CC0A42", "#CE0A40", "#D00A3E", "#D20A3C", "#D50A3A", "#D70A38", "#D90A36", "#DB0934", "#DD0932", "#DF0930", "#E2092E", "#E4092C", "#E6092A", "#E80928", "#EA0926", "#ED0924"]
/* green => red */ var colorGradient = ["#429C27", "#439A26", "#449926", "#469726", "#479626", "#489525", "#4A9325", "#4B9225", "#4D9025", "#4E8F25", "#4F8E24", "#518C24", "#528B24", "#548924", "#558824", "#568723", "#588523", "#598423", "#5B8223", "#5C8122", "#5D8022", "#5F7E22", "#607D22", "#627B22", "#637A21", "#647921", "#667721", "#677621", "#697421", "#6A7320", "#6B7220", "#6D7020", "#6E6F20", "#706E20", "#716C1F", "#726B1F", "#74691F", "#75681F", "#76671E", "#78651E", "#79641E", "#7B621E", "#7C611E", "#7D601D", "#7F5E1D", "#805D1D", "#825B1D", "#835A1D", "#84591C", "#86571C", "#87561C", "#89541C", "#8A531B", "#8B521B", "#8D501B", "#8E4F1B", "#904D1B", "#914C1A", "#924B1A", "#94491A", "#95481A", "#97461A", "#984519", "#994419", "#9B4219", "#9C4119", "#9E4019", "#9F3E18", "#A03D18", "#A23B18", "#A33A18", "#A43917", "#A63717", "#A73617", "#A93417", "#AA3317", "#AB3216", "#AD3016", "#AE2F16", "#B02D16", "#B12C16", "#B22B15", "#B42915", "#B52815", "#B72615", "#B82514", "#B92414", "#BB2214", "#BC2114", "#BE1F14", "#BF1E13", "#C01D13", "#C21B13", "#C31A13", "#C51813", "#C61712", "#C71612", "#C91412", "#CA1312", "#CC1212"]
editor.setOption("extraKeys", extraKeys);

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save