Browse Source

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

cl-refactor
yann300 10 years ago
parent
commit
3fc3a0af76
  1. 4
      BuildInfo.h.in
  2. 47
      CMakeLists.txt
  3. 5
      alethzero/DappLoader.cpp
  4. 71
      alethzero/MainWin.cpp
  5. 68
      eth/main.cpp
  6. 43
      ethkey/KeyAux.h
  7. 1
      ethminer/CMakeLists.txt
  8. 14
      evmjit/include/evmjit/JIT-c.h
  9. 6
      evmjit/libevmjit/JIT-c.cpp
  10. 8
      extdep/getstuff.bat
  11. 4
      libdevcore/Common.cpp
  12. 33
      libdevcore/Common.h
  13. 11
      libdevcore/CommonJS.h
  14. 81
      libdevcore/FixedHash.h
  15. 9
      libdevcore/SHA3.cpp
  16. 19
      libdevcore/SHA3.h
  17. 32
      libdevcore/vector_ref.h
  18. 2
      libdevcrypto/AES.h
  19. 46
      libdevcrypto/Common.cpp
  20. 30
      libdevcrypto/Common.h
  21. 18
      libdevcrypto/CryptoPP.cpp
  22. 6
      libdevcrypto/CryptoPP.h
  23. 2
      libdevcrypto/ECDHE.cpp
  24. 4
      libdevcrypto/ECDHE.h
  25. 63
      libdevcrypto/SecretStore.cpp
  26. 11
      libdevcrypto/SecretStore.h
  27. 41
      libethash-cl/ethash_cl_miner.cpp
  28. 2
      libethcore/BasicAuthority.cpp
  29. 19
      libethcore/BlockInfo.cpp
  30. 3
      libethcore/BlockInfo.h
  31. 4
      libethcore/CMakeLists.txt
  32. 29
      libethcore/Common.cpp
  33. 2
      libethcore/CommonJS.h
  34. 9
      libethcore/Ethash.cpp
  35. 2
      libethcore/Ethash.h
  36. 20
      libethcore/EthashCPUMiner.cpp
  37. 12
      libethcore/EthashCPUMiner.h
  38. 2
      libethcore/Farm.h
  39. 51
      libethcore/KeyManager.cpp
  40. 9
      libethcore/KeyManager.h
  41. 32
      libethcore/Params.cpp
  42. 1
      libethcore/Params.h
  43. 100
      libethereum/BlockChain.cpp
  44. 35
      libethereum/BlockChain.h
  45. 1
      libethereum/BlockQueue.cpp
  46. 6
      libethereum/CanonBlockChain.cpp
  47. 5
      libethereum/CanonBlockChain.h
  48. 17
      libethereum/Client.cpp
  49. 4
      libethereum/Client.h
  50. 3
      libethereum/Executive.cpp
  51. 33
      libethereum/State.cpp
  52. 6
      libethereum/TransactionQueue.cpp
  53. 4
      libethereum/TransactionQueue.h
  54. 4
      libethereumx/Ethereum.cpp
  55. 4
      libethereumx/Ethereum.h
  56. 2
      libevm/SmartVM.cpp
  57. 3
      libevm/VM.cpp
  58. 2
      libp2p/Host.cpp
  59. 16
      libp2p/RLPXSocketIO.cpp
  60. 4
      libp2p/RLPxHandshake.cpp
  61. 2
      libweb3jsonrpc/JsonHelper.cpp
  62. 2
      libweb3jsonrpc/JsonHelper.h
  63. 28
      libweb3jsonrpc/WebThreeStubServer.cpp
  64. 4
      libweb3jsonrpc/WebThreeStubServer.h
  65. 2
      libweb3jsonrpc/WebThreeStubServerBase.cpp
  66. 10
      libweb3jsonrpc/WebThreeStubServerBase.h
  67. 4
      libwhisper/CMakeLists.txt
  68. 4
      libwhisper/Interface.h
  69. 12
      libwhisper/Message.cpp
  70. 6
      libwhisper/Message.h
  71. 2
      mix/ClientModel.h
  72. 2
      mix/FileIo.cpp
  73. 6
      test/libdevcrypto/AES.cpp
  74. 32
      test/libdevcrypto/SecretStore.cpp
  75. 43
      test/libdevcrypto/crypto.cpp
  76. 14
      test/libethcore/commonjs.cpp
  77. 45
      test/libethereum/StateTestsFiller/stSystemOperationsTestFiller.json
  78. 3
      test/libethereum/gaspricer.cpp
  79. 4
      test/libethereum/stateOriginal.cpp

4
BuildInfo.h.in

@ -1,7 +1,7 @@
#pragma once
#define ETH_PROJECT_VERSION "@PROJECT_VERSION@"
#define ETH_COMMIT_HASH @ETH_COMMIT_HASH@
#define ETH_CLEAN_REPO @ETH_CLEAN_REPO@
#define ETH_BUILD_TYPE @ETH_BUILD_TYPE@
#define ETH_BUILD_PLATFORM @ETH_BUILD_PLATFORM@
#define ETH_BUILD_PLATFORM @ETH_BUILD_PLATFORM@

47
CMakeLists.txt

@ -1,7 +1,13 @@
# cmake global
cmake_minimum_required(VERSION 2.8.12)
project(ethereum)
set(PROJECT_VERSION "0.9.35")
if (${CMAKE_VERSION} VERSION_GREATER 3.0)
cmake_policy(SET CMP0048 NEW) # allow VERSION argument in project()
project(ethereum VERSION ${PROJECT_VERSION})
else()
project(ethereum)
endif()
set(CMAKE_AUTOMOC ON)
@ -41,7 +47,7 @@ option(TOOLS "Build the tools components" ON)
option(GUI "Build GUI components (AlethZero, Mix)" ON)
option(TESTS "Build the tests." ON)
option(NOBOOST "No use of boost macros in test functions" OFF)
option(EVMJIT "Build just-in-time compiler for EVM code (requires LLVM)" OFF)
option(EVMJIT "Build just-in-time compiler for EVM code (requires LLVM)" ON)
option(ETHASHCL "Build in support for GPU mining via OpenCL" ON)
option(JSCONSOLE "Build in javascript console" ON)
option(FRONTIER "Build for Frontier network" OFF)
@ -136,6 +142,7 @@ function(createBuildInfo)
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMAND ${CMAKE_COMMAND} -DETH_SOURCE_DIR="${CMAKE_SOURCE_DIR}" -DETH_DST_DIR="${CMAKE_BINARY_DIR}"
-DETH_BUILD_TYPE="${_cmake_build_type}" -DETH_BUILD_PLATFORM="${ETH_BUILD_PLATFORM}"
-DPROJECT_VERSION="${PROJECT_VERSION}"
-P "${ETH_SCRIPTS_DIR}/buildinfo.cmake"
)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
@ -223,6 +230,9 @@ if (GUI)
set(JSONRPC ON)
endif()
# Default CMAKE_BUILD_TYPE to "Release".
set(CMAKE_BUILD_TYPE CACHE STRING "Release")
# note: The value "default" which provides the defaults is just a fake value
# which lets us keep the default values of all build options and is set at
# the beginning of this file.
@ -292,8 +302,23 @@ elseif (BUNDLE STREQUAL "miner")
set(ETHKEY OFF)
set(MINER ON)
set(ETHASHCL ON)
elseif (BUNDLE STREQUAL "release")
set(SERPENT OFF)
elseif (BUNDLE STREQUAL "default") # development builds
set(SERPENT ${DECENT_PLATFORM})
set(SOLIDITY ON)
set(USENPM OFF)
set(GUI ON)
set(TOOLS ON)
set(TESTS ON)
set(FATDB ON)
set(ETHASHCL ON)
set(EVMJIT ON)
set(JSCONSOLE ON)
set(JSONRPC ON)
if ("x${CMAKE_BUILD_TYPE}" STREQUAL "x")
set(CMAKE_BUILD_TYPE "RelWithDebInfo")
endif ()
elseif (BUNDLE STREQUAL "release") # release builds
set(SERPENT ${DECENT_PLATFORM})
set(SOLIDITY ON)
set(USENPM OFF)
set(GUI ON)
@ -304,10 +329,9 @@ elseif (BUNDLE STREQUAL "release")
set(EVMJIT ON)
set(JSCONSOLE ON)
set(JSONRPC ON)
set(FRONTIER ON)
endif ()
# Default CMAKE_BUILD_TYPE to "Release".
set(CMAKE_BUILD_TYPE CACHE STRING "Release")
if ("x${CMAKE_BUILD_TYPE}" STREQUAL "x")
set(CMAKE_BUILD_TYPE "Release")
endif ()
@ -374,9 +398,14 @@ else()
endif()
if (EVMJIT)
if (CMAKE_SYSTEM_NAME STREQUAL "Windows" AND NOT DEFINED LLVM_DIR)
set(LLVM_DIR "${CMAKE_SOURCE_DIR}/extdep/install/windows/x64/share/llvm/cmake")
if (NOT DEFINED LLVM_DIR)
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set(LLVM_DIR "${CMAKE_SOURCE_DIR}/extdep/install/windows/x64/share/llvm/cmake")
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
set(LLVM_DIR "/usr/local/opt/llvm/share/llvm/cmake")
endif()
endif()
set(EVMJIT_CPP TRUE) # include CPP-JIT connector
add_subdirectory(evmjit)
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
@ -522,7 +551,7 @@ if (WIN32)
set(CPACK_PACKAGE_VENDOR "ethereum.org")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
set(CPACK_PACKAGE_VERSION "0.9.34")
set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION})
set(CPACK_GENERATOR "NSIS")
# seems to be not working
# set(CPACK_PACKAGE_ICON "${CMAKE_CURRENT_SOURCE_DIR}/alethzero/alethzero.bmp")

5
alethzero/DappLoader.cpp

@ -130,14 +130,14 @@ void DappLoader::downloadComplete(QNetworkReply* _reply)
h256 expected = m_uriHashes[requestUrl];
bytes package(reinterpret_cast<unsigned char const*>(data.constData()), reinterpret_cast<unsigned char const*>(data.constData() + data.size()));
Secp256k1PP dec;
dec.decrypt(expected, package);
dec.decrypt(Secret(expected), package);
h256 got = sha3(package);
if (got != expected)
{
//try base64
data = QByteArray::fromBase64(data);
package = bytes(reinterpret_cast<unsigned char const*>(data.constData()), reinterpret_cast<unsigned char const*>(data.constData() + data.size()));
dec.decrypt(expected, package);
dec.decrypt(Secret(expected), package);
got = sha3(package);
if (got != expected)
throw dev::Exception() << errinfo_comment("Dapp content hash does not match");
@ -145,6 +145,7 @@ void DappLoader::downloadComplete(QNetworkReply* _reply)
RLP rlp(package);
loadDapp(rlp);
bytesRef(&package).cleanse(); // TODO: replace with bytesSec once the crypto API is up to it.
}
catch (...)
{

71
alethzero/MainWin.cpp

@ -233,7 +233,7 @@ Main::Main(QWidget *parent) :
m_httpConnector.reset(new jsonrpc::HttpServer(SensibleHttpPort, "", "", dev::SensibleHttpThreads));
auto w3ss = new OurWebThreeStubServer(*m_httpConnector, this);
m_server.reset(w3ss);
auto sessionKey = w3ss->newSession(SessionPermissions{{Priviledge::Admin}});
auto sessionKey = w3ss->newSession(SessionPermissions{{Privilege::Admin}});
connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString)));
m_server->setIdentities(keysAsVector(owned()));
m_server->StartListening();
@ -360,8 +360,7 @@ void Main::refreshWhisper()
void Main::addNewId(QString _ids)
{
Secret _id = jsToSecret(_ids.toStdString());
KeyPair kp(_id);
KeyPair kp(jsToSecret(_ids.toStdString()));
m_myIdentities.push_back(kp);
m_server->setIdentities(keysAsVector(owned()));
refreshWhisper();
@ -846,29 +845,15 @@ void Main::readSettings(bool _skipGeometry)
restoreGeometry(s.value("geometry").toByteArray());
restoreState(s.value("windowState").toByteArray());
{
QByteArray b = s.value("address").toByteArray();
if (!b.isEmpty())
{
h256 k;
for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i)
{
memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret));
if (!m_keyManager.hasAccount(KeyPair(k).address()))
m_keyManager.import(k, "Imported (UNSAFE) key.");
}
}
}
{
m_myIdentities.clear();
QByteArray b = s.value("identities").toByteArray();
if (!b.isEmpty())
{
h256 k;
Secret k;
for (unsigned i = 0; i < b.size() / sizeof(Secret); ++i)
{
memcpy(&k, b.data() + i * sizeof(Secret), sizeof(Secret));
memcpy(k.writable().data(), b.data() + i * sizeof(Secret), sizeof(Secret));
if (!count(m_myIdentities.begin(), m_myIdentities.end(), KeyPair(k)))
m_myIdentities.append(KeyPair(k));
}
@ -961,7 +946,7 @@ void Main::on_importKey_triggered()
bytes b = fromHex(s.toStdString());
if (b.size() == 32)
{
auto k = KeyPair(h256(b));
auto k = KeyPair(Secret(bytesConstRef(&b)));
if (!m_keyManager.hasAccount(k.address()))
{
QString s = QInputDialog::getText(this, "Import Account Key", "Enter this account's name");
@ -1017,46 +1002,18 @@ void Main::on_claimPresale_triggered()
QString s = QFileDialog::getOpenFileName(this, "Claim Account Contents", QDir::homePath(), "JSON Files (*.json);;All Files (*)");
try
{
js::mValue val;
json_spirit::read_string(asString(dev::contents(s.toStdString())), val);
auto obj = val.get_obj();
if (obj["encseed"].type() == js::str_type)
{
auto encseed = fromHex(obj["encseed"].get_str());
KeyPair k;
for (bool gotit = false; !gotit;)
{
gotit = true;
k = KeyPair::fromEncryptedSeed(&encseed, QInputDialog::getText(this, "Enter Password", "Enter the wallet's passphrase", QLineEdit::Password).toStdString());
if (obj["ethaddr"].type() == js::str_type)
{
Address a(obj["ethaddr"].get_str());
Address b = k.address();
if (a != b)
{
if (QMessageBox::warning(this, "Password Wrong", "Could not import the secret key: the password you gave appears to be wrong.", QMessageBox::Retry, QMessageBox::Cancel) == QMessageBox::Cancel)
return;
else
gotit = false;
}
}
}
cnote << k.address();
if (!m_keyManager.hasAccount(k.address()))
ethereum()->submitTransaction(k.sec(), ethereum()->balanceAt(k.address()) - gasPrice() * c_txGas, m_beneficiary, {}, c_txGas, gasPrice());
else
QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account.");
}
KeyPair k = m_keyManager.presaleSecret(dev::contentsString(s.toStdString()), [&](bool){ return QInputDialog::getText(this, "Enter Password", "Enter the wallet's passphrase", QLineEdit::Password).toStdString(); });
cnote << k.address();
if (!m_keyManager.hasAccount(k.address()))
ethereum()->submitTransaction(k.sec(), ethereum()->balanceAt(k.address()) - gasPrice() * c_txGas, m_beneficiary, {}, c_txGas, gasPrice());
else
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("encseed type is not js::str_type") );
QMessageBox::warning(this, "Already Have Key", "Could not import the secret key: we already own this account.");
}
catch (dev::eth::PasswordUnknown&) {}
catch (...)
{
cerr << "Unhandled exception!" << endl <<
boost::current_exception_diagnostic_information();
QMessageBox::warning(this, "Key File Invalid", "Could not find secret key definition. This is probably not an Ethereum key file.");
}
}
@ -1068,7 +1025,7 @@ void Main::on_exportKey_triggered()
auto hba = ui->ourAccounts->currentItem()->data(Qt::UserRole).toByteArray();
Address h((byte const*)hba.data(), Address::ConstructFromPointer);
Secret s = retrieveSecret(h);
QMessageBox::information(this, "Export Account Key", "Secret key to account " + QString::fromStdString(render(h) + " is:\n" + s.hex()));
QMessageBox::information(this, "Export Account Key", "Secret key to account " + QString::fromStdString(render(h) + " is:\n" + s.makeInsecure().hex()));
}
}
@ -1340,9 +1297,7 @@ void Main::refreshAccounts()
bool showContract = ui->showContracts->isChecked();
bool showBasic = ui->showBasic->isChecked();
bool onlyNamed = ui->onlyNamed->isChecked();
auto as = ethereum()->addresses();
sort(as.begin(), as.end());
for (auto const& i: as)
for (auto const& i: ethereum()->addresses())
{
bool isContract = (ethereum()->codeHashAt(i) != EmptySHA3);
if (!((showContract && isContract) || (showBasic && !isContract)))

68
eth/main.cpp

@ -66,7 +66,7 @@ using namespace dev::eth;
using namespace boost::algorithm;
using dev::eth::Instruction;
static bool g_silence = false;
static std::atomic<bool> g_silence = {false};
void interactiveHelp()
{
@ -140,6 +140,7 @@ void help()
<< " -R,--rebuild Rebuild the blockchain from the existing database." << endl
<< " --rescue Attempt to rescue a corrupt database." << endl
<< endl
<< " --import-presale <file> Import a presale key; you'll need to type the password to this." << endl
<< " -s,--import-secret <secret> Import a secret key into the key store and use as the default." << endl
<< " -S,--import-session-secret <secret> Import a secret key into the key store and use as the default for this session only." << endl
<< " --sign-key <address> Sign all transactions with the key of the given address." << endl
@ -204,6 +205,10 @@ void help()
<< " -v,--verbosity <0 - 9> Set the log verbosity from 0 to 9 (default: 8)." << endl
<< " -V,--version Show the version and exit." << endl
<< " -h,--help Show this help message and exit." << endl
<< endl
<< "Experimental / Proof of Concept:" << endl
<< " --shh Enable Whisper" << endl
<< endl
;
exit(0);
}
@ -226,6 +231,12 @@ void version()
exit(0);
}
void importPresale(KeyManager& _km, string const& _file, function<string()> _pass)
{
KeyPair k = _km.presaleSecret(contentsString(_file), [&](bool){ return _pass(); });
_km.import(k.secret(), "Presale wallet" + _file + " (insecure)");
}
Address c_config = Address("ccdeac59d35627b7de09332e819d5159e7bb7250");
string pretty(h160 _a, dev::eth::State const& _st)
{
@ -280,10 +291,13 @@ enum class Format
Human
};
void stopMiningAfterXBlocks(eth::Client* _c, unsigned _start, unsigned _mining)
void stopMiningAfterXBlocks(eth::Client* _c, unsigned _start, unsigned& io_mining)
{
if (_c->isMining() && _c->blockChain().details().number - _start == _mining)
if (io_mining != ~(unsigned)0 && io_mining && _c->isMining() && _c->blockChain().details().number - _start == io_mining)
{
_c->stopMining();
io_mining = ~(unsigned)0;
}
this_thread::sleep_for(chrono::milliseconds(100));
}
@ -526,7 +540,7 @@ void interactiveMode(eth::Client* c, std::shared_ptr<eth::TrivialGasPricer> gasP
{
try
{
Secret secret = h256(fromHex(sechex));
Secret secret(fromHex(sechex));
Address dest = h160(fromHex(hexAddr));
c->submitTransaction(secret, amount, dest, data, gas, gasPrice);
}
@ -594,7 +608,7 @@ void interactiveMode(eth::Client* c, std::shared_ptr<eth::TrivialGasPricer> gasP
{
try
{
Secret secret = h256(fromHex(sechex));
Secret secret(fromHex(sechex));
Address dest = h160(fromHex(hexAddr));
c->submitTransaction(secret, amount, dest, data, gas, gasPrice, nonce);
}
@ -654,7 +668,7 @@ void interactiveMode(eth::Client* c, std::shared_ptr<eth::TrivialGasPricer> gasP
{
try
{
Secret secret = h256(fromHex(sechex));
Secret secret(fromHex(sechex));
cout << " new contract address : " << c->submitTransaction(secret, amount, data, gas, gasPrice) << endl;
}
catch (BadHexCharacter& _e)
@ -1094,6 +1108,7 @@ int main(int argc, char** argv)
string jsonAdmin;
string genesisJSON;
dev::eth::Network releaseNetwork = c_network;
u256 gasFloor = UndefinedU256;
string privateChain;
bool upnp = true;
@ -1120,6 +1135,7 @@ int main(int argc, char** argv)
Address signingKey;
Address sessionKey;
Address beneficiary = signingKey;
strings presaleImports;
/// Structured logging params
bool structuredLogging = false;
@ -1138,6 +1154,9 @@ int main(int argc, char** argv)
/// Wallet password stuff
string masterPassword;
/// Whisper
bool useWhisper = false;
string configFile = getDataDir() + "/config.rlp";
bytes b = contents(configFile);
@ -1147,13 +1166,7 @@ int main(int argc, char** argv)
if (b.size())
{
RLP config(b);
if (config[0].size() == 32) // secret key - import and forget.
{
Secret s = config[0].toHash<Secret>();
toImport.push_back(s);
}
else // new format - just use it as an address.
signingKey = config[0].toHash<Address>();
signingKey = config[0].toHash<Address>();
beneficiary = config[1].toHash<Address>();
}
@ -1300,13 +1313,13 @@ int main(int argc, char** argv)
else if ((arg == "-s" || arg == "--import-secret") && i + 1 < argc)
{
Secret s(fromHex(argv[++i]));
toImport.push_back(s);
toImport.emplace_back(s);
signingKey = toAddress(s);
}
else if ((arg == "-S" || arg == "--import-session-secret") && i + 1 < argc)
{
Secret s(fromHex(argv[++i]));
toImport.push_back(s);
toImport.emplace_back(s);
sessionKey = toAddress(s);
}
else if ((arg == "--sign-key") && i + 1 < argc)
@ -1324,7 +1337,7 @@ int main(int argc, char** argv)
}
else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc)
dbPath = argv[++i];
else if (arg == "--genesis-json" && i + 1 < argc)
else if ((arg == "--genesis-json" || arg == "--genesis") && i + 1 < argc)
{
try
{
@ -1338,6 +1351,8 @@ int main(int argc, char** argv)
}
else if (arg == "--frontier")
releaseNetwork = eth::Network::Frontier;
else if (arg == "--gas-floor" && i + 1 < argc)
gasFloor = u256(argv[++i]);
else if (arg == "--olympic")
releaseNetwork = eth::Network::Olympic;
/* else if ((arg == "-B" || arg == "--block-fees") && i + 1 < argc)
@ -1434,6 +1449,8 @@ int main(int argc, char** argv)
pinning = true;
else if (arg == "--hermit")
pinning = disableDiscovery = true;
else if (arg == "--import-presale" && i + 1 < argc)
presaleImports.push_back(argv[++i]);
else if (arg == "-f" || arg == "--force-mining")
forceMining = true;
else if (arg == "--old-interactive")
@ -1484,6 +1501,8 @@ int main(int argc, char** argv)
}
}
#endif
else if (arg == "--shh")
useWhisper = true;
else if (arg == "-h" || arg == "--help")
help();
else if (arg == "-V" || arg == "--version")
@ -1501,6 +1520,8 @@ int main(int argc, char** argv)
CanonBlockChain<Ethash>::forceGenesisExtraData(sha3(privateChain).asBytes());
if (!genesisJSON.empty())
CanonBlockChain<Ethash>::setGenesis(genesisJSON);
if (gasFloor != UndefinedU256)
c_gasFloorTarget = gasFloor;
if (g_logVerbosity > 0)
{
@ -1547,7 +1568,7 @@ int main(int argc, char** argv)
};
auto getPassword = [&](string const& prompt){
auto s = g_silence;
bool s = g_silence;
g_silence = true;
cout << endl;
string ret = dev::getPassword(prompt);
@ -1564,11 +1585,12 @@ int main(int argc, char** argv)
netPrefs.pin = pinning || !privateChain.empty();
auto nodesState = contents((dbPath.size() ? dbPath : getDataDir()) + "/network.rlp");
auto caps = useWhisper ? set<string>{"eth", "shh"} : set<string>{"eth"};
dev::WebThreeDirect web3(
WebThreeDirect::composeClientVersion("++eth", clientName),
dbPath,
withExisting,
nodeMode == NodeMode::Full ? set<string>{"eth"/*, "shh"*/} : set<string>(),
nodeMode == NodeMode::Full ? caps : set<string>(),
netPrefs,
&nodesState);
web3.ethereum()->setMineOnBadChain(mineOnWrongChain);
@ -1711,6 +1733,9 @@ int main(int argc, char** argv)
keyManager.create(masterPassword);
}
for (auto const& presale: presaleImports)
importPresale(keyManager, presale, [&](){ return getPassword("Enter your wallet password for " + presale + ": "); });
for (auto const& s: toImport)
{
keyManager.import(s, "Imported key (UNSAFE)");
@ -1762,9 +1787,9 @@ int main(int argc, char** argv)
jsonrpcServer->setMiningBenefactorChanger([&](Address const& a) { beneficiary = a; });
jsonrpcServer->StartListening();
if (jsonAdmin.empty())
jsonAdmin = jsonrpcServer->newSession(SessionPermissions{{Priviledge::Admin}});
jsonAdmin = jsonrpcServer->newSession(SessionPermissions{{Privilege::Admin}});
else
jsonrpcServer->addSession(jsonAdmin, SessionPermissions{{Priviledge::Admin}});
jsonrpcServer->addSession(jsonAdmin, SessionPermissions{{Privilege::Admin}});
cout << "JSONRPC Admin Session Key: " << jsonAdmin << endl;
writeFile(getDataDir("web3") + "/session.key", jsonAdmin);
writeFile(getDataDir("web3") + "/session.url", "http://localhost:" + toString(jsonRPCURL));
@ -1793,7 +1818,8 @@ int main(int argc, char** argv)
#if ETH_JSCONSOLE || !ETH_TRUE
JSLocalConsole console;
shared_ptr<dev::WebThreeStubServer> rpcServer = make_shared<dev::WebThreeStubServer>(*console.connector(), web3, make_shared<SimpleAccountHolder>([&](){ return web3.ethereum(); }, getAccountPassword, keyManager), vector<KeyPair>(), keyManager, *gasPricer);
console.eval("web3.admin.setSessionKey('" + jsonAdmin + "')");
string sessionKey = rpcServer->newSession(SessionPermissions{{Privilege::Admin}});
console.eval("web3.admin.setSessionKey('" + sessionKey + "')");
while (!g_exit)
{
console.readExpression();

43
ethkey/KeyAux.h

@ -104,6 +104,7 @@ public:
New,
Import,
ImportWithAddress,
ImportPresale,
Export,
Recode,
Kill,
@ -143,7 +144,7 @@ public:
m_mode = OperationMode::DecodeTx;
else if (arg == "--import-bare")
m_mode = OperationMode::ImportBare;
else if (arg == "--list-bare")
else if (arg == "-l" || arg == "--list-bare")
m_mode = OperationMode::ListBare;
else if (arg == "--export-bare")
m_mode = OperationMode::ExportBare;
@ -168,7 +169,13 @@ public:
m_inputs = strings(1, argv[++i]);
m_name = argv[++i];
}
else if ((arg == "-i" || arg == "--import-with-address") && i + 3 < argc)
else if (arg == "--import-presale" && i + 2 < argc)
{
m_mode = OperationMode::ImportPresale;
m_inputs = strings(1, argv[++i]);
m_name = argv[++i];
}
else if (arg == "--import-with-address" && i + 3 < argc)
{
m_mode = OperationMode::ImportWithAddress;
m_inputs = strings(1, argv[++i]);
@ -192,7 +199,7 @@ public:
{
KeyPair k(Secret::random());
while (m_icap && k.address()[0])
k = KeyPair(sha3(k.secret()));
k = KeyPair(Secret(sha3(k.secret().ref())));
return k;
}
@ -352,7 +359,7 @@ public:
if (m_lock.empty())
m_lock = createPassword("Enter a password with which to secure this account: ");
auto k = makeKey();
h128 u = store.importSecret(k.secret().asBytes(), m_lock);
h128 u = store.importSecret(k.secret().ref(), m_lock);
cout << "Created key " << toUUID(u) << endl;
cout << " Address: " << k.address().hex() << endl;
cout << " ICAP: " << ICAP(k.address()).encoded() << endl;
@ -362,12 +369,12 @@ public:
for (string const& input: m_inputs)
{
h128 u;
bytes b;
b = fromHex(input);
bytesSec b;
b.writable() = fromHex(input);
if (b.size() != 32)
{
std::string s = contentsString(input);
b = fromHex(s);
b.writable() = fromHex(s);
if (b.size() != 32)
u = store.importKey(input);
}
@ -386,18 +393,18 @@ public:
if (!contents(i).empty())
{
h128 u = store.readKey(i, false);
bytes s = store.secret(u, [&](){ return getPassword("Enter password for key " + i + ": "); });
bytesSec s = store.secret(u, [&](){ return getPassword("Enter password for key " + i + ": "); });
cout << "Key " << i << ":" << endl;
cout << " UUID: " << toUUID(u) << ":" << endl;
cout << " Address: " << toAddress(Secret(s)).hex() << endl;
cout << " Secret: " << Secret(s).abridged() << endl;
cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
}
else if (h128 u = fromUUID(i))
{
bytes s = store.secret(u, [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); });
bytesSec s = store.secret(u, [&](){ return getPassword("Enter password for key " + toUUID(u) + ": "); });
cout << "Key " << i << ":" << endl;
cout << " Address: " << toAddress(Secret(s)).hex() << endl;
cout << " Secret: " << Secret(s).abridged() << endl;
cout << " Secret: " << toHex(s.ref().cropped(0, 8)) << "..." << endl;
}
else
cerr << "Couldn't inspect " << i << "; not found." << endl;
@ -454,12 +461,12 @@ public:
{
string const& i = m_inputs[0];
h128 u;
bytes b;
b = fromHex(i);
bytesSec b;
b.writable() = fromHex(i);
if (b.size() != 32)
{
std::string s = contentsString(i);
b = fromHex(s);
b.writable() = fromHex(s);
if (b.size() != 32)
u = wallet.store().importKey(i);
}
@ -477,6 +484,13 @@ public:
cout << " UUID: " << toUUID(u) << endl;
break;
}
case OperationMode::ImportPresale:
{
std::string pw;
KeyPair k = wallet.presaleSecret(contentsString(m_inputs[0]), [&](bool){ return (pw = getPassword("Enter the password for the presale key: ")); });
wallet.import(k.secret(), m_name, pw, "Same password as used for presale key");
break;
}
case OperationMode::List:
{
vector<u128> bare;
@ -530,6 +544,7 @@ public:
<< " -l,--list List all keys available in wallet." << endl
<< " -n,--new <name> Create a new key with given name and add it in the wallet." << endl
<< " -i,--import [<uuid>|<file>|<secret-hex>] <name> Import keys from given source and place in wallet." << endl
<< " --import-presale <file> <name> Import a presale wallet into a key with the given name." << endl
<< " --import-with-address [<uuid>|<file>|<secret-hex>] <address> <name> Import keys from given source with given address and place in wallet." << endl
<< " -e,--export [ <address>|<uuid> , ... ] Export given keys." << endl
<< " -r,--recode [ <address>|<uuid>|<file> , ... ] Decrypt and re-encrypt given keys." << endl

1
ethminer/CMakeLists.txt

@ -30,6 +30,7 @@ endif()
target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} ethash)
target_link_libraries(${EXECUTABLE} devcrypto)
if (DEFINED WIN32 AND NOT DEFINED CMAKE_COMPILER_IS_MINGW)
eth_copy_dlls("${EXECUTABLE}" MHD_DLLS)

14
evmjit/include/evmjit/JIT-c.h

@ -1,6 +1,14 @@
#include "stdint.h"
#ifdef _MSC_VER
#define EXPORT __declspec(dllexport)
#define _ALLOW_KEYWORD_MACROS
#define noexcept throw()
#else
#define EXPORT
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -51,11 +59,11 @@ typedef enum evmjit_return_code
typedef struct evmjit_context evmjit_context;
evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env);
EXPORT evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env);
evmjit_return_code evmjit_exec(evmjit_context* _context);
EXPORT evmjit_return_code evmjit_exec(evmjit_context* _context);
void evmjit_destroy(evmjit_context* _context);
EXPORT void evmjit_destroy(evmjit_context* _context);
inline char const* evmjit_get_output(evmjit_runtime_data* _data) { return _data->callData; }

6
evmjit/libevmjit/JIT-c.cpp

@ -6,7 +6,7 @@ extern "C"
{
using namespace dev::evmjit;
EXPORT evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env)
evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env)
{
auto data = reinterpret_cast<RuntimeData*>(_data);
auto env = reinterpret_cast<Env*>(_env);
@ -20,13 +20,13 @@ EXPORT evmjit_context* evmjit_create(evmjit_runtime_data* _data, void* _env)
return reinterpret_cast<evmjit_context*>(context);
}
EXPORT void evmjit_destroy(evmjit_context* _context)
void evmjit_destroy(evmjit_context* _context)
{
auto context = reinterpret_cast<ExecutionContext*>(_context);
delete context;
}
EXPORT evmjit_return_code evmjit_exec(evmjit_context* _context)
evmjit_return_code evmjit_exec(evmjit_context* _context)
{
auto context = reinterpret_cast<ExecutionContext*>(_context);

8
extdep/getstuff.bat

@ -27,13 +27,13 @@ set eth_version=%2
cd download
if not exist %eth_name%-%eth_version%.tar.gz (
for /f "tokens=2 delims={}" %%g in ('bitsadmin /create %eth_name%-%eth_version%.tar.gz') do (
bitsadmin /transfer {%%g} /download /priority normal %eth_server%/%eth_name%-%eth_version%.tar.gz %cd%\%eth_name%-%eth_version%.tar.gz
if not exist %eth_name%-%eth_version%-x64.tar.gz (
for /f "tokens=2 delims={}" %%g in ('bitsadmin /create %eth_name%-%eth_version%-x64.tar.gz') do (
bitsadmin /transfer {%%g} /download /priority normal %eth_server%/%eth_name%-%eth_version%-x64.tar.gz %cd%\%eth_name%-%eth_version%-x64.tar.gz
bitsadmin /cancel {%%g}
)
)
if not exist %eth_name%-%eth_version% cmake -E tar -zxvf %eth_name%-%eth_version%.tar.gz
if not exist %eth_name%-%eth_version% cmake -E tar -zxvf %eth_name%-%eth_version%-x64.tar.gz
cmake -E copy_directory %eth_name%-%eth_version% ..\install\windows
cd ..

4
libdevcore/Common.cpp

@ -22,13 +22,14 @@
#include "Common.h"
#include "Exceptions.h"
#include "Log.h"
#include "BuildInfo.h"
using namespace std;
using namespace dev;
namespace dev
{
char const* Version = "0.9.34";
char const* Version = ETH_PROJECT_VERSION;
const u256 UndefinedU256 = ~(u256)0;
@ -57,4 +58,3 @@ TimerHelper::~TimerHelper()
}
}

33
libdevcore/Common.h

@ -79,6 +79,39 @@ using bytes = std::vector<byte>;
using bytesRef = vector_ref<byte>;
using bytesConstRef = vector_ref<byte const>;
template <class T>
class secure_vector
{
public:
secure_vector() {}
secure_vector(secure_vector<T> const& _c) = default;
explicit secure_vector(unsigned _size): m_data(_size) {}
explicit secure_vector(unsigned _size, T _item): m_data(_size, _item) {}
explicit secure_vector(std::vector<T> const& _c): m_data(_c) {}
explicit secure_vector(vector_ref<T> _c): m_data(_c.data(), _c.data() + _c.size()) {}
explicit secure_vector(vector_ref<const T> _c): m_data(_c.data(), _c.data() + _c.size()) {}
~secure_vector() { ref().cleanse(); }
secure_vector<T>& operator=(secure_vector<T> const& _c) { ref().cleanse(); m_data = _c.m_data; return *this; }
std::vector<T>& writable() { clear(); return m_data; }
std::vector<T> const& makeInsecure() const { return m_data; }
void clear() { ref().cleanse(); }
vector_ref<T> ref() { return vector_ref<T>(&m_data); }
vector_ref<T const> ref() const { return vector_ref<T const>(&m_data); }
size_t size() const { return m_data.size(); }
bool empty() const { return m_data.empty(); }
void swap(secure_vector<T>& io_other) { m_data.swap(io_other.m_data); }
private:
std::vector<T> m_data;
};
using bytesSec = secure_vector<byte>;
// Numeric types.
using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
using u64 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<64, 64, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;

11
libdevcore/CommonJS.h

@ -51,10 +51,17 @@ inline std::string toJS(bytes const& _n, std::size_t _padding = 0)
return "0x" + toHex(n);
}
template< typename T >std::string toJS( T const& i )
template<unsigned T> std::string toJS(SecureFixedHash<T> const& _i)
{
std::stringstream stream;
stream << "0x" << std::hex << i;
stream << "0x" << _i.makeInsecure().hex();
return stream.str();
}
template<typename T> std::string toJS(T const& _i)
{
std::stringstream stream;
stream << "0x" << std::hex << _i;
return stream.str();
}

81
libdevcore/FixedHash.h

@ -214,10 +214,83 @@ public:
return ret;
}
void clear() { m_data.fill(0); }
private:
std::array<byte, N> m_data; ///< The binary data.
};
template <unsigned T>
class SecureFixedHash: private FixedHash<T>
{
public:
using ConstructFromHashType = typename FixedHash<T>::ConstructFromHashType;
using ConstructFromStringType = typename FixedHash<T>::ConstructFromStringType;
using ConstructFromPointerType = typename FixedHash<T>::ConstructFromPointerType;
SecureFixedHash() = default;
explicit SecureFixedHash(bytes const& _b, ConstructFromHashType _t = FixedHash<T>::FailIfDifferent): FixedHash<T>(_b, _t) {}
explicit SecureFixedHash(bytesConstRef _b, ConstructFromHashType _t = FixedHash<T>::FailIfDifferent): FixedHash<T>(_b, _t) {}
explicit SecureFixedHash(bytesSec const& _b, ConstructFromHashType _t = FixedHash<T>::FailIfDifferent): FixedHash<T>(_b.ref(), _t) {}
template <unsigned M> explicit SecureFixedHash(FixedHash<M> const& _h, ConstructFromHashType _t = FixedHash<T>::AlignLeft): FixedHash<T>(_h, _t) {}
template <unsigned M> explicit SecureFixedHash(SecureFixedHash<M> const& _h, ConstructFromHashType _t = FixedHash<T>::AlignLeft): FixedHash<T>(_h.makeInsecure(), _t) {}
explicit SecureFixedHash(std::string const& _s, ConstructFromStringType _t = FixedHash<T>::FromHex, ConstructFromHashType _ht = FixedHash<T>::FailIfDifferent): FixedHash<T>(_s, _t, _ht) {}
explicit SecureFixedHash(bytes const* _d, ConstructFromPointerType _t): FixedHash<T>(_d, _t) {}
~SecureFixedHash() { ref().cleanse(); }
SecureFixedHash<T>& operator=(SecureFixedHash<T> const& _c) { ref().cleanse(); FixedHash<T>::operator=(static_cast<FixedHash<T> const&>(_c)); return *this; }
using FixedHash<T>::size;
bytesSec asBytesSec() const { return bytesSec(ref()); }
FixedHash<T> const& makeInsecure() const { return static_cast<FixedHash<T> const&>(*this); }
FixedHash<T>& writable() { clear(); return static_cast<FixedHash<T>&>(*this); }
using FixedHash<T>::operator bool;
// The obvious comparison operators.
bool operator==(SecureFixedHash const& _c) const { return static_cast<FixedHash<T> const&>(*this).operator==(static_cast<FixedHash<T> const&>(_c)); }
bool operator!=(SecureFixedHash const& _c) const { return static_cast<FixedHash<T> const&>(*this).operator!=(static_cast<FixedHash<T> const&>(_c)); }
bool operator<(SecureFixedHash const& _c) const { return static_cast<FixedHash<T> const&>(*this).operator<(static_cast<FixedHash<T> const&>(_c)); }
bool operator>=(SecureFixedHash const& _c) const { return static_cast<FixedHash<T> const&>(*this).operator>=(static_cast<FixedHash<T> const&>(_c)); }
bool operator<=(SecureFixedHash const& _c) const { return static_cast<FixedHash<T> const&>(*this).operator<=(static_cast<FixedHash<T> const&>(_c)); }
bool operator>(SecureFixedHash const& _c) const { return static_cast<FixedHash<T> const&>(*this).operator>(static_cast<FixedHash<T> const&>(_c)); }
using FixedHash<T>::operator==;
using FixedHash<T>::operator!=;
using FixedHash<T>::operator<;
using FixedHash<T>::operator>=;
using FixedHash<T>::operator<=;
using FixedHash<T>::operator>;
// The obvious binary operators.
SecureFixedHash& operator^=(FixedHash<T> const& _c) { static_cast<FixedHash<T>&>(*this).operator^=(_c); return *this; }
SecureFixedHash operator^(FixedHash<T> const& _c) const { return SecureFixedHash(*this) ^= _c; }
SecureFixedHash& operator|=(FixedHash<T> const& _c) { static_cast<FixedHash<T>&>(*this).operator^=(_c); return *this; }
SecureFixedHash operator|(FixedHash<T> const& _c) const { return SecureFixedHash(*this) |= _c; }
SecureFixedHash& operator&=(FixedHash<T> const& _c) { static_cast<FixedHash<T>&>(*this).operator^=(_c); return *this; }
SecureFixedHash operator&(FixedHash<T> const& _c) const { return SecureFixedHash(*this) &= _c; }
SecureFixedHash& operator^=(SecureFixedHash const& _c) { static_cast<FixedHash<T>&>(*this).operator^=(static_cast<FixedHash<T> const&>(_c)); return *this; }
SecureFixedHash operator^(SecureFixedHash const& _c) const { return SecureFixedHash(*this) ^= _c; }
SecureFixedHash& operator|=(SecureFixedHash const& _c) { static_cast<FixedHash<T>&>(*this).operator^=(static_cast<FixedHash<T> const&>(_c)); return *this; }
SecureFixedHash operator|(SecureFixedHash const& _c) const { return SecureFixedHash(*this) |= _c; }
SecureFixedHash& operator&=(SecureFixedHash const& _c) { static_cast<FixedHash<T>&>(*this).operator^=(static_cast<FixedHash<T> const&>(_c)); return *this; }
SecureFixedHash operator&(SecureFixedHash const& _c) const { return SecureFixedHash(*this) &= _c; }
SecureFixedHash operator~() const { ~static_cast<FixedHash<T>&>(*this); return *this; }
using FixedHash<T>::abridged;
using FixedHash<T>::abridgedMiddle;
bytesConstRef ref() const { return FixedHash<T>::ref(); }
byte const* data() const { return FixedHash<T>::data(); }
static SecureFixedHash<T> random() { SecureFixedHash<T> ret; ret.FixedHash<T>::ref().randomize(); return ret; }
using FixedHash<T>::firstBitSet;
void clear() { ref().cleanse(); }
};
/// Fast equality operator for h256.
template<> inline bool FixedHash<32>::operator==(FixedHash<32> const& _other) const
{
@ -244,6 +317,14 @@ inline std::ostream& operator<<(std::ostream& _out, FixedHash<N> const& _h)
return _out;
}
/// Stream I/O for the SecureFixedHash class.
template <unsigned N>
inline std::ostream& operator<<(std::ostream& _out, SecureFixedHash<N> const& _h)
{
_out << "SecureFixedHash#" << std::hex << typename FixedHash<N>::hash()(_h.makeInsecure()) << std::dec;
return _out;
}
// Common types of FixedHash.
using h2048 = FixedHash<256>;
using h1024 = FixedHash<128>;

9
libdevcore/SHA3.cpp

@ -211,13 +211,14 @@ defsha3(512)
}
h256 sha3(bytesConstRef _input)
bool sha3(bytesConstRef _input, bytesRef o_output)
{
// FIXME: What with unaligned memory?
h256 ret;
keccak::sha3_256(ret.data(), 32, _input.data(), _input.size());
if (o_output.size() != 32)
return false;
keccak::sha3_256(o_output.data(), 32, _input.data(), _input.size());
// keccak::keccak(ret.data(), 32, (uint64_t const*)_input.data(), _input.size());
return ret;
return true;
}
}

19
libdevcore/SHA3.h

@ -32,20 +32,31 @@ namespace dev
// SHA-3 convenience routines.
/// 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); }
/// @returns false if o_output.size() != 32.
bool sha3(bytesConstRef _input, bytesRef o_output);
/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.
inline h256 sha3(bytesConstRef _input) { h256 ret; sha3(_input, ret.ref()); return ret; }
inline SecureFixedHash<32> sha3Secure(bytesConstRef _input) { SecureFixedHash<32> ret; sha3(_input, ret.writable().ref()); return ret; }
/// Calculate SHA3-256 hash of the given input, returning as a 256-bit hash.
inline h256 sha3(bytes const& _input) { return sha3(bytesConstRef(&_input)); }
inline SecureFixedHash<32> sha3Secure(bytes const& _input) { return sha3Secure(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)); }
inline SecureFixedHash<32> sha3Secure(std::string const& _input) { return sha3Secure(bytesConstRef(_input)); }
/// 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()); }
template<unsigned N> inline SecureFixedHash<32> sha3Secure(FixedHash<N> const& _input) { return sha3Secure(_input.ref()); }
/// Fully secure variants are equivalent for sha3 and sha3Secure.
inline SecureFixedHash<32> sha3(bytesSec const& _input) { return sha3Secure(_input.ref()); }
inline SecureFixedHash<32> sha3Secure(bytesSec const& _input) { return sha3Secure(_input.ref()); }
template<unsigned N> inline SecureFixedHash<32> sha3(SecureFixedHash<N> const& _input) { return sha3Secure(_input.ref()); }
template<unsigned N> inline SecureFixedHash<32> sha3Secure(SecureFixedHash<N> const& _input) { return sha3Secure(_input.ref()); }
/// 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()); }

32
libdevcore/vector_ref.h

@ -5,10 +5,14 @@
#include <type_traits>
#include <vector>
#include <string>
#include <random>
namespace dev
{
static unsigned char s_cleanseCounter = 0;
static std::random_device s_vectorRefEngine;
/**
* A modifiable reference to an existing object or vector in memory.
*/
@ -65,6 +69,34 @@ public:
void copyTo(vector_ref<typename std::remove_const<_T>::type> _t) const { if (overlapsWith(_t)) memmove(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); else memcpy(_t.data(), m_data, std::min(_t.size(), m_count) * sizeof(_T)); }
/// Copies the contents of this vector_ref to the contents of @a _t, and zeros further trailing elements in @a _t.
void populate(vector_ref<typename std::remove_const<_T>::type> _t) const { copyTo(_t); memset(_t.data() + m_count, 0, std::max(_t.size(), m_count) - m_count); }
/// Populate with random data.
template <class Engine>
void randomize(Engine& _eng)
{
uint8_t* e = (uint8_t*)end();
for (uint8_t* i = (uint8_t*)begin(); i != e; ++i)
*i = (uint8_t)std::uniform_int_distribution<uint16_t>(0, 255)(_eng);
}
/// @returns a random valued object.
void randomize() { randomize(s_vectorRefEngine); }
/// Securely overwrite the memory.
/// @note adapted from OpenSSL's implementation.
void cleanse()
{
uint8_t* p = (uint8_t*)begin();
size_t len = (uint8_t*)end() - p;
size_t loop = len;
size_t count = s_cleanseCounter;
while (loop--)
{
*(p++) = (uint8_t)count;
count += (17 + ((size_t)p & 0xf));
}
p = (uint8_t*)memchr((uint8_t*)begin(), (uint8_t)count, len);
if (p)
count += (63 + (size_t)p);
s_cleanseCounter = (uint8_t)count;
}
_T* begin() { return m_data; }
_T* end() { return m_data + m_count; }

2
libdevcrypto/AES.h

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

46
libdevcrypto/Common.cpp

@ -149,7 +149,7 @@ bool dev::decryptSym(Secret const& _k, bytesConstRef _cipher, bytes& o_plain)
return decrypt(_k, _cipher, o_plain);
}
std::pair<bytes, h128> dev::encryptSymNoAuth(h128 const& _k, bytesConstRef _plain)
std::pair<bytes, h128> dev::encryptSymNoAuth(SecureFixedHash<16> const& _k, bytesConstRef _plain)
{
h128 iv(Nonce::get());
return make_pair(encryptSymNoAuth(_k, iv, _plain), iv);
@ -175,23 +175,23 @@ bytes dev::encryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _pl
}
}
bytes dev::decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher)
bytesSec dev::decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher)
{
if (_k.size() != 16 && _k.size() != 24 && _k.size() != 32)
return bytes();
return bytesSec();
SecByteBlock key(_k.data(), _k.size());
try
{
CTR_Mode<AES>::Decryption d;
d.SetKeyWithIV(key, key.size(), _iv.data());
bytes ret(_cipher.size());
d.ProcessData(ret.data(), _cipher.data(), _cipher.size());
bytesSec ret(_cipher.size());
d.ProcessData(ret.writable().data(), _cipher.data(), _cipher.size());
return ret;
}
catch (CryptoPP::Exception& _e)
{
cerr << _e.what() << endl;
return bytes();
return bytesSec();
}
}
@ -239,12 +239,12 @@ bool dev::verify(Public const& _p, Signature const& _s, h256 const& _hash)
#endif
}
bytes dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen)
bytesSec dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen)
{
bytes ret(_dkLen);
bytesSec ret(_dkLen);
if (PKCS5_PBKDF2_HMAC<SHA256>().DeriveKey(
ret.data(),
ret.size(),
ret.writable().data(),
_dkLen,
0,
reinterpret_cast<byte const*>(_pass.data()),
_pass.size(),
@ -256,9 +256,9 @@ bytes dev::pbkdf2(string const& _pass, bytes const& _salt, unsigned _iterations,
return ret;
}
bytes dev::scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen)
bytesSec dev::scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen)
{
bytes ret(_dkLen);
bytesSec ret(_dkLen);
if (libscrypt_scrypt(
reinterpret_cast<uint8_t const*>(_pass.data()),
_pass.size(),
@ -267,34 +267,34 @@ bytes dev::scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uin
_n,
_r,
_p,
ret.data(),
ret.size()
ret.writable().data(),
_dkLen
) != 0)
BOOST_THROW_EXCEPTION(CryptoException() << errinfo_comment("Key derivation failed."));
return ret;
}
void KeyPair::populateFromSecret(Secret const& _sec)
{
m_secret = _sec;
if (s_secp256k1pp.verifySecret(m_secret, m_public))
m_address = toAddress(m_public);
}
KeyPair KeyPair::create()
{
for (int i = 0; i < 100; ++i)
{
KeyPair ret(FixedHash<32>::random());
KeyPair ret(Secret::random());
if (ret.address())
return ret;
}
return KeyPair();
}
KeyPair::KeyPair(h256 _sec):
m_secret(_sec)
{
if (s_secp256k1pp.verifySecret(m_secret, m_public))
m_address = toAddress(m_public);
}
KeyPair KeyPair::fromEncryptedSeed(bytesConstRef _seed, std::string const& _password)
{
return KeyPair(sha3(aesDecrypt(_seed, _password)));
return KeyPair(Secret(sha3(aesDecrypt(_seed, _password))));
}
h256 crypto::kdf(Secret const& _priv, h256 const& _hash)

30
libdevcrypto/Common.h

@ -32,9 +32,7 @@
namespace dev
{
/// A secret key: 32 bytes.
/// @NOTE This is not endian-specific; it's just a bunch of bytes.
using Secret = h256;
using Secret = SecureFixedHash<32>;
/// A public key: 64 bytes.
/// @NOTE This is not endian-specific; it's just a bunch of bytes.
@ -76,7 +74,7 @@ using Addresses = h160s;
using AddressHash = std::unordered_set<h160>;
/// A vector of secrets.
using Secrets = h256s;
using Secrets = std::vector<Secret>;
/// Convert a secret key into the public key equivalent.
Public toPublic(Secret const& _secret);
@ -110,21 +108,21 @@ void encryptECIES(Public const& _k, bytesConstRef _plain, bytes& o_cipher);
bool decryptECIES(Secret const& _k, bytesConstRef _cipher, bytes& o_plaintext);
/// Encrypts payload with random IV/ctr using AES128-CTR.
std::pair<bytes, h128> encryptSymNoAuth(h128 const& _k, bytesConstRef _plain);
std::pair<bytes, h128> encryptSymNoAuth(SecureFixedHash<16> const& _k, bytesConstRef _plain);
/// Encrypts payload with specified IV/ctr using AES128-CTR.
bytes encryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _plain);
/// Decrypts payload with specified IV/ctr using AES128-CTR.
bytes decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher);
bytesSec decryptAES128CTR(bytesConstRef _k, h128 const& _iv, bytesConstRef _cipher);
/// Encrypts payload with specified IV/ctr using AES128-CTR.
inline bytes encryptSymNoAuth(h128 const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); }
inline bytes encryptSymNoAuth(h256 const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); }
inline bytes encryptSymNoAuth(SecureFixedHash<16> const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); }
inline bytes encryptSymNoAuth(SecureFixedHash<32> const& _k, h128 const& _iv, bytesConstRef _plain) { return encryptAES128CTR(_k.ref(), _iv, _plain); }
/// Decrypts payload with specified IV/ctr using AES128-CTR.
inline bytes decryptSymNoAuth(h128 const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); }
inline bytes decryptSymNoAuth(h256 const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); }
inline bytesSec decryptSymNoAuth(SecureFixedHash<16> const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); }
inline bytesSec decryptSymNoAuth(SecureFixedHash<32> const& _k, h128 const& _iv, bytesConstRef _cipher) { return decryptAES128CTR(_k.ref(), _iv, _cipher); }
/// Recovers Public key from signed message hash.
Public recover(Signature const& _sig, h256 const& _hash);
@ -136,10 +134,10 @@ Signature sign(Secret const& _k, h256 const& _hash);
bool verify(Public const& _k, Signature const& _s, h256 const& _hash);
/// Derive key via PBKDF2.
bytes pbkdf2(std::string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen = 32);
bytesSec pbkdf2(std::string const& _pass, bytes const& _salt, unsigned _iterations, unsigned _dkLen = 32);
/// Derive key via Scrypt.
bytes scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen);
bytesSec scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uint32_t _r, uint32_t _p, unsigned _dkLen);
/// Simple class that represents a "key pair".
/// All of the data of the class can be regenerated from the secret key (m_secret) alone.
@ -151,7 +149,7 @@ public:
KeyPair() {}
/// Normal constructor - populates object from the given secret key.
KeyPair(Secret _k);
KeyPair(Secret const& _k) { populateFromSecret(_k); }
/// Create a new, randomly generated object.
static KeyPair create();
@ -170,10 +168,12 @@ public:
/// Retrieve the associated address of the public key.
Address const& address() const { return m_address; }
bool operator==(KeyPair const& _c) const { return m_secret == _c.m_secret; }
bool operator!=(KeyPair const& _c) const { return m_secret != _c.m_secret; }
bool operator==(KeyPair const& _c) const { return m_public == _c.m_public; }
bool operator!=(KeyPair const& _c) const { return m_public != _c.m_public; }
private:
void populateFromSecret(Secret const& _k);
Secret m_secret;
Public m_public;
Address m_address;

18
libdevcrypto/CryptoPP.cpp

@ -33,7 +33,7 @@ static_assert(dev::Secret::size == 32, "Secret key must be 32 bytes.");
static_assert(dev::Public::size == 64, "Public key must be 64 bytes.");
static_assert(dev::Signature::size == 65, "Signature must be 65 bytes.");
bytes Secp256k1PP::eciesKDF(Secret _z, bytes _s1, unsigned kdByteLen)
bytes Secp256k1PP::eciesKDF(Secret const& _z, bytes _s1, unsigned kdByteLen)
{
auto reps = ((kdByteLen + 7) * 8) / (CryptoPP::SHA256::BLOCKSIZE * 8);
// SEC/ISO/Shoup specify counter size SHOULD be equivalent
@ -67,7 +67,7 @@ void Secp256k1PP::encryptECIES(Public const& _k, bytes& io_cipher)
{
// interop w/go ecies implementation
auto r = KeyPair::create();
h256 z;
Secret z;
ecdh::agree(r.sec(), _k, z);
auto key = eciesKDF(z, bytes(), 32);
bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16);
@ -77,7 +77,7 @@ void Secp256k1PP::encryptECIES(Public const& _k, bytes& io_cipher)
bytes mKey(32);
ctx.Final(mKey.data());
bytes cipherText = encryptSymNoAuth(h128(eKey), h128(), bytesConstRef(&io_cipher));
bytes cipherText = encryptSymNoAuth(SecureFixedHash<16>(eKey), h128(), bytesConstRef(&io_cipher));
if (cipherText.empty())
return;
@ -110,8 +110,8 @@ bool Secp256k1PP::decryptECIES(Secret const& _k, bytes& io_text)
// invalid message: length
return false;
h256 z;
ecdh::agree(_k, *(Public*)(io_text.data()+1), z);
Secret z;
ecdh::agree(_k, *(Public*)(io_text.data() + 1), z);
auto key = eciesKDF(z, bytes(), 64);
bytesConstRef eKey = bytesConstRef(&key).cropped(0, 16);
bytesRef mKeyMaterial = bytesRef(&key).cropped(16, 16);
@ -137,7 +137,7 @@ bool Secp256k1PP::decryptECIES(Secret const& _k, bytes& io_text)
if (mac[i] != msgMac[i])
return false;
plain = decryptSymNoAuth(h128(eKey), iv, cipherNoIV);
plain = decryptSymNoAuth(SecureFixedHash<16>(eKey), iv, cipherNoIV).makeInsecure();
io_text.resize(plain.size());
io_text.swap(plain);
@ -222,7 +222,7 @@ Signature Secp256k1PP::sign(Secret const& _key, h256 const& _hash)
Integer kInv = k.InverseMod(m_q);
Integer z(_hash.asBytes().data(), 32);
Integer s = (kInv * (Integer(_key.asBytes().data(), 32) * r + z)) % m_q;
Integer s = (kInv * (Integer(_key.data(), 32) * r + z)) % m_q;
if (r == 0 || s == 0)
BOOST_THROW_EXCEPTION(InvalidState());
@ -310,7 +310,7 @@ bool Secp256k1PP::verifySecret(Secret const& _s, Public& _p)
return true;
}
void Secp256k1PP::agree(Secret const& _s, Public const& _r, h256& o_s)
void Secp256k1PP::agree(Secret const& _s, Public const& _r, Secret& o_s)
{
// TODO: mutex ASN1::secp256k1() singleton
// Creating Domain is non-const for m_oid and m_oid is not thread-safe
@ -318,7 +318,7 @@ void Secp256k1PP::agree(Secret const& _s, Public const& _r, h256& o_s)
assert(d.AgreedValueLength() == sizeof(o_s));
byte remote[65] = {0x04};
memcpy(&remote[1], _r.data(), 64);
d.Agree(o_s.data(), _s.data(), remote);
d.Agree(o_s.writable().data(), _s.data(), remote);
}
void Secp256k1PP::exportPublicKey(CryptoPP::DL_PublicKey_EC<CryptoPP::ECP> const& _k, Public& o_p)

6
libdevcrypto/CryptoPP.h

@ -87,7 +87,7 @@ public:
bool decryptECIES(Secret const& _k, bytes& io_text);
/// Key derivation function used by encryptECIES and decryptECIES.
bytes eciesKDF(Secret _z, bytes _s1, unsigned kdBitLen = 256);
bytes eciesKDF(Secret const& _z, bytes _s1, unsigned kdBitLen = 256);
/// @returns siganture of message.
Signature sign(Secret const& _k, bytesConstRef _message);
@ -107,10 +107,10 @@ public:
/// Verifies _s is a valid secret key and returns corresponding public key in o_p.
bool verifySecret(Secret const& _s, Public& o_p);
void agree(Secret const& _s, Public const& _r, h256& o_s);
void agree(Secret const& _s, Public const& _r, Secret& o_s);
protected:
void exportPrivateKey(DL_PrivateKey_EC<ECP> const& _k, Secret& o_s) { _k.GetPrivateExponent().Encode(o_s.data(), Secret::size); }
void exportPrivateKey(DL_PrivateKey_EC<ECP> const& _k, Secret& o_s) { _k.GetPrivateExponent().Encode(o_s.writable().data(), Secret::size); }
void exportPublicKey(DL_PublicKey_EC<ECP> const& _k, Public& o_p);

2
libdevcrypto/ECDHE.cpp

@ -29,7 +29,7 @@ using namespace dev::crypto;
static Secp256k1PP s_secp256k1;
void dev::crypto::ecdh::agree(Secret const& _s, Public const& _r, h256& o_s)
void dev::crypto::ecdh::agree(Secret const& _s, Public const& _r, Secret& o_s)
{
s_secp256k1.agree(_s, _r, o_s);
}

4
libdevcrypto/ECDHE.h

@ -39,7 +39,7 @@ using AliasSession = std::pair<Public,h256>;
class Alias
{
public:
Alias(Secret _s): m_secret(_s) {};
Alias(Secret const& _s): m_secret(_s) {};
AliasSession session(Address _a) { return m_sessions.count(_a) ? m_sessions.find(_a)->second : AliasSession(); }
@ -50,7 +50,7 @@ private:
namespace ecdh
{
void agree(Secret const& _s, Public const& _r, h256& o_s);
void agree(Secret const& _s, Public const& _r, Secret& o_s);
}
/**

63
libdevcrypto/SecretStore.cpp

@ -91,26 +91,26 @@ SecretStore::SecretStore(string const& _path): m_path(_path)
load();
}
bytes SecretStore::secret(h128 const& _uuid, function<string()> const& _pass, bool _useCache) const
bytesSec SecretStore::secret(h128 const& _uuid, function<string()> const& _pass, bool _useCache) const
{
auto rit = m_cached.find(_uuid);
if (_useCache && rit != m_cached.end())
return rit->second;
auto it = m_keys.find(_uuid);
bytes key;
bytesSec key;
if (it != m_keys.end())
{
key = decrypt(it->second.encryptedKey, _pass());
key = bytesSec(decrypt(it->second.encryptedKey, _pass()));
if (!key.empty())
m_cached[_uuid] = key;
}
return key;
}
h128 SecretStore::importSecret(bytes const& _s, string const& _pass)
h128 SecretStore::importSecret(bytesSec const& _s, string const& _pass)
{
h128 r;
EncryptedKey key{encrypt(_s, _pass), string()};
EncryptedKey key{encrypt(_s.ref(), _pass), string()};
r = h128::random();
m_cached[r] = _s;
m_keys[r] = move(key);
@ -118,6 +118,17 @@ h128 SecretStore::importSecret(bytes const& _s, string const& _pass)
return r;
}
h128 SecretStore::importSecret(bytesConstRef _s, string const& _pass)
{
h128 r;
EncryptedKey key{encrypt(_s, _pass), string()};
r = h128::random();
m_cached[r] = bytesSec(_s);
m_keys[r] = move(key);
save();
return r;
}
void SecretStore::kill(h128 const& _uuid)
{
m_cached.erase(_uuid);
@ -188,16 +199,16 @@ h128 SecretStore::readKeyContent(string const& _content, string const& _file)
bool SecretStore::recode(h128 const& _uuid, string const& _newPass, function<string()> const& _pass, KDF _kdf)
{
bytes s = secret(_uuid, _pass, true);
bytesSec s = secret(_uuid, _pass, true);
if (s.empty())
return false;
m_cached.erase(_uuid);
m_keys[_uuid].encryptedKey = encrypt(s, _newPass, _kdf);
m_keys[_uuid].encryptedKey = encrypt(s.ref(), _newPass, _kdf);
save();
return true;
}
static bytes deriveNewKey(string const& _pass, KDF _kdf, js::mObject& o_ret)
static bytesSec deriveNewKey(string const& _pass, KDF _kdf, js::mObject& o_ret)
{
unsigned dklen = 32;
unsigned iterations = 1 << 18;
@ -233,16 +244,16 @@ static bytes deriveNewKey(string const& _pass, KDF _kdf, js::mObject& o_ret)
}
}
string SecretStore::encrypt(bytes const& _v, string const& _pass, KDF _kdf)
string SecretStore::encrypt(bytesConstRef _v, string const& _pass, KDF _kdf)
{
js::mObject ret;
bytes derivedKey = deriveNewKey(_pass, _kdf, ret);
bytesSec derivedKey = deriveNewKey(_pass, _kdf, ret);
if (derivedKey.empty())
BOOST_THROW_EXCEPTION(crypto::CryptoException() << errinfo_comment("Key derivation failed."));
ret["cipher"] = "aes-128-ctr";
h128 key(derivedKey, h128::AlignLeft);
SecureFixedHash<16> key(derivedKey, h128::AlignLeft);
h128 iv = h128::random();
{
js::mObject params;
@ -251,19 +262,19 @@ string SecretStore::encrypt(bytes const& _v, string const& _pass, KDF _kdf)
}
// cipher text
bytes cipherText = encryptSymNoAuth(key, iv, &_v);
bytes cipherText = encryptSymNoAuth(key, iv, _v);
if (cipherText.empty())
BOOST_THROW_EXCEPTION(crypto::CryptoException() << errinfo_comment("Key encryption failed."));
ret["ciphertext"] = toHex(cipherText);
// and mac.
h256 mac = sha3(ref(derivedKey).cropped(16, 16).toBytes() + cipherText);
h256 mac = sha3(derivedKey.ref().cropped(16, 16).toBytes() + cipherText);
ret["mac"] = toHex(mac.ref());
return js::write_string(js::mValue(ret), true);
}
bytes SecretStore::decrypt(string const& _v, string const& _pass)
bytesSec SecretStore::decrypt(string const& _v, string const& _pass)
{
js::mObject o;
{
@ -273,14 +284,14 @@ bytes SecretStore::decrypt(string const& _v, string const& _pass)
}
// derive key
bytes derivedKey;
bytesSec derivedKey;
if (o["kdf"].get_str() == "pbkdf2")
{
auto params = o["kdfparams"].get_obj();
if (params["prf"].get_str() != "hmac-sha256")
{
cwarn << "Unknown PRF for PBKDF2" << params["prf"].get_str() << "not supported.";
return bytes();
return bytesSec();
}
unsigned iterations = params["c"].get_int();
bytes salt = fromHex(params["salt"].get_str());
@ -294,13 +305,13 @@ bytes SecretStore::decrypt(string const& _v, string const& _pass)
else
{
cwarn << "Unknown KDF" << o["kdf"].get_str() << "not supported.";
return bytes();
return bytesSec();
}
if (derivedKey.size() < 32 && !(o.count("compat") && o["compat"].get_str() == "2"))
{
cwarn << "Derived key's length too short (<32 bytes)";
return bytes();
return bytesSec();
}
bytes cipherText = fromHex(o["ciphertext"].get_str());
@ -311,23 +322,23 @@ bytes SecretStore::decrypt(string const& _v, string const& _pass)
h256 mac(o["mac"].get_str());
h256 macExp;
if (o.count("compat") && o["compat"].get_str() == "2")
macExp = sha3(bytesConstRef(&derivedKey).cropped(derivedKey.size() - 16).toBytes() + cipherText);
macExp = sha3(derivedKey.ref().cropped(derivedKey.size() - 16).toBytes() + cipherText);
else
macExp = sha3(bytesConstRef(&derivedKey).cropped(16, 16).toBytes() + cipherText);
macExp = sha3(derivedKey.ref().cropped(16, 16).toBytes() + cipherText);
if (mac != macExp)
{
cwarn << "Invalid key - MAC mismatch; expected" << toString(macExp) << ", got" << toString(mac);
return bytes();
return bytesSec();
}
}
else if (o.count("sillymac"))
{
h256 mac(o["sillymac"].get_str());
h256 macExp = sha3(asBytes(o["sillymacjson"].get_str()) + bytesConstRef(&derivedKey).cropped(derivedKey.size() - 16).toBytes() + cipherText);
h256 macExp = sha3(asBytes(o["sillymacjson"].get_str()) + derivedKey.ref().cropped(derivedKey.size() - 16).toBytes() + cipherText);
if (mac != macExp)
{
cwarn << "Invalid key - MAC mismatch; expected" << toString(macExp) << ", got" << toString(mac);
return bytes();
return bytesSec();
}
}
else
@ -340,15 +351,15 @@ bytes SecretStore::decrypt(string const& _v, string const& _pass)
h128 iv(params["iv"].get_str());
if (o.count("compat") && o["compat"].get_str() == "2")
{
h128 key(sha3(h128(derivedKey, h128::AlignRight)), h128::AlignRight);
SecureFixedHash<16> key(sha3Secure(derivedKey.ref().cropped(derivedKey.size() - 16)), h128::AlignRight);
return decryptSymNoAuth(key, iv, &cipherText);
}
else
return decryptSymNoAuth(h128(derivedKey, h128::AlignLeft), iv, &cipherText);
return decryptSymNoAuth(SecureFixedHash<16>(derivedKey, h128::AlignLeft), iv, &cipherText);
}
else
{
cwarn << "Unknown cipher" << o["cipher"].get_str() << "not supported.";
return bytes();
return bytesSec();
}
}

11
libdevcrypto/SecretStore.h

@ -52,7 +52,7 @@ public:
/// @returns the secret key stored by the given @a _uuid.
/// @param _pass function that returns the password for the key.
/// @param _useCache if true, allow previously decrypted keys to be returned directly.
bytes secret(h128 const& _uuid, std::function<std::string()> const& _pass, bool _useCache = true) const;
bytesSec secret(h128 const& _uuid, std::function<std::string()> const& _pass, bool _useCache = true) const;
/// Imports the (encrypted) key stored in the file @a _file and copies it to the managed directory.
h128 importKey(std::string const& _file) { auto ret = readKey(_file, false); if (ret) save(); return ret; }
/// Imports the (encrypted) key contained in the json formatted @a _content and stores it in
@ -60,7 +60,8 @@ public:
h128 importKeyContent(std::string const& _content) { auto ret = readKeyContent(_content, std::string()); if (ret) save(); return ret; }
/// Imports the decrypted key given by @a _s and stores it, encrypted with
/// (a key derived from) the password @a _pass.
h128 importSecret(bytes const& _s, std::string const& _pass);
h128 importSecret(bytesSec const& _s, std::string const& _pass);
h128 importSecret(bytesConstRef _s, std::string const& _pass);
/// Decrypts and re-encrypts the key identified by @a _uuid.
bool recode(h128 const& _uuid, std::string const& _newPass, std::function<std::string()> const& _pass, KDF _kdf = KDF::Scrypt);
/// Removes the key specified by @a _uuid from both memory and disk.
@ -102,12 +103,12 @@ private:
void load(std::string const& _keysPath);
void load() { load(m_path); }
/// Encrypts @a _v with a key derived from @a _pass or the empty string on error.
static std::string encrypt(bytes const& _v, std::string const& _pass, KDF _kdf = KDF::Scrypt);
static std::string encrypt(bytesConstRef _v, std::string const& _pass, KDF _kdf = KDF::Scrypt);
/// Decrypts @a _v with a key derived from @a _pass or the empty byte array on error.
static bytes decrypt(std::string const& _v, std::string const& _pass);
static bytesSec decrypt(std::string const& _v, std::string const& _pass);
/// Stores decrypted keys by uuid.
mutable std::unordered_map<h128, bytes> m_cached;
mutable std::unordered_map<h128, bytesSec> m_cached;
/// Stores encrypted keys together with the file they were loaded from by uuid.
std::unordered_map<h128, EncryptedKey> m_keys;

41
libethash-cl/ethash_cl_miner.cpp

@ -361,15 +361,25 @@ bool ethash_cl_miner::init(
try
{
m_dagChunksCount = 1;
ETHCL_LOG("Creating one big buffer for the DAG");
m_dagChunks.push_back(cl::Buffer(m_context, CL_MEM_READ_ONLY, _dagSize));
ETHCL_LOG("Created one big buffer for the DAG");
ETHCL_LOG("Loading single big chunk kernels");
m_hashKernel = cl::Kernel(program, "ethash_hash");
m_searchKernel = cl::Kernel(program, "ethash_search");
ETHCL_LOG("Mapping one big chunk.");
m_queue.enqueueWriteBuffer(m_dagChunks[0], CL_TRUE, 0, _dagSize, _dag);
}
catch (cl::Error const& err)
{
ETHCL_LOG("Allocating/mapping single buffer failed with: " << err.what() << "(" << err.err() << "). GPU can't allocate the DAG in a single chunk. Bailing.");
return false;
#if 0 // Disabling chunking for release since it seems not to work. Never manages to mine a block. TODO: Fix when time is found.
int errCode = err.err();
if (errCode != CL_INVALID_BUFFER_SIZE || errCode != CL_MEM_OBJECT_ALLOCATION_FAILURE)
ETHCL_LOG("Allocating single buffer failed with: " << err.what() << "(" << errCode << ")");
ETHCL_LOG("Allocating/mapping single buffer failed with: " << err.what() << "(" << errCode << ")");
cl_ulong result;
// if we fail midway on the try above make sure we start clean
m_dagChunks.clear();
device.getInfo(CL_DEVICE_MAX_MEM_ALLOC_SIZE, &result);
ETHCL_LOG(
"Failed to allocate 1 big chunk. Max allocateable memory is "
@ -387,32 +397,9 @@ bool ethash_cl_miner::init(
(i == 3) ? (_dagSize - 3 * ((_dagSize >> 9) << 7)) : (_dagSize >> 9) << 7
));
}
}
if (m_dagChunksCount == 1)
{
ETHCL_LOG("Loading single big chunk kernels");
m_hashKernel = cl::Kernel(program, "ethash_hash");
m_searchKernel = cl::Kernel(program, "ethash_search");
}
else
{
ETHCL_LOG("Loading chunk kernels");
m_hashKernel = cl::Kernel(program, "ethash_hash_chunks");
m_searchKernel = cl::Kernel(program, "ethash_search_chunks");
}
// create buffer for header
ETHCL_LOG("Creating buffer for header.");
m_header = cl::Buffer(m_context, CL_MEM_READ_ONLY, 32);
if (m_dagChunksCount == 1)
{
ETHCL_LOG("Mapping one big chunk.");
m_queue.enqueueWriteBuffer(m_dagChunks[0], CL_TRUE, 0, _dagSize, _dag);
}
else
{
// TODO Note: If we ever change to _dagChunksNum other than 4, then the size would need recalculation
void* dag_ptr[4];
for (unsigned i = 0; i < m_dagChunksCount; i++)
@ -425,7 +412,11 @@ bool ethash_cl_miner::init(
memcpy(dag_ptr[i], (char *)_dag + i*((_dagSize >> 9) << 7), (i == 3) ? (_dagSize - 3 * ((_dagSize >> 9) << 7)) : (_dagSize >> 9) << 7);
m_queue.enqueueUnmapMemObject(m_dagChunks[i], dag_ptr[i]);
}
#endif
}
// create buffer for header
ETHCL_LOG("Creating buffer for header.");
m_header = cl::Buffer(m_context, CL_MEM_READ_ONLY, 32);
// create mining buffers
for (unsigned i = 0; i != c_bufferCount; ++i)

2
libethcore/BasicAuthority.cpp

@ -101,7 +101,7 @@ private:
if (_name == "authorities")
BasicAuthority::s_authorities = rlp.toUnorderedSet<Address>();
else if (_name == "authority")
m_secret = rlp.toHash<Secret>();
m_secret = Secret(rlp.toHash<h256>());
else
return false;
return true;

19
libethcore/BlockInfo.cpp

@ -176,7 +176,7 @@ void BlockInfo::verifyInternals(bytesConstRef _block) const
}
clog(BlockInfoDiagnosticsChannel) << "Expected uncle hash:" << toString(sha3(root[2].data()));
if (m_sha3Uncles != sha3(root[2].data()))
BOOST_THROW_EXCEPTION(InvalidUnclesHash());
BOOST_THROW_EXCEPTION(InvalidUnclesHash() << Hash256RequirementError(sha3(root[2].data()), m_sha3Uncles));
}
void BlockInfo::populateFromParent(BlockInfo const& _parent)
@ -184,23 +184,20 @@ void BlockInfo::populateFromParent(BlockInfo const& _parent)
m_stateRoot = _parent.stateRoot();
m_number = _parent.m_number + 1;
m_parentHash = _parent.m_hash;
m_gasLimit = selectGasLimit(_parent);
m_gasLimit = _parent.childGasLimit();
m_gasUsed = 0;
m_difficulty = calculateDifficulty(_parent);
}
u256 BlockInfo::selectGasLimit(BlockInfo const& _parent) const
u256 BlockInfo::childGasLimit(u256 const& _gasFloorTarget) const
{
static const u256 c_gasFloorTarget = 3141592;
u256 gasFloorTarget =
_gasFloorTarget == UndefinedU256 ? c_gasFloorTarget : _gasFloorTarget;
if (!m_number)
throw GenesisBlockCannotBeCalculated();
if (m_gasLimit < gasFloorTarget)
return min<u256>(gasFloorTarget, m_gasLimit + m_gasLimit / c_gasLimitBoundDivisor - 1);
else
// target minimum of 3141592
if (_parent.m_gasLimit < c_gasFloorTarget)
return min<u256>(c_gasFloorTarget, _parent.m_gasLimit + _parent.m_gasLimit / c_gasLimitBoundDivisor - 1);
else
return max<u256>(c_gasFloorTarget, _parent.m_gasLimit - _parent.m_gasLimit / c_gasLimitBoundDivisor + 1 + (_parent.m_gasUsed * 6 / 5) / c_gasLimitBoundDivisor);
return max<u256>(gasFloorTarget, m_gasLimit - m_gasLimit / c_gasLimitBoundDivisor + 1 + (m_gasUsed * 6 / 5) / c_gasLimitBoundDivisor);
}
u256 BlockInfo::calculateDifficulty(BlockInfo const& _parent) const

3
libethcore/BlockInfo.h

@ -115,7 +115,7 @@ public:
void populateFromParent(BlockInfo const& parent);
u256 calculateDifficulty(BlockInfo const& _parent) const;
u256 selectGasLimit(BlockInfo const& _parent) const;
u256 childGasLimit(u256 const& _gasFloorTarget = UndefinedU256) const;
h256 const& boundary() const;
h256 const& parentHash() const { return m_parentHash; }
@ -127,6 +127,7 @@ public:
void setCoinbaseAddress(Address const& _v) { m_coinbaseAddress = _v; noteDirty(); }
void setRoots(h256 const& _t, h256 const& _r, h256 const& _u, h256 const& _s) { m_transactionsRoot = _t; m_receiptsRoot = _r; m_stateRoot = _s; m_sha3Uncles = _u; noteDirty(); }
void setGasUsed(u256 const& _v) { m_gasUsed = _v; noteDirty(); }
void setGasLimit(u256 const& _v) { m_gasLimit = _v; noteDirty(); }
void setExtraData(bytes const& _v) { m_extraData = _v; noteDirty(); }
void setLogBloom(LogBloom const& _v) { m_logBloom = _v; noteDirty(); }
void setDifficulty(u256 const& _v) { m_difficulty = _v; noteDirty(); }

4
libethcore/CMakeLists.txt

@ -23,13 +23,11 @@ file(GLOB HEADERS "*.h")
add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} ethash)
target_link_libraries(${EXECUTABLE} devcrypto)
target_link_libraries(${EXECUTABLE} evmcore)
if (ETHASHCL)
target_link_libraries(${EXECUTABLE} ethash-cl)
endif ()
target_link_libraries(${EXECUTABLE} devcrypto)
if (CPUID_FOUND)
target_link_libraries(${EXECUTABLE} ${CPUID_LIBRARIES})
endif ()

29
libethcore/Common.cpp

@ -51,36 +51,7 @@ const unsigned c_databaseBaseVersion = 9;
const unsigned c_databaseVersionModifier = 0;
#endif
#if ETH_FRONTIER
Network c_network = resetNetwork(Network::Frontier);
#else
Network c_network = resetNetwork(Network::Olympic);
#endif
Network resetNetwork(Network _n)
{
c_network = _n;
c_maximumExtraDataSize = c_network == Network::Olympic ? 1024 : 32;
switch(_n)
{
case Network::Turbo:
c_minGasLimit = 100000000;
break;
case Network::Olympic:
c_minGasLimit = 125000;
break;
case Network::Frontier:
c_minGasLimit = 5000;
break;
}
c_gasLimitBoundDivisor = 1024;
c_minimumDifficulty = 131072;
c_difficultyBoundDivisor = 2048;
c_durationLimit = c_network == Network::Turbo ? 2 : c_network == Network::Olympic ? 8 : 13;
c_blockReward = c_network == Network::Olympic ? (1500 * finney) : (5 * ether);
return _n;
}
const unsigned c_databaseVersion = c_databaseBaseVersion + (c_databaseVersionModifier << 8) + (23 << 9);

2
libethcore/CommonJS.h

@ -40,7 +40,7 @@ Address toAddress(std::string const& _a);
inline Public jsToPublic(std::string const& _s) { return jsToFixed<sizeof(dev::Public)>(_s); }
/// Leniently convert string to Secret (h256). Accepts integers, "0x" prefixing, non-exact length.
inline Secret jsToSecret(std::string const& _s) { return jsToFixed<sizeof(dev::Secret)>(_s); }
inline Secret jsToSecret(std::string const& _s) { h256 d = jsToFixed<sizeof(dev::Secret)>(_s); Secret ret(d); d.ref().cleanse(); return ret; }
/// Leniently convert string to Address (h160). Accepts integers, "0x" prefixing, non-exact length.
inline Address jsToAddress(std::string const& _s) { return jsToFixed<sizeof(dev::Address)>(_s); }

9
libethcore/Ethash.cpp

@ -177,15 +177,22 @@ StringHashMap Ethash::BlockHeaderRaw::jsInfo() const
return { { "nonce", toJS(m_nonce) }, { "seedHash", toJS(seedHash()) }, { "mixHash", toJS(m_mixHash) } };
}
void Ethash::manuallySetWork(SealEngineFace* _engine, BlockHeader const& _work)
{
// set m_sealing to the current problem.
if (EthashSealEngine* e = dynamic_cast<EthashSealEngine*>(_engine))
e->m_sealing = _work;
}
void Ethash::manuallySubmitWork(SealEngineFace* _engine, h256 const& _mixHash, Nonce _nonce)
{
if (EthashSealEngine* e = dynamic_cast<EthashSealEngine*>(_engine))
{
// Go via the farm since the handler function object is stored as a local within the Farm's lambda.
// Has the side effect of stopping local workers, which is good, as long as it only does it for
// valid submissions.
static_cast<GenericFarmFace<EthashProofOfWork>&>(e->m_farm).submitProof(EthashProofOfWork::Solution{_nonce, _mixHash}, nullptr);
}
}
bool Ethash::isWorking(SealEngineFace* _engine)

2
libethcore/Ethash.h

@ -99,6 +99,8 @@ public:
};
using BlockHeader = BlockHeaderPolished<BlockHeaderRaw>;
static void manuallySetWork(SealEngineFace* _engine, BlockHeader const& _work);
// TODO: Move elsewhere (EthashAux?)
static void ensurePrecomputed(unsigned _number);
};

20
libethcore/EthashCPUMiner.cpp

@ -53,6 +53,26 @@ static string jsonEncode(map<string, string> const& _m)
}
#endif
EthashCPUMiner::EthashCPUMiner(GenericMiner<EthashProofOfWork>::ConstructionInfo const& _ci):
GenericMiner<EthashProofOfWork>(_ci), Worker("miner" + toString(index()))
{
}
EthashCPUMiner::~EthashCPUMiner()
{
}
void EthashCPUMiner::kickOff()
{
stopWorking();
startWorking();
}
void EthashCPUMiner::pause()
{
stopWorking();
}
void EthashCPUMiner::workLoop()
{
auto tid = std::this_thread::get_id();

12
libethcore/EthashCPUMiner.h

@ -35,7 +35,8 @@ namespace eth
class EthashCPUMiner: public GenericMiner<EthashProofOfWork>, Worker
{
public:
EthashCPUMiner(GenericMiner<EthashProofOfWork>::ConstructionInfo const& _ci): GenericMiner<EthashProofOfWork>(_ci), Worker("miner" + toString(index())) {}
EthashCPUMiner(GenericMiner<EthashProofOfWork>::ConstructionInfo const& _ci);
~EthashCPUMiner();
static unsigned instances() { return s_numInstances > 0 ? s_numInstances : std::thread::hardware_concurrency(); }
static std::string platformInfo();
@ -44,13 +45,8 @@ public:
static void setNumInstances(unsigned _instances) { s_numInstances = std::min<unsigned>(_instances, std::thread::hardware_concurrency()); }
protected:
void kickOff() override
{
stopWorking();
startWorking();
}
void pause() override { stopWorking(); }
void kickOff() override;
void pause() override;
private:
void workLoop() override;

2
libethcore/Farm.h

@ -67,7 +67,6 @@ public:
void setWork(WorkPackage const& _wp)
{
WriteGuard l(x_minerWork);
cdebug << "Farm::setWork()";
if (_wp.headerHash == m_work.headerHash)
return;
m_work = _wp;
@ -84,7 +83,6 @@ public:
bool start(std::string const& _sealer)
{
WriteGuard l(x_minerWork);
cdebug << "start()";
if (!m_miners.empty() && m_lastSealer == _sealer)
return true;
if (!m_sealers.count(_sealer))

51
libethcore/KeyManager.cpp

@ -23,12 +23,14 @@
#include <thread>
#include <mutex>
#include <boost/filesystem.hpp>
#include <test/JsonSpiritHeaders.h>
#include <libdevcore/Log.h>
#include <libdevcore/Guards.h>
#include <libdevcore/RLP.h>
using namespace std;
using namespace dev;
using namespace eth;
namespace js = json_spirit;
namespace fs = boost::filesystem;
KeyManager::KeyManager(string const& _keysFile, string const& _secretsPath):
@ -81,9 +83,9 @@ bool KeyManager::load(string const& _pass)
{
bytes salt = contents(m_keysFile + ".salt");
bytes encKeys = contents(m_keysFile);
m_keysFileKey = h128(pbkdf2(_pass, salt, 262144, 16));
bytes bs = decryptSymNoAuth(m_keysFileKey, h128(), &encKeys);
RLP s(bs);
m_keysFileKey = SecureFixedHash<16>(pbkdf2(_pass, salt, 262144, 16));
bytesSec bs = decryptSymNoAuth(m_keysFileKey, h128(), &encKeys);
RLP s(bs.ref());
unsigned version = unsigned(s[0]);
if (version == 1)
{
@ -178,7 +180,7 @@ h128 KeyManager::import(Secret const& _s, string const& _accountName, string con
auto passHash = hashPassword(_pass);
cachePassword(_pass);
m_passwordHint[passHash] = _passwordHint;
auto uuid = m_store.importSecret(_s.asBytes(), _pass);
auto uuid = m_store.importSecret(_s.asBytesSec(), _pass);
m_keyInfo[uuid] = KeyInfo{passHash, _accountName};
m_addrLookup[addr] = uuid;
write(m_keysFile);
@ -187,7 +189,7 @@ h128 KeyManager::import(Secret const& _s, string const& _accountName, string con
void KeyManager::importExisting(h128 const& _uuid, string const& _info, string const& _pass, string const& _passwordHint)
{
bytes key = m_store.secret(_uuid, [&](){ return _pass; });
bytesSec key = m_store.secret(_uuid, [&](){ return _pass; });
if (key.empty())
return;
Address a = KeyPair(Secret(key)).address();
@ -216,6 +218,39 @@ void KeyManager::kill(Address const& _a)
write(m_keysFile);
}
KeyPair KeyManager::presaleSecret(std::string const& _json, function<string(bool)> const& _password)
{
js::mValue val;
json_spirit::read_string(_json, val);
auto obj = val.get_obj();
string p = _password(true);
if (obj["encseed"].type() == js::str_type)
{
auto encseed = fromHex(obj["encseed"].get_str());
KeyPair k;
for (bool gotit = false; !gotit;)
{
gotit = true;
k = KeyPair::fromEncryptedSeed(&encseed, p);
if (obj["ethaddr"].type() == js::str_type)
{
Address a(obj["ethaddr"].get_str());
Address b = k.address();
if (a != b)
{
if ((p = _password(false)).empty())
BOOST_THROW_EXCEPTION(PasswordUnknown());
else
gotit = false;
}
}
}
return k;
}
else
BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("encseed type is not js::str_type"));
}
Addresses KeyManager::accounts() const
{
Addresses ret;
@ -258,7 +293,7 @@ string const& KeyManager::passwordHint(Address const& _address) const
h256 KeyManager::hashPassword(string const& _pass) const
{
// TODO SECURITY: store this a bit more securely; Scrypt perhaps?
return h256(pbkdf2(_pass, asBytes(m_defaultPasswordDeprecated), 262144, 32));
return h256(pbkdf2(_pass, asBytes(m_defaultPasswordDeprecated), 262144, 32).makeInsecure());
}
void KeyManager::cachePassword(string const& _password) const
@ -278,14 +313,14 @@ void KeyManager::write(string const& _pass, string const& _keysFile) const
{
bytes salt = h256::random().asBytes();
writeFile(_keysFile + ".salt", salt);
auto key = h128(pbkdf2(_pass, salt, 262144, 16));
auto key = SecureFixedHash<16>(pbkdf2(_pass, salt, 262144, 16));
cachePassword(_pass);
m_master = hashPassword(_pass);
write(key, _keysFile);
}
void KeyManager::write(h128 const& _key, string const& _keysFile) const
void KeyManager::write(SecureFixedHash<16> const& _key, string const& _keysFile) const
{
RLPStream s(4);
s << 1; // version

9
libethcore/KeyManager.h

@ -123,6 +123,9 @@ public:
static std::string defaultPath() { return getDataDir("ethereum") + "/keys.info"; }
/// Extracts the secret key from the presale wallet.
KeyPair presaleSecret(std::string const& _json, std::function<std::string(bool)> const& _password);
private:
std::string getPassword(h128 const& _uuid, std::function<std::string()> const& _pass = DontKnowThrow) const;
std::string getPassword(h256 const& _passHash, std::function<std::string()> const& _pass = DontKnowThrow) const;
@ -136,8 +139,8 @@ private:
// @returns false if wasn't previously loaded ok.
bool write() const { return write(m_keysFile); }
bool write(std::string const& _keysFile) const;
void write(std::string const& _pass, std::string const& _keysFile) const;
void write(h128 const& _key, std::string const& _keysFile) const;
void write(std::string const& _pass, std::string const& _keysFile) const; // TODO: all passwords should be a secure string.
void write(SecureFixedHash<16> const& _key, std::string const& _keysFile) const;
// Ethereum keys.
@ -159,7 +162,7 @@ private:
std::string m_defaultPasswordDeprecated;
mutable std::string m_keysFile;
mutable h128 m_keysFileKey;
mutable SecureFixedHash<16> m_keysFileKey;
mutable h256 m_master;
SecretStore m_store;
};

32
libethcore/Params.cpp

@ -36,8 +36,40 @@ u256 c_minimumDifficulty;
u256 c_difficultyBoundDivisor;
u256 c_durationLimit;
u256 c_blockReward;
u256 c_gasFloorTarget;
//--- END: AUTOGENERATED FROM /feeStructure.json
#if ETH_FRONTIER
Network c_network = resetNetwork(Network::Frontier);
#else
Network c_network = resetNetwork(Network::Olympic);
#endif
Network resetNetwork(Network _n)
{
c_network = _n;
c_maximumExtraDataSize = c_network == Network::Olympic ? 1024 : 32;
switch(_n)
{
case Network::Turbo:
c_minGasLimit = 100000000;
break;
case Network::Olympic:
c_minGasLimit = 125000;
break;
case Network::Frontier:
c_minGasLimit = 5000;
break;
}
c_gasFloorTarget = c_network == Network::Frontier ? 5000 : 3141592;
c_gasLimitBoundDivisor = 1024;
c_minimumDifficulty = 131072;
c_difficultyBoundDivisor = 2048;
c_durationLimit = c_network == Network::Turbo ? 2 : c_network == Network::Olympic ? 8 : 13;
c_blockReward = c_network == Network::Olympic ? (1500 * finney) : (5 * ether);
return _n;
}
}
}

1
libethcore/Params.h

@ -36,6 +36,7 @@ extern u256 c_difficultyBoundDivisor;
extern u256 c_durationLimit;
extern u256 c_maximumExtraDataSize;
extern u256 c_blockReward;
extern u256 c_gasFloorTarget;
//--- END: AUTOGENERATED FROM /feeStructure.json
}

100
libethereum/BlockChain.cpp

@ -146,13 +146,13 @@ static const unsigned c_minCacheSize = 1024 * 1024 * 32;
#endif
BlockChain::BlockChain(bytes const& _genesisBlock, std::unordered_map<Address, Account> const& _genesisState, std::string const& _path, WithExisting _we, ProgressCallback const& _p):
BlockChain::BlockChain(bytes const& _genesisBlock, std::unordered_map<Address, Account> const& _genesisState, std::string const& _path):
m_dbPath(_path)
{
open(_genesisBlock, _genesisState, _path, _we, _p);
open(_genesisBlock, _genesisState, _path);
}
void BlockChain::open(bytes const& _genesisBlock, std::unordered_map<Address, Account> const& _genesisState, std::string const& _path, WithExisting _we, ProgressCallback const& _p)
void BlockChain::open(bytes const& _genesisBlock, std::unordered_map<Address, Account> const& _genesisState, std::string const& _path)
{
// initialise deathrow.
m_cacheUsage.resize(c_collectionQueueSize);
@ -165,9 +165,6 @@ void BlockChain::open(bytes const& _genesisBlock, std::unordered_map<Address, Ac
// remove the next line real soon. we don't need to be supporting this forever.
upgradeDatabase(_path, genesisHash());
if (openDatabase(_path, _we) != c_minorProtocolVersion)
rebuild(_path, _p);
}
BlockChain::~BlockChain()
@ -290,7 +287,7 @@ void BlockChain::rebuild(std::string const& _path, std::function<void(unsigned,
// Keep extras DB around, but under a temp name
delete m_extrasDB;
m_extrasDB = nullptr;
boost::filesystem::rename(path + "/details", path + "/extras.old");
boost::filesystem::rename(extrasPath + "/extras", extrasPath + "/extras.old");
ldb::DB* oldExtrasDB;
ldb::Options o;
o.create_if_missing = true;
@ -384,52 +381,49 @@ tuple<ImportRoute, bool, unsigned> BlockChain::sync(BlockQueue& _bq, OverlayDB c
Transactions goodTransactions;
unsigned count = 0;
for (VerifiedBlock const& block: blocks)
if (!badBlocks.empty())
badBlocks.push_back(block.verified.info.hash());
else
{
do {
try
{
// Nonce & uncle nonces already verified in verification thread at this point.
ImportRoute r;
DEV_TIMED_ABOVE("Block import " + toString(block.verified.info.number()), 500)
r = import(block.verified, _stateDB, ImportRequirements::Everything & ~ImportRequirements::ValidSeal & ~ImportRequirements::CheckUncles);
fresh += r.liveBlocks;
dead += r.deadBlocks;
goodTransactions.reserve(goodTransactions.size() + r.goodTranactions.size());
std::move(std::begin(r.goodTranactions), std::end(r.goodTranactions), std::back_inserter(goodTransactions));
++count;
}
catch (dev::eth::UnknownParent)
{
cwarn << "ODD: Import queue contains block with unknown parent.";// << LogTag::Error << boost::current_exception_diagnostic_information();
// NOTE: don't reimport since the queue should guarantee everything in the right order.
// Can't continue - chain bad.
badBlocks.push_back(block.verified.info.hash());
}
catch (dev::eth::FutureTime)
{
cwarn << "ODD: Import queue contains a block with future time.";
this_thread::sleep_for(chrono::seconds(1));
continue;
}
catch (dev::eth::TransientError)
{
this_thread::sleep_for(chrono::milliseconds(100));
continue;
}
catch (Exception& ex)
{
// cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!";// << LogTag::Error << diagnostic_information(ex);
if (m_onBad)
m_onBad(ex);
// NOTE: don't reimport since the queue should guarantee everything in the right order.
// Can't continue - chain bad.
badBlocks.push_back(block.verified.info.hash());
}
} while (false);
}
{
do {
try
{
// Nonce & uncle nonces already verified in verification thread at this point.
ImportRoute r;
DEV_TIMED_ABOVE("Block import " + toString(block.verified.info.number()), 500)
r = import(block.verified, _stateDB, ImportRequirements::Everything & ~ImportRequirements::ValidSeal & ~ImportRequirements::CheckUncles);
fresh += r.liveBlocks;
dead += r.deadBlocks;
goodTransactions.reserve(goodTransactions.size() + r.goodTranactions.size());
std::move(std::begin(r.goodTranactions), std::end(r.goodTranactions), std::back_inserter(goodTransactions));
++count;
}
catch (dev::eth::UnknownParent)
{
cwarn << "ODD: Import queue contains block with unknown parent.";// << LogTag::Error << boost::current_exception_diagnostic_information();
// NOTE: don't reimport since the queue should guarantee everything in the right order.
// Can't continue - chain bad.
badBlocks.push_back(block.verified.info.hash());
}
catch (dev::eth::FutureTime)
{
cwarn << "ODD: Import queue contains a block with future time.";
this_thread::sleep_for(chrono::seconds(1));
continue;
}
catch (dev::eth::TransientError)
{
this_thread::sleep_for(chrono::milliseconds(100));
continue;
}
catch (Exception& ex)
{
// cnote << "Exception while importing block. Someone (Jeff? That you?) seems to be giving us dodgy blocks!";// << LogTag::Error << diagnostic_information(ex);
if (m_onBad)
m_onBad(ex);
// NOTE: don't reimport since the queue should guarantee everything in the right order.
// Can't continue - chain bad.
badBlocks.push_back(block.verified.info.hash());
}
} while (false);
}
return make_tuple(ImportRoute{dead, fresh, goodTransactions}, _bq.doneDrain(badBlocks), count);
}

35
libethereum/BlockChain.h

@ -104,11 +104,13 @@ public:
class BlockChain
{
public:
BlockChain(bytes const& _genesisBlock, StateDefinition const& _genesisState, std::string const& _path, WithExisting _we = WithExisting::Trust, ProgressCallback const& _p = ProgressCallback());
/// Doesn't open the database - if you want it open it's up to you to subclass this and open it
/// in the constructor there.
BlockChain(bytes const& _genesisBlock, StateDefinition const& _genesisState, std::string const& _path);
~BlockChain();
/// Reopen everything.
virtual void reopen(WithExisting _we = WithExisting::Trust, ProgressCallback const& _pc = ProgressCallback()) { close(); open(m_genesisBlock, m_genesisState, m_dbPath, _we, _pc); }
virtual void reopen(WithExisting _we = WithExisting::Trust, ProgressCallback const& _pc = ProgressCallback()) { close(); open(m_genesisBlock, m_genesisState, m_dbPath); openDatabase(m_dbPath, _we, _pc); }
/// (Potentially) renders invalid existing bytesConstRef returned by lastBlock.
/// To be called from main loop every 100ms or so.
@ -292,13 +294,22 @@ public:
protected:
static h256 chunkId(unsigned _level, unsigned _index) { return h256(_index * 0xff + _level); }
/// Initialise everything and open the database.
void open(bytes const& _genesisBlock, std::unordered_map<Address, Account> const& _genesisState, std::string const& _path, WithExisting _we, ProgressCallback const& _p);
/// Initialise everything and ready for openning the database.
// TODO: rename to init
void open(bytes const& _genesisBlock, std::unordered_map<Address, Account> const& _genesisState, std::string const& _path);
/// Open the database.
unsigned openDatabase(std::string const& _path, WithExisting _we = WithExisting::Trust);
// TODO: rename to open.
unsigned openDatabase(std::string const& _path, WithExisting _we);
/// Finalise everything and close the database.
void close();
/// Open the database, rebuilding if necessary.
void openDatabase(std::string const& _path, WithExisting _we, ProgressCallback const& _pc)
{
if (openDatabase(_path, _we) != c_minorProtocolVersion || _we == WithExisting::Verify)
rebuild(_path, _pc);
}
template<class T, class K, unsigned N> T queryExtras(K const& _h, std::unordered_map<K, T>& _m, boost::shared_mutex& _x, T const& _n, ldb::DB* _extrasDB = nullptr) const
{
{
@ -389,9 +400,11 @@ class FullBlockChain: public BlockChain
public:
using BlockHeader = typename Sealer::BlockHeader;
FullBlockChain(bytes const& _genesisBlock, StateDefinition const& _genesisState, std::string const& _path, WithExisting _we = WithExisting::Trust, ProgressCallback const& _p = ProgressCallback()):
BlockChain(_genesisBlock, _genesisState, _path, _we, _p)
{}
FullBlockChain(bytes const& _genesisBlock, StateDefinition const& _genesisState, std::string const& _path, WithExisting _we, ProgressCallback const& _pc = ProgressCallback()):
BlockChain(_genesisBlock, _genesisState, _path)
{
openDatabase(_path, _we, _pc);
}
/// Get the header of a block (or the most recent mined if none given). Thread-safe.
typename Sealer::BlockHeader header(h256 const& _hash) const { return typename Sealer::BlockHeader(headerData(_hash), IgnoreSeal, _hash, HeaderData); }
@ -482,6 +495,12 @@ public:
res.block = bytesConstRef(_block);
return res;
}
protected:
/// Constructor for derived classes to use when they'll open the chain db afterwards.
FullBlockChain(bytes const& _genesisBlock, StateDefinition const& _genesisState, std::string const& _path):
BlockChain(_genesisBlock, _genesisState, _path)
{}
};
std::ostream& operator<<(std::ostream& _out, BlockChain const& _bc);

1
libethereum/BlockQueue.cpp

@ -76,6 +76,7 @@ void BlockQueue::clear()
m_drainingSet.clear();
m_verified.clear();
m_unverified.clear();
m_verifying.clear();
m_unknownSet.clear();
m_unknown.clear();
m_future.clear();

6
libethereum/CanonBlockChain.cpp

@ -45,14 +45,16 @@ string CanonBlockChain<Ethash>::s_genesisStateJSON;
bytes CanonBlockChain<Ethash>::s_genesisExtraData;
CanonBlockChain<Ethash>::CanonBlockChain(std::string const& _path, WithExisting _we, ProgressCallback const& _pc):
FullBlockChain<Ethash>(createGenesisBlock(), createGenesisState(), _path, _we, _pc)
FullBlockChain<Ethash>(createGenesisBlock(), createGenesisState(), _path)
{
BlockChain::openDatabase(_path, _we, _pc);
}
void CanonBlockChain<Ethash>::reopen(WithExisting _we, ProgressCallback const& _pc)
{
close();
open(createGenesisBlock(), createGenesisState(), m_dbPath, _we, _pc);
open(createGenesisBlock(), createGenesisState(), m_dbPath);
openDatabase(m_dbPath, _we, _pc);
}
bytes CanonBlockChain<Ethash>::createGenesisBlock()

5
libethereum/CanonBlockChain.h

@ -52,7 +52,10 @@ class CanonBlockChain: public FullBlockChain<Sealer>
public:
CanonBlockChain(WithExisting _we = WithExisting::Trust, ProgressCallback const& _pc = ProgressCallback()): CanonBlockChain<Sealer>(std::string(), _we, _pc) {}
CanonBlockChain(std::string const& _path, WithExisting _we = WithExisting::Trust, ProgressCallback const& _pc = ProgressCallback()):
FullBlockChain<Sealer>(createGenesisBlock(), StateDefinition(), _path, _we, _pc) {}
FullBlockChain<Sealer>(createGenesisBlock(), StateDefinition(), _path, _we, _pc)
{
BlockChain::openDatabase(_path, _we, _pc);
}
~CanonBlockChain() {}
/// @returns the genesis block as its RLP-encoded byte array.

17
libethereum/Client.cpp

@ -94,6 +94,7 @@ void Client::init(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _
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_tqReplaced = m_tq.onReplaced([=](h256 const&){ this->resetState(); });
m_bqReady = m_bq.onReady([=](){ this->onBlockQueueReady(); }); // TODO: should read m_bq->onReady(thisThread, syncBlockQueue);
m_bq.setOnBad([=](Exception& ex){ this->onBadBlock(ex); });
bc().setOnBad([=](Exception& ex){ this->onBadBlock(ex); });
@ -650,6 +651,21 @@ void Client::resyncStateFromChain()
}
}
void Client::resetState()
{
State newPreMine;
DEV_READ_GUARDED(x_preMine)
newPreMine = m_preMine;
DEV_WRITE_GUARDED(x_working)
m_working = newPreMine;
DEV_READ_GUARDED(x_working) DEV_WRITE_GUARDED(x_postMine)
m_postMine = m_working;
onPostStateChanged();
onTransactionQueueReady();
}
void Client::onChainChanged(ImportRoute const& _ir)
{
h256Hash changeds;
@ -908,6 +924,7 @@ std::tuple<h256, h256, h256> EthashClient::getEthashWork()
// otherwise, set this to true so that it gets prepped next time.
m_remoteWorking = true;
Ethash::BlockHeader bh = Ethash::BlockHeader(m_miningInfo);
Ethash::manuallySetWork(m_sealEngine.get(), bh);
return std::tuple<h256, h256, h256>(bh.hashWithout(), bh.seedHash(), bh.boundary());
}

4
libethereum/Client.h

@ -254,6 +254,9 @@ protected:
/// Called after processing blocks by onChainChanged(_ir)
void resyncStateFromChain();
/// Clear working state of transactions
void resetState();
/// Magically called when the chain has changed. An import route is provided.
/// Called by either submitWork() or in our main thread through syncBlockQueue().
void onChainChanged(ImportRoute const& _ir);
@ -307,6 +310,7 @@ protected:
std::shared_ptr<SealEngineFace> m_sealEngine; ///< Our block-sealing engine.
Handler<> m_tqReady;
Handler<h256 const&> m_tqReplaced;
Handler<> m_bqReady;
bool m_wouldMine = false; ///< True if we /should/ be mining.

3
libethereum/Executive.cpp

@ -325,7 +325,8 @@ bool Executive::go(OnOpFunc const& _onOp)
#endif
try
{
auto vm = VMFactory::create();
// Create VM instance. Force Interpreter if tracing requested.
auto vm = _onOp ? VMFactory::create(VMKind::Interpreter) : VMFactory::create();
if (m_isCreation)
{
auto out = vm->exec(m_gas, *m_ext, _onOp);

33
libethereum/State.cpp

@ -906,8 +906,12 @@ bool State::sealBlock(bytesConstRef _header)
if (!m_committedToMine)
return false;
// Check that this header is indeed for this block.
if (BlockInfo(_header, CheckNothing, h256{}, HeaderData).hashWithout() != m_currentBlock.hashWithout())
return false;
// Looks good!
clog(StateDetail) << "Sealing block!";
// Got it!
// Compile block:
RLPStream ret;
@ -1137,6 +1141,12 @@ bool State::isTrieGood(bool _enforceRefs, bool _requireNoLeftOvers) const
ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Permanence _p, OnOpFunc const& _onOp)
{
auto onOp = _onOp;
#if ETH_VMTRACE
if (isChannelVisible<VMTraceChannel>())
onOp = Executive::simpleTrace(); // override tracer
#endif
#if ETH_PARANOIA
paranoia("start of execution.", true);
State old(*this);
@ -1161,16 +1171,7 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per
ctrace << toHex(e.t().rlp());
#endif
if (!e.execute())
#if ETH_VMTRACE
{
if (isChannelVisible<VMTraceChannel>())
e.go(e.simpleTrace());
else
e.go(_onOp);
}
#else
e.go(_onOp);
#endif
e.go(onOp);
e.finalize();
#if ETH_PARANOIA
@ -1183,13 +1184,13 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per
else
{
commit();
#if ETH_PARANOIA && !ETH_FATDB
ctrace << "Executed; now" << rootHash();
ctrace << old.diff(*this);
paranoia("after execution commit.", true);
if (e.t().receiveAddress())
{
EnforceRefs r(m_db, true);
@ -1200,9 +1201,9 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per
}
}
#endif
// TODO: CHECK TRIE after level DB flush to make sure exactly the same.
// Add to the user-originated transactions that we've executed.
m_transactions.push_back(e.t());
m_receipts.push_back(TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs()));

6
libethereum/TransactionQueue.cpp

@ -147,7 +147,11 @@ ImportResult TransactionQueue::manageImport_WITH_LOCK(h256 const& _h, Transactio
if (_transaction.gasPrice() < (*t->second).transaction.gasPrice())
return ImportResult::OverbidGasPrice;
else
remove_WITH_LOCK((*t->second).transaction.sha3());
{
h256 dropped = (*t->second).transaction.sha3();
remove_WITH_LOCK(dropped);
m_onReplaced(dropped);
}
}
}
auto fs = m_future.find(_transaction.from());

4
libethereum/TransactionQueue.h

@ -117,6 +117,9 @@ public:
/// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported
template <class T> Handler<ImportResult, h256 const&, h512 const&> onImport(T const& _t) { return m_onImport.add(_t); }
/// Register a handler that will be called once asynchronous verification is comeplte an transaction has been imported
template <class T> Handler<h256 const&> onReplaced(T const& _t) { return m_onReplaced.add(_t); }
private:
/// Verified and imported transaction
@ -184,6 +187,7 @@ private:
Signal<> m_onReady; ///< Called when a subsequent call to import transactions will return a non-empty container. Be nice and exit fast.
Signal<ImportResult, h256 const&, h512 const&> m_onImport; ///< Called for each import attempt. Arguments are result, transaction id an node id. Be nice and exit fast.
Signal<h256 const&> m_onReplaced; ///< Called whan transction is dropped during a call to import() to make room for another transaction.
unsigned m_limit; ///< Max number of pending transactions
unsigned m_futureLimit; ///< Max number of future transactions
unsigned m_futureSize = 0; ///< Current number of future transactions

4
libethereumx/Ethereum.cpp

@ -83,7 +83,7 @@ void Ethereum::connect(std::string const& _seedHost, unsigned short _port)
{
}
void Ethereum::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice)
void Ethereum::submitTransaction(Secret const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice)
{
}
@ -92,7 +92,7 @@ bytes Ethereum::call(Address const& _from, u256 _value, Address _dest, bytes con
return bytes();
}
Address Ethereum::submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice)
Address Ethereum::submitTransaction(Secret const& _secret, u256 _endowment, bytes const& _init, u256 _gas, u256 _gasPrice)
{
return Address();
}

4
libethereumx/Ethereum.h

@ -62,11 +62,11 @@ public:
~Ethereum();
/// Submits the given message-call transaction.
void submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
void submitTransaction(Secret const& _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
/// Submits a new contract-creation transaction.
/// @returns the new contract's address (assuming it all goes through).
Address submitTransaction(Secret _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
Address submitTransaction(Secret const& _secret, u256 _endowment, bytes const& _init, u256 _gas = 10000, u256 _gasPrice = 10 * szabo);
/// Injects the RLP-encoded transaction given by the _rlp into the transaction queue directly.
void inject(bytesConstRef _rlp);

2
libevm/SmartVM.cpp

@ -61,8 +61,8 @@ namespace
class JitWorker
{
std::thread m_worker;
concurrent_queue<JitTask> m_queue;
std::thread m_worker; // Worker must be last to initialize
void work()
{

3
libevm/VM.cpp

@ -103,7 +103,7 @@ void VM::checkRequirements(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp,
newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 2]);
break;
case Instruction::SHA3:
runGas = c_sha3Gas + (m_stack[m_stack.size() - 2] + 31) / 32 * c_sha3WordGas;
runGas = c_sha3Gas + ((bigint)m_stack[m_stack.size() - 2] + 31) / 32 * c_sha3WordGas;
newTempSize = memNeed(m_stack.back(), m_stack[m_stack.size() - 2]);
break;
case Instruction::CALLDATACOPY:
@ -392,6 +392,7 @@ bytesConstRef VM::execImpl(u256& io_gas, ExtVMFace& _ext, OnOpFunc const& _onOp)
auto a = asAddress(m_stack.back());
m_stack.pop_back();
copyDataToMemory(&_ext.codeAt(a), m_stack, m_temp);
break;
}
case Instruction::GASPRICE:
m_stack.push_back(_ext.gasPrice);

2
libp2p/Host.cpp

@ -809,7 +809,7 @@ bytes Host::saveNetwork() const
// else: TODO: use previous configuration if available
RLPStream ret(3);
ret << dev::p2p::c_protocolVersion << m_alias.secret();
ret << dev::p2p::c_protocolVersion << m_alias.secret().ref();
ret.appendList(count);
if (!!count)
ret.appendRaw(network.out(), count);

16
libp2p/RLPXSocketIO.cpp

@ -1,16 +1,16 @@
/*
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/>.
*/
@ -34,7 +34,7 @@ RLPXSocketIO::RLPXSocketIO(unsigned _protCount, RLPXFrameCoder& _coder, bi::tcp:
m_flowControl(_flowControl),
m_coder(_coder),
m_socket(_socket),
m_writers(move(writers(_protCount))),
m_writers(writers(_protCount)),
m_egressCapacity(m_flowControl ? _initialCapacity : MaxPacketSize * m_writers.size())
{}
@ -61,11 +61,11 @@ void RLPXSocketIO::send(unsigned _protocolType, unsigned _type, RLPStream& _payl
void RLPXSocketIO::doWrite()
{
m_toSend.clear();
size_t capacity;
DEV_GUARDED(x_queued)
capacity = min(m_egressCapacity, MaxPacketSize);
size_t active = 0;
for (auto const& w: m_writers)
if (w.size())
@ -97,7 +97,7 @@ void RLPXSocketIO::write(size_t _dequed)
{
if (ec)
return; // TCPSocketWriteError
bool reschedule = false;
DEV_GUARDED(x_queued)
{
@ -109,4 +109,4 @@ void RLPXSocketIO::write(size_t _dequed)
if (reschedule)
doWrite();
});
}
}

4
libp2p/RLPxHandshake.cpp

@ -40,7 +40,7 @@ void RLPXHandshake::writeAuth()
// E(remote-pubk, S(ecdhe-random, ecdh-shared-secret^nonce) || H(ecdhe-random-pubk) || pubk || nonce || 0x0)
Secret staticShared;
crypto::ecdh::agree(m_host->m_alias.sec(), m_remote, staticShared);
sign(m_ecdhe.seckey(), staticShared ^ m_nonce).ref().copyTo(sig);
sign(m_ecdhe.seckey(), staticShared.makeInsecure() ^ m_nonce).ref().copyTo(sig);
sha3(m_ecdhe.pubkey().ref(), hepubk);
m_host->m_alias.pub().ref().copyTo(pubk);
m_nonce.ref().copyTo(nonce);
@ -92,7 +92,7 @@ void RLPXHandshake::readAuth()
Secret sharedSecret;
crypto::ecdh::agree(m_host->m_alias.sec(), m_remote, sharedSecret);
m_remoteEphemeral = recover(*(Signature*)sig.data(), sharedSecret ^ m_remoteNonce);
m_remoteEphemeral = recover(*(Signature*)sig.data(), sharedSecret.makeInsecure() ^ m_remoteNonce);
if (sha3(m_remoteEphemeral) != *(h256*)hepubk.data())
clog(NetP2PConnect) << "p2p.connect.ingress auth failed (invalid: hash mismatch) for" << m_socket->remoteEndpoint();

2
libweb3jsonrpc/JsonHelper.cpp

@ -482,7 +482,7 @@ shh::Message toMessage(Json::Value const& _json)
return ret;
}
shh::Envelope toSealed(Json::Value const& _json, shh::Message const& _m, Secret _from)
shh::Envelope toSealed(Json::Value const& _json, shh::Message const& _m, Secret const& _from)
{
unsigned ttl = 50;
unsigned workToProve = 50;

2
libweb3jsonrpc/JsonHelper.h

@ -89,7 +89,7 @@ namespace shh
Json::Value toJson(h256 const& _h, Envelope const& _e, Message const& _m);
Message toMessage(Json::Value const& _json);
Envelope toSealed(Json::Value const& _json, Message const& _m, Secret _from);
Envelope toSealed(Json::Value const& _json, Message const& _m, Secret const& _from);
std::pair<Topics, Public> toWatch(Json::Value const& _json);
}

28
libweb3jsonrpc/WebThreeStubServer.cpp

@ -77,11 +77,11 @@ bool WebThreeStubServer::eth_notePassword(string const& _password)
return true;
}
#define ADMIN requires(_session, Priviledge::Admin)
#define ADMIN_GUARD requires(_session, Privilege::Admin)
Json::Value WebThreeStubServer::admin_eth_blockQueueStatus(string const& _session)
{
ADMIN;
ADMIN_GUARD;
Json::Value ret;
BlockQueueStatus bqs = m_web3.ethereum()->blockQueue().status();
ret["importing"] = (int)bqs.importing;
@ -96,14 +96,14 @@ Json::Value WebThreeStubServer::admin_eth_blockQueueStatus(string const& _sessio
bool WebThreeStubServer::admin_eth_setAskPrice(std::string const& _wei, std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
m_gp.setAsk(jsToU256(_wei));
return true;
}
bool WebThreeStubServer::admin_eth_setBidPrice(std::string const& _wei, std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
m_gp.setBid(jsToU256(_wei));
return true;
}
@ -120,7 +120,7 @@ dev::eth::BlockQueue const& WebThreeStubServer::bq() const
Json::Value WebThreeStubServer::admin_eth_findBlock(std::string const& _blockHash, std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
h256 h(_blockHash);
if (bc().isKnown(h))
return toJson(bc().info(h));
@ -141,20 +141,20 @@ Json::Value WebThreeStubServer::admin_eth_findBlock(std::string const& _blockHas
std::string WebThreeStubServer::admin_eth_blockQueueFirstUnknown(std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
return bq().firstUnknown().hex();
}
bool WebThreeStubServer::admin_eth_blockQueueRetryUnknown(std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
m_web3.ethereum()->retryUnknown();
return true;
}
Json::Value WebThreeStubServer::admin_eth_allAccounts(std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
Json::Value ret;
u256 total = 0;
u256 pendingtotal = 0;
@ -184,7 +184,7 @@ Json::Value WebThreeStubServer::admin_eth_allAccounts(std::string const& _sessio
Json::Value WebThreeStubServer::admin_eth_newAccount(Json::Value const& _info, std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
if (!_info.isMember("name"))
throw jsonrpc::JsonRpcException("No member found: name");
string name = _info["name"].asString();
@ -206,7 +206,7 @@ Json::Value WebThreeStubServer::admin_eth_newAccount(Json::Value const& _info, s
bool WebThreeStubServer::admin_eth_setMiningBenefactor(std::string const& _uuidOrAddress, std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
Address a;
h128 uuid = fromUUID(_uuidOrAddress);
if (uuid)
@ -222,7 +222,7 @@ bool WebThreeStubServer::admin_eth_setMiningBenefactor(std::string const& _uuidO
Json::Value WebThreeStubServer::admin_eth_inspect(std::string const& _address, std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
if (!isHash<Address>(_address))
throw jsonrpc::JsonRpcException("Invalid address given.");
@ -251,7 +251,7 @@ h256 WebThreeStubServer::blockHash(std::string const& _blockNumberOrHash) const
Json::Value WebThreeStubServer::admin_eth_reprocess(std::string const& _blockNumberOrHash, std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
Json::Value ret;
PopulationStatistics ps;
m_web3.ethereum()->state(blockHash(_blockNumberOrHash), &ps);
@ -263,7 +263,7 @@ Json::Value WebThreeStubServer::admin_eth_reprocess(std::string const& _blockNum
Json::Value WebThreeStubServer::admin_eth_vmTrace(std::string const& _blockNumberOrHash, int _txIndex, std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
Json::Value ret;
@ -299,7 +299,7 @@ Json::Value WebThreeStubServer::admin_eth_vmTrace(std::string const& _blockNumbe
Json::Value WebThreeStubServer::admin_eth_getReceiptByHashAndIndex(std::string const& _blockNumberOrHash, int _txIndex, std::string const& _session)
{
ADMIN;
ADMIN_GUARD;
if (_txIndex < 0)
throw jsonrpc::JsonRpcException("Negative index");
auto h = blockHash(_blockNumberOrHash);

4
libweb3jsonrpc/WebThreeStubServer.h

@ -40,7 +40,7 @@ class BlockQueue;
struct SessionPermissions
{
std::unordered_set<Priviledge> priviledges;
std::unordered_set<Privilege> privileges;
};
/**
@ -59,7 +59,7 @@ public:
virtual void setMiningBenefactorChanger(std::function<void(Address const&)> const& _f) { m_setMiningBenefactor = _f; }
private:
virtual bool hasPriviledgeLevel(std::string const& _session, Priviledge _l) const override { auto it = m_sessions.find(_session); return it != m_sessions.end() && it->second.priviledges.count(_l); }
virtual bool hasPrivilegeLevel(std::string const& _session, Privilege _l) const override { auto it = m_sessions.find(_session); return it != m_sessions.end() && it->second.privileges.count(_l); }
virtual dev::eth::Interface* client() override;
virtual std::shared_ptr<dev::shh::Interface> face() override;

2
libweb3jsonrpc/WebThreeStubServerBase.cpp

@ -510,7 +510,7 @@ string WebThreeStubServerBase::eth_compileSerpent(string const& _source)
return res;
}
#define ADMIN requires(_session, Priviledge::Admin)
#define ADMIN requires(_session, Privilege::Admin)
bool WebThreeStubServerBase::admin_web3_setVerbosity(int _v, string const& _session)
{

10
libweb3jsonrpc/WebThreeStubServerBase.h

@ -59,7 +59,7 @@ public:
virtual void put(std::string const& _name, std::string const& _key, std::string const& _value) = 0;
};
enum class Priviledge
enum class Privilege
{
Admin
};
@ -69,9 +69,9 @@ enum class Priviledge
namespace std
{
template<> struct hash<dev::Priviledge>
template<> struct hash<dev::Privilege>
{
size_t operator()(dev::Priviledge _value) const { return (size_t)_value; }
size_t operator()(dev::Privilege _value) const { return (size_t)_value; }
};
}
@ -190,8 +190,8 @@ public:
std::map<dev::Public, dev::Secret> const& ids() const { return m_shhIds; }
protected:
void requires(std::string const& _session, Priviledge _l) const { if (!hasPriviledgeLevel(_session, _l)) throw jsonrpc::JsonRpcException("Invalid priviledges"); }
virtual bool hasPriviledgeLevel(std::string const& _session, Priviledge _l) const { (void)_session; (void)_l; return false; }
void requires(std::string const& _session, Privilege _l) const { if (!hasPrivilegeLevel(_session, _l)) throw jsonrpc::JsonRpcException("Invalid privileges"); }
virtual bool hasPrivilegeLevel(std::string const& _session, Privilege _l) const { (void)_session; (void)_l; return false; }
virtual dev::eth::Interface* client() = 0;
virtual std::shared_ptr<dev::shh::Interface> face() = 0;

4
libwhisper/CMakeLists.txt

@ -21,10 +21,10 @@ file(GLOB HEADERS "*.h")
add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} ethcore)
#target_link_libraries(${EXECUTABLE} ethcore)
target_link_libraries(${EXECUTABLE} p2p)
target_link_libraries(${EXECUTABLE} devcrypto)
target_link_libraries(${EXECUTABLE} devcore)
target_link_libraries(${EXECUTABLE} p2p)
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )

4
libwhisper/Interface.h

@ -76,8 +76,8 @@ public:
void post(bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_topics, _ttl, _workToProve)); }
void post(Public _to, bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).sealTo(_to, _topics, _ttl, _workToProve)); }
void post(Secret _from, bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_from, _topics, _ttl, _workToProve)); }
void post(Secret _from, Public _to, bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).sealTo(_from, _to, _topics, _ttl, _workToProve)); }
void post(Secret const& _from, bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).seal(_from, _topics, _ttl, _workToProve)); }
void post(Secret const& _from, Public _to, bytes const& _payload, Topics _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { inject(Message(_payload).sealTo(_from, _to, _topics, _ttl, _workToProve)); }
};
struct WatshhChannel: public dev::LogChannel { static const char* name() { return "shh"; } static const int verbosity = 1; };

12
libwhisper/Message.cpp

@ -60,7 +60,7 @@ bool Message::openBroadcastEnvelope(Envelope const& _e, Topics const& _fk, bytes
for (unsigned i = 0; i < _e.topic().size(); ++i)
if (_e.topic()[i] == knownTopic[ti])
{
topicSecret = _fk[ti];
topicSecret = Secret(_fk[ti]);
topicIndex = i;
break;
}
@ -69,9 +69,9 @@ bool Message::openBroadcastEnvelope(Envelope const& _e, Topics const& _fk, bytes
return false;
unsigned index = topicIndex * 2;
h256 encryptedKey = h256(bytesConstRef(&(_e.data())).cropped(h256::size * index, h256::size));
Secret encryptedKey(bytesConstRef(&(_e.data())).cropped(h256::size * index, h256::size));
h256 salt = h256(bytesConstRef(&(_e.data())).cropped(h256::size * ++index, h256::size));
h256 key = generateGamma(topicSecret, salt) ^ encryptedKey;
Secret key = Secret(generateGamma(topicSecret, salt).makeInsecure() ^ encryptedKey.makeInsecure());
bytesConstRef cipherText = bytesConstRef(&(_e.data())).cropped(h256::size * 2 * _e.topic().size());
return decryptSym(key, cipherText, o_b);
}
@ -97,7 +97,7 @@ bool Message::populate(bytes const& _data)
return true;
}
Envelope Message::seal(Secret _from, Topics const& _fullTopics, unsigned _ttl, unsigned _workToProve) const
Envelope Message::seal(Secret const& _from, Topics const& _fullTopics, unsigned _ttl, unsigned _workToProve) const
{
AbridgedTopics topics = abridge(_fullTopics);
Envelope ret(time(0) + _ttl, _ttl, topics);
@ -122,10 +122,10 @@ Envelope Message::seal(Secret _from, Topics const& _fullTopics, unsigned _ttl, u
// this message is for broadcast (could be read by anyone who knows at least one of the topics)
// create the shared secret for encrypting the payload, then encrypt the shared secret with each topic
Secret s = Secret::random();
for (h256 const& t : _fullTopics)
for (h256 const& t: _fullTopics)
{
h256 salt = h256::random();
ret.m_data += (generateGamma(t, salt) ^ s).asBytes();
ret.m_data += (generateGamma(Secret(t), salt).makeInsecure() ^ s.makeInsecure()).ref().toBytes();
ret.m_data += salt.asBytes();
}

6
libwhisper/Message.h

@ -118,16 +118,16 @@ public:
operator bool() const { return !!m_payload.size() || m_from || m_to; }
/// Turn this message into a ditributable Envelope.
Envelope seal(Secret _from, Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) const;
Envelope seal(Secret const& _from, Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) const;
// Overloads for skipping _from or specifying _to.
Envelope seal(Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) const { return seal(Secret(), _topics, _ttl, _workToProve); }
Envelope sealTo(Public _to, Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { m_to = _to; return seal(Secret(), _topics, _ttl, _workToProve); }
Envelope sealTo(Secret _from, Public _to, Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { m_to = _to; return seal(_from, _topics, _ttl, _workToProve); }
Envelope sealTo(Secret const& _from, Public _to, Topics const& _topics, unsigned _ttl = 50, unsigned _workToProve = 50) { m_to = _to; return seal(_from, _topics, _ttl, _workToProve); }
private:
bool populate(bytes const& _data);
bool openBroadcastEnvelope(Envelope const& _e, Topics const& _t, bytes& o_b);
h256 generateGamma(h256 const& _key, h256 const& _salt) const { return sha3(_key ^ _salt); }
Secret generateGamma(Secret const& _key, h256 const& _salt) const { return sha3(_key ^ _salt); }
Public m_from;
Public m_to;

2
mix/ClientModel.h

@ -55,7 +55,7 @@ struct SolidityType;
struct TransactionSettings
{
TransactionSettings() {}
TransactionSettings(QString const& _contractId, QString const& _functionId, u256 _value, u256 _gas, bool _gasAuto, u256 _gasPrice, Secret _sender, bool _isContractCreation, bool _isFunctionCall):
TransactionSettings(QString const& _contractId, QString const& _functionId, u256 _value, u256 _gas, bool _gasAuto, u256 _gasPrice, Secret const& _sender, bool _isContractCreation, bool _isFunctionCall):
contractId(_contractId), functionId(_functionId), value(_value), gas(_gas), gasAuto(_gasAuto), gasPrice(_gasPrice), sender(_sender), isContractCreation(_isContractCreation), isFunctionCall(_isFunctionCall) {}
TransactionSettings(QString const& _stdContractName, QString const& _stdContractUrl):
contractId(_stdContractName), gasAuto(true), stdContractUrl(_stdContractUrl), isContractCreation(true), isFunctionCall(true) {}

2
mix/FileIo.cpp

@ -187,7 +187,7 @@ QStringList FileIo::makePackage(QString const& _deploymentFolder)
bytes dapp = rlpStr.out();
dev::h256 dappHash = dev::sha3(dapp);
//encrypt
KeyPair key(dappHash);
KeyPair key((Secret(dappHash)));
Secp256k1PP enc;
enc.encrypt(key.pub(), dapp);

6
test/libdevcrypto/AES.cpp

@ -35,7 +35,7 @@ BOOST_AUTO_TEST_CASE(AesDecrypt)
{
cout << "AesDecrypt" << endl;
bytes seed = fromHex("2dbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621");
KeyPair kp(sha3(aesDecrypt(&seed, "test")));
KeyPair kp(sha3Secure(aesDecrypt(&seed, "test")));
BOOST_CHECK(Address("07746f871de684297923f933279555dda418f8a2") == kp.address());
}
@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE(AesDecryptWrongSeed)
{
cout << "AesDecryptWrongSeed" << endl;
bytes seed = fromHex("badaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621");
KeyPair kp(sha3(aesDecrypt(&seed, "test")));
KeyPair kp(sha3Secure(aesDecrypt(&seed, "test")));
BOOST_CHECK(Address("07746f871de684297923f933279555dda418f8a2") != kp.address());
}
@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(AesDecryptWrongPassword)
{
cout << "AesDecryptWrongPassword" << endl;
bytes seed = fromHex("2dbaead416c20cfd00c2fc9f1788ff9f965a2000799c96a624767cb0e1e90d2d7191efdd92349226742fdc73d1d87e2d597536c4641098b9a89836c94f58a2ab4c525c27c4cb848b3e22ea245b2bc5c8c7beaa900b0c479253fc96fce7ffc621");
KeyPair kp(sha3(aesDecrypt(&seed, "badtest")));
KeyPair kp(sha3Secure(aesDecrypt(&seed, "badtest")));
BOOST_CHECK(Address("07746f871de684297923f933279555dda418f8a2") != kp.address());
}

32
test/libdevcrypto/SecretStore.cpp

@ -61,9 +61,9 @@ BOOST_AUTO_TEST_CASE(basic_tests)
SecretStore store(tmpDir.path());
h128 u = store.readKeyContent(js::write_string(o["json"], false));
cdebug << "read uuid" << u;
bytes s = store.secret(u, [&](){ return o["password"].get_str(); });
cdebug << "got secret" << toHex(s);
BOOST_REQUIRE_EQUAL(toHex(s), o["priv"].get_str());
bytesSec s = store.secret(u, [&](){ return o["password"].get_str(); });
cdebug << "got secret" << toHex(s.makeInsecure());
BOOST_REQUIRE_EQUAL(toHex(s.makeInsecure()), o["priv"].get_str());
}
}
@ -98,7 +98,7 @@ BOOST_AUTO_TEST_CASE(import_key_from_file)
uuid = store.importKey(importFile);
BOOST_CHECK(!!uuid);
BOOST_CHECK(contentsString(importFile) == keyData);
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure()));
BOOST_CHECK_EQUAL(store.keys().size(), 1);
}
fs::remove(importFile);
@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE(import_key_from_file)
{
SecretStore store(storeDir.path());
BOOST_CHECK_EQUAL(store.keys().size(), 1);
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure()));
}
}
@ -121,15 +121,15 @@ BOOST_AUTO_TEST_CASE(import_secret)
{
SecretStore store(storeDir.path());
BOOST_CHECK_EQUAL(store.keys().size(), 0);
uuid = store.importSecret(fromHex(priv), password);
uuid = store.importSecret(bytesSec(fromHex(priv)), password);
BOOST_CHECK(!!uuid);
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure()));
BOOST_CHECK_EQUAL(store.keys().size(), 1);
}
{
SecretStore store(storeDir.path());
BOOST_CHECK_EQUAL(store.keys().size(), 1);
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure()));
}
}
}
@ -145,12 +145,12 @@ BOOST_AUTO_TEST_CASE(wrong_password)
{
SecretStore store(storeDir.path());
BOOST_CHECK_EQUAL(store.keys().size(), 0);
uuid = store.importSecret(fromHex(priv), password);
uuid = store.importSecret(bytesSec(fromHex(priv)), password);
BOOST_CHECK(!!uuid);
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure()));
BOOST_CHECK_EQUAL(store.keys().size(), 1);
// password will not be queried
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return "abcdefg"; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return "abcdefg"; }).makeInsecure()));
}
{
SecretStore store(storeDir.path());
@ -171,9 +171,9 @@ BOOST_AUTO_TEST_CASE(recode)
{
SecretStore store(storeDir.path());
BOOST_CHECK_EQUAL(store.keys().size(), 0);
uuid = store.importSecret(fromHex(priv), password);
uuid = store.importSecret(bytesSec(fromHex(priv)), password);
BOOST_CHECK(!!uuid);
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return password; }).makeInsecure()));
BOOST_CHECK_EQUAL(store.keys().size(), 1);
}
{
@ -182,16 +182,16 @@ BOOST_AUTO_TEST_CASE(recode)
BOOST_CHECK(store.secret(uuid, [&](){ return "abcdefg"; }).empty());
BOOST_CHECK(store.recode(uuid, changedPassword, [&](){ return password; }));
BOOST_CHECK_EQUAL(store.keys().size(), 1);
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return changedPassword; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return changedPassword; }).makeInsecure()));
store.clearCache();
BOOST_CHECK(store.secret(uuid, [&](){ return password; }).empty());
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return changedPassword; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return changedPassword; }).makeInsecure()));
}
{
SecretStore store(storeDir.path());
BOOST_CHECK_EQUAL(store.keys().size(), 1);
BOOST_CHECK(store.secret(uuid, [&](){ return password; }).empty());
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return changedPassword; })));
BOOST_CHECK_EQUAL(priv, toHex(store.secret(uuid, [&](){ return changedPassword; }).makeInsecure()));
}
}

43
test/libdevcrypto/crypto.cpp

@ -87,7 +87,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_patch)
BOOST_AUTO_TEST_CASE(verify_secert)
{
h256 empty;
Secret empty;
KeyPair kNot(empty);
BOOST_REQUIRE(!kNot.address());
KeyPair k(sha3(empty));
@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_cryptopp_secp256k1libport)
bytes e(fromHex("0x01"));
e.resize(32);
int tests = 2;
while (sha3(&e, &e), secret = sha3(secret.asBytes()), tests--)
while (sha3(&e, &e), secret = sha3(secret), tests--)
{
KeyPair key(secret);
Public pkey = key.pub();
@ -145,7 +145,7 @@ BOOST_AUTO_TEST_CASE(cryptopp_cryptopp_secp256k1libport)
Integer r = s_params.ConvertElementToInteger(rp);
Integer kInv = kInt.InverseMod(q);
Integer s = (kInv * (Integer(secret.asBytes().data(), 32)*r + heInt)) % q;
Integer s = (kInv * (Integer(secret.data(), 32) * r + heInt)) % q;
BOOST_REQUIRE(!!r && !!s);
Signature sig;
@ -311,7 +311,7 @@ BOOST_AUTO_TEST_CASE(ecies_kdf)
BOOST_REQUIRE(eKey1.toBytes() == eKey2.toBytes());
BOOST_REQUIRE(mKey1.toBytes() == mKey2.toBytes());
BOOST_REQUIRE((u256)h256(z1) > 0);
BOOST_REQUIRE(!!z1);
BOOST_REQUIRE(z1 == z2);
BOOST_REQUIRE(key1.size() > 0 && ((u512)h512(key1)) > 0);
@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(ecdh)
ECDH<ECP>::Domain dhA(s_curveOID);
Secret shared;
BOOST_REQUIRE(dhA.Agree(shared.data(), a.sec().data(), pubb));
BOOST_REQUIRE(dhA.Agree(shared.writable().data(), a.sec().data(), pubb));
BOOST_REQUIRE(shared);
}
@ -453,7 +453,7 @@ BOOST_AUTO_TEST_CASE(handshakeNew)
bytesRef nonce(&auth[Signature::size + h256::size + Public::size], h256::size);
crypto::ecdh::agree(nodeA.sec(), nodeB.pub(), ssA);
sign(eA.seckey(), ssA ^ nonceA).ref().copyTo(sig);
sign(eA.seckey(), (ssA ^ nonceA).makeInsecure()).ref().copyTo(sig);
sha3(eA.pubkey().ref(), hepubk);
nodeA.pub().ref().copyTo(pubk);
nonceA.ref().copyTo(nonce);
@ -514,27 +514,27 @@ BOOST_AUTO_TEST_CASE(handshakeNew)
bytes keyMaterialBytes(512);
bytesRef keyMaterial(&keyMaterialBytes);
h256 ess;
Secret ess;
// todo: ecdh-agree should be able to output bytes
eA.agree(eBAck, ess);
ess.ref().copyTo(keyMaterial.cropped(0, h256::size));
ssA.ref().copyTo(keyMaterial.cropped(h256::size, h256::size));
// auto token = sha3(ssA);
aEncryptK = sha3(keyMaterial);
aEncryptK = sha3Secure(keyMaterial);
aEncryptK.ref().copyTo(keyMaterial.cropped(h256::size, h256::size));
aMacK = sha3(keyMaterial);
aMacK = sha3Secure(keyMaterial);
keyMaterialBytes.resize(h256::size + authcipher.size());
keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size());
(aMacK ^ nonceBAck).ref().copyTo(keyMaterial);
bytesConstRef(&authcipher).copyTo(keyMaterial.cropped(h256::size, authcipher.size()));
aEgressMac = sha3(keyMaterial);
aEgressMac = sha3Secure(keyMaterial);
keyMaterialBytes.resize(h256::size + ackcipher.size());
keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size());
(aMacK ^ nonceA).ref().copyTo(keyMaterial);
bytesConstRef(&ackcipher).copyTo(keyMaterial.cropped(h256::size, ackcipher.size()));
aIngressMac = sha3(keyMaterial);
aIngressMac = sha3Secure(keyMaterial);
}
@ -573,7 +573,7 @@ BOOST_AUTO_TEST_CASE(handshakeNew)
Secret ss;
s_secp256k1.agree(nodeB.sec(), nodeAAuth, ss);
eAAuth = recover(sigAuth, ss ^ nonceAAuth);
eAAuth = recover(sigAuth, (ss ^ nonceAAuth).makeInsecure());
// todo: test when this fails; means remote is bad or packet bits were flipped
BOOST_REQUIRE_EQUAL(heA, sha3(eAAuth));
BOOST_REQUIRE_EQUAL(eAAuth, eA.pubkey());
@ -581,29 +581,29 @@ BOOST_AUTO_TEST_CASE(handshakeNew)
bytes keyMaterialBytes(512);
bytesRef keyMaterial(&keyMaterialBytes);
h256 ess;
Secret ess;
// todo: ecdh-agree should be able to output bytes
eB.agree(eAAuth, ess);
// s_secp256k1.agree(eB.seckey(), eAAuth, ess);
ess.ref().copyTo(keyMaterial.cropped(0, h256::size));
ssB.ref().copyTo(keyMaterial.cropped(h256::size, h256::size));
// auto token = sha3(ssA);
bEncryptK = sha3(keyMaterial);
bEncryptK = sha3Secure(keyMaterial);
bEncryptK.ref().copyTo(keyMaterial.cropped(h256::size, h256::size));
bMacK = sha3(keyMaterial);
bMacK = sha3Secure(keyMaterial);
// todo: replace nonceB with decrypted nonceB
keyMaterialBytes.resize(h256::size + ackcipher.size());
keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size());
(bMacK ^ nonceAAuth).ref().copyTo(keyMaterial);
bytesConstRef(&ackcipher).copyTo(keyMaterial.cropped(h256::size, ackcipher.size()));
bEgressMac = sha3(keyMaterial);
bEgressMac = sha3Secure(keyMaterial);
keyMaterialBytes.resize(h256::size + authcipher.size());
keyMaterial.retarget(keyMaterialBytes.data(), keyMaterialBytes.size());
(bMacK ^ nonceB).ref().copyTo(keyMaterial);
bytesConstRef(&authcipher).copyTo(keyMaterial.cropped(h256::size, authcipher.size()));
bIngressMac = sha3(keyMaterial);
bIngressMac = sha3Secure(keyMaterial);
}
BOOST_REQUIRE_EQUAL(aEncryptK, bEncryptK);
@ -617,7 +617,7 @@ BOOST_AUTO_TEST_CASE(handshakeNew)
BOOST_AUTO_TEST_CASE(ecies_aes128_ctr_unaligned)
{
h128 encryptK(sha3("..."), h128::AlignLeft);
SecureFixedHash<16> encryptK(sha3("..."), h128::AlignLeft);
h256 egressMac(sha3("+++"));
// TESTING: send encrypt magic sequence
bytes magic {0x22,0x40,0x08,0x91};
@ -629,16 +629,17 @@ BOOST_AUTO_TEST_CASE(ecies_aes128_ctr_unaligned)
egressMac.ref().copyTo(bytesRef(&magicCipherAndMac).cropped(magicCipherAndMac.size() - 32, 32));
bytesConstRef cipher(&magicCipherAndMac[0], magicCipherAndMac.size() - 32);
bytes plaintext = decryptSymNoAuth(encryptK, h128(), cipher);
bytes plaintext = decryptSymNoAuth(encryptK, h128(), cipher).makeInsecure();
plaintext.resize(magic.size());
// @alex @subtly TODO: FIX: this check is pointless with the above line.
BOOST_REQUIRE(plaintext.size() > 0);
BOOST_REQUIRE(magic == plaintext);
}
BOOST_AUTO_TEST_CASE(ecies_aes128_ctr)
{
h128 k(sha3("0xAAAA"), h128::AlignLeft);
SecureFixedHash<16> k(sha3("0xAAAA"), h128::AlignLeft);
string m = "AAAAAAAAAAAAAAAA";
bytesConstRef msg((byte*)m.data(), m.size());
@ -646,7 +647,7 @@ BOOST_AUTO_TEST_CASE(ecies_aes128_ctr)
h128 iv;
tie(ciphertext, iv) = encryptSymNoAuth(k, msg);
bytes plaintext = decryptSymNoAuth(k, iv, &ciphertext);
bytes plaintext = decryptSymNoAuth(k, iv, &ciphertext).makeInsecure();
BOOST_REQUIRE_EQUAL(asString(plaintext), m);
}

14
test/libethcore/commonjs.cpp

@ -32,8 +32,8 @@ BOOST_AUTO_TEST_CASE(jsToPublic)
{
cnote << "Testing jsToPublic...";
KeyPair kp = KeyPair::create();
string string = toJS(kp.pub());
Public pub = dev::jsToPublic(string);
string s = toJS(kp.pub());
Public pub = dev::jsToPublic(s);
BOOST_CHECK_EQUAL(kp.pub(), pub);
}
@ -41,8 +41,8 @@ BOOST_AUTO_TEST_CASE(jsToAddress)
{
cnote << "Testing jsToPublic...";
KeyPair kp = KeyPair::create();
string string = toJS(kp.address());
Address address = dev::jsToAddress(string);
string s = toJS(kp.address());
Address address = dev::jsToAddress(s);
BOOST_CHECK_EQUAL(kp.address(), address);
}
@ -50,9 +50,9 @@ BOOST_AUTO_TEST_CASE(jsToSecret)
{
cnote << "Testing jsToPublic...";
KeyPair kp = KeyPair::create();
string string = toJS(kp.secret());
Secret secret = dev::jsToSecret(string);
BOOST_CHECK_EQUAL(kp.secret(), secret);
string s = toJS(kp.secret().makeInsecure());
Secret secret = dev::jsToSecret(s);
BOOST_CHECK_EQUAL(kp.secret().makeInsecure(), secret.makeInsecure());
}
BOOST_AUTO_TEST_SUITE_END()

45
test/libethereum/StateTestsFiller/stSystemOperationsTestFiller.json

@ -2832,5 +2832,48 @@
"to" : "bbbf5374fce5edbc8e2a8697c15331677e6ebf0b",
"value" : "10"
}
}
},
"extcodecopy" : {
"env" : {
"currentCoinbase" : "4401fcaf7d64d53fb1cfc5c9045c32aa919a8c82",
"currentDifficulty" : "0x7fb7d889155ce8c6",
"currentGasLimit" : "0x58272e28",
"currentNumber" : "0x7608d138",
"currentTimestamp" : "0xa4befad141d51c4f",
"previousHash" : "d30f77155de00f207ad60109897e790f73e9f3431be25717bf3651d91949f041"
},
"pre" : {
"095e7baea6a6c7c4c2dfeb977efac326af552d87" : {
"balance" : "0x05c81eb0",
"code" : "0x7f15688566a82f5f946c68028bf626b349e495daa43e33529a76437ac416cd1b7d6e7dae7454bb193b1c28e64a6a935bc373cea0c5cc171fa61277e5604a3bc8aef4de3d38820658600b80797ada6e82e95f6520383f95f5c7dae56b4dc13b6f22ecabfce07c3cff51",
"nonce" : "0xfe",
"storage" : {
}
},
"945304eb96065b2a98b57a48a06ae28d285a71b5" : {
"balance" : "0x4d6769f8",
"code" : "0x5a60106017601160116018601c600f601b601d5f60026013600f601a8d5a5b7679177b5dd41a23db52998c4dcd14e88390dcc9f3ed5783601660145f6013600d601f60016011600e600c600d601f60138c7a58f20fd882eb51408a52e569ce80e93270ab53ae9de3fec5498a5c72ce1fcd11bb1553736959df779a616b738c1f407c12459490afe302da311a673488d09e71041d0761dee4829e3c38e0b1b1787810f2e11e2289983c1ab47cf5ebd38c12f1719232b5f3a7b27a9ea8858a071c4169392ec725646311235cbd9534e5d7cd8cb5e2287738a43f803384f4e62fe6629ea2e609a71759edab5c3a58b87e94c95f710aa6059b0663c9f374ce6ea0a000c5d594c41252d4a74d64896a987cc57c24df2ce8ffb85adcc27dce2d19f7006fbc1c5a7b79a319418fd6c27ddebcf170192262d82c1053333f6115c8b258b81e2e84d723c98dbd4535de7f922723a15827bbcfd07f9e2c5027c7736ed68c61b332059d7ec1bae1c1fd41a361d35b996d9740a588b6abf3293236afb927717328c014846148ce67eaf2b33d90672366dafeaae0714eb39e7fd5076a831d8eb4a3546288a3e1a0087aebe80b6bbfa4041330b05d094a697236fe7654d8a7ce630f83a832620125d781666e898f7fdcfd0031",
"nonce" : "0xdd",
"storage" : {
}
},
"a94f5374fce5edbc8e2a8697c15331677e6ebf0b" : {
"balance" : "0x4f6ca7b90ceb5fd4",
"code" : "0x",
"nonce" : "0x00",
"storage" : {
}
}
},
"transaction" : {
"data" : "0x6e27b0577f2549e5fa01e3db96e7b03a62e489115538620295677faf15040c1c1796bad130e2462a8b8d6bbe0fa35bf12087047ef4ff4e66df8772196b4401998ff7f4219c013a0d927b22d8d3fdf625809abb182507d180e687b666f4f1e4f3b8172e87760f436c701264b89739f3d7c50ec524f16b1a4f91397b760a5209b9b7710544694ecf2729643b3ca545c7",
"gasLimit" : "0x3bd760dd",
"gasPrice" : "0x1cd49878",
"nonce" : "0x00",
"secretKey" : "45a915e4d060149eb4365960e6a7a45f334393093061116b197e3240065ff2d8",
"to" : "095e7baea6a6c7c4c2dfeb977efac326af552d87",
"value" : "0x24a39757"
}
}
}

3
test/libethereum/gaspricer.cpp

@ -17,6 +17,7 @@
/** @file gasPricer.cpp
* @author Christoph Jentzsch <cj@ethdev.com>
* @date 2015
* Gas pricer tests
*/
#include <libtestutils/BlockChainLoader.h>
@ -32,7 +33,7 @@ using namespace dev::eth;
namespace dev { namespace test {
void executeGasPricerTest(const string name, double _etherPrice, double _blockFee, const string bcTestPath, TransactionPriority _txPrio, u256 _expectedAsk, u256 _expectedBid)
void executeGasPricerTest(string const& name, double _etherPrice, double _blockFee, string const& bcTestPath, TransactionPriority _txPrio, u256 _expectedAsk, u256 _expectedBid)
{
cnote << name;
BasicGasPricer gp(u256(double(ether / 1000) / _etherPrice), u256(_blockFee * 1000));

4
test/libethereum/stateOriginal.cpp

@ -54,8 +54,8 @@ BOOST_AUTO_TEST_CASE(Complex)
cnote << "Testing State...";
KeyPair me = sha3("Gav Wood");
KeyPair myMiner = sha3("Gav's Miner");
KeyPair me = Secret(sha3("Gav Wood"));
KeyPair myMiner = Secret(sha3("Gav's Miner"));
// KeyPair you = sha3("123");
Defaults::setDBPath(boost::filesystem::temp_directory_path().string() + "/" + toString(chrono::system_clock::now().time_since_epoch().count()));

Loading…
Cancel
Save