From cf6b358af532392cd38799a36c94ac535d62ff6d Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 22 Jan 2020 13:48:35 -0500 Subject: [PATCH] Allow aliases of variants in ABI (port of EOSIO/eos#7377) --- libraries/chain/abi_serializer.cpp | 2 +- unittests/abi_tests.cpp | 55 ++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/libraries/chain/abi_serializer.cpp b/libraries/chain/abi_serializer.cpp index 91950de1f12..f3d473f25b5 100644 --- a/libraries/chain/abi_serializer.cpp +++ b/libraries/chain/abi_serializer.cpp @@ -118,7 +118,7 @@ namespace eosio { namespace chain { structs[st.name] = st; for( const auto& td : abi.types ) { - EOS_ASSERT(_is_type(td.type, ctx), invalid_type_inside_abi, "invalid type ${type}", ("type",td.type)); + EOS_ASSERT(!_is_type(td.new_type_name, ctx), duplicate_abi_type_def_exception, "type already exists", ("new_type_name",impl::limit_size(td.new_type_name))); typedefs[td.new_type_name] = td.type; diff --git a/unittests/abi_tests.cpp b/unittests/abi_tests.cpp index dab7532b28c..a47cc3da581 100644 --- a/unittests/abi_tests.cpp +++ b/unittests/abi_tests.cpp @@ -1955,8 +1955,8 @@ BOOST_AUTO_TEST_CASE(abi_type_redefine) } )====="; - auto is_type_exception = [](fc::exception const & e) -> bool { return e.to_detail_string().find("invalid type") != std::string::npos; }; - BOOST_CHECK_EXCEPTION( abi_serializer abis(fc::json::from_string(repeat_abi).as(), max_serialization_time), invalid_type_inside_abi, is_type_exception ); + auto is_type_exception = [](fc::exception const & e) -> bool { return e.to_detail_string().find("Circular reference in type account_name") != std::string::npos; }; + BOOST_CHECK_EXCEPTION( abi_serializer abis(fc::json::from_string(repeat_abi).as(), max_serialization_time), abi_circular_def_exception, is_type_exception ); } FC_LOG_AND_RETHROW() } @@ -2304,6 +2304,57 @@ BOOST_AUTO_TEST_CASE(variants) } FC_LOG_AND_RETHROW() } +BOOST_AUTO_TEST_CASE(aliased_variants) +{ + using eosio::testing::fc_exception_message_starts_with; + + auto aliased_variant = R"({ + "version": "eosio::abi/1.1", + "types": [ + { "new_type_name": "foo", "type": "foo_variant" } + ], + "variants": [ + {"name": "foo_variant", "types": ["int8", "string"]} + ], + })"; + + try { + // round-trip abi through multiple formats + // json -> variant -> abi_def -> bin + auto bin = fc::raw::pack(fc::json::from_string(aliased_variant).as()); + // bin -> abi_def -> variant -> abi_def + abi_serializer abis(variant(fc::raw::unpack(bin)).as(), max_serialization_time ); + + verify_round_trip_conversion(abis, "foo", R"(["int8",21])", "0015"); + } FC_LOG_AND_RETHROW() +} + +BOOST_AUTO_TEST_CASE(variant_of_aliases) +{ + using eosio::testing::fc_exception_message_starts_with; + + auto aliased_variant = R"({ + "version": "eosio::abi/1.1", + "types": [ + { "new_type_name": "foo_0", "type": "int8" }, + { "new_type_name": "foo_1", "type": "string" } + ], + "variants": [ + {"name": "foo", "types": ["foo_0", "foo_1"]} + ], + })"; + + try { + // round-trip abi through multiple formats + // json -> variant -> abi_def -> bin + auto bin = fc::raw::pack(fc::json::from_string(aliased_variant).as()); + // bin -> abi_def -> variant -> abi_def + abi_serializer abis(variant(fc::raw::unpack(bin)).as(), max_serialization_time ); + + verify_round_trip_conversion(abis, "foo", R"(["foo_0",21])", "0015"); + } FC_LOG_AND_RETHROW() +} + BOOST_AUTO_TEST_CASE(extend) { using eosio::testing::fc_exception_message_starts_with;