From ff2c6f862fc9aee2dd5c115b0737b2afc37e0dcb Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Mon, 26 Feb 2018 17:49:21 +0800 Subject: [PATCH 1/5] Initial implementation to modify RPC Error Message Structure and eosioc display of it --- .../account_history_api_plugin.cpp | 4 +-- plugins/chain_api_plugin/chain_api_plugin.cpp | 10 +++--- .../faucet_testnet_plugin.cpp | 4 +-- plugins/http_plugin/http_plugin.cpp | 8 ++--- .../include/eosio/http_plugin/http_plugin.hpp | 35 ++++++++++++++++--- plugins/net_api_plugin/net_api_plugin.cpp | 4 +-- .../txn_test_gen_plugin.cpp | 4 +-- .../wallet_api_plugin/wallet_api_plugin.cpp | 4 +-- programs/eosioc/help_text.cpp | 26 ++++++++++---- programs/eosioc/help_text.hpp | 2 +- programs/eosioc/httpc.cpp | 20 ++++++++++- programs/eosioc/main.cpp | 4 ++- 12 files changed, 93 insertions(+), 32 deletions(-) diff --git a/plugins/account_history_api_plugin/account_history_api_plugin.cpp b/plugins/account_history_api_plugin/account_history_api_plugin.cpp index 242a20ea198..2202adda3f2 100644 --- a/plugins/account_history_api_plugin/account_history_api_plugin.cpp +++ b/plugins/account_history_api_plugin/account_history_api_plugin.cpp @@ -28,11 +28,11 @@ void account_history_api_plugin::plugin_initialize(const variables_map&) {} auto result = api_handle.call_name(fc::json::from_string(body).as()); \ cb(200, fc::json::to_string(result)); \ } catch (fc::eof_exception& e) { \ - error_results results{400, "Bad Request", e.to_string()}; \ + error_results results{400, "Bad Request", e}; \ cb(400, fc::json::to_string(results)); \ elog("Unable to parse arguments: ${args}", ("args", body)); \ } catch (fc::exception& e) { \ - error_results results{500, "Internal Service Error", e.to_detail_string()}; \ + error_results results{500, "Internal Service Error", e}; \ cb(500, fc::json::to_string(results)); \ elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \ } \ diff --git a/plugins/chain_api_plugin/chain_api_plugin.cpp b/plugins/chain_api_plugin/chain_api_plugin.cpp index 3f2deb2f2c1..a51cb21a19d 100644 --- a/plugins/chain_api_plugin/chain_api_plugin.cpp +++ b/plugins/chain_api_plugin/chain_api_plugin.cpp @@ -36,20 +36,20 @@ void chain_api_plugin::plugin_initialize(const variables_map&) {} auto result = api_handle.call_name(fc::json::from_string(body).as()); \ cb(http_response_code, fc::json::to_string(result)); \ } catch (chain::tx_missing_sigs& e) { \ - error_results results{401, "UnAuthorized", e.to_string()}; \ + error_results results{401, "UnAuthorized", e}; \ cb(401, fc::json::to_string(results)); \ } catch (chain::tx_duplicate& e) { \ - error_results results{409, "Conflict", e.to_string()}; \ + error_results results{409, "Conflict", e}; \ cb(409, fc::json::to_string(results)); \ } catch (chain::transaction_exception& e) { \ - error_results results{400, "Bad Request", e.to_string()}; \ + error_results results{400, "Bad Request", e}; \ cb(400, fc::json::to_string(results)); \ } catch (fc::eof_exception& e) { \ - error_results results{400, "Bad Request", e.to_string()}; \ + error_results results{400, "Bad Request", e}; \ cb(400, fc::json::to_string(results)); \ elog("Unable to parse arguments: ${args}", ("args", body)); \ } catch (fc::exception& e) { \ - error_results results{500, "Internal Service Error", e.to_detail_string()}; \ + error_results results{500, "Internal Service Error", e}; \ cb(500, fc::json::to_string(results)); \ elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \ } \ diff --git a/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp b/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp index f9bf9f2305e..6b7acb31eef 100644 --- a/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp +++ b/plugins/faucet_testnet_plugin/faucet_testnet_plugin.cpp @@ -63,11 +63,11 @@ using results_pair = std::pair; const auto result = api_handle->invoke_cb(body); \ response_cb(result.first, fc::json::to_string(result.second)); \ } catch (fc::eof_exception& e) { \ - error_results results{400, "Bad Request", e.to_string()}; \ + error_results results{400, "Bad Request", e}; \ response_cb(400, fc::json::to_string(results)); \ elog("Unable to parse arguments: ${args}", ("args", body)); \ } catch (fc::exception& e) { \ - error_results results{500, "Internal Service Error", e.to_detail_string()}; \ + error_results results{500, "Internal Service Error", e}; \ response_cb(500, fc::json::to_string(results)); \ elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \ } \ diff --git a/plugins/http_plugin/http_plugin.cpp b/plugins/http_plugin/http_plugin.cpp index 7f853401aa8..d0c8c27195d 100644 --- a/plugins/http_plugin/http_plugin.cpp +++ b/plugins/http_plugin/http_plugin.cpp @@ -186,25 +186,25 @@ namespace eosio { } else { wlog("404 - not found: ${ep}", ("ep",resource)); error_results results{websocketpp::http::status_code::not_found, - "Not Found", "Unknown Endpoint"}; + "Not Found", fc::exception(fc::log_message(fc::log_context(), "Unknown Endpoint"))}; con->set_body(fc::json::to_string(results)); con->set_status(websocketpp::http::status_code::not_found); } } catch( const fc::exception& e ) { elog( "http: ${e}", ("e",e.to_detail_string())); error_results results{websocketpp::http::status_code::internal_server_error, - "Internal Service Error", e.to_detail_string()}; + "Internal Service Error", e}; con->set_body(fc::json::to_string(results)); con->set_status(websocketpp::http::status_code::internal_server_error); } catch( const std::exception& e ) { elog( "http: ${e}", ("e",e.what())); error_results results{websocketpp::http::status_code::internal_server_error, - "Internal Service Error", e.what()}; + "Internal Service Error", fc::exception(fc::log_message(fc::log_context(), e.what()))}; con->set_body(fc::json::to_string(results)); con->set_status(websocketpp::http::status_code::internal_server_error); } catch( ... ) { error_results results{websocketpp::http::status_code::internal_server_error, - "Internal Service Error", "unknown exception"}; + "Internal Service Error", fc::exception(fc::log_message(fc::log_context(), "Unknown Exception"))}; con->set_body(fc::json::to_string(results)); con->set_status(websocketpp::http::status_code::internal_server_error); } diff --git a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp index 428f4f3e8e7..3ee8851154b 100644 --- a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp +++ b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp @@ -4,6 +4,7 @@ */ #pragma once #include +#include #include @@ -80,10 +81,36 @@ namespace eosio { * @brief Structure used to create JSON error responses */ struct error_results { - uint16_t code; - string message; - string details; + struct error_detail { + int64_t code; + string name; + string message; + string details; + vector stack_trace; + + static const uint8_t stack_trace_limit = 10; + + error_detail() {}; + + error_detail(const fc::exception& exc) { + code = exc.code(); + name = exc.name(); + message = exc.what(); + details = exc.top_message(); + for (auto itr = exc.get_log().begin(); itr != exc.get_log().end(); ++itr) { + // Prevent sending trace that are too big + if (stack_trace.size() >= stack_trace_limit) break; + // Append context + stack_trace.emplace_back(itr->get_context()); + } + } + }; + + uint16_t code; + string message; + error_detail error; }; } -FC_REFLECT(eosio::error_results, (code)(message)(details)) +FC_REFLECT(eosio::error_results::error_detail, (code)(name)(message)(details)(stack_trace)) +FC_REFLECT(eosio::error_results, (code)(message)(error)) diff --git a/plugins/net_api_plugin/net_api_plugin.cpp b/plugins/net_api_plugin/net_api_plugin.cpp index f8651e3a6e2..54d3d25c104 100644 --- a/plugins/net_api_plugin/net_api_plugin.cpp +++ b/plugins/net_api_plugin/net_api_plugin.cpp @@ -31,11 +31,11 @@ using namespace eosio; INVOKE \ cb(http_response_code, fc::json::to_string(result)); \ } catch (fc::eof_exception& e) { \ - error_results results{400, "Bad Request", e.to_string()}; \ + error_results results{400, "Bad Request", e}; \ cb(400, fc::json::to_string(results)); \ elog("Unable to parse arguments: ${args}", ("args", body)); \ } catch (fc::exception& e) { \ - error_results results{500, "Internal Service Error", e.to_detail_string()}; \ + error_results results{500, "Internal Service Error", e}; \ cb(500, fc::json::to_string(results)); \ elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \ } \ diff --git a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp index f4e442af7ac..1bc02dd246e 100644 --- a/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp +++ b/plugins/txn_test_gen_plugin/txn_test_gen_plugin.cpp @@ -46,11 +46,11 @@ using namespace eosio::chain; INVOKE \ cb(http_response_code, fc::json::to_string(result)); \ } catch (fc::eof_exception& e) { \ - error_results results{400, "Bad Request", e.to_string()}; \ + error_results results{400, "Bad Request", e}; \ cb(400, fc::json::to_string(results)); \ elog("Unable to parse arguments: ${args}", ("args", body)); \ } catch (fc::exception& e) { \ - error_results results{500, "Internal Service Error", e.to_detail_string()}; \ + error_results results{500, "Internal Service Error", e}; \ cb(500, fc::json::to_string(results)); \ elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \ } \ diff --git a/plugins/wallet_api_plugin/wallet_api_plugin.cpp b/plugins/wallet_api_plugin/wallet_api_plugin.cpp index c4ae48e8cdf..4bd46dec174 100644 --- a/plugins/wallet_api_plugin/wallet_api_plugin.cpp +++ b/plugins/wallet_api_plugin/wallet_api_plugin.cpp @@ -32,11 +32,11 @@ using namespace eosio; INVOKE \ cb(http_response_code, fc::json::to_string(result)); \ } catch (fc::eof_exception& e) { \ - error_results results{400, "Bad Request", e.to_string()}; \ + error_results results{400, "Bad Request", e}; \ cb(400, fc::json::to_string(results)); \ elog("Unable to parse arguments: ${args}", ("args", body)); \ } catch (fc::exception& e) { \ - error_results results{500, "Internal Service Error", e.to_detail_string()}; \ + error_results results{500, "Internal Service Error", e}; \ cb(500, fc::json::to_string(results)); \ elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \ } \ diff --git a/programs/eosioc/help_text.cpp b/programs/eosioc/help_text.cpp index 2f799d58d81..6c0b14b224a 100644 --- a/programs/eosioc/help_text.cpp +++ b/programs/eosioc/help_text.cpp @@ -182,22 +182,25 @@ e.g. }] })====="; +const char* error_advice_3030002 = R"=====(Ensure that you have the related private keys inside your wallet)====="; + const std::map error_advice = { { 3120001, error_advice_3120001 }, { 3120002, error_advice_3120002 }, { 3120003, error_advice_3120003 }, { 3120004, error_advice_3120004 }, { 3120005, error_advice_3120005 }, - { 3120006, error_advice_3120006 } + { 3120006, error_advice_3120006 }, + { 3030002, error_advice_3030002 } }; namespace eosio { namespace client { namespace help { -bool print_recognized_error_code(const fc::exception& e) { +bool print_recognized_error_code(const fc::exception& e, const bool show_error_trace) { // eos recognized error code is from 3000000 to 3999999 // refer to libraries/chain/include/eosio/chain/exceptions.hpp if (e.code() >= 3000000 && e.code() <= 3999999) { - std::string advice, explanation; + std::string advice, explanation, stack_trace; // Get advice, if any const auto advice_itr = error_advice.find(e.code()); @@ -210,20 +213,31 @@ bool print_recognized_error_code(const fc::exception& e) { // Localize the message as needed explanation += "\n " + localized_with_variant(log.get_format().data(), log.get_data()); } + // Check if there's stack trace to be added + if (!log.get_context().get_method().empty() && show_error_trace) { + stack_trace += "\n " + + log.get_context().get_file() + ":" + + fc::to_string(log.get_context().get_line_number()) + " " + + log.get_context().get_method(); + } } + // Append header if (!explanation.empty()) explanation = std::string("Error Details:") + explanation; + if (!stack_trace.empty()) stack_trace = std::string("Stack Trace:") + stack_trace; std::cerr << "\033[31m" << "Error " << e.code() << ": " << e.what() << "\033[0m"; if (!advice.empty()) std::cerr << "\n" << "\033[32m" << advice << "\033[0m"; - if (!explanation.empty()) std::cerr << "\n" << "\033[33m" << explanation << "\033[0m" << std::endl; + if (!explanation.empty()) std::cerr << "\n" << "\033[33m" << explanation << "\033[0m"; + if (!stack_trace.empty()) std::cerr << "\n" << stack_trace; + std::cerr << std::endl; return true; } return false; } -bool print_help_text(const fc::exception& e) { +bool print_help_text(const fc::exception& e, const bool show_error_trace) { // Check if the exception has recognized error code - if (print_recognized_error_code(e)) return true; + if (print_recognized_error_code(e, show_error_trace)) return true; bool result = false; // Large input strings to std::regex can cause SIGSEGV, this is a known bug in libstdc++. // See https://stackoverflow.com/questions/36304204/%D0%A1-regex-segfault-on-long-sequences diff --git a/programs/eosioc/help_text.hpp b/programs/eosioc/help_text.hpp index 9a05e176af4..ce75e692c70 100644 --- a/programs/eosioc/help_text.hpp +++ b/programs/eosioc/help_text.hpp @@ -6,5 +6,5 @@ #include namespace eosio { namespace client { namespace help { - bool print_help_text(const fc::exception& e); + bool print_help_text(const fc::exception& e, const bool show_error_trace); }}} \ No newline at end of file diff --git a/programs/eosioc/httpc.cpp b/programs/eosioc/httpc.cpp index dc433b7c373..5added3be7b 100644 --- a/programs/eosioc/httpc.cpp +++ b/programs/eosioc/httpc.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include using boost::asio::ip::tcp; @@ -106,8 +108,24 @@ fc::variant call( const std::string& server, uint16_t port, throw boost::system::system_error(error); // std::cout << re.str() <<"\n"; + const auto response_result = fc::json::from_string(re.str()); if( status_code == 200 || status_code == 201 || status_code == 202 ) { - return fc::json::from_string(re.str()); + return response_result; + } else { + auto &&error = response_result.as().error; + + // eos recognized error code is from 3000000 to 3999999 + // refer to libraries/chain/include/eosio/chain/exceptions.hpp + if (error.code >= 3000000 && error.code <= 3999999) { + // Construct fc exception from error + fc::exception new_exception(error.code, error.name, error.message); + new_exception.append_log(fc::log_message(fc::log_context(), error.details)); + + for (auto & trace : error.stack_trace) { + new_exception.append_log(fc::log_message(trace, std::string())); + } + throw new_exception; + } } FC_ASSERT( status_code == 200, "Error code ${c}\n: ${msg}\n", ("c", status_code)("msg", re.str()) ); diff --git a/programs/eosioc/main.cpp b/programs/eosioc/main.cpp index 16a14ea1442..72bb99aa02e 100644 --- a/programs/eosioc/main.cpp +++ b/programs/eosioc/main.cpp @@ -459,6 +459,8 @@ int main( int argc, char** argv ) { bool verbose_errors = false; app.add_flag( "-v,--verbose", verbose_errors, localized("output verbose actions on error")); + bool show_error_trace = false; + app.add_flag( "-t,--error-trace", show_error_trace, localized("output error stack trace")); auto version = app.add_subcommand("version", localized("Retrieve version information"), false); version->require_subcommand(); @@ -1006,7 +1008,7 @@ int main( int argc, char** argv ) { } } else { // attempt to extract the error code if one is present - if (verbose_errors || !print_help_text(e)) { + if (verbose_errors || !print_help_text(e, show_error_trace)) { elog("Failed with error: ${e}", ("e", verbose_errors ? e.to_detail_string() : e.to_string())); } } From bb2217c65f42b9dc43e7a825df1922f3e397397f Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 26 Feb 2018 16:46:40 -0500 Subject: [PATCH 2/5] Use eosio binaryen fork as a submodule --- .gitmodules | 3 +++ CMakeLists.txt | 2 ++ CMakeModules/wasm.cmake | 31 ++------------------- eosio_build.sh | 4 +-- externals/binaryen | 1 + scripts/eosio_build_amazon.sh | 21 --------------- scripts/eosio_build_darwin.sh | 20 -------------- scripts/eosio_build_fedora.sh | 21 --------------- scripts/eosio_build_ubuntu.sh | 21 --------------- tests/chain_tests/proof_tests.cpp | 45 +++++++++++++++++++++++++++++++ tools/eosiocpp.in | 4 +-- 11 files changed, 56 insertions(+), 117 deletions(-) create mode 160000 externals/binaryen diff --git a/.gitmodules b/.gitmodules index daa6a58c2dc..e25104d077a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -17,3 +17,6 @@ path = contracts/libc++/upstream url = https://github.com/EOSIO/libcxx.git branch = eosio +[submodule "externals/binaryen"] + path = externals/binaryen + url = https://github.com/EOSIO/binaryen diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bde96a85f2..2e8a7dc75e0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,8 @@ if(ENABLE_COVERAGE_TESTING) find_program( GENHTML_PATH NAMES genhtml) endif() +add_subdirectory( externals ) + include(wasm) if(WASM_TOOLCHAIN) message(STATUS "Using WASM clang => " ${WASM_CLANG}) diff --git a/CMakeModules/wasm.cmake b/CMakeModules/wasm.cmake index 464d1748066..337ad37b367 100644 --- a/CMakeModules/wasm.cmake +++ b/CMakeModules/wasm.cmake @@ -26,35 +26,8 @@ else() set(WASM_LLVM_LINK $ENV{WASM_LLVM_LINK}) endif() -if( NOT ("${WASM_CLANG}" STREQUAL "" OR "${WASM_LLC}" STREQUAL "" OR "${WASM_LLVM_LINK}" STREQUAL "") ) - if( NOT "${BINARYEN_ROOT}" STREQUAL "" ) - - if(EXISTS "${BINARYEN_ROOT}/bin/s2wasm") - - set(BINARYEN_BIN ${BINARYEN_ROOT}/bin) - - endif() - - else() - - message(STATUS "BINARYEN_BIN not defined looking in PATH") - find_path(BINARYEN_BIN - NAMES s2wasm - ENV PATH ) - if (BINARYEN_BIN AND NOT EXISTS ${BINARYEN_ROOT}/s2wasm) - - unset(BINARYEN_BIN) - - endif() - - endif() - - message(STATUS "BINARYEN_BIN => " ${BINARYEN_BIN}) - -endif() - # TODO: Check if compiler is able to generate wasm32 -if( NOT ("${WASM_CLANG}" STREQUAL "" OR "${WASM_LLC}" STREQUAL "" OR "${WASM_LLVM_LINK}" STREQUAL "" OR NOT BINARYEN_BIN) ) +if( NOT ("${WASM_CLANG}" STREQUAL "" OR "${WASM_LLC}" STREQUAL "" OR "${WASM_LLVM_LINK}" STREQUAL "") ) set(WASM_TOOLCHAIN TRUE) endif() @@ -199,7 +172,7 @@ macro(add_wast_executable) add_custom_command(OUTPUT ${DESTINATION_FOLDER}/${target}.wast DEPENDS ${target}.s - COMMAND ${BINARYEN_BIN}/s2wasm -o ${DESTINATION_FOLDER}/${target}.wast -s 4096 ${MAX_MEMORY_PARAM} ${target}.s + COMMAND $ -o ${DESTINATION_FOLDER}/${target}.wast -s 4096 ${MAX_MEMORY_PARAM} ${target}.s COMMENT "Generating WAST ${target}.wast" WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} VERBATIM diff --git a/eosio_build.sh b/eosio_build.sh index 8c62bbaea5c..e0406cd6fdc 100755 --- a/eosio_build.sh +++ b/eosio_build.sh @@ -81,7 +81,6 @@ esac export BOOST_ROOT=${HOME}/opt/boost_1_66_0 - export BINARYEN_BIN=${HOME}/opt/binaryen/bin export OPENSSL_ROOT_DIR=/usr/include/openssl export OPENSSL_LIBRARIES=/usr/include/openssl export WASM_LLVM_CONFIG=${HOME}/opt/wasm/bin/llvm-config @@ -93,7 +92,6 @@ if [ $ARCH == "Darwin" ]; then OPENSSL_ROOT_DIR=/usr/local/opt/openssl OPENSSL_LIBRARIES=/usr/local/opt/openssl/lib - BINARYEN_BIN=/usr/local/binaryen/bin/ WASM_LLVM_CONFIG=/usr/local/wasm/bin/llvm-config CXX_COMPILER=clang++ C_COMPILER=clang @@ -122,7 +120,7 @@ # Build EOS $CMAKE -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_CXX_COMPILER=${CXX_COMPILER} \ -DCMAKE_C_COMPILER=${C_COMPILER} -DWASM_LLVM_CONFIG=${WASM_LLVM_CONFIG} \ - -DBINARYEN_BIN=${BINARYEN_BIN} -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} \ + -DOPENSSL_ROOT_DIR=${OPENSSL_ROOT_DIR} \ -DOPENSSL_LIBRARIES=${OPENSSL_LIBRARIES} .. if [ $? -ne 0 ]; then printf "\n\t>>>>>>>>>>>>>>>>>>>> CMAKE building EOSIO has exited with the above error.\n\n" diff --git a/externals/binaryen b/externals/binaryen new file mode 160000 index 00000000000..0b980a9e877 --- /dev/null +++ b/externals/binaryen @@ -0,0 +1 @@ +Subproject commit 0b980a9e87740db4d657ee38b2668da35752264e diff --git a/scripts/eosio_build_amazon.sh b/scripts/eosio_build_amazon.sh index b2e51cfba02..efa49cf05e2 100644 --- a/scripts/eosio_build_amazon.sh +++ b/scripts/eosio_build_amazon.sh @@ -172,27 +172,6 @@ printf "\tsecp256k1 found\n" fi - printf "\n\tChecking for binaryen\n" - if [ ! -d ${HOME}/opt/binaryen ]; then - # Install binaryen v1.37.14: - printf "\tInstalling binaryen v1.37.14:\n" - cd ${TEMP_DIR} - git clone https://github.com/WebAssembly/binaryen - cd binaryen - git checkout tags/1.37.14 - $CMAKE . && make -j${CPU_CORE} - if [ $? -ne 0 ]; then - printf "\tError compiling binaryen.\n" - printf "\tExiting now.\n\n" - exit; - fi - mkdir -p ${HOME}/opt/binaryen/ 2>/dev/null - mv ${TEMP_DIR}/binaryen/bin ${HOME}/opt/binaryen/ - rm -rf ${TEMP_DIR}/binaryen - else - printf "\tBinaryen found at ${HOME}/opt/binaryen\n" - fi - printf "\n\tChecking for LLVM with WASM support.\n" if [ ! -d ${HOME}/opt/wasm/bin ]; then # Build LLVM and clang with EXPERIMENTAL WASM support: diff --git a/scripts/eosio_build_darwin.sh b/scripts/eosio_build_darwin.sh index 5242462687b..ab253023ed2 100644 --- a/scripts/eosio_build_darwin.sh +++ b/scripts/eosio_build_darwin.sh @@ -181,26 +181,6 @@ printf "\tsecp256k1 found at /usr/local/lib/\n" fi - printf "\n\tChecking for binaryen\n" - if [ ! -e /usr/local/binaryen/bin/binaryen.js ]; then - cd ${TEMP_DIR} - git clone https://github.com/WebAssembly/binaryen - cd binaryen - git checkout tags/1.37.14 - cmake . && make -j${CPU_CORE} - if [ $? -ne 0 ]; then - printf "\tError compiling binaryen.\n" - printf "\tExiting now.\n\n" - exit; - fi - sudo mkdir /usr/local/binaryen - sudo mv ${TEMP_DIR}/binaryen/bin /usr/local/binaryen - sudo ln -s /usr/local/binaryen/bin/* /usr/local - sudo rm -rf ${TEMP_DIR}/binaryen - else - printf "\tBinaryen found at /usr/local/binaryen/bin/\n" - fi - printf "\n\tChecking for WASM\n" if [ ! -d /usr/local/wasm/bin ]; then # Build LLVM and clang for WASM: diff --git a/scripts/eosio_build_fedora.sh b/scripts/eosio_build_fedora.sh index 94a83e93854..159fb37d34d 100644 --- a/scripts/eosio_build_fedora.sh +++ b/scripts/eosio_build_fedora.sh @@ -145,27 +145,6 @@ printf "\tsecp256k1 found\n" fi - printf "\n\tChecking for binaryen\n" - if [ ! -d ${HOME}/opt/binaryen ]; then - # Install binaryen v1.37.14: - printf "\tInstalling binaryen v1.37.14:\n" - cd ${TEMP_DIR} - git clone https://github.com/WebAssembly/binaryen - cd binaryen - git checkout tags/1.37.14 - cmake . && make -j${CPU_CORE} - if [ $? -ne 0 ]; then - printf "\tError compiling binaryen.\n" - printf "\tExiting now.\n\n" - exit; - fi - mkdir -p ${HOME}/opt/binaryen/ 2>/dev/null - mv ${TEMP_DIR}/binaryen/bin ${HOME}/opt/binaryen/ - rm -rf ${TEMP_DIR}/binaryen - else - printf "\tBinaryen found at ${HOME}/opt/binaryen\n" - fi - printf "\n\tChecking for LLVM with WASM support.\n" if [ ! -d ${HOME}/opt/wasm/bin ]; then # Build LLVM and clang with EXPERIMENTAL WASM support: diff --git a/scripts/eosio_build_ubuntu.sh b/scripts/eosio_build_ubuntu.sh index 6c3926ea26a..c394167d561 100644 --- a/scripts/eosio_build_ubuntu.sh +++ b/scripts/eosio_build_ubuntu.sh @@ -127,27 +127,6 @@ printf "\tsecp256k1 found\n" fi - printf "\n\tChecking for binaryen\n" - if [ ! -d ${HOME}/opt/binaryen ]; then - # Install binaryen v1.37.14: - printf "\tInstalling binaryen v1.37.14:\n" - cd ${TEMP_DIR} - git clone https://github.com/WebAssembly/binaryen - cd binaryen - git checkout tags/1.37.14 - cmake . && make -j${CPU_CORE} - if [ $? -ne 0 ]; then - printf "\tError compiling binaryen.\n" - printf "\tExiting now.\n\n" - exit; - fi - mkdir -p ${HOME}/opt/binaryen/ 2>/dev/null - mv ${TEMP_DIR}/binaryen/bin ${HOME}/opt/binaryen/ - rm -rf ${TEMP_DIR}/binaryen - else - printf "\tBinaryen found at ${HOME}/opt/binaryen\n" - fi - printf "\n\tChecking for LLVM with WASM support.\n" if [ ! -d ${HOME}/opt/wasm/bin ]; then # Build LLVM and clang for WASM: diff --git a/tests/chain_tests/proof_tests.cpp b/tests/chain_tests/proof_tests.cpp index 4f1edaa71be..858320dd949 100644 --- a/tests/chain_tests/proof_tests.cpp +++ b/tests/chain_tests/proof_tests.cpp @@ -118,6 +118,51 @@ bool proof_is_valid(const digest_type& digest, const vector& path, BOOST_AUTO_TEST_SUITE(proof_tests) +static const char poo[] = R"=====( +(module + (table 0 anyfunc) + (memory $0 16) + (export "memory" (memory $0)) + (export "apply" (func $apply)) + + (func $complex_stuff_and_return_a_bool (result i32) + (i32.const 0) + ) + + (func $apply (param $0 i64) (param $1 i64) + (br_if 0 (call $complex_stuff_and_return_a_bool)) + + (drop (i64.mul (i64.const 56) (i64.const 34))) + (drop (i64.mul (i64.const 12) (i64.const 55))) + (drop (i64.mul (i64.const 536) (i64.const 2333))) + (drop (i64.mul (i64.const 23) (i64.const 12))) + (drop (i64.mul (i64.const 543) (i64.const 76533))) + ) +) +)====="; + +BOOST_FIXTURE_TEST_CASE( big_memory, tester ) try { + produce_blocks(2); + + create_accounts( {N(bigmem)} ); + produce_block(); + + set_code(N(bigmem), poo); + produce_blocks(1); + + signed_transaction trx; + action act; + act.account = N(bigmem); + act.name = N(); + act.authorization = vector{{N(bigmem),config::active_name}}; + trx.actions.push_back(act); + + set_tapos(trx); + trx.sign(get_private_key( N(bigmem), "active" ), chain_id_type()); + push_transaction(trx); + +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( prove_block_in_chain, tester ) { try { vector known_blocks; known_blocks.reserve(100); diff --git a/tools/eosiocpp.in b/tools/eosiocpp.in index 4664ecfc0fd..8a55ed0c034 100755 --- a/tools/eosiocpp.in +++ b/tools/eosiocpp.in @@ -40,8 +40,8 @@ function build_contract { @WASM_LLVM_LINK@ -o $workdir/linked.bc $workdir/built/* # echo @WASM_LLC@ --asm-verbose=false -o $workdir/assembly.s $workdir/linked.bc @WASM_LLC@ --asm-verbose=false -o $workdir/assembly.s $workdir/linked.bc -# echo @BINARYEN_BIN@/s2wasm -o $outname -s 16384 $workdir/assembly.s - @BINARYEN_BIN@/s2wasm -o $outname -s 16384 $workdir/assembly.s +# echo ${EOSIO_INSTALL_DIR}/bin/eosio-s2wasm -o $outname -s 16384 $workdir/assembly.s + ${EOSIO_INSTALL_DIR}/bin/eosio-s2wasm -o $outname -s 16384 $workdir/assembly.s # echo rm -rf $workdir rm -rf $workdir From ee3b5c7a58416a8edc55fcab50cbfa8cb45150fe Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 26 Feb 2018 16:49:26 -0500 Subject: [PATCH 3/5] Remove change the snuck in on last commit This is why I avoid add -a --- tests/chain_tests/proof_tests.cpp | 45 ------------------------------- 1 file changed, 45 deletions(-) diff --git a/tests/chain_tests/proof_tests.cpp b/tests/chain_tests/proof_tests.cpp index 858320dd949..4f1edaa71be 100644 --- a/tests/chain_tests/proof_tests.cpp +++ b/tests/chain_tests/proof_tests.cpp @@ -118,51 +118,6 @@ bool proof_is_valid(const digest_type& digest, const vector& path, BOOST_AUTO_TEST_SUITE(proof_tests) -static const char poo[] = R"=====( -(module - (table 0 anyfunc) - (memory $0 16) - (export "memory" (memory $0)) - (export "apply" (func $apply)) - - (func $complex_stuff_and_return_a_bool (result i32) - (i32.const 0) - ) - - (func $apply (param $0 i64) (param $1 i64) - (br_if 0 (call $complex_stuff_and_return_a_bool)) - - (drop (i64.mul (i64.const 56) (i64.const 34))) - (drop (i64.mul (i64.const 12) (i64.const 55))) - (drop (i64.mul (i64.const 536) (i64.const 2333))) - (drop (i64.mul (i64.const 23) (i64.const 12))) - (drop (i64.mul (i64.const 543) (i64.const 76533))) - ) -) -)====="; - -BOOST_FIXTURE_TEST_CASE( big_memory, tester ) try { - produce_blocks(2); - - create_accounts( {N(bigmem)} ); - produce_block(); - - set_code(N(bigmem), poo); - produce_blocks(1); - - signed_transaction trx; - action act; - act.account = N(bigmem); - act.name = N(); - act.authorization = vector{{N(bigmem),config::active_name}}; - trx.actions.push_back(act); - - set_tapos(trx); - trx.sign(get_private_key( N(bigmem), "active" ), chain_id_type()); - push_transaction(trx); - -} FC_LOG_AND_RETHROW() - BOOST_FIXTURE_TEST_CASE( prove_block_in_chain, tester ) { try { vector known_blocks; known_blocks.reserve(100); From 0760acdf47624e6c16fca8a74e2cec6e48221057 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Mon, 26 Feb 2018 16:53:29 -0500 Subject: [PATCH 4/5] Add missing cmakelists for externals directory --- externals/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 externals/CMakeLists.txt diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt new file mode 100644 index 00000000000..4fac3528746 --- /dev/null +++ b/externals/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory( binaryen ) From 47c0458f724474395dae854be9c8bc161db78440 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Tue, 27 Feb 2018 18:29:54 +0800 Subject: [PATCH 5/5] Improve error details to display request error details --- libraries/chain/name.cpp | 11 ++++++----- plugins/http_plugin/http_plugin.cpp | 6 +++--- programs/eosioc/help_text.cpp | 12 ++++++++---- programs/eosioc/help_text.hpp | 2 +- programs/eosioc/httpc.cpp | 15 ++++++++++----- programs/eosioc/main.cpp | 4 +--- 6 files changed, 29 insertions(+), 21 deletions(-) diff --git a/libraries/chain/name.cpp b/libraries/chain/name.cpp index 262e2dc221a..6cb09b34906 100644 --- a/libraries/chain/name.cpp +++ b/libraries/chain/name.cpp @@ -7,12 +7,13 @@ namespace eosio { namespace chain { void name::set( const char* str ) { - try { - const auto len = strnlen(str,14); - EOS_ASSERT( len <= 13, name_type_exception, "Name is longer than 13 characters (${name}) ", ("name",string(str)) ); + const auto len = strnlen(str, 14); + EOS_ASSERT(len <= 13, name_type_exception, "Name is longer than 13 characters (${name}) ", ("name", string(str))); value = string_to_name(str); - EOS_ASSERT( to_string() == string(str), name_type_exception, "Name not properly normalized (name: ${name}, normalized: ${normalized}) ", ("name",string(str))("normalized",to_string()) ); - }FC_CAPTURE_AND_RETHROW( (str) ) } + EOS_ASSERT(to_string() == string(str), name_type_exception, + "Name not properly normalized (name: ${name}, normalized: ${normalized}) ", + ("name", string(str))("normalized", to_string())); + } name::operator string()const { static const char* charmap = ".12345abcdefghijklmnopqrstuvwxyz"; diff --git a/plugins/http_plugin/http_plugin.cpp b/plugins/http_plugin/http_plugin.cpp index d0c8c27195d..1c62389ccf2 100644 --- a/plugins/http_plugin/http_plugin.cpp +++ b/plugins/http_plugin/http_plugin.cpp @@ -186,7 +186,7 @@ namespace eosio { } else { wlog("404 - not found: ${ep}", ("ep",resource)); error_results results{websocketpp::http::status_code::not_found, - "Not Found", fc::exception(fc::log_message(fc::log_context(), "Unknown Endpoint"))}; + "Not Found", fc::exception(FC_LOG_MESSAGE(error, "Unknown Endpoint"))}; con->set_body(fc::json::to_string(results)); con->set_status(websocketpp::http::status_code::not_found); } @@ -199,12 +199,12 @@ namespace eosio { } catch( const std::exception& e ) { elog( "http: ${e}", ("e",e.what())); error_results results{websocketpp::http::status_code::internal_server_error, - "Internal Service Error", fc::exception(fc::log_message(fc::log_context(), e.what()))}; + "Internal Service Error", fc::exception(FC_LOG_MESSAGE(error, e.what()))}; con->set_body(fc::json::to_string(results)); con->set_status(websocketpp::http::status_code::internal_server_error); } catch( ... ) { error_results results{websocketpp::http::status_code::internal_server_error, - "Internal Service Error", fc::exception(fc::log_message(fc::log_context(), "Unknown Exception"))}; + "Internal Service Error", fc::exception(FC_LOG_MESSAGE(error, "Unknown Exception"))}; con->set_body(fc::json::to_string(results)); con->set_status(websocketpp::http::status_code::internal_server_error); } diff --git a/programs/eosioc/help_text.cpp b/programs/eosioc/help_text.cpp index 6c0b14b224a..5b8f6f06107 100644 --- a/programs/eosioc/help_text.cpp +++ b/programs/eosioc/help_text.cpp @@ -5,6 +5,7 @@ #include "help_text.hpp" #include "localize.hpp" #include +#include using namespace eosio::client::localize; @@ -196,7 +197,7 @@ const std::map error_advice = { namespace eosio { namespace client { namespace help { -bool print_recognized_error_code(const fc::exception& e, const bool show_error_trace) { +bool print_recognized_error_code(const fc::exception& e, const bool verbose_errors) { // eos recognized error code is from 3000000 to 3999999 // refer to libraries/chain/include/eosio/chain/exceptions.hpp if (e.code() >= 3000000 && e.code() <= 3999999) { @@ -212,9 +213,12 @@ bool print_recognized_error_code(const fc::exception& e, const bool show_error_t if (!log.get_format().empty()) { // Localize the message as needed explanation += "\n " + localized_with_variant(log.get_format().data(), log.get_data()); + } else if (log.get_data().size() > 0 && verbose_errors) { + // Show data-only log only if verbose_errors option is enabled + explanation += "\n " + fc::json::to_string(log.get_data()); } // Check if there's stack trace to be added - if (!log.get_context().get_method().empty() && show_error_trace) { + if (!log.get_context().get_method().empty() && verbose_errors) { stack_trace += "\n " + log.get_context().get_file() + ":" + fc::to_string(log.get_context().get_line_number()) + " " + @@ -235,9 +239,9 @@ bool print_recognized_error_code(const fc::exception& e, const bool show_error_t return false; } -bool print_help_text(const fc::exception& e, const bool show_error_trace) { +bool print_help_text(const fc::exception& e, const bool verbose_errors) { // Check if the exception has recognized error code - if (print_recognized_error_code(e, show_error_trace)) return true; + if (print_recognized_error_code(e, verbose_errors)) return true; bool result = false; // Large input strings to std::regex can cause SIGSEGV, this is a known bug in libstdc++. // See https://stackoverflow.com/questions/36304204/%D0%A1-regex-segfault-on-long-sequences diff --git a/programs/eosioc/help_text.hpp b/programs/eosioc/help_text.hpp index ce75e692c70..a62652bdcc2 100644 --- a/programs/eosioc/help_text.hpp +++ b/programs/eosioc/help_text.hpp @@ -6,5 +6,5 @@ #include namespace eosio { namespace client { namespace help { - bool print_help_text(const fc::exception& e, const bool show_error_trace); + bool print_help_text(const fc::exception& e, const bool verbose_errors); }}} \ No newline at end of file diff --git a/programs/eosioc/httpc.cpp b/programs/eosioc/httpc.cpp index 5added3be7b..cbdc6d2c25a 100644 --- a/programs/eosioc/httpc.cpp +++ b/programs/eosioc/httpc.cpp @@ -118,11 +118,15 @@ fc::variant call( const std::string& server, uint16_t port, // refer to libraries/chain/include/eosio/chain/exceptions.hpp if (error.code >= 3000000 && error.code <= 3999999) { // Construct fc exception from error + const auto &stack_trace = error.stack_trace; fc::exception new_exception(error.code, error.name, error.message); - new_exception.append_log(fc::log_message(fc::log_context(), error.details)); - - for (auto & trace : error.stack_trace) { - new_exception.append_log(fc::log_message(trace, std::string())); + if (stack_trace.empty()) { + new_exception.append_log(FC_LOG_MESSAGE(error, error.details)); + } else { + for (auto itr = stack_trace.begin(); itr != stack_trace.end(); itr++) { + const auto &error_message = itr == stack_trace.begin() ? error.details : std::string(); + new_exception.append_log(fc::log_message(*itr, error_message)); + } } throw new_exception; } @@ -132,5 +136,6 @@ fc::variant call( const std::string& server, uint16_t port, } FC_ASSERT( !"unable to connect" ); - } FC_CAPTURE_AND_RETHROW( (server)(port)(path)(postdata) ) + } FC_RETHROW_EXCEPTIONS( error, "Request Path: ${server}:${port}${path}\n Request Post Data: ${postdata}}" , + ("server", server)("port", port)("path", path)("postdata", postdata) ) } diff --git a/programs/eosioc/main.cpp b/programs/eosioc/main.cpp index 72bb99aa02e..f5973a7253e 100644 --- a/programs/eosioc/main.cpp +++ b/programs/eosioc/main.cpp @@ -459,8 +459,6 @@ int main( int argc, char** argv ) { bool verbose_errors = false; app.add_flag( "-v,--verbose", verbose_errors, localized("output verbose actions on error")); - bool show_error_trace = false; - app.add_flag( "-t,--error-trace", show_error_trace, localized("output error stack trace")); auto version = app.add_subcommand("version", localized("Retrieve version information"), false); version->require_subcommand(); @@ -1008,7 +1006,7 @@ int main( int argc, char** argv ) { } } else { // attempt to extract the error code if one is present - if (verbose_errors || !print_help_text(e, show_error_trace)) { + if (!print_help_text(e, verbose_errors) && verbose_errors) { elog("Failed with error: ${e}", ("e", verbose_errors ? e.to_detail_string() : e.to_string())); } }