diff --git a/plugins/trace_api_plugin/abi_data_handler.cpp b/plugins/trace_api_plugin/abi_data_handler.cpp index 574eb9919b..07b7f4edd5 100644 --- a/plugins/trace_api_plugin/abi_data_handler.cpp +++ b/plugins/trace_api_plugin/abi_data_handler.cpp @@ -31,7 +31,10 @@ namespace eosio::trace_api { auto params = serializer_p->binary_to_variant(type_name, action.data, abi_yield); if constexpr (std::is_same_v) { if(action.return_value.size() > 0) { - ret_data = serializer_p->binary_to_variant(type_name, action.return_value, abi_yield); + auto return_type_name = serializer_p->get_action_result_type(action_name); + if (!return_type_name.empty()) { + ret_data = serializer_p->binary_to_variant(return_type_name, action.return_value, abi_yield); + } } } return {params, ret_data}; diff --git a/plugins/trace_api_plugin/request_handler.cpp b/plugins/trace_api_plugin/request_handler.cpp index 582c134413..a20225e2ab 100644 --- a/plugins/trace_api_plugin/request_handler.cpp +++ b/plugins/trace_api_plugin/request_handler.cpp @@ -37,25 +37,22 @@ namespace { }); for ( int index : indices) { const auto& a = actions.at(index); - auto common_mvo = fc::mutable_variant_object(); + auto action_variant = fc::mutable_variant_object(); - common_mvo("global_sequence", a.global_sequence) + action_variant("global_sequence", a.global_sequence) ("receiver", a.receiver.to_string()) ("account", a.account.to_string()) ("action", a.action.to_string()) ("authorization", process_authorizations(a.authorization)) ("data", fc::to_hex(a.data.data(), a.data.size())); - auto action_variant = fc::mutable_variant_object(); if constexpr(std::is_same_v){ - action_variant(std::move(common_mvo)); auto [params, return_data] = data_handler(a); if (!params.is_null()) { action_variant("params", params); } } else if constexpr(std::is_same_v){ - action_variant(std::move(common_mvo)); action_variant("return_value", fc::to_hex(a.return_value.data(),a.return_value.size())) ; auto [params, return_data] = data_handler(a); if (!params.is_null()) { diff --git a/plugins/trace_api_plugin/test/test_data_handlers.cpp b/plugins/trace_api_plugin/test/test_data_handlers.cpp index 464b3a81c1..129c87926c 100644 --- a/plugins/trace_api_plugin/test/test_data_handlers.cpp +++ b/plugins/trace_api_plugin/test/test_data_handlers.cpp @@ -21,6 +21,7 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto actual = handler.serialize_to_variant(action_trace_t); BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); + BOOST_REQUIRE(!std::get<1>(actual)); } BOOST_AUTO_TEST_CASE(empty_data_v1) @@ -36,6 +37,7 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto actual = handler.serialize_to_variant(action_trace_t); BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); + BOOST_REQUIRE(!std::get<1>(actual)); } BOOST_AUTO_TEST_CASE(no_abi) @@ -50,6 +52,7 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto actual = handler.serialize_to_variant(action_trace_t); BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); + BOOST_REQUIRE(!std::get<1>(actual)); } BOOST_AUTO_TEST_CASE(no_abi_v1) @@ -65,6 +68,7 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto actual = handler.serialize_to_variant(action_trace_t); BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); + BOOST_REQUIRE(!std::get<1>(actual)); } BOOST_AUTO_TEST_CASE(basic_abi) @@ -98,20 +102,22 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto actual = handler.serialize_to_variant(action_trace_t); BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); + BOOST_REQUIRE(!std::get<1>(actual)); } BOOST_AUTO_TEST_CASE(basic_abi_v1) { auto action = action_trace_v1 { { 0, "alice"_n, "alice"_n, "foo"_n, {}, {0x00, 0x01, 0x02, 0x03}}, - {0x04, 0x05, 0x06, 0x07} + {0x04, 0x05, 0x06} }; std::variant action_trace_t = action; auto abi = chain::abi_def ( {}, { - { "foo", "", { {"a", "varuint32"}, {"b", "varuint32"}, {"c", "varuint32"}, {"d", "varuint32"} } } + { "foo", "", { {"a", "varuint32"}, {"b", "varuint32"}, {"c", "varuint32"}, {"d", "varuint32"} } }, + { "foor", "", { {"e", "varuint32"}, {"f", "varuint32"}, {"g", "varuint32"} } } }, { { "foo"_n, "foo", ""} @@ -119,6 +125,7 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) {}, {}, {} ); abi.version = "eosio::abi/1."; + abi.action_results = { std::vector{ chain::action_result_def{ "foo"_n, "foor"} } }; abi_data_handler handler(exception_handler{}); handler.add_abi("alice"_n, std::move(abi)); @@ -128,10 +135,16 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) ("b", 1) ("c", 2) ("d", 3); + fc::variant expected_return = fc::mutable_variant_object() + ("e", 4) + ("f", 5) + ("g", 6); auto actual = handler.serialize_to_variant(action_trace_t); BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); + BOOST_REQUIRE(std::get<1>(actual)); + BOOST_TEST(to_kv(expected_return) == to_kv(*std::get<1>(actual)), boost::test_tools::per_element()); } BOOST_AUTO_TEST_CASE(basic_abi_wrong_type) @@ -161,6 +174,7 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto actual = handler.serialize_to_variant(action_trace_t); BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); + BOOST_REQUIRE(!std::get<1>(actual)); } BOOST_AUTO_TEST_CASE(basic_abi_wrong_type_v1) @@ -190,6 +204,7 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto actual = handler.serialize_to_variant(action_trace_t); BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); + BOOST_REQUIRE(!std::get<1>(actual)); } BOOST_AUTO_TEST_CASE(basic_abi_insufficient_data) @@ -221,6 +236,44 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); BOOST_TEST(log_called); + BOOST_REQUIRE(!std::get<1>(actual)); } + // If no ABI provided for return type then do not attempt to decode it + BOOST_AUTO_TEST_CASE(basic_abi_no_return_abi_when_return_value_provided) + { + auto action = action_trace_v1 { + { 0, "alice"_n, "alice"_n, "foo"_n, {}, {0x00, 0x01, 0x02, 0x03}}, + {0x04, 0x05, 0x06} + }; + + std::variant action_trace_t = action; + + auto abi = chain::abi_def ( {}, + { + { "foo", "", { {"a", "varuint32"}, {"b", "varuint32"}, {"c", "varuint32"}, {"d", "varuint32"} } }, + }, + { + { "foo"_n, "foo", ""} + }, + {}, {}, {} + ); + abi.version = "eosio::abi/1."; + + abi_data_handler handler(exception_handler{}); + handler.add_abi("alice"_n, std::move(abi)); + + fc::variant expected = fc::mutable_variant_object() + ("a", 0) + ("b", 1) + ("c", 2) + ("d", 3); + + auto actual = handler.serialize_to_variant(action_trace_t, [](){}); + + BOOST_TEST(to_kv(expected) == to_kv(std::get<0>(actual)), boost::test_tools::per_element()); + BOOST_REQUIRE(!std::get<1>(actual)); + } + + BOOST_AUTO_TEST_SUITE_END()