From a00c76944e2a10021c3ffd0915a6ae39734467e4 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 23 Mar 2015 12:07:57 +0100 Subject: [PATCH 01/16] Removing string as a token. - The string keyword is reserved for future use but should not be a token in the code since it can cause trigger internal compiler assertions. - fixes #1384 --- libsolidity/ExpressionCompiler.h | 1 - libsolidity/Token.h | 1 - 2 files changed, 2 deletions(-) diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index e6caad747..2577d21b5 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -42,7 +42,6 @@ class CompilerContext; class Type; class IntegerType; class ArrayType; -class StaticStringType; /** * Compiler for expressions, i.e. converts an AST tree whose root is an Expression into a stream diff --git a/libsolidity/Token.h b/libsolidity/Token.h index b2951e939..6ffbe2194 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -290,7 +290,6 @@ namespace solidity K(Byte, "byte", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ - K(StringType, "string", 0) \ K(Real, "real", 0) \ K(UReal, "ureal", 0) \ T(TypesEnd, NULL, 0) /* used as type enum end marker */ \ From 237b6da0ca9ea5507dc8caebcec26867a30f9d49 Mon Sep 17 00:00:00 2001 From: winsvega Date: Mon, 23 Mar 2015 17:52:34 +0300 Subject: [PATCH 02/16] Transaction Data Must Be Array +libsecp256k1test --- libethereum/Transaction.cpp | 4 ++++ test/ttTransactionTestFiller.json | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index 31a7f74a9..9a5e7fb3f 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -68,6 +68,10 @@ Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig) m_type = rlp[field = 3].isEmpty() ? ContractCreation : MessageCall; m_receiveAddress = rlp[field = 3].isEmpty() ? Address() : rlp[field = 3].toHash
(RLP::VeryStrict); m_value = rlp[field = 4].toInt(); + + if (rlp[field = 5].isList()) + BOOST_THROW_EXCEPTION(BadRLP() << errinfo_comment("transaction data RLP must be an array")); + m_data = rlp[field = 5].toBytes(); byte v = rlp[field = 6].toInt() - 27; h256 r = rlp[field = 7].toInt(); diff --git a/test/ttTransactionTestFiller.json b/test/ttTransactionTestFiller.json index 105b64abc..4f8005c5f 100644 --- a/test/ttTransactionTestFiller.json +++ b/test/ttTransactionTestFiller.json @@ -511,6 +511,7 @@ "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } }, + "unpadedRValue": { "transaction": { "nonce": "13", @@ -523,5 +524,19 @@ "v": "28", "value": "" } + }, + + "libsecp256k1test": { + "transaction": { + "nonce": "", + "gasPrice": "0x09184e72a000", + "gasLimit": "0x1388", + "to": "", + "data": "", + "r": "44", + "s": "4", + "v": "27", + "value": "" + } } } From d12f6540d193f212b181cc33b458a298d3d8723b Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Mon, 23 Mar 2015 13:09:15 +0100 Subject: [PATCH 03/16] Adding keywords for future use section in Token.h --- libsolidity/Token.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 6ffbe2194..57d71c1fe 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -143,7 +143,6 @@ namespace solidity \ /* Keywords */ \ K(Break, "break", 0) \ - K(Case, "case", 0) \ K(Const, "constant", 0) \ K(Anonymous, "anonymous", 0) \ K(Continue, "continue", 0) \ @@ -168,7 +167,6 @@ namespace solidity K(Return, "return", 0) \ K(Returns, "returns", 0) \ K(Struct, "struct", 0) \ - K(Switch, "switch", 0) \ K(Var, "var", 0) \ K(While, "while", 0) \ K(Enum, "enum", 0) \ @@ -305,6 +303,13 @@ namespace solidity /* Identifiers (not keywords or future reserved words). */ \ T(Identifier, NULL, 0) \ \ + /* Keywords reserved for future. use*/ \ + T(String, "string", 0) \ + K(Case, "case", 0) \ + K(Switch, "switch", 0) \ + K(Throw, "throw", 0) \ + K(Try, "try", 0) \ + K(Catch, "catch", 0) \ /* Illegal token - not able to scan. */ \ T(Illegal, "ILLEGAL", 0) \ \ From 4a436715cfa38b699a1f58c077d8e3717f233f6b Mon Sep 17 00:00:00 2001 From: winsvega Date: Mon, 23 Mar 2015 23:50:04 +0300 Subject: [PATCH 04/16] Exceptions --- libethereum/Transaction.cpp | 2 +- test/transaction.cpp | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index 9a5e7fb3f..502f089fb 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -69,7 +69,7 @@ Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig) m_receiveAddress = rlp[field = 3].isEmpty() ? Address() : rlp[field = 3].toHash
(RLP::VeryStrict); m_value = rlp[field = 4].toInt(); - if (rlp[field = 5].isList()) + if (!rlp[field = 5].isData()) BOOST_THROW_EXCEPTION(BadRLP() << errinfo_comment("transaction data RLP must be an array")); m_data = rlp[field = 5].toBytes(); diff --git a/test/transaction.cpp b/test/transaction.cpp index 77f6ecdaf..4c57326ba 100644 --- a/test/transaction.cpp +++ b/test/transaction.cpp @@ -48,6 +48,13 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) if (!txFromRlp.signature().isValid()) BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") ); } + catch(Exception const& _e) + { + cnote << i.first; + cnote << "Transaction Exception: " << diagnostic_information(_e); + BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transaction object should not be defined because the RLP is invalid!"); + continue; + } catch(...) { BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transaction object should not be defined because the RLP is invalid!"); From 9e10137d33d505a78091bc7d07963facfd336b20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Bylica?= Date: Tue, 24 Mar 2015 13:54:05 +0100 Subject: [PATCH 05/16] Increase executable stack size to 16MB on Windows Fixes ethereum/cpp-ethereum#1313 --- cmake/EthCompilerSettings.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index a0d5a50c1..7a5c94e6b 100755 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -43,7 +43,8 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") # warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification # warning LNK4099: pdb was not found with lib - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075") + # stack size 16MB + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075 /STACK:16777216") # windows likes static set(ETH_STATIC 1) From fdd2959fff4815b0bce45019c22adf8825ab0192 Mon Sep 17 00:00:00 2001 From: Lefteris Karapetsas Date: Tue, 24 Mar 2015 19:04:41 +0100 Subject: [PATCH 06/16] Adding some more reserved keywords --- libsolidity/Token.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libsolidity/Token.h b/libsolidity/Token.h index 57d71c1fe..1435dcc57 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -310,6 +310,9 @@ namespace solidity K(Throw, "throw", 0) \ K(Try, "try", 0) \ K(Catch, "catch", 0) \ + K(Using, "using", 0) \ + K(Type, "type", 0) \ + K(TypeOf, "typeof", 0) \ /* Illegal token - not able to scan. */ \ T(Illegal, "ILLEGAL", 0) \ \ From c905a66b3e101f51fa054957f8e8fb6276f31062 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Tue, 24 Mar 2015 20:40:22 +0100 Subject: [PATCH 07/16] fixed numeber of http server threads, fixed #1147 --- alethzero/MainWin.cpp | 6 +++++- eth/main.cpp | 12 ++++++++++-- neth/main.cpp | 12 ++++++++++-- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index d566882f3..034952ecd 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -164,7 +164,11 @@ Main::Main(QWidget *parent) : 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(), false, {"eth", "shh"}, p2p::NetworkPreferences(), network)); - m_httpConnector.reset(new jsonrpc::HttpServer(8080)); +#if ETH_DEBUG + m_httpConnector.reset(new jsonrpc::HttpServer(8080, "", "", 1)); +#else + m_httpConnector.reset(new jsonrpc::HttpServer(8080, "", "", 4)); +#endif m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), keysAsVector(m_myKeys), this)); connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString))); m_server->setIdentities(keysAsVector(owned())); diff --git a/eth/main.cpp b/eth/main.cpp index eda6e12ae..e89a1250f 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -457,7 +457,11 @@ int main(int argc, char** argv) unique_ptr jsonrpcConnector; if (jsonrpc > -1) { - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); +#if ETH_DEBUG + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); +#else + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); +#endif jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); @@ -583,7 +587,11 @@ int main(int argc, char** argv) { if (jsonrpc < 0) jsonrpc = 8080; - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); +#if ETH_DEBUG + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); +#else + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); +#endif jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); diff --git a/neth/main.cpp b/neth/main.cpp index 4888f784d..fc4c8c9c6 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -474,7 +474,11 @@ int main(int argc, char** argv) unique_ptr jsonrpcConnector; if (jsonrpc > -1) { - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); +#if ETH_DEBUG + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); +#else + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); +#endif jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); @@ -625,7 +629,11 @@ int main(int argc, char** argv) { if (jsonrpc < 0) jsonrpc = 8080; - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); +#if ETH_DEBUG + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); +#else + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); +#endif jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); From 7567cf72ec9bb11319eef9c218dd28459eb7c45e Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 25 Mar 2015 09:31:43 +0100 Subject: [PATCH 08/16] split #1351, cmake changes --- cmake/EthDependencies.cmake | 3 +++ cmake/EthUtils.cmake | 40 +++++++++++++++++++++++++++++++++++++ cmake/scripts/runtest.cmake | 15 ++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 cmake/scripts/runtest.cmake diff --git a/cmake/EthDependencies.cmake b/cmake/EthDependencies.cmake index ea272da56..05893715e 100644 --- a/cmake/EthDependencies.cmake +++ b/cmake/EthDependencies.cmake @@ -30,6 +30,9 @@ if (APPLE) set (CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/local/opt/qt5") endif() +find_program(CTEST_COMMAND ctest) +message(STATUS "ctest path: ${CTEST_COMMAND}") + # Dependencies must have a version number, to ensure reproducible build. The version provided here is the one that is in the extdep repository. If you use system libraries, version numbers may be different. find_package (CryptoPP 5.6.2 EXACT REQUIRED) diff --git a/cmake/EthUtils.cmake b/cmake/EthUtils.cmake index c6fd43ed4..69690156a 100644 --- a/cmake/EthUtils.cmake +++ b/cmake/EthUtils.cmake @@ -22,3 +22,43 @@ macro(replace_if_different SOURCE DST) endif() endmacro() +macro(eth_add_test NAME) + + # parse arguments here + set(commands) + set(current_command "") + foreach (arg ${ARGN}) + if (arg STREQUAL "ARGS") + if (current_command) + list(APPEND commands ${current_command}) + endif() + set(current_command "") + else () + set(current_command "${current_command} ${arg}") + endif() + endforeach(arg) + list(APPEND commands ${current_command}) + + message(STATUS "test: ${NAME} | ${commands}") + + # create tests + set(index 0) + list(LENGTH commands count) + while (index LESS count) + list(GET commands ${index} test_arguments) + + set(run_test "--run_test=${NAME}") + add_test(NAME "${NAME}.${index}" COMMAND testeth ${run_test} ${test_arguments}) + + math(EXPR index "${index} + 1") + endwhile(index LESS count) + + # add target to run them + add_custom_target("test.${NAME}" + DEPENDS testeth + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + COMMAND ${CMAKE_COMMAND} -DETH_TEST_NAME="${NAME}" -DCTEST_COMMAND="${CTEST_COMMAND}" -P "${ETH_SCRIPTS_DIR}/runtest.cmake" + ) + +endmacro() + diff --git a/cmake/scripts/runtest.cmake b/cmake/scripts/runtest.cmake new file mode 100644 index 000000000..15f7409ef --- /dev/null +++ b/cmake/scripts/runtest.cmake @@ -0,0 +1,15 @@ +# Should be used to run ctest +# +# example usage: +# cmake -DETH_TEST_NAME=TestInterfaceStub -DCTEST_COMMAND=/path/to/ctest -P scripts/runtest.cmake + +if (NOT CTEST_COMMAND) + message(FATAL_ERROR "ctest could not be found!") +endif() + +# verbosity is off, cause BOOST_MESSAGE is not thread safe and output is a trash +# see https://codecrafter.wordpress.com/2012/11/01/c-unit-test-framework-adapter-part-3/ +# +# output might not be usefull cause of thread safety issue +execute_process(COMMAND ${CTEST_COMMAND} --force-new-ctest-process -C Debug --output-on-failure -j 4 -R "${ETH_TEST_NAME}[.].*") + From c4a4b8014b23fdbac8483eec487528f961eba4f3 Mon Sep 17 00:00:00 2001 From: Marek Kotewicz Date: Wed, 25 Mar 2015 09:41:47 +0100 Subject: [PATCH 09/16] fixed dependency on windows.h include order when using std::min && std::max --- cmake/EthCompilerSettings.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index a0d5a50c1..bbc8473e6 100755 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -38,7 +38,8 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") # disable decorated name length exceeded, name was truncated (4503) # disable warning C4535: calling _set_se_translator() requires /EHa (for boost tests) # declare Windows XP requirement - add_compile_options(/MP /EHsc /wd4068 /wd4996 /wd4503 -D_WIN32_WINNT=0x0501) + # undefine windows.h MAX && MIN macros cause it cause conflicts with std::min && std::max functions + add_compile_options(/MP /EHsc /wd4068 /wd4996 /wd4503 -D_WIN32_WINNT=0x0501 /DNOMINMAX) # disable empty object file warning set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") # warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification From 36e2c9dbeee9c7f5a3b27ac320e6d9e558da532f Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 25 Mar 2015 12:32:34 +0100 Subject: [PATCH 10/16] Hide accounts/contracts when we're not compiled with FATDB. Fixes #1403 --- alethzero/Main.ui | 4 ++-- alethzero/MainWin.cpp | 25 +++++++++++++++++++------ libethereum/Interface.h | 1 + libethereum/State.cpp | 4 ++++ libethereum/State.h | 1 + 5 files changed, 27 insertions(+), 8 deletions(-) diff --git a/alethzero/Main.ui b/alethzero/Main.ui index da5ee6c4a..34f240fbf 100644 --- a/alethzero/Main.ui +++ b/alethzero/Main.ui @@ -208,7 +208,7 @@ - + QDockWidget::DockWidgetFeatureMask @@ -566,7 +566,7 @@ - + QDockWidget::DockWidgetFeatureMask diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index d566882f3..f63cd74f0 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -135,6 +135,11 @@ Main::Main(QWidget *parent) : // ui->log->addItem(QString::fromStdString(s)); }; +#if !ETH_FATDB + ui->dockWidgetAccounts->hide(); + ui->dockWidgetContracts->hide(); +#endif + #if ETH_DEBUG m_servers.append("localhost:30300"); #endif @@ -1036,6 +1041,7 @@ void Main::refreshPending() void Main::refreshAccounts() { +#if ETH_FATDB cwatch << "refreshAccounts()"; ui->accounts->clear(); ui->contracts->clear(); @@ -1053,6 +1059,7 @@ void Main::refreshAccounts() ->setData(Qt::UserRole, QByteArray((char const*)i.data(), Address::size)); } } +#endif } void Main::refreshBlockCount() @@ -1626,16 +1633,22 @@ void Main::on_ourAccounts_doubleClicked() void Main::on_accounts_doubleClicked() { - auto hba = ui->accounts->currentItem()->data(Qt::UserRole).toByteArray(); - auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); - qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); + if (!ui->accounts->isEmpty()) + { + auto hba = ui->accounts->currentItem()->data(Qt::UserRole).toByteArray(); + auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); + qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); + } } void Main::on_contracts_doubleClicked() { - auto hba = ui->contracts->currentItem()->data(Qt::UserRole).toByteArray(); - auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); - qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); + if (!ui->contracts->isEmpty()) + { + auto hba = ui->contracts->currentItem()->data(Qt::UserRole).toByteArray(); + auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); + qApp->clipboard()->setText(QString::fromStdString(toHex(h.asArray()))); + } } static shh::FullTopic topicFromText(QString _s) diff --git a/libethereum/Interface.h b/libethereum/Interface.h index 68eb4b094..b78106ae1 100644 --- a/libethereum/Interface.h +++ b/libethereum/Interface.h @@ -138,6 +138,7 @@ public: virtual StateDiff diff(unsigned _txi, BlockNumber _block) const = 0; /// Get a list of all active addresses. + /// NOTE: This only works when compiled with ETH_FATDB; otherwise will throw InterfaceNotSupported. virtual Addresses addresses() const { return addresses(m_default); } virtual Addresses addresses(BlockNumber _block) const = 0; diff --git a/libethereum/State.cpp b/libethereum/State.cpp index c5732116d..486abde12 100644 --- a/libethereum/State.cpp +++ b/libethereum/State.cpp @@ -342,6 +342,7 @@ u256 State::enactOn(bytesConstRef _block, BlockInfo const& _bi, BlockChain const map State::addresses() const { +#if ETH_FATDB map ret; for (auto i: m_cache) if (i.second.isAlive()) @@ -350,6 +351,9 @@ map State::addresses() const if (m_cache.find(i.first) == m_cache.end()) ret[i.first] = RLP(i.second)[1].toInt(); return ret; +#else + throw InterfaceNotSupported("State::addresses()"); +#endif } void State::resetCurrent() diff --git a/libethereum/State.h b/libethereum/State.h index 46a111a9b..3883a4897 100644 --- a/libethereum/State.h +++ b/libethereum/State.h @@ -127,6 +127,7 @@ public: OverlayDB const& db() const { return m_db; } /// @returns the set containing all addresses currently in use in Ethereum. + /// @throws InterfaceNotSupported if compiled without ETH_FATDB. std::map addresses() const; /// Get the header information on the present block. From e26de2489e1751405372c18360c52b138fa9de75 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 25 Mar 2015 13:10:30 +0100 Subject: [PATCH 11/16] Fix AZ accounts/contracts panes. Added initial ABI tool. --- CMakeLists.txt | 3 +- abi/CMakeLists.txt | 16 +++++ abi/main.cpp | 137 ++++++++++++++++++++++++++++++++++++++++++ alethzero/MainWin.cpp | 8 +-- 4 files changed, 159 insertions(+), 5 deletions(-) create mode 100644 abi/CMakeLists.txt create mode 100644 abi/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index e7e89a5a7..40a3e8e63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -160,7 +160,6 @@ if (EVMJIT) endif() add_subdirectory(libdevcore) -add_subdirectory(rlp) add_subdirectory(libevmcore) add_subdirectory(liblll) @@ -199,6 +198,8 @@ add_subdirectory(test) if (NOT JUSTTESTS) + add_subdirectory(rlp) + add_subdirectory(abi) add_subdirectory(eth) if("x${CMAKE_BUILD_TYPE}" STREQUAL "xDebug") diff --git a/abi/CMakeLists.txt b/abi/CMakeLists.txt new file mode 100644 index 000000000..82c7c4240 --- /dev/null +++ b/abi/CMakeLists.txt @@ -0,0 +1,16 @@ +cmake_policy(SET CMP0015 NEW) +set(CMAKE_AUTOMOC OFF) + +aux_source_directory(. SRC_LIST) + +include_directories(BEFORE ..) +include_directories(${LEVELDB_INCLUDE_DIRS}) + +set(EXECUTABLE abi) + +add_executable(${EXECUTABLE} ${SRC_LIST}) + +target_link_libraries(${EXECUTABLE} ethereum) + +install( TARGETS ${EXECUTABLE} DESTINATION bin) + diff --git a/abi/main.cpp b/abi/main.cpp new file mode 100644 index 000000000..7bb00e390 --- /dev/null +++ b/abi/main.cpp @@ -0,0 +1,137 @@ +/* + 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 main.cpp + * @author Gav Wood + * @date 2014 + * RLP tool. + */ +#include +#include +#include +#include "../test/JsonSpiritHeaders.h" +#include +#include +#include +#include +using namespace std; +using namespace dev; +namespace js = json_spirit; + +void help() +{ + cout + << "Usage abi enc (, (, ... ))" << endl + << " abi enc -a (, (, ... ))" << endl + << " abi dec -a [ | ]" << endl + << "Options:" << endl + << " -a,--abi-file Specify the JSON ABI file." << endl + << "Output options (dec mode):" << endl + << " -i,--index When decoding, output only the nth (counting from 0) return value." << endl + << " -d,--decimal All data should be displayed as decimal." << endl + << " -x,--hex Display all data as hex." << endl + << " -b,--binary Display all data as binary." << endl + << " -p,--prefix Prefix by a base identifier." << endl + << " -z,--no-zeroes Remove any leading zeroes from the data." << endl + << " -n,--no-nulls Remove any trailing nulls from the data." << endl + << "General options:" << endl + << " -h,--help Print this help message and exit." << endl + << " -V,--version Show the version and exit." << endl + ; + exit(0); +} + +void version() +{ + cout << "abi version " << dev::Version << endl; + exit(0); +} + +enum class Mode { + Encode, + Decode +}; + +enum class Encoding { + Auto, + Decimal, + Hex, + Binary, +}; + +int main(int argc, char** argv) +{ + Encoding encoding = Encoding::Auto; + Mode mode = Mode::Encode; + string abiFile; + string methodName; + bool outputPrefix = false; + bool clearZeroes = false; + bool clearNulls = false; + int outputIndex = -1; + + for (int i = 1; i < argc; ++i) + { + string arg = argv[i]; + if (arg == "-h" || arg == "--help") + help(); + else if (arg == "enc" && i == 1) + mode = Mode::Encode; + else if (arg == "dec" && i == 1) + mode = Mode::Decode; + else if ((arg == "-a" || arg == "--abi") && argc > i) + abiFile = argv[++i]; + else if ((arg == "-i" || arg == "--index") && argc > i) + outputIndex = atoi(argv[++i]); + else if (arg == "-p" || arg == "--prefix") + outputPrefix = true; + else if (arg == "-z" || arg == "--no-zeroes") + clearZeroes = true; + else if (arg == "-n" || arg == "--no-nulls") + clearNulls = true; + else if (arg == "-x" || arg == "--hex") + encoding = Encoding::Hex; + else if (arg == "-d" || arg == "--decimal" || arg == "--dec") + encoding = Encoding::Decimal; + else if (arg == "-b" || arg == "--binary" || arg == "--bin") + encoding = Encoding::Binary; + else if (arg == "-V" || arg == "--version") + version(); + else + methodName = arg; + } + + string abi; + if (abiFile == "--") + for (int i = cin.get(); i != -1; i = cin.get()) + abi.push_back((char)i); + else if (!abiFile.empty()) + abi = contentsString(abiFile); + + if (mode == Mode::Encode) + { + (void)encoding; + (void)outputPrefix; + (void)clearZeroes; + (void)clearNulls; + (void)outputIndex; + } + else if (mode == Mode::Decode) + { + } + + return 0; +} diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index f63cd74f0..4b9af1666 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -136,8 +136,8 @@ Main::Main(QWidget *parent) : }; #if !ETH_FATDB - ui->dockWidgetAccounts->hide(); - ui->dockWidgetContracts->hide(); + delete ui->dockWidget_accounts; + delete ui->dockWidget_contracts; #endif #if ETH_DEBUG @@ -1633,7 +1633,7 @@ void Main::on_ourAccounts_doubleClicked() void Main::on_accounts_doubleClicked() { - if (!ui->accounts->isEmpty()) + if (ui->accounts->count()) { auto hba = ui->accounts->currentItem()->data(Qt::UserRole).toByteArray(); auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); @@ -1643,7 +1643,7 @@ void Main::on_accounts_doubleClicked() void Main::on_contracts_doubleClicked() { - if (!ui->contracts->isEmpty()) + if (ui->contracts->count()) { auto hba = ui->contracts->currentItem()->data(Qt::UserRole).toByteArray(); auto h = Address((byte const*)hba.data(), Address::ConstructFromPointer); From 42e6a291444e2b3e0b1075302ef3f65d0fcba6d3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 25 Mar 2015 14:45:50 +0100 Subject: [PATCH 12/16] More towards an implementation. --- abi/main.cpp | 75 +++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 66 insertions(+), 9 deletions(-) diff --git a/abi/main.cpp b/abi/main.cpp index 7bb00e390..34187acc7 100644 --- a/abi/main.cpp +++ b/abi/main.cpp @@ -39,8 +39,10 @@ void help() << " abi dec -a [ | ]" << endl << "Options:" << endl << " -a,--abi-file Specify the JSON ABI file." << endl + << "Input options (enc mode):" << endl + << " -p,--prefix Require all arguments to be prefixed 0x (hex), . (decimal), # (binary)." << endl << "Output options (dec mode):" << endl - << " -i,--index When decoding, output only the nth (counting from 0) return value." << endl + << " -i,--index Output only the nth (counting from 0) return value." << endl << " -d,--decimal All data should be displayed as decimal." << endl << " -x,--hex Display all data as hex." << endl << " -b,--binary Display all data as binary." << endl @@ -72,16 +74,57 @@ enum class Encoding { Binary, }; +struct InvalidUserString: public Exception {}; + +pair fromUser(std::string const& _arg, bool _requirePrefix) +{ + if (_requirePrefix) + { + if (_arg.substr(0, 2) == "0x") + return make_pair(fromHex(_arg), false); + if (_arg.substr(0, 1) == ".") + return make_pair(toCompactBigEndian(bigint(_arg.substr(1))), false); + if (_arg.substr(0, 1) == "#") + return make_pair(asBytes(_arg.substr(1)), true); + throw InvalidUserString(); + } + else + { + if (_arg.substr(0, 2) == "0x") + return make_pair(fromHex(_arg), false); + if (_arg.find_first_not_of("0123456789")) + return make_pair(toCompactBigEndian(bigint(_arg)), false); + return make_pair(asBytes(_arg), true); + } +} + +bytes aligned(bytes const& _b, bool _left, unsigned _length) +{ + bytes ret = _b; + while (ret.size() < _length) + if (_left) + ret.push_back(0); + else + ret.insert(ret.begin(), 0); + while (ret.size() > _length) + if (_left) + ret.pop_back(); + else + ret.erase(ret.begin()); + return ret; +} + int main(int argc, char** argv) { Encoding encoding = Encoding::Auto; Mode mode = Mode::Encode; string abiFile; - string methodName; - bool outputPrefix = false; + string method; + bool prefix = false; bool clearZeroes = false; bool clearNulls = false; int outputIndex = -1; + vector> args; for (int i = 1; i < argc; ++i) { @@ -97,7 +140,7 @@ int main(int argc, char** argv) else if ((arg == "-i" || arg == "--index") && argc > i) outputIndex = atoi(argv[++i]); else if (arg == "-p" || arg == "--prefix") - outputPrefix = true; + prefix = true; else if (arg == "-z" || arg == "--no-zeroes") clearZeroes = true; else if (arg == "-n" || arg == "--no-nulls") @@ -110,8 +153,10 @@ int main(int argc, char** argv) encoding = Encoding::Binary; else if (arg == "-V" || arg == "--version") version(); + else if (method.empty()) + method = arg; else - methodName = arg; + args.push_back(fromUser(arg, prefix)); } string abi; @@ -122,16 +167,28 @@ int main(int argc, char** argv) abi = contentsString(abiFile); if (mode == Mode::Encode) + { + if (abi.empty()) + { + bytes ret; + if (!method.empty()) + ret = FixedHash<32>(sha3(method)).asBytes(); + if (method.empty()) + for (pair const& arg: args) + ret += aligned(arg.first, arg.second, 32); + } + else + { + // TODO: read abi. + } + } + else if (mode == Mode::Decode) { (void)encoding; - (void)outputPrefix; (void)clearZeroes; (void)clearNulls; (void)outputIndex; } - else if (mode == Mode::Decode) - { - } return 0; } From d71bec193f7991d70e96fa2b4819652546bae21b Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 25 Mar 2015 18:33:20 +0100 Subject: [PATCH 13/16] Clean up some code redundancy. Merge branch 'develop' of github.com:ethereum/cpp-ethereum into develop --- alethzero/MainWin.cpp | 6 +++++- cmake/EthCompilerSettings.cmake | 3 ++- eth/main.cpp | 12 ++++++++++-- libethereum/Transaction.cpp | 4 ++++ libsolidity/ExpressionCompiler.h | 1 - libsolidity/Token.h | 13 ++++++++++--- neth/main.cpp | 12 ++++++++++-- test/transaction.cpp | 7 +++++++ test/ttTransactionTestFiller.json | 15 +++++++++++++++ 9 files changed, 63 insertions(+), 10 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index 4b9af1666..d0cfafd7d 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -169,7 +169,11 @@ Main::Main(QWidget *parent) : 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(), false, {"eth", "shh"}, p2p::NetworkPreferences(), network)); - m_httpConnector.reset(new jsonrpc::HttpServer(8080)); +#if ETH_DEBUG + m_httpConnector.reset(new jsonrpc::HttpServer(8080, "", "", 1)); +#else + m_httpConnector.reset(new jsonrpc::HttpServer(8080, "", "", 4)); +#endif m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), keysAsVector(m_myKeys), this)); connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString))); m_server->setIdentities(keysAsVector(owned())); diff --git a/cmake/EthCompilerSettings.cmake b/cmake/EthCompilerSettings.cmake index a0d5a50c1..7a5c94e6b 100755 --- a/cmake/EthCompilerSettings.cmake +++ b/cmake/EthCompilerSettings.cmake @@ -43,7 +43,8 @@ elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221") # warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/SAFESEH' specification # warning LNK4099: pdb was not found with lib - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075") + # stack size 16MB + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /ignore:4099,4075 /STACK:16777216") # windows likes static set(ETH_STATIC 1) diff --git a/eth/main.cpp b/eth/main.cpp index eda6e12ae..e89a1250f 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -457,7 +457,11 @@ int main(int argc, char** argv) unique_ptr jsonrpcConnector; if (jsonrpc > -1) { - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); +#if ETH_DEBUG + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); +#else + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); +#endif jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); @@ -583,7 +587,11 @@ int main(int argc, char** argv) { if (jsonrpc < 0) jsonrpc = 8080; - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); +#if ETH_DEBUG + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); +#else + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); +#endif jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); diff --git a/libethereum/Transaction.cpp b/libethereum/Transaction.cpp index 31a7f74a9..502f089fb 100644 --- a/libethereum/Transaction.cpp +++ b/libethereum/Transaction.cpp @@ -68,6 +68,10 @@ Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig) m_type = rlp[field = 3].isEmpty() ? ContractCreation : MessageCall; m_receiveAddress = rlp[field = 3].isEmpty() ? Address() : rlp[field = 3].toHash
(RLP::VeryStrict); m_value = rlp[field = 4].toInt(); + + if (!rlp[field = 5].isData()) + BOOST_THROW_EXCEPTION(BadRLP() << errinfo_comment("transaction data RLP must be an array")); + m_data = rlp[field = 5].toBytes(); byte v = rlp[field = 6].toInt() - 27; h256 r = rlp[field = 7].toInt(); diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index e6caad747..2577d21b5 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -42,7 +42,6 @@ class CompilerContext; class Type; class IntegerType; class ArrayType; -class StaticStringType; /** * Compiler for expressions, i.e. converts an AST tree whose root is an Expression into a stream diff --git a/libsolidity/Token.h b/libsolidity/Token.h index b2951e939..1435dcc57 100644 --- a/libsolidity/Token.h +++ b/libsolidity/Token.h @@ -143,7 +143,6 @@ namespace solidity \ /* Keywords */ \ K(Break, "break", 0) \ - K(Case, "case", 0) \ K(Const, "constant", 0) \ K(Anonymous, "anonymous", 0) \ K(Continue, "continue", 0) \ @@ -168,7 +167,6 @@ namespace solidity K(Return, "return", 0) \ K(Returns, "returns", 0) \ K(Struct, "struct", 0) \ - K(Switch, "switch", 0) \ K(Var, "var", 0) \ K(While, "while", 0) \ K(Enum, "enum", 0) \ @@ -290,7 +288,6 @@ namespace solidity K(Byte, "byte", 0) \ K(Address, "address", 0) \ K(Bool, "bool", 0) \ - K(StringType, "string", 0) \ K(Real, "real", 0) \ K(UReal, "ureal", 0) \ T(TypesEnd, NULL, 0) /* used as type enum end marker */ \ @@ -306,6 +303,16 @@ namespace solidity /* Identifiers (not keywords or future reserved words). */ \ T(Identifier, NULL, 0) \ \ + /* Keywords reserved for future. use*/ \ + T(String, "string", 0) \ + K(Case, "case", 0) \ + K(Switch, "switch", 0) \ + K(Throw, "throw", 0) \ + K(Try, "try", 0) \ + K(Catch, "catch", 0) \ + K(Using, "using", 0) \ + K(Type, "type", 0) \ + K(TypeOf, "typeof", 0) \ /* Illegal token - not able to scan. */ \ T(Illegal, "ILLEGAL", 0) \ \ diff --git a/neth/main.cpp b/neth/main.cpp index 4888f784d..fc4c8c9c6 100644 --- a/neth/main.cpp +++ b/neth/main.cpp @@ -474,7 +474,11 @@ int main(int argc, char** argv) unique_ptr jsonrpcConnector; if (jsonrpc > -1) { - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); +#if ETH_DEBUG + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); +#else + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); +#endif jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); @@ -625,7 +629,11 @@ int main(int argc, char** argv) { if (jsonrpc < 0) jsonrpc = 8080; - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc)); +#if ETH_DEBUG + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); +#else + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); +#endif jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); diff --git a/test/transaction.cpp b/test/transaction.cpp index 77f6ecdaf..4c57326ba 100644 --- a/test/transaction.cpp +++ b/test/transaction.cpp @@ -48,6 +48,13 @@ void doTransactionTests(json_spirit::mValue& _v, bool _fillin) if (!txFromRlp.signature().isValid()) BOOST_THROW_EXCEPTION(Exception() << errinfo_comment("transaction from RLP signature is invalid") ); } + catch(Exception const& _e) + { + cnote << i.first; + cnote << "Transaction Exception: " << diagnostic_information(_e); + BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transaction object should not be defined because the RLP is invalid!"); + continue; + } catch(...) { BOOST_CHECK_MESSAGE(o.count("transaction") == 0, "A transaction object should not be defined because the RLP is invalid!"); diff --git a/test/ttTransactionTestFiller.json b/test/ttTransactionTestFiller.json index 0058feac1..c04b76848 100644 --- a/test/ttTransactionTestFiller.json +++ b/test/ttTransactionTestFiller.json @@ -571,6 +571,7 @@ "s" : "0x8887321be575c8095f789dd4c743dfe42c1820f9231f98a962b210e3ac2452a3" } }, + "unpadedRValue": { "transaction": { "nonce": "13", @@ -583,5 +584,19 @@ "v": "28", "value": "" } + }, + + "libsecp256k1test": { + "transaction": { + "nonce": "", + "gasPrice": "0x09184e72a000", + "gasLimit": "0x1388", + "to": "", + "data": "", + "r": "44", + "s": "4", + "v": "27", + "value": "" + } } } From 60da83fb0acf3b3a77a3aaa099c4e4793eec9233 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 25 Mar 2015 18:51:08 +0100 Subject: [PATCH 14/16] Record and detail gas refund. --- alethzero/MainWin.cpp | 6 +----- alethzero/Transact.cpp | 4 ++-- eth/main.cpp | 18 +++++------------- libethereum/Executive.cpp | 5 +++++ libethereum/Executive.h | 2 +- libethereum/Transaction.h | 3 ++- libweb3jsonrpc/WebThreeStubServerBase.cpp | 7 +++++++ libweb3jsonrpc/WebThreeStubServerBase.h | 3 +++ 8 files changed, 26 insertions(+), 22 deletions(-) diff --git a/alethzero/MainWin.cpp b/alethzero/MainWin.cpp index d0cfafd7d..0ee2961a1 100644 --- a/alethzero/MainWin.cpp +++ b/alethzero/MainWin.cpp @@ -169,11 +169,7 @@ Main::Main(QWidget *parent) : 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(), false, {"eth", "shh"}, p2p::NetworkPreferences(), network)); -#if ETH_DEBUG - m_httpConnector.reset(new jsonrpc::HttpServer(8080, "", "", 1)); -#else - m_httpConnector.reset(new jsonrpc::HttpServer(8080, "", "", 4)); -#endif + m_httpConnector.reset(new jsonrpc::HttpServer(SensibleHttpPort, "", "", dev::SensibleHttpThreads)); m_server.reset(new OurWebThreeStubServer(*m_httpConnector, *web3(), keysAsVector(m_myKeys), this)); connect(&*m_server, SIGNAL(onNewId(QString)), SLOT(addNewId(QString))); m_server->setIdentities(keysAsVector(owned())); diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 7248ee4a6..29eafff03 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -328,8 +328,8 @@ void Transact::rejigData() to = m_context->fromString(ui->destination->currentText()); er = ethereum()->call(s, value(), to, m_data, ethereum()->gasLimitRemaining(), gasPrice()); } - gasNeeded = (qint64)er.gasUsed; - htmlInfo = QString("
INFO Gas required: %1 total = %2 base, %3 exec
").arg(gasNeeded).arg(baseGas).arg(gasNeeded - baseGas) + htmlInfo; + gasNeeded = (qint64)(er.gasUsed + er.gasRefunded); + htmlInfo = QString("
INFO Gas required: %1 total = %2 base, %3 exec [%4 refunded later]
").arg(gasNeeded).arg(baseGas).arg(gasNeeded - baseGas).arg(er.gasRefunded) + htmlInfo; if (er.excepted != TransactionException::None) { diff --git a/eth/main.cpp b/eth/main.cpp index e89a1250f..03c54a5b1 100644 --- a/eth/main.cpp +++ b/eth/main.cpp @@ -117,7 +117,7 @@ void help() << " -i,--interactive Enter interactive mode (default: non-interactive)." << endl #if ETH_JSONRPC << " -j,--json-rpc Enable JSON-RPC server (default: off)." << endl - << " --json-rpc-port Specify JSON-RPC server port (implies '-j', default: 8080)." << endl + << " --json-rpc-port Specify JSON-RPC server port (implies '-j', default: " << SensibleHttpPort << ")." << endl #endif << " -K,--kill-blockchain First kill the blockchain." << endl << " -l,--listen Listen on the given port for incoming connected (default: 30303)." << endl @@ -370,7 +370,7 @@ int main(int argc, char** argv) interactive = true; #if ETH_JSONRPC else if ((arg == "-j" || arg == "--json-rpc")) - jsonrpc = jsonrpc == -1 ? 8080 : jsonrpc; + jsonrpc = jsonrpc == -1 ? SensibleHttpPort : jsonrpc; else if (arg == "--json-rpc-port" && i + 1 < argc) jsonrpc = atoi(argv[++i]); #endif @@ -457,11 +457,7 @@ int main(int argc, char** argv) unique_ptr jsonrpcConnector; if (jsonrpc > -1) { -#if ETH_DEBUG - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); -#else - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); -#endif + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); @@ -586,12 +582,8 @@ int main(int argc, char** argv) else if (cmd == "jsonstart") { if (jsonrpc < 0) - jsonrpc = 8080; -#if ETH_DEBUG - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 1)); -#else - jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", 4)); -#endif + jsonrpc = SensibleHttpPort; + jsonrpcConnector = unique_ptr(new jsonrpc::HttpServer(jsonrpc, "", "", SensibleHttpThreads)); jsonrpcServer = shared_ptr(new WebThreeStubServer(*jsonrpcConnector.get(), web3, vector({us}))); jsonrpcServer->setIdentities({us}); jsonrpcServer->StartListening(); diff --git a/libethereum/Executive.cpp b/libethereum/Executive.cpp index 597506821..c574fa650 100644 --- a/libethereum/Executive.cpp +++ b/libethereum/Executive.cpp @@ -44,6 +44,11 @@ u256 Executive::gasUsed() const return m_t.gas() - m_endGas; } +ExecutionResult Executive::executionResult() const +{ + return ExecutionResult(gasUsed(), m_excepted, m_newAddress, m_out, m_codeDeposit, m_ext ? m_ext->sub.refunds : 0); +} + void Executive::accrueSubState(SubState& _parentContext) { if (m_ext) diff --git a/libethereum/Executive.h b/libethereum/Executive.h index d04a39da8..eb0c27ad2 100644 --- a/libethereum/Executive.h +++ b/libethereum/Executive.h @@ -104,7 +104,7 @@ public: bool excepted() const { return m_excepted != TransactionException::None; } /// Get the above in an amalgamated fashion. - ExecutionResult executionResult() const { return ExecutionResult(gasUsed(), m_excepted, m_newAddress, m_out, m_codeDeposit); } + ExecutionResult executionResult() const; private: bool setup(); diff --git a/libethereum/Transaction.h b/libethereum/Transaction.h index 1287be64e..bed291868 100644 --- a/libethereum/Transaction.h +++ b/libethereum/Transaction.h @@ -75,12 +75,13 @@ TransactionException toTransactionException(VMException const& _e); struct ExecutionResult { ExecutionResult() = default; - ExecutionResult(u256 _gasUsed, TransactionException _excepted, Address _newAddress, bytesConstRef _output, CodeDeposit _codeDeposit): gasUsed(_gasUsed), excepted(_excepted), newAddress(_newAddress), output(_output.toBytes()), codeDeposit(_codeDeposit) {} + ExecutionResult(u256 _gasUsed, TransactionException _excepted, Address _newAddress, bytesConstRef _output, CodeDeposit _codeDeposit, u256 _gasRefund): gasUsed(_gasUsed), excepted(_excepted), newAddress(_newAddress), output(_output.toBytes()), codeDeposit(_codeDeposit), gasRefunded(_gasRefund) {} u256 gasUsed = 0; TransactionException excepted = TransactionException::Unknown; Address newAddress; bytes output; CodeDeposit codeDeposit = CodeDeposit::None; + u256 gasRefunded = 0; }; std::ostream& operator<<(std::ostream& _out, ExecutionResult const& _er); diff --git a/libweb3jsonrpc/WebThreeStubServerBase.cpp b/libweb3jsonrpc/WebThreeStubServerBase.cpp index 9e4ffe174..806df6b30 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.cpp +++ b/libweb3jsonrpc/WebThreeStubServerBase.cpp @@ -47,6 +47,13 @@ using namespace jsonrpc; using namespace dev; using namespace dev::eth; +#if ETH_DEBUG +const unsigned dev::SensibleHttpThreads = 1; +#else +const unsigned dev::SensibleHttpThreads = 4; +#endif +const unsigned dev::SensibleHttpPort = 8080; + static Json::Value toJson(dev::eth::BlockInfo const& _bi) { Json::Value res; diff --git a/libweb3jsonrpc/WebThreeStubServerBase.h b/libweb3jsonrpc/WebThreeStubServerBase.h index 214573e0d..40265ac10 100644 --- a/libweb3jsonrpc/WebThreeStubServerBase.h +++ b/libweb3jsonrpc/WebThreeStubServerBase.h @@ -48,6 +48,9 @@ namespace shh class Interface; } +extern const unsigned SensibleHttpThreads; +extern const unsigned SensibleHttpPort; + class WebThreeStubDatabaseFace { public: From 7f915a1949067846be46a373a73eadea836371a3 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 25 Mar 2015 18:52:21 +0100 Subject: [PATCH 15/16] Minor compile fix. --- alethzero/Transact.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/alethzero/Transact.cpp b/alethzero/Transact.cpp index 29eafff03..534f18a69 100644 --- a/alethzero/Transact.cpp +++ b/alethzero/Transact.cpp @@ -329,7 +329,7 @@ void Transact::rejigData() er = ethereum()->call(s, value(), to, m_data, ethereum()->gasLimitRemaining(), gasPrice()); } gasNeeded = (qint64)(er.gasUsed + er.gasRefunded); - htmlInfo = QString("
INFO Gas required: %1 total = %2 base, %3 exec [%4 refunded later]
").arg(gasNeeded).arg(baseGas).arg(gasNeeded - baseGas).arg(er.gasRefunded) + htmlInfo; + htmlInfo = QString("
INFO Gas required: %1 total = %2 base, %3 exec [%4 refunded later]
").arg(gasNeeded).arg(baseGas).arg(gasNeeded - baseGas).arg((qint64)er.gasRefunded) + htmlInfo; if (er.excepted != TransactionException::None) { From fc5b6de4952d541518029af15a987133af392082 Mon Sep 17 00:00:00 2001 From: Gav Wood Date: Wed, 25 Mar 2015 19:03:57 +0100 Subject: [PATCH 16/16] Remove asOf redundancy. Minor mix typo fix. --- libethereum/Client.cpp | 21 +++++---------------- libethereum/Client.h | 4 ++-- libethereum/ClientBase.cpp | 23 ++++++++++++++++------- libethereum/ClientBase.h | 19 +++++++++++-------- mix/MixClient.cpp | 23 ++++++----------------- mix/MixClient.h | 6 +++--- 6 files changed, 43 insertions(+), 53 deletions(-) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index f1ef6df71..5af2bebd3 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -246,7 +246,7 @@ void Client::clearPending() void Client::noteChanged(h256Set const& _filters) { - Guard l(m_filterLock); + Guard l(x_filtersWatches); if (_filters.size()) cnote << "noteChanged(" << _filters << ")"; // accrue all changes left in each filter into the watches. @@ -266,7 +266,7 @@ void Client::noteChanged(h256Set const& _filters) void Client::appendFromNewPending(TransactionReceipt const& _receipt, h256Set& io_changed, h256 _transactionHash) { - Guard l(m_filterLock); + Guard l(x_filtersWatches); for (pair& i: m_filters) if (i.second.filter.envelops(RelativeBlock::Pending, m_bc.number() + 1)) { @@ -288,7 +288,7 @@ void Client::appendFromNewBlock(h256 const& _block, h256Set& io_changed) auto d = m_bc.info(_block); auto br = m_bc.receipts(_block); - Guard l(m_filterLock); + Guard l(x_filtersWatches); for (pair& i: m_filters) if (i.second.filter.envelops(RelativeBlock::Latest, d.number) && i.second.filter.matches(d.logBloom)) // acceptable number & looks like block may contain a matching log entry. @@ -535,7 +535,7 @@ void Client::doWork() // watches garbage collection vector toUninstall; { - Guard l(m_filterLock); + Guard l(x_filtersWatches); for (auto key: keysOf(m_watches)) if (m_watches[key].lastPoll != chrono::system_clock::time_point::max() && chrono::system_clock::now() - m_watches[key].lastPoll > chrono::seconds(20)) { @@ -553,18 +553,7 @@ void Client::doWork() } } -State Client::asOf(BlockNumber _h) const -{ - ReadGuard l(x_stateDB); - if (_h == PendingBlock) - return m_postMine; - else if (_h == LatestBlock) - return m_preMine; - - return State(m_stateDB, bc(), bc().numberHash(_h)); -} - -State Client::asOf(h256 _block) const +State Client::asOf(h256 const& _block) const { ReadGuard l(x_stateDB); return State(m_stateDB, bc(), _block); diff --git a/libethereum/Client.h b/libethereum/Client.h index c49181a13..dad0ca664 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -254,8 +254,8 @@ protected: /// Returns the state object for the full block (i.e. the terminal state) for index _h. /// Works properly with LatestBlock and PendingBlock. - virtual State asOf(BlockNumber _h) const override; - virtual State asOf(h256 _block) const override; + using ClientBase::asOf; + virtual State asOf(h256 const& _block) const override; virtual State preMine() const override { ReadGuard l(x_stateDB); return m_preMine; } virtual State postMine() const override { ReadGuard l(x_stateDB); return m_postMine; } virtual void prepareForTransaction() override; diff --git a/libethereum/ClientBase.cpp b/libethereum/ClientBase.cpp index 03e74de58..f9caf98ac 100644 --- a/libethereum/ClientBase.cpp +++ b/libethereum/ClientBase.cpp @@ -29,6 +29,15 @@ using namespace std; using namespace dev; using namespace dev::eth; +State ClientBase::asOf(BlockNumber _h) const +{ + if (_h == PendingBlock) + return postMine(); + else if (_h == LatestBlock) + return preMine(); + return asOf(bc().numberHash(_h)); +} + void ClientBase::submitTransaction(Secret _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice) { prepareForTransaction(); @@ -123,7 +132,7 @@ LocalisedLogEntries ClientBase::logs(unsigned _watchId) const LogFilter f; try { - Guard l(m_filterLock); + Guard l(x_filtersWatches); f = m_filters.at(m_watches.at(_watchId).id).filter; } catch (...) @@ -196,7 +205,7 @@ unsigned ClientBase::installWatch(LogFilter const& _f, Reaping _r) { h256 h = _f.sha3(); { - Guard l(m_filterLock); + Guard l(x_filtersWatches); if (!m_filters.count(h)) { cwatch << "FFF" << _f << h.abridged(); @@ -210,7 +219,7 @@ unsigned ClientBase::installWatch(h256 _h, Reaping _r) { unsigned ret; { - Guard l(m_filterLock); + Guard l(x_filtersWatches); ret = m_watches.size() ? m_watches.rbegin()->first + 1 : 0; m_watches[ret] = ClientWatch(_h, _r); cwatch << "+++" << ret << _h.abridged(); @@ -219,7 +228,7 @@ unsigned ClientBase::installWatch(h256 _h, Reaping _r) if (ch.empty()) ch.push_back(InitialChange); { - Guard l(m_filterLock); + Guard l(x_filtersWatches); swap(m_watches[ret].changes, ch); } return ret; @@ -229,7 +238,7 @@ bool ClientBase::uninstallWatch(unsigned _i) { cwatch << "XXX" << _i; - Guard l(m_filterLock); + Guard l(x_filtersWatches); auto it = m_watches.find(_i); if (it == m_watches.end()) @@ -249,7 +258,7 @@ bool ClientBase::uninstallWatch(unsigned _i) LocalisedLogEntries ClientBase::peekWatch(unsigned _watchId) const { - Guard l(m_filterLock); + Guard l(x_filtersWatches); cwatch << "peekWatch" << _watchId; auto& w = m_watches.at(_watchId); @@ -260,7 +269,7 @@ LocalisedLogEntries ClientBase::peekWatch(unsigned _watchId) const LocalisedLogEntries ClientBase::checkWatch(unsigned _watchId) { - Guard l(m_filterLock); + Guard l(x_filtersWatches); LocalisedLogEntries ret; cwatch << "checkWatch" << _watchId; diff --git a/libethereum/ClientBase.h b/libethereum/ClientBase.h index 662f170ba..9d9482277 100644 --- a/libethereum/ClientBase.h +++ b/libethereum/ClientBase.h @@ -126,7 +126,7 @@ public: virtual Addresses addresses(BlockNumber _block) const override; virtual u256 gasLimitRemaining() const override; - // Set the coinbase address + /// Set the coinbase address virtual void setAddress(Address _us) override; /// Get the coinbase address @@ -143,21 +143,24 @@ public: virtual std::pair getWork() override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::getWork")); } virtual bool submitWork(eth::ProofOfWork::Proof const&) override { BOOST_THROW_EXCEPTION(InterfaceNotSupported("dev::eth::ClientBase::submitWork")); } -protected: + State asOf(BlockNumber _h) const; +protected: + /// The interface that must be implemented in any class deriving this. + /// { virtual BlockChain const& bc() const = 0; - virtual State asOf(BlockNumber _h) const = 0; - virtual State asOf(h256 _h) const = 0; + virtual State asOf(h256 const& _h) const = 0; virtual State preMine() const = 0; virtual State postMine() const = 0; virtual void prepareForTransaction() = 0; + /// } - TransactionQueue m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. + TransactionQueue m_tq; ///< Maintains a list of incoming transactions not yet in a block on the blockchain. // filters - mutable Mutex m_filterLock; - std::map m_filters; - std::map m_watches; + mutable Mutex x_filtersWatches; ///< Our lock. + std::map m_filters; ///< The dictionary of filters that are active. + std::map m_watches; ///< Each and every watch - these reference a filter. }; diff --git a/mix/MixClient.cpp b/mix/MixClient.cpp index b6a9a45b1..0a2464b65 100644 --- a/mix/MixClient.cpp +++ b/mix/MixClient.cpp @@ -58,7 +58,7 @@ bytes MixBlockChain::createGenesisBlock(h256 _stateRoot) } MixClient::MixClient(std::string const& _dbPath): - m_dbPath(_dbPath), m_minigThreads(0) + m_dbPath(_dbPath), m_miningThreads(0) { std::map account; account.insert(std::make_pair(c_defaultUserAccountSecret, 1000000 * ether)); @@ -72,7 +72,7 @@ MixClient::~MixClient() void MixClient::resetState(std::map _accounts) { WriteGuard l(x_state); - Guard fl(m_filterLock); + Guard fl(x_filtersWatches); m_filters.clear(); m_watches.clear(); @@ -188,7 +188,7 @@ void MixClient::executeTransaction(Transaction const& _t, State& _state, bool _c BOOST_THROW_EXCEPTION(OutOfGas() << errinfo_comment("Not enough gas for contract deployment")); // collect watches h256Set changed; - Guard l(m_filterLock); + Guard l(x_filtersWatches); for (std::pair& i: m_filters) if ((unsigned)i.second.filter.latest() > bc().number()) { @@ -234,18 +234,7 @@ ExecutionResult MixClient::execution(unsigned _index) const return m_executions.at(_index); } -State MixClient::asOf(BlockNumber _block) const -{ - ReadGuard l(x_state); - if (_block == PendingBlock) - return m_state; - else if (_block == LatestBlock) - return m_startState; - - return State(m_stateDB, bc(), bc().numberHash(_block)); -} - -State MixClient::asOf(h256 _block) const +State MixClient::asOf(h256 const& _block) const { ReadGuard l(x_state); return State(m_stateDB, bc(), _block); @@ -325,12 +314,12 @@ void MixClient::setAddress(Address _us) void MixClient::setMiningThreads(unsigned _threads) { - m_minigThreads = _threads; + m_miningThreads = _threads; } unsigned MixClient::miningThreads() const { - return m_minigThreads; + return m_miningThreads; } void MixClient::startMining() diff --git a/mix/MixClient.h b/mix/MixClient.h index 1a81f10cc..179b445ac 100644 --- a/mix/MixClient.h +++ b/mix/MixClient.h @@ -78,8 +78,8 @@ protected: virtual dev::eth::BlockChain& bc() { return *m_bc; } /// InterfaceStub methods - virtual dev::eth::State asOf(eth::BlockNumber _block) const override; - virtual dev::eth::State asOf(h256 _block) const override; + virtual dev::eth::State asOf(h256 const& _block) const override; + using ClientBase::asOf; virtual dev::eth::BlockChain const& bc() const override { return *m_bc; } virtual dev::eth::State preMine() const override { ReadGuard l(x_state); return m_startState; } virtual dev::eth::State postMine() const override { ReadGuard l(x_state); return m_state; } @@ -98,7 +98,7 @@ private: mutable boost::shared_mutex x_executions; ExecutionResults m_executions; std::string m_dbPath; - unsigned m_minigThreads; + unsigned m_miningThreads; }; }