From 8ede212ca250597a0e9fe0fe175b55f40a0e7683 Mon Sep 17 00:00:00 2001 From: Kayan Date: Tue, 4 Sep 2018 14:40:37 +0800 Subject: [PATCH 1/3] 5523 fix abi serialization exception in get block --- .../include/eosio/chain/abi_serializer.hpp | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/libraries/chain/include/eosio/chain/abi_serializer.hpp b/libraries/chain/include/eosio/chain/abi_serializer.hpp index 1e5bca6b5b3..d53455f2a79 100644 --- a/libraries/chain/include/eosio/chain/abi_serializer.hpp +++ b/libraries/chain/include/eosio/chain/abi_serializer.hpp @@ -286,21 +286,25 @@ namespace impl { mvo("name", act.name); mvo("authorization", act.authorization); - auto abi = resolver(act.account); - if (abi.valid()) { - auto type = abi->get_action_type(act.name); - if (!type.empty()) { - try { - mvo( "data", abi->_binary_to_variant( type, act.data, recursion_depth, deadline, max_serialization_time )); - mvo("hex_data", act.data); - } catch(...) { - // any failure to serialize data, then leave as not serailzed + try { + auto abi = resolver(act.account); + if (abi.valid()) { + auto type = abi->get_action_type(act.name); + if (!type.empty()) { + try { + mvo( "data", abi->_binary_to_variant( type, act.data, recursion_depth, deadline, max_serialization_time )); + mvo("hex_data", act.data); + } catch(...) { + // any failure to serialize data, then leave as not serailzed + mvo("data", act.data); + } + } else { mvo("data", act.data); } } else { mvo("data", act.data); } - } else { + } catch(...) { mvo("data", act.data); } out(name, std::move(mvo)); From 4c51fedafc20cadfc7c06326d053c17071a081fd Mon Sep 17 00:00:00 2001 From: Kayan Date: Wed, 5 Sep 2018 15:29:54 +0800 Subject: [PATCH 2/3] add unitest cases for chain_plugin get_block --- unittests/CMakeLists.txt | 3 +- unittests/chain_plugin_tests.cpp | 135 +++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 unittests/chain_plugin_tests.cpp diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 7442b00a69e..9eff48fa519 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -19,10 +19,11 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/config.hpp.in ${CMAKE_CURRENT file(GLOB UNIT_TESTS "*.cpp") add_executable( unit_test ${UNIT_TESTS} ${WASM_UNIT_TESTS} ) -target_link_libraries( unit_test eosio_chain chainbase eosio_testing eos_utilities abi_generator fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( unit_test eosio_chain chainbase chain_plugin eosio_testing eos_utilities abi_generator fc ${PLATFORM_SPECIFIC_LIBS} ) target_include_directories( unit_test PUBLIC ${CMAKE_SOURCE_DIR}/libraries/testing/include + ${CMAKE_SOURCE_DIR}/plugins/chain_plugin/include ${CMAKE_SOURCE_DIR}/contracts ${CMAKE_BINARY_DIR}/contracts ${CMAKE_CURRENT_SOURCE_DIR}/contracts diff --git a/unittests/chain_plugin_tests.cpp b/unittests/chain_plugin_tests.cpp new file mode 100644 index 00000000000..6abfc0a08a2 --- /dev/null +++ b/unittests/chain_plugin_tests.cpp @@ -0,0 +1,135 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include + +#include + +#include +#include + +#include "test_wasts.hpp" +#include "test_softfloat_wasts.hpp" + +#include +#include + +#ifdef NON_VALIDATING_TEST +#define TESTER tester +#else +#define TESTER validating_tester +#endif + +using namespace eosio; +using namespace eosio::chain; +using namespace eosio::testing; +using namespace fc; + +BOOST_AUTO_TEST_SUITE(chain_plugin_tests) + +BOOST_FIXTURE_TEST_CASE( get_block_with_invalid_abi, TESTER ) try { + produce_blocks(2); + + create_accounts( {N(asserter)} ); + produce_block(); + + // setup contract and abi + set_code(N(asserter), asserter_wast); + set_abi(N(asserter), asserter_abi); + produce_blocks(1); + + auto resolver = [&,this]( const account_name& name ) -> optional { + try { + const auto& accnt = this->control->db().get( name ); + abi_def abi; + if (abi_serializer::to_abi(accnt.abi, abi)) { + return abi_serializer(abi, abi_serializer_max_time); + } + return optional(); + } FC_RETHROW_EXCEPTIONS(error, "resolver failed at chain_plugin_tests::abi_invalid_type"); + }; + + // abi should be resolved + BOOST_REQUIRE_EQUAL(true, resolver(N(asserter)).valid()); + + // make an action using the valid contract & abi + variant pretty_trx = mutable_variant_object() + ("actions", variants({ + mutable_variant_object() + ("account", "asserter") + ("name", "procassert") + ("authorization", variants({ + mutable_variant_object() + ("actor", "asserter") + ("permission", name(config::active_name).to_string()) + })) + ("data", mutable_variant_object() + ("condition", 1) + ("message", "Should Not Assert!") + ) + }) + ); + signed_transaction trx; + abi_serializer::from_variant(pretty_trx, trx, resolver, abi_serializer_max_time); + set_transaction_headers(trx); + trx.sign( get_private_key( N(asserter), "active" ), control->get_chain_id() ); + push_transaction( trx ); + produce_blocks(1); + + // retrieve block num + uint32_t headnum = this->control->head_block_num(); + + char headnumstr[20]; + sprintf(headnumstr, "%d", headnum); + chain_apis::read_only::get_block_params param{headnumstr}; + chain_apis::read_only plugin(*(this->control), fc::microseconds(INT_MAX)); + + // block should be decoded successfully + std::string block_str = json::to_pretty_string(plugin.get_block(param)); + BOOST_TEST(block_str.find("procassert") != std::string::npos); + BOOST_TEST(block_str.find("condition") != std::string::npos); + BOOST_TEST(block_str.find("Should Not Assert!") != std::string::npos); + BOOST_TEST(block_str.find("011253686f756c64204e6f742041737365727421") != std::string::npos); //action data + + // set an invalid abi (int8->xxxx) + std::string abi2 = asserter_abi; + auto pos = abi2.find("int8"); + BOOST_TEST(pos != std::string::npos); + abi2.replace(pos, 4, "xxxx"); + set_abi(N(asserter), abi2.c_str()); + produce_blocks(1); + + // resolving the invalid abi result in exception + BOOST_CHECK_THROW(resolver(N(asserter)), invalid_type_inside_abi); + + // get the same block as string, results in decode failed(invalid abi) but not exception + std::string block_str2 = json::to_pretty_string(plugin.get_block(param)); + BOOST_TEST(block_str2.find("procassert") != std::string::npos); + BOOST_TEST(block_str2.find("condition") == std::string::npos); // decode failed + BOOST_TEST(block_str2.find("Should Not Assert!") == std::string::npos); // decode failed + BOOST_TEST(block_str2.find("011253686f756c64204e6f742041737365727421") != std::string::npos); //action data + +} FC_LOG_AND_RETHROW() /// get_block_with_invalid_abi + +BOOST_AUTO_TEST_SUITE_END() + From b727733035bec2f57b6fe7a7fcc9bd80a5e61798 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 5 Sep 2018 14:04:17 -0500 Subject: [PATCH 3/3] Move chain_plugin_tests from unittests to tests --- tests/CMakeLists.txt | 8 +++++--- {unittests => tests}/chain_plugin_tests.cpp | 3 --- unittests/CMakeLists.txt | 3 +-- 3 files changed, 6 insertions(+), 8 deletions(-) rename {unittests => tests}/chain_plugin_tests.cpp (98%) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 86c6e97cb36..50b12cf1cb0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -13,12 +13,14 @@ set( CMAKE_CXX_STANDARD 14 ) include_directories("${CMAKE_SOURCE_DIR}/plugins/wallet_plugin/include") -file(GLOB UNIT_TESTS "wallet_tests.cpp") +file(GLOB UNIT_TESTS "*.cpp") -add_executable( plugin_test ${UNIT_TESTS} ${WASM_UNIT_TESTS} main.cpp) +add_executable( plugin_test ${UNIT_TESTS} ${WASM_UNIT_TESTS} ) target_link_libraries( plugin_test eosio_testing eosio_chain chainbase eos_utilities chain_plugin wallet_plugin abi_generator fc ${PLATFORM_SPECIFIC_LIBS} ) -target_include_directories( plugin_test PUBLIC ${CMAKE_SOURCE_DIR}/plugins/net_plugin/include ) +target_include_directories( plugin_test PUBLIC + ${CMAKE_SOURCE_DIR}/plugins/net_plugin/include + ${CMAKE_SOURCE_DIR}/plugins/chain_plugin/include ) add_dependencies(plugin_test asserter test_api test_api_mem test_api_db test_api_multi_index exchange proxy identity identity_test stltest infinite eosio.system eosio.token eosio.bios test.inline multi_index_test noop dice eosio.msig) # diff --git a/unittests/chain_plugin_tests.cpp b/tests/chain_plugin_tests.cpp similarity index 98% rename from unittests/chain_plugin_tests.cpp rename to tests/chain_plugin_tests.cpp index 6abfc0a08a2..2b7867a07e9 100644 --- a/unittests/chain_plugin_tests.cpp +++ b/tests/chain_plugin_tests.cpp @@ -28,9 +28,6 @@ #include #include -#include "test_wasts.hpp" -#include "test_softfloat_wasts.hpp" - #include #include diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 9eff48fa519..7442b00a69e 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -19,11 +19,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/config.hpp.in ${CMAKE_CURRENT file(GLOB UNIT_TESTS "*.cpp") add_executable( unit_test ${UNIT_TESTS} ${WASM_UNIT_TESTS} ) -target_link_libraries( unit_test eosio_chain chainbase chain_plugin eosio_testing eos_utilities abi_generator fc ${PLATFORM_SPECIFIC_LIBS} ) +target_link_libraries( unit_test eosio_chain chainbase eosio_testing eos_utilities abi_generator fc ${PLATFORM_SPECIFIC_LIBS} ) target_include_directories( unit_test PUBLIC ${CMAKE_SOURCE_DIR}/libraries/testing/include - ${CMAKE_SOURCE_DIR}/plugins/chain_plugin/include ${CMAKE_SOURCE_DIR}/contracts ${CMAKE_BINARY_DIR}/contracts ${CMAKE_CURRENT_SOURCE_DIR}/contracts