Skip to content

Commit

Permalink
Merge pull request #2249 from AntelopeIO/GH-2228-return-value-main
Browse files Browse the repository at this point in the history
[5.0 -> main] TraceAPI: Correctly convert return value via ABI
  • Loading branch information
heifner authored Feb 20, 2024
2 parents 910fe05 + 998135e commit cc8a4d2
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 8 deletions.
5 changes: 4 additions & 1 deletion plugins/trace_api_plugin/abi_data_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<T, action_trace_v1>) {
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};
Expand Down
7 changes: 2 additions & 5 deletions plugins/trace_api_plugin/request_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<ActionTrace, action_trace_v0>){
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<ActionTrace, action_trace_v1>){
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()) {
Expand Down
57 changes: 55 additions & 2 deletions plugins/trace_api_plugin/test/test_data_handlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -98,27 +102,30 @@ 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_v0, action_trace_v1> 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", ""}
},
{}, {}, {}
);
abi.version = "eosio::abi/1.";
abi.action_results = { std::vector<chain::action_result_def>{ chain::action_result_def{ "foo"_n, "foor"} } };

abi_data_handler handler(exception_handler{});
handler.add_abi("alice"_n, std::move(abi));
Expand All @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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_v0, action_trace_v1> 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()

0 comments on commit cc8a4d2

Please sign in to comment.