Browse Source

Merge branch 'develop'

Conflicts:
	alethzero/MainWin.cpp
	libethereum/Common.h
cl-refactor
Gav Wood 11 years ago
parent
commit
02f843b6e4
  1. 5
      .gitignore
  2. 55
      BuildInfo.sh
  3. 17
      CMakeLists.txt
  4. 89
      TODO
  5. 4
      alethzero/CMakeLists.txt
  6. 39
      alethzero/MainWin.cpp
  7. 10
      eth/main.cpp
  8. 30
      libethereum/Client.cpp
  9. 15
      libethereum/Client.h
  10. 5
      libethereum/Common.h
  11. 1
      libethereum/Defaults.h
  12. 2
      libethereum/Exceptions.h
  13. 20
      libethereum/PeerNetwork.cpp
  14. 3
      libethereum/PeerNetwork.h
  15. 46
      libethereum/State.cpp
  16. 22
      libethereum/Transaction.cpp
  17. 24
      libethereum/TransactionQueue.cpp
  18. 6
      libethereum/TransactionQueue.h
  19. 8
      libethereum/TrieDB.h
  20. 9
      release.sh
  21. 1
      test/crypto.cpp
  22. 1
      test/dagger.cpp
  23. 69
      test/hexPrefix.cpp
  24. 18
      test/main.cpp
  25. 90
      test/rlp.cpp
  26. 2
      test/state.cpp
  27. 54
      test/trie.cpp
  28. 1
      test/vm.cpp
  29. 82
      test/vmtests.json
  30. 33
      windows/Alethzero.vcxproj
  31. 3
      windows/Alethzero.vcxproj.filters
  32. 25
      windows/BuildInfo.lua
  33. 25
      windows/Ethereum.vcxproj
  34. 16
      windows/Ethereum.vcxproj.filters
  35. 6
      windows/LibEthereum.props
  36. 6
      windows/UseQt.props

5
.gitignore

@ -19,4 +19,9 @@ ipch
*.opensdf *.opensdf
*.suo *.suo
# Generated headers
*.h
*.user *.user
*.user.*
*~

55
BuildInfo.sh

@ -0,0 +1,55 @@
CURRENT_SOURCE_DIR=$1
CURRENT_BINARY_DIR=$2
BUILD_TYPE=$3
BUILD_PLATFORM=$4
echo "Current source dir: $CURRENT_SOURCE_DIR"
echo "Current binary dir: $CURRENT_BINARY_DIR"
echo "Build type: $BUILD_TYPE"
echo "Build platform: $BUILD_PLATFORM"
if [[ -e "$CURRENT_SOURCE_DIR/BuildInfo.h" ]]
then
echo "Using existing BuildInfo.h"
cp $CURRENT_SOURCE_DIR/BuildInfo.h $CURRENT_BINARY_DIR/BuildInfo.h.tmp
else
if [[ -e "$CURRENT_SOURCE_DIR/.git" ]]
then
ETH_COMMIT_HASH=$(git --git-dir=$CURRENT_SOURCE_DIR/.git --work-tree=$CURRENT_SOURCE_DIR rev-parse HEAD)
ETH_LOCAL_CHANGES=$(git --git-dir=$CURRENT_SOURCE_DIR/.git --work-tree=$CURRENT_SOURCE_DIR diff --shortstat)
if [[ -z "$ETH_LOCAL_CHANGES" ]]
then
ETH_CLEAN_REPO=1
else
ETH_CLEAN_REPO=0
fi
echo "Commit hash: ${ETH_COMMIT_HASH} (Clean: ${ETH_CLEAN_REPO} - ${ETH_LOCAL_CHANGES})"
else
echo "Unknown repo."
ETH_COMMIT_HASH=0
ETH_CLEAN_REPO=1
fi
echo "// This file was automatically generated by cmake" > $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#pragma once" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#define ETH_COMMIT_HASH $ETH_COMMIT_HASH" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#define ETH_CLEAN_REPO $ETH_CLEAN_REPO" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#define ETH_BUILD_TYPE $BUILD_TYPE" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
echo "#define ETH_BUILD_PLATFORM $BUILD_PLATFORM" >> $CURRENT_BINARY_DIR/BuildInfo.h.tmp
fi
if [[ -e "$CURRENT_BINARY_DIR/BuildInfo.h" ]]
then
DIFF=$(diff $CURRENT_BINARY_DIR/BuildInfo.h $CURRENT_BINARY_DIR/BuildInfo.h.tmp)
if [[ -z "$DIFF" ]]
then
rm $CURRENT_BINARY_DIR/BuildInfo.h.tmp
else
mv $CURRENT_BINARY_DIR/BuildInfo.h.tmp $CURRENT_BINARY_DIR/BuildInfo.h
fi
else
mv $CURRENT_BINARY_DIR/BuildInfo.h.tmp $CURRENT_BINARY_DIR/BuildInfo.h
fi

17
CMakeLists.txt

@ -5,8 +5,6 @@ set(CMAKE_AUTOMOC ON)
cmake_policy(SET CMP0015 NEW) cmake_policy(SET CMP0015 NEW)
set(ETH_BUILD_TYPE ${CMAKE_BUILD_TYPE})
# Default HEADLESS to 0. # Default HEADLESS to 0.
set(HEADLESS CACHE BOOL 0) set(HEADLESS CACHE BOOL 0)
if ("x${HEADLESS}" STREQUAL "x") if ("x${HEADLESS}" STREQUAL "x")
@ -66,9 +64,8 @@ set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG") set(CMAKE_CXX_FLAGS_RELEASE "-O4 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
add_definitions("-DETH_BUILD_TYPE=${ETH_BUILD_TYPE}") #add_definitions("-DETH_BUILD_TYPE=${ETH_BUILD_TYPE}")
add_definitions("-DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}") #add_definitions("-DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}")
#set(CMAKE_CXX_FLAGS, "${CMAKE_CXX_FLAGS} -DETH_VERSION=${ETH_VERSION} -DETH_BUILD_TYPE=${ETH_BUILD_TYPE} -DETH_BUILD_PLATFORM=${ETH_BUILD_PLATFORM}")
# Compiler-specific C++11 activation. # Compiler-specific C++11 activation.
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU") if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
@ -134,15 +131,19 @@ else ()
# Always "found", given last block. # Always "found", given last block.
include_directories(${CRYPTOPP_INCLUDE_DIR}) include_directories(${CRYPTOPP_INCLUDE_DIR})
if (NOT APPLE) if(NOT APPLE)
link_directories(${CRYPTOPP_LIBRARIES}) link_directories(${CRYPTOPP_LIBRARIES})
endif () endif()
endif () endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
link_directories(/usr/local/lib) link_directories(/usr/local/lib)
endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin") endif(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
# Generate header file containing useful build information
add_custom_target(BuildInfo.h ALL COMMAND bash ${CMAKE_CURRENT_SOURCE_DIR}/BuildInfo.sh ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_BUILD_TYPE} ${ETH_BUILD_PLATFORM})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
add_subdirectory(secp256k1) add_subdirectory(secp256k1)
add_subdirectory(libethereum) add_subdirectory(libethereum)
add_subdirectory(test) add_subdirectory(test)

89
TODO

@ -1,89 +0,0 @@
### UP FOR GRABS
Tests
- Use standard tests.
Crypto stuff:
- kFromMessage
- Check all the tweak instructions.
Network:
- *** Exponential backoff on bad connection.
- *** Handle exception when no network.
- NotInChain will be very bad for new peers - it'll run through until the genesis.
- Check how many it has first.
- Crypto on network - use id as public key?
- Make work with IPv6
- Peers rated.
- Useful/useless - new blocks/transactions or useful peers?
- Solid communications?
- Strategy for peer suggestion?
Cleanups & caching
- All caches should flush unused data (I'm looking at you, BlockChain) to avoid memory overload.
- State DB should keep only last few N blocks worth of nodes (except for restore points - configurable, defaults to every 30000th block - all blocks that are restore points should be stored so their stateRoots are known good).
THREAD-SAFETY
- BlockChain
- TransactionQueue
- State
General:
- Better logging.
- Colours.
- Move over to new system.
- Remove block chain on protocol change (i.e. store protocol with block chain).
Robustness
- Remove aborts
- Recover from all exceptions.
- Store version alongside BC DB.
- Better handling of corrupt blocks.
- Kill DB & restart.
GUI
- Make address/block chain list model-based, JIT populated.
- Make everything else model-based
- Qt/QML class.
- Turn on/off debug channels.
For PoC3:
- Shared contract acceptence tests.
### Marko
Ubuntu builds
- Raring (branch, local, x64 only :-( )
- Quantal (branch) (Launchpad)
- Saucy (master) (Launchpad)
### Alex
Mac build.
Mac build instructions.
### Eric
Windows XC build.
Windows XC build instructions.
### Tim/Harv
Windows MSVC build.
Windows MSVC build instructions.
LATER:
Trie on DB.
- Move the restore point stuff into block restore points
- i.e. keep all nodes from last 127 blocks with counter, at 128, kill but keep every (60*24*7)th or so i.e. one per week as a restore point.
- maybe allow this to be configured.
### TIM
Stateful Miner class.
Better Mod-Exp.

4
alethzero/CMakeLists.txt

@ -87,10 +87,12 @@ elseif (${TARGET_PLATFORM} STREQUAL "w64")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-keep-inline-dllexport -static-libgcc -static-libstdc++ -static")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-s -Wl,-subsystem,windows -mthreads -L/usr/x86_64-w64-mingw32/plugins/platforms")
target_link_libraries(${EXECUTEABLE} gcc) target_link_libraries(${EXECUTEABLE} gcc)
target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32) target_link_libraries(${EXECUTEABLE} mingw32 qtmain mswsock iphlpapi qwindows shlwapi Qt5PlatformSupport opengl32 gdi32 comdlg32 oleaut32 imm32 winmm ole32 uuid ws2_32)
target_link_libraries(${EXECUTEABLE} boost_system-mt-s) target_link_libraries(${EXECUTEABLE} boost_system-mt-s)
target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s) target_link_libraries(${EXECUTEABLE} boost_filesystem-mt-s)
target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s) target_link_libraries(${EXECUTEABLE} boost_thread_win32-mt-s)
# target_link_libraries(${EXECUTEABLE} ssl)
target_link_libraries(${EXECUTEABLE} crypt32)
target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport) target_link_libraries(${EXECUTEABLE} Qt5PlatformSupport)
set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS) set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS)
else () else ()

39
alethzero/MainWin.cpp

@ -6,6 +6,7 @@
#include <libethereum/Dagger.h> #include <libethereum/Dagger.h>
#include <libethereum/Client.h> #include <libethereum/Client.h>
#include <libethereum/Instruction.h> #include <libethereum/Instruction.h>
#include "BuildInfo.h"
#include "MainWin.h" #include "MainWin.h"
#include "ui_Main.h" #include "ui_Main.h"
using namespace std; using namespace std;
@ -53,9 +54,6 @@ static void initUnits(QComboBox* _b)
_b->setCurrentIndex(6); _b->setCurrentIndex(6);
} }
#define ADD_QUOTES_HELPER(s) #s
#define ADD_QUOTES(s) ADD_QUOTES_HELPER(s)
Main::Main(QWidget *parent) : Main::Main(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::Main) ui(new Ui::Main)
@ -118,18 +116,20 @@ Main::Main(QWidget *parent) :
#if ETH_DEBUG #if ETH_DEBUG
m_servers.append("192.168.0.10:30301"); m_servers.append("192.168.0.10:30301");
#else #else
connect(&m_webCtrl, &QNetworkAccessManager::finished, [&](QNetworkReply* _r) int pocnumber = QString(ETH_QUOTED(ETH_VERSION)).section('.', 1, 1).toInt();
if (pocnumber == 3)
m_servers.push_back("54.201.28.117:30303");
else
{ {
m_servers = QString::fromUtf8(_r->readAll()).split("\n", QString::SkipEmptyParts); connect(&m_webCtrl, &QNetworkAccessManager::finished, [&](QNetworkReply* _r)
}); {
#ifdef _MSC_VER m_servers = QString::fromUtf8(_r->readAll()).split("\n", QString::SkipEmptyParts);
QNetworkRequest r(QUrl("http://www.ethereum.org/servers.poc3.txt")); });
#else QNetworkRequest r(QUrl("http://www.ethereum.org/servers.poc" + QString::number(pocnumber) + ".txt"));
QNetworkRequest r(QUrl("https://www.ethereum.org/servers.poc3.txt")); r.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1712.0 Safari/537.36");
#endif m_webCtrl.get(r);
r.setHeader(QNetworkRequest::UserAgentHeader, "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1712.0 Safari/537.36"); srand(time(0));
m_webCtrl.get(r); }
srand(time(0));
#endif #endif
on_verbosity_sliderMoved(); on_verbosity_sliderMoved();
@ -186,7 +186,7 @@ Address Main::fromString(QString const& _a) const
void Main::on_about_triggered() void Main::on_about_triggered()
{ {
QMessageBox::about(this, "About AlethZero PoC-3", "AlethZero/v" ADD_QUOTES(ETH_VERSION) "/" ADD_QUOTES(ETH_BUILD_TYPE) "/" ADD_QUOTES(ETH_BUILD_PLATFORM) "\nBy Gav Wood, 2014.\nBased on a design by Vitalik Buterin.\n\nTeam Ethereum++ includes: Eric Lombrozo, Marko Simovic, Alex Leverington, Tim Hughes and several others."); QMessageBox::about(this, "About AlethZero PoC-" + QString(ETH_QUOTED(ETH_VERSION)).section('.', 1, 1), QString("AlethZero/v" ETH_QUOTED(ETH_VERSION) "/" ETH_QUOTED(ETH_BUILD_TYPE) "/" ETH_QUOTED(ETH_BUILD_PLATFORM) "\n" ETH_QUOTED(ETH_COMMIT_HASH)) + (ETH_CLEAN_REPO ? "\nCLEAN" : "\n+ LOCAL CHANGES") + "\n\nBy Gav Wood, 2014.\nBased on a design by Vitalik Buterin.\n\nTeam Ethereum++ includes: Eric Lombrozo, Marko Simovic, Alex Leverington, Tim Hughes and several others.");
} }
void Main::writeSettings() void Main::writeSettings()
@ -246,7 +246,10 @@ void Main::readSettings()
ui->clientName->setText(s.value("clientName", "").toString()); ui->clientName->setText(s.value("clientName", "").toString());
ui->idealPeers->setValue(s.value("idealPeers", ui->idealPeers->value()).toInt()); ui->idealPeers->setValue(s.value("idealPeers", ui->idealPeers->value()).toInt());
ui->port->setValue(s.value("port", ui->port->value()).toInt()); ui->port->setValue(s.value("port", ui->port->value()).toInt());
ui->nameReg->setText(s.value("nameReg", "11f62328e131dbb05ce4c73a3de3c7ab1c84a163").toString()); if (s.value("nameReg").toString() == "11f62328e131dbb05ce4c73a3de3c7ab1c84a163")
s.remove("nameReg");
ui->nameReg->setText(s.value("nameReg", "8ff91e5b145a23ab1afef34f12587c18bd42aec0").toString());
} }
void Main::on_nameReg_textChanged() void Main::on_nameReg_textChanged()
@ -588,10 +591,10 @@ void Main::on_net_triggered()
{ {
ui->port->setEnabled(!ui->net->isChecked()); ui->port->setEnabled(!ui->net->isChecked());
ui->clientName->setEnabled(!ui->net->isChecked()); ui->clientName->setEnabled(!ui->net->isChecked());
string n = "AlethZero/v" ADD_QUOTES(ETH_VERSION); string n = "AlethZero/v" ETH_QUOTED(ETH_VERSION);
if (ui->clientName->text().size()) if (ui->clientName->text().size())
n += "/" + ui->clientName->text().toStdString(); n += "/" + ui->clientName->text().toStdString();
n += "/" ADD_QUOTES(ETH_BUILD_TYPE) "/" ADD_QUOTES(ETH_BUILD_PLATFORM); n += "/" ETH_QUOTED(ETH_BUILD_TYPE) "/" ETH_QUOTED(ETH_BUILD_PLATFORM);
m_client->setClientVersion(n); m_client->setClientVersion(n);
if (ui->net->isChecked()) if (ui->net->isChecked())
{ {

10
eth/main.cpp

@ -29,12 +29,10 @@
#include "BlockChain.h" #include "BlockChain.h"
#include "State.h" #include "State.h"
#include "FileSystem.h" #include "FileSystem.h"
#include "BuildInfo.h"
using namespace std; using namespace std;
using namespace eth; using namespace eth;
#define ADD_QUOTES_HELPER(s) #s
#define ADD_QUOTES(s) ADD_QUOTES_HELPER(s)
bool isTrue(std::string const& _m) bool isTrue(std::string const& _m)
{ {
return _m == "on" || _m == "yes" || _m == "true" || _m == "1"; return _m == "on" || _m == "yes" || _m == "true" || _m == "1";
@ -72,8 +70,8 @@ void help()
void version() void version()
{ {
cout << "eth version " << ADD_QUOTES(ETH_VERSION) << endl; cout << "eth version " << ETH_QUOTED(ETH_VERSION) << endl;
cout << "Build: " << ADD_QUOTES(ETH_BUILD_PLATFORM) << "/" << ADD_QUOTES(ETH_BUILD_TYPE) << endl; cout << "Build: " << ETH_QUOTED(ETH_BUILD_PLATFORM) << "/" << ETH_QUOTED(ETH_BUILD_TYPE) << endl;
exit(0); exit(0);
} }
@ -189,7 +187,7 @@ int main(int argc, char** argv)
if (!clientName.empty()) if (!clientName.empty())
clientName += "/"; clientName += "/";
Client c("Ethereum(++)/" + clientName + "v" ADD_QUOTES(ETH_VERSION) "/" ADD_QUOTES(ETH_BUILD_TYPE) "/" ADD_QUOTES(ETH_BUILD_PLATFORM), coinbase, dbPath); Client c("Ethereum(++)/" + clientName + "v" ETH_QUOTED(ETH_VERSION) "/" ETH_QUOTED(ETH_BUILD_TYPE) "/" ETH_QUOTED(ETH_BUILD_PLATFORM), coinbase, dbPath);
if (interactive) if (interactive)
{ {

30
libethereum/Client.cpp

@ -23,20 +23,44 @@
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#include <boost/filesystem.hpp>
#include "Common.h" #include "Common.h"
#include "Defaults.h" #include "Defaults.h"
using namespace std; using namespace std;
using namespace eth; using namespace eth;
VersionChecker::VersionChecker(string const& _dbPath, unsigned _protocolVersion):
m_path(_dbPath.size() ? _dbPath : Defaults::dbPath()),
m_protocolVersion(_protocolVersion)
{
m_ok = RLP(contents(m_path + "/protocol")).toInt<unsigned>(RLP::LaisezFaire) == _protocolVersion;
}
void VersionChecker::setOk()
{
if (!m_ok)
{
try
{
boost::filesystem::create_directory(m_path);
}
catch (...) {}
writeFile(m_path + "/protocol", rlp(m_protocolVersion));
}
}
Client::Client(std::string const& _clientVersion, Address _us, std::string const& _dbPath): Client::Client(std::string const& _clientVersion, Address _us, std::string const& _dbPath):
m_clientVersion(_clientVersion), m_clientVersion(_clientVersion),
m_bc(_dbPath), m_vc(_dbPath, PeerSession::protocolVersion()),
m_stateDB(State::openDB(_dbPath)), m_bc(_dbPath, !m_vc.ok()),
m_stateDB(State::openDB(_dbPath, !m_vc.ok())),
m_preMine(_us, m_stateDB), m_preMine(_us, m_stateDB),
m_postMine(_us, m_stateDB), m_postMine(_us, m_stateDB),
m_workState(Active) m_workState(Active)
{ {
Defaults::setDBPath(_dbPath); if (_dbPath.size())
Defaults::setDBPath(_dbPath);
m_vc.setOk();
// Synchronise the state according to the head of the block chain. // Synchronise the state according to the head of the block chain.
// TODO: currently it contains keys for *all* blocks. Make it remove old ones. // TODO: currently it contains keys for *all* blocks. Make it remove old ones.

15
libethereum/Client.h

@ -60,6 +60,20 @@ enum ClientWorkState
Deleted Deleted
}; };
class VersionChecker
{
public:
VersionChecker(std::string const& _dbPath, unsigned _protocolVersion);
void setOk();
bool ok() const { return m_ok; }
private:
bool m_ok;
std::string m_path;
unsigned m_protocolVersion;
};
class Client class Client
{ {
public: public:
@ -141,6 +155,7 @@ private:
void work(); void work();
std::string m_clientVersion; ///< Our end-application client's name/version. std::string m_clientVersion; ///< Our end-application client's name/version.
VersionChecker m_vc; ///< Dummy object to check & update the protocol version.
BlockChain m_bc; ///< Maintains block database. BlockChain m_bc; ///< Maintains block database.
TransactionQueue m_tq; ///< Maintains list of incoming transactions not yet on the block chain. TransactionQueue m_tq; ///< Maintains list of incoming transactions not yet on the block chain.
Overlay m_stateDB; ///< Acts as the central point for the state database, so multiple States can share it. Overlay m_stateDB; ///< Acts as the central point for the state database, so multiple States can share it.

5
libethereum/Common.h

@ -24,7 +24,7 @@
#pragma once #pragma once
// define version // define version
#define ETH_VERSION 0.3.10 #define ETH_VERSION 0.3.11
// way to many uint to size_t warnings in 32 bit build // way to many uint to size_t warnings in 32 bit build
#ifdef _M_IX86 #ifdef _M_IX86
@ -57,6 +57,9 @@
// CryptoPP defines byte in the global namespace, so so must we. // CryptoPP defines byte in the global namespace, so so must we.
using byte = uint8_t; using byte = uint8_t;
#define ETH_QUOTED_HELPER(s) #s
#define ETH_QUOTED(s) ETH_QUOTED_HELPER(s)
namespace eth namespace eth
{ {

1
libethereum/Defaults.h

@ -36,6 +36,7 @@ public:
static Defaults* get() { if (!s_this) s_this = new Defaults; return s_this; } static Defaults* get() { if (!s_this) s_this = new Defaults; return s_this; }
static void setDBPath(std::string const& _dbPath) { get()->m_dbPath = _dbPath; } static void setDBPath(std::string const& _dbPath) { get()->m_dbPath = _dbPath; }
static std::string const& dbPath() { return get()->m_dbPath; }
private: private:
std::string m_dbPath; std::string m_dbPath;

2
libethereum/Exceptions.h

@ -31,7 +31,7 @@ class NoSuchContract: public Exception {};
class ContractAddressCollision: public Exception {}; class ContractAddressCollision: public Exception {};
class FeeTooSmall: public Exception {}; class FeeTooSmall: public Exception {};
class InvalidSignature: public Exception {}; class InvalidSignature: public Exception {};
class InvalidTransactionFormat: public Exception {}; class InvalidTransactionFormat: public Exception { public: InvalidTransactionFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid transaction format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } };
class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } }; class InvalidBlockFormat: public Exception { public: InvalidBlockFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } };
class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } }; class InvalidBlockHeaderFormat: public Exception { public: InvalidBlockHeaderFormat(int _f, bytesConstRef _d): m_f(_f), m_d(_d.toBytes()) {} int m_f; bytes m_d; virtual std::string description() const { return "Invalid block header format: Bad field " + toString(m_f) + " (" + asHex(m_d) + ")"; } };
class InvalidUnclesHash: public Exception {}; class InvalidUnclesHash: public Exception {};

20
libethereum/PeerNetwork.cpp

@ -43,7 +43,7 @@ using namespace eth;
#define clogS(X) eth::LogOutputStream<X, true>(false) << "| " << std::setw(2) << m_socket.native_handle() << "] " #define clogS(X) eth::LogOutputStream<X, true>(false) << "| " << std::setw(2) << m_socket.native_handle() << "] "
static const int c_protocolVersion = 7; static const int c_protocolVersion = 8;
static const eth::uint c_maxHashes = 32; ///< Maximum number of hashes GetChain will ever send. static const eth::uint c_maxHashes = 32; ///< Maximum number of hashes GetChain will ever send.
static const eth::uint c_maxBlocks = 32; ///< Maximum number of blocks Blocks will ever send. BUG: if this gets too big (e.g. 2048) stuff starts going wrong. static const eth::uint c_maxBlocks = 32; ///< Maximum number of blocks Blocks will ever send. BUG: if this gets too big (e.g. 2048) stuff starts going wrong.
@ -97,6 +97,16 @@ PeerSession::~PeerSession()
m_socket.close(); m_socket.close();
} }
int PeerSession::protocolVersion()
{
return c_protocolVersion;
}
int PeerSession::networkId()
{
return 0;
}
bi::tcp::endpoint PeerSession::endpoint() const bi::tcp::endpoint PeerSession::endpoint() const
{ {
if (m_socket.is_open()) if (m_socket.is_open())
@ -591,6 +601,8 @@ void PeerSession::doRead()
{ {
if (m_incoming[0] != 0x22 || m_incoming[1] != 0x40 || m_incoming[2] != 0x08 || m_incoming[3] != 0x91) if (m_incoming[0] != 0x22 || m_incoming[1] != 0x40 || m_incoming[2] != 0x08 || m_incoming[3] != 0x91)
{ {
disconnect(BadProtocol);
return;
clogS(NetWarn) << "Out of alignment. Skipping: " << hex << showbase << (int)m_incoming[0] << dec; clogS(NetWarn) << "Out of alignment. Skipping: " << hex << showbase << (int)m_incoming[0] << dec;
memmove(m_incoming.data(), m_incoming.data() + 1, m_incoming.size() - 1); memmove(m_incoming.data(), m_incoming.data() + 1, m_incoming.size() - 1);
m_incoming.resize(m_incoming.size() - 1); m_incoming.resize(m_incoming.size() - 1);
@ -610,6 +622,7 @@ void PeerSession::doRead()
cerr << "Received " << len << ": " << asHex(bytesConstRef(m_incoming.data() + 8, len)) << endl; cerr << "Received " << len << ": " << asHex(bytesConstRef(m_incoming.data() + 8, len)) << endl;
cwarn << "INVALID MESSAGE RECEIVED"; cwarn << "INVALID MESSAGE RECEIVED";
disconnect(BadProtocol); disconnect(BadProtocol);
return;
} }
else else
{ {
@ -830,9 +843,8 @@ void PeerServer::ensureAccepting()
{ {
clog(NetWarn) << "ERROR: " << _e.what(); clog(NetWarn) << "ERROR: " << _e.what();
} }
m_accepting = false; m_accepting = false;
if (m_mode == NodeMode::PeerServer || m_peers.size() < m_idealPeerCount * 2) if (ec.value() != 1 && (m_mode == NodeMode::PeerServer || m_peers.size() < m_idealPeerCount * 2))
ensureAccepting(); ensureAccepting();
}); });
} }
@ -926,7 +938,7 @@ bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o)
{ {
for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++it) for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++it)
if (_tq.import(*it)) if (_tq.import(*it))
ret = true; {}//ret = true; // just putting a transaction in the queue isn't enough to change the state - it might have an invalid nonce...
else else
m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on. m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on.
m_incomingTransactions.clear(); m_incomingTransactions.clear();

3
libethereum/PeerNetwork.h

@ -101,6 +101,9 @@ public:
bool isOpen() const { return m_socket.is_open(); } bool isOpen() const { return m_socket.is_open(); }
static int protocolVersion();
static int networkId();
bi::tcp::endpoint endpoint() const; ///< for other peers to connect to. bi::tcp::endpoint endpoint() const; ///< for other peers to connect to.
private: private:

46
libethereum/State.cpp

@ -55,8 +55,6 @@ Overlay State::openDB(std::string _path, bool _killExisting)
if (_path.empty()) if (_path.empty())
_path = Defaults::get()->m_dbPath; _path = Defaults::get()->m_dbPath;
boost::filesystem::create_directory(_path); boost::filesystem::create_directory(_path);
if (_killExisting)
boost::filesystem::remove_all(_path + "/state");
ldb::Options o; ldb::Options o;
o.create_if_missing = true; o.create_if_missing = true;
@ -288,31 +286,41 @@ bool State::sync(TransactionQueue& _tq)
// TRANSACTIONS // TRANSACTIONS
bool ret = false; bool ret = false;
auto ts = _tq.transactions(); auto ts = _tq.transactions();
for (auto const& i: ts) vector<pair<h256, bytes>> futures;
for (int goodTxs = 1; goodTxs;)
{ {
if (!m_transactionSet.count(i.first)) goodTxs = 0;
for (auto const& i: ts)
{ {
// don't have it yet! Execute it now. if (!m_transactionSet.count(i.first))
try
{ {
execute(i.second); // don't have it yet! Execute it now.
ret = true; try
} {
catch (InvalidNonce const& in) execute(i.second);
{ ret = true;
if (in.required > in.candidate) _tq.noteGood(i);
++goodTxs;
}
catch (InvalidNonce const& in)
{
if (in.required > in.candidate)
{
// too old
_tq.drop(i.first);
ret = true;
}
else
_tq.setFuture(i);
}
catch (std::exception const&)
{ {
// too old // Something else went wrong - drop it.
_tq.drop(i.first); _tq.drop(i.first);
ret = true; ret = true;
} }
} }
catch (std::exception const&)
{
// Something else went wrong - drop it.
_tq.drop(i.first);
ret = true;
}
} }
} }
return ret; return ret;

22
libethereum/Transaction.cpp

@ -30,14 +30,22 @@ using namespace eth;
Transaction::Transaction(bytesConstRef _rlpData) Transaction::Transaction(bytesConstRef _rlpData)
{ {
int field = 0;
RLP rlp(_rlpData); RLP rlp(_rlpData);
nonce = rlp[0].toInt<u256>(); try
receiveAddress = rlp[1].toHash<Address>(); {
value = rlp[2].toInt<u256>(); nonce = rlp[field = 0].toInt<u256>();
data.reserve(rlp[3].itemCountStrict()); receiveAddress = rlp[field = 1].toHash<Address>();
for (auto const& i: rlp[3]) value = rlp[field = 2].toInt<u256>();
data.push_back(i.toInt<u256>()); data.reserve(rlp[field = 3].itemCountStrict());
vrs = Signature{ rlp[4].toInt<byte>(), rlp[5].toInt<u256>(), rlp[6].toInt<u256>() }; for (auto const& i: rlp[3])
data.push_back(i.toInt<u256>());
vrs = Signature{ rlp[field = 4].toInt<byte>(), rlp[field = 5].toInt<u256>(), rlp[field = 6].toInt<u256>() };
}
catch (RLPException const&)
{
throw InvalidTransactionFormat(field, rlp[field].data());
}
} }
Address Transaction::safeSender() const noexcept Address Transaction::safeSender() const noexcept

24
libethereum/TransactionQueue.cpp

@ -43,11 +43,33 @@ bool TransactionQueue::import(bytes const& _block)
// If valid, append to blocks. // If valid, append to blocks.
m_data[h] = _block; m_data[h] = _block;
} }
catch (InvalidTransactionFormat const& _e)
{
cwarn << "Ignoring invalid transaction: " << _e.description();
return false;
}
catch (std::exception const& _e) catch (std::exception const& _e)
{ {
cout << "*** Ignoring invalid transaction: " << _e.what(); cwarn << "Ignoring invalid transaction: " << _e.what();
return false; return false;
} }
return true; return true;
} }
void TransactionQueue::setFuture(std::pair<h256, bytes> const& _t)
{
if (m_data.count(_t.first))
{
m_data.erase(_t.first);
m_future.insert(make_pair(Transaction(_t.second).sender(), _t));
}
}
void TransactionQueue::noteGood(std::pair<h256, bytes> const& _t)
{
auto r = m_future.equal_range(Transaction(_t.second).sender());
for (auto it = r.first; it != r.second; ++it)
m_data.insert(_t);
m_future.erase(r.first, r.second);
}

6
libethereum/TransactionQueue.h

@ -40,14 +40,18 @@ public:
void drop(h256 _txHash) { m_data.erase(_txHash); } void drop(h256 _txHash) { m_data.erase(_txHash); }
std::map<h256, bytes> const& transactions() const { return m_data; } std::map<h256, bytes> const& transactions() const { return m_data; }
void setFuture(std::pair<h256, bytes> const& _t);
void noteGood(std::pair<h256, bytes> const& _t);
Transactions interestQueue() { Transactions ret; swap(ret, m_interestQueue); return ret; } Transactions interestQueue() { Transactions ret; swap(ret, m_interestQueue); return ret; }
void pushInterest(Address _a) { m_interest[_a]++; } void pushInterest(Address _a) { m_interest[_a]++; }
void popInterest(Address _a) { if (m_interest[_a] > 1) m_interest[_a]--; else if (m_interest[_a]) m_interest.erase(_a); } void popInterest(Address _a) { if (m_interest[_a] > 1) m_interest[_a]--; else if (m_interest[_a]) m_interest.erase(_a); }
private: private:
std::map<h256, bytes> m_data; ///< the queue. std::map<h256, bytes> m_data; ///< Map of SHA3(tx) to tx.
Transactions m_interestQueue; Transactions m_interestQueue;
std::map<Address, int> m_interest; std::map<Address, int> m_interest;
std::multimap<Address, std::pair<h256, bytes>> m_future; ///< For transactions that have a future nonce; we map their sender address to the tx stuff, and insert once the sender has a valid TX.
}; };
} }

8
libethereum/TrieDB.h

@ -31,14 +31,6 @@ namespace ldb = leveldb;
namespace eth namespace eth
{ {
class DBFace
{
public:
virtual std::string node(h256 _h) const = 0;
virtual void insertNode(h256 _h, bytesConstRef _v) = 0;
virtual void killNode(h256 _h) = 0;
};
class BasicMap class BasicMap
{ {
public: public:

9
release.sh

@ -35,6 +35,14 @@ git checkout "$branch"
archdir="cpp-ethereum-$version" archdir="cpp-ethereum-$version"
archfile="$archdir.tar.bz2" archfile="$archdir.tar.bz2"
echo Making BuildInfo...
mkdir build
cd build
cmake ..
cd ..
cp build/BuildInfo.h .
rm -rf build
echo Cleaning backup files... echo Cleaning backup files...
find . | grep \~ | xargs rm -f find . | grep \~ | xargs rm -f
@ -51,6 +59,7 @@ mv cpp-ethereum $archdir
echo Creating archive... echo Creating archive...
tar c $archdir | bzip2 -- > $archfile tar c $archdir | bzip2 -- > $archfile
shasum $archfile
[[ ! "$version" == "" ]] && ln -sf $archfile "cpp-ethereum_$version.orig.tar.bz2" [[ ! "$version" == "" ]] && ln -sf $archfile "cpp-ethereum_$version.orig.tar.bz2"

1
test/crypto.cpp

@ -30,6 +30,7 @@ using namespace eth;
int cryptoTest() int cryptoTest()
{ {
cnote << "Testing Crypto...";
secp256k1_start(); secp256k1_start();
KeyPair p(Secret(fromUserHex("3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4"))); KeyPair p(Secret(fromUserHex("3ecb44df2159c26e0f995712d4f39b6f6e499b40749b1cf1246c37f9516cb6a4")));

1
test/dagger.cpp

@ -28,6 +28,7 @@ using namespace eth;
int daggerTest() int daggerTest()
{ {
cnote << "Testing Dagger...";
// Test dagger // Test dagger
{ {
auto s = steady_clock::now(); auto s = steady_clock::now();

69
test/hexPrefix.cpp

@ -20,38 +20,51 @@
* Main test functions. * Main test functions.
*/ */
#include <fstream>
#include "../json_spirit/json_spirit_reader_template.h"
#include "../json_spirit/json_spirit_writer_template.h"
#include "TrieCommon.h" #include "TrieCommon.h"
using namespace std; using namespace std;
using namespace eth; using namespace eth;
namespace js = json_spirit;
int hexPrefixTest() namespace eth
{
template <> class UnitTest<3>
{ {
/* public:
* Hex-prefix Notation. First nibble has flags: oddness = 2^0 & termination = 2^1 int operator()()
* [0,0,1,2,3,4,5] 0x10012345 {
* [0,1,2,3,4,5] 0x00012345 js::mValue v;
* [1,2,3,4,5] 0x112345 string s = asString(contents("../../tests/hexencodetest.json"));
* [0,0,1,2,3,4] 0x00001234 js::read_string(s, v);
* [0,1,2,3,4] 0x101234 bool passed = true;
* [1,2,3,4] 0x001234 for (auto& i: v.get_obj())
* [0,0,1,2,3,4,5,T] 0x30012345 {
* [0,0,1,2,3,4,T] 0x20001234 js::mObject& o = i.second.get_obj();
* [0,1,2,3,4,5,T] 0x20012345 cnote << i.first;
* [1,2,3,4,5,T] 0x312345 bytes v;
* [1,2,3,4,T] 0x201234 for (auto& i: o["seq"].get_array())
*/ v.push_back((byte)i.get_int());
assert(asHex(hexPrefixEncode({0, 0, 1, 2, 3, 4, 5}, false)) == "10012345"); auto e = hexPrefixEncode(v, o["term"].get_bool());
assert(asHex(hexPrefixEncode({0, 1, 2, 3, 4, 5}, false)) == "00012345"); if (!o["out"].is_null() && o["out"].get_str() != asHex(e))
assert(asHex(hexPrefixEncode({1, 2, 3, 4, 5}, false)) == "112345"); {
assert(asHex(hexPrefixEncode({0, 0, 1, 2, 3, 4}, false)) == "00001234"); cwarn << "Test failed.";
assert(asHex(hexPrefixEncode({0, 1, 2, 3, 4}, false)) == "101234"); cwarn << "Test says:" << o["out"].get_str();
assert(asHex(hexPrefixEncode({1, 2, 3, 4}, false)) == "001234"); cwarn << "Impl says:" << asHex(e);
assert(asHex(hexPrefixEncode({0, 0, 1, 2, 3, 4, 5}, true)) == "30012345"); passed = false;
assert(asHex(hexPrefixEncode({0, 0, 1, 2, 3, 4}, true)) == "20001234"); }
assert(asHex(hexPrefixEncode({0, 1, 2, 3, 4, 5}, true)) == "20012345"); }
assert(asHex(hexPrefixEncode({1, 2, 3, 4, 5}, true)) == "312345"); return passed ? 0 : 1;
assert(asHex(hexPrefixEncode({1, 2, 3, 4}, true)) == "201234"); }
return 0; };
} }
int hexPrefixTest()
{
cnote << "Testing Hex-Prefix-Encode...";
return UnitTest<3>()();
}

18
test/main.cpp

@ -42,14 +42,16 @@ int main(int, char**)
std::cout << asHex(s.out()) << std::endl; std::cout << asHex(s.out()) << std::endl;
std::cout << sha3(s.out()) << std::endl;*/ std::cout << sha3(s.out()) << std::endl;*/
hexPrefixTest(); int r = 0;
rlpTest(); r += hexPrefixTest();
trieTest(); r += rlpTest();
daggerTest(); r += trieTest();
cryptoTest(); r += vmTest();
vmTest(); r += cryptoTest(); // TODO: Put in tests repo.
// stateTest(); // r += daggerTest();
// peerTest(argc, argv); // r += stateTest();
// r += peerTest(argc, argv);
assert(!r);
return 0; return 0;
} }

90
test/rlp.cpp

@ -20,48 +20,70 @@
* RLP test functions. * RLP test functions.
*/ */
#include <fstream>
#include "../json_spirit/json_spirit_reader_template.h"
#include "../json_spirit/json_spirit_writer_template.h"
#include <RLP.h> #include <RLP.h>
using namespace std; using namespace std;
using namespace eth; using namespace eth;
namespace js = json_spirit;
int rlpTest() namespace eth
{ {
// int of value 15
assert(RLP("\x0f") == 15);
assert(asString(rlp(15)) == "\x0f");
// 3-character string
assert(RLP("\x83""dog") == "dog");
assert(asString(rlp("dog")) == "\x83""dog");
// 2-item list
string twoItemListString = "\xc5\x0f\x83""dog";
RLP twoItemList(twoItemListString);
assert(twoItemList.itemCount() == 2);
assert(twoItemList[0] == 15);
assert(twoItemList[1] == "dog");
assert(asString(rlpList(15, "dog")) == "\xc5\x0f\x83""dog");
// null
assert(RLP("\x80") == "");
assert(asString(rlp("")) == "\x80");
// 1-byte (8-bit) int
assert(RLP("\x81\x80") == 128);
assert(asString(rlp(128)) == "\x81\x80");
// 2-byte (16-bit) int template <> class UnitTest<2>
assert(RLP("\x82\x01\x01") == 257); {
assert(asString(rlp(257)) == "\x82\x01\x01"); public:
static void buildRLP(js::mValue& _v, RLPStream& _rlp)
{
if (_v.type() == js::array_type)
{
RLPStream s;
for (auto& i: _v.get_array())
buildRLP(i, s);
_rlp.appendList(s.out());
}
else if (_v.type() == js::int_type)
_rlp.append(_v.get_uint64());
else if (_v.type() == js::str_type)
{
auto s = _v.get_str();
if (s.size() && s[0] == '#')
_rlp.append(bigint(s.substr(1)));
else
_rlp.append(s);
}
}
// 32-byte (256-bit) int int operator()()
assert(RLP("\xa0\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f") == bigint("0x100102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f")); {
assert(asString(rlp(bigint("0x100102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"))) == "\xa0\x10\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"); js::mValue v;
string s = asString(contents("../../tests/rlptest.json"));
js::read_string(s, v);
bool passed = true;
for (auto& i: v.get_obj())
{
js::mObject& o = i.second.get_obj();
cnote << i.first;
RLPStream s;
buildRLP(o["in"], s);
if (!o["out"].is_null() && o["out"].get_str() != asHex(s.out()))
{
cwarn << "Test failed.";
cwarn << "Test says:" << o["out"].get_str();
cwarn << "Impl says:" << asHex(s.out());
passed = false;
}
}
return passed ? 0 : 1;
}
// 56-character string. };
assert(RLP("\xb8\x38""Lorem ipsum dolor sit amet, consectetur adipisicing elit") == "Lorem ipsum dolor sit amet, consectetur adipisicing elit");
assert(asString(rlp("Lorem ipsum dolor sit amet, consectetur adipisicing elit")) == "\xb8\x38""Lorem ipsum dolor sit amet, consectetur adipisicing elit");
return 0;
} }
int rlpTest()
{
cnote << "Testing RLP...";
return UnitTest<2>()();
}

2
test/state.cpp

@ -30,6 +30,8 @@ using namespace eth;
int stateTest() int stateTest()
{ {
cnote << "Testing State...";
KeyPair me = sha3("Gav Wood"); KeyPair me = sha3("Gav Wood");
KeyPair myMiner = sha3("Gav's Miner"); KeyPair myMiner = sha3("Gav's Miner");
// KeyPair you = sha3("123"); // KeyPair you = sha3("123");

54
test/trie.cpp

@ -20,6 +20,9 @@
* Trie test functions. * Trie test functions.
*/ */
#include <fstream>
#include "../json_spirit/json_spirit_reader_template.h"
#include "../json_spirit/json_spirit_writer_template.h"
#include <random> #include <random>
#include <TrieHash.h> #include <TrieHash.h>
#include <TrieDB.h> #include <TrieDB.h>
@ -27,6 +30,53 @@
using namespace std; using namespace std;
using namespace eth; using namespace eth;
namespace js = json_spirit;
namespace eth
{
unsigned fac(unsigned _i) { return _i > 2 ? _i * fac(_i - 1) : _i; }
template <> class UnitTest<4>
{
public:
int operator()()
{
js::mValue v;
string s = asString(contents("../../tests/trietest.json"));
js::read_string(s, v);
bool passed = true;
for (auto& i: v.get_obj())
{
js::mObject& o = i.second.get_obj();
cnote << i.first;
vector<pair<string, string>> ss;
for (auto& i: o["in"].get_obj())
ss.push_back(make_pair(i.first, i.second.get_str()));
for (unsigned j = 0; j < fac((unsigned)ss.size()); ++j)
{
next_permutation(ss.begin(), ss.end());
BasicMap m;
GenericTrieDB<BasicMap> t(&m);
t.init();
for (auto const& k: ss)
t.insert(k.first, k.second);
if (!o["root"].is_null() && o["root"].get_str() != asHex(t.root().asArray()))
{
cwarn << "Test failed on permutation " << j;
cwarn << "Test says:" << o["root"].get_str();
cwarn << "Impl says:" << asHex(t.root().asArray());
passed = false;
}
}
}
return passed ? 0 : 1;
}
};
}
inline h256 stringMapHash256(StringMap const& _s) inline h256 stringMapHash256(StringMap const& _s)
{ {
return hash256(_s); return hash256(_s);
@ -34,6 +84,10 @@ inline h256 stringMapHash256(StringMap const& _s)
int trieTest() int trieTest()
{ {
cnote << "Testing Trie...";
return UnitTest<4>()();
// More tests...
{ {
BasicMap m; BasicMap m;
GenericTrieDB<BasicMap> t(&m); GenericTrieDB<BasicMap> t(&m);

1
test/vm.cpp

@ -446,6 +446,7 @@ public:
int vmTest() int vmTest()
{ {
cnote << "Testing VM...";
return UnitTest<1>()(); return UnitTest<1>()();
} }

82
test/vmtests.json

@ -1,29 +1,83 @@
{ {
"suicide": { "suicide": {
"env" : { "env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6", "previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"previousNonce" : "9c9c6567b5ec0c5f3f25df79be42707090f1e62e9db84cbb556ae2a2f6ccccae", "previousNonce" : "9c9c6567b5ec0c5f3f25df79be42707090f1e62e9db84cbb556ae2a2f6ccccae",
"currentDifficulty" : "256", "currentDifficulty" : "256",
"currentTimestamp" : 1, "currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba", "currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"feeMultiplier" : 1 "feeMultiplier" : 1
}, },
"pre" : { "pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : { "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : 1000000000000000000, "balance" : 1000000000000000000,
"nonce" : 0, "nonce" : 0,
"code" : "(suicide (txsender))" "code" : "(suicide (txsender))"
} }
}, },
"exec" : [ "exec" : [
{ {
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6", "address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"sender" : "cd1722f3947def4cf144679da39c4c32bdc35681", "sender" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : 1000000000000000000, "value" : 1000000000000000000,
"data" : [ "data" : [
] ]
} }
] ]
},
"arith": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"previousNonce" : "9c9c6567b5ec0c5f3f25df79be42707090f1e62e9db84cbb556ae2a2f6ccccae",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"feeMultiplier" : 1
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : 1000000000000000000,
"nonce" : 0,
"code" : "(seq (mktx (txsender) (+ 2 2 (* 4 4 4) (/ 2 2) (% 3 2) (- 8 2 2)) 0) )"
}
},
"exec" : [
{
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"sender" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : 1000000000000000000,
"data" : [
]
}
]
},
"boolean": {
"env" : {
"previousHash" : "5e20a0453cecd065ea59c37ac63e079ee08998b6045136a8ce6635c7912ec0b6",
"previousNonce" : "9c9c6567b5ec0c5f3f25df79be42707090f1e62e9db84cbb556ae2a2f6ccccae",
"currentDifficulty" : "256",
"currentTimestamp" : 1,
"currentCoinbase" : "2adc25665018aa1fe0e6bc666dac8fc2697ff9ba",
"feeMultiplier" : 1
},
"pre" : {
"0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6" : {
"balance" : 1000000000000000000,
"nonce" : 0,
"code" : "(seq (when (and 1 1) (mktx (txsender) 2 0)) (when (and 1 0) (mktx (txsender) 3 0)) (when (and 0 1) (mktx (txsender) 4 0)) (when (and 0 0) (mktx (txsender) 5 0)) (when (or 1 1) (mktx (txsender) 12 0)) (when (or 1 0) (mktx (txsender) 13 0)) (when (or 0 1) (mktx (txsender) 14 0)) (when (or 0 0) (mktx (txsender) 15 0)) )"
}
},
"exec" : [
{
"address" : "0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6",
"sender" : "cd1722f3947def4cf144679da39c4c32bdc35681",
"value" : 1000000000000000000,
"data" : [
]
}
]
}, },
"mktx": { "mktx": {

33
windows/Alethzero.vcxproj

@ -170,17 +170,17 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\alethzero\MainWin.h"> <CustomBuild Include="..\alethzero\MainWin.h">
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">"$(Lua)" moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command> <Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)moc_%(FileName).cpp</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)moc_%(FileName).cpp</Outputs>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Message> </Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">"$(Lua)" moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command> <Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</Message> </Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">"$(Lua)" moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command> <Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</Message> </Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">"$(Lua)" moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command> <Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Lua) moc.lua "$(QtBin)/moc" "$(IntDir)moc_%(FileName).cpp" "@(ClCompile->'%(AdditionalIncludeDirectories)');$(IncludePath)" "@(ClCompile->'%(PreprocessorDefinitions)');_MSC_VER=1800" "%(FullPath)"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Message> </Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)moc_%(FileName).cpp</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)moc_%(FileName).cpp</Outputs>
@ -206,6 +206,31 @@
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)ui_%(FileName).h</Outputs> <Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)ui_%(FileName).h</Outputs>
</CustomBuild> </CustomBuild>
</ItemGroup> </ItemGroup>
<ItemGroup>
<CustomBuild Include="BuildInfo.lua">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Lua) "%(FullPath)" "$(IntDir)%(FileName).h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Lua) "%(FullPath)" "$(IntDir)%(FileName).h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Lua) "%(FullPath)" "$(IntDir)%(FileName).h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Message>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Lua) "%(FullPath)" "$(IntDir)%(FileName).h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(FileName).h</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(FileName).h</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(FileName).h</Outputs>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(FileName).h</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../.git/index</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../.git/index</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../.git/index</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../.git/index</AdditionalInputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

3
windows/Alethzero.vcxproj.filters

@ -24,5 +24,8 @@
<ItemGroup> <ItemGroup>
<CustomBuild Include="..\alethzero\MainWin.h" /> <CustomBuild Include="..\alethzero\MainWin.h" />
<CustomBuild Include="..\alethzero\Main.ui" /> <CustomBuild Include="..\alethzero\Main.ui" />
<CustomBuild Include="BuildInfo.lua">
<Filter>Windows</Filter>
</CustomBuild>
</ItemGroup> </ItemGroup>
</Project> </Project>

25
windows/BuildInfo.lua

@ -0,0 +1,25 @@
function os.capture(cmd)
local f = io.popen(cmd, 'r')
if (f) then
local s = f:read('*a')
if (f:close()) then
return s
end
end
return nil
end
hash = (os.capture("git rev-parse HEAD") or "UnknownRevision"):gsub("\n$", "")
clean = ((os.capture("git diff --name-only") or "0"):gsub("\n$", "") == "") and "1" or "0"
local output = io.open(arg[1], "w")
if (output) then
output:write("// This file was automatically generated by buildinfo.lua\n#pragma once\n\n")
output:write("#define ETH_COMMIT_HASH "..hash.."\n")
output:write("#define ETH_CLEAN_REPO "..clean.."\n")
output:close()
end

25
windows/Ethereum.vcxproj

@ -160,6 +160,31 @@
<ItemGroup> <ItemGroup>
<ClCompile Include="..\eth\main.cpp" /> <ClCompile Include="..\eth\main.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<CustomBuild Include="BuildInfo.lua">
<FileType>Document</FileType>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(Lua) "%(FullPath)" "$(IntDir)%(FileName).h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(FileName).h</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(Lua) "%(FullPath)" "$(IntDir)%(FileName).h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(FileName).h</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(Lua) "%(FullPath)" "$(IntDir)%(FileName).h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(FileName).h</Outputs>
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(Lua) "%(FullPath)" "$(IntDir)%(FileName).h"</Command>
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
</Message>
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(FileName).h</Outputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../.git/index</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">../.git/index</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">../.git/index</AdditionalInputs>
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">../.git/index</AdditionalInputs>
</CustomBuild>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>

16
windows/Ethereum.vcxproj.filters

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="..\eth\main.cpp" />
</ItemGroup>
<ItemGroup>
<Filter Include="Windows">
<UniqueIdentifier>{ed0eafbf-bbfb-4700-b7c0-9b58049cc681}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="BuildInfo.lua">
<Filter>Windows</Filter>
</CustomBuild>
</ItemGroup>
</Project>

6
windows/LibEthereum.props

@ -3,6 +3,7 @@
<ImportGroup Label="PropertySheets" /> <ImportGroup Label="PropertySheets" />
<PropertyGroup Label="UserMacros"> <PropertyGroup Label="UserMacros">
<BoostDir>../../boost</BoostDir> <BoostDir>../../boost</BoostDir>
<Lua>"../../lua/lua"</Lua>
</PropertyGroup> </PropertyGroup>
<PropertyGroup> <PropertyGroup>
<OutDir>..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\</OutDir> <OutDir>..\..\_build\$(ProjectName)\$(Platform)_$(Configuration)\</OutDir>
@ -14,7 +15,7 @@
<WarningLevel>Level4</WarningLevel> <WarningLevel>Level4</WarningLevel>
<TreatWarningAsError>true</TreatWarningAsError> <TreatWarningAsError>true</TreatWarningAsError>
<MinimalRebuild>false</MinimalRebuild> <MinimalRebuild>false</MinimalRebuild>
<AdditionalIncludeDirectories>include/$(ProjectName);../libethereum;$(BoostDir);../../leveldb/include;../../cryptopp;../secp256k1;../../miniupnp</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>include/$(ProjectName);$(IntDir);../libethereum;$(BoostDir);../../leveldb/include;../../cryptopp;../secp256k1;../../miniupnp</AdditionalIncludeDirectories>
<PreprocessorDefinitions>ETH_BUILD_PLATFORM=Windows/VS2013;ETH_BUILD_TYPE=$(Configuration)-$(Platform);STATICLIB;LEVELDB_PLATFORM_WINDOWS;USE_NUM_BOOST;USE_FIELD_10X26;USE_FIELD_INV_BUILTIN;_WIN32_WINNT=0x0501;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>ETH_BUILD_PLATFORM=Windows/VS2013;ETH_BUILD_TYPE=$(Configuration)-$(Platform);STATICLIB;LEVELDB_PLATFORM_WINDOWS;USE_NUM_BOOST;USE_FIELD_10X26;USE_FIELD_INV_BUILTIN;_WIN32_WINNT=0x0501;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeTypeInfo>true</RuntimeTypeInfo> <RuntimeTypeInfo>true</RuntimeTypeInfo>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
@ -27,5 +28,8 @@
<BuildMacro Include="BoostDir"> <BuildMacro Include="BoostDir">
<Value>$(BoostDir)</Value> <Value>$(BoostDir)</Value>
</BuildMacro> </BuildMacro>
<BuildMacro Include="Lua">
<Value>$(Lua)</Value>
</BuildMacro>
</ItemGroup> </ItemGroup>
</Project> </Project>

6
windows/UseQt.props

@ -6,13 +6,12 @@
<QtBin>$(QtDir)/qtbase/bin</QtBin> <QtBin>$(QtDir)/qtbase/bin</QtBin>
<QtInclude>$(QtDir)/qtbase/include;../../Qt/Src/qtbase/include</QtInclude> <QtInclude>$(QtDir)/qtbase/include;../../Qt/Src/qtbase/include</QtInclude>
<QtLib>$(QtDir)/qtbase/lib;$(QtDir)/qtbase/plugins/platforms</QtLib> <QtLib>$(QtDir)/qtbase/lib;$(QtDir)/qtbase/plugins/platforms</QtLib>
<Lua>../../lua/lua</Lua>
</PropertyGroup> </PropertyGroup>
<PropertyGroup /> <PropertyGroup />
<ItemDefinitionGroup> <ItemDefinitionGroup>
<Link /> <Link />
<ClCompile> <ClCompile>
<AdditionalIncludeDirectories>..;$(IntDir);$(QtInclude);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..;$(QtInclude);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile> </ClCompile>
<Link> <Link>
<AdditionalLibraryDirectories>$(QtLib);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories> <AdditionalLibraryDirectories>$(QtLib);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
@ -31,8 +30,5 @@
<BuildMacro Include="QtLib"> <BuildMacro Include="QtLib">
<Value>$(QtLib)</Value> <Value>$(QtLib)</Value>
</BuildMacro> </BuildMacro>
<BuildMacro Include="Lua">
<Value>$(Lua)</Value>
</BuildMacro>
</ItemGroup> </ItemGroup>
</Project> </Project>
Loading…
Cancel
Save