diff --git a/CMakeLists.txt b/CMakeLists.txt
index 289cecad8..ac37454d8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -295,6 +295,7 @@ message("-- EVMJIT Build LLVM-based JIT EVM (experimental!) ${EVMJIT}"
message("------------------------------------------------------------------------")
message("")
+set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin")
set(CMAKE_THREAD_LIBS_INIT pthread)
include(EthCompilerSettings)
diff --git a/alethzero/Main.ui b/alethzero/Main.ui
index 5b0ad7582..e0852142a 100644
--- a/alethzero/Main.ui
+++ b/alethzero/Main.ui
@@ -151,6 +151,7 @@
+
@@ -1727,6 +1728,11 @@ font-size: 14pt
In&ject Block
+
+
+ Prepare Next &DAG
+
+
diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp
index 87c9c2dc9..7551eaa35 100644
--- a/alethzero/MainWin.cpp
+++ b/alethzero/MainWin.cpp
@@ -204,7 +204,7 @@ Main::Main(QWidget *parent) :
QSettings s("ethereum", "alethzero");
m_networkConfig = s.value("peers").toByteArray();
bytesConstRef network((byte*)m_networkConfig.data(), m_networkConfig.size());
- m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), WithExisting::Trust, {"eth", "shh"}, p2p::NetworkPreferences(), network));
+ m_webThree.reset(new WebThreeDirect(string("AlethZero/v") + dev::Version + "/" DEV_QUOTED(ETH_BUILD_TYPE) "/" DEV_QUOTED(ETH_BUILD_PLATFORM), getDataDir(), WithExisting::Trust, {"eth"/*, "shh"*/}, p2p::NetworkPreferences(), network));
m_httpConnector.reset(new jsonrpc::HttpServer(SensibleHttpPort, "", "", dev::SensibleHttpThreads));
m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), this));
@@ -943,22 +943,30 @@ void Main::on_preview_triggered()
refreshAll();
}
+void Main::on_prepNextDAG_triggered()
+{
+ EthashAux::computeFull(ethereum()->blockChain().number() + ETHASH_EPOCH_LENGTH);
+}
+
void Main::refreshMining()
{
+ pair gp = EthashAux::fullGeneratingProgress();
+ QString t;
+ if (gp.first != EthashAux::NotGenerating)
+ t = QString("DAG for #%1-#%2: %3% complete; ").arg(gp.first).arg(gp.first + ETHASH_EPOCH_LENGTH - 1).arg(gp.second);
MiningProgress p = ethereum()->miningProgress();
- ui->mineStatus->setText(ethereum()->isMining() ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Not mining");
- if (!ui->miningView->isVisible())
- return;
- list l = ethereum()->miningHistory();
- static unsigned lh = 0;
- if (p.hashes < lh)
- ui->miningView->resetStats();
- lh = p.hashes;
- ui->miningView->appendStats(l, p);
-/* if (p.ms)
- for (MineInfo const& i: l)
- cnote << i.hashes * 10 << "h/sec, need:" << i.requirement << " best:" << i.best << " best-so-far:" << p.best << " avg-speed:" << (p.hashes * 1000 / p.ms) << "h/sec";
-*/
+ ui->mineStatus->setText(t + (ethereum()->isMining() ? p.hashes > 0 ? QString("%1s @ %2kH/s").arg(p.ms / 1000).arg(p.ms ? p.hashes / p.ms : 0) : "Awaiting DAG" : "Not mining"));
+ if (ethereum()->isMining() && p.hashes > 0)
+ {
+ if (!ui->miningView->isVisible())
+ return;
+ list l = ethereum()->miningHistory();
+ static unsigned lh = 0;
+ if (p.hashes < lh)
+ ui->miningView->resetStats();
+ lh = p.hashes;
+ ui->miningView->appendStats(l, p);
+ }
}
void Main::setBeneficiary(Address const& _b)
@@ -1878,6 +1886,7 @@ void Main::on_mine_triggered()
{
if (ui->mine->isChecked())
{
+// EthashAux::computeFull(ethereum()->blockChain().number());
ethereum()->setAddress(m_beneficiary);
ethereum()->startMining();
}
@@ -2027,6 +2036,7 @@ std::string Main::prettyU256(dev::u256 const& _n) const
void Main::on_post_clicked()
{
+ return;
shh::Message m;
m.setTo(stringToPublic(ui->shhTo->currentText()));
m.setPayload(parseData(ui->shhData->toPlainText().toStdString()));
@@ -2051,6 +2061,7 @@ int Main::authenticate(QString _title, QString _text)
void Main::refreshWhispers()
{
+ return;
ui->whispers->clear();
for (auto const& w: whisper()->all())
{
diff --git a/alethzero/MainWin.h b/alethzero/MainWin.h
index 51d4cc8f4..d9075d178 100644
--- a/alethzero/MainWin.h
+++ b/alethzero/MainWin.h
@@ -124,6 +124,7 @@ private slots:
// Mining
void on_mine_triggered();
+ void on_prepNextDAG_triggered();
// View
void on_refresh_triggered();
diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp
index bc37db8ef..f2a8ef0d5 100644
--- a/alethzero/Transact.cpp
+++ b/alethzero/Transact.cpp
@@ -299,8 +299,9 @@ void Transact::rejigData()
return;
// Determine how much balance we have to play with...
- auto s = findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice());
- auto b = ethereum()->balanceAt(KeyPair(s).address(), PendingBlock);
+ //findSecret(value() + ethereum()->gasLimitRemaining() * gasPrice());
+ auto s = fromAccount();
+ auto b = ethereum()->balanceAt(s, PendingBlock);
m_allGood = true;
QString htmlInfo;
diff --git a/cmake/EthExecutableHelper.cmake b/cmake/EthExecutableHelper.cmake
index 1d1cb887b..3dd7fa798 100644
--- a/cmake/EthExecutableHelper.cmake
+++ b/cmake/EthExecutableHelper.cmake
@@ -45,25 +45,26 @@ endmacro()
macro(eth_copy_dlls EXECUTABLE DLLS)
# dlls must be unsubstitud list variable (without ${}) in format
- # optimized;path_to_dll.dll;debug;path_to_dlld.dll
+ # optimized;path_to_dll.dll;debug;path_to_dlld.dll
list(GET ${DLLS} 1 DLL_RELEASE)
list(GET ${DLLS} 3 DLL_DEBUG)
+ get_target_property(TARGET_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE} RUNTIME_OUTPUT_DIRECTORY)
add_custom_command(TARGET ${EXECUTABLE}
- POST_BUILD
- COMMAND ${CMAKE_COMMAND} ARGS
- -DDLL_RELEASE="${DLL_RELEASE}"
- -DDLL_DEBUG="${DLL_DEBUG}"
+ POST_BUILD
+ COMMAND ${CMAKE_COMMAND} ARGS
+ -DDLL_RELEASE="${DLL_RELEASE}"
+ -DDLL_DEBUG="${DLL_DEBUG}"
-DCONF="$"
- -DDESTINATION="${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}"
+ -DDESTINATION="${TARGET_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}"
-P "${ETH_SCRIPTS_DIR}/copydlls.cmake"
)
endmacro()
-#
+#
# this function requires the following variables to be specified:
# ETH_DEPENDENCY_INSTALL_DIR
#
-# params:
+# params:
# QMLDIR
#
@@ -74,7 +75,7 @@ macro(eth_install_executable EXECUTABLE)
set (one_value_args QMLDIR)
set (multi_value_args DLLS)
cmake_parse_arguments (ETH_INSTALL_EXECUTABLE "${options}" "${one_value_args}" "${multi_value_args}" "${extra_macro_args}")
-
+
if (ETH_INSTALL_EXECUTABLE_QMLDIR)
if (APPLE)
set(eth_qml_dir "-qmldir=${ETH_INSTALL_EXECUTABLE_QMLDIR}")
@@ -87,19 +88,15 @@ macro(eth_install_executable EXECUTABLE)
if (APPLE)
# First have qt5 install plugins and frameworks
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
- COMMAND ${MACDEPLOYQT_APP} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app -executable=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app/Contents/MacOS/${EXECUTABLE} ${eth_qml_dir}
- WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
- COMMAND sh ${CMAKE_SOURCE_DIR}/macdeployfix.sh ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.app/Contents
+ COMMAND ${MACDEPLOYQT_APP} ${EXECUTABLE}.app -executable=${EXECUTABLE}.app/Contents/MacOS/${EXECUTABLE} ${eth_qml_dir}
+ WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}
+ COMMAND sh ${CMAKE_SOURCE_DIR}/macdeployfix.sh ${EXECUTABLE}.app/Contents
)
-
- # This tool and next will inspect linked libraries in order to determine which dependencies are required
- if (${CMAKE_CFG_INTDIR} STREQUAL ".")
- # TODO: This should only happen for GUI application
- set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}.app")
- else ()
- set(APP_BUNDLE_PATH "${CMAKE_CURRENT_BINARY_DIR}/\$ENV{CONFIGURATION}/${EXECUTABLE}.app")
- endif ()
+ # TODO: This should only happen for GUI application
+ set(APP_BUNDLE_PATH "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INDIR}/${EXECUTABLE}.app")
+
+ # This tool and next will inspect linked libraries in order to determine which dependencies are required
install(CODE "
include(BundleUtilities)
set(BU_CHMOD_BUNDLE_ITEMS 1)
@@ -111,14 +108,15 @@ macro(eth_install_executable EXECUTABLE)
get_target_property(TARGET_LIBS ${EXECUTABLE} INTERFACE_LINK_LIBRARIES)
string(REGEX MATCH "Qt5::Core" HAVE_QT ${TARGET_LIBS})
if ("${HAVE_QT}" STREQUAL "Qt5::Core")
+ get_target_property(TARGET_RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE} RUNTIME_OUTPUT_DIRECTORY)
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
- COMMAND cmd /C "set PATH=${Qt5Core_DIR}/../../../bin;%PATH% && ${WINDEPLOYQT_APP} ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.exe ${eth_qml_dir}"
+ COMMAND cmd /C "set PATH=${Qt5Core_DIR}/../../../bin;%PATH% && ${WINDEPLOYQT_APP} ${TARGET_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/${EXECUTABLE}.exe ${eth_qml_dir}"
WORKING_DIRECTORY ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
#workaround for https://bugreports.qt.io/browse/QTBUG-42083
add_custom_command(TARGET ${EXECUTABLE} POST_BUILD
COMMAND cmd /C "(echo [Paths] & echo.Prefix=.)" > "qt.conf"
- WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR} VERBATIM
+ WORKING_DIRECTORY ${TARGET_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR} VERBATIM
)
endif()
@@ -144,5 +142,3 @@ macro(eth_install_executable EXECUTABLE)
endif ()
endmacro()
-
-
diff --git a/cmake/scripts/copydlls.cmake b/cmake/scripts/copydlls.cmake
index 6d86b8e4e..57eb0ffd4 100644
--- a/cmake/scripts/copydlls.cmake
+++ b/cmake/scripts/copydlls.cmake
@@ -14,5 +14,4 @@ else () # Debug
set(DLL ${DLL_DEBUG})
endif()
-execute_process(COMMAND ${CMAKE_COMMAND} -E copy "${DLL}" "${DESTINATION}")
-
+execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${DLL}" "${DESTINATION}")
diff --git a/eth/main.cpp b/eth/main.cpp
index 60d454287..abb78c20d 100644
--- a/eth/main.cpp
+++ b/eth/main.cpp
@@ -158,6 +158,11 @@ void help()
<< " --port Connect to remote port (default: 30303)." << endl
<< " --network-id Only connect to other hosts with this network id (default:0)." << endl
<< " --upnp Use UPnP for NAT (default: on)." << endl
+ << endl
+ << "Client structured logging:" << endl
+ << " --structured-logging Enable structured logging (default output to stdout)." << endl
+ << " --structured-logging-format Set the structured logging time format." << endl
+ << " --structured-logging-url Set the structured logging destination (currently only file:// supported)." << endl
#if ETH_JSONRPC || !ETH_TRUE
<< endl
<< "Work farming mode:" << endl
@@ -806,8 +811,11 @@ int main(int argc, char** argv)
structuredLoggingFormat = string(argv[++i]);
else if (arg == "--structured-logging")
structuredLogging = true;
- else if (arg == "--structured-logging-destination" && i + 1 < argc)
+ else if (arg == "--structured-logging-url" && i + 1 < argc)
+ {
+ structuredLogging = true;
structuredLoggingURL = argv[++i];
+ }
else if ((arg == "-d" || arg == "--path" || arg == "--db-path") && i + 1 < argc)
dbPath = argv[++i];
else if ((arg == "-D" || arg == "--create-dag") && i + 1 < argc)
@@ -848,7 +856,7 @@ int main(int argc, char** argv)
auto boundary = bi.boundary();
m = boost::to_lower_copy(string(argv[++i]));
bi.nonce = h64(m);
- auto r = EthashAux::eval(seedHash, powHash, bi.nonce);
+ auto r = EthashAux::eval((uint64_t)bi.number, powHash, bi.nonce);
bool valid = r.value < boundary;
cout << (valid ? "VALID :-)" : "INVALID :-(") << endl;
cout << r.value << (valid ? " < " : " >= ") << boundary << endl;
@@ -857,7 +865,7 @@ int main(int argc, char** argv)
cout << " with seed as " << seedHash << endl;
if (valid)
cout << "(mixHash = " << r.mixHash << ")" << endl;
- cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light(seedHash)->data()) << endl;
+ cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light((uint64_t)bi.number)->data()) << endl;
exit(0);
}
catch (...)
@@ -1033,6 +1041,28 @@ int main(int argc, char** argv)
if (!clientName.empty())
clientName += "/";
+ string logbuf;
+ bool silence = false;
+ std::string additional;
+ g_logPost = [&](std::string const& a, char const*){
+ if (silence)
+ logbuf += a + "\n";
+ else
+ cout << "\r \r" << a << endl << additional << flush;
+ };
+
+ auto getPassword = [&](string const& prompt){
+ auto s = silence;
+ silence = true;
+ cout << endl;
+ string ret = dev::getPassword(prompt);
+ silence = s;
+ return ret;
+ };
+ auto getAccountPassword = [&](Address const& a){
+ return getPassword("Enter password for address " + keyManager.accountDetails()[a].first + " (" + a.abridged() + "; hint:" + keyManager.accountDetails()[a].second + "): ");
+ };
+
StructuredLogger::get().initialize(structuredLogging, structuredLoggingFormat, structuredLoggingURL);
VMFactory::setKind(jit ? VMKind::JIT : VMKind::Interpreter);
auto netPrefs = publicIP.empty() ? NetworkPreferences(listenIP ,listenPort, upnp) : NetworkPreferences(publicIP, listenIP ,listenPort, upnp);
@@ -1042,13 +1072,38 @@ int main(int argc, char** argv)
clientImplString,
dbPath,
killChain,
- nodeMode == NodeMode::Full ? set{"eth", "shh"} : set(),
+ nodeMode == NodeMode::Full ? set{"eth"/*, "shh"*/} : set(),
netPrefs,
&nodesState);
if (mode == OperationMode::DAGInit)
doInitDAG(web3.ethereum()->blockChain().number() + (initDAG == PendingBlock ? 30000 : 0));
+ if (keyManager.exists())
+ while (masterPassword.empty())
+ {
+ masterPassword = getPassword("Please enter your MASTER password: ");
+ if (!keyManager.load(masterPassword))
+ {
+ cout << "Password invalid. Try again." << endl;
+ masterPassword.clear();
+ }
+ }
+ else
+ {
+ while (masterPassword.empty())
+ {
+ masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): ");
+ string confirm = getPassword("Please confirm the password by entering it again: ");
+ if (masterPassword != confirm)
+ {
+ cout << "Passwords were different. Try again." << endl;
+ masterPassword.clear();
+ }
+ }
+ keyManager.create(masterPassword);
+ }
+
auto toNumber = [&](string const& s) -> unsigned {
if (s == "latest")
return web3.ethereum()->number();
@@ -1137,53 +1192,13 @@ int main(int argc, char** argv)
if (remoteHost.size())
web3.addNode(p2p::NodeId(), remoteHost + ":" + toString(remotePort));
- if (keyManager.exists())
- while (masterPassword.empty())
- {
- masterPassword = getPassword("Please enter your MASTER password: ");
- if (!keyManager.load(masterPassword))
- {
- cout << "Password invalid. Try again." << endl;
- masterPassword.clear();
- }
- }
- else
- {
- while (masterPassword.empty())
- {
- masterPassword = getPassword("Please enter a MASTER password to protect your key store (make it strong!): ");
- string confirm = getPassword("Please confirm the password by entering it again: ");
- if (masterPassword != confirm)
- {
- cout << "Passwords were different. Try again." << endl;
- masterPassword.clear();
- }
- }
- keyManager.create(masterPassword);
- }
-
- string logbuf;
- bool silence = false;
- std::string additional;
- g_logPost = [&](std::string const& a, char const*) { if (silence) logbuf += a + "\n"; else cout << "\r \r" << a << endl << additional << flush; };
-
- // TODO: give hints &c.
- auto getPassword = [&](Address const& a){
- auto s = silence;
- silence = true;
- cout << endl;
- string ret = dev::getPassword("Enter password for address " + keyManager.accountDetails()[a].first + " (" + a.abridged() + "; hint:" + keyManager.accountDetails()[a].second + "): ");
- silence = s;
- return ret;
- };
-
#if ETH_JSONRPC || !ETH_TRUE
shared_ptr jsonrpcServer;
unique_ptr jsonrpcConnector;
if (jsonrpc > -1)
{
jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads));
- jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector()));
+ jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getAccountPassword, keyManager), vector()));
jsonrpcServer->StartListening();
}
#endif
@@ -1327,7 +1342,7 @@ int main(int argc, char** argv)
if (jsonrpc < 0)
jsonrpc = SensibleHttpPort;
jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads));
- jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getPassword, keyManager), vector()));
+ jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, make_shared([&](){return web3.ethereum();}, getAccountPassword, keyManager), vector()));
jsonrpcServer->StartListening();
}
else if (cmd == "jsonstop")
@@ -1479,7 +1494,7 @@ int main(int argc, char** argv)
try
{
Address dest = h160(fromHex(hexAddr, WhenError::Throw));
- c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), amount, dest, bytes(), minGas);
+ c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), amount, dest, bytes(), minGas);
}
catch (BadHexCharacter& _e)
{
@@ -1548,7 +1563,7 @@ int main(int argc, char** argv)
else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas;
else
- c->submitTransaction(keyManager.secret(signingKey, [&](){ return getPassword(signingKey); }), endowment, init, gas, gasPrice);
+ c->submitTransaction(keyManager.secret(signingKey, [&](){ return getAccountPassword(signingKey); }), endowment, init, gas, gasPrice);
}
else
cwarn << "Require parameters: contract ENDOWMENT GASPRICE GAS CODEHEX";
diff --git a/ethminer/main.cpp b/ethminer/main.cpp
index 02ccf2dd8..124d3f779 100644
--- a/ethminer/main.cpp
+++ b/ethminer/main.cpp
@@ -417,7 +417,7 @@ int main(int argc, char** argv)
auto boundary = bi.boundary();
m = boost::to_lower_copy(string(argv[++i]));
bi.nonce = h64(m);
- auto r = EthashAux::eval(seedHash, powHash, bi.nonce);
+ auto r = EthashAux::eval((uint64_t)bi.number, powHash, bi.nonce);
bool valid = r.value < boundary;
cout << (valid ? "VALID :-)" : "INVALID :-(") << endl;
cout << r.value << (valid ? " < " : " >= ") << boundary << endl;
@@ -426,7 +426,7 @@ int main(int argc, char** argv)
cout << " with seed as " << seedHash << endl;
if (valid)
cout << "(mixHash = " << r.mixHash << ")" << endl;
- cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light(seedHash)->data()) << endl;
+ cout << "SHA3( light(seed) ) = " << sha3(EthashAux::light((uint64_t)bi.number)->data()) << endl;
exit(0);
}
catch (...)
diff --git a/evmjit/CMakeLists.txt b/evmjit/CMakeLists.txt
index 5ab394a80..a0e9c1f46 100644
--- a/evmjit/CMakeLists.txt
+++ b/evmjit/CMakeLists.txt
@@ -33,6 +33,8 @@ else()
link_directories(/usr/lib/llvm-3.5/lib)
endif()
+get_filename_component(EVMJIT_INCLUDE_DIR include ABSOLUTE)
+
add_subdirectory(libevmjit)
if(EVMJIT_CPP)
diff --git a/evmjit/include/evmjit/DataTypes.h b/evmjit/include/evmjit/DataTypes.h
new file mode 100644
index 000000000..179d9a372
--- /dev/null
+++ b/evmjit/include/evmjit/DataTypes.h
@@ -0,0 +1,56 @@
+#pragma once
+
+#include
+#include
+
+namespace dev
+{
+namespace evmjit
+{
+
+struct h256
+{
+ uint64_t words[4];
+};
+
+inline bool operator==(h256 _h1, h256 _h2)
+{
+ return _h1.words[0] == _h2.words[0] &&
+ _h1.words[1] == _h2.words[1] &&
+ _h1.words[2] == _h2.words[2] &&
+ _h1.words[3] == _h2.words[3];
+}
+
+/// Representation of 256-bit value binary compatible with LLVM i256
+struct i256
+{
+ uint64_t a = 0;
+ uint64_t b = 0;
+ uint64_t c = 0;
+ uint64_t d = 0;
+
+ i256() = default;
+ i256(h256 _h)
+ {
+ a = _h.words[0];
+ b = _h.words[1];
+ c = _h.words[2];
+ d = _h.words[3];
+ }
+};
+
+}
+}
+
+namespace std
+{
+template<> struct hash
+{
+ size_t operator()(dev::evmjit::h256 const& _h) const
+ {
+ /// This implementation expects the argument to be a full 256-bit Keccak hash.
+ /// It does nothing more than returning a slice of the input hash.
+ return static_cast(_h.words[0]);
+ };
+};
+}
diff --git a/evmjit/include/evmjit/JIT.h b/evmjit/include/evmjit/JIT.h
new file mode 100644
index 000000000..446dd9e56
--- /dev/null
+++ b/evmjit/include/evmjit/JIT.h
@@ -0,0 +1,36 @@
+#pragma once
+
+#include "evmjit/DataTypes.h"
+
+namespace dev
+{
+namespace eth
+{
+namespace jit
+{
+ class ExecutionEngine;
+}
+}
+
+namespace evmjit
+{
+
+class JIT
+{
+public:
+
+ /// Ask JIT if the EVM code is ready for execution.
+ /// Returns `true` if the EVM code has been compiled and loaded into memory.
+ /// In this case the code can be executed without overhead.
+ /// \param _codeHash The Keccak hash of the EVM code.
+ static bool isCodeReady(h256 _codeHash);
+
+private:
+ friend class dev::eth::jit::ExecutionEngine;
+
+ static void* getCode(h256 _codeHash);
+ static void mapCode(h256 _codeHash, void* _funcAddr);
+};
+
+}
+}
diff --git a/evmjit/libevmjit-cpp/CMakeLists.txt b/evmjit/libevmjit-cpp/CMakeLists.txt
index 5b4dbb9c8..5b2a35b00 100644
--- a/evmjit/libevmjit-cpp/CMakeLists.txt
+++ b/evmjit/libevmjit-cpp/CMakeLists.txt
@@ -19,6 +19,7 @@ add_library(${TARGET_NAME} STATIC ${SOURCES})
set_property(TARGET ${TARGET_NAME} PROPERTY FOLDER "libs")
include_directories(../..)
+include_directories(${EVMJIT_INCLUDE_DIR})
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${Boost_INCLUDE_DIRS})
diff --git a/evmjit/libevmjit-cpp/Env.cpp b/evmjit/libevmjit-cpp/Env.cpp
index 2c37412fc..a5a60f48c 100644
--- a/evmjit/libevmjit-cpp/Env.cpp
+++ b/evmjit/libevmjit-cpp/Env.cpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
#include "Utils.h"
@@ -16,7 +17,7 @@ extern "C"
using namespace dev;
using namespace dev::eth;
- using jit::i256;
+ using evmjit::i256;
EXPORT void env_sload(ExtVMFace* _env, i256* _index, i256* o_value)
{
diff --git a/evmjit/libevmjit-cpp/JitVM.cpp b/evmjit/libevmjit-cpp/JitVM.cpp
index 84cc41dd1..7acbec5c1 100644
--- a/evmjit/libevmjit-cpp/JitVM.cpp
+++ b/evmjit/libevmjit-cpp/JitVM.cpp
@@ -32,9 +32,7 @@ bytesConstRef JitVM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _step)
if (rejected)
{
cwarn << "Execution rejected by EVM JIT (gas limit: " << m_gas << "), executing with interpreter";
- VMFactory::setKind(VMKind::Interpreter);
- m_fallbackVM = VMFactory::create(m_gas);
- VMFactory::setKind(VMKind::JIT);
+ m_fallbackVM = VMFactory::create(VMKind::Interpreter, m_gas);
auto&& output = m_fallbackVM->go(_ext, _onOp, _step);
m_gas = m_fallbackVM->gas(); // copy remaining gas, Executive expects it
return output;
diff --git a/evmjit/libevmjit-cpp/Utils.h b/evmjit/libevmjit-cpp/Utils.h
index ac796920b..f9b9b2ef4 100644
--- a/evmjit/libevmjit-cpp/Utils.h
+++ b/evmjit/libevmjit-cpp/Utils.h
@@ -1,13 +1,13 @@
#pragma once
-#include
+#include
namespace dev
{
namespace eth
{
-inline u256 llvm2eth(jit::i256 _i)
+inline u256 llvm2eth(evmjit::i256 _i)
{
u256 u = 0;
u |= _i.d;
@@ -20,9 +20,9 @@ inline u256 llvm2eth(jit::i256 _i)
return u;
}
-inline jit::i256 eth2llvm(u256 _u)
+inline evmjit::i256 eth2llvm(u256 _u)
{
- jit::i256 i;
+ evmjit::i256 i;
u256 mask = 0xFFFFFFFFFFFFFFFF;
i.a = static_cast(_u & mask);
_u >>= 64;
@@ -34,5 +34,11 @@ inline jit::i256 eth2llvm(u256 _u)
return i;
}
+inline evmjit::h256 eth2llvm(h256 _u)
+{
+ /// Just directly copies memory
+ return *(evmjit::h256*)&_u;
+}
+
}
}
diff --git a/evmjit/libevmjit/CMakeLists.txt b/evmjit/libevmjit/CMakeLists.txt
index 7f4e763d7..4b15d52ac 100644
--- a/evmjit/libevmjit/CMakeLists.txt
+++ b/evmjit/libevmjit/CMakeLists.txt
@@ -8,6 +8,7 @@ set(SOURCES
Common.h
Compiler.cpp Compiler.h
CompilerHelper.cpp CompilerHelper.h
+ ${EVMJIT_INCLUDE_DIR}/evmjit/DataTypes.h
Endianness.cpp Endianness.h
ExecStats.cpp ExecStats.h
ExecutionEngine.cpp ExecutionEngine.h
@@ -15,6 +16,7 @@ set(SOURCES
GasMeter.cpp GasMeter.h
Instruction.cpp Instruction.h
interface.cpp interface.h
+ JIT.cpp ${EVMJIT_INCLUDE_DIR}/evmjit/JIT.h
Memory.cpp Memory.h
Optimizer.cpp Optimizer.h
Runtime.cpp Runtime.h
@@ -79,6 +81,7 @@ set_target_properties(${TARGET_NAME} PROPERTIES
VERSION ${EVMJIT_VERSION} SOVERSION ${EVMJIT_SOVERSION}
FOLDER "libs")
+include_directories(${EVMJIT_INCLUDE_DIR})
include_directories(${LLVM_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR}/gen)
diff --git a/evmjit/libevmjit/Common.h b/evmjit/libevmjit/Common.h
index 028f0b3c5..b519614fe 100644
--- a/evmjit/libevmjit/Common.h
+++ b/evmjit/libevmjit/Common.h
@@ -31,7 +31,7 @@ enum class ReturnCode
// Standard error codes
OutOfGas = -1,
- StackUnderflow = -2,
+ StackUnderflow = -2,
BadJumpDestination = -3,
BadInstruction = -4,
Rejected = -5, ///< Input data (code, gas, block info, etc.) does not meet JIT requirement and execution request has been rejected
@@ -46,16 +46,6 @@ enum class ReturnCode
LinkerWorkaround = -299,
};
-/// Representation of 256-bit value binary compatible with LLVM i256
-struct i256
-{
- uint64_t a = 0;
- uint64_t b = 0;
- uint64_t c = 0;
- uint64_t d = 0;
-};
-static_assert(sizeof(i256) == 32, "Wrong i265 size");
-
#define UNTESTED assert(false)
}
diff --git a/evmjit/libevmjit/ExecutionEngine.cpp b/evmjit/libevmjit/ExecutionEngine.cpp
index e15dad969..08ca403b5 100644
--- a/evmjit/libevmjit/ExecutionEngine.cpp
+++ b/evmjit/libevmjit/ExecutionEngine.cpp
@@ -19,6 +19,7 @@
#include
#include "preprocessor/llvm_includes_end.h"
+#include "evmjit/JIT.h"
#include "Runtime.h"
#include "Compiler.h"
#include "Optimizer.h"
@@ -33,6 +34,7 @@ namespace eth
{
namespace jit
{
+using evmjit::JIT;
namespace
{
@@ -119,8 +121,6 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env)
// TODO: Do not pseudo-init the cache every time
auto objectCache = (g_cache != CacheMode::off && g_cache != CacheMode::clear) ? Cache::getObjectCache(g_cache, listener.get()) : nullptr;
- static std::unordered_map funcCache;
-
static std::unique_ptr ee;
if (!ee)
{
@@ -147,8 +147,9 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env)
module.release(); // Successfully created llvm::ExecutionEngine takes ownership of the module
ee->setObjectCache(objectCache);
- if (preloadCache)
- Cache::preload(*ee, funcCache);
+ // FIXME: Disabled during API changes
+ //if (preloadCache)
+ // Cache::preload(*ee, funcCache);
}
static StatsCollector statsCollector;
@@ -156,11 +157,8 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env)
auto mainFuncName = codeHash(_data->codeHash);
m_runtime.init(_data, _env);
- EntryFuncPtr entryFuncPtr = nullptr;
- auto it = funcCache.find(mainFuncName);
- if (it != funcCache.end())
- entryFuncPtr = (EntryFuncPtr) it->second;
-
+ // TODO: Remove cast
+ auto entryFuncPtr = (EntryFuncPtr) JIT::getCode(_data->codeHash);
if (!entryFuncPtr)
{
auto module = objectCache ? Cache::getObject(mainFuncName) : nullptr;
@@ -183,12 +181,10 @@ ReturnCode ExecutionEngine::run(RuntimeData* _data, Env* _env)
module.release();
listener->stateChanged(ExecState::CodeGen);
entryFuncPtr = (EntryFuncPtr)ee->getFunctionAddress(mainFuncName);
+ if (!CHECK(entryFuncPtr))
+ return ReturnCode::LLVMLinkError;
+ JIT::mapCode(_data->codeHash, (void*)entryFuncPtr); // FIXME: Remove cast
}
- if (!CHECK(entryFuncPtr))
- return ReturnCode::LLVMLinkError;
-
- if (it == funcCache.end())
- funcCache[mainFuncName] = (uint64_t) entryFuncPtr;
listener->stateChanged(ExecState::Execution);
auto returnCode = entryFuncPtr(&m_runtime);
diff --git a/evmjit/libevmjit/JIT.cpp b/evmjit/libevmjit/JIT.cpp
new file mode 100644
index 000000000..9774c7396
--- /dev/null
+++ b/evmjit/libevmjit/JIT.cpp
@@ -0,0 +1,46 @@
+#include "evmjit/JIT.h"
+
+#include
+
+namespace dev
+{
+namespace evmjit
+{
+namespace
+{
+
+class JITImpl: JIT
+{
+public:
+ std::unordered_map codeMap;
+
+ static JITImpl& instance()
+ {
+ static JITImpl s_instance;
+ return s_instance;
+ }
+};
+
+} // anonymous namespace
+
+bool JIT::isCodeReady(h256 _codeHash)
+{
+ return JITImpl::instance().codeMap.count(_codeHash) != 0;
+}
+
+void* JIT::getCode(h256 _codeHash)
+{
+ auto& codeMap = JITImpl::instance().codeMap;
+ auto it = codeMap.find(_codeHash);
+ if (it != codeMap.end())
+ return it->second;
+ return nullptr;
+}
+
+void JIT::mapCode(h256 _codeHash, void* _funcAddr)
+{
+ JITImpl::instance().codeMap.insert(std::make_pair(_codeHash, _funcAddr));
+}
+
+}
+}
diff --git a/evmjit/libevmjit/RuntimeData.h b/evmjit/libevmjit/RuntimeData.h
index cc081cc58..6a5cd0d14 100644
--- a/evmjit/libevmjit/RuntimeData.h
+++ b/evmjit/libevmjit/RuntimeData.h
@@ -1,5 +1,6 @@
#pragma once
+#include "evmjit/DataTypes.h"
#include "Common.h"
namespace dev
@@ -8,7 +9,9 @@ namespace eth
{
namespace jit
{
-
+using evmjit::i256;
+using evmjit::h256;
+
struct RuntimeData
{
enum Index
@@ -49,7 +52,7 @@ struct RuntimeData
int64_t timestamp = 0;
byte const* code = nullptr;
uint64_t codeSize = 0;
- i256 codeHash;
+ h256 codeHash;
};
/// VM Environment (ExtVM) opaque type
diff --git a/libdevcore/Common.cpp b/libdevcore/Common.cpp
index 06950cbee..6723ab76d 100644
--- a/libdevcore/Common.cpp
+++ b/libdevcore/Common.cpp
@@ -28,7 +28,7 @@ using namespace dev;
namespace dev
{
-char const* Version = "0.9.18";
+char const* Version = "0.9.19";
const u256 UndefinedU256 = ~(u256)0;
diff --git a/libdevcore/Common.h b/libdevcore/Common.h
index 41f1b1d49..95817e41c 100644
--- a/libdevcore/Common.h
+++ b/libdevcore/Common.h
@@ -199,12 +199,12 @@ private:
#define DEV_TIMED_FUNCTION DEV_TIMED_SCOPE(__PRETTY_FUNCTION__)
#endif
-#define DEV_TIMED_IF(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(#S, MS), true); __eth_t.second; __eth_t.second = false)
-#define DEV_TIMED_SCOPE_IF(S) ::dev::TimerHelper __eth_t(S, MS)
+#define DEV_TIMED_ABOVE(S, MS) for (::std::pair<::dev::TimerHelper, bool> __eth_t(::dev::TimerHelper(#S, MS), true); __eth_t.second; __eth_t.second = false)
+#define DEV_TIMED_SCOPE_ABOVE(S) ::dev::TimerHelper __eth_t(S, MS)
#if WIN32
-#define DEV_TIMED_FUNCTION_IF(MS) DEV_TIMED_SCOPE_IF(__FUNCSIG__, MS)
+#define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__FUNCSIG__, MS)
#else
-#define DEV_TIMED_FUNCTION_IF(MS) DEV_TIMED_SCOPE_IF(__PRETTY_FUNCTION__, MS)
+#define DEV_TIMED_FUNCTION_ABOVE(MS) DEV_TIMED_SCOPE_ABOVE(__PRETTY_FUNCTION__, MS)
#endif
enum class WithExisting: int
diff --git a/libdevcore/Worker.cpp b/libdevcore/Worker.cpp
index 7d790ccf6..ab19b2f74 100644
--- a/libdevcore/Worker.cpp
+++ b/libdevcore/Worker.cpp
@@ -65,15 +65,15 @@ void Worker::startWorking()
m_state.exchange(ex);
// cnote << "Waiting until not Stopped...";
- DEV_TIMED_IF(Worker stopping, 100)
+ DEV_TIMED_ABOVE(Worker stopping, 100)
while (m_state == WorkerState::Stopped)
this_thread::sleep_for(chrono::milliseconds(20));
}
}));
// cnote << "Spawning" << m_name;
}
- DEV_TIMED_IF(Start worker, 100)
- while (m_state != WorkerState::Started)
+ DEV_TIMED_ABOVE(Start worker, 100)
+ while (m_state == WorkerState::Starting)
this_thread::sleep_for(chrono::microseconds(20));
}
@@ -85,7 +85,7 @@ void Worker::stopWorking()
WorkerState ex = WorkerState::Started;
m_state.compare_exchange_strong(ex, WorkerState::Stopping);
- DEV_TIMED_IF(Stop worker, 100)
+ DEV_TIMED_ABOVE(Stop worker, 100)
while (m_state != WorkerState::Stopped)
this_thread::sleep_for(chrono::microseconds(20));
}
@@ -99,7 +99,7 @@ void Worker::terminate()
{
m_state.exchange(WorkerState::Killing);
- DEV_TIMED_IF(Terminate worker, 100)
+ DEV_TIMED_ABOVE(Terminate worker, 100)
m_work->join();
m_work.reset();
diff --git a/libdevcrypto/MemoryDB.cpp b/libdevcrypto/MemoryDB.cpp
index 4b08db083..2cf56475b 100644
--- a/libdevcrypto/MemoryDB.cpp
+++ b/libdevcrypto/MemoryDB.cpp
@@ -32,6 +32,7 @@ const char* DBWarn::name() { return "TDB"; }
std::unordered_map MemoryDB::get() const
{
+ ReadGuard l(x_this);
std::unordered_map ret;
for (auto const& i: m_main)
if (!m_enforceRefs || i.second.second > 0)
@@ -39,21 +40,34 @@ std::unordered_map MemoryDB::get() const
return ret;
}
+MemoryDB& MemoryDB::operator=(MemoryDB const& _c)
+{
+ if (this == &_c)
+ return *this;
+ ReadGuard l(_c.x_this);
+ WriteGuard l2(x_this);
+ m_main = _c.m_main;
+ m_aux = _c.m_aux;
+ return *this;
+}
+
std::string MemoryDB::lookup(h256 const& _h) const
{
+ ReadGuard l(x_this);
auto it = m_main.find(_h);
if (it != m_main.end())
{
if (!m_enforceRefs || it->second.second > 0)
return it->second.first;
-// else if (m_enforceRefs && m_refCount.count(it->first) && !m_refCount.at(it->first))
-// cnote << "Lookup required for value with no refs. Let's hope it's in the DB." << _h;
+ else
+ cwarn << "Lookup required for value with refcount == 0. This is probably a critical trie issue" << _h;
}
return std::string();
}
bool MemoryDB::exists(h256 const& _h) const
{
+ ReadGuard l(x_this);
auto it = m_main.find(_h);
if (it != m_main.end() && (!m_enforceRefs || it->second.second > 0))
return true;
@@ -62,6 +76,7 @@ bool MemoryDB::exists(h256 const& _h) const
void MemoryDB::insert(h256 const& _h, bytesConstRef _v)
{
+ WriteGuard l(x_this);
auto it = m_main.find(_h);
if (it != m_main.end())
{
@@ -77,34 +92,34 @@ void MemoryDB::insert(h256 const& _h, bytesConstRef _v)
bool MemoryDB::kill(h256 const& _h)
{
+ ReadGuard l(x_this);
if (m_main.count(_h))
{
if (m_main[_h].second > 0)
+ {
m_main[_h].second--;
+ return true;
+ }
#if ETH_PARANOIA
else
{
// If we get to this point, then there was probably a node in the level DB which we need to remove and which we have previously
// used as part of the memory-based MemoryDB. Nothing to be worried about *as long as the node exists in the DB*.
dbdebug << "NOKILL-WAS" << _h;
- return false;
}
dbdebug << "KILL" << _h << "=>" << m_main[_h].second;
- return true;
}
else
{
dbdebug << "NOKILL" << _h;
- return false;
- }
-#else
- }
- return true;
#endif
+ }
+ return false;
}
void MemoryDB::purge()
{
+ WriteGuard l(x_this);
for (auto it = m_main.begin(); it != m_main.end(); )
if (it->second.second)
++it;
@@ -114,6 +129,7 @@ void MemoryDB::purge()
h256Hash MemoryDB::keys() const
{
+ ReadGuard l(x_this);
h256Hash ret;
for (auto const& i: m_main)
if (i.second.second)
diff --git a/libdevcrypto/MemoryDB.h b/libdevcrypto/MemoryDB.h
index 3169d8fbc..169682815 100644
--- a/libdevcrypto/MemoryDB.h
+++ b/libdevcrypto/MemoryDB.h
@@ -23,6 +23,7 @@
#include
#include
+#include
#include
#include
#include
@@ -43,6 +44,9 @@ class MemoryDB
public:
MemoryDB() {}
+ MemoryDB(MemoryDB const& _c) { operator=(_c); }
+
+ MemoryDB& operator=(MemoryDB const& _c);
void clear() { m_main.clear(); } // WARNING !!!! didn't originally clear m_refCount!!!
std::unordered_map get() const;
@@ -53,13 +57,14 @@ public:
bool kill(h256 const& _h);
void purge();
- bytes lookupAux(h256 const& _h) const { try { return m_aux.at(_h).first; } catch (...) { return bytes(); } }
- void removeAux(h256 const& _h) { m_aux[_h].second = false; }
- void insertAux(h256 const& _h, bytesConstRef _v) { m_aux[_h] = make_pair(_v.toBytes(), true); }
+ bytes lookupAux(h256 const& _h) const { ReadGuard l(x_this); auto it = m_aux.find(_h); if (it != m_aux.end() && (!m_enforceRefs || it->second.second)) return it->second.first; return bytes(); }
+ void removeAux(h256 const& _h) { WriteGuard l(x_this); m_aux[_h].second = false; }
+ void insertAux(h256 const& _h, bytesConstRef _v) { WriteGuard l(x_this); m_aux[_h] = make_pair(_v.toBytes(), true); }
h256Hash keys() const;
protected:
+ mutable SharedMutex x_this;
std::unordered_map> m_main;
std::unordered_map> m_aux;
diff --git a/libdevcrypto/OverlayDB.cpp b/libdevcrypto/OverlayDB.cpp
index 87c8a0927..957c7f0e3 100644
--- a/libdevcrypto/OverlayDB.cpp
+++ b/libdevcrypto/OverlayDB.cpp
@@ -19,6 +19,7 @@
* @date 2014
*/
+#include
#include
#include
#include
@@ -29,6 +30,8 @@ using namespace dev;
namespace dev
{
+h256 const EmptyTrie = sha3(rlp(""));
+
OverlayDB::~OverlayDB()
{
if (m_db.use_count() == 1 && m_db.get())
@@ -41,30 +44,41 @@ void OverlayDB::commit()
{
ldb::WriteBatch batch;
// cnote << "Committing nodes to disk DB:";
- for (auto const& i: m_main)
+ DEV_READ_GUARDED(x_this)
{
-// cnote << i.first << "#" << m_main[i.first].second;
- if (i.second.second)
- batch.Put(ldb::Slice((char const*)i.first.data(), i.first.size), ldb::Slice(i.second.first.data(), i.second.first.size()));
- }
- for (auto const& i: m_aux)
- if (i.second.second)
+ for (auto const& i: m_main)
{
- bytes b = i.first.asBytes();
- b.push_back(255); // for aux
- batch.Put(bytesConstRef(&b), bytesConstRef(&i.second.first));
+ if (i.second.second)
+ batch.Put(ldb::Slice((char const*)i.first.data(), i.first.size), ldb::Slice(i.second.first.data(), i.second.first.size()));
+// cnote << i.first << "#" << m_main[i.first].second;
}
- m_db->Write(m_writeOptions, &batch);
+ for (auto const& i: m_aux)
+ if (i.second.second)
+ {
+ bytes b = i.first.asBytes();
+ b.push_back(255); // for aux
+ batch.Put(bytesConstRef(&b), bytesConstRef(&i.second.first));
+ }
+ }
+
+ while (true)
+ {
+ ldb::Status o = m_db->Write(m_writeOptions, &batch);
+ if (o.ok())
+ break;
+ cwarn << "Error writing to database. Sleeping a while then retrying. If it keeps saying this, free up some space!";
+ this_thread::sleep_for(chrono::milliseconds(500));
+ }
m_aux.clear();
m_main.clear();
}
}
-bytes OverlayDB::lookupAux(h256 _h) const
+bytes OverlayDB::lookupAux(h256 const& _h) const
{
bytes ret = MemoryDB::lookupAux(_h);
if (!ret.empty())
- return ret;
+ return move(ret);
std::string v;
bytes b = _h.asBytes();
b.push_back(255); // for aux
@@ -76,18 +90,19 @@ bytes OverlayDB::lookupAux(h256 _h) const
void OverlayDB::rollback()
{
+ WriteGuard l(x_this);
m_main.clear();
}
-std::string OverlayDB::lookup(h256 _h) const
+std::string OverlayDB::lookup(h256 const& _h) const
{
std::string ret = MemoryDB::lookup(_h);
if (ret.empty() && m_db)
m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret);
- return ret;
+ return move(ret);
}
-bool OverlayDB::exists(h256 _h) const
+bool OverlayDB::exists(h256 const& _h) const
{
if (MemoryDB::exists(_h))
return true;
@@ -97,16 +112,20 @@ bool OverlayDB::exists(h256 _h) const
return !ret.empty();
}
-void OverlayDB::kill(h256 _h)
+void OverlayDB::kill(h256 const& _h)
{
-#if ETH_PARANOIA
+#if ETH_PARANOIA || 1
if (!MemoryDB::kill(_h))
{
std::string ret;
if (m_db)
m_db->Get(m_readOptions, ldb::Slice((char const*)_h.data(), 32), &ret);
- if (ret.empty())
+ // No point node ref decreasing for EmptyTrie since we never bother incrementing it in the first place for
+ // empty storage tries.
+ if (ret.empty() && _h != EmptyTrie)
cnote << "Decreasing DB node ref count below zero with no DB node. Probably have a corrupt Trie." << _h;
+
+ // TODO: for 1.1: ref-counted triedb.
}
#else
MemoryDB::kill(_h);
diff --git a/libdevcrypto/OverlayDB.h b/libdevcrypto/OverlayDB.h
index 7f7736ac1..2e5428bdf 100644
--- a/libdevcrypto/OverlayDB.h
+++ b/libdevcrypto/OverlayDB.h
@@ -46,11 +46,11 @@ public:
void commit();
void rollback();
- std::string lookup(h256 _h) const;
- bool exists(h256 _h) const;
- void kill(h256 _h);
+ std::string lookup(h256 const& _h) const;
+ bool exists(h256 const& _h) const;
+ void kill(h256 const& _h);
- bytes lookupAux(h256 _h) const;
+ bytes lookupAux(h256 const& _h) const;
private:
using MemoryDB::clear;
diff --git a/libdevcrypto/TrieDB.cpp b/libdevcrypto/TrieDB.cpp
index 6f84a3e29..719bd74ad 100644
--- a/libdevcrypto/TrieDB.cpp
+++ b/libdevcrypto/TrieDB.cpp
@@ -25,6 +25,6 @@ using namespace std;
using namespace dev;
h256 const dev::c_shaNull = sha3(rlp(""));
-h256 const dev::EmptyTrie = c_shaNull;
+h256 const dev::EmptyTrie = sha3(rlp(""));
const char* TrieDBChannel::name() { return "-T-"; }
diff --git a/libdevcrypto/TrieDB.h b/libdevcrypto/TrieDB.h
index ff2bcc589..29b412bab 100644
--- a/libdevcrypto/TrieDB.h
+++ b/libdevcrypto/TrieDB.h
@@ -79,7 +79,7 @@ public:
void open(DB* _db) { m_db = _db; }
void open(DB* _db, h256 const& _root, Verification _v = Verification::Normal) { m_db = _db; setRoot(_root, _v); }
- void init() { setRoot(insertNode(&RLPNull)); assert(node(m_root).size()); }
+ void init() { setRoot(forceInsertNode(&RLPNull)); assert(node(m_root).size()); }
void setRoot(h256 const& _root, Verification _v = Verification::Normal)
{
@@ -88,11 +88,13 @@ public:
{
if (m_root == c_shaNull && !m_db->exists(m_root))
init();
-
- /*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/
+ }
+ /*std::cout << "Setting root to " << _root << " (patched to " << m_root << ")" << std::endl;*/
+#if ETH_DEBUG
+ if (_v == Verification::Normal)
+#endif
if (!node(m_root).size())
BOOST_THROW_EXCEPTION(RootNotFound());
- }
}
/// True if the trie is uninitialised (i.e. that the DB doesn't contain the root node).
@@ -282,11 +284,17 @@ private:
std::string deref(RLP const& _n) const;
std::string node(h256 _h) const { return m_db->lookup(_h); }
- void insertNode(h256 _h, bytesConstRef _v) { m_db->insert(_h, _v); }
- void killNode(h256 _h) { m_db->kill(_h); }
- h256 insertNode(bytesConstRef _v) { auto h = sha3(_v); insertNode(h, _v); return h; }
- void killNode(RLP const& _d) { if (_d.data().size() >= 32) killNode(sha3(_d.data())); }
+ // These are low-level node insertion functions that just go straight through into the DB.
+ h256 forceInsertNode(bytesConstRef _v) { auto h = sha3(_v); forceInsertNode(h, _v); return h; }
+ void forceInsertNode(h256 _h, bytesConstRef _v) { m_db->insert(_h, _v); }
+ void forceKillNode(h256 _h) { m_db->kill(_h); }
+
+ // This are semantically-aware node insertion functions that only kills when the node's
+ // data is < 32 bytes. It can safely be used when pruning the trie but won't work correctly
+ // for the special case of the root (which is always looked up via a hash). In that case,
+ // use forceKillNode().
+ void killNode(RLP const& _d) { if (_d.data().size() >= 32) forceKillNode(sha3(_d.data())); }
h256 m_root;
DB* m_db = nullptr;
@@ -743,8 +751,8 @@ template void GenericTrieDB::insert(bytesConstRef _key, bytesCons
// However, we know it's the root node and thus always hashed.
// So, if it's less than 32 (and thus should have been deleted but wasn't) then we delete it here.
if (rv.size() < 32)
- killNode(m_root);
- m_root = insertNode(&b);
+ forceKillNode(m_root);
+ m_root = forceInsertNode(&b);
}
template std::string GenericTrieDB::at(bytesConstRef _key) const
@@ -890,8 +898,8 @@ template void GenericTrieDB::remove(bytesConstRef _key)
if (b.size())
{
if (rv.size() < 32)
- killNode(m_root);
- m_root = insertNode(&b);
+ forceKillNode(m_root);
+ m_root = forceInsertNode(&b);
}
}
@@ -1081,7 +1089,7 @@ template RLPStream& GenericTrieDB::streamNode(RLPStream& _s, byte
if (_b.size() < 32)
_s.appendRaw(_b);
else
- _s.append(insertNode(&_b));
+ _s.append(forceInsertNode(&_b));
return _s;
}
@@ -1122,7 +1130,7 @@ template bytes GenericTrieDB::graft(RLP const& _orig)
// remove second item from the trie after derefrencing it into s & n.
auto lh = _orig[1].toHash();
s = node(lh);
- killNode(lh);
+ forceKillNode(lh);
n = RLP(s);
}
assert(n.itemCount() == 2);
diff --git a/libethash-cl/ethash_cl_miner.cpp b/libethash-cl/ethash_cl_miner.cpp
index cc35d6215..79efbcb97 100644
--- a/libethash-cl/ethash_cl_miner.cpp
+++ b/libethash-cl/ethash_cl_miner.cpp
@@ -120,9 +120,7 @@ unsigned ethash_cl_miner::get_num_devices(unsigned _platformId)
void ethash_cl_miner::finish()
{
if (m_queue())
- {
m_queue.finish();
- }
}
bool ethash_cl_miner::init(uint8_t const* _dag, uint64_t _dagSize, unsigned workgroup_size, unsigned _platformId, unsigned _deviceId)
@@ -162,9 +160,7 @@ bool ethash_cl_miner::init(uint8_t const* _dag, uint64_t _dagSize, unsigned work
return false;
}
if (strncmp("OpenCL 1.1", device_version.c_str(), 10) == 0)
- {
m_opencl_1_1 = true;
- }
// create context
m_context = cl::Context(std::vector(&device, &device + 1));
diff --git a/libethash/CMakeLists.txt b/libethash/CMakeLists.txt
index 009cd2d92..907eccd40 100644
--- a/libethash/CMakeLists.txt
+++ b/libethash/CMakeLists.txt
@@ -10,8 +10,7 @@ if (NOT MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99")
endif()
-set(FILES util.c
- util.h
+set(FILES util.h
io.c
internal.c
ethash.h
@@ -21,7 +20,7 @@ set(FILES util.c
data_sizes.h)
if (MSVC)
- list(APPEND FILES io_win32.c)
+ list(APPEND FILES util_win32.c io_win32.c mmap_win32.c)
else()
list(APPEND FILES io_posix.c)
endif()
@@ -46,4 +45,4 @@ endif()
if (NOT ETHASHCL)
install( TARGETS ${LIBRARY} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
-endif ()
+endif ()
\ No newline at end of file
diff --git a/libethash/data_sizes.h b/libethash/data_sizes.h
index cf52ae4f8..83cc30bcb 100644
--- a/libethash/data_sizes.h
+++ b/libethash/data_sizes.h
@@ -49,416 +49,416 @@ extern "C" {
static const uint64_t dag_sizes[2048] = {
- 1073739904U, 1082130304U, 1090514816U, 1098906752U, 1107293056U,
- 1115684224U, 1124070016U, 1132461952U, 1140849536U, 1149232768U,
- 1157627776U, 1166013824U, 1174404736U, 1182786944U, 1191180416U,
- 1199568512U, 1207958912U, 1216345216U, 1224732032U, 1233124736U,
- 1241513344U, 1249902464U, 1258290304U, 1266673792U, 1275067264U,
- 1283453312U, 1291844992U, 1300234112U, 1308619904U, 1317010048U,
- 1325397376U, 1333787776U, 1342176128U, 1350561664U, 1358954368U,
- 1367339392U, 1375731584U, 1384118144U, 1392507008U, 1400897408U,
- 1409284736U, 1417673344U, 1426062464U, 1434451072U, 1442839168U,
- 1451229056U, 1459615616U, 1468006016U, 1476394112U, 1484782976U,
- 1493171584U, 1501559168U, 1509948032U, 1518337664U, 1526726528U,
- 1535114624U, 1543503488U, 1551892096U, 1560278656U, 1568669056U,
- 1577056384U, 1585446272U, 1593831296U, 1602219392U, 1610610304U,
- 1619000192U, 1627386752U, 1635773824U, 1644164224U, 1652555648U,
- 1660943488U, 1669332608U, 1677721216U, 1686109312U, 1694497664U,
- 1702886272U, 1711274624U, 1719661184U, 1728047744U, 1736434816U,
- 1744829056U, 1753218944U, 1761606272U, 1769995904U, 1778382464U,
- 1786772864U, 1795157888U, 1803550592U, 1811937664U, 1820327552U,
- 1828711552U, 1837102976U, 1845488768U, 1853879936U, 1862269312U,
- 1870656896U, 1879048064U, 1887431552U, 1895825024U, 1904212096U,
- 1912601216U, 1920988544U, 1929379456U, 1937765504U, 1946156672U,
- 1954543232U, 1962932096U, 1971321728U, 1979707264U, 1988093056U,
- 1996487552U, 2004874624U, 2013262208U, 2021653888U, 2030039936U,
- 2038430848U, 2046819968U, 2055208576U, 2063596672U, 2071981952U,
- 2080373632U, 2088762752U, 2097149056U, 2105539712U, 2113928576U,
- 2122315136U, 2130700672U, 2139092608U, 2147483264U, 2155872128U,
- 2164257664U, 2172642176U, 2181035392U, 2189426048U, 2197814912U,
- 2206203008U, 2214587264U, 2222979712U, 2231367808U, 2239758208U,
- 2248145024U, 2256527744U, 2264922752U, 2273312128U, 2281701248U,
- 2290086272U, 2298476672U, 2306867072U, 2315251072U, 2323639168U,
- 2332032128U, 2340420224U, 2348808064U, 2357196416U, 2365580416U,
- 2373966976U, 2382363008U, 2390748544U, 2399139968U, 2407530368U,
- 2415918976U, 2424307328U, 2432695424U, 2441084288U, 2449472384U,
- 2457861248U, 2466247808U, 2474637184U, 2483026816U, 2491414144U,
- 2499803776U, 2508191872U, 2516582272U, 2524970368U, 2533359232U,
- 2541743488U, 2550134144U, 2558525056U, 2566913408U, 2575301504U,
- 2583686528U, 2592073856U, 2600467328U, 2608856192U, 2617240448U,
- 2625631616U, 2634022016U, 2642407552U, 2650796416U, 2659188352U,
- 2667574912U, 2675965312U, 2684352896U, 2692738688U, 2701130624U,
- 2709518464U, 2717907328U, 2726293376U, 2734685056U, 2743073152U,
- 2751462016U, 2759851648U, 2768232832U, 2776625536U, 2785017728U,
- 2793401984U, 2801794432U, 2810182016U, 2818571648U, 2826959488U,
- 2835349376U, 2843734144U, 2852121472U, 2860514432U, 2868900992U,
- 2877286784U, 2885676928U, 2894069632U, 2902451584U, 2910843008U,
- 2919234688U, 2927622784U, 2936011648U, 2944400768U, 2952789376U,
- 2961177728U, 2969565568U, 2977951616U, 2986338944U, 2994731392U,
- 3003120256U, 3011508352U, 3019895936U, 3028287104U, 3036675968U,
- 3045063808U, 3053452928U, 3061837696U, 3070228352U, 3078615424U,
- 3087003776U, 3095394944U, 3103782272U, 3112173184U, 3120562048U,
- 3128944768U, 3137339264U, 3145725056U, 3154109312U, 3162505088U,
- 3170893184U, 3179280256U, 3187669376U, 3196056704U, 3204445568U,
- 3212836736U, 3221224064U, 3229612928U, 3238002304U, 3246391168U,
- 3254778496U, 3263165824U, 3271556224U, 3279944576U, 3288332416U,
- 3296719232U, 3305110912U, 3313500032U, 3321887104U, 3330273152U,
- 3338658944U, 3347053184U, 3355440512U, 3363827072U, 3372220288U,
- 3380608384U, 3388997504U, 3397384576U, 3405774208U, 3414163072U,
- 3422551936U, 3430937984U, 3439328384U, 3447714176U, 3456104576U,
- 3464493952U, 3472883584U, 3481268864U, 3489655168U, 3498048896U,
- 3506434432U, 3514826368U, 3523213952U, 3531603584U, 3539987072U,
- 3548380288U, 3556763264U, 3565157248U, 3573545344U, 3581934464U,
- 3590324096U, 3598712704U, 3607098752U, 3615488384U, 3623877248U,
- 3632265856U, 3640646528U, 3649043584U, 3657430144U, 3665821568U,
- 3674207872U, 3682597504U, 3690984832U, 3699367808U, 3707764352U,
- 3716152448U, 3724541056U, 3732925568U, 3741318016U, 3749706368U,
- 3758091136U, 3766481536U, 3774872704U, 3783260032U, 3791650432U,
- 3800036224U, 3808427648U, 3816815488U, 3825204608U, 3833592704U,
- 3841981568U, 3850370432U, 3858755968U, 3867147904U, 3875536256U,
- 3883920512U, 3892313728U, 3900702592U, 3909087872U, 3917478784U,
- 3925868416U, 3934256512U, 3942645376U, 3951032192U, 3959422336U,
- 3967809152U, 3976200064U, 3984588416U, 3992974976U, 4001363584U,
- 4009751168U, 4018141312U, 4026530432U, 4034911616U, 4043308928U,
- 4051695488U, 4060084352U, 4068472448U, 4076862848U, 4085249408U,
- 4093640576U, 4102028416U, 4110413696U, 4118805632U, 4127194496U,
- 4135583104U, 4143971968U, 4152360832U, 4160746112U, 4169135744U,
- 4177525888U, 4185912704U, 4194303616U, 4202691968U, 4211076736U,
- 4219463552U, 4227855488U, 4236246656U, 4244633728U, 4253022848U,
- 4261412224U, 4269799808U, 4278184832U, 4286578048U, 4294962304U,
- 4303349632U, 4311743104U, 4320130432U, 4328521088U, 4336909184U,
- 4345295488U, 4353687424U, 4362073472U, 4370458496U, 4378852736U,
- 4387238528U, 4395630208U, 4404019072U, 4412407424U, 4420790656U,
- 4429182848U, 4437571456U, 4445962112U, 4454344064U, 4462738048U,
- 4471119232U, 4479516544U, 4487904128U, 4496289664U, 4504682368U,
- 4513068416U, 4521459584U, 4529846144U, 4538232704U, 4546619776U,
- 4555010176U, 4563402112U, 4571790208U, 4580174464U, 4588567936U,
- 4596957056U, 4605344896U, 4613734016U, 4622119808U, 4630511488U,
- 4638898816U, 4647287936U, 4655675264U, 4664065664U, 4672451968U,
- 4680842624U, 4689231488U, 4697620352U, 4706007424U, 4714397056U,
- 4722786176U, 4731173248U, 4739562368U, 4747951744U, 4756340608U,
- 4764727936U, 4773114496U, 4781504384U, 4789894784U, 4798283648U,
- 4806667648U, 4815059584U, 4823449472U, 4831835776U, 4840226176U,
- 4848612224U, 4857003392U, 4865391488U, 4873780096U, 4882169728U,
- 4890557312U, 4898946944U, 4907333248U, 4915722368U, 4924110976U,
- 4932499328U, 4940889728U, 4949276032U, 4957666432U, 4966054784U,
- 4974438016U, 4982831488U, 4991221376U, 4999607168U, 5007998848U,
- 5016386432U, 5024763776U, 5033164672U, 5041544576U, 5049941888U,
- 5058329728U, 5066717056U, 5075107456U, 5083494272U, 5091883904U,
- 5100273536U, 5108662144U, 5117048192U, 5125436032U, 5133827456U,
- 5142215296U, 5150605184U, 5158993024U, 5167382144U, 5175769472U,
- 5184157568U, 5192543872U, 5200936064U, 5209324928U, 5217711232U,
- 5226102656U, 5234490496U, 5242877312U, 5251263872U, 5259654016U,
- 5268040832U, 5276434304U, 5284819328U, 5293209728U, 5301598592U,
- 5309986688U, 5318374784U, 5326764416U, 5335151488U, 5343542144U,
- 5351929472U, 5360319872U, 5368706944U, 5377096576U, 5385484928U,
- 5393871232U, 5402263424U, 5410650496U, 5419040384U, 5427426944U,
- 5435816576U, 5444205952U, 5452594816U, 5460981376U, 5469367936U,
- 5477760896U, 5486148736U, 5494536832U, 5502925952U, 5511315328U,
- 5519703424U, 5528089984U, 5536481152U, 5544869504U, 5553256064U,
- 5561645696U, 5570032768U, 5578423936U, 5586811264U, 5595193216U,
- 5603585408U, 5611972736U, 5620366208U, 5628750464U, 5637143936U,
- 5645528192U, 5653921408U, 5662310272U, 5670694784U, 5679082624U,
- 5687474048U, 5695864448U, 5704251008U, 5712641408U, 5721030272U,
- 5729416832U, 5737806208U, 5746194304U, 5754583936U, 5762969984U,
- 5771358592U, 5779748224U, 5788137856U, 5796527488U, 5804911232U,
- 5813300608U, 5821692544U, 5830082176U, 5838468992U, 5846855552U,
- 5855247488U, 5863636096U, 5872024448U, 5880411008U, 5888799872U,
- 5897186432U, 5905576832U, 5913966976U, 5922352768U, 5930744704U,
- 5939132288U, 5947522432U, 5955911296U, 5964299392U, 5972688256U,
- 5981074304U, 5989465472U, 5997851008U, 6006241408U, 6014627968U,
- 6023015552U, 6031408256U, 6039796096U, 6048185216U, 6056574848U,
- 6064963456U, 6073351808U, 6081736064U, 6090128768U, 6098517632U,
- 6106906496U, 6115289216U, 6123680896U, 6132070016U, 6140459648U,
- 6148849024U, 6157237376U, 6165624704U, 6174009728U, 6182403712U,
- 6190792064U, 6199176064U, 6207569792U, 6215952256U, 6224345216U,
- 6232732544U, 6241124224U, 6249510272U, 6257899136U, 6266287744U,
- 6274676864U, 6283065728U, 6291454336U, 6299843456U, 6308232064U,
- 6316620928U, 6325006208U, 6333395584U, 6341784704U, 6350174848U,
- 6358562176U, 6366951296U, 6375337856U, 6383729536U, 6392119168U,
- 6400504192U, 6408895616U, 6417283456U, 6425673344U, 6434059136U,
- 6442444672U, 6450837376U, 6459223424U, 6467613056U, 6476004224U,
- 6484393088U, 6492781952U, 6501170048U, 6509555072U, 6517947008U,
- 6526336384U, 6534725504U, 6543112832U, 6551500672U, 6559888768U,
- 6568278656U, 6576662912U, 6585055616U, 6593443456U, 6601834112U,
- 6610219648U, 6618610304U, 6626999168U, 6635385472U, 6643777408U,
- 6652164224U, 6660552832U, 6668941952U, 6677330048U, 6685719424U,
- 6694107776U, 6702493568U, 6710882176U, 6719274112U, 6727662976U,
- 6736052096U, 6744437632U, 6752825984U, 6761213824U, 6769604224U,
- 6777993856U, 6786383488U, 6794770816U, 6803158144U, 6811549312U,
- 6819937664U, 6828326528U, 6836706176U, 6845101696U, 6853491328U,
- 6861880448U, 6870269312U, 6878655104U, 6887046272U, 6895433344U,
- 6903822208U, 6912212864U, 6920596864U, 6928988288U, 6937377152U,
- 6945764992U, 6954149248U, 6962544256U, 6970928768U, 6979317376U,
- 6987709312U, 6996093824U, 7004487296U, 7012875392U, 7021258624U,
- 7029652352U, 7038038912U, 7046427776U, 7054818944U, 7063207808U,
- 7071595136U, 7079980928U, 7088372608U, 7096759424U, 7105149824U,
- 7113536896U, 7121928064U, 7130315392U, 7138699648U, 7147092352U,
- 7155479168U, 7163865728U, 7172249984U, 7180648064U, 7189036672U,
- 7197424768U, 7205810816U, 7214196608U, 7222589824U, 7230975104U,
- 7239367552U, 7247755904U, 7256145536U, 7264533376U, 7272921472U,
- 7281308032U, 7289694848U, 7298088832U, 7306471808U, 7314864512U,
- 7323253888U, 7331643008U, 7340029568U, 7348419712U, 7356808832U,
- 7365196672U, 7373585792U, 7381973888U, 7390362752U, 7398750592U,
- 7407138944U, 7415528576U, 7423915648U, 7432302208U, 7440690304U,
- 7449080192U, 7457472128U, 7465860992U, 7474249088U, 7482635648U,
- 7491023744U, 7499412608U, 7507803008U, 7516192384U, 7524579968U,
- 7532967296U, 7541358464U, 7549745792U, 7558134656U, 7566524032U,
- 7574912896U, 7583300992U, 7591690112U, 7600075136U, 7608466816U,
- 7616854912U, 7625244544U, 7633629824U, 7642020992U, 7650410368U,
- 7658794112U, 7667187328U, 7675574912U, 7683961984U, 7692349568U,
- 7700739712U, 7709130368U, 7717519232U, 7725905536U, 7734295424U,
- 7742683264U, 7751069056U, 7759457408U, 7767849088U, 7776238208U,
- 7784626816U, 7793014912U, 7801405312U, 7809792128U, 7818179968U,
- 7826571136U, 7834957184U, 7843347328U, 7851732352U, 7860124544U,
- 7868512384U, 7876902016U, 7885287808U, 7893679744U, 7902067072U,
- 7910455936U, 7918844288U, 7927230848U, 7935622784U, 7944009344U,
- 7952400256U, 7960786048U, 7969176704U, 7977565312U, 7985953408U,
- 7994339968U, 8002730368U, 8011119488U, 8019508096U, 8027896192U,
- 8036285056U, 8044674688U, 8053062272U, 8061448832U, 8069838464U,
- 8078227328U, 8086616704U, 8095006592U, 8103393664U, 8111783552U,
- 8120171392U, 8128560256U, 8136949376U, 8145336704U, 8153726848U,
- 8162114944U, 8170503296U, 8178891904U, 8187280768U, 8195669632U,
- 8204058496U, 8212444544U, 8220834176U, 8229222272U, 8237612672U,
- 8246000768U, 8254389376U, 8262775168U, 8271167104U, 8279553664U,
- 8287944064U, 8296333184U, 8304715136U, 8313108352U, 8321497984U,
- 8329885568U, 8338274432U, 8346663296U, 8355052928U, 8363441536U,
- 8371828352U, 8380217984U, 8388606592U, 8396996224U, 8405384576U,
- 8413772672U, 8422161536U, 8430549376U, 8438939008U, 8447326592U,
- 8455715456U, 8464104832U, 8472492928U, 8480882048U, 8489270656U,
- 8497659776U, 8506045312U, 8514434944U, 8522823808U, 8531208832U,
- 8539602304U, 8547990656U, 8556378752U, 8564768384U, 8573154176U,
- 8581542784U, 8589933952U, 8598322816U, 8606705024U, 8615099264U,
- 8623487872U, 8631876992U, 8640264064U, 8648653952U, 8657040256U,
- 8665430656U, 8673820544U, 8682209152U, 8690592128U, 8698977152U,
- 8707374464U, 8715763328U, 8724151424U, 8732540032U, 8740928384U,
- 8749315712U, 8757704576U, 8766089344U, 8774480768U, 8782871936U,
- 8791260032U, 8799645824U, 8808034432U, 8816426368U, 8824812928U,
- 8833199488U, 8841591424U, 8849976448U, 8858366336U, 8866757248U,
- 8875147136U, 8883532928U, 8891923328U, 8900306816U, 8908700288U,
- 8917088384U, 8925478784U, 8933867392U, 8942250368U, 8950644608U,
- 8959032704U, 8967420544U, 8975809664U, 8984197504U, 8992584064U,
- 9000976256U, 9009362048U, 9017752448U, 9026141312U, 9034530688U,
- 9042917504U, 9051307904U, 9059694208U, 9068084864U, 9076471424U,
- 9084861824U, 9093250688U, 9101638528U, 9110027648U, 9118416512U,
- 9126803584U, 9135188096U, 9143581312U, 9151969664U, 9160356224U,
- 9168747136U, 9177134464U, 9185525632U, 9193910144U, 9202302848U,
- 9210690688U, 9219079552U, 9227465344U, 9235854464U, 9244244864U,
- 9252633472U, 9261021824U, 9269411456U, 9277799296U, 9286188928U,
- 9294574208U, 9302965888U, 9311351936U, 9319740032U, 9328131968U,
- 9336516736U, 9344907392U, 9353296768U, 9361685888U, 9370074752U,
- 9378463616U, 9386849408U, 9395239808U, 9403629184U, 9412016512U,
- 9420405376U, 9428795008U, 9437181568U, 9445570688U, 9453960832U,
- 9462346624U, 9470738048U, 9479121536U, 9487515008U, 9495903616U,
- 9504289664U, 9512678528U, 9521067904U, 9529456256U, 9537843584U,
- 9546233728U, 9554621312U, 9563011456U, 9571398784U, 9579788672U,
- 9588178304U, 9596567168U, 9604954496U, 9613343104U, 9621732992U,
- 9630121856U, 9638508416U, 9646898816U, 9655283584U, 9663675776U,
- 9672061312U, 9680449664U, 9688840064U, 9697230464U, 9705617536U,
- 9714003584U, 9722393984U, 9730772608U, 9739172224U, 9747561088U,
- 9755945344U, 9764338816U, 9772726144U, 9781116544U, 9789503872U,
- 9797892992U, 9806282624U, 9814670464U, 9823056512U, 9831439232U,
- 9839833984U, 9848224384U, 9856613504U, 9865000576U, 9873391232U,
- 9881772416U, 9890162816U, 9898556288U, 9906940544U, 9915333248U,
- 9923721088U, 9932108672U, 9940496512U, 9948888448U, 9957276544U,
- 9965666176U, 9974048384U, 9982441088U, 9990830464U, 9999219584U,
- 10007602816U, 10015996544U, 10024385152U, 10032774016U, 10041163648U,
- 10049548928U, 10057940096U, 10066329472U, 10074717824U, 10083105152U,
- 10091495296U, 10099878784U, 10108272256U, 10116660608U, 10125049216U,
- 10133437312U, 10141825664U, 10150213504U, 10158601088U, 10166991232U,
- 10175378816U, 10183766144U, 10192157312U, 10200545408U, 10208935552U,
- 10217322112U, 10225712768U, 10234099328U, 10242489472U, 10250876032U,
- 10259264896U, 10267656064U, 10276042624U, 10284429184U, 10292820352U,
- 10301209472U, 10309598848U, 10317987712U, 10326375296U, 10334763392U,
- 10343153536U, 10351541632U, 10359930752U, 10368318592U, 10376707456U,
- 10385096576U, 10393484672U, 10401867136U, 10410262144U, 10418647424U,
- 10427039104U, 10435425664U, 10443810176U, 10452203648U, 10460589952U,
- 10468982144U, 10477369472U, 10485759104U, 10494147712U, 10502533504U,
- 10510923392U, 10519313536U, 10527702656U, 10536091264U, 10544478592U,
- 10552867712U, 10561255808U, 10569642368U, 10578032768U, 10586423168U,
- 10594805632U, 10603200128U, 10611588992U, 10619976064U, 10628361344U,
- 10636754048U, 10645143424U, 10653531776U, 10661920384U, 10670307968U,
- 10678696832U, 10687086464U, 10695475072U, 10703863168U, 10712246144U,
- 10720639616U, 10729026688U, 10737414784U, 10745806208U, 10754190976U,
- 10762581376U, 10770971264U, 10779356288U, 10787747456U, 10796135552U,
- 10804525184U, 10812915584U, 10821301888U, 10829692288U, 10838078336U,
- 10846469248U, 10854858368U, 10863247232U, 10871631488U, 10880023424U,
- 10888412032U, 10896799616U, 10905188992U, 10913574016U, 10921964672U,
- 10930352768U, 10938742912U, 10947132544U, 10955518592U, 10963909504U,
- 10972298368U, 10980687488U, 10989074816U, 10997462912U, 11005851776U,
- 11014241152U, 11022627712U, 11031017344U, 11039403904U, 11047793024U,
- 11056184704U, 11064570752U, 11072960896U, 11081343872U, 11089737856U,
- 11098128256U, 11106514816U, 11114904448U, 11123293568U, 11131680128U,
- 11140065152U, 11148458368U, 11156845696U, 11165236864U, 11173624192U,
- 11182013824U, 11190402688U, 11198790784U, 11207179136U, 11215568768U,
- 11223957376U, 11232345728U, 11240734592U, 11249122688U, 11257511296U,
- 11265899648U, 11274285952U, 11282675584U, 11291065472U, 11299452544U,
- 11307842432U, 11316231296U, 11324616832U, 11333009024U, 11341395584U,
- 11349782656U, 11358172288U, 11366560384U, 11374950016U, 11383339648U,
- 11391721856U, 11400117376U, 11408504192U, 11416893568U, 11425283456U,
- 11433671552U, 11442061184U, 11450444672U, 11458837888U, 11467226752U,
- 11475611776U, 11484003968U, 11492392064U, 11500780672U, 11509169024U,
- 11517550976U, 11525944448U, 11534335616U, 11542724224U, 11551111808U,
- 11559500672U, 11567890304U, 11576277376U, 11584667008U, 11593056128U,
- 11601443456U, 11609830016U, 11618221952U, 11626607488U, 11634995072U,
- 11643387776U, 11651775104U, 11660161664U, 11668552576U, 11676940928U,
- 11685330304U, 11693718656U, 11702106496U, 11710496128U, 11718882688U,
- 11727273088U, 11735660416U, 11744050048U, 11752437376U, 11760824704U,
- 11769216128U, 11777604736U, 11785991296U, 11794381952U, 11802770048U,
- 11811157888U, 11819548544U, 11827932544U, 11836324736U, 11844713344U,
- 11853100928U, 11861486464U, 11869879936U, 11878268032U, 11886656896U,
- 11895044992U, 11903433088U, 11911822976U, 11920210816U, 11928600448U,
- 11936987264U, 11945375872U, 11953761152U, 11962151296U, 11970543488U,
- 11978928512U, 11987320448U, 11995708288U, 12004095104U, 12012486272U,
- 12020875136U, 12029255552U, 12037652096U, 12046039168U, 12054429568U,
- 12062813824U, 12071206528U, 12079594624U, 12087983744U, 12096371072U,
- 12104759936U, 12113147264U, 12121534592U, 12129924992U, 12138314624U,
- 12146703232U, 12155091584U, 12163481216U, 12171864704U, 12180255872U,
- 12188643968U, 12197034112U, 12205424512U, 12213811328U, 12222199424U,
- 12230590336U, 12238977664U, 12247365248U, 12255755392U, 12264143488U,
- 12272531584U, 12280920448U, 12289309568U, 12297694592U, 12306086528U,
- 12314475392U, 12322865024U, 12331253632U, 12339640448U, 12348029312U,
- 12356418944U, 12364805248U, 12373196672U, 12381580928U, 12389969024U,
- 12398357632U, 12406750592U, 12415138432U, 12423527552U, 12431916416U,
- 12440304512U, 12448692352U, 12457081216U, 12465467776U, 12473859968U,
- 12482245504U, 12490636672U, 12499025536U, 12507411584U, 12515801728U,
- 12524190592U, 12532577152U, 12540966272U, 12549354368U, 12557743232U,
- 12566129536U, 12574523264U, 12582911872U, 12591299456U, 12599688064U,
- 12608074624U, 12616463488U, 12624845696U, 12633239936U, 12641631616U,
- 12650019968U, 12658407296U, 12666795136U, 12675183232U, 12683574656U,
- 12691960192U, 12700350592U, 12708740224U, 12717128576U, 12725515904U,
- 12733906816U, 12742295168U, 12750680192U, 12759071872U, 12767460736U,
- 12775848832U, 12784236928U, 12792626816U, 12801014656U, 12809404288U,
- 12817789312U, 12826181504U, 12834568832U, 12842954624U, 12851345792U,
- 12859732352U, 12868122496U, 12876512128U, 12884901248U, 12893289088U,
- 12901672832U, 12910067584U, 12918455168U, 12926842496U, 12935232896U,
- 12943620736U, 12952009856U, 12960396928U, 12968786816U, 12977176192U,
- 12985563776U, 12993951104U, 13002341504U, 13010730368U, 13019115392U,
- 13027506304U, 13035895168U, 13044272512U, 13052673152U, 13061062528U,
- 13069446272U, 13077838976U, 13086227072U, 13094613632U, 13103000192U,
- 13111393664U, 13119782528U, 13128157568U, 13136559232U, 13144945024U,
- 13153329536U, 13161724288U, 13170111872U, 13178502784U, 13186884736U,
- 13195279744U, 13203667072U, 13212057472U, 13220445824U, 13228832128U,
- 13237221248U, 13245610624U, 13254000512U, 13262388352U, 13270777472U,
- 13279166336U, 13287553408U, 13295943296U, 13304331904U, 13312719488U,
- 13321108096U, 13329494656U, 13337885824U, 13346274944U, 13354663808U,
- 13363051136U, 13371439232U, 13379825024U, 13388210816U, 13396605056U,
- 13404995456U, 13413380224U, 13421771392U, 13430159744U, 13438546048U,
- 13446937216U, 13455326848U, 13463708288U, 13472103808U, 13480492672U,
- 13488875648U, 13497269888U, 13505657728U, 13514045312U, 13522435712U,
- 13530824576U, 13539210112U, 13547599232U, 13555989376U, 13564379008U,
- 13572766336U, 13581154432U, 13589544832U, 13597932928U, 13606320512U,
- 13614710656U, 13623097472U, 13631477632U, 13639874944U, 13648264064U,
- 13656652928U, 13665041792U, 13673430656U, 13681818496U, 13690207616U,
- 13698595712U, 13706982272U, 13715373184U, 13723762048U, 13732150144U,
- 13740536704U, 13748926592U, 13757316224U, 13765700992U, 13774090112U,
- 13782477952U, 13790869376U, 13799259008U, 13807647872U, 13816036736U,
- 13824425344U, 13832814208U, 13841202304U, 13849591424U, 13857978752U,
- 13866368896U, 13874754688U, 13883145344U, 13891533184U, 13899919232U,
- 13908311168U, 13916692096U, 13925085056U, 13933473152U, 13941866368U,
- 13950253696U, 13958643584U, 13967032192U, 13975417216U, 13983807616U,
- 13992197504U, 14000582272U, 14008973696U, 14017363072U, 14025752192U,
- 14034137984U, 14042528384U, 14050918016U, 14059301504U, 14067691648U,
- 14076083584U, 14084470144U, 14092852352U, 14101249664U, 14109635968U,
- 14118024832U, 14126407552U, 14134804352U, 14143188608U, 14151577984U,
- 14159968384U, 14168357248U, 14176741504U, 14185127296U, 14193521024U,
- 14201911424U, 14210301824U, 14218685056U, 14227067264U, 14235467392U,
- 14243855488U, 14252243072U, 14260630144U, 14269021568U, 14277409408U,
- 14285799296U, 14294187904U, 14302571392U, 14310961792U, 14319353728U,
- 14327738752U, 14336130944U, 14344518784U, 14352906368U, 14361296512U,
- 14369685376U, 14378071424U, 14386462592U, 14394848128U, 14403230848U,
- 14411627392U, 14420013952U, 14428402304U, 14436793472U, 14445181568U,
- 14453569664U, 14461959808U, 14470347904U, 14478737024U, 14487122816U,
- 14495511424U, 14503901824U, 14512291712U, 14520677504U, 14529064832U,
- 14537456768U, 14545845632U, 14554234496U, 14562618496U, 14571011456U,
- 14579398784U, 14587789184U, 14596172672U, 14604564608U, 14612953984U,
- 14621341312U, 14629724288U, 14638120832U, 14646503296U, 14654897536U,
- 14663284864U, 14671675264U, 14680061056U, 14688447616U, 14696835968U,
- 14705228416U, 14713616768U, 14722003328U, 14730392192U, 14738784128U,
- 14747172736U, 14755561088U, 14763947648U, 14772336512U, 14780725376U,
- 14789110144U, 14797499776U, 14805892736U, 14814276992U, 14822670208U,
- 14831056256U, 14839444352U, 14847836032U, 14856222848U, 14864612992U,
- 14872997504U, 14881388672U, 14889775744U, 14898165376U, 14906553472U,
- 14914944896U, 14923329664U, 14931721856U, 14940109696U, 14948497024U,
- 14956887424U, 14965276544U, 14973663616U, 14982053248U, 14990439808U,
- 14998830976U, 15007216768U, 15015605888U, 15023995264U, 15032385152U,
- 15040768384U, 15049154944U, 15057549184U, 15065939072U, 15074328448U,
- 15082715008U, 15091104128U, 15099493504U, 15107879296U, 15116269184U,
- 15124659584U, 15133042304U, 15141431936U, 15149824384U, 15158214272U,
- 15166602368U, 15174991232U, 15183378304U, 15191760512U, 15200154496U,
- 15208542592U, 15216931712U, 15225323392U, 15233708416U, 15242098048U,
- 15250489216U, 15258875264U, 15267265408U, 15275654528U, 15284043136U,
- 15292431488U, 15300819584U, 15309208192U, 15317596544U, 15325986176U,
- 15334374784U, 15342763648U, 15351151744U, 15359540608U, 15367929728U,
- 15376318336U, 15384706432U, 15393092992U, 15401481856U, 15409869952U,
- 15418258816U, 15426649984U, 15435037568U, 15443425664U, 15451815296U,
- 15460203392U, 15468589184U, 15476979328U, 15485369216U, 15493755776U,
- 15502146944U, 15510534272U, 15518924416U, 15527311232U, 15535699072U,
- 15544089472U, 15552478336U, 15560866688U, 15569254528U, 15577642624U,
- 15586031488U, 15594419072U, 15602809472U, 15611199104U, 15619586432U,
- 15627975296U, 15636364928U, 15644753792U, 15653141888U, 15661529216U,
- 15669918848U, 15678305152U, 15686696576U, 15695083136U, 15703474048U,
- 15711861632U, 15720251264U, 15728636288U, 15737027456U, 15745417088U,
- 15753804928U, 15762194048U, 15770582656U, 15778971008U, 15787358336U,
- 15795747712U, 15804132224U, 15812523392U, 15820909696U, 15829300096U,
- 15837691264U, 15846071936U, 15854466944U, 15862855808U, 15871244672U,
- 15879634816U, 15888020608U, 15896409728U, 15904799104U, 15913185152U,
- 15921577088U, 15929966464U, 15938354816U, 15946743424U, 15955129472U,
- 15963519872U, 15971907968U, 15980296064U, 15988684928U, 15997073024U,
- 16005460864U, 16013851264U, 16022241152U, 16030629248U, 16039012736U,
- 16047406976U, 16055794816U, 16064181376U, 16072571264U, 16080957824U,
- 16089346688U, 16097737856U, 16106125184U, 16114514816U, 16122904192U,
- 16131292544U, 16139678848U, 16148066944U, 16156453504U, 16164839552U,
- 16173236096U, 16181623424U, 16190012032U, 16198401152U, 16206790528U,
- 16215177344U, 16223567744U, 16231956352U, 16240344704U, 16248731008U,
- 16257117824U, 16265504384U, 16273898624U, 16282281856U, 16290668672U,
- 16299064192U, 16307449216U, 16315842176U, 16324230016U, 16332613504U,
- 16341006464U, 16349394304U, 16357783168U, 16366172288U, 16374561664U,
- 16382951296U, 16391337856U, 16399726208U, 16408116352U, 16416505472U,
- 16424892032U, 16433282176U, 16441668224U, 16450058624U, 16458448768U,
- 16466836864U, 16475224448U, 16483613056U, 16492001408U, 16500391808U,
- 16508779648U, 16517166976U, 16525555328U, 16533944192U, 16542330752U,
- 16550719616U, 16559110528U, 16567497088U, 16575888512U, 16584274816U,
- 16592665472U, 16601051008U, 16609442944U, 16617832064U, 16626218624U,
- 16634607488U, 16642996096U, 16651385728U, 16659773824U, 16668163712U,
- 16676552576U, 16684938112U, 16693328768U, 16701718144U, 16710095488U,
- 16718492288U, 16726883968U, 16735272832U, 16743661184U, 16752049792U,
- 16760436608U, 16768827008U, 16777214336U, 16785599104U, 16793992832U,
- 16802381696U, 16810768768U, 16819151744U, 16827542656U, 16835934848U,
- 16844323712U, 16852711552U, 16861101952U, 16869489536U, 16877876864U,
- 16886265728U, 16894653056U, 16903044736U, 16911431296U, 16919821696U,
- 16928207488U, 16936592768U, 16944987776U, 16953375616U, 16961763968U,
- 16970152832U, 16978540928U, 16986929536U, 16995319168U, 17003704448U,
- 17012096896U, 17020481152U, 17028870784U, 17037262208U, 17045649536U,
- 17054039936U, 17062426496U, 17070814336U, 17079205504U, 17087592064U,
- 17095978112U, 17104369024U, 17112759424U, 17121147776U, 17129536384U,
- 17137926016U, 17146314368U, 17154700928U, 17163089792U, 17171480192U,
- 17179864192U, 17188256896U, 17196644992U, 17205033856U, 17213423488U,
- 17221811072U, 17230198912U, 17238588032U, 17246976896U, 17255360384U,
- 17263754624U, 17272143232U, 17280530048U, 17288918912U, 17297309312U,
- 17305696384U, 17314085504U, 17322475136U, 17330863744U, 17339252096U,
- 17347640192U, 17356026496U, 17364413824U, 17372796544U, 17381190016U,
- 17389583488U, 17397972608U, 17406360704U, 17414748544U, 17423135872U,
- 17431527296U, 17439915904U, 17448303232U, 17456691584U, 17465081728U,
- 17473468288U, 17481857408U, 17490247552U, 17498635904U, 17507022464U,
- 17515409024U, 17523801728U, 17532189824U, 17540577664U, 17548966016U,
- 17557353344U, 17565741184U, 17574131584U, 17582519168U, 17590907008U,
- 17599296128U, 17607687808U, 17616076672U, 17624455808U, 17632852352U,
- 17641238656U, 17649630848U, 17658018944U, 17666403968U, 17674794112U,
- 17683178368U, 17691573376U, 17699962496U, 17708350592U, 17716739968U,
- 17725126528U, 17733517184U, 17741898112U, 17750293888U, 17758673024U,
- 17767070336U, 17775458432U, 17783848832U, 17792236928U, 17800625536U,
- 17809012352U, 17817402752U, 17825785984U, 17834178944U, 17842563968U,
- 17850955648U, 17859344512U, 17867732864U, 17876119424U, 17884511872U,
- 17892900224U, 17901287296U, 17909677696U, 17918058112U, 17926451072U,
- 17934843776U, 17943230848U, 17951609216U, 17960008576U, 17968397696U,
- 17976784256U, 17985175424U, 17993564032U, 18001952128U, 18010339712U,
- 18018728576U, 18027116672U, 18035503232U, 18043894144U, 18052283264U,
- 18060672128U, 18069056384U, 18077449856U, 18085837184U, 18094225792U,
- 18102613376U, 18111004544U, 18119388544U, 18127781248U, 18136170368U,
- 18144558976U, 18152947328U, 18161336192U, 18169724288U, 18178108544U,
- 18186498944U, 18194886784U, 18203275648U, 18211666048U, 18220048768U,
- 18228444544U, 18236833408U, 18245220736U
+ 1073739904U, 1082130304U, 1090514816U, 1098906752U, 1107293056U,
+ 1115684224U, 1124070016U, 1132461952U, 1140849536U, 1149232768U,
+ 1157627776U, 1166013824U, 1174404736U, 1182786944U, 1191180416U,
+ 1199568512U, 1207958912U, 1216345216U, 1224732032U, 1233124736U,
+ 1241513344U, 1249902464U, 1258290304U, 1266673792U, 1275067264U,
+ 1283453312U, 1291844992U, 1300234112U, 1308619904U, 1317010048U,
+ 1325397376U, 1333787776U, 1342176128U, 1350561664U, 1358954368U,
+ 1367339392U, 1375731584U, 1384118144U, 1392507008U, 1400897408U,
+ 1409284736U, 1417673344U, 1426062464U, 1434451072U, 1442839168U,
+ 1451229056U, 1459615616U, 1468006016U, 1476394112U, 1484782976U,
+ 1493171584U, 1501559168U, 1509948032U, 1518337664U, 1526726528U,
+ 1535114624U, 1543503488U, 1551892096U, 1560278656U, 1568669056U,
+ 1577056384U, 1585446272U, 1593831296U, 1602219392U, 1610610304U,
+ 1619000192U, 1627386752U, 1635773824U, 1644164224U, 1652555648U,
+ 1660943488U, 1669332608U, 1677721216U, 1686109312U, 1694497664U,
+ 1702886272U, 1711274624U, 1719661184U, 1728047744U, 1736434816U,
+ 1744829056U, 1753218944U, 1761606272U, 1769995904U, 1778382464U,
+ 1786772864U, 1795157888U, 1803550592U, 1811937664U, 1820327552U,
+ 1828711552U, 1837102976U, 1845488768U, 1853879936U, 1862269312U,
+ 1870656896U, 1879048064U, 1887431552U, 1895825024U, 1904212096U,
+ 1912601216U, 1920988544U, 1929379456U, 1937765504U, 1946156672U,
+ 1954543232U, 1962932096U, 1971321728U, 1979707264U, 1988093056U,
+ 1996487552U, 2004874624U, 2013262208U, 2021653888U, 2030039936U,
+ 2038430848U, 2046819968U, 2055208576U, 2063596672U, 2071981952U,
+ 2080373632U, 2088762752U, 2097149056U, 2105539712U, 2113928576U,
+ 2122315136U, 2130700672U, 2139092608U, 2147483264U, 2155872128U,
+ 2164257664U, 2172642176U, 2181035392U, 2189426048U, 2197814912U,
+ 2206203008U, 2214587264U, 2222979712U, 2231367808U, 2239758208U,
+ 2248145024U, 2256527744U, 2264922752U, 2273312128U, 2281701248U,
+ 2290086272U, 2298476672U, 2306867072U, 2315251072U, 2323639168U,
+ 2332032128U, 2340420224U, 2348808064U, 2357196416U, 2365580416U,
+ 2373966976U, 2382363008U, 2390748544U, 2399139968U, 2407530368U,
+ 2415918976U, 2424307328U, 2432695424U, 2441084288U, 2449472384U,
+ 2457861248U, 2466247808U, 2474637184U, 2483026816U, 2491414144U,
+ 2499803776U, 2508191872U, 2516582272U, 2524970368U, 2533359232U,
+ 2541743488U, 2550134144U, 2558525056U, 2566913408U, 2575301504U,
+ 2583686528U, 2592073856U, 2600467328U, 2608856192U, 2617240448U,
+ 2625631616U, 2634022016U, 2642407552U, 2650796416U, 2659188352U,
+ 2667574912U, 2675965312U, 2684352896U, 2692738688U, 2701130624U,
+ 2709518464U, 2717907328U, 2726293376U, 2734685056U, 2743073152U,
+ 2751462016U, 2759851648U, 2768232832U, 2776625536U, 2785017728U,
+ 2793401984U, 2801794432U, 2810182016U, 2818571648U, 2826959488U,
+ 2835349376U, 2843734144U, 2852121472U, 2860514432U, 2868900992U,
+ 2877286784U, 2885676928U, 2894069632U, 2902451584U, 2910843008U,
+ 2919234688U, 2927622784U, 2936011648U, 2944400768U, 2952789376U,
+ 2961177728U, 2969565568U, 2977951616U, 2986338944U, 2994731392U,
+ 3003120256U, 3011508352U, 3019895936U, 3028287104U, 3036675968U,
+ 3045063808U, 3053452928U, 3061837696U, 3070228352U, 3078615424U,
+ 3087003776U, 3095394944U, 3103782272U, 3112173184U, 3120562048U,
+ 3128944768U, 3137339264U, 3145725056U, 3154109312U, 3162505088U,
+ 3170893184U, 3179280256U, 3187669376U, 3196056704U, 3204445568U,
+ 3212836736U, 3221224064U, 3229612928U, 3238002304U, 3246391168U,
+ 3254778496U, 3263165824U, 3271556224U, 3279944576U, 3288332416U,
+ 3296719232U, 3305110912U, 3313500032U, 3321887104U, 3330273152U,
+ 3338658944U, 3347053184U, 3355440512U, 3363827072U, 3372220288U,
+ 3380608384U, 3388997504U, 3397384576U, 3405774208U, 3414163072U,
+ 3422551936U, 3430937984U, 3439328384U, 3447714176U, 3456104576U,
+ 3464493952U, 3472883584U, 3481268864U, 3489655168U, 3498048896U,
+ 3506434432U, 3514826368U, 3523213952U, 3531603584U, 3539987072U,
+ 3548380288U, 3556763264U, 3565157248U, 3573545344U, 3581934464U,
+ 3590324096U, 3598712704U, 3607098752U, 3615488384U, 3623877248U,
+ 3632265856U, 3640646528U, 3649043584U, 3657430144U, 3665821568U,
+ 3674207872U, 3682597504U, 3690984832U, 3699367808U, 3707764352U,
+ 3716152448U, 3724541056U, 3732925568U, 3741318016U, 3749706368U,
+ 3758091136U, 3766481536U, 3774872704U, 3783260032U, 3791650432U,
+ 3800036224U, 3808427648U, 3816815488U, 3825204608U, 3833592704U,
+ 3841981568U, 3850370432U, 3858755968U, 3867147904U, 3875536256U,
+ 3883920512U, 3892313728U, 3900702592U, 3909087872U, 3917478784U,
+ 3925868416U, 3934256512U, 3942645376U, 3951032192U, 3959422336U,
+ 3967809152U, 3976200064U, 3984588416U, 3992974976U, 4001363584U,
+ 4009751168U, 4018141312U, 4026530432U, 4034911616U, 4043308928U,
+ 4051695488U, 4060084352U, 4068472448U, 4076862848U, 4085249408U,
+ 4093640576U, 4102028416U, 4110413696U, 4118805632U, 4127194496U,
+ 4135583104U, 4143971968U, 4152360832U, 4160746112U, 4169135744U,
+ 4177525888U, 4185912704U, 4194303616U, 4202691968U, 4211076736U,
+ 4219463552U, 4227855488U, 4236246656U, 4244633728U, 4253022848U,
+ 4261412224U, 4269799808U, 4278184832U, 4286578048U, 4294962304U,
+ 4303349632U, 4311743104U, 4320130432U, 4328521088U, 4336909184U,
+ 4345295488U, 4353687424U, 4362073472U, 4370458496U, 4378852736U,
+ 4387238528U, 4395630208U, 4404019072U, 4412407424U, 4420790656U,
+ 4429182848U, 4437571456U, 4445962112U, 4454344064U, 4462738048U,
+ 4471119232U, 4479516544U, 4487904128U, 4496289664U, 4504682368U,
+ 4513068416U, 4521459584U, 4529846144U, 4538232704U, 4546619776U,
+ 4555010176U, 4563402112U, 4571790208U, 4580174464U, 4588567936U,
+ 4596957056U, 4605344896U, 4613734016U, 4622119808U, 4630511488U,
+ 4638898816U, 4647287936U, 4655675264U, 4664065664U, 4672451968U,
+ 4680842624U, 4689231488U, 4697620352U, 4706007424U, 4714397056U,
+ 4722786176U, 4731173248U, 4739562368U, 4747951744U, 4756340608U,
+ 4764727936U, 4773114496U, 4781504384U, 4789894784U, 4798283648U,
+ 4806667648U, 4815059584U, 4823449472U, 4831835776U, 4840226176U,
+ 4848612224U, 4857003392U, 4865391488U, 4873780096U, 4882169728U,
+ 4890557312U, 4898946944U, 4907333248U, 4915722368U, 4924110976U,
+ 4932499328U, 4940889728U, 4949276032U, 4957666432U, 4966054784U,
+ 4974438016U, 4982831488U, 4991221376U, 4999607168U, 5007998848U,
+ 5016386432U, 5024763776U, 5033164672U, 5041544576U, 5049941888U,
+ 5058329728U, 5066717056U, 5075107456U, 5083494272U, 5091883904U,
+ 5100273536U, 5108662144U, 5117048192U, 5125436032U, 5133827456U,
+ 5142215296U, 5150605184U, 5158993024U, 5167382144U, 5175769472U,
+ 5184157568U, 5192543872U, 5200936064U, 5209324928U, 5217711232U,
+ 5226102656U, 5234490496U, 5242877312U, 5251263872U, 5259654016U,
+ 5268040832U, 5276434304U, 5284819328U, 5293209728U, 5301598592U,
+ 5309986688U, 5318374784U, 5326764416U, 5335151488U, 5343542144U,
+ 5351929472U, 5360319872U, 5368706944U, 5377096576U, 5385484928U,
+ 5393871232U, 5402263424U, 5410650496U, 5419040384U, 5427426944U,
+ 5435816576U, 5444205952U, 5452594816U, 5460981376U, 5469367936U,
+ 5477760896U, 5486148736U, 5494536832U, 5502925952U, 5511315328U,
+ 5519703424U, 5528089984U, 5536481152U, 5544869504U, 5553256064U,
+ 5561645696U, 5570032768U, 5578423936U, 5586811264U, 5595193216U,
+ 5603585408U, 5611972736U, 5620366208U, 5628750464U, 5637143936U,
+ 5645528192U, 5653921408U, 5662310272U, 5670694784U, 5679082624U,
+ 5687474048U, 5695864448U, 5704251008U, 5712641408U, 5721030272U,
+ 5729416832U, 5737806208U, 5746194304U, 5754583936U, 5762969984U,
+ 5771358592U, 5779748224U, 5788137856U, 5796527488U, 5804911232U,
+ 5813300608U, 5821692544U, 5830082176U, 5838468992U, 5846855552U,
+ 5855247488U, 5863636096U, 5872024448U, 5880411008U, 5888799872U,
+ 5897186432U, 5905576832U, 5913966976U, 5922352768U, 5930744704U,
+ 5939132288U, 5947522432U, 5955911296U, 5964299392U, 5972688256U,
+ 5981074304U, 5989465472U, 5997851008U, 6006241408U, 6014627968U,
+ 6023015552U, 6031408256U, 6039796096U, 6048185216U, 6056574848U,
+ 6064963456U, 6073351808U, 6081736064U, 6090128768U, 6098517632U,
+ 6106906496U, 6115289216U, 6123680896U, 6132070016U, 6140459648U,
+ 6148849024U, 6157237376U, 6165624704U, 6174009728U, 6182403712U,
+ 6190792064U, 6199176064U, 6207569792U, 6215952256U, 6224345216U,
+ 6232732544U, 6241124224U, 6249510272U, 6257899136U, 6266287744U,
+ 6274676864U, 6283065728U, 6291454336U, 6299843456U, 6308232064U,
+ 6316620928U, 6325006208U, 6333395584U, 6341784704U, 6350174848U,
+ 6358562176U, 6366951296U, 6375337856U, 6383729536U, 6392119168U,
+ 6400504192U, 6408895616U, 6417283456U, 6425673344U, 6434059136U,
+ 6442444672U, 6450837376U, 6459223424U, 6467613056U, 6476004224U,
+ 6484393088U, 6492781952U, 6501170048U, 6509555072U, 6517947008U,
+ 6526336384U, 6534725504U, 6543112832U, 6551500672U, 6559888768U,
+ 6568278656U, 6576662912U, 6585055616U, 6593443456U, 6601834112U,
+ 6610219648U, 6618610304U, 6626999168U, 6635385472U, 6643777408U,
+ 6652164224U, 6660552832U, 6668941952U, 6677330048U, 6685719424U,
+ 6694107776U, 6702493568U, 6710882176U, 6719274112U, 6727662976U,
+ 6736052096U, 6744437632U, 6752825984U, 6761213824U, 6769604224U,
+ 6777993856U, 6786383488U, 6794770816U, 6803158144U, 6811549312U,
+ 6819937664U, 6828326528U, 6836706176U, 6845101696U, 6853491328U,
+ 6861880448U, 6870269312U, 6878655104U, 6887046272U, 6895433344U,
+ 6903822208U, 6912212864U, 6920596864U, 6928988288U, 6937377152U,
+ 6945764992U, 6954149248U, 6962544256U, 6970928768U, 6979317376U,
+ 6987709312U, 6996093824U, 7004487296U, 7012875392U, 7021258624U,
+ 7029652352U, 7038038912U, 7046427776U, 7054818944U, 7063207808U,
+ 7071595136U, 7079980928U, 7088372608U, 7096759424U, 7105149824U,
+ 7113536896U, 7121928064U, 7130315392U, 7138699648U, 7147092352U,
+ 7155479168U, 7163865728U, 7172249984U, 7180648064U, 7189036672U,
+ 7197424768U, 7205810816U, 7214196608U, 7222589824U, 7230975104U,
+ 7239367552U, 7247755904U, 7256145536U, 7264533376U, 7272921472U,
+ 7281308032U, 7289694848U, 7298088832U, 7306471808U, 7314864512U,
+ 7323253888U, 7331643008U, 7340029568U, 7348419712U, 7356808832U,
+ 7365196672U, 7373585792U, 7381973888U, 7390362752U, 7398750592U,
+ 7407138944U, 7415528576U, 7423915648U, 7432302208U, 7440690304U,
+ 7449080192U, 7457472128U, 7465860992U, 7474249088U, 7482635648U,
+ 7491023744U, 7499412608U, 7507803008U, 7516192384U, 7524579968U,
+ 7532967296U, 7541358464U, 7549745792U, 7558134656U, 7566524032U,
+ 7574912896U, 7583300992U, 7591690112U, 7600075136U, 7608466816U,
+ 7616854912U, 7625244544U, 7633629824U, 7642020992U, 7650410368U,
+ 7658794112U, 7667187328U, 7675574912U, 7683961984U, 7692349568U,
+ 7700739712U, 7709130368U, 7717519232U, 7725905536U, 7734295424U,
+ 7742683264U, 7751069056U, 7759457408U, 7767849088U, 7776238208U,
+ 7784626816U, 7793014912U, 7801405312U, 7809792128U, 7818179968U,
+ 7826571136U, 7834957184U, 7843347328U, 7851732352U, 7860124544U,
+ 7868512384U, 7876902016U, 7885287808U, 7893679744U, 7902067072U,
+ 7910455936U, 7918844288U, 7927230848U, 7935622784U, 7944009344U,
+ 7952400256U, 7960786048U, 7969176704U, 7977565312U, 7985953408U,
+ 7994339968U, 8002730368U, 8011119488U, 8019508096U, 8027896192U,
+ 8036285056U, 8044674688U, 8053062272U, 8061448832U, 8069838464U,
+ 8078227328U, 8086616704U, 8095006592U, 8103393664U, 8111783552U,
+ 8120171392U, 8128560256U, 8136949376U, 8145336704U, 8153726848U,
+ 8162114944U, 8170503296U, 8178891904U, 8187280768U, 8195669632U,
+ 8204058496U, 8212444544U, 8220834176U, 8229222272U, 8237612672U,
+ 8246000768U, 8254389376U, 8262775168U, 8271167104U, 8279553664U,
+ 8287944064U, 8296333184U, 8304715136U, 8313108352U, 8321497984U,
+ 8329885568U, 8338274432U, 8346663296U, 8355052928U, 8363441536U,
+ 8371828352U, 8380217984U, 8388606592U, 8396996224U, 8405384576U,
+ 8413772672U, 8422161536U, 8430549376U, 8438939008U, 8447326592U,
+ 8455715456U, 8464104832U, 8472492928U, 8480882048U, 8489270656U,
+ 8497659776U, 8506045312U, 8514434944U, 8522823808U, 8531208832U,
+ 8539602304U, 8547990656U, 8556378752U, 8564768384U, 8573154176U,
+ 8581542784U, 8589933952U, 8598322816U, 8606705024U, 8615099264U,
+ 8623487872U, 8631876992U, 8640264064U, 8648653952U, 8657040256U,
+ 8665430656U, 8673820544U, 8682209152U, 8690592128U, 8698977152U,
+ 8707374464U, 8715763328U, 8724151424U, 8732540032U, 8740928384U,
+ 8749315712U, 8757704576U, 8766089344U, 8774480768U, 8782871936U,
+ 8791260032U, 8799645824U, 8808034432U, 8816426368U, 8824812928U,
+ 8833199488U, 8841591424U, 8849976448U, 8858366336U, 8866757248U,
+ 8875147136U, 8883532928U, 8891923328U, 8900306816U, 8908700288U,
+ 8917088384U, 8925478784U, 8933867392U, 8942250368U, 8950644608U,
+ 8959032704U, 8967420544U, 8975809664U, 8984197504U, 8992584064U,
+ 9000976256U, 9009362048U, 9017752448U, 9026141312U, 9034530688U,
+ 9042917504U, 9051307904U, 9059694208U, 9068084864U, 9076471424U,
+ 9084861824U, 9093250688U, 9101638528U, 9110027648U, 9118416512U,
+ 9126803584U, 9135188096U, 9143581312U, 9151969664U, 9160356224U,
+ 9168747136U, 9177134464U, 9185525632U, 9193910144U, 9202302848U,
+ 9210690688U, 9219079552U, 9227465344U, 9235854464U, 9244244864U,
+ 9252633472U, 9261021824U, 9269411456U, 9277799296U, 9286188928U,
+ 9294574208U, 9302965888U, 9311351936U, 9319740032U, 9328131968U,
+ 9336516736U, 9344907392U, 9353296768U, 9361685888U, 9370074752U,
+ 9378463616U, 9386849408U, 9395239808U, 9403629184U, 9412016512U,
+ 9420405376U, 9428795008U, 9437181568U, 9445570688U, 9453960832U,
+ 9462346624U, 9470738048U, 9479121536U, 9487515008U, 9495903616U,
+ 9504289664U, 9512678528U, 9521067904U, 9529456256U, 9537843584U,
+ 9546233728U, 9554621312U, 9563011456U, 9571398784U, 9579788672U,
+ 9588178304U, 9596567168U, 9604954496U, 9613343104U, 9621732992U,
+ 9630121856U, 9638508416U, 9646898816U, 9655283584U, 9663675776U,
+ 9672061312U, 9680449664U, 9688840064U, 9697230464U, 9705617536U,
+ 9714003584U, 9722393984U, 9730772608U, 9739172224U, 9747561088U,
+ 9755945344U, 9764338816U, 9772726144U, 9781116544U, 9789503872U,
+ 9797892992U, 9806282624U, 9814670464U, 9823056512U, 9831439232U,
+ 9839833984U, 9848224384U, 9856613504U, 9865000576U, 9873391232U,
+ 9881772416U, 9890162816U, 9898556288U, 9906940544U, 9915333248U,
+ 9923721088U, 9932108672U, 9940496512U, 9948888448U, 9957276544U,
+ 9965666176U, 9974048384U, 9982441088U, 9990830464U, 9999219584U,
+ 10007602816U, 10015996544U, 10024385152U, 10032774016U, 10041163648U,
+ 10049548928U, 10057940096U, 10066329472U, 10074717824U, 10083105152U,
+ 10091495296U, 10099878784U, 10108272256U, 10116660608U, 10125049216U,
+ 10133437312U, 10141825664U, 10150213504U, 10158601088U, 10166991232U,
+ 10175378816U, 10183766144U, 10192157312U, 10200545408U, 10208935552U,
+ 10217322112U, 10225712768U, 10234099328U, 10242489472U, 10250876032U,
+ 10259264896U, 10267656064U, 10276042624U, 10284429184U, 10292820352U,
+ 10301209472U, 10309598848U, 10317987712U, 10326375296U, 10334763392U,
+ 10343153536U, 10351541632U, 10359930752U, 10368318592U, 10376707456U,
+ 10385096576U, 10393484672U, 10401867136U, 10410262144U, 10418647424U,
+ 10427039104U, 10435425664U, 10443810176U, 10452203648U, 10460589952U,
+ 10468982144U, 10477369472U, 10485759104U, 10494147712U, 10502533504U,
+ 10510923392U, 10519313536U, 10527702656U, 10536091264U, 10544478592U,
+ 10552867712U, 10561255808U, 10569642368U, 10578032768U, 10586423168U,
+ 10594805632U, 10603200128U, 10611588992U, 10619976064U, 10628361344U,
+ 10636754048U, 10645143424U, 10653531776U, 10661920384U, 10670307968U,
+ 10678696832U, 10687086464U, 10695475072U, 10703863168U, 10712246144U,
+ 10720639616U, 10729026688U, 10737414784U, 10745806208U, 10754190976U,
+ 10762581376U, 10770971264U, 10779356288U, 10787747456U, 10796135552U,
+ 10804525184U, 10812915584U, 10821301888U, 10829692288U, 10838078336U,
+ 10846469248U, 10854858368U, 10863247232U, 10871631488U, 10880023424U,
+ 10888412032U, 10896799616U, 10905188992U, 10913574016U, 10921964672U,
+ 10930352768U, 10938742912U, 10947132544U, 10955518592U, 10963909504U,
+ 10972298368U, 10980687488U, 10989074816U, 10997462912U, 11005851776U,
+ 11014241152U, 11022627712U, 11031017344U, 11039403904U, 11047793024U,
+ 11056184704U, 11064570752U, 11072960896U, 11081343872U, 11089737856U,
+ 11098128256U, 11106514816U, 11114904448U, 11123293568U, 11131680128U,
+ 11140065152U, 11148458368U, 11156845696U, 11165236864U, 11173624192U,
+ 11182013824U, 11190402688U, 11198790784U, 11207179136U, 11215568768U,
+ 11223957376U, 11232345728U, 11240734592U, 11249122688U, 11257511296U,
+ 11265899648U, 11274285952U, 11282675584U, 11291065472U, 11299452544U,
+ 11307842432U, 11316231296U, 11324616832U, 11333009024U, 11341395584U,
+ 11349782656U, 11358172288U, 11366560384U, 11374950016U, 11383339648U,
+ 11391721856U, 11400117376U, 11408504192U, 11416893568U, 11425283456U,
+ 11433671552U, 11442061184U, 11450444672U, 11458837888U, 11467226752U,
+ 11475611776U, 11484003968U, 11492392064U, 11500780672U, 11509169024U,
+ 11517550976U, 11525944448U, 11534335616U, 11542724224U, 11551111808U,
+ 11559500672U, 11567890304U, 11576277376U, 11584667008U, 11593056128U,
+ 11601443456U, 11609830016U, 11618221952U, 11626607488U, 11634995072U,
+ 11643387776U, 11651775104U, 11660161664U, 11668552576U, 11676940928U,
+ 11685330304U, 11693718656U, 11702106496U, 11710496128U, 11718882688U,
+ 11727273088U, 11735660416U, 11744050048U, 11752437376U, 11760824704U,
+ 11769216128U, 11777604736U, 11785991296U, 11794381952U, 11802770048U,
+ 11811157888U, 11819548544U, 11827932544U, 11836324736U, 11844713344U,
+ 11853100928U, 11861486464U, 11869879936U, 11878268032U, 11886656896U,
+ 11895044992U, 11903433088U, 11911822976U, 11920210816U, 11928600448U,
+ 11936987264U, 11945375872U, 11953761152U, 11962151296U, 11970543488U,
+ 11978928512U, 11987320448U, 11995708288U, 12004095104U, 12012486272U,
+ 12020875136U, 12029255552U, 12037652096U, 12046039168U, 12054429568U,
+ 12062813824U, 12071206528U, 12079594624U, 12087983744U, 12096371072U,
+ 12104759936U, 12113147264U, 12121534592U, 12129924992U, 12138314624U,
+ 12146703232U, 12155091584U, 12163481216U, 12171864704U, 12180255872U,
+ 12188643968U, 12197034112U, 12205424512U, 12213811328U, 12222199424U,
+ 12230590336U, 12238977664U, 12247365248U, 12255755392U, 12264143488U,
+ 12272531584U, 12280920448U, 12289309568U, 12297694592U, 12306086528U,
+ 12314475392U, 12322865024U, 12331253632U, 12339640448U, 12348029312U,
+ 12356418944U, 12364805248U, 12373196672U, 12381580928U, 12389969024U,
+ 12398357632U, 12406750592U, 12415138432U, 12423527552U, 12431916416U,
+ 12440304512U, 12448692352U, 12457081216U, 12465467776U, 12473859968U,
+ 12482245504U, 12490636672U, 12499025536U, 12507411584U, 12515801728U,
+ 12524190592U, 12532577152U, 12540966272U, 12549354368U, 12557743232U,
+ 12566129536U, 12574523264U, 12582911872U, 12591299456U, 12599688064U,
+ 12608074624U, 12616463488U, 12624845696U, 12633239936U, 12641631616U,
+ 12650019968U, 12658407296U, 12666795136U, 12675183232U, 12683574656U,
+ 12691960192U, 12700350592U, 12708740224U, 12717128576U, 12725515904U,
+ 12733906816U, 12742295168U, 12750680192U, 12759071872U, 12767460736U,
+ 12775848832U, 12784236928U, 12792626816U, 12801014656U, 12809404288U,
+ 12817789312U, 12826181504U, 12834568832U, 12842954624U, 12851345792U,
+ 12859732352U, 12868122496U, 12876512128U, 12884901248U, 12893289088U,
+ 12901672832U, 12910067584U, 12918455168U, 12926842496U, 12935232896U,
+ 12943620736U, 12952009856U, 12960396928U, 12968786816U, 12977176192U,
+ 12985563776U, 12993951104U, 13002341504U, 13010730368U, 13019115392U,
+ 13027506304U, 13035895168U, 13044272512U, 13052673152U, 13061062528U,
+ 13069446272U, 13077838976U, 13086227072U, 13094613632U, 13103000192U,
+ 13111393664U, 13119782528U, 13128157568U, 13136559232U, 13144945024U,
+ 13153329536U, 13161724288U, 13170111872U, 13178502784U, 13186884736U,
+ 13195279744U, 13203667072U, 13212057472U, 13220445824U, 13228832128U,
+ 13237221248U, 13245610624U, 13254000512U, 13262388352U, 13270777472U,
+ 13279166336U, 13287553408U, 13295943296U, 13304331904U, 13312719488U,
+ 13321108096U, 13329494656U, 13337885824U, 13346274944U, 13354663808U,
+ 13363051136U, 13371439232U, 13379825024U, 13388210816U, 13396605056U,
+ 13404995456U, 13413380224U, 13421771392U, 13430159744U, 13438546048U,
+ 13446937216U, 13455326848U, 13463708288U, 13472103808U, 13480492672U,
+ 13488875648U, 13497269888U, 13505657728U, 13514045312U, 13522435712U,
+ 13530824576U, 13539210112U, 13547599232U, 13555989376U, 13564379008U,
+ 13572766336U, 13581154432U, 13589544832U, 13597932928U, 13606320512U,
+ 13614710656U, 13623097472U, 13631477632U, 13639874944U, 13648264064U,
+ 13656652928U, 13665041792U, 13673430656U, 13681818496U, 13690207616U,
+ 13698595712U, 13706982272U, 13715373184U, 13723762048U, 13732150144U,
+ 13740536704U, 13748926592U, 13757316224U, 13765700992U, 13774090112U,
+ 13782477952U, 13790869376U, 13799259008U, 13807647872U, 13816036736U,
+ 13824425344U, 13832814208U, 13841202304U, 13849591424U, 13857978752U,
+ 13866368896U, 13874754688U, 13883145344U, 13891533184U, 13899919232U,
+ 13908311168U, 13916692096U, 13925085056U, 13933473152U, 13941866368U,
+ 13950253696U, 13958643584U, 13967032192U, 13975417216U, 13983807616U,
+ 13992197504U, 14000582272U, 14008973696U, 14017363072U, 14025752192U,
+ 14034137984U, 14042528384U, 14050918016U, 14059301504U, 14067691648U,
+ 14076083584U, 14084470144U, 14092852352U, 14101249664U, 14109635968U,
+ 14118024832U, 14126407552U, 14134804352U, 14143188608U, 14151577984U,
+ 14159968384U, 14168357248U, 14176741504U, 14185127296U, 14193521024U,
+ 14201911424U, 14210301824U, 14218685056U, 14227067264U, 14235467392U,
+ 14243855488U, 14252243072U, 14260630144U, 14269021568U, 14277409408U,
+ 14285799296U, 14294187904U, 14302571392U, 14310961792U, 14319353728U,
+ 14327738752U, 14336130944U, 14344518784U, 14352906368U, 14361296512U,
+ 14369685376U, 14378071424U, 14386462592U, 14394848128U, 14403230848U,
+ 14411627392U, 14420013952U, 14428402304U, 14436793472U, 14445181568U,
+ 14453569664U, 14461959808U, 14470347904U, 14478737024U, 14487122816U,
+ 14495511424U, 14503901824U, 14512291712U, 14520677504U, 14529064832U,
+ 14537456768U, 14545845632U, 14554234496U, 14562618496U, 14571011456U,
+ 14579398784U, 14587789184U, 14596172672U, 14604564608U, 14612953984U,
+ 14621341312U, 14629724288U, 14638120832U, 14646503296U, 14654897536U,
+ 14663284864U, 14671675264U, 14680061056U, 14688447616U, 14696835968U,
+ 14705228416U, 14713616768U, 14722003328U, 14730392192U, 14738784128U,
+ 14747172736U, 14755561088U, 14763947648U, 14772336512U, 14780725376U,
+ 14789110144U, 14797499776U, 14805892736U, 14814276992U, 14822670208U,
+ 14831056256U, 14839444352U, 14847836032U, 14856222848U, 14864612992U,
+ 14872997504U, 14881388672U, 14889775744U, 14898165376U, 14906553472U,
+ 14914944896U, 14923329664U, 14931721856U, 14940109696U, 14948497024U,
+ 14956887424U, 14965276544U, 14973663616U, 14982053248U, 14990439808U,
+ 14998830976U, 15007216768U, 15015605888U, 15023995264U, 15032385152U,
+ 15040768384U, 15049154944U, 15057549184U, 15065939072U, 15074328448U,
+ 15082715008U, 15091104128U, 15099493504U, 15107879296U, 15116269184U,
+ 15124659584U, 15133042304U, 15141431936U, 15149824384U, 15158214272U,
+ 15166602368U, 15174991232U, 15183378304U, 15191760512U, 15200154496U,
+ 15208542592U, 15216931712U, 15225323392U, 15233708416U, 15242098048U,
+ 15250489216U, 15258875264U, 15267265408U, 15275654528U, 15284043136U,
+ 15292431488U, 15300819584U, 15309208192U, 15317596544U, 15325986176U,
+ 15334374784U, 15342763648U, 15351151744U, 15359540608U, 15367929728U,
+ 15376318336U, 15384706432U, 15393092992U, 15401481856U, 15409869952U,
+ 15418258816U, 15426649984U, 15435037568U, 15443425664U, 15451815296U,
+ 15460203392U, 15468589184U, 15476979328U, 15485369216U, 15493755776U,
+ 15502146944U, 15510534272U, 15518924416U, 15527311232U, 15535699072U,
+ 15544089472U, 15552478336U, 15560866688U, 15569254528U, 15577642624U,
+ 15586031488U, 15594419072U, 15602809472U, 15611199104U, 15619586432U,
+ 15627975296U, 15636364928U, 15644753792U, 15653141888U, 15661529216U,
+ 15669918848U, 15678305152U, 15686696576U, 15695083136U, 15703474048U,
+ 15711861632U, 15720251264U, 15728636288U, 15737027456U, 15745417088U,
+ 15753804928U, 15762194048U, 15770582656U, 15778971008U, 15787358336U,
+ 15795747712U, 15804132224U, 15812523392U, 15820909696U, 15829300096U,
+ 15837691264U, 15846071936U, 15854466944U, 15862855808U, 15871244672U,
+ 15879634816U, 15888020608U, 15896409728U, 15904799104U, 15913185152U,
+ 15921577088U, 15929966464U, 15938354816U, 15946743424U, 15955129472U,
+ 15963519872U, 15971907968U, 15980296064U, 15988684928U, 15997073024U,
+ 16005460864U, 16013851264U, 16022241152U, 16030629248U, 16039012736U,
+ 16047406976U, 16055794816U, 16064181376U, 16072571264U, 16080957824U,
+ 16089346688U, 16097737856U, 16106125184U, 16114514816U, 16122904192U,
+ 16131292544U, 16139678848U, 16148066944U, 16156453504U, 16164839552U,
+ 16173236096U, 16181623424U, 16190012032U, 16198401152U, 16206790528U,
+ 16215177344U, 16223567744U, 16231956352U, 16240344704U, 16248731008U,
+ 16257117824U, 16265504384U, 16273898624U, 16282281856U, 16290668672U,
+ 16299064192U, 16307449216U, 16315842176U, 16324230016U, 16332613504U,
+ 16341006464U, 16349394304U, 16357783168U, 16366172288U, 16374561664U,
+ 16382951296U, 16391337856U, 16399726208U, 16408116352U, 16416505472U,
+ 16424892032U, 16433282176U, 16441668224U, 16450058624U, 16458448768U,
+ 16466836864U, 16475224448U, 16483613056U, 16492001408U, 16500391808U,
+ 16508779648U, 16517166976U, 16525555328U, 16533944192U, 16542330752U,
+ 16550719616U, 16559110528U, 16567497088U, 16575888512U, 16584274816U,
+ 16592665472U, 16601051008U, 16609442944U, 16617832064U, 16626218624U,
+ 16634607488U, 16642996096U, 16651385728U, 16659773824U, 16668163712U,
+ 16676552576U, 16684938112U, 16693328768U, 16701718144U, 16710095488U,
+ 16718492288U, 16726883968U, 16735272832U, 16743661184U, 16752049792U,
+ 16760436608U, 16768827008U, 16777214336U, 16785599104U, 16793992832U,
+ 16802381696U, 16810768768U, 16819151744U, 16827542656U, 16835934848U,
+ 16844323712U, 16852711552U, 16861101952U, 16869489536U, 16877876864U,
+ 16886265728U, 16894653056U, 16903044736U, 16911431296U, 16919821696U,
+ 16928207488U, 16936592768U, 16944987776U, 16953375616U, 16961763968U,
+ 16970152832U, 16978540928U, 16986929536U, 16995319168U, 17003704448U,
+ 17012096896U, 17020481152U, 17028870784U, 17037262208U, 17045649536U,
+ 17054039936U, 17062426496U, 17070814336U, 17079205504U, 17087592064U,
+ 17095978112U, 17104369024U, 17112759424U, 17121147776U, 17129536384U,
+ 17137926016U, 17146314368U, 17154700928U, 17163089792U, 17171480192U,
+ 17179864192U, 17188256896U, 17196644992U, 17205033856U, 17213423488U,
+ 17221811072U, 17230198912U, 17238588032U, 17246976896U, 17255360384U,
+ 17263754624U, 17272143232U, 17280530048U, 17288918912U, 17297309312U,
+ 17305696384U, 17314085504U, 17322475136U, 17330863744U, 17339252096U,
+ 17347640192U, 17356026496U, 17364413824U, 17372796544U, 17381190016U,
+ 17389583488U, 17397972608U, 17406360704U, 17414748544U, 17423135872U,
+ 17431527296U, 17439915904U, 17448303232U, 17456691584U, 17465081728U,
+ 17473468288U, 17481857408U, 17490247552U, 17498635904U, 17507022464U,
+ 17515409024U, 17523801728U, 17532189824U, 17540577664U, 17548966016U,
+ 17557353344U, 17565741184U, 17574131584U, 17582519168U, 17590907008U,
+ 17599296128U, 17607687808U, 17616076672U, 17624455808U, 17632852352U,
+ 17641238656U, 17649630848U, 17658018944U, 17666403968U, 17674794112U,
+ 17683178368U, 17691573376U, 17699962496U, 17708350592U, 17716739968U,
+ 17725126528U, 17733517184U, 17741898112U, 17750293888U, 17758673024U,
+ 17767070336U, 17775458432U, 17783848832U, 17792236928U, 17800625536U,
+ 17809012352U, 17817402752U, 17825785984U, 17834178944U, 17842563968U,
+ 17850955648U, 17859344512U, 17867732864U, 17876119424U, 17884511872U,
+ 17892900224U, 17901287296U, 17909677696U, 17918058112U, 17926451072U,
+ 17934843776U, 17943230848U, 17951609216U, 17960008576U, 17968397696U,
+ 17976784256U, 17985175424U, 17993564032U, 18001952128U, 18010339712U,
+ 18018728576U, 18027116672U, 18035503232U, 18043894144U, 18052283264U,
+ 18060672128U, 18069056384U, 18077449856U, 18085837184U, 18094225792U,
+ 18102613376U, 18111004544U, 18119388544U, 18127781248U, 18136170368U,
+ 18144558976U, 18152947328U, 18161336192U, 18169724288U, 18178108544U,
+ 18186498944U, 18194886784U, 18203275648U, 18211666048U, 18220048768U,
+ 18228444544U, 18236833408U, 18245220736U
};
@@ -478,335 +478,335 @@ static const uint64_t dag_sizes[2048] = {
// Sow[i*HashBytes]; j++]]]][[2]][[1]]
const uint64_t cache_sizes[2048] = {
- 16776896U, 16907456U, 17039296U, 17170112U, 17301056U, 17432512U, 17563072U,
- 17693888U, 17824192U, 17955904U, 18087488U, 18218176U, 18349504U, 18481088U,
- 18611392U, 18742336U, 18874304U, 19004224U, 19135936U, 19267264U, 19398208U,
- 19529408U, 19660096U, 19791424U, 19922752U, 20053952U, 20184896U, 20315968U,
- 20446912U, 20576576U, 20709184U, 20840384U, 20971072U, 21102272U, 21233216U,
- 21364544U, 21494848U, 21626816U, 21757376U, 21887552U, 22019392U, 22151104U,
- 22281536U, 22412224U, 22543936U, 22675264U, 22806464U, 22935872U, 23068096U,
- 23198272U, 23330752U, 23459008U, 23592512U, 23723968U, 23854912U, 23986112U,
- 24116672U, 24247616U, 24378688U, 24509504U, 24640832U, 24772544U, 24903488U,
- 25034432U, 25165376U, 25296704U, 25427392U, 25558592U, 25690048U, 25820096U,
- 25951936U, 26081728U, 26214208U, 26345024U, 26476096U, 26606656U, 26737472U,
- 26869184U, 26998208U, 27131584U, 27262528U, 27393728U, 27523904U, 27655744U,
- 27786688U, 27917888U, 28049344U, 28179904U, 28311488U, 28441792U, 28573504U,
- 28700864U, 28835648U, 28966208U, 29096768U, 29228608U, 29359808U, 29490752U,
- 29621824U, 29752256U, 29882816U, 30014912U, 30144448U, 30273728U, 30406976U,
- 30538432U, 30670784U, 30799936U, 30932672U, 31063744U, 31195072U, 31325248U,
- 31456192U, 31588288U, 31719232U, 31850432U, 31981504U, 32110784U, 32243392U,
- 32372672U, 32505664U, 32636608U, 32767808U, 32897344U, 33029824U, 33160768U,
- 33289664U, 33423296U, 33554368U, 33683648U, 33816512U, 33947456U, 34076992U,
- 34208704U, 34340032U, 34471744U, 34600256U, 34734016U, 34864576U, 34993984U,
- 35127104U, 35258176U, 35386688U, 35518528U, 35650624U, 35782336U, 35910976U,
- 36044608U, 36175808U, 36305728U, 36436672U, 36568384U, 36699968U, 36830656U,
- 36961984U, 37093312U, 37223488U, 37355072U, 37486528U, 37617472U, 37747904U,
- 37879232U, 38009792U, 38141888U, 38272448U, 38403392U, 38535104U, 38660672U,
- 38795584U, 38925632U, 39059264U, 39190336U, 39320768U, 39452096U, 39581632U,
- 39713984U, 39844928U, 39974848U, 40107968U, 40238144U, 40367168U, 40500032U,
- 40631744U, 40762816U, 40894144U, 41023552U, 41155904U, 41286208U, 41418304U,
- 41547712U, 41680448U, 41811904U, 41942848U, 42073792U, 42204992U, 42334912U,
- 42467008U, 42597824U, 42729152U, 42860096U, 42991552U, 43122368U, 43253696U,
- 43382848U, 43515712U, 43646912U, 43777088U, 43907648U, 44039104U, 44170432U,
- 44302144U, 44433344U, 44564288U, 44694976U, 44825152U, 44956864U, 45088448U,
- 45219008U, 45350464U, 45481024U, 45612608U, 45744064U, 45874496U, 46006208U,
- 46136768U, 46267712U, 46399424U, 46529344U, 46660672U, 46791488U, 46923328U,
- 47053504U, 47185856U, 47316928U, 47447872U, 47579072U, 47710144U, 47839936U,
- 47971648U, 48103232U, 48234176U, 48365248U, 48496192U, 48627136U, 48757312U,
- 48889664U, 49020736U, 49149248U, 49283008U, 49413824U, 49545152U, 49675712U,
- 49807168U, 49938368U, 50069056U, 50200256U, 50331584U, 50462656U, 50593472U,
- 50724032U, 50853952U, 50986048U, 51117632U, 51248576U, 51379904U, 51510848U,
- 51641792U, 51773248U, 51903296U, 52035136U, 52164032U, 52297664U, 52427968U,
- 52557376U, 52690112U, 52821952U, 52952896U, 53081536U, 53213504U, 53344576U,
- 53475776U, 53608384U, 53738816U, 53870528U, 54000832U, 54131776U, 54263744U,
- 54394688U, 54525248U, 54655936U, 54787904U, 54918592U, 55049152U, 55181248U,
- 55312064U, 55442752U, 55574336U, 55705024U, 55836224U, 55967168U, 56097856U,
- 56228672U, 56358592U, 56490176U, 56621888U, 56753728U, 56884928U, 57015488U,
- 57146816U, 57278272U, 57409216U, 57540416U, 57671104U, 57802432U, 57933632U,
- 58064576U, 58195264U, 58326976U, 58457408U, 58588864U, 58720192U, 58849984U,
- 58981696U, 59113024U, 59243456U, 59375552U, 59506624U, 59637568U, 59768512U,
- 59897792U, 60030016U, 60161984U, 60293056U, 60423872U, 60554432U, 60683968U,
- 60817216U, 60948032U, 61079488U, 61209664U, 61341376U, 61471936U, 61602752U,
- 61733696U, 61865792U, 61996736U, 62127808U, 62259136U, 62389568U, 62520512U,
- 62651584U, 62781632U, 62910784U, 63045056U, 63176128U, 63307072U, 63438656U,
- 63569216U, 63700928U, 63831616U, 63960896U, 64093888U, 64225088U, 64355392U,
- 64486976U, 64617664U, 64748608U, 64879424U, 65009216U, 65142464U, 65273792U,
- 65402816U, 65535424U, 65666752U, 65797696U, 65927744U, 66060224U, 66191296U,
- 66321344U, 66453056U, 66584384U, 66715328U, 66846656U, 66977728U, 67108672U,
- 67239104U, 67370432U, 67501888U, 67631296U, 67763776U, 67895104U, 68026304U,
- 68157248U, 68287936U, 68419264U, 68548288U, 68681408U, 68811968U, 68942912U,
- 69074624U, 69205568U, 69337024U, 69467584U, 69599168U, 69729472U, 69861184U,
- 69989824U, 70122944U, 70253888U, 70385344U, 70515904U, 70647232U, 70778816U,
- 70907968U, 71040832U, 71171648U, 71303104U, 71432512U, 71564992U, 71695168U,
- 71826368U, 71958464U, 72089536U, 72219712U, 72350144U, 72482624U, 72613568U,
- 72744512U, 72875584U, 73006144U, 73138112U, 73268672U, 73400128U, 73530944U,
- 73662272U, 73793344U, 73924544U, 74055104U, 74185792U, 74316992U, 74448832U,
- 74579392U, 74710976U, 74841664U, 74972864U, 75102784U, 75233344U, 75364544U,
- 75497024U, 75627584U, 75759296U, 75890624U, 76021696U, 76152256U, 76283072U,
- 76414144U, 76545856U, 76676672U, 76806976U, 76937792U, 77070016U, 77200832U,
- 77331392U, 77462464U, 77593664U, 77725376U, 77856448U, 77987776U, 78118336U,
- 78249664U, 78380992U, 78511424U, 78642496U, 78773056U, 78905152U, 79033664U,
- 79166656U, 79297472U, 79429568U, 79560512U, 79690816U, 79822784U, 79953472U,
- 80084672U, 80214208U, 80346944U, 80477632U, 80608576U, 80740288U, 80870848U,
- 81002048U, 81133504U, 81264448U, 81395648U, 81525952U, 81657536U, 81786304U,
- 81919808U, 82050112U, 82181312U, 82311616U, 82443968U, 82573376U, 82705984U,
- 82835776U, 82967744U, 83096768U, 83230528U, 83359552U, 83491264U, 83622464U,
- 83753536U, 83886016U, 84015296U, 84147776U, 84277184U, 84409792U, 84540608U,
- 84672064U, 84803008U, 84934336U, 85065152U, 85193792U, 85326784U, 85458496U,
- 85589312U, 85721024U, 85851968U, 85982656U, 86112448U, 86244416U, 86370112U,
- 86506688U, 86637632U, 86769344U, 86900672U, 87031744U, 87162304U, 87293632U,
- 87424576U, 87555392U, 87687104U, 87816896U, 87947968U, 88079168U, 88211264U,
- 88341824U, 88473152U, 88603712U, 88735424U, 88862912U, 88996672U, 89128384U,
- 89259712U, 89390272U, 89521984U, 89652544U, 89783872U, 89914816U, 90045376U,
- 90177088U, 90307904U, 90438848U, 90569152U, 90700096U, 90832832U, 90963776U,
- 91093696U, 91223744U, 91356992U, 91486784U, 91618496U, 91749824U, 91880384U,
- 92012224U, 92143552U, 92273344U, 92405696U, 92536768U, 92666432U, 92798912U,
- 92926016U, 93060544U, 93192128U, 93322816U, 93453632U, 93583936U, 93715136U,
- 93845056U, 93977792U, 94109504U, 94240448U, 94371776U, 94501184U, 94632896U,
- 94764224U, 94895552U, 95023424U, 95158208U, 95287744U, 95420224U, 95550016U,
- 95681216U, 95811904U, 95943872U, 96075328U, 96203584U, 96337856U, 96468544U,
- 96599744U, 96731072U, 96860992U, 96992576U, 97124288U, 97254848U, 97385536U,
- 97517248U, 97647808U, 97779392U, 97910464U, 98041408U, 98172608U, 98303168U,
- 98434496U, 98565568U, 98696768U, 98827328U, 98958784U, 99089728U, 99220928U,
- 99352384U, 99482816U, 99614272U, 99745472U, 99876416U, 100007104U,
- 100138048U, 100267072U, 100401088U, 100529984U, 100662592U, 100791872U,
- 100925248U, 101056064U, 101187392U, 101317952U, 101449408U, 101580608U,
- 101711296U, 101841728U, 101973824U, 102104896U, 102235712U, 102366016U,
- 102498112U, 102628672U, 102760384U, 102890432U, 103021888U, 103153472U,
- 103284032U, 103415744U, 103545152U, 103677248U, 103808576U, 103939648U,
- 104070976U, 104201792U, 104332736U, 104462528U, 104594752U, 104725952U,
- 104854592U, 104988608U, 105118912U, 105247808U, 105381184U, 105511232U,
- 105643072U, 105774784U, 105903296U, 106037056U, 106167872U, 106298944U,
- 106429504U, 106561472U, 106691392U, 106822592U, 106954304U, 107085376U,
- 107216576U, 107346368U, 107478464U, 107609792U, 107739712U, 107872192U,
- 108003136U, 108131392U, 108265408U, 108396224U, 108527168U, 108657344U,
- 108789568U, 108920384U, 109049792U, 109182272U, 109312576U, 109444928U,
- 109572928U, 109706944U, 109837888U, 109969088U, 110099648U, 110230976U,
- 110362432U, 110492992U, 110624704U, 110755264U, 110886208U, 111017408U,
- 111148864U, 111279296U, 111410752U, 111541952U, 111673024U, 111803456U,
- 111933632U, 112066496U, 112196416U, 112328512U, 112457792U, 112590784U,
- 112715968U, 112852672U, 112983616U, 113114944U, 113244224U, 113376448U,
- 113505472U, 113639104U, 113770304U, 113901376U, 114031552U, 114163264U,
- 114294592U, 114425536U, 114556864U, 114687424U, 114818624U, 114948544U,
- 115080512U, 115212224U, 115343296U, 115473472U, 115605184U, 115736128U,
- 115867072U, 115997248U, 116128576U, 116260288U, 116391488U, 116522944U,
- 116652992U, 116784704U, 116915648U, 117046208U, 117178304U, 117308608U,
- 117440192U, 117569728U, 117701824U, 117833024U, 117964096U, 118094656U,
- 118225984U, 118357312U, 118489024U, 118617536U, 118749632U, 118882112U,
- 119012416U, 119144384U, 119275328U, 119406016U, 119537344U, 119668672U,
- 119798464U, 119928896U, 120061376U, 120192832U, 120321728U, 120454336U,
- 120584512U, 120716608U, 120848192U, 120979136U, 121109056U, 121241408U,
- 121372352U, 121502912U, 121634752U, 121764416U, 121895744U, 122027072U,
- 122157632U, 122289088U, 122421184U, 122550592U, 122682944U, 122813888U,
- 122945344U, 123075776U, 123207488U, 123338048U, 123468736U, 123600704U,
- 123731264U, 123861952U, 123993664U, 124124608U, 124256192U, 124386368U,
- 124518208U, 124649024U, 124778048U, 124911296U, 125041088U, 125173696U,
- 125303744U, 125432896U, 125566912U, 125696576U, 125829056U, 125958592U,
- 126090304U, 126221248U, 126352832U, 126483776U, 126615232U, 126746432U,
- 126876608U, 127008704U, 127139392U, 127270336U, 127401152U, 127532224U,
- 127663552U, 127794752U, 127925696U, 128055232U, 128188096U, 128319424U,
- 128449856U, 128581312U, 128712256U, 128843584U, 128973632U, 129103808U,
- 129236288U, 129365696U, 129498944U, 129629888U, 129760832U, 129892288U,
- 130023104U, 130154048U, 130283968U, 130416448U, 130547008U, 130678336U,
- 130807616U, 130939456U, 131071552U, 131202112U, 131331776U, 131464384U,
- 131594048U, 131727296U, 131858368U, 131987392U, 132120256U, 132250816U,
- 132382528U, 132513728U, 132644672U, 132774976U, 132905792U, 133038016U,
- 133168832U, 133299392U, 133429312U, 133562048U, 133692992U, 133823296U,
- 133954624U, 134086336U, 134217152U, 134348608U, 134479808U, 134607296U,
- 134741056U, 134872384U, 135002944U, 135134144U, 135265472U, 135396544U,
- 135527872U, 135659072U, 135787712U, 135921472U, 136052416U, 136182848U,
- 136313792U, 136444864U, 136576448U, 136707904U, 136837952U, 136970048U,
- 137099584U, 137232064U, 137363392U, 137494208U, 137625536U, 137755712U,
- 137887424U, 138018368U, 138149824U, 138280256U, 138411584U, 138539584U,
- 138672832U, 138804928U, 138936128U, 139066688U, 139196864U, 139328704U,
- 139460032U, 139590208U, 139721024U, 139852864U, 139984576U, 140115776U,
- 140245696U, 140376512U, 140508352U, 140640064U, 140769856U, 140902336U,
- 141032768U, 141162688U, 141294016U, 141426496U, 141556544U, 141687488U,
- 141819584U, 141949888U, 142080448U, 142212544U, 142342336U, 142474432U,
- 142606144U, 142736192U, 142868288U, 142997824U, 143129408U, 143258944U,
- 143392448U, 143523136U, 143653696U, 143785024U, 143916992U, 144045632U,
- 144177856U, 144309184U, 144440768U, 144570688U, 144701888U, 144832448U,
- 144965056U, 145096384U, 145227584U, 145358656U, 145489856U, 145620928U,
- 145751488U, 145883072U, 146011456U, 146144704U, 146275264U, 146407232U,
- 146538176U, 146668736U, 146800448U, 146931392U, 147062336U, 147193664U,
- 147324224U, 147455936U, 147586624U, 147717056U, 147848768U, 147979456U,
- 148110784U, 148242368U, 148373312U, 148503232U, 148635584U, 148766144U,
- 148897088U, 149028416U, 149159488U, 149290688U, 149420224U, 149551552U,
- 149683136U, 149814976U, 149943616U, 150076352U, 150208064U, 150338624U,
- 150470464U, 150600256U, 150732224U, 150862784U, 150993088U, 151125952U,
- 151254976U, 151388096U, 151519168U, 151649728U, 151778752U, 151911104U,
- 152042944U, 152174144U, 152304704U, 152435648U, 152567488U, 152698816U,
- 152828992U, 152960576U, 153091648U, 153222976U, 153353792U, 153484096U,
- 153616192U, 153747008U, 153878336U, 154008256U, 154139968U, 154270912U,
- 154402624U, 154533824U, 154663616U, 154795712U, 154926272U, 155057984U,
- 155188928U, 155319872U, 155450816U, 155580608U, 155712064U, 155843392U,
- 155971136U, 156106688U, 156237376U, 156367424U, 156499264U, 156630976U,
- 156761536U, 156892352U, 157024064U, 157155008U, 157284416U, 157415872U,
- 157545536U, 157677248U, 157810496U, 157938112U, 158071744U, 158203328U,
- 158334656U, 158464832U, 158596288U, 158727616U, 158858048U, 158988992U,
- 159121216U, 159252416U, 159381568U, 159513152U, 159645632U, 159776192U,
- 159906496U, 160038464U, 160169536U, 160300352U, 160430656U, 160563008U,
- 160693952U, 160822208U, 160956352U, 161086784U, 161217344U, 161349184U,
- 161480512U, 161611456U, 161742272U, 161873216U, 162002752U, 162135872U,
- 162266432U, 162397888U, 162529216U, 162660032U, 162790976U, 162922048U,
- 163052096U, 163184576U, 163314752U, 163446592U, 163577408U, 163707968U,
- 163839296U, 163969984U, 164100928U, 164233024U, 164364224U, 164494912U,
- 164625856U, 164756672U, 164887616U, 165019072U, 165150016U, 165280064U,
- 165412672U, 165543104U, 165674944U, 165805888U, 165936832U, 166067648U,
- 166198336U, 166330048U, 166461248U, 166591552U, 166722496U, 166854208U,
- 166985408U, 167116736U, 167246656U, 167378368U, 167508416U, 167641024U,
- 167771584U, 167903168U, 168034112U, 168164032U, 168295744U, 168427456U,
- 168557632U, 168688448U, 168819136U, 168951616U, 169082176U, 169213504U,
- 169344832U, 169475648U, 169605952U, 169738048U, 169866304U, 169999552U,
- 170131264U, 170262464U, 170393536U, 170524352U, 170655424U, 170782016U,
- 170917696U, 171048896U, 171179072U, 171310784U, 171439936U, 171573184U,
- 171702976U, 171835072U, 171966272U, 172097216U, 172228288U, 172359232U,
- 172489664U, 172621376U, 172747712U, 172883264U, 173014208U, 173144512U,
- 173275072U, 173407424U, 173539136U, 173669696U, 173800768U, 173931712U,
- 174063424U, 174193472U, 174325696U, 174455744U, 174586816U, 174718912U,
- 174849728U, 174977728U, 175109696U, 175242688U, 175374272U, 175504832U,
- 175636288U, 175765696U, 175898432U, 176028992U, 176159936U, 176291264U,
- 176422592U, 176552512U, 176684864U, 176815424U, 176946496U, 177076544U,
- 177209152U, 177340096U, 177470528U, 177600704U, 177731648U, 177864256U,
- 177994816U, 178126528U, 178257472U, 178387648U, 178518464U, 178650176U,
- 178781888U, 178912064U, 179044288U, 179174848U, 179305024U, 179436736U,
- 179568448U, 179698496U, 179830208U, 179960512U, 180092608U, 180223808U,
- 180354752U, 180485696U, 180617152U, 180748096U, 180877504U, 181009984U,
- 181139264U, 181272512U, 181402688U, 181532608U, 181663168U, 181795136U,
- 181926592U, 182057536U, 182190016U, 182320192U, 182451904U, 182582336U,
- 182713792U, 182843072U, 182976064U, 183107264U, 183237056U, 183368384U,
- 183494848U, 183631424U, 183762752U, 183893824U, 184024768U, 184154816U,
- 184286656U, 184417984U, 184548928U, 184680128U, 184810816U, 184941248U,
- 185072704U, 185203904U, 185335616U, 185465408U, 185596352U, 185727296U,
- 185859904U, 185989696U, 186121664U, 186252992U, 186383552U, 186514112U,
- 186645952U, 186777152U, 186907328U, 187037504U, 187170112U, 187301824U,
- 187429184U, 187562048U, 187693504U, 187825472U, 187957184U, 188087104U,
- 188218304U, 188349376U, 188481344U, 188609728U, 188743616U, 188874304U,
- 189005248U, 189136448U, 189265088U, 189396544U, 189528128U, 189660992U,
- 189791936U, 189923264U, 190054208U, 190182848U, 190315072U, 190447424U,
- 190577984U, 190709312U, 190840768U, 190971328U, 191102656U, 191233472U,
- 191364032U, 191495872U, 191626816U, 191758016U, 191888192U, 192020288U,
- 192148928U, 192282176U, 192413504U, 192542528U, 192674752U, 192805952U,
- 192937792U, 193068608U, 193198912U, 193330496U, 193462208U, 193592384U,
- 193723456U, 193854272U, 193985984U, 194116672U, 194247232U, 194379712U,
- 194508352U, 194641856U, 194772544U, 194900672U, 195035072U, 195166016U,
- 195296704U, 195428032U, 195558592U, 195690304U, 195818176U, 195952576U,
- 196083392U, 196214336U, 196345792U, 196476736U, 196607552U, 196739008U,
- 196869952U, 197000768U, 197130688U, 197262784U, 197394368U, 197523904U,
- 197656384U, 197787584U, 197916608U, 198049472U, 198180544U, 198310208U,
- 198442432U, 198573632U, 198705088U, 198834368U, 198967232U, 199097792U,
- 199228352U, 199360192U, 199491392U, 199621696U, 199751744U, 199883968U,
- 200014016U, 200146624U, 200276672U, 200408128U, 200540096U, 200671168U,
- 200801984U, 200933312U, 201062464U, 201194944U, 201326144U, 201457472U,
- 201588544U, 201719744U, 201850816U, 201981632U, 202111552U, 202244032U,
- 202374464U, 202505152U, 202636352U, 202767808U, 202898368U, 203030336U,
- 203159872U, 203292608U, 203423296U, 203553472U, 203685824U, 203816896U,
- 203947712U, 204078272U, 204208192U, 204341056U, 204472256U, 204603328U,
- 204733888U, 204864448U, 204996544U, 205125568U, 205258304U, 205388864U,
- 205517632U, 205650112U, 205782208U, 205913536U, 206044736U, 206176192U,
- 206307008U, 206434496U, 206569024U, 206700224U, 206831168U, 206961856U,
- 207093056U, 207223616U, 207355328U, 207486784U, 207616832U, 207749056U,
- 207879104U, 208010048U, 208141888U, 208273216U, 208404032U, 208534336U,
- 208666048U, 208796864U, 208927424U, 209059264U, 209189824U, 209321792U,
- 209451584U, 209582656U, 209715136U, 209845568U, 209976896U, 210106432U,
- 210239296U, 210370112U, 210501568U, 210630976U, 210763712U, 210894272U,
- 211024832U, 211156672U, 211287616U, 211418176U, 211549376U, 211679296U,
- 211812032U, 211942592U, 212074432U, 212204864U, 212334016U, 212467648U,
- 212597824U, 212727616U, 212860352U, 212991424U, 213120832U, 213253952U,
- 213385024U, 213515584U, 213645632U, 213777728U, 213909184U, 214040128U,
- 214170688U, 214302656U, 214433728U, 214564544U, 214695232U, 214826048U,
- 214956992U, 215089088U, 215219776U, 215350592U, 215482304U, 215613248U,
- 215743552U, 215874752U, 216005312U, 216137024U, 216267328U, 216399296U,
- 216530752U, 216661696U, 216790592U, 216923968U, 217054528U, 217183168U,
- 217316672U, 217448128U, 217579072U, 217709504U, 217838912U, 217972672U,
- 218102848U, 218233024U, 218364736U, 218496832U, 218627776U, 218759104U,
- 218888896U, 219021248U, 219151936U, 219281728U, 219413056U, 219545024U,
- 219675968U, 219807296U, 219938624U, 220069312U, 220200128U, 220331456U,
- 220461632U, 220592704U, 220725184U, 220855744U, 220987072U, 221117888U,
- 221249216U, 221378368U, 221510336U, 221642048U, 221772736U, 221904832U,
- 222031808U, 222166976U, 222297536U, 222428992U, 222559936U, 222690368U,
- 222820672U, 222953152U, 223083968U, 223213376U, 223345984U, 223476928U,
- 223608512U, 223738688U, 223869376U, 224001472U, 224132672U, 224262848U,
- 224394944U, 224524864U, 224657344U, 224788288U, 224919488U, 225050432U,
- 225181504U, 225312704U, 225443776U, 225574592U, 225704768U, 225834176U,
- 225966784U, 226097216U, 226229824U, 226360384U, 226491712U, 226623424U,
- 226754368U, 226885312U, 227015104U, 227147456U, 227278528U, 227409472U,
- 227539904U, 227669696U, 227802944U, 227932352U, 228065216U, 228196288U,
- 228326464U, 228457792U, 228588736U, 228720064U, 228850112U, 228981056U,
- 229113152U, 229243328U, 229375936U, 229505344U, 229636928U, 229769152U,
- 229894976U, 230030272U, 230162368U, 230292416U, 230424512U, 230553152U,
- 230684864U, 230816704U, 230948416U, 231079616U, 231210944U, 231342016U,
- 231472448U, 231603776U, 231733952U, 231866176U, 231996736U, 232127296U,
- 232259392U, 232388672U, 232521664U, 232652608U, 232782272U, 232914496U,
- 233043904U, 233175616U, 233306816U, 233438528U, 233569984U, 233699776U,
- 233830592U, 233962688U, 234092224U, 234221888U, 234353984U, 234485312U,
- 234618304U, 234749888U, 234880832U, 235011776U, 235142464U, 235274048U,
- 235403456U, 235535936U, 235667392U, 235797568U, 235928768U, 236057152U,
- 236190272U, 236322752U, 236453312U, 236583616U, 236715712U, 236846528U,
- 236976448U, 237108544U, 237239104U, 237371072U, 237501632U, 237630784U,
- 237764416U, 237895232U, 238026688U, 238157632U, 238286912U, 238419392U,
- 238548032U, 238681024U, 238812608U, 238941632U, 239075008U, 239206336U,
- 239335232U, 239466944U, 239599168U, 239730496U, 239861312U, 239992384U,
- 240122816U, 240254656U, 240385856U, 240516928U, 240647872U, 240779072U,
- 240909632U, 241040704U, 241171904U, 241302848U, 241433408U, 241565248U,
- 241696192U, 241825984U, 241958848U, 242088256U, 242220224U, 242352064U,
- 242481856U, 242611648U, 242744896U, 242876224U, 243005632U, 243138496U,
- 243268672U, 243400384U, 243531712U, 243662656U, 243793856U, 243924544U,
- 244054592U, 244187072U, 244316608U, 244448704U, 244580032U, 244710976U,
- 244841536U, 244972864U, 245104448U, 245233984U, 245365312U, 245497792U,
- 245628736U, 245759936U, 245889856U, 246021056U, 246152512U, 246284224U,
- 246415168U, 246545344U, 246675904U, 246808384U, 246939584U, 247070144U,
- 247199552U, 247331648U, 247463872U, 247593536U, 247726016U, 247857088U,
- 247987648U, 248116928U, 248249536U, 248380736U, 248512064U, 248643008U,
- 248773312U, 248901056U, 249036608U, 249167552U, 249298624U, 249429184U,
- 249560512U, 249692096U, 249822784U, 249954112U, 250085312U, 250215488U,
- 250345792U, 250478528U, 250608704U, 250739264U, 250870976U, 251002816U,
- 251133632U, 251263552U, 251395136U, 251523904U, 251657792U, 251789248U,
- 251919424U, 252051392U, 252182464U, 252313408U, 252444224U, 252575552U,
- 252706624U, 252836032U, 252968512U, 253099712U, 253227584U, 253361728U,
- 253493056U, 253623488U, 253754432U, 253885504U, 254017216U, 254148032U,
- 254279488U, 254410432U, 254541376U, 254672576U, 254803264U, 254933824U,
- 255065792U, 255196736U, 255326528U, 255458752U, 255589952U, 255721408U,
- 255851072U, 255983296U, 256114624U, 256244416U, 256374208U, 256507712U,
- 256636096U, 256768832U, 256900544U, 257031616U, 257162176U, 257294272U,
- 257424448U, 257555776U, 257686976U, 257818432U, 257949632U, 258079552U,
- 258211136U, 258342464U, 258473408U, 258603712U, 258734656U, 258867008U,
- 258996544U, 259127744U, 259260224U, 259391296U, 259522112U, 259651904U,
- 259784384U, 259915328U, 260045888U, 260175424U, 260308544U, 260438336U,
- 260570944U, 260700992U, 260832448U, 260963776U, 261092672U, 261226304U,
- 261356864U, 261487936U, 261619648U, 261750592U, 261879872U, 262011968U,
- 262143424U, 262274752U, 262404416U, 262537024U, 262667968U, 262799296U,
- 262928704U, 263061184U, 263191744U, 263322944U, 263454656U, 263585216U,
- 263716672U, 263847872U, 263978944U, 264108608U, 264241088U, 264371648U,
- 264501184U, 264632768U, 264764096U, 264895936U, 265024576U, 265158464U,
- 265287488U, 265418432U, 265550528U, 265681216U, 265813312U, 265943488U,
- 266075968U, 266206144U, 266337728U, 266468032U, 266600384U, 266731072U,
- 266862272U, 266993344U, 267124288U, 267255616U, 267386432U, 267516992U,
- 267648704U, 267777728U, 267910592U, 268040512U, 268172096U, 268302784U,
- 268435264U, 268566208U, 268696256U, 268828096U, 268959296U, 269090368U,
- 269221312U, 269352256U, 269482688U, 269614784U, 269745856U, 269876416U,
- 270007616U, 270139328U, 270270272U, 270401216U, 270531904U, 270663616U,
- 270791744U, 270924736U, 271056832U, 271186112U, 271317184U, 271449536U,
- 271580992U, 271711936U, 271843136U, 271973056U, 272105408U, 272236352U,
- 272367296U, 272498368U, 272629568U, 272759488U, 272891456U, 273022784U,
- 273153856U, 273284672U, 273415616U, 273547072U, 273677632U, 273808448U,
- 273937088U, 274071488U, 274200896U, 274332992U, 274463296U, 274595392U,
- 274726208U, 274857536U, 274988992U, 275118656U, 275250496U, 275382208U,
- 275513024U, 275643968U, 275775296U, 275906368U, 276037184U, 276167872U,
- 276297664U, 276429376U, 276560576U, 276692672U, 276822976U, 276955072U,
- 277085632U, 277216832U, 277347008U, 277478848U, 277609664U, 277740992U,
- 277868608U, 278002624U, 278134336U, 278265536U, 278395328U, 278526784U,
- 278657728U, 278789824U, 278921152U, 279052096U, 279182912U, 279313088U,
- 279443776U, 279576256U, 279706048U, 279838528U, 279969728U, 280099648U,
- 280230976U, 280361408U, 280493632U, 280622528U, 280755392U, 280887104U,
- 281018176U, 281147968U, 281278912U, 281411392U, 281542592U, 281673152U,
- 281803712U, 281935552U, 282066496U, 282197312U, 282329024U, 282458816U,
- 282590272U, 282720832U, 282853184U, 282983744U, 283115072U, 283246144U,
- 283377344U, 283508416U, 283639744U, 283770304U, 283901504U, 284032576U,
- 284163136U, 284294848U, 284426176U, 284556992U, 284687296U, 284819264U,
- 284950208U, 285081536U
+ 16776896U, 16907456U, 17039296U, 17170112U, 17301056U, 17432512U, 17563072U,
+ 17693888U, 17824192U, 17955904U, 18087488U, 18218176U, 18349504U, 18481088U,
+ 18611392U, 18742336U, 18874304U, 19004224U, 19135936U, 19267264U, 19398208U,
+ 19529408U, 19660096U, 19791424U, 19922752U, 20053952U, 20184896U, 20315968U,
+ 20446912U, 20576576U, 20709184U, 20840384U, 20971072U, 21102272U, 21233216U,
+ 21364544U, 21494848U, 21626816U, 21757376U, 21887552U, 22019392U, 22151104U,
+ 22281536U, 22412224U, 22543936U, 22675264U, 22806464U, 22935872U, 23068096U,
+ 23198272U, 23330752U, 23459008U, 23592512U, 23723968U, 23854912U, 23986112U,
+ 24116672U, 24247616U, 24378688U, 24509504U, 24640832U, 24772544U, 24903488U,
+ 25034432U, 25165376U, 25296704U, 25427392U, 25558592U, 25690048U, 25820096U,
+ 25951936U, 26081728U, 26214208U, 26345024U, 26476096U, 26606656U, 26737472U,
+ 26869184U, 26998208U, 27131584U, 27262528U, 27393728U, 27523904U, 27655744U,
+ 27786688U, 27917888U, 28049344U, 28179904U, 28311488U, 28441792U, 28573504U,
+ 28700864U, 28835648U, 28966208U, 29096768U, 29228608U, 29359808U, 29490752U,
+ 29621824U, 29752256U, 29882816U, 30014912U, 30144448U, 30273728U, 30406976U,
+ 30538432U, 30670784U, 30799936U, 30932672U, 31063744U, 31195072U, 31325248U,
+ 31456192U, 31588288U, 31719232U, 31850432U, 31981504U, 32110784U, 32243392U,
+ 32372672U, 32505664U, 32636608U, 32767808U, 32897344U, 33029824U, 33160768U,
+ 33289664U, 33423296U, 33554368U, 33683648U, 33816512U, 33947456U, 34076992U,
+ 34208704U, 34340032U, 34471744U, 34600256U, 34734016U, 34864576U, 34993984U,
+ 35127104U, 35258176U, 35386688U, 35518528U, 35650624U, 35782336U, 35910976U,
+ 36044608U, 36175808U, 36305728U, 36436672U, 36568384U, 36699968U, 36830656U,
+ 36961984U, 37093312U, 37223488U, 37355072U, 37486528U, 37617472U, 37747904U,
+ 37879232U, 38009792U, 38141888U, 38272448U, 38403392U, 38535104U, 38660672U,
+ 38795584U, 38925632U, 39059264U, 39190336U, 39320768U, 39452096U, 39581632U,
+ 39713984U, 39844928U, 39974848U, 40107968U, 40238144U, 40367168U, 40500032U,
+ 40631744U, 40762816U, 40894144U, 41023552U, 41155904U, 41286208U, 41418304U,
+ 41547712U, 41680448U, 41811904U, 41942848U, 42073792U, 42204992U, 42334912U,
+ 42467008U, 42597824U, 42729152U, 42860096U, 42991552U, 43122368U, 43253696U,
+ 43382848U, 43515712U, 43646912U, 43777088U, 43907648U, 44039104U, 44170432U,
+ 44302144U, 44433344U, 44564288U, 44694976U, 44825152U, 44956864U, 45088448U,
+ 45219008U, 45350464U, 45481024U, 45612608U, 45744064U, 45874496U, 46006208U,
+ 46136768U, 46267712U, 46399424U, 46529344U, 46660672U, 46791488U, 46923328U,
+ 47053504U, 47185856U, 47316928U, 47447872U, 47579072U, 47710144U, 47839936U,
+ 47971648U, 48103232U, 48234176U, 48365248U, 48496192U, 48627136U, 48757312U,
+ 48889664U, 49020736U, 49149248U, 49283008U, 49413824U, 49545152U, 49675712U,
+ 49807168U, 49938368U, 50069056U, 50200256U, 50331584U, 50462656U, 50593472U,
+ 50724032U, 50853952U, 50986048U, 51117632U, 51248576U, 51379904U, 51510848U,
+ 51641792U, 51773248U, 51903296U, 52035136U, 52164032U, 52297664U, 52427968U,
+ 52557376U, 52690112U, 52821952U, 52952896U, 53081536U, 53213504U, 53344576U,
+ 53475776U, 53608384U, 53738816U, 53870528U, 54000832U, 54131776U, 54263744U,
+ 54394688U, 54525248U, 54655936U, 54787904U, 54918592U, 55049152U, 55181248U,
+ 55312064U, 55442752U, 55574336U, 55705024U, 55836224U, 55967168U, 56097856U,
+ 56228672U, 56358592U, 56490176U, 56621888U, 56753728U, 56884928U, 57015488U,
+ 57146816U, 57278272U, 57409216U, 57540416U, 57671104U, 57802432U, 57933632U,
+ 58064576U, 58195264U, 58326976U, 58457408U, 58588864U, 58720192U, 58849984U,
+ 58981696U, 59113024U, 59243456U, 59375552U, 59506624U, 59637568U, 59768512U,
+ 59897792U, 60030016U, 60161984U, 60293056U, 60423872U, 60554432U, 60683968U,
+ 60817216U, 60948032U, 61079488U, 61209664U, 61341376U, 61471936U, 61602752U,
+ 61733696U, 61865792U, 61996736U, 62127808U, 62259136U, 62389568U, 62520512U,
+ 62651584U, 62781632U, 62910784U, 63045056U, 63176128U, 63307072U, 63438656U,
+ 63569216U, 63700928U, 63831616U, 63960896U, 64093888U, 64225088U, 64355392U,
+ 64486976U, 64617664U, 64748608U, 64879424U, 65009216U, 65142464U, 65273792U,
+ 65402816U, 65535424U, 65666752U, 65797696U, 65927744U, 66060224U, 66191296U,
+ 66321344U, 66453056U, 66584384U, 66715328U, 66846656U, 66977728U, 67108672U,
+ 67239104U, 67370432U, 67501888U, 67631296U, 67763776U, 67895104U, 68026304U,
+ 68157248U, 68287936U, 68419264U, 68548288U, 68681408U, 68811968U, 68942912U,
+ 69074624U, 69205568U, 69337024U, 69467584U, 69599168U, 69729472U, 69861184U,
+ 69989824U, 70122944U, 70253888U, 70385344U, 70515904U, 70647232U, 70778816U,
+ 70907968U, 71040832U, 71171648U, 71303104U, 71432512U, 71564992U, 71695168U,
+ 71826368U, 71958464U, 72089536U, 72219712U, 72350144U, 72482624U, 72613568U,
+ 72744512U, 72875584U, 73006144U, 73138112U, 73268672U, 73400128U, 73530944U,
+ 73662272U, 73793344U, 73924544U, 74055104U, 74185792U, 74316992U, 74448832U,
+ 74579392U, 74710976U, 74841664U, 74972864U, 75102784U, 75233344U, 75364544U,
+ 75497024U, 75627584U, 75759296U, 75890624U, 76021696U, 76152256U, 76283072U,
+ 76414144U, 76545856U, 76676672U, 76806976U, 76937792U, 77070016U, 77200832U,
+ 77331392U, 77462464U, 77593664U, 77725376U, 77856448U, 77987776U, 78118336U,
+ 78249664U, 78380992U, 78511424U, 78642496U, 78773056U, 78905152U, 79033664U,
+ 79166656U, 79297472U, 79429568U, 79560512U, 79690816U, 79822784U, 79953472U,
+ 80084672U, 80214208U, 80346944U, 80477632U, 80608576U, 80740288U, 80870848U,
+ 81002048U, 81133504U, 81264448U, 81395648U, 81525952U, 81657536U, 81786304U,
+ 81919808U, 82050112U, 82181312U, 82311616U, 82443968U, 82573376U, 82705984U,
+ 82835776U, 82967744U, 83096768U, 83230528U, 83359552U, 83491264U, 83622464U,
+ 83753536U, 83886016U, 84015296U, 84147776U, 84277184U, 84409792U, 84540608U,
+ 84672064U, 84803008U, 84934336U, 85065152U, 85193792U, 85326784U, 85458496U,
+ 85589312U, 85721024U, 85851968U, 85982656U, 86112448U, 86244416U, 86370112U,
+ 86506688U, 86637632U, 86769344U, 86900672U, 87031744U, 87162304U, 87293632U,
+ 87424576U, 87555392U, 87687104U, 87816896U, 87947968U, 88079168U, 88211264U,
+ 88341824U, 88473152U, 88603712U, 88735424U, 88862912U, 88996672U, 89128384U,
+ 89259712U, 89390272U, 89521984U, 89652544U, 89783872U, 89914816U, 90045376U,
+ 90177088U, 90307904U, 90438848U, 90569152U, 90700096U, 90832832U, 90963776U,
+ 91093696U, 91223744U, 91356992U, 91486784U, 91618496U, 91749824U, 91880384U,
+ 92012224U, 92143552U, 92273344U, 92405696U, 92536768U, 92666432U, 92798912U,
+ 92926016U, 93060544U, 93192128U, 93322816U, 93453632U, 93583936U, 93715136U,
+ 93845056U, 93977792U, 94109504U, 94240448U, 94371776U, 94501184U, 94632896U,
+ 94764224U, 94895552U, 95023424U, 95158208U, 95287744U, 95420224U, 95550016U,
+ 95681216U, 95811904U, 95943872U, 96075328U, 96203584U, 96337856U, 96468544U,
+ 96599744U, 96731072U, 96860992U, 96992576U, 97124288U, 97254848U, 97385536U,
+ 97517248U, 97647808U, 97779392U, 97910464U, 98041408U, 98172608U, 98303168U,
+ 98434496U, 98565568U, 98696768U, 98827328U, 98958784U, 99089728U, 99220928U,
+ 99352384U, 99482816U, 99614272U, 99745472U, 99876416U, 100007104U,
+ 100138048U, 100267072U, 100401088U, 100529984U, 100662592U, 100791872U,
+ 100925248U, 101056064U, 101187392U, 101317952U, 101449408U, 101580608U,
+ 101711296U, 101841728U, 101973824U, 102104896U, 102235712U, 102366016U,
+ 102498112U, 102628672U, 102760384U, 102890432U, 103021888U, 103153472U,
+ 103284032U, 103415744U, 103545152U, 103677248U, 103808576U, 103939648U,
+ 104070976U, 104201792U, 104332736U, 104462528U, 104594752U, 104725952U,
+ 104854592U, 104988608U, 105118912U, 105247808U, 105381184U, 105511232U,
+ 105643072U, 105774784U, 105903296U, 106037056U, 106167872U, 106298944U,
+ 106429504U, 106561472U, 106691392U, 106822592U, 106954304U, 107085376U,
+ 107216576U, 107346368U, 107478464U, 107609792U, 107739712U, 107872192U,
+ 108003136U, 108131392U, 108265408U, 108396224U, 108527168U, 108657344U,
+ 108789568U, 108920384U, 109049792U, 109182272U, 109312576U, 109444928U,
+ 109572928U, 109706944U, 109837888U, 109969088U, 110099648U, 110230976U,
+ 110362432U, 110492992U, 110624704U, 110755264U, 110886208U, 111017408U,
+ 111148864U, 111279296U, 111410752U, 111541952U, 111673024U, 111803456U,
+ 111933632U, 112066496U, 112196416U, 112328512U, 112457792U, 112590784U,
+ 112715968U, 112852672U, 112983616U, 113114944U, 113244224U, 113376448U,
+ 113505472U, 113639104U, 113770304U, 113901376U, 114031552U, 114163264U,
+ 114294592U, 114425536U, 114556864U, 114687424U, 114818624U, 114948544U,
+ 115080512U, 115212224U, 115343296U, 115473472U, 115605184U, 115736128U,
+ 115867072U, 115997248U, 116128576U, 116260288U, 116391488U, 116522944U,
+ 116652992U, 116784704U, 116915648U, 117046208U, 117178304U, 117308608U,
+ 117440192U, 117569728U, 117701824U, 117833024U, 117964096U, 118094656U,
+ 118225984U, 118357312U, 118489024U, 118617536U, 118749632U, 118882112U,
+ 119012416U, 119144384U, 119275328U, 119406016U, 119537344U, 119668672U,
+ 119798464U, 119928896U, 120061376U, 120192832U, 120321728U, 120454336U,
+ 120584512U, 120716608U, 120848192U, 120979136U, 121109056U, 121241408U,
+ 121372352U, 121502912U, 121634752U, 121764416U, 121895744U, 122027072U,
+ 122157632U, 122289088U, 122421184U, 122550592U, 122682944U, 122813888U,
+ 122945344U, 123075776U, 123207488U, 123338048U, 123468736U, 123600704U,
+ 123731264U, 123861952U, 123993664U, 124124608U, 124256192U, 124386368U,
+ 124518208U, 124649024U, 124778048U, 124911296U, 125041088U, 125173696U,
+ 125303744U, 125432896U, 125566912U, 125696576U, 125829056U, 125958592U,
+ 126090304U, 126221248U, 126352832U, 126483776U, 126615232U, 126746432U,
+ 126876608U, 127008704U, 127139392U, 127270336U, 127401152U, 127532224U,
+ 127663552U, 127794752U, 127925696U, 128055232U, 128188096U, 128319424U,
+ 128449856U, 128581312U, 128712256U, 128843584U, 128973632U, 129103808U,
+ 129236288U, 129365696U, 129498944U, 129629888U, 129760832U, 129892288U,
+ 130023104U, 130154048U, 130283968U, 130416448U, 130547008U, 130678336U,
+ 130807616U, 130939456U, 131071552U, 131202112U, 131331776U, 131464384U,
+ 131594048U, 131727296U, 131858368U, 131987392U, 132120256U, 132250816U,
+ 132382528U, 132513728U, 132644672U, 132774976U, 132905792U, 133038016U,
+ 133168832U, 133299392U, 133429312U, 133562048U, 133692992U, 133823296U,
+ 133954624U, 134086336U, 134217152U, 134348608U, 134479808U, 134607296U,
+ 134741056U, 134872384U, 135002944U, 135134144U, 135265472U, 135396544U,
+ 135527872U, 135659072U, 135787712U, 135921472U, 136052416U, 136182848U,
+ 136313792U, 136444864U, 136576448U, 136707904U, 136837952U, 136970048U,
+ 137099584U, 137232064U, 137363392U, 137494208U, 137625536U, 137755712U,
+ 137887424U, 138018368U, 138149824U, 138280256U, 138411584U, 138539584U,
+ 138672832U, 138804928U, 138936128U, 139066688U, 139196864U, 139328704U,
+ 139460032U, 139590208U, 139721024U, 139852864U, 139984576U, 140115776U,
+ 140245696U, 140376512U, 140508352U, 140640064U, 140769856U, 140902336U,
+ 141032768U, 141162688U, 141294016U, 141426496U, 141556544U, 141687488U,
+ 141819584U, 141949888U, 142080448U, 142212544U, 142342336U, 142474432U,
+ 142606144U, 142736192U, 142868288U, 142997824U, 143129408U, 143258944U,
+ 143392448U, 143523136U, 143653696U, 143785024U, 143916992U, 144045632U,
+ 144177856U, 144309184U, 144440768U, 144570688U, 144701888U, 144832448U,
+ 144965056U, 145096384U, 145227584U, 145358656U, 145489856U, 145620928U,
+ 145751488U, 145883072U, 146011456U, 146144704U, 146275264U, 146407232U,
+ 146538176U, 146668736U, 146800448U, 146931392U, 147062336U, 147193664U,
+ 147324224U, 147455936U, 147586624U, 147717056U, 147848768U, 147979456U,
+ 148110784U, 148242368U, 148373312U, 148503232U, 148635584U, 148766144U,
+ 148897088U, 149028416U, 149159488U, 149290688U, 149420224U, 149551552U,
+ 149683136U, 149814976U, 149943616U, 150076352U, 150208064U, 150338624U,
+ 150470464U, 150600256U, 150732224U, 150862784U, 150993088U, 151125952U,
+ 151254976U, 151388096U, 151519168U, 151649728U, 151778752U, 151911104U,
+ 152042944U, 152174144U, 152304704U, 152435648U, 152567488U, 152698816U,
+ 152828992U, 152960576U, 153091648U, 153222976U, 153353792U, 153484096U,
+ 153616192U, 153747008U, 153878336U, 154008256U, 154139968U, 154270912U,
+ 154402624U, 154533824U, 154663616U, 154795712U, 154926272U, 155057984U,
+ 155188928U, 155319872U, 155450816U, 155580608U, 155712064U, 155843392U,
+ 155971136U, 156106688U, 156237376U, 156367424U, 156499264U, 156630976U,
+ 156761536U, 156892352U, 157024064U, 157155008U, 157284416U, 157415872U,
+ 157545536U, 157677248U, 157810496U, 157938112U, 158071744U, 158203328U,
+ 158334656U, 158464832U, 158596288U, 158727616U, 158858048U, 158988992U,
+ 159121216U, 159252416U, 159381568U, 159513152U, 159645632U, 159776192U,
+ 159906496U, 160038464U, 160169536U, 160300352U, 160430656U, 160563008U,
+ 160693952U, 160822208U, 160956352U, 161086784U, 161217344U, 161349184U,
+ 161480512U, 161611456U, 161742272U, 161873216U, 162002752U, 162135872U,
+ 162266432U, 162397888U, 162529216U, 162660032U, 162790976U, 162922048U,
+ 163052096U, 163184576U, 163314752U, 163446592U, 163577408U, 163707968U,
+ 163839296U, 163969984U, 164100928U, 164233024U, 164364224U, 164494912U,
+ 164625856U, 164756672U, 164887616U, 165019072U, 165150016U, 165280064U,
+ 165412672U, 165543104U, 165674944U, 165805888U, 165936832U, 166067648U,
+ 166198336U, 166330048U, 166461248U, 166591552U, 166722496U, 166854208U,
+ 166985408U, 167116736U, 167246656U, 167378368U, 167508416U, 167641024U,
+ 167771584U, 167903168U, 168034112U, 168164032U, 168295744U, 168427456U,
+ 168557632U, 168688448U, 168819136U, 168951616U, 169082176U, 169213504U,
+ 169344832U, 169475648U, 169605952U, 169738048U, 169866304U, 169999552U,
+ 170131264U, 170262464U, 170393536U, 170524352U, 170655424U, 170782016U,
+ 170917696U, 171048896U, 171179072U, 171310784U, 171439936U, 171573184U,
+ 171702976U, 171835072U, 171966272U, 172097216U, 172228288U, 172359232U,
+ 172489664U, 172621376U, 172747712U, 172883264U, 173014208U, 173144512U,
+ 173275072U, 173407424U, 173539136U, 173669696U, 173800768U, 173931712U,
+ 174063424U, 174193472U, 174325696U, 174455744U, 174586816U, 174718912U,
+ 174849728U, 174977728U, 175109696U, 175242688U, 175374272U, 175504832U,
+ 175636288U, 175765696U, 175898432U, 176028992U, 176159936U, 176291264U,
+ 176422592U, 176552512U, 176684864U, 176815424U, 176946496U, 177076544U,
+ 177209152U, 177340096U, 177470528U, 177600704U, 177731648U, 177864256U,
+ 177994816U, 178126528U, 178257472U, 178387648U, 178518464U, 178650176U,
+ 178781888U, 178912064U, 179044288U, 179174848U, 179305024U, 179436736U,
+ 179568448U, 179698496U, 179830208U, 179960512U, 180092608U, 180223808U,
+ 180354752U, 180485696U, 180617152U, 180748096U, 180877504U, 181009984U,
+ 181139264U, 181272512U, 181402688U, 181532608U, 181663168U, 181795136U,
+ 181926592U, 182057536U, 182190016U, 182320192U, 182451904U, 182582336U,
+ 182713792U, 182843072U, 182976064U, 183107264U, 183237056U, 183368384U,
+ 183494848U, 183631424U, 183762752U, 183893824U, 184024768U, 184154816U,
+ 184286656U, 184417984U, 184548928U, 184680128U, 184810816U, 184941248U,
+ 185072704U, 185203904U, 185335616U, 185465408U, 185596352U, 185727296U,
+ 185859904U, 185989696U, 186121664U, 186252992U, 186383552U, 186514112U,
+ 186645952U, 186777152U, 186907328U, 187037504U, 187170112U, 187301824U,
+ 187429184U, 187562048U, 187693504U, 187825472U, 187957184U, 188087104U,
+ 188218304U, 188349376U, 188481344U, 188609728U, 188743616U, 188874304U,
+ 189005248U, 189136448U, 189265088U, 189396544U, 189528128U, 189660992U,
+ 189791936U, 189923264U, 190054208U, 190182848U, 190315072U, 190447424U,
+ 190577984U, 190709312U, 190840768U, 190971328U, 191102656U, 191233472U,
+ 191364032U, 191495872U, 191626816U, 191758016U, 191888192U, 192020288U,
+ 192148928U, 192282176U, 192413504U, 192542528U, 192674752U, 192805952U,
+ 192937792U, 193068608U, 193198912U, 193330496U, 193462208U, 193592384U,
+ 193723456U, 193854272U, 193985984U, 194116672U, 194247232U, 194379712U,
+ 194508352U, 194641856U, 194772544U, 194900672U, 195035072U, 195166016U,
+ 195296704U, 195428032U, 195558592U, 195690304U, 195818176U, 195952576U,
+ 196083392U, 196214336U, 196345792U, 196476736U, 196607552U, 196739008U,
+ 196869952U, 197000768U, 197130688U, 197262784U, 197394368U, 197523904U,
+ 197656384U, 197787584U, 197916608U, 198049472U, 198180544U, 198310208U,
+ 198442432U, 198573632U, 198705088U, 198834368U, 198967232U, 199097792U,
+ 199228352U, 199360192U, 199491392U, 199621696U, 199751744U, 199883968U,
+ 200014016U, 200146624U, 200276672U, 200408128U, 200540096U, 200671168U,
+ 200801984U, 200933312U, 201062464U, 201194944U, 201326144U, 201457472U,
+ 201588544U, 201719744U, 201850816U, 201981632U, 202111552U, 202244032U,
+ 202374464U, 202505152U, 202636352U, 202767808U, 202898368U, 203030336U,
+ 203159872U, 203292608U, 203423296U, 203553472U, 203685824U, 203816896U,
+ 203947712U, 204078272U, 204208192U, 204341056U, 204472256U, 204603328U,
+ 204733888U, 204864448U, 204996544U, 205125568U, 205258304U, 205388864U,
+ 205517632U, 205650112U, 205782208U, 205913536U, 206044736U, 206176192U,
+ 206307008U, 206434496U, 206569024U, 206700224U, 206831168U, 206961856U,
+ 207093056U, 207223616U, 207355328U, 207486784U, 207616832U, 207749056U,
+ 207879104U, 208010048U, 208141888U, 208273216U, 208404032U, 208534336U,
+ 208666048U, 208796864U, 208927424U, 209059264U, 209189824U, 209321792U,
+ 209451584U, 209582656U, 209715136U, 209845568U, 209976896U, 210106432U,
+ 210239296U, 210370112U, 210501568U, 210630976U, 210763712U, 210894272U,
+ 211024832U, 211156672U, 211287616U, 211418176U, 211549376U, 211679296U,
+ 211812032U, 211942592U, 212074432U, 212204864U, 212334016U, 212467648U,
+ 212597824U, 212727616U, 212860352U, 212991424U, 213120832U, 213253952U,
+ 213385024U, 213515584U, 213645632U, 213777728U, 213909184U, 214040128U,
+ 214170688U, 214302656U, 214433728U, 214564544U, 214695232U, 214826048U,
+ 214956992U, 215089088U, 215219776U, 215350592U, 215482304U, 215613248U,
+ 215743552U, 215874752U, 216005312U, 216137024U, 216267328U, 216399296U,
+ 216530752U, 216661696U, 216790592U, 216923968U, 217054528U, 217183168U,
+ 217316672U, 217448128U, 217579072U, 217709504U, 217838912U, 217972672U,
+ 218102848U, 218233024U, 218364736U, 218496832U, 218627776U, 218759104U,
+ 218888896U, 219021248U, 219151936U, 219281728U, 219413056U, 219545024U,
+ 219675968U, 219807296U, 219938624U, 220069312U, 220200128U, 220331456U,
+ 220461632U, 220592704U, 220725184U, 220855744U, 220987072U, 221117888U,
+ 221249216U, 221378368U, 221510336U, 221642048U, 221772736U, 221904832U,
+ 222031808U, 222166976U, 222297536U, 222428992U, 222559936U, 222690368U,
+ 222820672U, 222953152U, 223083968U, 223213376U, 223345984U, 223476928U,
+ 223608512U, 223738688U, 223869376U, 224001472U, 224132672U, 224262848U,
+ 224394944U, 224524864U, 224657344U, 224788288U, 224919488U, 225050432U,
+ 225181504U, 225312704U, 225443776U, 225574592U, 225704768U, 225834176U,
+ 225966784U, 226097216U, 226229824U, 226360384U, 226491712U, 226623424U,
+ 226754368U, 226885312U, 227015104U, 227147456U, 227278528U, 227409472U,
+ 227539904U, 227669696U, 227802944U, 227932352U, 228065216U, 228196288U,
+ 228326464U, 228457792U, 228588736U, 228720064U, 228850112U, 228981056U,
+ 229113152U, 229243328U, 229375936U, 229505344U, 229636928U, 229769152U,
+ 229894976U, 230030272U, 230162368U, 230292416U, 230424512U, 230553152U,
+ 230684864U, 230816704U, 230948416U, 231079616U, 231210944U, 231342016U,
+ 231472448U, 231603776U, 231733952U, 231866176U, 231996736U, 232127296U,
+ 232259392U, 232388672U, 232521664U, 232652608U, 232782272U, 232914496U,
+ 233043904U, 233175616U, 233306816U, 233438528U, 233569984U, 233699776U,
+ 233830592U, 233962688U, 234092224U, 234221888U, 234353984U, 234485312U,
+ 234618304U, 234749888U, 234880832U, 235011776U, 235142464U, 235274048U,
+ 235403456U, 235535936U, 235667392U, 235797568U, 235928768U, 236057152U,
+ 236190272U, 236322752U, 236453312U, 236583616U, 236715712U, 236846528U,
+ 236976448U, 237108544U, 237239104U, 237371072U, 237501632U, 237630784U,
+ 237764416U, 237895232U, 238026688U, 238157632U, 238286912U, 238419392U,
+ 238548032U, 238681024U, 238812608U, 238941632U, 239075008U, 239206336U,
+ 239335232U, 239466944U, 239599168U, 239730496U, 239861312U, 239992384U,
+ 240122816U, 240254656U, 240385856U, 240516928U, 240647872U, 240779072U,
+ 240909632U, 241040704U, 241171904U, 241302848U, 241433408U, 241565248U,
+ 241696192U, 241825984U, 241958848U, 242088256U, 242220224U, 242352064U,
+ 242481856U, 242611648U, 242744896U, 242876224U, 243005632U, 243138496U,
+ 243268672U, 243400384U, 243531712U, 243662656U, 243793856U, 243924544U,
+ 244054592U, 244187072U, 244316608U, 244448704U, 244580032U, 244710976U,
+ 244841536U, 244972864U, 245104448U, 245233984U, 245365312U, 245497792U,
+ 245628736U, 245759936U, 245889856U, 246021056U, 246152512U, 246284224U,
+ 246415168U, 246545344U, 246675904U, 246808384U, 246939584U, 247070144U,
+ 247199552U, 247331648U, 247463872U, 247593536U, 247726016U, 247857088U,
+ 247987648U, 248116928U, 248249536U, 248380736U, 248512064U, 248643008U,
+ 248773312U, 248901056U, 249036608U, 249167552U, 249298624U, 249429184U,
+ 249560512U, 249692096U, 249822784U, 249954112U, 250085312U, 250215488U,
+ 250345792U, 250478528U, 250608704U, 250739264U, 250870976U, 251002816U,
+ 251133632U, 251263552U, 251395136U, 251523904U, 251657792U, 251789248U,
+ 251919424U, 252051392U, 252182464U, 252313408U, 252444224U, 252575552U,
+ 252706624U, 252836032U, 252968512U, 253099712U, 253227584U, 253361728U,
+ 253493056U, 253623488U, 253754432U, 253885504U, 254017216U, 254148032U,
+ 254279488U, 254410432U, 254541376U, 254672576U, 254803264U, 254933824U,
+ 255065792U, 255196736U, 255326528U, 255458752U, 255589952U, 255721408U,
+ 255851072U, 255983296U, 256114624U, 256244416U, 256374208U, 256507712U,
+ 256636096U, 256768832U, 256900544U, 257031616U, 257162176U, 257294272U,
+ 257424448U, 257555776U, 257686976U, 257818432U, 257949632U, 258079552U,
+ 258211136U, 258342464U, 258473408U, 258603712U, 258734656U, 258867008U,
+ 258996544U, 259127744U, 259260224U, 259391296U, 259522112U, 259651904U,
+ 259784384U, 259915328U, 260045888U, 260175424U, 260308544U, 260438336U,
+ 260570944U, 260700992U, 260832448U, 260963776U, 261092672U, 261226304U,
+ 261356864U, 261487936U, 261619648U, 261750592U, 261879872U, 262011968U,
+ 262143424U, 262274752U, 262404416U, 262537024U, 262667968U, 262799296U,
+ 262928704U, 263061184U, 263191744U, 263322944U, 263454656U, 263585216U,
+ 263716672U, 263847872U, 263978944U, 264108608U, 264241088U, 264371648U,
+ 264501184U, 264632768U, 264764096U, 264895936U, 265024576U, 265158464U,
+ 265287488U, 265418432U, 265550528U, 265681216U, 265813312U, 265943488U,
+ 266075968U, 266206144U, 266337728U, 266468032U, 266600384U, 266731072U,
+ 266862272U, 266993344U, 267124288U, 267255616U, 267386432U, 267516992U,
+ 267648704U, 267777728U, 267910592U, 268040512U, 268172096U, 268302784U,
+ 268435264U, 268566208U, 268696256U, 268828096U, 268959296U, 269090368U,
+ 269221312U, 269352256U, 269482688U, 269614784U, 269745856U, 269876416U,
+ 270007616U, 270139328U, 270270272U, 270401216U, 270531904U, 270663616U,
+ 270791744U, 270924736U, 271056832U, 271186112U, 271317184U, 271449536U,
+ 271580992U, 271711936U, 271843136U, 271973056U, 272105408U, 272236352U,
+ 272367296U, 272498368U, 272629568U, 272759488U, 272891456U, 273022784U,
+ 273153856U, 273284672U, 273415616U, 273547072U, 273677632U, 273808448U,
+ 273937088U, 274071488U, 274200896U, 274332992U, 274463296U, 274595392U,
+ 274726208U, 274857536U, 274988992U, 275118656U, 275250496U, 275382208U,
+ 275513024U, 275643968U, 275775296U, 275906368U, 276037184U, 276167872U,
+ 276297664U, 276429376U, 276560576U, 276692672U, 276822976U, 276955072U,
+ 277085632U, 277216832U, 277347008U, 277478848U, 277609664U, 277740992U,
+ 277868608U, 278002624U, 278134336U, 278265536U, 278395328U, 278526784U,
+ 278657728U, 278789824U, 278921152U, 279052096U, 279182912U, 279313088U,
+ 279443776U, 279576256U, 279706048U, 279838528U, 279969728U, 280099648U,
+ 280230976U, 280361408U, 280493632U, 280622528U, 280755392U, 280887104U,
+ 281018176U, 281147968U, 281278912U, 281411392U, 281542592U, 281673152U,
+ 281803712U, 281935552U, 282066496U, 282197312U, 282329024U, 282458816U,
+ 282590272U, 282720832U, 282853184U, 282983744U, 283115072U, 283246144U,
+ 283377344U, 283508416U, 283639744U, 283770304U, 283901504U, 284032576U,
+ 284163136U, 284294848U, 284426176U, 284556992U, 284687296U, 284819264U,
+ 284950208U, 285081536U
};
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/libethash/endian.h b/libethash/endian.h
index 9ca842e47..0ee402d9a 100644
--- a/libethash/endian.h
+++ b/libethash/endian.h
@@ -3,38 +3,6 @@
#include
#include "compiler.h"
-static const uint8_t BitReverseTable256[] =
- {
- 0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0, 0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
- 0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8, 0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
- 0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4, 0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
- 0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC, 0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
- 0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2, 0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
- 0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA, 0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
- 0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6, 0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
- 0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE, 0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
- 0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1, 0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
- 0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9, 0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
- 0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5, 0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
- 0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED, 0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
- 0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3, 0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
- 0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB, 0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
- 0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7, 0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
- 0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
- };
-
-static inline uint32_t bitfn_swap32(uint32_t a) {
- return (BitReverseTable256[a & 0xff] << 24) |
- (BitReverseTable256[(a >> 8) & 0xff] << 16) |
- (BitReverseTable256[(a >> 16) & 0xff] << 8) |
- (BitReverseTable256[(a >> 24) & 0xff]);
-}
-
-static inline uint64_t bitfn_swap64(uint64_t a) {
- return ((uint64_t) bitfn_swap32((uint32_t) (a >> 32))) |
- (((uint64_t) bitfn_swap32((uint32_t) a)) << 32);
-}
-
#if defined(__MINGW32__) || defined(_WIN32)
# define LITTLE_ENDIAN 1234
# define BYTE_ORDER LITTLE_ENDIAN
@@ -53,22 +21,52 @@ static inline uint64_t bitfn_swap64(uint64_t a) {
# define BIG_ENDIAN 1234
# define BYTE_ORDER BIG_ENDIAN
#else
-
# include
+#endif
+#if defined(_WIN32)
+#include
+#define ethash_swap_u32(input_) _byteswap_ulong(input_)
+#define ethash_swap_u64(input_) _byteswap_uint64(input_)
+#elif defined(__APPLE__)
+#include
+#define ethash_swap_u32(input_) OSSwapInt32(input_)
+#define ethash_swap_u64(input_) OSSwapInt64(input_)
+#else // posix
+#include
+#define ethash_swap_u32(input_) __bswap_32(input_)
+#define ethash_swap_u64(input_) __bswap_64(input_)
#endif
#if LITTLE_ENDIAN == BYTE_ORDER
-#define fix_endian32(x) (x)
-#define fix_endian64(x) (x)
+#define fix_endian32(dst_ ,src_) dst_ = src_
+#define fix_endian32_same(val_)
+#define fix_endian64(dst_, src_) dst_ = src_
+#define fix_endian64_same(val_)
+#define fix_endian_arr32(arr_, size_)
+#define fix_endian_arr64(arr_, size_)
#elif BIG_ENDIAN == BYTE_ORDER
-#define fix_endian32(x) bitfn_swap32(x)
-#define fix_endian64(x) bitfn_swap64(x)
+#define fix_endian32(dst_, src_) dst_ = ethash_swap_u32(src_)
+#define fix_endian32_same(val_) val_ = ethash_swap_u32(val_)
+#define fix_endian64(dst_, src_) dst_ = ethash_swap_u64(src_
+#define fix_endian64_same(val_) val_ = ethash_swap_u64(val_)
+#define fix_endian_arr32(arr_, size_) \
+ do { \
+ for (unsigned i_ = 0; i_ < (size_), ++i_) { \
+ arr_[i_] = ethash_swap_u32(arr_[i_]); \
+ } \
+ while (0)
+#define fix_endian_arr64(arr_, size_) \
+ do { \
+ for (unsigned i_ = 0; i_ < (size_), ++i_) { \
+ arr_[i_] = ethash_swap_u64(arr_[i_]); \
+ } \
+ while (0) \
#else
# error "endian not supported"
-#endif // BYTE_ORDER
\ No newline at end of file
+#endif // BYTE_ORDER
diff --git a/libethash/ethash.h b/libethash/ethash.h
index bc62a29cc..0c6a1f9e9 100644
--- a/libethash/ethash.h
+++ b/libethash/ethash.h
@@ -24,7 +24,6 @@
#include
#include
#include
-#include
#include "compiler.h"
#define ETHASH_REVISION 23
@@ -38,101 +37,110 @@
#define ETHASH_DATASET_PARENTS 256
#define ETHASH_CACHE_ROUNDS 3
#define ETHASH_ACCESSES 64
+#define ETHASH_DAG_MAGIC_NUM_SIZE 8
+#define ETHASH_DAG_MAGIC_NUM 0xFEE1DEADBADDCAFE
#ifdef __cplusplus
extern "C" {
#endif
-typedef struct ethash_params {
- uint64_t full_size; // Size of full data set (in bytes, multiple of mix size (128)).
- uint64_t cache_size; // Size of compute cache (in bytes, multiple of node size (64)).
-} ethash_params;
+/// Type of a seedhash/blockhash e.t.c.
+typedef struct ethash_h256 { uint8_t b[32]; } ethash_h256_t;
-typedef struct ethash_return_value {
- uint8_t result[32];
- uint8_t mix_hash[32];
-} ethash_return_value;
-
-uint64_t ethash_get_datasize(const uint32_t block_number);
-uint64_t ethash_get_cachesize(const uint32_t block_number);
-
-// initialize the parameters
-static inline void ethash_params_init(ethash_params *params, const uint32_t block_number) {
- params->full_size = ethash_get_datasize(block_number);
- params->cache_size = ethash_get_cachesize(block_number);
-}
-
-/***********************************
- * OLD API *************************
- ***********************************
- ******************** (deprecated) *
- ***********************************/
+// convenience macro to statically initialize an h256_t
+// usage:
+// ethash_h256_t a = ethash_h256_static_init(1, 2, 3, ... )
+// have to provide all 32 values. If you don't provide all the rest
+// will simply be unitialized (not guranteed to be 0)
+#define ethash_h256_static_init(...) \
+ { {__VA_ARGS__} }
-void ethash_get_seedhash(uint8_t seedhash[32], const uint32_t block_number);
-void ethash_mkcache(void *cache, ethash_params const *params, const uint8_t seed[32]);
-void ethash_light(ethash_return_value *ret, void const *cache, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce);
-void ethash_compute_full_data(void *mem, ethash_params const *params, void const *cache);
-void ethash_full(ethash_return_value *ret, void const *full_mem, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce);
+struct ethash_light;
+typedef struct ethash_light* ethash_light_t;
+struct ethash_full;
+typedef struct ethash_full* ethash_full_t;
+typedef int(*ethash_callback_t)(unsigned);
-/***********************************
- * NEW API *************************
- ***********************************/
-
-// TODO: compute params and seed in ethash_new_light; it should take only block_number
-// TODO: store params in ethash_light_t/ethash_full_t to avoid having to repass into compute/new_full
-
-typedef uint8_t const ethash_seedhash_t[32];
-
-typedef void const* ethash_light_t;
-static inline ethash_light_t ethash_new_light(ethash_params const* params, ethash_seedhash_t seed) {
- void* ret = malloc((size_t)params->cache_size);
- ethash_mkcache(ret, params, seed);
- return ret;
-}
-static inline void ethash_compute_light(ethash_return_value *ret, ethash_light_t light, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) {
- ethash_light(ret, light, params, header_hash, nonce);
-}
-static inline void ethash_delete_light(ethash_light_t light) {
- free((void*)light);
-}
-
-typedef void const* ethash_full_t;
-static inline ethash_full_t ethash_new_full(ethash_params const* params, ethash_light_t light) {
- void* ret = malloc((size_t)params->full_size);
- ethash_compute_full_data(ret, params, light);
- return ret;
-}
-static inline void ethash_prep_full(void *full, ethash_params const *params, void const *cache) {
- ethash_compute_full_data(full, params, cache);
-}
-static inline void ethash_compute_full(ethash_return_value *ret, void const *full, ethash_params const *params, const uint8_t header_hash[32], const uint64_t nonce) {
- ethash_full(ret, full, params, header_hash, nonce);
-}
-
-/// @brief Compare two s256-bit big-endian values.
-/// @returns 1 if @a a is less than or equal to @a b, 0 otherwise.
-/// Both parameters are 256-bit big-endian values.
-static inline int ethash_leq_be256(const uint8_t a[32], const uint8_t b[32]) {
- // Boundary is big endian
- for (int i = 0; i < 32; i++) {
- if (a[i] == b[i])
- continue;
- return a[i] < b[i];
- }
- return 1;
-}
-
-/// Perofrms a cursory check on the validity of the nonce.
-/// @returns 1 if the nonce may possibly be valid for the given header_hash & boundary.
-/// @p boundary equivalent to 2 ^ 256 / block_difficulty, represented as a 256-bit big-endian.
-int ethash_preliminary_check_boundary(
- const uint8_t header_hash[32],
- const uint64_t nonce,
- const uint8_t mix_hash[32],
- const uint8_t boundary[32]);
-
-#define ethash_quick_check_difficulty ethash_preliminary_check_boundary
-#define ethash_check_difficulty ethash_leq_be256
+typedef struct ethash_return_value {
+ ethash_h256_t result;
+ ethash_h256_t mix_hash;
+ bool success;
+} ethash_return_value_t;
+
+/**
+ * Allocate and initialize a new ethash_light handler
+ *
+ * @param block_number The block number for which to create the handler
+ * @return Newly allocated ethash_light handler or NULL in case of
+ * ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
+ */
+ethash_light_t ethash_light_new(uint64_t block_number);
+/**
+ * Frees a previously allocated ethash_light handler
+ * @param light The light handler to free
+ */
+void ethash_light_delete(ethash_light_t light);
+/**
+ * Calculate the light client data
+ *
+ * @param light The light client handler
+ * @param header_hash The header hash to pack into the mix
+ * @param nonce The nonce to pack into the mix
+ * @return an object of ethash_return_value_t holding the return values
+ */
+ethash_return_value_t ethash_light_compute(
+ ethash_light_t light,
+ ethash_h256_t const header_hash,
+ uint64_t nonce
+);
+
+/**
+ * Allocate and initialize a new ethash_full handler
+ *
+ * @param light The light handler containing the cache.
+ * @param callback A callback function with signature of @ref ethash_callback_t
+ * It accepts an unsigned with which a progress of DAG calculation
+ * can be displayed. If all goes well the callback should return 0.
+ * If a non-zero value is returned then DAG generation will stop.
+ * Be advised. A progress value of 100 means that DAG creation is
+ * almost complete and that this function will soon return succesfully.
+ * It does not mean that the function has already had a succesfull return.
+ * @return Newly allocated ethash_full handler or NULL in case of
+ * ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
+ */
+ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback);
+
+/**
+ * Frees a previously allocated ethash_full handler
+ * @param full The light handler to free
+ */
+void ethash_full_delete(ethash_full_t full);
+/**
+ * Calculate the full client data
+ *
+ * @param full The full client handler
+ * @param header_hash The header hash to pack into the mix
+ * @param nonce The nonce to pack into the mix
+ * @return An object of ethash_return_value to hold the return value
+ */
+ethash_return_value_t ethash_full_compute(
+ ethash_full_t full,
+ ethash_h256_t const header_hash,
+ uint64_t nonce
+);
+/**
+ * Get a pointer to the full DAG data
+ */
+void const* ethash_full_dag(ethash_full_t full);
+/**
+ * Get the size of the DAG data
+ */
+uint64_t ethash_full_dag_size(ethash_full_t full);
+
+/**
+ * Calculate the seedhash for a given block number
+ */
+ethash_h256_t ethash_get_seedhash(uint64_t block_number);
#ifdef __cplusplus
}
diff --git a/libethash/fnv.h b/libethash/fnv.h
index edabeaae2..d23c4e247 100644
--- a/libethash/fnv.h
+++ b/libethash/fnv.h
@@ -29,10 +29,11 @@ extern "C" {
#define FNV_PRIME 0x01000193
-static inline uint32_t fnv_hash(const uint32_t x, const uint32_t y) {
- return x*FNV_PRIME ^ y;
+static inline uint32_t fnv_hash(uint32_t const x, uint32_t const y)
+{
+ return x * FNV_PRIME ^ y;
}
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/libethash/internal.c b/libethash/internal.c
index 130ca13c3..e881e0c7b 100644
--- a/libethash/internal.c
+++ b/libethash/internal.c
@@ -8,11 +8,11 @@
ethash 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
+ 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 .
+ along with cpp-ethereum. If not, see .
*/
/** @file internal.c
* @author Tim Hughes
@@ -23,11 +23,15 @@
#include
#include
#include
+#include
+#include
+#include "mmap.h"
#include "ethash.h"
#include "fnv.h"
#include "endian.h"
#include "internal.h"
#include "data_sizes.h"
+#include "io.h"
#ifdef WITH_CRYPTOPP
@@ -37,264 +41,456 @@
#include "sha3.h"
#endif // WITH_CRYPTOPP
-uint64_t ethash_get_datasize(const uint32_t block_number) {
- assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
- return dag_sizes[block_number / ETHASH_EPOCH_LENGTH];
+uint64_t ethash_get_datasize(uint64_t const block_number)
+{
+ assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
+ return dag_sizes[block_number / ETHASH_EPOCH_LENGTH];
}
-uint64_t ethash_get_cachesize(const uint32_t block_number) {
- assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
- return cache_sizes[block_number / ETHASH_EPOCH_LENGTH];
+uint64_t ethash_get_cachesize(uint64_t const block_number)
+{
+ assert(block_number / ETHASH_EPOCH_LENGTH < 2048);
+ return cache_sizes[block_number / ETHASH_EPOCH_LENGTH];
}
// Follows Sergio's "STRICT MEMORY HARD HASHING FUNCTIONS" (2014)
// https://bitslog.files.wordpress.com/2013/12/memohash-v0-3.pdf
// SeqMemoHash(s, R, N)
-void static ethash_compute_cache_nodes(
- node *const nodes,
- ethash_params const *params,
- const uint8_t seed[32]) {
- assert((params->cache_size % sizeof(node)) == 0);
- uint32_t const num_nodes = (uint32_t) (params->cache_size / sizeof(node));
-
- SHA3_512(nodes[0].bytes, seed, 32);
-
- for (unsigned i = 1; i != num_nodes; ++i) {
- SHA3_512(nodes[i].bytes, nodes[i - 1].bytes, 64);
- }
-
- for (unsigned j = 0; j != ETHASH_CACHE_ROUNDS; j++) {
- for (unsigned i = 0; i != num_nodes; i++) {
- uint32_t const idx = nodes[i].words[0] % num_nodes;
- node data;
- data = nodes[(num_nodes - 1 + i) % num_nodes];
- for (unsigned w = 0; w != NODE_WORDS; ++w) {
- data.words[w] ^= nodes[idx].words[w];
- }
- SHA3_512(nodes[i].bytes, data.bytes, sizeof(data));
- }
- }
-
- // now perform endian conversion
-#if BYTE_ORDER != LITTLE_ENDIAN
- for (unsigned w = 0; w != (num_nodes*NODE_WORDS); ++w)
- {
- nodes->words[w] = fix_endian32(nodes->words[w]);
- }
-#endif
-}
-
-void ethash_mkcache(
- void *cache,
- ethash_params const *params,
- const uint8_t seed[32]) {
- node *nodes = (node *) cache;
- ethash_compute_cache_nodes(nodes, params, seed);
+bool static ethash_compute_cache_nodes(
+ node* const nodes,
+ uint64_t cache_size,
+ ethash_h256_t const* seed
+)
+{
+ if (cache_size % sizeof(node) != 0) {
+ return false;
+ }
+ uint32_t const num_nodes = (uint32_t) (cache_size / sizeof(node));
+
+ SHA3_512(nodes[0].bytes, (uint8_t*)seed, 32);
+
+ for (uint32_t i = 1; i != num_nodes; ++i) {
+ SHA3_512(nodes[i].bytes, nodes[i - 1].bytes, 64);
+ }
+
+ for (uint32_t j = 0; j != ETHASH_CACHE_ROUNDS; j++) {
+ for (uint32_t i = 0; i != num_nodes; i++) {
+ uint32_t const idx = nodes[i].words[0] % num_nodes;
+ node data;
+ data = nodes[(num_nodes - 1 + i) % num_nodes];
+ for (uint32_t w = 0; w != NODE_WORDS; ++w) {
+ data.words[w] ^= nodes[idx].words[w];
+ }
+ SHA3_512(nodes[i].bytes, data.bytes, sizeof(data));
+ }
+ }
+
+ // now perform endian conversion
+ fix_endian_arr32(nodes->words, num_nodes * NODE_WORDS);
+ return true;
}
void ethash_calculate_dag_item(
- node *const ret,
- const unsigned node_index,
- const struct ethash_params *params,
- const void *cache) {
-
- uint32_t num_parent_nodes = (uint32_t) (params->cache_size / sizeof(node));
- node const *cache_nodes = (node const *) cache;
- node const *init = &cache_nodes[node_index % num_parent_nodes];
-
- memcpy(ret, init, sizeof(node));
- ret->words[0] ^= node_index;
- SHA3_512(ret->bytes, ret->bytes, sizeof(node));
-
+ node* const ret,
+ uint32_t node_index,
+ ethash_light_t const light
+)
+{
+ uint32_t num_parent_nodes = (uint32_t) (light->cache_size / sizeof(node));
+ node const* cache_nodes = (node const *) light->cache;
+ node const* init = &cache_nodes[node_index % num_parent_nodes];
+ memcpy(ret, init, sizeof(node));
+ ret->words[0] ^= node_index;
+ SHA3_512(ret->bytes, ret->bytes, sizeof(node));
#if defined(_M_X64) && ENABLE_SSE
- __m128i const fnv_prime = _mm_set1_epi32(FNV_PRIME);
- __m128i xmm0 = ret->xmm[0];
- __m128i xmm1 = ret->xmm[1];
- __m128i xmm2 = ret->xmm[2];
- __m128i xmm3 = ret->xmm[3];
+ __m128i const fnv_prime = _mm_set1_epi32(FNV_PRIME);
+ __m128i xmm0 = ret->xmm[0];
+ __m128i xmm1 = ret->xmm[1];
+ __m128i xmm2 = ret->xmm[2];
+ __m128i xmm3 = ret->xmm[3];
#endif
- for (unsigned i = 0; i != ETHASH_DATASET_PARENTS; ++i) {
- uint32_t parent_index = ((node_index ^ i) * FNV_PRIME ^ ret->words[i % NODE_WORDS]) % num_parent_nodes;
- node const *parent = &cache_nodes[parent_index];
+ for (uint32_t i = 0; i != ETHASH_DATASET_PARENTS; ++i) {
+ uint32_t parent_index = fnv_hash(node_index ^ i, ret->words[i % NODE_WORDS]) % num_parent_nodes;
+ node const *parent = &cache_nodes[parent_index];
#if defined(_M_X64) && ENABLE_SSE
- {
- xmm0 = _mm_mullo_epi32(xmm0, fnv_prime);
- xmm1 = _mm_mullo_epi32(xmm1, fnv_prime);
- xmm2 = _mm_mullo_epi32(xmm2, fnv_prime);
- xmm3 = _mm_mullo_epi32(xmm3, fnv_prime);
- xmm0 = _mm_xor_si128(xmm0, parent->xmm[0]);
- xmm1 = _mm_xor_si128(xmm1, parent->xmm[1]);
- xmm2 = _mm_xor_si128(xmm2, parent->xmm[2]);
- xmm3 = _mm_xor_si128(xmm3, parent->xmm[3]);
-
- // have to write to ret as values are used to compute index
- ret->xmm[0] = xmm0;
- ret->xmm[1] = xmm1;
- ret->xmm[2] = xmm2;
- ret->xmm[3] = xmm3;
- }
- #else
- {
- for (unsigned w = 0; w != NODE_WORDS; ++w) {
- ret->words[w] = fnv_hash(ret->words[w], parent->words[w]);
- }
- }
+ {
+ xmm0 = _mm_mullo_epi32(xmm0, fnv_prime);
+ xmm1 = _mm_mullo_epi32(xmm1, fnv_prime);
+ xmm2 = _mm_mullo_epi32(xmm2, fnv_prime);
+ xmm3 = _mm_mullo_epi32(xmm3, fnv_prime);
+ xmm0 = _mm_xor_si128(xmm0, parent->xmm[0]);
+ xmm1 = _mm_xor_si128(xmm1, parent->xmm[1]);
+ xmm2 = _mm_xor_si128(xmm2, parent->xmm[2]);
+ xmm3 = _mm_xor_si128(xmm3, parent->xmm[3]);
+
+ // have to write to ret as values are used to compute index
+ ret->xmm[0] = xmm0;
+ ret->xmm[1] = xmm1;
+ ret->xmm[2] = xmm2;
+ ret->xmm[3] = xmm3;
+ }
+ #else
+ {
+ for (unsigned w = 0; w != NODE_WORDS; ++w) {
+ ret->words[w] = fnv_hash(ret->words[w], parent->words[w]);
+ }
+ }
#endif
- }
-
- SHA3_512(ret->bytes, ret->bytes, sizeof(node));
+ }
+ SHA3_512(ret->bytes, ret->bytes, sizeof(node));
}
-void ethash_compute_full_data(
- void *mem,
- ethash_params const *params,
- void const *cache) {
- assert((params->full_size % (sizeof(uint32_t) * MIX_WORDS)) == 0);
- assert((params->full_size % sizeof(node)) == 0);
- node *full_nodes = mem;
-
- // now compute full nodes
- for (unsigned n = 0; n != (params->full_size / sizeof(node)); ++n) {
- ethash_calculate_dag_item(&(full_nodes[n]), n, params, cache);
- }
+bool ethash_compute_full_data(
+ void* mem,
+ uint64_t full_size,
+ ethash_light_t const light,
+ ethash_callback_t callback
+)
+{
+ if (full_size % (sizeof(uint32_t) * MIX_WORDS) != 0 ||
+ (full_size % sizeof(node)) != 0) {
+ return false;
+ }
+ uint32_t const max_n = (uint32_t)(full_size / sizeof(node));
+ node* full_nodes = mem;
+ double const progress_change = 1.0f / max_n;
+ double progress = 0.0f;
+ // now compute full nodes
+ for (uint32_t n = 0; n != max_n; ++n) {
+ if (callback &&
+ n % (max_n / 100) == 0 &&
+ callback((unsigned int)(ceil(progress * 100.0f))) != 0) {
+
+ return false;
+ }
+ progress += progress_change;
+ ethash_calculate_dag_item(&(full_nodes[n]), n, light);
+ }
+ return true;
}
-static void ethash_hash(
- ethash_return_value *ret,
- node const *full_nodes,
- void const *cache,
- ethash_params const *params,
- const uint8_t header_hash[32],
- const uint64_t nonce) {
-
- assert((params->full_size % MIX_WORDS) == 0);
+static bool ethash_hash(
+ ethash_return_value_t* ret,
+ node const* full_nodes,
+ ethash_light_t const light,
+ uint64_t full_size,
+ ethash_h256_t const header_hash,
+ uint64_t const nonce
+)
+{
+ if (full_size % MIX_WORDS != 0) {
+ return false;
+ }
+
+ // pack hash and nonce together into first 40 bytes of s_mix
+ assert(sizeof(node) * 8 == 512);
+ node s_mix[MIX_NODES + 1];
+ memcpy(s_mix[0].bytes, &header_hash, 32);
+ fix_endian64(s_mix[0].double_words[4], nonce);
+
+ // compute sha3-512 hash and replicate across mix
+ SHA3_512(s_mix->bytes, s_mix->bytes, 40);
+ fix_endian_arr32(s_mix[0].words, 16);
+
+ node* const mix = s_mix + 1;
+ for (uint32_t w = 0; w != MIX_WORDS; ++w) {
+ mix->words[w] = s_mix[0].words[w % NODE_WORDS];
+ }
+
+ unsigned const page_size = sizeof(uint32_t) * MIX_WORDS;
+ unsigned const num_full_pages = (unsigned) (full_size / page_size);
+
+ for (unsigned i = 0; i != ETHASH_ACCESSES; ++i) {
+ uint32_t const index = fnv_hash(s_mix->words[0] ^ i, mix->words[i % MIX_WORDS]) % num_full_pages;
+
+ for (unsigned n = 0; n != MIX_NODES; ++n) {
+ node const* dag_node;
+ if (full_nodes) {
+ dag_node = &full_nodes[MIX_NODES * index + n];
+ } else {
+ node tmp_node;
+ ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, light);
+ dag_node = &tmp_node;
+ }
- // pack hash and nonce together into first 40 bytes of s_mix
- assert(sizeof(node) * 8 == 512);
- node s_mix[MIX_NODES + 1];
- memcpy(s_mix[0].bytes, header_hash, 32);
-
-#if BYTE_ORDER != LITTLE_ENDIAN
- s_mix[0].double_words[4] = fix_endian64(nonce);
-#else
- s_mix[0].double_words[4] = nonce;
+#if defined(_M_X64) && ENABLE_SSE
+ {
+ __m128i fnv_prime = _mm_set1_epi32(FNV_PRIME);
+ __m128i xmm0 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[0]);
+ __m128i xmm1 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[1]);
+ __m128i xmm2 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[2]);
+ __m128i xmm3 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[3]);
+ mix[n].xmm[0] = _mm_xor_si128(xmm0, dag_node->xmm[0]);
+ mix[n].xmm[1] = _mm_xor_si128(xmm1, dag_node->xmm[1]);
+ mix[n].xmm[2] = _mm_xor_si128(xmm2, dag_node->xmm[2]);
+ mix[n].xmm[3] = _mm_xor_si128(xmm3, dag_node->xmm[3]);
+ }
+ #else
+ {
+ for (unsigned w = 0; w != NODE_WORDS; ++w) {
+ mix[n].words[w] = fnv_hash(mix[n].words[w], dag_node->words[w]);
+ }
+ }
#endif
+ }
+
+ }
+
+ // compress mix
+ for (uint32_t w = 0; w != MIX_WORDS; w += 4) {
+ uint32_t reduction = mix->words[w + 0];
+ reduction = reduction * FNV_PRIME ^ mix->words[w + 1];
+ reduction = reduction * FNV_PRIME ^ mix->words[w + 2];
+ reduction = reduction * FNV_PRIME ^ mix->words[w + 3];
+ mix->words[w / 4] = reduction;
+ }
+
+ fix_endian_arr32(mix->words, MIX_WORDS / 4);
+ memcpy(&ret->mix_hash, mix->bytes, 32);
+ // final Keccak hash
+ SHA3_256(&ret->result, s_mix->bytes, 64 + 32); // Keccak-256(s + compressed_mix)
+ return true;
+}
- // compute sha3-512 hash and replicate across mix
- SHA3_512(s_mix->bytes, s_mix->bytes, 40);
-
-#if BYTE_ORDER != LITTLE_ENDIAN
- for (unsigned w = 0; w != 16; ++w) {
- s_mix[0].words[w] = fix_endian32(s_mix[0].words[w]);
- }
-#endif
+void ethash_quick_hash(
+ ethash_h256_t* return_hash,
+ ethash_h256_t const* header_hash,
+ uint64_t const nonce,
+ ethash_h256_t const* mix_hash
+)
+{
+ uint8_t buf[64 + 32];
+ memcpy(buf, header_hash, 32);
+ fix_endian64_same(nonce);
+ memcpy(&(buf[32]), &nonce, 8);
+ SHA3_512(buf, buf, 40);
+ memcpy(&(buf[64]), mix_hash, 32);
+ SHA3_256(return_hash, buf, 64 + 32);
+}
- node *const mix = s_mix + 1;
- for (unsigned w = 0; w != MIX_WORDS; ++w) {
- mix->words[w] = s_mix[0].words[w % NODE_WORDS];
- }
+ethash_h256_t ethash_get_seedhash(uint64_t block_number)
+{
+ ethash_h256_t ret;
+ ethash_h256_reset(&ret);
+ uint64_t const epochs = block_number / ETHASH_EPOCH_LENGTH;
+ for (uint32_t i = 0; i < epochs; ++i)
+ SHA3_256(&ret, (uint8_t*)&ret, 32);
+ return ret;
+}
- unsigned const
- page_size = sizeof(uint32_t) * MIX_WORDS,
- num_full_pages = (unsigned) (params->full_size / page_size);
+bool ethash_quick_check_difficulty(
+ ethash_h256_t const* header_hash,
+ uint64_t const nonce,
+ ethash_h256_t const* mix_hash,
+ ethash_h256_t const* difficulty
+)
+{
+
+ ethash_h256_t return_hash;
+ ethash_quick_hash(&return_hash, header_hash, nonce, mix_hash);
+ return ethash_check_difficulty(&return_hash, difficulty);
+}
+ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed)
+{
+ struct ethash_light *ret;
+ ret = calloc(sizeof(*ret), 1);
+ if (!ret) {
+ return NULL;
+ }
+ ret->cache = malloc((size_t)cache_size);
+ if (!ret->cache) {
+ goto fail_free_light;
+ }
+ node* nodes = (node*)ret->cache;
+ if (!ethash_compute_cache_nodes(nodes, cache_size, seed)) {
+ goto fail_free_cache_mem;
+ }
+ ret->cache_size = cache_size;
+ return ret;
+
+fail_free_cache_mem:
+ free(ret->cache);
+fail_free_light:
+ free(ret);
+ return NULL;
+}
- for (unsigned i = 0; i != ETHASH_ACCESSES; ++i) {
- uint32_t const index = ((s_mix->words[0] ^ i) * FNV_PRIME ^ mix->words[i % MIX_WORDS]) % num_full_pages;
+ethash_light_t ethash_light_new(uint64_t block_number)
+{
+ ethash_h256_t seedhash = ethash_get_seedhash(block_number);
+ ethash_light_t ret;
+ ret = ethash_light_new_internal(ethash_get_cachesize(block_number), &seedhash);
+ ret->block_number = block_number;
+ return ret;
+}
- for (unsigned n = 0; n != MIX_NODES; ++n) {
- const node *dag_node = &full_nodes[MIX_NODES * index + n];
+void ethash_light_delete(ethash_light_t light)
+{
+ if (light->cache) {
+ free(light->cache);
+ }
+ free(light);
+}
- if (!full_nodes) {
- node tmp_node;
- ethash_calculate_dag_item(&tmp_node, index * MIX_NODES + n, params, cache);
- dag_node = &tmp_node;
- }
+ethash_return_value_t ethash_light_compute_internal(
+ ethash_light_t light,
+ uint64_t full_size,
+ ethash_h256_t const header_hash,
+ uint64_t nonce
+)
+{
+ ethash_return_value_t ret;
+ ret.success = true;
+ if (!ethash_hash(&ret, NULL, light, full_size, header_hash, nonce)) {
+ ret.success = false;
+ }
+ return ret;
+}
-#if defined(_M_X64) && ENABLE_SSE
- {
- __m128i fnv_prime = _mm_set1_epi32(FNV_PRIME);
- __m128i xmm0 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[0]);
- __m128i xmm1 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[1]);
- __m128i xmm2 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[2]);
- __m128i xmm3 = _mm_mullo_epi32(fnv_prime, mix[n].xmm[3]);
- mix[n].xmm[0] = _mm_xor_si128(xmm0, dag_node->xmm[0]);
- mix[n].xmm[1] = _mm_xor_si128(xmm1, dag_node->xmm[1]);
- mix[n].xmm[2] = _mm_xor_si128(xmm2, dag_node->xmm[2]);
- mix[n].xmm[3] = _mm_xor_si128(xmm3, dag_node->xmm[3]);
- }
- #else
- {
- for (unsigned w = 0; w != NODE_WORDS; ++w) {
- mix[n].words[w] = fnv_hash(mix[n].words[w], dag_node->words[w]);
- }
- }
-#endif
- }
-
- }
-
- // compress mix
- for (unsigned w = 0; w != MIX_WORDS; w += 4) {
- uint32_t reduction = mix->words[w + 0];
- reduction = reduction * FNV_PRIME ^ mix->words[w + 1];
- reduction = reduction * FNV_PRIME ^ mix->words[w + 2];
- reduction = reduction * FNV_PRIME ^ mix->words[w + 3];
- mix->words[w / 4] = reduction;
- }
-
-#if BYTE_ORDER != LITTLE_ENDIAN
- for (unsigned w = 0; w != MIX_WORDS/4; ++w) {
- mix->words[w] = fix_endian32(mix->words[w]);
- }
-#endif
+ethash_return_value_t ethash_light_compute(
+ ethash_light_t light,
+ ethash_h256_t const header_hash,
+ uint64_t nonce
+)
+{
+ uint64_t full_size = ethash_get_datasize(light->block_number);
+ return ethash_light_compute_internal(light, full_size, header_hash, nonce);
+}
- memcpy(ret->mix_hash, mix->bytes, 32);
- // final Keccak hash
- SHA3_256(ret->result, s_mix->bytes, 64 + 32); // Keccak-256(s + compressed_mix)
+static bool ethash_mmap(struct ethash_full* ret, FILE* f)
+{
+ int fd;
+ char* mmapped_data;
+ ret->file = f;
+ if ((fd = ethash_fileno(ret->file)) == -1) {
+ return false;
+ }
+ mmapped_data= mmap(
+ NULL,
+ (size_t)ret->file_size + ETHASH_DAG_MAGIC_NUM_SIZE,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ fd,
+ 0
+ );
+ if (mmapped_data == MAP_FAILED) {
+ return false;
+ }
+ ret->data = (node*)(mmapped_data + ETHASH_DAG_MAGIC_NUM_SIZE);
+ return true;
}
-void ethash_quick_hash(
- uint8_t return_hash[32],
- const uint8_t header_hash[32],
- const uint64_t nonce,
- const uint8_t mix_hash[32]) {
-
- uint8_t buf[64 + 32];
- memcpy(buf, header_hash, 32);
-#if BYTE_ORDER != LITTLE_ENDIAN
- nonce = fix_endian64(nonce);
-#endif
- memcpy(&(buf[32]), &nonce, 8);
- SHA3_512(buf, buf, 40);
- memcpy(&(buf[64]), mix_hash, 32);
- SHA3_256(return_hash, buf, 64 + 32);
+ethash_full_t ethash_full_new_internal(
+ char const* dirname,
+ ethash_h256_t const seed_hash,
+ uint64_t full_size,
+ ethash_light_t const light,
+ ethash_callback_t callback
+)
+{
+ struct ethash_full* ret;
+ FILE *f = NULL;
+ ret = calloc(sizeof(*ret), 1);
+ if (!ret) {
+ return NULL;
+ }
+ ret->file_size = (size_t)full_size;
+ switch (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, false)) {
+ case ETHASH_IO_FAIL:
+ goto fail_free_full;
+ case ETHASH_IO_MEMO_MATCH:
+ if (!ethash_mmap(ret, f)) {
+ goto fail_close_file;
+ }
+ return ret;
+ case ETHASH_IO_MEMO_SIZE_MISMATCH:
+ // if a DAG of same filename but unexpected size is found, silently force new file creation
+ if (ethash_io_prepare(dirname, seed_hash, &f, (size_t)full_size, true) != ETHASH_IO_MEMO_MISMATCH) {
+ goto fail_free_full;
+ }
+ // fallthrough to the mismatch case here, DO NOT go through match
+ case ETHASH_IO_MEMO_MISMATCH:
+ if (!ethash_mmap(ret, f)) {
+ goto fail_close_file;
+ }
+ break;
+ }
+
+ if (!ethash_compute_full_data(ret->data, full_size, light, callback)) {
+ goto fail_free_full_data;
+ }
+
+ // after the DAG has been filled then we finalize it by writting the magic number at the beginning
+ if (fseek(f, 0, SEEK_SET) != 0) {
+ goto fail_free_full_data;
+ }
+ uint64_t const magic_num = ETHASH_DAG_MAGIC_NUM;
+ if (fwrite(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
+ goto fail_free_full_data;
+ }
+ fflush(f); // make sure the magic number IS there
+ return ret;
+
+fail_free_full_data:
+ // could check that munmap(..) == 0 but even if it did not can't really do anything here
+ munmap(ret->data, (size_t)full_size);
+fail_close_file:
+ fclose(ret->file);
+fail_free_full:
+ free(ret);
+ return NULL;
}
-void ethash_get_seedhash(uint8_t seedhash[32], const uint32_t block_number) {
- memset(seedhash, 0, 32);
- const uint32_t epochs = block_number / ETHASH_EPOCH_LENGTH;
- for (uint32_t i = 0; i < epochs; ++i)
- SHA3_256(seedhash, seedhash, 32);
+ethash_full_t ethash_full_new(ethash_light_t light, ethash_callback_t callback)
+{
+ char strbuf[256];
+ if (!ethash_get_default_dirname(strbuf, 256)) {
+ return NULL;
+ }
+ uint64_t full_size = ethash_get_datasize(light->block_number);
+ ethash_h256_t seedhash = ethash_get_seedhash(light->block_number);
+ return ethash_full_new_internal(strbuf, seedhash, full_size, light, callback);
}
-int ethash_preliminary_check_boundary(
- const uint8_t header_hash[32],
- const uint64_t nonce,
- const uint8_t mix_hash[32],
- const uint8_t difficulty[32]) {
+void ethash_full_delete(ethash_full_t full)
+{
+ // could check that munmap(..) == 0 but even if it did not can't really do anything here
+ munmap(full->data, (size_t)full->file_size);
+ if (full->file) {
+ fclose(full->file);
+ }
+ free(full);
+}
- uint8_t return_hash[32];
- ethash_quick_hash(return_hash, header_hash, nonce, mix_hash);
- return ethash_leq_be256(return_hash, difficulty);
+ethash_return_value_t ethash_full_compute(
+ ethash_full_t full,
+ ethash_h256_t const header_hash,
+ uint64_t nonce
+)
+{
+ ethash_return_value_t ret;
+ ret.success = true;
+ if (!ethash_hash(
+ &ret,
+ (node const*)full->data,
+ NULL,
+ full->file_size,
+ header_hash,
+ nonce)) {
+ ret.success = false;
+ }
+ return ret;
}
-void ethash_full(ethash_return_value *ret, void const *full_mem, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) {
- ethash_hash(ret, (node const *) full_mem, NULL, params, previous_hash, nonce);
+void const* ethash_full_dag(ethash_full_t full)
+{
+ return full->data;
}
-void ethash_light(ethash_return_value *ret, void const *cache, ethash_params const *params, const uint8_t previous_hash[32], const uint64_t nonce) {
- ethash_hash(ret, NULL, cache, params, previous_hash, nonce);
+uint64_t ethash_full_dag_size(ethash_full_t full)
+{
+ return full->file_size;
}
diff --git a/libethash/internal.h b/libethash/internal.h
index dec7e6b13..4e2b695ac 100644
--- a/libethash/internal.h
+++ b/libethash/internal.h
@@ -2,6 +2,7 @@
#include "compiler.h"
#include "endian.h"
#include "ethash.h"
+#include
#define ENABLE_SSE 0
@@ -20,9 +21,9 @@ extern "C" {
#include
typedef union node {
- uint8_t bytes[NODE_WORDS * 4];
- uint32_t words[NODE_WORDS];
- uint64_t double_words[NODE_WORDS / 2];
+ uint8_t bytes[NODE_WORDS * 4];
+ uint32_t words[NODE_WORDS];
+ uint64_t double_words[NODE_WORDS / 2];
#if defined(_M_X64) && ENABLE_SSE
__m128i xmm[NODE_WORDS/4];
@@ -30,18 +31,139 @@ typedef union node {
} node;
+static inline uint8_t ethash_h256_get(ethash_h256_t const* hash, unsigned int i)
+{
+ return hash->b[i];
+}
+
+static inline void ethash_h256_set(ethash_h256_t* hash, unsigned int i, uint8_t v)
+{
+ hash->b[i] = v;
+}
+
+static inline void ethash_h256_reset(ethash_h256_t* hash)
+{
+ memset(hash, 0, 32);
+}
+
+// Returns if hash is less than or equal to difficulty
+static inline bool ethash_check_difficulty(
+ ethash_h256_t const* hash,
+ ethash_h256_t const* difficulty
+)
+{
+ // Difficulty is big endian
+ for (int i = 0; i < 32; i++) {
+ if (ethash_h256_get(hash, i) == ethash_h256_get(difficulty, i)) {
+ continue;
+ }
+ return ethash_h256_get(hash, i) < ethash_h256_get(difficulty, i);
+ }
+ return true;
+}
+
+bool ethash_quick_check_difficulty(
+ ethash_h256_t const* header_hash,
+ uint64_t const nonce,
+ ethash_h256_t const* mix_hash,
+ ethash_h256_t const* difficulty
+);
+
+struct ethash_light {
+ void* cache;
+ uint64_t cache_size;
+ uint64_t block_number;
+};
+
+/**
+ * Allocate and initialize a new ethash_light handler. Internal version
+ *
+ * @param cache_size The size of the cache in bytes
+ * @param seed Block seedhash to be used during the computation of the
+ * cache nodes
+ * @return Newly allocated ethash_light handler or NULL in case of
+ * ERRNOMEM or invalid parameters used for @ref ethash_compute_cache_nodes()
+ */
+ethash_light_t ethash_light_new_internal(uint64_t cache_size, ethash_h256_t const* seed);
+
+/**
+ * Calculate the light client data. Internal version.
+ *
+ * @param light The light client handler
+ * @param full_size The size of the full data in bytes.
+ * @param header_hash The header hash to pack into the mix
+ * @param nonce The nonce to pack into the mix
+ * @return The resulting hash.
+ */
+ethash_return_value_t ethash_light_compute_internal(
+ ethash_light_t light,
+ uint64_t full_size,
+ ethash_h256_t const header_hash,
+ uint64_t nonce
+);
+
+struct ethash_full {
+ FILE* file;
+ uint64_t file_size;
+ node* data;
+};
+
+/**
+ * Allocate and initialize a new ethash_full handler. Internal version.
+ *
+ * @param dirname The directory in which to put the DAG file.
+ * @param seedhash The seed hash of the block. Used in the DAG file naming.
+ * @param full_size The size of the full data in bytes.
+ * @param cache A cache object to use that was allocated with @ref ethash_cache_new().
+ * Iff this function succeeds the ethash_full_t will take memory
+ * memory ownership of the cache and free it at deletion. If
+ * not then the user still has to handle freeing of the cache himself.
+ * @param callback A callback function with signature of @ref ethash_callback_t
+ * It accepts an unsigned with which a progress of DAG calculation
+ * can be displayed. If all goes well the callback should return 0.
+ * If a non-zero value is returned then DAG generation will stop.
+ * @return Newly allocated ethash_full handler or NULL in case of
+ * ERRNOMEM or invalid parameters used for @ref ethash_compute_full_data()
+ */
+ethash_full_t ethash_full_new_internal(
+ char const* dirname,
+ ethash_h256_t const seed_hash,
+ uint64_t full_size,
+ ethash_light_t const light,
+ ethash_callback_t callback
+);
+
void ethash_calculate_dag_item(
- node *const ret,
- const unsigned node_index,
- ethash_params const *params,
- void const *cache
+ node* const ret,
+ uint32_t node_index,
+ ethash_light_t const cache
);
void ethash_quick_hash(
- uint8_t return_hash[32],
- const uint8_t header_hash[32],
- const uint64_t nonce,
- const uint8_t mix_hash[32]);
+ ethash_h256_t* return_hash,
+ ethash_h256_t const* header_hash,
+ const uint64_t nonce,
+ ethash_h256_t const* mix_hash
+);
+
+uint64_t ethash_get_datasize(uint64_t const block_number);
+uint64_t ethash_get_cachesize(uint64_t const block_number);
+
+/**
+ * Compute the memory data for a full node's memory
+ *
+ * @param mem A pointer to an ethash full's memory
+ * @param full_size The size of the full data in bytes
+ * @param cache A cache object to use in the calculation
+ * @param callback The callback function. Check @ref ethash_full_new() for details.
+ * @return true if all went fine and false for invalid parameters
+ */
+bool ethash_compute_full_data(
+ void* mem,
+ uint64_t full_size,
+ ethash_light_t const light,
+ ethash_callback_t callback
+);
#ifdef __cplusplus
}
diff --git a/libethash/io.c b/libethash/io.c
index 07387caaf..5b4e7da2b 100644
--- a/libethash/io.c
+++ b/libethash/io.c
@@ -22,68 +22,81 @@
#include
#include
-// silly macro to save some typing
-#define PASS_ARR(c_) (c_), sizeof(c_)
-
-static bool ethash_io_write_file(char const *dirname,
- char const* filename,
- size_t filename_length,
- void const* data,
- size_t data_size)
-{
- bool ret = false;
- char *fullname = ethash_io_create_filename(dirname, filename, filename_length);
- if (!fullname) {
- return false;
- }
- FILE *f = fopen(fullname, "wb");
- if (!f) {
- goto free_name;
- }
- if (data_size != fwrite(data, 1, data_size, f)) {
- goto close;
- }
-
- ret = true;
-close:
- fclose(f);
-free_name:
- free(fullname);
- return ret;
-}
-
-bool ethash_io_write(char const *dirname,
- ethash_params const* params,
- ethash_blockhash_t seedhash,
- void const* cache,
- uint8_t **data,
- size_t *data_size)
+enum ethash_io_rc ethash_io_prepare(
+ char const* dirname,
+ ethash_h256_t const seedhash,
+ FILE** output_file,
+ uint64_t file_size,
+ bool force_create
+)
{
- char info_buffer[DAG_MEMO_BYTESIZE];
- // allocate the bytes
- uint8_t *temp_data_ptr = malloc((size_t)params->full_size);
- if (!temp_data_ptr) {
- goto end;
- }
- ethash_compute_full_data(temp_data_ptr, params, cache);
+ char mutable_name[DAG_MUTABLE_NAME_MAX_SIZE];
+ enum ethash_io_rc ret = ETHASH_IO_FAIL;
- if (!ethash_io_write_file(dirname, PASS_ARR(DAG_FILE_NAME), temp_data_ptr, (size_t)params->full_size)) {
- goto fail_free;
- }
+ // assert directory exists
+ if (!ethash_mkdir(dirname)) {
+ goto end;
+ }
- ethash_io_serialize_info(ETHASH_REVISION, seedhash, info_buffer);
- if (!ethash_io_write_file(dirname, PASS_ARR(DAG_MEMO_NAME), info_buffer, DAG_MEMO_BYTESIZE)) {
- goto fail_free;
- }
+ ethash_io_mutable_name(ETHASH_REVISION, &seedhash, mutable_name);
+ char* tmpfile = ethash_io_create_filename(dirname, mutable_name, strlen(mutable_name));
+ if (!tmpfile) {
+ goto end;
+ }
- *data = temp_data_ptr;
- *data_size = (size_t)params->full_size;
- return true;
+ FILE *f;
+ if (!force_create) {
+ // try to open the file
+ f = ethash_fopen(tmpfile, "rb+");
+ if (f) {
+ size_t found_size;
+ if (!ethash_file_size(f, &found_size)) {
+ fclose(f);
+ goto free_memo;
+ }
+ if (file_size != found_size - ETHASH_DAG_MAGIC_NUM_SIZE) {
+ fclose(f);
+ ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
+ goto free_memo;
+ }
+ // compare the magic number, no need to care about endianess since it's local
+ uint64_t magic_num;
+ if (fread(&magic_num, ETHASH_DAG_MAGIC_NUM_SIZE, 1, f) != 1) {
+ // I/O error
+ fclose(f);
+ ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
+ goto free_memo;
+ }
+ if (magic_num != ETHASH_DAG_MAGIC_NUM) {
+ fclose(f);
+ ret = ETHASH_IO_MEMO_SIZE_MISMATCH;
+ goto free_memo;
+ }
+ ret = ETHASH_IO_MEMO_MATCH;
+ goto set_file;
+ }
+ }
+
+ // file does not exist, will need to be created
+ f = ethash_fopen(tmpfile, "wb+");
+ if (!f) {
+ goto free_memo;
+ }
+ // make sure it's of the proper size
+ if (fseek(f, (long int)(file_size + ETHASH_DAG_MAGIC_NUM_SIZE - 1), SEEK_SET) != 0) {
+ fclose(f);
+ goto free_memo;
+ }
+ fputc('\n', f);
+ fflush(f);
+ ret = ETHASH_IO_MEMO_MISMATCH;
+ goto set_file;
-fail_free:
- free(temp_data_ptr);
+ ret = ETHASH_IO_MEMO_MATCH;
+set_file:
+ *output_file = f;
+free_memo:
+ free(tmpfile);
end:
- return false;
+ return ret;
}
-
-#undef PASS_ARR
diff --git a/libethash/io.h b/libethash/io.h
index 0fa292362..05aa5ed37 100644
--- a/libethash/io.h
+++ b/libethash/io.h
@@ -22,94 +22,163 @@
#include
#include
#include
+#include
+#ifdef __cplusplus
+#define __STDC_FORMAT_MACROS 1
+#endif
+#include
+#include "endian.h"
#include "ethash.h"
#ifdef __cplusplus
extern "C" {
#endif
-
-typedef struct ethash_blockhash { uint8_t b[32]; } ethash_blockhash_t;
-
-static const char DAG_FILE_NAME[] = "full";
-static const char DAG_MEMO_NAME[] = "full.info";
-// MSVC thinks that "static const unsigned int" is not a compile time variable. Sorry for the #define :(
-#define DAG_MEMO_BYTESIZE 36
-
+// Maximum size for mutable part of DAG file name
+// 6 is for "full-R", the suffix of the filename
+// 10 is for maximum number of digits of a uint32_t (for REVISION)
+// 1 is for - and 16 is for the first 16 hex digits for first 8 bytes of
+// the seedhash and last 1 is for the null terminating character
+// Reference: https://github.com/ethereum/wiki/wiki/Ethash-DAG
+#define DAG_MUTABLE_NAME_MAX_SIZE (6 + 10 + 1 + 16 + 1)
/// Possible return values of @see ethash_io_prepare
enum ethash_io_rc {
- ETHASH_IO_FAIL = 0, ///< There has been an IO failure
- ETHASH_IO_MEMO_MISMATCH, ///< Memo file either did not exist or there was content mismatch
- ETHASH_IO_MEMO_MATCH, ///< Memo file existed and contents matched. No need to do anything
+ ETHASH_IO_FAIL = 0, ///< There has been an IO failure
+ ETHASH_IO_MEMO_SIZE_MISMATCH, ///< DAG with revision/hash match, but file size was wrong.
+ ETHASH_IO_MEMO_MISMATCH, ///< The DAG file did not exist or there was revision/hash mismatch
+ ETHASH_IO_MEMO_MATCH, ///< DAG file existed and revision/hash matched. No need to do anything
};
+// small hack for windows. I don't feel I should use va_args and forward just
+// to have this one function properly cross-platform abstracted
+#if defined(_WIN32) && !defined(__GNUC__)
+#define snprintf(...) sprintf_s(__VA_ARGS__)
+#endif
+
/**
* Prepares io for ethash
*
- * Create the DAG directory if it does not exist, and check if the memo file matches.
- * If it does not match then it's deleted to pave the way for @ref ethash_io_write()
+ * Create the DAG directory and the DAG file if they don't exist.
*
- * @param dirname A null terminated c-string of the path of the ethash
- * data directory. If it does not exist it's created.
- * @param seedhash The seedhash of the current block number
- * @return For possible return values @see enum ethash_io_rc
+ * @param[in] dirname A null terminated c-string of the path of the ethash
+ * data directory. If it does not exist it's created.
+ * @param[in] seedhash The seedhash of the current block number, used in the
+ * naming of the file as can be seen from the spec at:
+ * https://github.com/ethereum/wiki/wiki/Ethash-DAG
+ * @param[out] output_file If there was no failure then this will point to an open
+ * file descriptor. User is responsible for closing it.
+ * In the case of memo match then the file is open on read
+ * mode, while on the case of mismatch a new file is created
+ * on write mode
+ * @param[in] file_size The size that the DAG file should have on disk
+ * @param[out] force_create If true then there is no check to see if the file
+ * already exists
+ * @return For possible return values @see enum ethash_io_rc
*/
-enum ethash_io_rc ethash_io_prepare(char const *dirname, ethash_blockhash_t seedhash);
+enum ethash_io_rc ethash_io_prepare(
+ char const* dirname,
+ ethash_h256_t const seedhash,
+ FILE** output_file,
+ uint64_t file_size,
+ bool force_create
+);
+
/**
- * Fully computes data and writes it to the file on disk.
+ * An fopen wrapper for no-warnings crossplatform fopen.
*
- * This function should be called after @see ethash_io_prepare() and only if
- * its return value is @c ETHASH_IO_MEMO_MISMATCH. Will write both the full data
- * and the memo file.
+ * Msvc compiler considers fopen to be insecure and suggests to use their
+ * alternative. This is a wrapper for this alternative. Another way is to
+ * #define _CRT_SECURE_NO_WARNINGS, but disabling all security warnings does
+ * not sound like a good idea.
*
- * @param[in] dirname A null terminated c-string of the path of the ethash
- * data directory. Has to exist.
- * @param[in] params An ethash_params object containing the full size
- * and the cache size
- * @param[in] seedhash The seedhash of the current block number
- * @param[in] cache The cache data. Would have usually been calulated by
- * @see ethash_prep_light().
- * @param[out] data Pass a pointer to uint8_t by reference here. If the
- * function is succesfull then this point to the allocated
- * data calculated by @see ethash_prep_full(). Memory
- * ownership is transfered to the callee. Remember that
- * you eventually need to free this with a call to free().
- * @param[out] data_size Pass a size_t by value. If the function is succesfull
- * then this will contain the number of bytes allocated
- * for @a data.
- * @return True for success and false in case of failure.
+ * @param file_name The path to the file to open
+ * @param mode Opening mode. Check fopen()
+ * @return The FILE* or NULL in failure
*/
-bool ethash_io_write(char const *dirname,
- ethash_params const* params,
- ethash_blockhash_t seedhash,
- void const* cache,
- uint8_t **data,
- size_t *data_size);
+FILE* ethash_fopen(char const* file_name, char const* mode);
-static inline void ethash_io_serialize_info(uint32_t revision,
- ethash_blockhash_t seed_hash,
- char *output)
-{
- // if .info is only consumed locally we don't really care about endianess
- memcpy(output, &revision, 4);
- memcpy(output + 4, &seed_hash, 32);
-}
+/**
+ * An strncat wrapper for no-warnings crossplatform strncat.
+ *
+ * Msvc compiler considers strncat to be insecure and suggests to use their
+ * alternative. This is a wrapper for this alternative. Another way is to
+ * #define _CRT_SECURE_NO_WARNINGS, but disabling all security warnings does
+ * not sound like a good idea.
+ *
+ * @param des Destination buffer
+ * @param dest_size Maximum size of the destination buffer. This is the
+ * extra argument for the MSVC secure strncat
+ * @param src Souce buffer
+ * @param count Number of bytes to copy from source
+ * @return If all is well returns the dest buffer. If there is an
+ * error returns NULL
+ */
+char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count);
-static inline char *ethash_io_create_filename(char const *dirname,
- char const* filename,
- size_t filename_length)
-{
- // in C the cast is not needed, but a C++ compiler will complain for invalid conversion
- char *name = (char*)malloc(strlen(dirname) + filename_length);
- if (!name) {
- return NULL;
- }
+/**
+ * A cross-platform mkdir wrapper to create a directory or assert it's there
+ *
+ * @param dirname The full path of the directory to create
+ * @return true if the directory was created or if it already
+ * existed
+ */
+bool ethash_mkdir(char const* dirname);
- name[0] = '\0';
- strcat(name, dirname);
- strcat(name, filename);
- return name;
-}
+/**
+ * Get a file's size
+ *
+ * @param[in] f The open file stream whose size to get
+ * @param[out] size Pass a size_t by reference to contain the file size
+ * @return true in success and false if there was a failure
+ */
+bool ethash_file_size(FILE* f, size_t* ret_size);
+
+/**
+ * Get a file descriptor number from a FILE stream
+ *
+ * @param f The file stream whose fd to get
+ * @return Platform specific fd handler
+ */
+int ethash_fileno(FILE* f);
+
+/**
+ * Create the filename for the DAG.
+ *
+ * @param dirname The directory name in which the DAG file should reside
+ * If it does not end with a directory separator it is appended.
+ * @param filename The actual name of the file
+ * @param filename_length The length of the filename in bytes
+ * @return A char* containing the full name. User must deallocate.
+ */
+char* ethash_io_create_filename(
+ char const* dirname,
+ char const* filename,
+ size_t filename_length
+);
+
+/**
+ * Gets the default directory name for the DAG depending on the system
+ *
+ * The spec defining this directory is here: https://github.com/ethereum/wiki/wiki/Ethash-DAG
+ *
+ * @param[out] strbuf A string buffer of sufficient size to keep the
+ * null termninated string of the directory name
+ * @param[in] buffsize Size of @a strbuf in bytes
+ * @return true for success and false otherwise
+ */
+bool ethash_get_default_dirname(char* strbuf, size_t buffsize);
+static inline bool ethash_io_mutable_name(
+ uint32_t revision,
+ ethash_h256_t const* seed_hash,
+ char* output
+)
+{
+ uint64_t hash = *((uint64_t*)seed_hash);
+#if LITTLE_ENDIAN == BYTE_ORDER
+ hash = ethash_swap_u64(hash);
+#endif
+ return snprintf(output, DAG_MUTABLE_NAME_MAX_SIZE, "full-R%u-%016" PRIx64, revision, hash) >= 0;
+}
#ifdef __cplusplus
}
diff --git a/libethash/io_posix.c b/libethash/io_posix.c
index 9d9ccac69..7f03d5482 100644
--- a/libethash/io_posix.c
+++ b/libethash/io_posix.c
@@ -27,50 +27,76 @@
#include
#include
-enum ethash_io_rc ethash_io_prepare(char const *dirname, ethash_blockhash_t seedhash)
+FILE* ethash_fopen(char const* file_name, char const* mode)
{
- char read_buffer[DAG_MEMO_BYTESIZE];
- char expect_buffer[DAG_MEMO_BYTESIZE];
- enum ethash_io_rc ret = ETHASH_IO_FAIL;
+ return fopen(file_name, mode);
+}
- // assert directory exists, full owner permissions and read/search for others
- int rc = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
- if (rc == -1 && errno != EEXIST) {
- goto end;
- }
+char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count)
+{
+ return strlen(dest) + count + 1 <= dest_size ? strncat(dest, src, count) : NULL;
+}
- char *memofile = ethash_io_create_filename(dirname, DAG_MEMO_NAME, sizeof(DAG_MEMO_NAME));
- if (!memofile) {
- goto end;
- }
+bool ethash_mkdir(char const* dirname)
+{
+ int rc = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
+ return rc != -1 || errno == EEXIST;
+}
- // try to open memo file
- FILE *f = fopen(memofile, "rb");
- if (!f) {
- // file does not exist, so no checking happens. All is fine.
- ret = ETHASH_IO_MEMO_MISMATCH;
- goto free_memo;
- }
+int ethash_fileno(FILE *f)
+{
+ return fileno(f);
+}
- if (fread(read_buffer, 1, DAG_MEMO_BYTESIZE, f) != DAG_MEMO_BYTESIZE) {
- goto close;
- }
+char* ethash_io_create_filename(
+ char const* dirname,
+ char const* filename,
+ size_t filename_length
+)
+{
+ size_t dirlen = strlen(dirname);
+ size_t dest_size = dirlen + filename_length + 1;
+ if (dirname[dirlen] != '/') {
+ dest_size += 1;
+ }
+ char* name = malloc(dest_size);
+ if (!name) {
+ return NULL;
+ }
- ethash_io_serialize_info(ETHASH_REVISION, seedhash, expect_buffer);
- if (memcmp(read_buffer, expect_buffer, DAG_MEMO_BYTESIZE) != 0) {
- // we have different memo contents so delete the memo file
- if (unlink(memofile) != 0) {
- goto close;
- }
- ret = ETHASH_IO_MEMO_MISMATCH;
- }
+ name[0] = '\0';
+ ethash_strncat(name, dest_size, dirname, dirlen);
+ if (dirname[dirlen] != '/') {
+ ethash_strncat(name, dest_size, "/", 1);
+ }
+ ethash_strncat(name, dest_size, filename, filename_length);
+ return name;
+}
- ret = ETHASH_IO_MEMO_MATCH;
+bool ethash_file_size(FILE* f, size_t* ret_size)
+{
+ struct stat st;
+ int fd;
+ if ((fd = fileno(f)) == -1 || fstat(fd, &st) != 0) {
+ return false;
+ }
+ *ret_size = st.st_size;
+ return true;
+}
-close:
- fclose(f);
-free_memo:
- free(memofile);
-end:
- return ret;
+bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
+{
+ static const char dir_suffix[] = ".ethash/";
+ strbuf[0] = '\0';
+ char* home_dir = getenv("HOME");
+ size_t len = strlen(home_dir);
+ if (!ethash_strncat(strbuf, buffsize, home_dir, len)) {
+ return false;
+ }
+ if (home_dir[len] != '/') {
+ if (!ethash_strncat(strbuf, buffsize, "/", 1)) {
+ return false;
+ }
+ }
+ return ethash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix));
}
diff --git a/libethash/io_win32.c b/libethash/io_win32.c
index 77367fdd9..2e6c8deb8 100644
--- a/libethash/io_win32.c
+++ b/libethash/io_win32.c
@@ -23,51 +23,78 @@
#include
#include
#include
+#include
+#include
+#include
-enum ethash_io_rc ethash_io_prepare(char const *dirname, ethash_blockhash_t seedhash)
+FILE* ethash_fopen(char const* file_name, char const* mode)
{
- char read_buffer[DAG_MEMO_BYTESIZE];
- char expect_buffer[DAG_MEMO_BYTESIZE];
- enum ethash_io_rc ret = ETHASH_IO_FAIL;
+ FILE* f;
+ return fopen_s(&f, file_name, mode) == 0 ? f : NULL;
+}
- // assert directory exists
- int rc = _mkdir(dirname);
- if (rc == -1 && errno != EEXIST) {
- goto end;
- }
+char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count)
+{
+ return strncat_s(dest, dest_size, src, count) == 0 ? dest : NULL;
+}
- char *memofile = ethash_io_create_filename(dirname, DAG_MEMO_NAME, sizeof(DAG_MEMO_NAME));
- if (!memofile) {
- goto end;
- }
+bool ethash_mkdir(char const* dirname)
+{
+ int rc = _mkdir(dirname);
+ return rc != -1 || errno == EEXIST;
+}
- // try to open memo file
- FILE *f = fopen(memofile, "rb");
- if (!f) {
- // file does not exist, so no checking happens. All is fine.
- ret = ETHASH_IO_MEMO_MISMATCH;
- goto free_memo;
- }
+int ethash_fileno(FILE* f)
+{
+ return _fileno(f);
+}
- if (fread(read_buffer, 1, DAG_MEMO_BYTESIZE, f) != DAG_MEMO_BYTESIZE) {
- goto close;
- }
+char* ethash_io_create_filename(
+ char const* dirname,
+ char const* filename,
+ size_t filename_length
+)
+{
+ size_t dirlen = strlen(dirname);
+ size_t dest_size = dirlen + filename_length + 1;
+ if (dirname[dirlen] != '\\' || dirname[dirlen] != '/') {
+ dest_size += 1;
+ }
+ char* name = malloc(dest_size);
+ if (!name) {
+ return NULL;
+ }
+
+ name[0] = '\0';
+ ethash_strncat(name, dest_size, dirname, dirlen);
+ if (dirname[dirlen] != '\\' || dirname[dirlen] != '/') {
+ ethash_strncat(name, dest_size, "\\", 1);
+ }
+ ethash_strncat(name, dest_size, filename, filename_length);
+ return name;
+}
- ethash_io_serialize_info(ETHASH_REVISION, seedhash, expect_buffer);
- if (memcmp(read_buffer, expect_buffer, DAG_MEMO_BYTESIZE) != 0) {
- // we have different memo contents so delete the memo file
- if (_unlink(memofile) != 0) {
- goto close;
- }
- ret = ETHASH_IO_MEMO_MISMATCH;
- }
+bool ethash_file_size(FILE* f, size_t* ret_size)
+{
+ struct _stat st;
+ int fd;
+ if ((fd = _fileno(f)) == -1 || _fstat(fd, &st) != 0) {
+ return false;
+ }
+ *ret_size = st.st_size;
+ return true;
+}
- ret = ETHASH_IO_MEMO_MATCH;
+bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
+{
+ static const char dir_suffix[] = "Appdata\\Ethash\\";
+ strbuf[0] = '\0';
+ if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_PROFILE, NULL, 0, (WCHAR*)strbuf))) {
+ return false;
+ }
+ if (!ethash_strncat(strbuf, buffsize, "\\", 1)) {
+ return false;
+ }
-close:
- fclose(f);
-free_memo:
- free(memofile);
-end:
- return ret;
+ return ethash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix));
}
diff --git a/libethash/mmap.h b/libethash/mmap.h
new file mode 100644
index 000000000..1e226e83f
--- /dev/null
+++ b/libethash/mmap.h
@@ -0,0 +1,47 @@
+/*
+ This file is part of ethash.
+
+ ethash 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.
+
+ ethash 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 ethash. If not, see .
+*/
+/** @file mmap.h
+ * @author Lefteris Karapetsas
+ * @date 2015
+ */
+#pragma once
+#if defined(__MINGW32__) || defined(_WIN32)
+#include
+
+#define PROT_READ 0x1
+#define PROT_WRITE 0x2
+/* This flag is only available in WinXP+ */
+#ifdef FILE_MAP_EXECUTE
+#define PROT_EXEC 0x4
+#else
+#define PROT_EXEC 0x0
+#define FILE_MAP_EXECUTE 0
+#endif
+
+#define MAP_SHARED 0x01
+#define MAP_PRIVATE 0x02
+#define MAP_ANONYMOUS 0x20
+#define MAP_ANON MAP_ANONYMOUS
+#define MAP_FAILED ((void *) -1)
+
+void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset);
+void munmap(void* addr, size_t length);
+#else // posix, yay! ^_^
+#include
+#endif
+
+
diff --git a/libethash/mmap_win32.c b/libethash/mmap_win32.c
new file mode 100644
index 000000000..42968b98a
--- /dev/null
+++ b/libethash/mmap_win32.c
@@ -0,0 +1,84 @@
+/* mmap() replacement for Windows
+ *
+ * Author: Mike Frysinger
+ * Placed into the public domain
+ */
+
+/* References:
+ * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
+ * CloseHandle: http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
+ * MapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
+ * UnmapViewOfFile: http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
+ */
+
+#include
+#include
+#include "mmap.h"
+
+#ifdef __USE_FILE_OFFSET64
+# define DWORD_HI(x) (x >> 32)
+# define DWORD_LO(x) ((x) & 0xffffffff)
+#else
+# define DWORD_HI(x) (0)
+# define DWORD_LO(x) (x)
+#endif
+
+void* mmap(void* start, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
+ return MAP_FAILED;
+ if (fd == -1) {
+ if (!(flags & MAP_ANON) || offset)
+ return MAP_FAILED;
+ } else if (flags & MAP_ANON)
+ return MAP_FAILED;
+
+ DWORD flProtect;
+ if (prot & PROT_WRITE) {
+ if (prot & PROT_EXEC)
+ flProtect = PAGE_EXECUTE_READWRITE;
+ else
+ flProtect = PAGE_READWRITE;
+ } else if (prot & PROT_EXEC) {
+ if (prot & PROT_READ)
+ flProtect = PAGE_EXECUTE_READ;
+ else if (prot & PROT_EXEC)
+ flProtect = PAGE_EXECUTE;
+ } else
+ flProtect = PAGE_READONLY;
+
+ off_t end = length + offset;
+ HANDLE mmap_fd, h;
+ if (fd == -1)
+ mmap_fd = INVALID_HANDLE_VALUE;
+ else
+ mmap_fd = (HANDLE)_get_osfhandle(fd);
+ h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
+ if (h == NULL)
+ return MAP_FAILED;
+
+ DWORD dwDesiredAccess;
+ if (prot & PROT_WRITE)
+ dwDesiredAccess = FILE_MAP_WRITE;
+ else
+ dwDesiredAccess = FILE_MAP_READ;
+ if (prot & PROT_EXEC)
+ dwDesiredAccess |= FILE_MAP_EXECUTE;
+ if (flags & MAP_PRIVATE)
+ dwDesiredAccess |= FILE_MAP_COPY;
+ void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
+ if (ret == NULL) {
+ ret = MAP_FAILED;
+ }
+ // since we are handling the file ourselves with fd, close the Windows Handle here
+ CloseHandle(h);
+ return ret;
+}
+
+void munmap(void* addr, size_t length)
+{
+ UnmapViewOfFile(addr);
+}
+
+#undef DWORD_HI
+#undef DWORD_LO
diff --git a/libethash/sha3.c b/libethash/sha3.c
index 0c28230b8..e72fe1018 100644
--- a/libethash/sha3.c
+++ b/libethash/sha3.c
@@ -17,65 +17,65 @@
/*** Constants. ***/
static const uint8_t rho[24] = \
- { 1, 3, 6, 10, 15, 21,
- 28, 36, 45, 55, 2, 14,
- 27, 41, 56, 8, 25, 43,
- 62, 18, 39, 61, 20, 44};
+ { 1, 3, 6, 10, 15, 21,
+ 28, 36, 45, 55, 2, 14,
+ 27, 41, 56, 8, 25, 43,
+ 62, 18, 39, 61, 20, 44};
static const uint8_t pi[24] = \
- {10, 7, 11, 17, 18, 3,
- 5, 16, 8, 21, 24, 4,
- 15, 23, 19, 13, 12, 2,
- 20, 14, 22, 9, 6, 1};
+ {10, 7, 11, 17, 18, 3,
+ 5, 16, 8, 21, 24, 4,
+ 15, 23, 19, 13, 12, 2,
+ 20, 14, 22, 9, 6, 1};
static const uint64_t RC[24] = \
- {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
- 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
- 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
- 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
- 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
- 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
+ {1ULL, 0x8082ULL, 0x800000000000808aULL, 0x8000000080008000ULL,
+ 0x808bULL, 0x80000001ULL, 0x8000000080008081ULL, 0x8000000000008009ULL,
+ 0x8aULL, 0x88ULL, 0x80008009ULL, 0x8000000aULL,
+ 0x8000808bULL, 0x800000000000008bULL, 0x8000000000008089ULL, 0x8000000000008003ULL,
+ 0x8000000000008002ULL, 0x8000000000000080ULL, 0x800aULL, 0x800000008000000aULL,
+ 0x8000000080008081ULL, 0x8000000000008080ULL, 0x80000001ULL, 0x8000000080008008ULL};
/*** Helper macros to unroll the permutation. ***/
#define rol(x, s) (((x) << s) | ((x) >> (64 - s)))
#define REPEAT6(e) e e e e e e
#define REPEAT24(e) REPEAT6(e e e e)
#define REPEAT5(e) e e e e e
-#define FOR5(v, s, e) \
- v = 0; \
- REPEAT5(e; v += s;)
+#define FOR5(v, s, e) \
+ v = 0; \
+ REPEAT5(e; v += s;)
/*** Keccak-f[1600] ***/
static inline void keccakf(void* state) {
- uint64_t* a = (uint64_t*)state;
- uint64_t b[5] = {0};
- uint64_t t = 0;
- uint8_t x, y;
+ uint64_t* a = (uint64_t*)state;
+ uint64_t b[5] = {0};
+ uint64_t t = 0;
+ uint8_t x, y;
- for (int i = 0; i < 24; i++) {
- // Theta
- FOR5(x, 1,
- b[x] = 0;
- FOR5(y, 5,
- b[x] ^= a[x + y]; ))
- FOR5(x, 1,
- FOR5(y, 5,
- a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))
- // Rho and pi
- t = a[1];
- x = 0;
- REPEAT24(b[0] = a[pi[x]];
- a[pi[x]] = rol(t, rho[x]);
- t = b[0];
- x++; )
- // Chi
- FOR5(y,
- 5,
- FOR5(x, 1,
- b[x] = a[y + x];)
- FOR5(x, 1,
- a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))
- // Iota
- a[0] ^= RC[i];
- }
+ for (int i = 0; i < 24; i++) {
+ // Theta
+ FOR5(x, 1,
+ b[x] = 0;
+ FOR5(y, 5,
+ b[x] ^= a[x + y]; ))
+ FOR5(x, 1,
+ FOR5(y, 5,
+ a[y + x] ^= b[(x + 4) % 5] ^ rol(b[(x + 1) % 5], 1); ))
+ // Rho and pi
+ t = a[1];
+ x = 0;
+ REPEAT24(b[0] = a[pi[x]];
+ a[pi[x]] = rol(t, rho[x]);
+ t = b[0];
+ x++; )
+ // Chi
+ FOR5(y,
+ 5,
+ FOR5(x, 1,
+ b[x] = a[y + x];)
+ FOR5(x, 1,
+ a[y + x] = b[x] ^ ((~b[(x + 1) % 5]) & b[(x + 2) % 5]); ))
+ // Iota
+ a[0] ^= RC[i];
+ }
}
/******** The FIPS202-defined functions. ********/
@@ -83,20 +83,20 @@ static inline void keccakf(void* state) {
/*** Some helper macros. ***/
#define _(S) do { S } while (0)
-#define FOR(i, ST, L, S) \
- _(for (size_t i = 0; i < L; i += ST) { S; })
-#define mkapply_ds(NAME, S) \
- static inline void NAME(uint8_t* dst, \
- const uint8_t* src, \
- size_t len) { \
- FOR(i, 1, len, S); \
- }
-#define mkapply_sd(NAME, S) \
- static inline void NAME(const uint8_t* src, \
- uint8_t* dst, \
- size_t len) { \
- FOR(i, 1, len, S); \
- }
+#define FOR(i, ST, L, S) \
+ _(for (size_t i = 0; i < L; i += ST) { S; })
+#define mkapply_ds(NAME, S) \
+ static inline void NAME(uint8_t* dst, \
+ const uint8_t* src, \
+ size_t len) { \
+ FOR(i, 1, len, S); \
+ }
+#define mkapply_sd(NAME, S) \
+ static inline void NAME(const uint8_t* src, \
+ uint8_t* dst, \
+ size_t len) { \
+ FOR(i, 1, len, S); \
+ }
mkapply_ds(xorin, dst[i] ^= src[i]) // xorin
mkapply_sd(setout, dst[i] = src[i]) // setout
@@ -105,47 +105,47 @@ mkapply_sd(setout, dst[i] = src[i]) // setout
#define Plen 200
// Fold P*F over the full blocks of an input.
-#define foldP(I, L, F) \
- while (L >= rate) { \
- F(a, I, rate); \
- P(a); \
- I += rate; \
- L -= rate; \
- }
+#define foldP(I, L, F) \
+ while (L >= rate) { \
+ F(a, I, rate); \
+ P(a); \
+ I += rate; \
+ L -= rate; \
+ }
/** The sponge-based hash construction. **/
static inline int hash(uint8_t* out, size_t outlen,
- const uint8_t* in, size_t inlen,
- size_t rate, uint8_t delim) {
- if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
- return -1;
- }
- uint8_t a[Plen] = {0};
- // Absorb input.
- foldP(in, inlen, xorin);
- // Xor in the DS and pad frame.
- a[inlen] ^= delim;
- a[rate - 1] ^= 0x80;
- // Xor in the last block.
- xorin(a, in, inlen);
- // Apply P
- P(a);
- // Squeeze output.
- foldP(out, outlen, setout);
- setout(a, out, outlen);
- memset(a, 0, 200);
- return 0;
+ const uint8_t* in, size_t inlen,
+ size_t rate, uint8_t delim) {
+ if ((out == NULL) || ((in == NULL) && inlen != 0) || (rate >= Plen)) {
+ return -1;
+ }
+ uint8_t a[Plen] = {0};
+ // Absorb input.
+ foldP(in, inlen, xorin);
+ // Xor in the DS and pad frame.
+ a[inlen] ^= delim;
+ a[rate - 1] ^= 0x80;
+ // Xor in the last block.
+ xorin(a, in, inlen);
+ // Apply P
+ P(a);
+ // Squeeze output.
+ foldP(out, outlen, setout);
+ setout(a, out, outlen);
+ memset(a, 0, 200);
+ return 0;
}
-#define defsha3(bits) \
- int sha3_##bits(uint8_t* out, size_t outlen, \
- const uint8_t* in, size_t inlen) { \
- if (outlen > (bits/8)) { \
- return -1; \
- } \
- return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \
- }
+#define defsha3(bits) \
+ int sha3_##bits(uint8_t* out, size_t outlen, \
+ const uint8_t* in, size_t inlen) { \
+ if (outlen > (bits/8)) { \
+ return -1; \
+ } \
+ return hash(out, outlen, in, inlen, 200 - (bits / 4), 0x01); \
+ }
/*** FIPS202 SHA3 FOFs ***/
defsha3(256)
-defsha3(512)
\ No newline at end of file
+defsha3(512)
diff --git a/libethash/sha3.h b/libethash/sha3.h
index 36a0a5301..a38006292 100644
--- a/libethash/sha3.h
+++ b/libethash/sha3.h
@@ -8,20 +8,24 @@ extern "C" {
#include
#include
+struct ethash_h256;
+
#define decsha3(bits) \
- int sha3_##bits(uint8_t*, size_t, const uint8_t*, size_t);
+ int sha3_##bits(uint8_t*, size_t, uint8_t const*, size_t);
decsha3(256)
decsha3(512)
-static inline void SHA3_256(uint8_t * const ret, uint8_t const *data, const size_t size) {
- sha3_256(ret, 32, data, size);
+static inline void SHA3_256(struct ethash_h256 const* ret, uint8_t const* data, size_t const size)
+{
+ sha3_256((uint8_t*)ret, 32, data, size);
}
-static inline void SHA3_512(uint8_t * const ret, uint8_t const *data, const size_t size) {
- sha3_512(ret, 64, data, size);
+static inline void SHA3_512(uint8_t* ret, uint8_t const* data, size_t const size)
+{
+ sha3_512(ret, 64, data, size);
}
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/libethash/sha3_cryptopp.cpp b/libethash/sha3_cryptopp.cpp
index 6cbbcad8f..2a7c02664 100644
--- a/libethash/sha3_cryptopp.cpp
+++ b/libethash/sha3_cryptopp.cpp
@@ -19,16 +19,19 @@
* @author Tim Hughes
* @date 2015
*/
-
#include
#include
extern "C" {
-void SHA3_256(uint8_t *const ret, const uint8_t *data, size_t size) {
- CryptoPP::SHA3_256().CalculateDigest(ret, data, size);
+struct ethash_h256;
+typedef struct ethash_h256 ethash_h256_t;
+void SHA3_256(ethash_h256_t const* ret, uint8_t const* data, size_t size)
+{
+ CryptoPP::SHA3_256().CalculateDigest((uint8_t*)ret, data, size);
}
-void SHA3_512(uint8_t *const ret, const uint8_t *data, size_t size) {
- CryptoPP::SHA3_512().CalculateDigest(ret, data, size);
+void SHA3_512(uint8_t* const ret, uint8_t const* data, size_t size)
+{
+ CryptoPP::SHA3_512().CalculateDigest(ret, data, size);
+}
}
-}
\ No newline at end of file
diff --git a/libethash/sha3_cryptopp.h b/libethash/sha3_cryptopp.h
index f910960e1..9edc407d5 100644
--- a/libethash/sha3_cryptopp.h
+++ b/libethash/sha3_cryptopp.h
@@ -2,14 +2,17 @@
#include "compiler.h"
#include
+#include
#ifdef __cplusplus
extern "C" {
#endif
-void SHA3_256(uint8_t *const ret, const uint8_t *data, size_t size);
-void SHA3_512(uint8_t *const ret, const uint8_t *data, size_t size);
+struct ethash_h256;
+
+void SHA3_256(struct ethash_h256 const* ret, uint8_t const* data, size_t size);
+void SHA3_512(uint8_t* const ret, uint8_t const* data, size_t size);
#ifdef __cplusplus
}
-#endif
\ No newline at end of file
+#endif
diff --git a/libethash/util.h b/libethash/util.h
index 1e6d4fbab..c5fc6e55b 100644
--- a/libethash/util.h
+++ b/libethash/util.h
@@ -27,9 +27,9 @@ extern "C" {
#endif
#ifdef _MSC_VER
-void debugf(const char *str, ...);
+void debugf(char const* str, ...);
#else
-#define debugf(...) fprintf(stderr, __VA_ARGS__)
+#define debugf printf
#endif
static inline uint32_t min_u32(uint32_t a, uint32_t b)
diff --git a/libethash/util_win32.c b/libethash/util_win32.c
new file mode 100644
index 000000000..268e6db05
--- /dev/null
+++ b/libethash/util_win32.c
@@ -0,0 +1,38 @@
+/*
+ This file is part of cpp-ethereum.
+
+ cpp-ethereum is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ cpp-ethereum is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with cpp-ethereum. If not, see .
+*/
+/** @file util.c
+ * @author Tim Hughes
+ * @date 2015
+ */
+#include
+#include
+#include "util.h"
+
+
+// foward declare without all of Windows.h
+__declspec(dllimport) void __stdcall OutputDebugStringA(char const* lpOutputString);
+
+void debugf(char const* str, ...)
+{
+ va_list args;
+ va_start(args, str);
+
+ char buf[1<<16];
+ _vsnprintf_s(buf, sizeof(buf), sizeof(buf), str, args);
+ buf[sizeof(buf)-1] = '\0';
+ OutputDebugStringA(buf);
+}
diff --git a/libethcore/Ethash.cpp b/libethcore/Ethash.cpp
index 011f0b9e0..3724d8255 100644
--- a/libethcore/Ethash.cpp
+++ b/libethcore/Ethash.cpp
@@ -36,6 +36,7 @@
#include
#include
#include
+#include
#if ETH_ETHASHCL || !ETH_TRUE
#include
#endif
@@ -71,12 +72,13 @@ Ethash::WorkPackage Ethash::package(BlockInfo const& _bi)
ret.boundary = _bi.boundary();
ret.headerHash = _bi.headerHash(WithoutNonce);
ret.seedHash = _bi.seedHash();
+ ret.blockNumber = (uint64_t) _bi.number;
return ret;
}
-void Ethash::prep(BlockInfo const& _header)
+void Ethash::prep(BlockInfo const& _header, std::function const& _f)
{
- EthashAux::full(_header);
+ EthashAux::full((unsigned)_header.number, _f);
}
bool Ethash::preVerify(BlockInfo const& _header)
@@ -87,10 +89,10 @@ bool Ethash::preVerify(BlockInfo const& _header)
h256 boundary = u256((bigint(1) << 256) / _header.difficulty);
return !!ethash_quick_check_difficulty(
- _header.headerHash(WithoutNonce).data(),
+ (ethash_h256_t const*)_header.headerHash(WithoutNonce).data(),
(uint64_t)(u64)_header.nonce,
- _header.mixHash.data(),
- boundary.data());
+ (ethash_h256_t const*)_header.mixHash.data(),
+ (ethash_h256_t const*)boundary.data());
}
bool Ethash::verify(BlockInfo const& _header)
@@ -133,17 +135,14 @@ void Ethash::CPUMiner::workLoop()
WorkPackage w = work();
- auto p = EthashAux::params(w.seedHash);
- auto dag = EthashAux::full(w.seedHash);
- auto dagPointer = dag->data.data();
- uint8_t const* headerHashPointer = w.headerHash.data();
+ auto dag = EthashAux::full(w.blockNumber);
h256 boundary = w.boundary;
unsigned hashCount = 1;
for (; !shouldStop(); tryNonce++, hashCount++)
{
- ethash_compute_full(ðashReturn, dagPointer, &p, headerHashPointer, tryNonce);
- h256 value = h256(ethashReturn.result, h256::ConstructFromPointer);
- if (value <= boundary && submitProof(Solution{(Nonce)(u64)tryNonce, h256(ethashReturn.mix_hash, h256::ConstructFromPointer)}))
+ ethashReturn = ethash_full_compute(dag->full, *(ethash_h256_t*)w.headerHash.data(), tryNonce);
+ h256 value = h256((uint8_t*)ðashReturn.result, h256::ConstructFromPointer);
+ if (value <= boundary && submitProof(Solution{(Nonce)(u64)tryNonce, h256((uint8_t*)ðashReturn.mix_hash, h256::ConstructFromPointer)}))
break;
if (!(hashCount % 1000))
accumulateHashes(1000);
@@ -285,7 +284,7 @@ Ethash::GPUMiner::~GPUMiner()
bool Ethash::GPUMiner::report(uint64_t _nonce)
{
Nonce n = (Nonce)(u64)_nonce;
- Result r = EthashAux::eval(work().seedHash, work().headerHash, n);
+ Result r = EthashAux::eval(work().blockNumber, work().headerHash, n);
if (r.value < work().boundary)
return submitProof(Solution{n, r.mixHash});
return false;
@@ -311,8 +310,11 @@ void Ethash::GPUMiner::workLoop()
unsigned device = instances() > 1 ? index() : s_deviceId;
- EthashAux::FullType dag = EthashAux::full(m_minerSeed);
- m_miner->init(dag->data.data(), dag->data.size(), 32, s_platformId, device);
+ if (!EthashAux::computeFull(w.blockNumber))
+ return;
+ EthashAux::FullType dag = EthashAux::full(w.blockNumber);
+ bytesConstRef dagData = dag->data();
+ m_miner->init(dagData.data(), dagData.size(), 32, s_platformId, device);
}
uint64_t upper64OfBoundary = (uint64_t)(u64)((u256)w.boundary >> 192);
diff --git a/libethcore/Ethash.h b/libethcore/Ethash.h
index 9a66e9865..82db15e87 100644
--- a/libethcore/Ethash.h
+++ b/libethcore/Ethash.h
@@ -66,14 +66,15 @@ public:
h256 boundary;
h256 headerHash; ///< When h256() means "pause until notified a new work package is available".
- h256 seedHash;
+ h256 seedHash; /// LTODO: IS this needed now that we use the block number instead?
+ uint64_t blockNumber;
};
static const WorkPackage NullWorkPackage;
static std::string name();
static unsigned revision();
- static void prep(BlockInfo const& _header);
+ static void prep(BlockInfo const& _header, std::function const& _f = std::function());
static bool verify(BlockInfo const& _header);
static bool preVerify(BlockInfo const& _header);
static WorkPackage package(BlockInfo const& _header);
diff --git a/libethcore/EthashAux.cpp b/libethcore/EthashAux.cpp
index 0b9af98ac..f7a0ac41d 100644
--- a/libethcore/EthashAux.cpp
+++ b/libethcore/EthashAux.cpp
@@ -33,29 +33,25 @@
#include
#include
#include
+#include
#include "BlockInfo.h"
+#include "Exceptions.h"
using namespace std;
using namespace chrono;
using namespace dev;
using namespace eth;
+const char* DAGChannel::name() { return EthGreen "DAG"; }
+
EthashAux* dev::eth::EthashAux::s_this = nullptr;
EthashAux::~EthashAux()
{
}
-ethash_params EthashAux::params(BlockInfo const& _header)
-{
- return params((unsigned)_header.number);
-}
-
-ethash_params EthashAux::params(unsigned _n)
+uint64_t EthashAux::cacheSize(BlockInfo const& _header)
{
- ethash_params p;
- p.cache_size = ethash_get_cachesize(_n);
- p.full_size = ethash_get_datasize(_n);
- return p;
+ return ethash_get_cachesize((uint64_t)_header.number);
}
h256 EthashAux::seedHash(unsigned _number)
@@ -82,7 +78,7 @@ h256 EthashAux::seedHash(unsigned _number)
return get()->m_seedHashes[epoch];
}
-ethash_params EthashAux::params(h256 const& _seedHash)
+uint64_t EthashAux::number(h256 const& _seedHash)
{
Guard l(get()->x_epochs);
unsigned epoch = 0;
@@ -100,125 +96,136 @@ ethash_params EthashAux::params(h256 const& _seedHash)
}
else
epoch = epochIter->second;
- return params(epoch * ETHASH_EPOCH_LENGTH);
+ return epoch * ETHASH_EPOCH_LENGTH;
}
void EthashAux::killCache(h256 const& _s)
{
- RecursiveGuard l(x_this);
+ RecursiveGuard l(x_lights);
m_lights.erase(_s);
}
EthashAux::LightType EthashAux::light(BlockInfo const& _header)
{
- return light(_header.seedHash());
+ return light((uint64_t)_header.number);
}
-EthashAux::LightType EthashAux::light(h256 const& _seedHash)
+EthashAux::LightType EthashAux::light(uint64_t _blockNumber)
{
- RecursiveGuard l(get()->x_this);
- LightType ret = get()->m_lights[_seedHash];
- return ret ? ret : (get()->m_lights[_seedHash] = make_shared(_seedHash));
+ RecursiveGuard l(get()->x_lights);
+ h256 seedHash = EthashAux::seedHash(_blockNumber);
+ LightType ret = get()->m_lights[seedHash];
+ return ret ? ret : (get()->m_lights[seedHash] = make_shared(_blockNumber));
}
-EthashAux::LightAllocation::LightAllocation(h256 const& _seed)
+EthashAux::LightAllocation::LightAllocation(uint64_t _blockNumber)
{
- auto p = params(_seed);
- size = p.cache_size;
- light = ethash_new_light(&p, _seed.data());
+ light = ethash_light_new(_blockNumber);
+ size = ethash_get_cachesize(_blockNumber);
}
EthashAux::LightAllocation::~LightAllocation()
{
- ethash_delete_light(light);
+ ethash_light_delete(light);
}
-EthashAux::FullType EthashAux::full(BlockInfo const& _header, bytesRef _dest, bool _createIfMissing)
+bytesConstRef EthashAux::LightAllocation::data() const
{
- return full(_header.seedHash(), _dest, _createIfMissing);
+ return bytesConstRef((byte const*)light->cache, size);
}
-EthashAux::FullType EthashAux::full(h256 const& _seedHash, bytesRef _dest, bool _createIfMissing)
+EthashAux::FullAllocation::FullAllocation(ethash_light_t _light, ethash_callback_t _cb)
{
- RecursiveGuard l(get()->x_this);
- FullType ret = get()->m_fulls[_seedHash].lock();
- if (ret && _dest)
- {
- assert(ret->data.size() <= _dest.size());
- ret->data.copyTo(_dest);
- return FullType();
- }
- if (!ret)
- {
- // drop our last used cache sine we're allocating another 1GB.
- get()->m_lastUsedFull.reset();
+ full = ethash_full_new(_light, _cb);
+}
- try {
- boost::filesystem::create_directories(getDataDir("ethash"));
- } catch (...) {}
+EthashAux::FullAllocation::~FullAllocation()
+{
+ ethash_full_delete(full);
+}
- auto info = rlpList(Ethash::revision(), _seedHash);
- std::string oldMemoFile = getDataDir("ethash") + "/full";
- std::string memoFile = getDataDir("ethash") + "/full-R" + toString(ETHASH_REVISION) + "-" + toHex(_seedHash.ref().cropped(0, 8));
- if (boost::filesystem::exists(oldMemoFile) && contents(oldMemoFile + ".info") == info)
- {
- // memofile valid - rename.
- boost::filesystem::rename(oldMemoFile, memoFile);
- }
+bytesConstRef EthashAux::FullAllocation::data() const
+{
+ return bytesConstRef((byte const*)ethash_full_dag(full), size());
+}
- DEV_IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile));
- DEV_IGNORE_EXCEPTIONS(boost::filesystem::remove(oldMemoFile + ".info"));
+static std::function s_dagCallback;
+static int dagCallbackShim(unsigned _p)
+{
+ clog(DAGChannel) << "Generating DAG file. Progress: " << toString(_p) << "%";
+ return s_dagCallback ? s_dagCallback(_p) : 0;
+}
- ethash_params p = params(_seedHash);
- assert(!_dest || _dest.size() >= p.full_size); // must be big enough.
+EthashAux::FullType EthashAux::full(uint64_t _blockNumber, function const& _f)
+{
+ auto l = light(_blockNumber);
+ h256 seedHash = EthashAux::seedHash(_blockNumber);
+ FullType ret;
- bytesRef r = contentsNew(memoFile, _dest);
- if (!r)
+ DEV_GUARDED(get()->x_fulls)
+ if ((ret = get()->m_fulls[seedHash].lock()))
{
- if (!_createIfMissing)
- return FullType();
- // file didn't exist.
- if (_dest)
- // buffer was passed in - no insertion into cache nor need to allocate
- r = _dest;
- else
- r = bytesRef(new byte[p.full_size], p.full_size);
- ethash_prep_full(r.data(), &p, light(_seedHash)->light);
- writeFile(memoFile, r);
+ get()->m_lastUsedFull = ret;
+ return ret;
}
- if (_dest)
- return FullType();
- ret = make_shared(r);
- get()->m_fulls[_seedHash] = ret;
- }
- get()->m_lastUsedFull = ret;
+
+ s_dagCallback = _f;
+ ret = make_shared(l->light, dagCallbackShim);
+
+ DEV_GUARDED(get()->x_fulls)
+ get()->m_fulls[seedHash] = get()->m_lastUsedFull = ret;
return ret;
}
-Ethash::Result EthashAux::eval(BlockInfo const& _header, Nonce const& _nonce)
+unsigned EthashAux::computeFull(uint64_t _blockNumber)
{
- return eval(_header.seedHash(), _header.headerHash(WithoutNonce), _nonce);
+ Guard l(get()->x_fulls);
+ h256 seedHash = EthashAux::seedHash(_blockNumber);
+ if (FullType ret = get()->m_fulls[seedHash].lock())
+ {
+ get()->m_lastUsedFull = ret;
+ return 100;
+ }
+
+ if (!get()->m_fullGenerator || !get()->m_fullGenerator->joinable())
+ {
+ get()->m_fullProgress = 0;
+ get()->m_generatingFullNumber = _blockNumber / ETHASH_EPOCH_LENGTH * ETHASH_EPOCH_LENGTH;
+ get()->m_fullGenerator = unique_ptr(new thread([=](){
+ get()->full(_blockNumber, [](unsigned p){ get()->m_fullProgress = p; return 0; });
+ get()->m_fullProgress = 0;
+ get()->m_generatingFullNumber = NotGenerating;
+ }));
+ }
+
+ return (get()->m_generatingFullNumber == _blockNumber) ? get()->m_fullProgress : 0;
}
-Ethash::Result EthashAux::FullAllocation::compute(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) const
+Ethash::Result EthashAux::FullAllocation::compute(h256 const& _headerHash, Nonce const& _nonce) const
{
- ethash_return_value r;
- auto p = EthashAux::params(_seedHash);
- ethash_compute_full(&r, data.data(), &p, _headerHash.data(), (uint64_t)(u64)_nonce);
- return Ethash::Result{h256(r.result, h256::ConstructFromPointer), h256(r.mix_hash, h256::ConstructFromPointer)};
+ ethash_return_value_t r = ethash_full_compute(full, *(ethash_h256_t*)_headerHash.data(), (uint64_t)(u64)_nonce);
+ if (!r.success)
+ BOOST_THROW_EXCEPTION(DAGCreationFailure());
+ return Ethash::Result{h256((uint8_t*)&r.result, h256::ConstructFromPointer), h256((uint8_t*)&r.mix_hash, h256::ConstructFromPointer)};
}
-Ethash::Result EthashAux::LightAllocation::compute(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) const
+Ethash::Result EthashAux::LightAllocation::compute(h256 const& _headerHash, Nonce const& _nonce) const
+{
+ ethash_return_value r = ethash_light_compute(light, *(ethash_h256_t*)_headerHash.data(), (uint64_t)(u64)_nonce);
+ if (!r.success)
+ BOOST_THROW_EXCEPTION(DAGCreationFailure());
+ return Ethash::Result{h256((uint8_t*)&r.result, h256::ConstructFromPointer), h256((uint8_t*)&r.mix_hash, h256::ConstructFromPointer)};
+}
+
+Ethash::Result EthashAux::eval(BlockInfo const& _header, Nonce const& _nonce)
{
- ethash_return_value r;
- auto p = EthashAux::params(_seedHash);
- ethash_compute_light(&r, light, &p, _headerHash.data(), (uint64_t)(u64)_nonce);
- return Ethash::Result{h256(r.result, h256::ConstructFromPointer), h256(r.mix_hash, h256::ConstructFromPointer)};
+ return eval((uint64_t)_header.number, _header.headerHash(WithoutNonce), _nonce);
}
-Ethash::Result EthashAux::eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce)
+Ethash::Result EthashAux::eval(uint64_t _blockNumber, h256 const& _headerHash, Nonce const& _nonce)
{
- if (auto dag = EthashAux::get()->full(_seedHash, bytesRef(), false))
- return dag->compute(_seedHash, _headerHash, _nonce);
- return EthashAux::get()->light(_seedHash)->compute(_seedHash, _headerHash, _nonce);
+ h256 seedHash = EthashAux::seedHash(_blockNumber);
+ if (FullType dag = get()->m_fulls[seedHash].lock())
+ return dag->compute(_headerHash, _nonce);
+ return EthashAux::get()->light(_blockNumber)->compute(_headerHash, _nonce);
}
diff --git a/libethcore/EthashAux.h b/libethcore/EthashAux.h
index c90ee048e..f57f7a4d3 100644
--- a/libethcore/EthashAux.h
+++ b/libethcore/EthashAux.h
@@ -19,12 +19,17 @@
* @date 2014
*/
+#include
#include
+#include
#include "Ethash.h"
namespace dev
{
-namespace eth{
+namespace eth
+{
+
+struct DAGChannel: public LogChannel { static const char* name(); static const int verbosity = 1; };
class EthashAux
{
@@ -33,39 +38,47 @@ public:
static EthashAux* get() { if (!s_this) s_this = new EthashAux(); return s_this; }
- struct FullAllocation
- {
- FullAllocation(bytesConstRef _d): data(_d) {}
- ~FullAllocation() { delete [] data.data(); }
- Ethash::Result compute(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) const;
- bytesConstRef const data;
- };
-
struct LightAllocation
{
- LightAllocation(h256 const& _seed);
+ LightAllocation(uint64_t _blockNumber);
~LightAllocation();
- bytesConstRef data() const { return bytesConstRef((byte const*)light, size); }
- Ethash::Result compute(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce) const;
+ bytesConstRef data() const;
+ Ethash::Result compute(h256 const& _headerHash, Nonce const& _nonce) const;
ethash_light_t light;
uint64_t size;
};
+ struct FullAllocation
+ {
+ FullAllocation(ethash_light_t _light, ethash_callback_t _cb);
+ ~FullAllocation();
+ Ethash::Result compute(h256 const& _headerHash, Nonce const& _nonce) const;
+ bytesConstRef data() const;
+ uint64_t size() const { return ethash_full_dag_size(full); }
+ ethash_full_t full;
+ };
+
using LightType = std::shared_ptr;
using FullType = std::shared_ptr;
static h256 seedHash(unsigned _number);
- static ethash_params params(BlockInfo const& _header);
- static ethash_params params(h256 const& _seedHash);
- static ethash_params params(unsigned _n);
+ static uint64_t number(h256 const& _seedHash);
+ static uint64_t cacheSize(BlockInfo const& _header);
+
static LightType light(BlockInfo const& _header);
- static LightType light(h256 const& _seedHash);
- static FullType full(BlockInfo const& _header, bytesRef _dest = bytesRef(), bool _createIfMissing = true);
- static FullType full(h256 const& _header, bytesRef _dest = bytesRef(), bool _createIfMissing = true);
+ static LightType light(uint64_t _blockNumber);
+
+ static const uint64_t NotGenerating = (uint64_t)-1;
+ /// Kicks off generation of DAG for @a _blocknumber and @returns false or @returns true if ready.
+ static unsigned computeFull(uint64_t _blockNumber);
+ /// Information on the generation progress.
+ static std::pair fullGeneratingProgress() { return std::make_pair(get()->m_generatingFullNumber, get()->m_fullProgress); }
+ /// Kicks off generation of DAG for @a _blocknumber and blocks until ready; @returns result.
+ static FullType full(uint64_t _blockNumber, std::function const& _f = std::function());
static Ethash::Result eval(BlockInfo const& _header) { return eval(_header, _header.nonce); }
static Ethash::Result eval(BlockInfo const& _header, Nonce const& _nonce);
- static Ethash::Result eval(h256 const& _seedHash, h256 const& _headerHash, Nonce const& _nonce);
+ static Ethash::Result eval(uint64_t _blockNumber, h256 const& _headerHash, Nonce const& _nonce);
private:
EthashAux() {}
@@ -73,11 +86,17 @@ private:
void killCache(h256 const& _s);
static EthashAux* s_this;
- RecursiveMutex x_this;
+ RecursiveMutex x_lights;
std::unordered_map> m_lights;
+
+ Mutex x_fulls;
+ std::condition_variable m_fullsChanged;
std::unordered_map> m_fulls;
FullType m_lastUsedFull;
+ std::unique_ptr m_fullGenerator;
+ uint64_t m_generatingFullNumber = NotGenerating;
+ unsigned m_fullProgress;
Mutex x_epochs;
std::unordered_map m_epochs;
diff --git a/libethcore/Exceptions.h b/libethcore/Exceptions.h
index 3471a958f..8b73c96fe 100644
--- a/libethcore/Exceptions.h
+++ b/libethcore/Exceptions.h
@@ -73,6 +73,7 @@ class InvalidBlockNonce: virtual public dev::Exception {};
struct InvalidParentHash: virtual dev::Exception {};
struct InvalidNumber: virtual dev::Exception {};
struct InvalidContractAddress: virtual public dev::Exception {};
-
+struct DAGCreationFailure: virtual public dev::Exception {};
+struct DAGComputeFailure: virtual public dev::Exception {};
}
}
diff --git a/libethereum/BlockChain.cpp b/libethereum/BlockChain.cpp
index f13f83588..32a11ee53 100644
--- a/libethereum/BlockChain.cpp
+++ b/libethereum/BlockChain.cpp
@@ -466,7 +466,14 @@ ImportRoute BlockChain::import(bytes const& _block, OverlayDB const& _db, Import
blb.blooms.push_back(s.receipt(i).bloom());
br.receipts.push_back(s.receipt(i));
}
- s.cleanup(true);
+ try {
+ s.cleanup(true);
+ }
+ catch (BadRoot)
+ {
+ cwarn << "BadRoot error. Retrying import later.";
+ BOOST_THROW_EXCEPTION(FutureTime());
+ }
td = pd.totalDifficulty + tdIncrease;
diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp
index a43c98aa2..6d934f3ad 100644
--- a/libethereum/Client.cpp
+++ b/libethereum/Client.cpp
@@ -164,7 +164,7 @@ const char* ClientDetail::name() { return EthTeal "⧫" EthCoal " ●"; }
#endif
Client::Client(p2p::Host* _extNet, std::string const& _dbPath, WithExisting _forceAction, u256 _networkId):
- Worker("eth"),
+ Worker("eth", 0),
m_vc(_dbPath),
m_bc(_dbPath, max(m_vc.action(), _forceAction), [](unsigned d, unsigned t){ cerr << "REVISING BLOCKCHAIN: Processed " << d << " of " << t << "...\r"; }),
m_gp(new TrivialGasPricer),
diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h
index 235a6f540..2b271b1df 100644
--- a/libethereum/ClientBase.h
+++ b/libethereum/ClientBase.h
@@ -84,11 +84,11 @@ public:
using Interface::submitTransaction;
/// Makes the given call. Nothing is recorded into the state.
- virtual ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override;
+ virtual ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override;
using Interface::call;
/// Makes the given create. Nothing is recorded into the state.
- virtual ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * szabo, BlockNumber _blockNumber = PendingBlock, FudgeFactor _ff = FudgeFactor::Strict) override;
+ virtual ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, FudgeFactor _ff = FudgeFactor::Strict) override;
using Interface::create;
using Interface::balanceAt;
diff --git a/libethereum/State.cpp b/libethereum/State.cpp
index 50e4b26ab..167d6236e 100644
--- a/libethereum/State.cpp
+++ b/libethereum/State.cpp
@@ -515,10 +515,10 @@ pair State::sync(BlockChain const& _bc, TransactionQu
cnote << i.first << "Dropping old transaction (nonce too low)";
_tq.drop(i.first);
}
- else if (got > req + 5)
+ else if (got > req + 25)
{
// too new
- cnote << i.first << "Dropping new transaction (> 5 nonces ahead)";
+ cnote << i.first << "Dropping new transaction (> 25 nonces ahead)";
_tq.drop(i.first);
}
else
@@ -707,11 +707,21 @@ void State::cleanup(bool _fullCommit)
{
if (_fullCommit)
{
-
paranoia("immediately before database commit", true);
// Commit the new trie to disk.
clog(StateTrace) << "Committing to disk: stateRoot" << m_currentBlock.stateRoot << "=" << rootHash() << "=" << toHex(asBytes(m_db.lookup(rootHash())));
+
+ try {
+ EnforceRefs er(m_db, true);
+ rootHash();
+ }
+ catch (BadRoot const&)
+ {
+ clog(StateChat) << "Trie corrupt! :-(";
+ throw;
+ }
+
m_db.commit();
clog(StateTrace) << "Committed: stateRoot" << m_currentBlock.stateRoot << "=" << rootHash() << "=" << toHex(asBytes(m_db.lookup(rootHash())));
diff --git a/libevm/CMakeLists.txt b/libevm/CMakeLists.txt
index f6f0c01e4..26bb46e2e 100644
--- a/libevm/CMakeLists.txt
+++ b/libevm/CMakeLists.txt
@@ -15,6 +15,9 @@ aux_source_directory(. SRC_LIST)
# and windows is failing to build without that
include_directories(BEFORE ..)
include_directories(${Boost_INCLUDE_DIRS})
+if (EVMJIT)
+ include_directories(../evmjit/include)
+endif()
set(EXECUTABLE evm)
diff --git a/libevm/SmartVM.cpp b/libevm/SmartVM.cpp
new file mode 100644
index 000000000..4f759a745
--- /dev/null
+++ b/libevm/SmartVM.cpp
@@ -0,0 +1,79 @@
+/*
+ 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 .
+*/
+
+// SmartVM is only available if EVM JIT is enabled
+#if ETH_EVMJIT
+
+#include "SmartVM.h"
+#include
+#include
+#include
+#include
+#include
+#include "VMFactory.h"
+
+namespace dev
+{
+namespace eth
+{
+namespace
+{
+ using HitMap = std::unordered_map;
+
+ HitMap& getHitMap()
+ {
+ static HitMap s_hitMap;
+ return s_hitMap;
+ }
+}
+
+bytesConstRef SmartVM::go(ExtVMFace& _ext, OnOpFunc const& _onOp, uint64_t _steps)
+{
+ auto codeHash = sha3(_ext.code);
+ auto vmKind = VMKind::Interpreter; // default VM
+
+ // Jitted EVM code already in memory?
+ if (evmjit::JIT::isCodeReady(eth2llvm(codeHash)))
+ {
+ cnote << "Jitted";
+ vmKind = VMKind::JIT;
+ }
+ else
+ {
+ // Check EVM code hit count
+ static const uint64_t c_hitTreshold = 1;
+ auto& hits = getHitMap()[codeHash];
+ ++hits;
+ if (hits > c_hitTreshold)
+ {
+ cnote << "JIT selected";
+ vmKind = VMKind::JIT;
+ }
+ }
+
+ // TODO: Selected VM must be kept only because it returns reference to its internal memory.
+ // VM implementations should be stateless, without gas counter and escaping memory reference.
+ m_selectedVM = VMFactory::create(vmKind, gas());
+ auto out = m_selectedVM->go(_ext, _onOp, _steps);
+ m_gas = m_selectedVM->gas();
+ return out;
+}
+
+}
+}
+
+#endif
diff --git a/libevm/SmartVM.h b/libevm/SmartVM.h
new file mode 100644
index 000000000..29f464ecd
--- /dev/null
+++ b/libevm/SmartVM.h
@@ -0,0 +1,43 @@
+/*
+ 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 .
+*/
+#pragma once
+
+#include "VMFace.h"
+
+namespace dev
+{
+namespace eth
+{
+
+/// Smart VM proxy.
+///
+/// This class is a strategy pattern implementation for VM. For every EVM code
+/// execution request it tries to select the best VM implementation (Interpreter or JIT)
+/// by analyzing available information like: code size, hit count, JIT status, etc.
+class SmartVM: public VMFace
+{
+public:
+ SmartVM(u256 _gas): VMFace(_gas) {}
+
+ virtual bytesConstRef go(ExtVMFace& _ext, OnOpFunc const& _onOp = {}, uint64_t _steps = (uint64_t)-1) override final;
+
+private:
+ std::unique_ptr m_selectedVM;
+};
+
+}
+}
diff --git a/libevm/VMFactory.cpp b/libevm/VMFactory.cpp
index 1092906e4..db619fa85 100644
--- a/libevm/VMFactory.cpp
+++ b/libevm/VMFactory.cpp
@@ -18,6 +18,7 @@
#include "VMFactory.h"
#include
#include "VM.h"
+#include "SmartVM.h"
#if ETH_EVMJIT
#include
@@ -29,7 +30,7 @@ namespace eth
{
namespace
{
- VMKind g_kind = VMKind::Interpreter;
+ auto g_kind = VMKind::Interpreter;
}
void VMFactory::setKind(VMKind _kind)
@@ -38,11 +39,25 @@ void VMFactory::setKind(VMKind _kind)
}
std::unique_ptr VMFactory::create(u256 _gas)
+{
+ return create(g_kind, _gas);
+}
+
+std::unique_ptr VMFactory::create(VMKind _kind, u256 _gas)
{
#if ETH_EVMJIT
- return std::unique_ptr(g_kind == VMKind::JIT ? static_cast(new JitVM(_gas)) : static_cast(new VM(_gas)));
+ switch (_kind)
+ {
+ default:
+ case VMKind::Interpreter:
+ return std::unique_ptr(new VM(_gas));
+ case VMKind::JIT:
+ return std::unique_ptr(new JitVM(_gas));
+ case VMKind::Smart:
+ return std::unique_ptr(new SmartVM(_gas));
+ }
#else
- asserts(g_kind == VMKind::Interpreter && "JIT disabled in build configuration");
+ asserts(_kind == VMKind::Interpreter && "JIT disabled in build configuration");
return std::unique_ptr(new VM(_gas));
#endif
}
diff --git a/libevm/VMFactory.h b/libevm/VMFactory.h
index d0d02e0c4..d50b1aa3b 100644
--- a/libevm/VMFactory.h
+++ b/libevm/VMFactory.h
@@ -23,10 +23,11 @@ namespace dev
namespace eth
{
-enum class VMKind: bool
+enum class VMKind
{
Interpreter,
- JIT
+ JIT,
+ Smart
};
class VMFactory
@@ -34,7 +35,13 @@ class VMFactory
public:
VMFactory() = delete;
+ /// Creates a VM instance of global kind (controlled by setKind() function).
static std::unique_ptr create(u256 _gas);
+
+ /// Creates a VM instance of kind provided.
+ static std::unique_ptr create(VMKind _kind, u256 _gas);
+
+ /// Set global VM kind
static void setKind(VMKind _kind);
};
diff --git a/libevmasm/Assembly.cpp b/libevmasm/Assembly.cpp
index 9530ded49..1011392b9 100644
--- a/libevmasm/Assembly.cpp
+++ b/libevmasm/Assembly.cpp
@@ -24,6 +24,7 @@
#include
#include
#include
+#include
#include
using namespace std;
using namespace dev;
@@ -311,54 +312,54 @@ Assembly& Assembly::optimise(bool _enable)
copt << toString(*this);
count = 0;
- //@todo CFG interface should be a generator, that returns an item and a pointer to a
- // knownstate, which has to replace the current state if it is not null.
- // Feed these items to the CSE, but also store them and replace the stored version
- // if the items generated by the CSE are shorter. (or even use less gas?)
- copt << "Performing control flow analysis...";
+ copt << "Performing optimisation...";
{
ControlFlowGraph cfg(m_items);
- AssemblyItems optItems;
+ AssemblyItems optimisedItems;
for (BasicBlock const& block: cfg.optimisedBlocks())
- copy(m_items.begin() + block.begin, m_items.begin() + block.end,
- back_inserter(optItems));
- if (optItems.size() < m_items.size())
{
- copt << "Old size: " << m_items.size() << ", new size: " << optItems.size();
- m_items = move(optItems);
- count++;
+ assertThrow(!!block.startState, OptimizerException, "");
+ CommonSubexpressionEliminator eliminator(*block.startState);
+ auto iter = m_items.begin() + block.begin;
+ auto const end = m_items.begin() + block.end;
+ while (iter < end)
+ {
+ auto orig = iter;
+ iter = eliminator.feedItems(iter, end);
+ bool shouldReplace = false;
+ AssemblyItems optimisedChunk;
+ try
+ {
+ optimisedChunk = eliminator.getOptimizedItems();
+ shouldReplace = (optimisedChunk.size() < size_t(iter - orig));
+ }
+ catch (StackTooDeepException const&)
+ {
+ // This might happen if the opcode reconstruction is not as efficient
+ // as the hand-crafted code.
+ }
+
+ if (shouldReplace)
+ {
+ copt << "Old size: " << (iter - orig) << ", new size: " << optimisedChunk.size();
+ count++;
+ optimisedItems += optimisedChunk;
+ }
+ else
+ copy(orig, iter, back_inserter(optimisedItems));
+ }
}
- }
- copt << "Performing common subexpression elimination...";
- for (auto iter = m_items.begin(); iter != m_items.end();)
- {
- //@todo use only a single state / expression classes instance.
- KnownState state(make_shared());
- CommonSubexpressionEliminator eliminator(state);
- auto orig = iter;
- iter = eliminator.feedItems(iter, m_items.end());
- AssemblyItems optItems;
- bool shouldReplace = false;
- try
+ if (optimisedItems.size() < m_items.size())
{
- optItems = eliminator.getOptimizedItems();
- shouldReplace = (optItems.size() < size_t(iter - orig));
- }
- catch (StackTooDeepException const&)
- {
- // This might happen if the opcode reconstruction is not as efficient
- // as the hand-crafted code.
+ m_items = move(optimisedItems);
+ count++;
}
- if (shouldReplace)
- {
- copt << "Old size: " << (iter - orig) << ", new size: " << optItems.size();
+ // This only modifies PushTags, we have to run again to actually remove code.
+ BlockDeduplicator dedup(m_items);
+ if (dedup.deduplicate())
count++;
- for (auto moveIter = optItems.begin(); moveIter != optItems.end(); ++orig, ++moveIter)
- *orig = move(*moveIter);
- iter = m_items.erase(orig, iter);
- }
}
}
@@ -461,7 +462,8 @@ bytes Assembly::assemble() const
for (auto const& i: tagRef)
{
bytesRef r(ret.data() + i.first, bytesPerTag);
- toBigEndian(tagPos[i.second], r);
+ //@todo in the failure case, we could use the position of the invalid jumpdest
+ toBigEndian(i.second < tagPos.size() ? tagPos[i.second] : (1 << (8 * bytesPerTag)) - 1, r);
}
if (!m_data.empty())
diff --git a/libevmasm/AssemblyItem.h b/libevmasm/AssemblyItem.h
index 6f2a65de9..b3012a7ea 100644
--- a/libevmasm/AssemblyItem.h
+++ b/libevmasm/AssemblyItem.h
@@ -68,6 +68,8 @@ public:
/// @returns true iff the type and data of the items are equal.
bool operator==(AssemblyItem const& _other) const { return m_type == _other.m_type && m_data == _other.m_data; }
bool operator!=(AssemblyItem const& _other) const { return !operator==(_other); }
+ /// Less-than operator compatible with operator==.
+ bool operator<(AssemblyItem const& _other) const { return std::tie(m_type, m_data) < std::tie(_other.m_type, _other.m_data); }
/// @returns an upper bound for the number of bytes required by this item, assuming that
/// the value of a jump tag takes @a _addressLength bytes.
diff --git a/libevmasm/BlockDeduplicator.cpp b/libevmasm/BlockDeduplicator.cpp
new file mode 100644
index 000000000..eadbe1b40
--- /dev/null
+++ b/libevmasm/BlockDeduplicator.cpp
@@ -0,0 +1,91 @@
+/*
+ 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 .
+*/
+/**
+ * @file BlockDeduplicator.cpp
+ * @author Christian
+ * @date 2015
+ * Unifies basic blocks that share content.
+ */
+
+#include
+#include
+#include
+#include
+
+using namespace std;
+using namespace dev;
+using namespace dev::eth;
+
+
+bool BlockDeduplicator::deduplicate()
+{
+ // Compares indices based on the suffix that starts there, ignoring tags and stopping at
+ // opcodes that stop the control flow.
+ function comparator = [&](size_t _i, size_t _j)
+ {
+ if (_i == _j)
+ return false;
+
+ BlockIterator first(m_items.begin() + _i, m_items.end());
+ BlockIterator second(m_items.begin() + _j, m_items.end());
+ BlockIterator end(m_items.end(), m_items.end());
+
+ if (first != end && (*first).type() == Tag)
+ ++first;
+ if (second != end && (*second).type() == Tag)
+ ++second;
+
+ return std::lexicographical_compare(first, end, second, end);
+ };
+
+ set> blocksSeen(comparator);
+ map tagReplacement;
+ for (size_t i = 0; i < m_items.size(); ++i)
+ {
+ if (m_items.at(i).type() != Tag)
+ continue;
+ auto it = blocksSeen.find(i);
+ if (it == blocksSeen.end())
+ blocksSeen.insert(i);
+ else
+ tagReplacement[m_items.at(i).data()] = m_items.at(*it).data();
+ }
+
+ bool ret = false;
+ for (AssemblyItem& item: m_items)
+ if (item.type() == PushTag && tagReplacement.count(item.data()))
+ {
+ ret = true;
+ item.setData(tagReplacement.at(item.data()));
+ }
+ return ret;
+}
+
+BlockDeduplicator::BlockIterator& BlockDeduplicator::BlockIterator::operator++()
+{
+ if (it == end)
+ return *this;
+ if (SemanticInformation::altersControlFlow(*it) && *it != AssemblyItem(eth::Instruction::JUMPI))
+ it = end;
+ else
+ {
+ ++it;
+ while (it != end && it->type() == Tag)
+ ++it;
+ }
+ return *this;
+}
diff --git a/libevmasm/BlockDeduplicator.h b/libevmasm/BlockDeduplicator.h
new file mode 100644
index 000000000..8a82a1ed7
--- /dev/null
+++ b/libevmasm/BlockDeduplicator.h
@@ -0,0 +1,69 @@
+/*
+ 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 .
+*/
+/**
+ * @file BlockDeduplicator.h
+ * @author Christian
+ * @date 2015
+ * Unifies basic blocks that share content.
+ */
+
+#pragma once
+
+#include
+#include
+#include
+
+namespace dev
+{
+namespace eth
+{
+
+class AssemblyItem;
+using AssemblyItems = std::vector;
+
+/**
+ * Optimizer class to be used to unify blocks that share content.
+ * Modifies the passed vector in place.
+ */
+class BlockDeduplicator
+{
+public:
+ BlockDeduplicator(AssemblyItems& _items): m_items(_items) {}
+ /// @returns true if something was changed
+ bool deduplicate();
+
+private:
+ /// Iterator that skips tags skips to the end if (all branches of) the control
+ /// flow does not continue to the next instruction.
+ struct BlockIterator: std::iterator
+ {
+ public:
+ BlockIterator(AssemblyItems::const_iterator _it, AssemblyItems::const_iterator _end):
+ it(_it), end(_end) { }
+ BlockIterator& operator++();
+ bool operator==(BlockIterator const& _other) const { return it == _other.it; }
+ bool operator!=(BlockIterator const& _other) const { return it != _other.it; }
+ AssemblyItem const& operator*() const { return *it; }
+ AssemblyItems::const_iterator it;
+ AssemblyItems::const_iterator end;
+ };
+
+ AssemblyItems& m_items;
+};
+
+}
+}
diff --git a/libevmasm/CMakeLists.txt b/libevmasm/CMakeLists.txt
index f8150806f..eb8fea95c 100644
--- a/libevmasm/CMakeLists.txt
+++ b/libevmasm/CMakeLists.txt
@@ -19,15 +19,10 @@ set(EXECUTABLE evmasm)
file(GLOB HEADERS "*.h")
-if (ETH_STATIC)
- add_library(${EXECUTABLE} STATIC ${SRC_LIST} ${HEADERS})
-else()
- add_library(${EXECUTABLE} SHARED ${SRC_LIST} ${HEADERS})
-endif()
+add_library(${EXECUTABLE} ${SRC_LIST} ${HEADERS})
target_link_libraries(${EXECUTABLE} evmcore)
target_link_libraries(${EXECUTABLE} devcrypto)
install( TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin ARCHIVE DESTINATION lib LIBRARY DESTINATION lib )
install( FILES ${HEADERS} DESTINATION include/${EXECUTABLE} )
-
diff --git a/libevmasm/CommonSubexpressionEliminator.cpp b/libevmasm/CommonSubexpressionEliminator.cpp
index 4b85eba40..e369c9dbc 100644
--- a/libevmasm/CommonSubexpressionEliminator.cpp
+++ b/libevmasm/CommonSubexpressionEliminator.cpp
@@ -45,16 +45,22 @@ vector CommonSubexpressionEliminator::getOptimizedItems()
for (int height = minHeight; height <= m_state.stackHeight(); ++height)
targetStackContents[height] = m_state.stackElement(height, SourceLocation());
- // Debug info:
- //stream(cout, initialStackContents, targetStackContents);
-
AssemblyItems items = CSECodeGenerator(m_state.expressionClasses(), m_storeOperations).generateCode(
m_initialState.stackHeight(),
initialStackContents,
targetStackContents
);
if (m_breakingItem)
+ {
items.push_back(*m_breakingItem);
+ m_state.feedItem(*m_breakingItem);
+ }
+
+ // cleanup
+ m_initialState = m_state;
+ m_breakingItem = nullptr;
+ m_storeOperations.clear();
+
return items;
}
@@ -113,16 +119,14 @@ AssemblyItems CSECodeGenerator::generateCode(
{
m_stackHeight = _initialStackHeight;
m_stack = _initialStack;
+ m_targetStack = _targetStackContents;
for (auto const& item: m_stack)
- if (!m_classPositions.count(item.second))
- m_classPositions[item.second] = item.first;
-
- // @todo: provide information about the positions of copies of class elements
+ m_classPositions[item.second].insert(item.first);
// generate the dependency graph starting from final storage and memory writes and target stack contents
for (auto const& p: m_storeOperations)
addDependencies(p.second.back().expression);
- for (auto const& targetItem: _targetStackContents)
+ for (auto const& targetItem: m_targetStack)
{
m_finalClasses.insert(targetItem.second);
addDependencies(targetItem.second);
@@ -141,13 +145,16 @@ AssemblyItems CSECodeGenerator::generateCode(
generateClassElement(seqAndId.second, true);
// generate the target stack elements
- for (auto const& targetItem: _targetStackContents)
+ for (auto const& targetItem: m_targetStack)
{
- int position = generateClassElement(targetItem.second);
- assertThrow(position != c_invalidPosition, OptimizerException, "");
- if (position == targetItem.first)
+ if (m_stack.count(targetItem.first) && m_stack.at(targetItem.first) == targetItem.second)
+ continue; // already there
+ generateClassElement(targetItem.second);
+ assertThrow(!m_classPositions[targetItem.second].empty(), OptimizerException, "");
+ if (m_classPositions[targetItem.second].count(targetItem.first))
continue;
SourceLocation const& location = m_expressionClasses.representative(targetItem.second).item->getLocation();
+ int position = classElementPosition(targetItem.second);
if (position < targetItem.first)
// it is already at its target, we need another copy
appendDup(position, location);
@@ -164,21 +171,24 @@ AssemblyItems CSECodeGenerator::generateCode(
// check validity
int finalHeight = 0;
- if (!_targetStackContents.empty())
+ if (!m_targetStack.empty())
// have target stack, so its height should be the final height
- finalHeight = (--_targetStackContents.end())->first;
+ finalHeight = (--m_targetStack.end())->first;
else if (!_initialStack.empty())
// no target stack, only erase the initial stack
finalHeight = _initialStack.begin()->first - 1;
else
// neither initial no target stack, no change in height
- finalHeight = 0;
+ finalHeight = _initialStackHeight;
assertThrow(finalHeight == m_stackHeight, OptimizerException, "Incorrect final stack height.");
+
return m_generatedItems;
}
void CSECodeGenerator::addDependencies(Id _c)
{
+ if (m_classPositions.count(_c))
+ return; // it is already on the stack
if (m_neededBy.count(_c))
return; // we already computed the dependencies for _c
ExpressionClasses::Expression expr = m_expressionClasses.representative(_c);
@@ -254,19 +264,23 @@ void CSECodeGenerator::addDependencies(Id _c)
}
}
-int CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
+void CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
{
+ for (auto it: m_classPositions)
+ for (auto p: it.second)
+ if (p > m_stackHeight)
+ assertThrow(false, OptimizerException, "");
// do some cleanup
removeStackTopIfPossible();
if (m_classPositions.count(_c))
{
assertThrow(
- m_classPositions[_c] != c_invalidPosition,
+ !m_classPositions[_c].empty(),
OptimizerException,
"Element already removed but still needed."
);
- return m_classPositions[_c];
+ return;
}
ExpressionClasses::Expression const& expr = m_expressionClasses.representative(_c);
assertThrow(
@@ -339,16 +353,16 @@ int CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
m_generatedItems.back() == AssemblyItem(Instruction::SWAP1))
// this will not append a swap but remove the one that is already there
appendOrRemoveSwap(m_stackHeight - 1, location);
- for (auto arg: arguments)
- if (canBeRemoved(arg, _c))
- m_classPositions[arg] = c_invalidPosition;
for (size_t i = 0; i < arguments.size(); ++i)
+ {
+ m_classPositions[m_stack[m_stackHeight - i]].erase(m_stackHeight - i);
m_stack.erase(m_stackHeight - i);
+ }
appendItem(*expr.item);
if (expr.item->type() != Operation || instructionInfo(expr.item->instruction()).ret == 1)
{
m_stack[m_stackHeight] = _c;
- return m_classPositions[_c] = m_stackHeight;
+ m_classPositions[_c].insert(m_stackHeight);
}
else
{
@@ -357,31 +371,39 @@ int CSECodeGenerator::generateClassElement(Id _c, bool _allowSequenced)
OptimizerException,
"Invalid number of return values."
);
- return m_classPositions[_c] = c_invalidPosition;
+ m_classPositions[_c]; // ensure it is created to mark the expression as generated
}
}
int CSECodeGenerator::classElementPosition(Id _id) const
{
assertThrow(
- m_classPositions.count(_id) && m_classPositions.at(_id) != c_invalidPosition,
+ m_classPositions.count(_id) && !m_classPositions.at(_id).empty(),
OptimizerException,
"Element requested but is not present."
);
- return m_classPositions.at(_id);
+ return *max_element(m_classPositions.at(_id).begin(), m_classPositions.at(_id).end());
}
-bool CSECodeGenerator::canBeRemoved(Id _element, Id _result)
+bool CSECodeGenerator::canBeRemoved(Id _element, Id _result, int _fromPosition)
{
- // Returns false if _element is finally needed or is needed by a class that has not been
- // computed yet. Note that m_classPositions also includes classes that were deleted in the meantime.
- if (m_finalClasses.count(_element))
- return false;
+ // Default for _fromPosition is the canonical position of the element.
+ if (_fromPosition == c_invalidPosition)
+ _fromPosition = classElementPosition(_element);
- auto range = m_neededBy.equal_range(_element);
- for (auto it = range.first; it != range.second; ++it)
- if (it->second != _result && !m_classPositions.count(it->second))
- return false;
+ bool haveCopy = m_classPositions.at(_element).size() > 1;
+ if (m_finalClasses.count(_element))
+ // It is part of the target stack. It can be removed if it is a copy that is not in the target position.
+ return haveCopy && (!m_targetStack.count(_fromPosition) || m_targetStack[_fromPosition] != _element);
+ else if (!haveCopy)
+ {
+ // Can be removed unless it is needed by a class that has not been computed yet.
+ // Note that m_classPositions also includes classes that were deleted in the meantime.
+ auto range = m_neededBy.equal_range(_element);
+ for (auto it = range.first; it != range.second; ++it)
+ if (it->second != _result && !m_classPositions.count(it->second))
+ return false;
+ }
return true;
}
@@ -391,11 +413,11 @@ bool CSECodeGenerator::removeStackTopIfPossible()
return false;
assertThrow(m_stack.count(m_stackHeight) > 0, OptimizerException, "");
Id top = m_stack[m_stackHeight];
- if (!canBeRemoved(top))
+ if (!canBeRemoved(top, Id(-1), m_stackHeight))
return false;
- m_generatedItems.push_back(AssemblyItem(Instruction::POP));
+ m_classPositions[m_stack[m_stackHeight]].erase(m_stackHeight);
m_stack.erase(m_stackHeight);
- m_stackHeight--;
+ appendItem(AssemblyItem(Instruction::POP));
return true;
}
@@ -407,6 +429,7 @@ void CSECodeGenerator::appendDup(int _fromPosition, SourceLocation const& _locat
assertThrow(1 <= instructionNum, OptimizerException, "Invalid stack access.");
appendItem(AssemblyItem(dupInstruction(instructionNum), _location));
m_stack[m_stackHeight] = m_stack[_fromPosition];
+ m_classPositions[m_stack[m_stackHeight]].insert(m_stackHeight);
}
void CSECodeGenerator::appendOrRemoveSwap(int _fromPosition, SourceLocation const& _location)
@@ -418,13 +441,15 @@ void CSECodeGenerator::appendOrRemoveSwap(int _fromPosition, SourceLocation cons
assertThrow(instructionNum <= 16, StackTooDeepException, "Stack too deep.");
assertThrow(1 <= instructionNum, OptimizerException, "Invalid stack access.");
appendItem(AssemblyItem(swapInstruction(instructionNum), _location));
- // The value of a class can be present in multiple locations on the stack. We only update the
- // "canonical" one that is tracked by m_classPositions
- if (m_classPositions[m_stack[m_stackHeight]] == m_stackHeight)
- m_classPositions[m_stack[m_stackHeight]] = _fromPosition;
- if (m_classPositions[m_stack[_fromPosition]] == _fromPosition)
- m_classPositions[m_stack[_fromPosition]] = m_stackHeight;
- swap(m_stack[m_stackHeight], m_stack[_fromPosition]);
+
+ if (m_stack[m_stackHeight] != m_stack[_fromPosition])
+ {
+ m_classPositions[m_stack[m_stackHeight]].erase(m_stackHeight);
+ m_classPositions[m_stack[m_stackHeight]].insert(_fromPosition);
+ m_classPositions[m_stack[_fromPosition]].erase(_fromPosition);
+ m_classPositions[m_stack[_fromPosition]].insert(m_stackHeight);
+ swap(m_stack[m_stackHeight], m_stack[_fromPosition]);
+ }
if (m_generatedItems.size() >= 2 &&
SemanticInformation::isSwapInstruction(m_generatedItems.back()) &&
*(m_generatedItems.end() - 2) == m_generatedItems.back())
diff --git a/libevmasm/CommonSubexpressionEliminator.h b/libevmasm/CommonSubexpressionEliminator.h
index 6e1ba40b3..a35e31d90 100644
--- a/libevmasm/CommonSubexpressionEliminator.h
+++ b/libevmasm/CommonSubexpressionEliminator.h
@@ -71,13 +71,6 @@ public:
/// @returns the resulting items after optimization.
AssemblyItems getOptimizedItems();
- /// Streams debugging information to @a _out.
- std::ostream& stream(
- std::ostream& _out,
- std::map _initialStack = std::map(),
- std::map _targetStack = std::map()
- ) const;
-
private:
/// Feeds the item into the system for analysis.
void feedItem(AssemblyItem const& _item, bool _copyItem = false);
@@ -126,16 +119,15 @@ private:
void addDependencies(Id _c);
/// Produce code that generates the given element if it is not yet present.
- /// @returns the stack position of the element or c_invalidPosition if it does not actually
- /// generate a value on the stack.
/// @param _allowSequenced indicates that sequence-constrained operations are allowed
- int generateClassElement(Id _c, bool _allowSequenced = false);
+ void generateClassElement(Id _c, bool _allowSequenced = false);
/// @returns the position of the representative of the given id on the stack.
/// @note throws an exception if it is not on the stack.
int classElementPosition(Id _id) const;
- /// @returns true if @a _element can be removed - in general or, if given, while computing @a _result.
- bool canBeRemoved(Id _element, Id _result = Id(-1));
+ /// @returns true if the copy of @a _element can be removed from stack position _fromPosition
+ /// - in general or, if given, while computing @a _result.
+ bool canBeRemoved(Id _element, Id _result = Id(-1), int _fromPosition = c_invalidPosition);
/// Appends code to remove the topmost stack element if it can be removed.
bool removeStackTopIfPossible();
@@ -157,8 +149,8 @@ private:
std::multimap m_neededBy;
/// Current content of the stack.
std::map m_stack;
- /// Current positions of equivalence classes, equal to c_invalidPosition if already deleted.
- std::map m_classPositions;
+ /// Current positions of equivalence classes, equal to the empty set if already deleted.
+ std::map> m_classPositions;
/// The actual eqivalence class items and how to compute them.
ExpressionClasses& m_expressionClasses;
@@ -167,6 +159,7 @@ private:
std::map, StoreOperations> m_storeOperations;
/// The set of equivalence classes that should be present on the stack at the end.
std::set m_finalClasses;
+ std::map m_targetStack;
};
template
@@ -175,6 +168,7 @@ _AssemblyItemIterator CommonSubexpressionEliminator::feedItems(
_AssemblyItemIterator _end
)
{
+ assertThrow(!m_breakingItem, OptimizerException, "Invalid use of CommonSubexpressionEliminator.");
for (; _iterator != _end && !SemanticInformation::breaksCSEAnalysisBlock(*_iterator); ++_iterator)
feedItem(*_iterator);
if (_iterator != _end)
diff --git a/libevmasm/ControlFlowGraph.cpp b/libevmasm/ControlFlowGraph.cpp
index 2e28317a3..cc68b2af8 100644
--- a/libevmasm/ControlFlowGraph.cpp
+++ b/libevmasm/ControlFlowGraph.cpp
@@ -142,7 +142,7 @@ void ControlFlowGraph::removeUnusedBlocks()
BasicBlock const& block = m_blocks.at(blocksToProcess.back());
blocksToProcess.pop_back();
for (BlockId tag: block.pushedTags)
- if (!neededBlocks.count(tag))
+ if (!neededBlocks.count(tag) && m_blocks.count(tag))
{
neededBlocks.insert(tag);
blocksToProcess.push_back(tag);
@@ -191,12 +191,12 @@ void ControlFlowGraph::setPrevLinks()
if (push.type() != PushTag)
continue;
BlockId nextId(push.data());
- if (m_blocks.at(nextId).prev)
+ if (m_blocks.count(nextId) && m_blocks.at(nextId).prev)
continue;
bool hasLoop = false;
- for (BlockId id = nextId; id && !hasLoop; id = m_blocks.at(id).next)
+ for (BlockId id = nextId; id && m_blocks.count(id) && !hasLoop; id = m_blocks.at(id).next)
hasLoop = (id == blockId);
- if (hasLoop)
+ if (hasLoop || !m_blocks.count(nextId))
continue;
m_blocks[nextId].prev = blockId;
@@ -225,6 +225,8 @@ void ControlFlowGraph::gatherKnowledge()
{
//@todo we might have to do something like incrementing the sequence number for each JUMPDEST
assertThrow(!!workQueue.back().first, OptimizerException, "");
+ if (!m_blocks.count(workQueue.back().first))
+ continue; // too bad, we do not know the tag, probably an invalid jump
BasicBlock& block = m_blocks.at(workQueue.back().first);
KnownStatePointer state = workQueue.back().second;
workQueue.pop_back();
@@ -281,6 +283,15 @@ void ControlFlowGraph::gatherKnowledge()
)
workQueue.push_back(make_pair(block.next, state->copy()));
}
+
+ // Remove all blocks we never visited here. This might happen because a tag is pushed but
+ // never used for a JUMP.
+ // Note that this invalidates some contents of pushedTags
+ for (auto it = m_blocks.begin(); it != m_blocks.end();)
+ if (!it->second.startState)
+ it = m_blocks.erase(it);
+ else
+ it++;
}
BasicBlocks ControlFlowGraph::rebuildCode()
@@ -288,7 +299,8 @@ BasicBlocks ControlFlowGraph::rebuildCode()
map pushes;
for (auto& idAndBlock: m_blocks)
for (BlockId ref: idAndBlock.second.pushedTags)
- pushes[ref]++;
+ if (m_blocks.count(ref))
+ pushes[ref]++;
set blocksToAdd;
for (auto it: m_blocks)
diff --git a/libevmasm/KnownState.cpp b/libevmasm/KnownState.cpp
index 41ac4802b..5a70a74fb 100644
--- a/libevmasm/KnownState.cpp
+++ b/libevmasm/KnownState.cpp
@@ -160,23 +160,51 @@ KnownState::StoreOperation KnownState::feedItem(AssemblyItem const& _item, bool
return op;
}
-void KnownState::reduceToCommonKnowledge(KnownState const& /*_other*/)
+/// Helper function for KnownState::reduceToCommonKnowledge, removes everything from
+/// _this which is not in or not equal to the value in _other.
+template void intersect(
+ _Mapping& _this,
+ _Mapping const& _other,
+ function<_KeyType(_KeyType)> const& _keyTrans = [](_KeyType _k) { return _k; }
+)
+{
+ for (auto it = _this.begin(); it != _this.end();)
+ if (_other.count(_keyTrans(it->first)) && _other.at(_keyTrans(it->first)) == it->second)
+ ++it;
+ else
+ it = _this.erase(it);
+}
+
+template void intersect(_Mapping& _this, _Mapping const& _other)
{
- //@todo
- *this = KnownState(m_expressionClasses);
+ intersect<_Mapping, ExpressionClasses::Id>(_this, _other, [](ExpressionClasses::Id _k) { return _k; });
+}
+
+void KnownState::reduceToCommonKnowledge(KnownState const& _other)
+{
+ int stackDiff = m_stackHeight - _other.m_stackHeight;
+ function stackKeyTransform = [=](int _key) -> int { return _key - stackDiff; };
+ intersect(m_stackElements, _other.m_stackElements, stackKeyTransform);
+ // Use the smaller stack height. Essential to terminate in case of loops.
+ if (m_stackHeight > _other.m_stackHeight)
+ {
+ map shiftedStack;
+ for (auto const& stackElement: m_stackElements)
+ shiftedStack[stackElement.first - stackDiff] = stackElement.second;
+ m_stackElements = move(shiftedStack);
+ m_stackHeight = _other.m_stackHeight;
+ }
+
+ intersect(m_storageContent, _other.m_storageContent);
+ intersect(m_memoryContent, _other.m_memoryContent);
}
bool KnownState::operator==(const KnownState& _other) const
{
- //@todo
- return (
- m_stackElements.empty() &&
- _other.m_stackElements.empty() &&
- m_storageContent.empty() &&
- _other.m_storageContent.empty() &&
- m_memoryContent.empty() &&
- _other.m_memoryContent.empty()
- );
+ return m_storageContent == _other.m_storageContent &&
+ m_memoryContent == _other.m_memoryContent &&
+ m_stackHeight == _other.m_stackHeight &&
+ m_stackElements == _other.m_stackElements;
}
ExpressionClasses::Id KnownState::stackElement(int _stackHeight, SourceLocation const& _location)
diff --git a/libsolidity/Compiler.cpp b/libsolidity/Compiler.cpp
index bcd4f9d68..66c503172 100644
--- a/libsolidity/Compiler.cpp
+++ b/libsolidity/Compiler.cpp
@@ -377,12 +377,16 @@ bool Compiler::visit(IfStatement const& _ifStatement)
StackHeightChecker checker(m_context);
CompilerContext::LocationSetter locationSetter(m_context, _ifStatement);
compileExpression(_ifStatement.getCondition());
- eth::AssemblyItem trueTag = m_context.appendConditionalJump();
+ m_context << eth::Instruction::ISZERO;
+ eth::AssemblyItem falseTag = m_context.appendConditionalJump();
+ eth::AssemblyItem endTag = falseTag;
+ _ifStatement.getTrueStatement().accept(*this);
if (_ifStatement.getFalseStatement())
+ {
+ endTag = m_context.appendJumpToNew();
+ m_context << falseTag;
_ifStatement.getFalseStatement()->accept(*this);
- eth::AssemblyItem endTag = m_context.appendJumpToNew();
- m_context << trueTag;
- _ifStatement.getTrueStatement().accept(*this);
+ }
m_context << endTag;
checker.check();
diff --git a/mix/ClientModel.cpp b/mix/ClientModel.cpp
index b355c336f..a6eadbf4a 100644
--- a/mix/ClientModel.cpp
+++ b/mix/ClientModel.cpp
@@ -316,7 +316,6 @@ void ClientModel::executeSequence(vector const& _sequence,
TransactionSettings stdTransaction = transaction;
stdTransaction.gasAuto = true;
Address address = deployContract(stdContractCode, stdTransaction);
- deployedContracts.push_back(address);
m_stdContractAddresses[stdTransaction.contractId] = address;
m_stdContractNames[address] = stdTransaction.contractId;
}
diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp
index 636a665e6..5c6ec07c0 100644
--- a/mix/CodeModel.cpp
+++ b/mix/CodeModel.cpp
@@ -219,6 +219,19 @@ void CodeModel::reset(QVariantMap const& _documents)
emit scheduleCompilationJob(++m_backgroundJobId);
}
+void CodeModel::unregisterContractSrc(QString const& _documentId)
+{
+ {
+ Guard pl(x_pendingContracts);
+ m_pendingContracts.erase(_documentId);
+ }
+
+ // launch the background thread
+ m_compiling = true;
+ emit stateChanged();
+ emit scheduleCompilationJob(++m_backgroundJobId);
+}
+
void CodeModel::registerCodeChange(QString const& _documentId, QString const& _code)
{
{
diff --git a/mix/CodeModel.h b/mix/CodeModel.h
index 3f713a17b..a0b03951f 100644
--- a/mix/CodeModel.h
+++ b/mix/CodeModel.h
@@ -160,6 +160,8 @@ public:
Q_INVOKABLE CompiledContract* contractByDocumentId(QString const& _documentId) const;
/// Reset code model
Q_INVOKABLE void reset() { reset(QVariantMap()); }
+ /// Delete a contract source
+ Q_INVOKABLE void unregisterContractSrc(QString const& _documentId);
/// Convert solidity type info to mix type
static SolidityType nodeType(dev::solidity::Type const* _type);
/// Check if given location belongs to contract or function
diff --git a/mix/FileIo.cpp b/mix/FileIo.cpp
index 0991aa63d..22538194c 100644
--- a/mix/FileIo.cpp
+++ b/mix/FileIo.cpp
@@ -210,3 +210,9 @@ void FileIo::stopWatching(QString const& _path)
{
m_watcher->removePath(pathFromUrl(_path));
}
+
+void FileIo::deleteFile(QString const& _path)
+{
+ QFile file(pathFromUrl(_path));
+ file.remove();
+}
diff --git a/mix/FileIo.h b/mix/FileIo.h
index 33c2bd5fd..90a143120 100644
--- a/mix/FileIo.h
+++ b/mix/FileIo.h
@@ -66,6 +66,8 @@ public:
Q_INVOKABLE void watchFileChanged(QString const& _path);
/// Stop Listenning for files change in @arg _path.
Q_INVOKABLE void stopWatching(QString const& _path);
+ /// Delete a file
+ Q_INVOKABLE void deleteFile(QString const& _path);
private:
QString getHomePath() const;
diff --git a/mix/qml/CodeEditorView.qml b/mix/qml/CodeEditorView.qml
index e4d62ed81..bb7e203bf 100644
--- a/mix/qml/CodeEditorView.qml
+++ b/mix/qml/CodeEditorView.qml
@@ -190,9 +190,12 @@ Item {
for (var i = 0; i < openDocCount; i++)
{
var doc = editorListModel.get(i);
- var editor = editors.itemAt(i).item;
- if (editor)
- fileIo.writeFile(doc.path, editor.getText());
+ if (editors.itemAt(i))
+ {
+ var editor = editors.itemAt(i).item;
+ if (editor)
+ fileIo.writeFile(doc.path, editor.getText());
+ }
}
}
@@ -315,6 +318,16 @@ Item {
break;
}
}
+
+ onDocumentRemoved: {
+ for (var i = 0; i < editorListModel.count; i++)
+ if (editorListModel.get(i).documentId === documentId)
+ {
+ editorListModel.remove(i);
+ openDocCount--;
+ break;
+ }
+ }
}
function loadIfNotLoaded () {
diff --git a/mix/qml/FilesSection.qml b/mix/qml/FilesSection.qml
index d89875583..5e49143a7 100644
--- a/mix/qml/FilesSection.qml
+++ b/mix/qml/FilesSection.qml
@@ -3,6 +3,7 @@ import QtQuick.Window 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 1.0
import QtQuick.Controls.Styles 1.3
+import QtQuick.Dialogs 1.2
import "."
@@ -241,8 +242,13 @@ Rectangle
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
onClicked:{
- if (mouse.button === Qt.RightButton && !isContract)
- contextMenu.popup();
+ if (mouse.button === Qt.RightButton)
+ {
+ if (isContract)
+ contextMenuContract.popup();
+ else
+ contextMenu.popup();
+ }
else if (mouse.button === Qt.LeftButton)
{
rootItem.isSelected = true;
@@ -263,11 +269,32 @@ Rectangle
MenuItem {
text: qsTr("Delete")
onTriggered: {
- projectModel.removeDocument(documentId);
- wrapperItem.removeDocument(documentId);
+ deleteConfirmation.open();
}
}
}
+
+ Menu {
+ id: contextMenuContract
+ MenuItem {
+ text: qsTr("Delete")
+ onTriggered: {
+ deleteConfirmation.open();
+ }
+ }
+ }
+
+ MessageDialog
+ {
+ id: deleteConfirmation
+ text: qsTr("Are you sure to delete this file ?")
+ standardButtons: StandardIcon.Ok | StandardIcon.Cancel
+ onAccepted:
+ {
+ projectModel.removeDocument(documentId);
+ wrapperItem.removeDocument(documentId);
+ }
+ }
}
}
}
diff --git a/mix/qml/js/ProjectModel.js b/mix/qml/js/ProjectModel.js
index 6ec906996..6fce7686d 100644
--- a/mix/qml/js/ProjectModel.js
+++ b/mix/qml/js/ProjectModel.js
@@ -294,7 +294,10 @@ function renameDocument(documentId, newName) {
function getDocument(documentId) {
var i = getDocumentIndex(documentId);
- return projectListModel.get(i);
+ if (i === -1)
+ return undefined;
+ else
+ return projectListModel.get(i);
}
function getDocumentIdByName(fileName)
@@ -308,10 +311,13 @@ function getDocumentIdByName(fileName)
function removeDocument(documentId) {
var i = getDocumentIndex(documentId);
var document = projectListModel.get(i);
- if (!document.isContract) {
- projectListModel.remove(i);
- documentRemoved(documentId);
- }
+ fileIo.stopWatching(document.path);
+ fileIo.deleteFile(document.path);
+ if (document.isContract)
+ codeModel.unregisterContractSrc(documentId);
+ projectListModel.remove(i);
+ saveProjectFile();
+ documentRemoved(documentId);
}
function newHtmlFile() {
diff --git a/mix/test/qml/TestMain.qml b/mix/test/qml/TestMain.qml
index 829364a99..727d90b25 100644
--- a/mix/test/qml/TestMain.qml
+++ b/mix/test/qml/TestMain.qml
@@ -113,5 +113,6 @@ TestCase
function test_project_contractRename() { TestProject.test_contractRename(); }
function test_project_multipleWebPages() { TestProject.test_multipleWebPages(); }
function test_project_multipleContractsSameFile() { TestProject.test_multipleContractsSameFile(); }
+ function test_project_deleteFile() { TestProject.test_deleteFile(); }
}
diff --git a/mix/test/qml/js/TestDebugger.js b/mix/test/qml/js/TestDebugger.js
index 4933136ff..4e295c46f 100644
--- a/mix/test/qml/js/TestDebugger.js
+++ b/mix/test/qml/js/TestDebugger.js
@@ -223,13 +223,16 @@ function test_ctrTypeAsParam()
"}");
mainApplication.projectModel.stateListModel.editState(0); //C1 ctor already added
var transactionDialog = mainApplication.projectModel.stateDialog.transactionDialog;
+ mainApplication.projectModel.stateDialog.model.editTransaction(3);
+ ts.waitForRendering(transactionDialog, 3000);
+ clickElement(transactionDialog, 200, 300);
+ ts.typeString("", transactionDialog);
+ transactionDialog.acceptAndClose();
mainApplication.projectModel.stateDialog.model.addTransaction();
transactionDialog = mainApplication.projectModel.stateDialog.transactionDialog;
ts.waitForRendering(transactionDialog, 3000);
transactionDialog.selectContract("C2");
transactionDialog.selectFunction("getFromC1");
- clickElement(transactionDialog, 406, 340);
- clickElement(transactionDialog, 406, 366);
transactionDialog.acceptAndClose();
mainApplication.projectModel.stateDialog.acceptAndClose();
mainApplication.mainContent.startQuickDebugging();
diff --git a/mix/test/qml/js/TestProject.js b/mix/test/qml/js/TestProject.js
index 49b5ea51f..fe1023f05 100644
--- a/mix/test/qml/js/TestProject.js
+++ b/mix/test/qml/js/TestProject.js
@@ -44,3 +44,17 @@ function test_multipleContractsSameFile()
tryCompare(mainApplication.mainContent.rightPane.transactionLog.transactionModel.get(3), "contract", "C2");
tryCompare(mainApplication.mainContent.rightPane.transactionLog.transactionModel.get(4), "contract", "C3");
}
+
+function test_deleteFile()
+{
+ newProject();
+ var path = mainApplication.projectModel.projectPath;
+ createHtml("page1.html", "Fail
");
+ createHtml("page2.html", "Fail
");
+ createHtml("page3.html", "Fail
");
+ mainApplication.projectModel.removeDocument("page2.html");
+ mainApplication.projectModel.closeProject(function(){});
+ mainApplication.projectModel.loadProject(path);
+ var doc = mainApplication.projectModel.getDocument("page2.html");
+ verify(!doc, "page2.html has not been removed");
+}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 39a235c58..bedbe42f3 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -95,6 +95,12 @@ if (JSONRPC)
target_link_libraries(testeth ${JSON_RPC_CPP_CLIENT_LIBRARIES})
endif()
+if (UNIX) # Create symlink to old testeth location to make bildbot happy
+ add_custom_command(TARGET testeth POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_BINARY_DIR}/bin/testeth ${CMAKE_BINARY_DIR}/test/testeth
+ )
+endif()
+
enable_testing()
set(CTEST_OUTPUT_ON_FAILURE TRUE)
@@ -110,7 +116,6 @@ eth_add_test(ClientBase
)
eth_add_test(JsonRpc
- ARGS --eth_testfile=BlockTests/bcJS_API_Test
+ ARGS --eth_testfile=BlockTests/bcJS_API_Test
ARGS --eth_testfile=BlockTests/bcValidBlockTest
)
-
diff --git a/test/TestHelper.cpp b/test/TestHelper.cpp
index 96e11e02c..14d845a31 100644
--- a/test/TestHelper.cpp
+++ b/test/TestHelper.cpp
@@ -288,7 +288,7 @@ void ImportTest::checkExpectedState(State const& _stateExpect, State const& _sta
{
addressOptions = _expectedStateOptions.at(a.first);
}
- catch(std::out_of_range)
+ catch(std::out_of_range const&)
{
BOOST_ERROR("expectedStateOptions map does not match expectedState in checkExpectedState!");
break;
@@ -549,58 +549,53 @@ void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _e
}
}
-void userDefinedTest(string testTypeFlag, std::function doTests)
+void userDefinedTest(std::function doTests)
{
- Options::get(); // parse command line options, e.g. to enable JIT
+ if (!Options::get().singleTest)
+ return;
- for (int i = 1; i < boost::unit_test::framework::master_test_suite().argc; ++i)
+ if (Options::get().singleTestFile.empty() || Options::get().singleTestName.empty())
{
- string arg = boost::unit_test::framework::master_test_suite().argv[i];
- if (arg == testTypeFlag)
- {
- if (boost::unit_test::framework::master_test_suite().argc <= i + 2)
- {
- cnote << "Missing filename\nUsage: testeth " << testTypeFlag << " \n";
- return;
- }
- string filename = boost::unit_test::framework::master_test_suite().argv[i + 1];
- string testname = boost::unit_test::framework::master_test_suite().argv[i + 2];
- int currentVerbosity = g_logVerbosity;
- g_logVerbosity = 12;
- try
- {
- cnote << "Testing user defined test: " << filename;
- json_spirit::mValue v;
- string s = asString(contents(filename));
- BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. ");
- json_spirit::read_string(s, v);
- json_spirit::mObject oSingleTest;
-
- json_spirit::mObject::const_iterator pos = v.get_obj().find(testname);
- if (pos == v.get_obj().end())
- {
- cnote << "Could not find test: " << testname << " in " << filename << "\n";
- return;
- }
- else
- oSingleTest[pos->first] = pos->second;
+ cnote << "Missing user test specification\nUsage: testeth --singletest \n";
+ return;
+ }
- json_spirit::mValue v_singleTest(oSingleTest);
- doTests(v_singleTest, false);
- }
- catch (Exception const& _e)
- {
- BOOST_ERROR("Failed Test with Exception: " << diagnostic_information(_e));
- g_logVerbosity = currentVerbosity;
- }
- catch (std::exception const& _e)
- {
- BOOST_ERROR("Failed Test with Exception: " << _e.what());
- g_logVerbosity = currentVerbosity;
- }
- g_logVerbosity = currentVerbosity;
+ auto& filename = Options::get().singleTestFile;
+ auto& testname = Options::get().singleTestName;
+ int currentVerbosity = g_logVerbosity;
+ g_logVerbosity = 12;
+ try
+ {
+ cnote << "Testing user defined test: " << filename;
+ json_spirit::mValue v;
+ string s = asString(contents(filename));
+ BOOST_REQUIRE_MESSAGE(s.length() > 0, "Contents of " + filename + " is empty. ");
+ json_spirit::read_string(s, v);
+ json_spirit::mObject oSingleTest;
+
+ json_spirit::mObject::const_iterator pos = v.get_obj().find(testname);
+ if (pos == v.get_obj().end())
+ {
+ cnote << "Could not find test: " << testname << " in " << filename << "\n";
+ return;
}
+ else
+ oSingleTest[pos->first] = pos->second;
+
+ json_spirit::mValue v_singleTest(oSingleTest);
+ doTests(v_singleTest, false);
}
+ catch (Exception const& _e)
+ {
+ BOOST_ERROR("Failed Test with Exception: " << diagnostic_information(_e));
+ g_logVerbosity = currentVerbosity;
+ }
+ catch (std::exception const& _e)
+ {
+ BOOST_ERROR("Failed Test with Exception: " << _e.what());
+ g_logVerbosity = currentVerbosity;
+ }
+ g_logVerbosity = currentVerbosity;
}
void executeTests(const string& _name, const string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function doTests)
@@ -707,10 +702,9 @@ Options::Options()
{
auto arg = std::string{argv[i]};
if (arg == "--jit")
- {
- jit = true;
eth::VMFactory::setKind(eth::VMKind::JIT);
- }
+ else if (arg == "--vm=smart")
+ eth::VMFactory::setKind(eth::VMKind::Smart);
else if (arg == "--vmtrace")
vmtrace = true;
else if (arg == "--filltests")
@@ -743,7 +737,20 @@ Options::Options()
else if (arg == "--singletest" && i + 1 < argc)
{
singleTest = true;
- singleTestName = argv[i + 1];
+ auto name1 = std::string{argv[i + 1]};
+ if (i + 1 < argc) // two params
+ {
+ auto name2 = std::string{argv[i + 2]};
+ if (name2[0] == '-') // not param, another option
+ singleTestName = std::move(name1);
+ else
+ {
+ singleTestFile = std::move(name1);
+ singleTestName = std::move(name2);
+ }
+ }
+ else
+ singleTestName = std::move(name1);
}
}
}
diff --git a/test/TestHelper.h b/test/TestHelper.h
index 02f509e4c..d1da7e24b 100644
--- a/test/TestHelper.h
+++ b/test/TestHelper.h
@@ -157,7 +157,7 @@ void checkLog(eth::LogEntries _resultLogs, eth::LogEntries _expectedLogs);
void checkCallCreates(eth::Transactions _resultCallCreates, eth::Transactions _expectedCallCreates);
void executeTests(const std::string& _name, const std::string& _testPathAppendix, const boost::filesystem::path _pathToFiller, std::function doTests);
-void userDefinedTest(std::string testTypeFlag, std::function doTests);
+void userDefinedTest(std::function doTests);
RLPStream createRLPStreamFromTransactionFields(json_spirit::mObject& _tObj);
eth::LastHashes lastHashes(u256 _currentBlockNumber);
json_spirit::mObject fillJsonWithState(eth::State _state);
@@ -179,7 +179,6 @@ void checkAddresses(mapType& _expectedAddrs, mapType& _resultAddrs)
class Options
{
public:
- bool jit = false; ///< Use JIT
bool vmtrace = false; ///< Create EVM execution tracer // TODO: Link with log verbosity?
bool fillTests = false; ///< Create JSON test files from execution results
bool stats = false; ///< Execution time stats
@@ -189,6 +188,7 @@ public:
/// Test selection
/// @{
bool singleTest = false;
+ std::string singleTestFile;
std::string singleTestName;
bool performance = false;
bool quadratic = false;
diff --git a/test/libdevcrypto/trie.cpp b/test/libdevcrypto/trie.cpp
index 3b3fa1dd2..d41739a01 100644
--- a/test/libdevcrypto/trie.cpp
+++ b/test/libdevcrypto/trie.cpp
@@ -102,10 +102,13 @@ BOOST_AUTO_TEST_CASE(hex_encoded_securetrie_test)
{
next_permutation(ss.begin(), ss.end());
MemoryDB m;
+ EnforceRefs r(m, true);
GenericTrieDB t(&m);
MemoryDB hm;
+ EnforceRefs hr(hm, true);
HashedGenericTrieDB ht(&hm);
MemoryDB fm;
+ EnforceRefs fr(fm, true);
FatGenericTrieDB ft(&fm);
t.init();
ht.init();
@@ -164,10 +167,13 @@ BOOST_AUTO_TEST_CASE(trie_test_anyorder)
{
next_permutation(ss.begin(), ss.end());
MemoryDB m;
+ EnforceRefs r(m, true);
GenericTrieDB t(&m);
MemoryDB hm;
+ EnforceRefs hr(hm, true);
HashedGenericTrieDB ht(&hm);
MemoryDB fm;
+ EnforceRefs fr(fm, true);
FatGenericTrieDB ft(&fm);
t.init();
ht.init();
@@ -244,10 +250,13 @@ BOOST_AUTO_TEST_CASE(trie_tests_ordered)
}
MemoryDB m;
+ EnforceRefs r(m, true);
GenericTrieDB t(&m);
MemoryDB hm;
+ EnforceRefs hr(hm, true);
HashedGenericTrieDB ht(&hm);
MemoryDB fm;
+ EnforceRefs fr(fm, true);
FatGenericTrieDB ft(&fm);
t.init();
ht.init();
@@ -360,6 +369,7 @@ BOOST_AUTO_TEST_CASE(moreTrieTests)
#endif
{
MemoryDB m;
+ EnforceRefs r(m, true);
GenericTrieDB d(&m);
d.init(); // initialise as empty tree.
MemTrie t;
diff --git a/test/libethcore/dagger.cpp b/test/libethcore/dagger.cpp
index 119780346..4faf0a283 100644
--- a/test/libethcore/dagger.cpp
+++ b/test/libethcore/dagger.cpp
@@ -63,14 +63,14 @@ BOOST_AUTO_TEST_CASE(basic_test)
unsigned cacheSize(o["cache_size"].get_int());
h256 cacheHash(o["cache_hash"].get_str());
- BOOST_REQUIRE_EQUAL(EthashAux::get()->params(header).cache_size, cacheSize);
+ BOOST_REQUIRE_EQUAL(EthashAux::get()->light(header)->size, cacheSize);
BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->light(header)->data()), cacheHash);
#if TEST_FULL
unsigned fullSize(o["full_size"].get_int());
h256 fullHash(o["full_hash"].get_str());
- BOOST_REQUIRE_EQUAL(EthashAux::get()->full(header).size(), fullSize);
- BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->full(header)), fullHash);
+ BOOST_REQUIRE_EQUAL(EthashAux::get()->full(header)->size(), fullSize);
+ BOOST_REQUIRE_EQUAL(sha3(EthashAux::get()->full(header)->data()), fullHash);
#endif
h256 result(o["result"].get_str());
diff --git a/test/libethereum/blockchain.cpp b/test/libethereum/blockchain.cpp
index c5ac936fe..2f76e43ae 100644
--- a/test/libethereum/blockchain.cpp
+++ b/test/libethereum/blockchain.cpp
@@ -792,7 +792,7 @@ BOOST_AUTO_TEST_CASE(bcWalletTest)
BOOST_AUTO_TEST_CASE(userDefinedFile)
{
- dev::test::userDefinedTest("--singletest", dev::test::doBlockchainTests);
+ dev::test::userDefinedTest(dev::test::doBlockchainTests);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libethereum/state.cpp b/test/libethereum/state.cpp
index b682056ee..fe0f10ca3 100644
--- a/test/libethereum/state.cpp
+++ b/test/libethereum/state.cpp
@@ -265,7 +265,7 @@ BOOST_AUTO_TEST_CASE(stRandom)
BOOST_AUTO_TEST_CASE(userDefinedFileState)
{
- dev::test::userDefinedTest("--singletest", dev::test::doStateTests);
+ dev::test::userDefinedTest(dev::test::doStateTests);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libethereum/transaction.cpp b/test/libethereum/transaction.cpp
index 058d03322..017e51ded 100644
--- a/test/libethereum/transaction.cpp
+++ b/test/libethereum/transaction.cpp
@@ -195,7 +195,7 @@ BOOST_AUTO_TEST_CASE(ttCreateTest)
BOOST_AUTO_TEST_CASE(userDefinedFile)
{
- dev::test::userDefinedTest("--singletest", dev::test::doTransactionTests);
+ dev::test::userDefinedTest(dev::test::doTransactionTests);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libevm/vm.cpp b/test/libevm/vm.cpp
index 4c666dbba..090258244 100644
--- a/test/libevm/vm.cpp
+++ b/test/libevm/vm.cpp
@@ -432,7 +432,7 @@ void doVMTests(json_spirit::mValue& v, bool _fillin)
}
}
-} } // Namespace Close
+} } // namespace close
BOOST_AUTO_TEST_SUITE(VMTests)
@@ -542,7 +542,7 @@ BOOST_AUTO_TEST_CASE(vmRandom)
BOOST_AUTO_TEST_CASE(userDefinedFile)
{
- dev::test::userDefinedTest("--singletest", dev::test::doVMTests);
+ dev::test::userDefinedTest(dev::test::doVMTests);
}
BOOST_AUTO_TEST_SUITE_END()
diff --git a/test/libp2p/capability.cpp b/test/libp2p/capability.cpp
new file mode 100644
index 000000000..2c158f4d8
--- /dev/null
+++ b/test/libp2p/capability.cpp
@@ -0,0 +1,150 @@
+/*
+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 .
+*/
+/** @file capability.cpp
+* @author Vladislav Gluhovsky
+* @date May 2015
+*/
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace std;
+using namespace dev;
+using namespace dev::p2p;
+
+struct P2PFixture
+{
+ P2PFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = true; }
+ ~P2PFixture() { dev::p2p::NodeIPEndpoint::test_allowLocal = false; }
+};
+
+struct VerbosityHolder
+{
+ VerbosityHolder(): oldLogVerbosity(g_logVerbosity) { g_logVerbosity = 10; }
+ ~VerbosityHolder() { g_logVerbosity = oldLogVerbosity; }
+
+ int oldLogVerbosity;
+};
+
+class TestCapability: public Capability
+{
+public:
+ TestCapability(Session* _s, HostCapabilityFace* _h, unsigned _idOffset): Capability(_s, _h, _idOffset), m_cntReceivedMessages(0), m_testSum(0) {}
+ virtual ~TestCapability() {}
+ int countReceivedMessages() { return m_cntReceivedMessages; }
+ int testSum() { return m_testSum; }
+ static std::string name() { return "test"; }
+ static u256 version() { return 2; }
+ static unsigned messageCount() { return UserPacket + 1; }
+ void sendTestMessage(int _i) { RLPStream s; sealAndSend(prep(s, UserPacket, 1) << _i); }
+
+protected:
+ virtual bool interpret(unsigned _id, RLP const& _r) override;
+
+ int m_cntReceivedMessages;
+ int m_testSum;
+};
+
+bool TestCapability::interpret(unsigned _id, RLP const& _r)
+{
+ cnote << "Capability::interpret(): custom message received";
+ ++m_cntReceivedMessages;
+ m_testSum += _r[0].toInt();
+ BOOST_ASSERT(_id == UserPacket);
+ return (_id == UserPacket);
+}
+
+class TestHostCapability: public HostCapability, public Worker
+{
+public:
+ TestHostCapability(): Worker("test") {}
+ virtual ~TestHostCapability() {}
+
+ void sendTestMessage(NodeId const& _id, int _x)
+ {
+ for (auto i: peerSessions())
+ if (_id == i.second->id)
+ i.first->cap().get()->sendTestMessage(_x);
+ }
+
+ std::pair retrieveTestData(NodeId const& _id)
+ {
+ int cnt = 0;
+ int checksum = 0;
+ for (auto i: peerSessions())
+ if (_id == i.second->id)
+ {
+ cnt += i.first->cap().get()->countReceivedMessages();
+ checksum += i.first->cap().get()->testSum();
+ }
+
+ return std::pair(cnt, checksum);
+ }
+};
+
+BOOST_FIXTURE_TEST_SUITE(p2pCapability, P2PFixture)
+
+BOOST_AUTO_TEST_CASE(capability)
+{
+ VerbosityHolder verbosityHolder;
+ cnote << "Testing Capability...";
+
+ const char* const localhost = "127.0.0.1";
+ NetworkPreferences prefs1(localhost, 30301, false);
+ NetworkPreferences prefs2(localhost, 30302, false);
+
+ Host host1("Test", prefs1);
+ auto thc1 = host1.registerCapability(new TestHostCapability());
+ host1.start();
+
+ Host host2("Test", prefs2);
+ auto thc2 = host2.registerCapability(new TestHostCapability());
+ host2.start();
+
+ int const step = 10;
+
+ for (int i = 0; i < 3000 && (!host1.isStarted() || !host2.isStarted()); i += step)
+ this_thread::sleep_for(chrono::milliseconds(step));
+
+ BOOST_REQUIRE(host1.isStarted() && host2.isStarted());
+ host1.requirePeer(host2.id(), NodeIPEndpoint(bi::address::from_string(localhost), prefs2.listenPort, prefs2.listenPort));
+
+ for (int i = 0; i < 3000 && (!host1.peerCount() || !host2.peerCount()); i += step)
+ this_thread::sleep_for(chrono::milliseconds(step));
+
+ BOOST_REQUIRE(host1.peerCount() > 0 && host2.peerCount() > 0);
+
+ int const target = 7;
+ int checksum = 0;
+ for (int i = 0; i < target; checksum += i++)
+ thc2->sendTestMessage(host1.id(), i);
+
+ this_thread::sleep_for(chrono::seconds(1));
+ std::pair testData = thc1->retrieveTestData(host2.id());
+ BOOST_REQUIRE_EQUAL(target, testData.first);
+ BOOST_REQUIRE_EQUAL(checksum, testData.second);
+}
+
+BOOST_AUTO_TEST_SUITE_END()
+
+
diff --git a/test/libsolidity/SolidityCompiler.cpp b/test/libsolidity/SolidityCompiler.cpp
index aa83c4650..dda7847ed 100644
--- a/test/libsolidity/SolidityCompiler.cpp
+++ b/test/libsolidity/SolidityCompiler.cpp
@@ -116,36 +116,35 @@ BOOST_AUTO_TEST_CASE(ifStatement)
bytes code = compileContract(sourceCode);
unsigned shift = 60;
unsigned boilerplateSize = 73;
- bytes expectation({byte(Instruction::JUMPDEST),
- byte(Instruction::PUSH1), 0x0,
- byte(Instruction::DUP1),
- byte(Instruction::PUSH1), byte(0x1b + shift), // "true" target
- byte(Instruction::JUMPI),
- // new check "else if" condition
- byte(Instruction::DUP1),
- byte(Instruction::ISZERO),
- byte(Instruction::PUSH1), byte(0x13 + shift),
- byte(Instruction::JUMPI),
- // "else" body
- byte(Instruction::PUSH1), 0x4f,
- byte(Instruction::POP),
- byte(Instruction::PUSH1), byte(0x17 + shift), // exit path of second part
- byte(Instruction::JUMP),
- // "else if" body
- byte(Instruction::JUMPDEST),
- byte(Instruction::PUSH1), 0x4e,
- byte(Instruction::POP),
- byte(Instruction::JUMPDEST),
- byte(Instruction::PUSH1), byte(0x1f + shift),
- byte(Instruction::JUMP),
- // "if" body
- byte(Instruction::JUMPDEST),
- byte(Instruction::PUSH1), 0x4d,
- byte(Instruction::POP),
- byte(Instruction::JUMPDEST),
- byte(Instruction::JUMPDEST),
- byte(Instruction::POP),
- byte(Instruction::JUMP)});
+ bytes expectation({
+ byte(Instruction::JUMPDEST),
+ byte(Instruction::PUSH1), 0x0,
+ byte(Instruction::DUP1),
+ byte(Instruction::ISZERO),
+ byte(Instruction::PUSH1), byte(0x0f + shift), // "false" target
+ byte(Instruction::JUMPI),
+ // "if" body
+ byte(Instruction::PUSH1), 0x4d,
+ byte(Instruction::POP),
+ byte(Instruction::PUSH1), byte(0x21 + shift),
+ byte(Instruction::JUMP),
+ // new check "else if" condition
+ byte(Instruction::JUMPDEST),
+ byte(Instruction::DUP1),
+ byte(Instruction::ISZERO),
+ byte(Instruction::ISZERO),
+ byte(Instruction::PUSH1), byte(0x1c + shift),
+ byte(Instruction::JUMPI),
+ // "else if" body
+ byte(Instruction::PUSH1), 0x4e,
+ byte(Instruction::POP),
+ byte(Instruction::PUSH1), byte(0x20 + shift),
+ byte(Instruction::JUMP),
+ // "else" body
+ byte(Instruction::JUMPDEST),
+ byte(Instruction::PUSH1), 0x4f,
+ byte(Instruction::POP),
+ });
checkCodePresentAt(code, expectation, boilerplateSize);
}
diff --git a/test/libsolidity/SolidityOptimizer.cpp b/test/libsolidity/SolidityOptimizer.cpp
index 3cb6a536a..efc9316b0 100644
--- a/test/libsolidity/SolidityOptimizer.cpp
+++ b/test/libsolidity/SolidityOptimizer.cpp
@@ -29,6 +29,7 @@
#include
#include
#include
+#include