Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Add action result to abi serializer #9310

Merged
merged 5 commits into from
Jul 14, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions libraries/chain/abi_serializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ namespace eosio { namespace chain {
tables.clear();
error_messages.clear();
variants.clear();
action_results.clear();

for( const auto& st : abi.structs )
structs[st.name] = st;
Expand All @@ -165,6 +166,9 @@ namespace eosio { namespace chain {
for( const auto& v : abi.variants.value )
variants[v.name] = v;

for( const auto& r : abi.action_results.value )
action_results[r.name] = r.result_type;

/**
* The ABI vector may contain duplicates which would make it
* an invalid ABI
Expand All @@ -175,6 +179,7 @@ namespace eosio { namespace chain {
EOS_ASSERT( tables.size() == abi.tables.size(), duplicate_abi_table_def_exception, "duplicate table definition detected" );
EOS_ASSERT( error_messages.size() == abi.error_messages.size(), duplicate_abi_err_msg_def_exception, "duplicate error message definition detected" );
EOS_ASSERT( variants.size() == abi.variants.value.size(), duplicate_abi_variant_def_exception, "duplicate variant definition detected" );
EOS_ASSERT( action_results.size() == abi.action_results.value.size(), duplicate_abi_action_results_def_exception, "duplicate action results definition detected" );

validate(ctx);
}
Expand Down Expand Up @@ -303,6 +308,11 @@ namespace eosio { namespace chain {
ctx.check_deadline();
EOS_ASSERT(_is_type(t.second, ctx), invalid_type_inside_abi, "${type}", ("type",impl::limit_size(t.second)) );
} FC_CAPTURE_AND_RETHROW( (t) ) }

for( const auto& r : action_results ) { try {
ctx.check_deadline();
EOS_ASSERT(_is_type(r.second, ctx), invalid_type_inside_abi, "${type}", ("type",impl::limit_size(r.second)) );
} FC_CAPTURE_AND_RETHROW( (r) ) }
}

std::string_view abi_serializer::resolve_type(const std::string_view& type)const {
Expand Down Expand Up @@ -591,6 +601,11 @@ namespace eosio { namespace chain {
if( itr != tables.end() ) return itr->second;
return type_name();
}
type_name abi_serializer::get_action_result_type(name action_result)const {
auto itr = action_results.find(action_result);
if( itr != action_results.end() ) return itr->second;
return type_name();
}

optional<string> abi_serializer::get_error_message( uint64_t error_code )const {
auto itr = error_messages.find( error_code );
Expand Down
2 changes: 2 additions & 0 deletions libraries/chain/include/eosio/chain/abi_serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ struct abi_serializer {

type_name get_action_type(name action)const;
type_name get_table_type(name action)const;
type_name get_action_result_type(name action_result)const;

optional<string> get_error_message( uint64_t error_code )const;

Expand Down Expand Up @@ -139,6 +140,7 @@ struct abi_serializer {
map<name,type_name> tables;
map<uint64_t, string> error_messages;
map<type_name, variant_def, std::less<>> variants;
map<name,type_name> action_results;

map<type_name, pair<unpack_function, pack_function>, std::less<>> built_in_types;
void configure_built_in_types();
Expand Down
2 changes: 2 additions & 0 deletions libraries/chain/include/eosio/chain/exceptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,8 @@ namespace eosio { namespace chain {
3015015, "Duplicate variant definition in the ABI" )
FC_DECLARE_DERIVED_EXCEPTION( unsupported_abi_version_exception, abi_exception,
3015016, "ABI has an unsupported version" )
FC_DECLARE_DERIVED_EXCEPTION( duplicate_abi_action_results_def_exception, abi_exception,
3015017, "Duplicate action results definition in the ABI" )

FC_DECLARE_DERIVED_EXCEPTION( contract_exception, chain_exception,
3160000, "Contract exception" )
Expand Down
22 changes: 22 additions & 0 deletions unittests/abi_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2361,7 +2361,29 @@ BOOST_AUTO_TEST_CASE(action_results)
],
})";

auto duplicate_action_results_abi = R"({
"version": "eosio::abi/1.2",
"action_results": [
{"name": "act1", "result_type": "string"},
{"name": "act1", "result_type": "string"},
],
})";

auto action_results_abi_invalid_type = R"({
"version": "eosio::abi/1.2",
"action_results": [
{"name": "act1", "result_type": "string"},
{"name": "act2", "result_type": "uint9000"},
],
})";

try {
// duplicate action_results definition detected
BOOST_CHECK_THROW( abi_serializer( fc::json::from_string(duplicate_action_results_abi).as<abi_def>(), abi_serializer::create_yield_function( max_serialization_time ) ), duplicate_abi_action_results_def_exception );

// invalid_type_inside_abi
BOOST_CHECK_THROW( abi_serializer( fc::json::from_string(action_results_abi_invalid_type).as<abi_def>(), abi_serializer::create_yield_function( max_serialization_time ) ), invalid_type_inside_abi );

// round-trip abi through multiple formats
// json -> variant -> abi_def -> bin
auto bin = fc::raw::pack(fc::json::from_string(action_results_abi).as<abi_def>());
Expand Down
25 changes: 25 additions & 0 deletions unittests/api_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3469,4 +3469,29 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try {

} FC_LOG_AND_RETHROW() }

BOOST_FIXTURE_TEST_CASE(action_results_tests, TESTER) { try {
produce_blocks(2);
create_account( N(test) );
set_code( N(test), contracts::action_results_wasm() );
produce_blocks(1);

auto call_autoresret_and_check = [&]( account_name contract, account_name signer, auto&& checker ) {
signed_transaction trx;
trx.actions.emplace_back( vector<permission_level>{{signer, config::active_name}}, contract, N(actionresret), bytes{} );
this->set_transaction_headers( trx, this->DEFAULT_EXPIRATION_DELTA );
trx.sign( this->get_private_key(signer, "active"), control->get_chain_id() );
auto res = this->push_transaction(trx);
checker( res );
};

call_autoresret_and_check( N(test), N(test), [&]( const transaction_trace_ptr& res ) {
BOOST_CHECK_EQUAL( res->receipt->status, transaction_receipt::executed );

auto &atrace = res->action_traces;
BOOST_REQUIRE_EQUAL( atrace[0].receipt.valid(), true );
BOOST_REQUIRE_EQUAL( atrace[0].return_value.size(), 4 );
BOOST_REQUIRE_EQUAL( fc::raw::unpack<int>(atrace[0].return_value), 10 );
} );
} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_SUITE_END()
1 change: 1 addition & 0 deletions unittests/contracts.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ namespace eosio {
MAKE_READ_WASM_ABI(test_api_db, test_api_db, test-contracts)
MAKE_READ_WASM_ABI(test_api_multi_index, test_api_multi_index, test-contracts)
MAKE_READ_WASM_ABI(test_ram_limit, test_ram_limit, test-contracts)
MAKE_READ_WASM_ABI(action_results, action_results, test-contracts)
MAKE_READ_WASM_ABI(wasm_config_bios, wasm_config_bios, test-contracts)
};
} /// eosio::testing
Expand Down
1 change: 1 addition & 0 deletions unittests/test-contracts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,5 @@ add_subdirectory( test_api )
add_subdirectory( test_api_db )
add_subdirectory( test_api_multi_index )
add_subdirectory( test_ram_limit )
add_subdirectory( action_results )
add_subdirectory( wasm_config_bios )
6 changes: 6 additions & 0 deletions unittests/test-contracts/action_results/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
if( EOSIO_COMPILE_TEST_CONTRACTS )
add_contract( action_results action_results action_results.cpp )
else()
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/action_results.wasm ${CMAKE_CURRENT_BINARY_DIR}/action_results.wasm COPYONLY )
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/action_results.abi ${CMAKE_CURRENT_BINARY_DIR}/action_results.abi COPYONLY )
endif()
28 changes: 28 additions & 0 deletions unittests/test-contracts/action_results/action_results.abi
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"____comment": "This file was generated with eosio-abigen. DO NOT EDIT ",
"version": "eosio::abi/1.2",
"types": [],
"structs": [
{
"name": "actionresret",
"base": "",
"fields": []
}
],
"actions": [
{
"name": "actionresret",
"type": "actionresret",
"ricardian_contract": ""
}
],
"tables": [],
"ricardian_clauses": [],
"variants": [],
"action_results": [
{
"name": "actionresret",
"result_type": "int32"
}
]
}
15 changes: 15 additions & 0 deletions unittests/test-contracts/action_results/action_results.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <eosio/eosio.hpp>

using namespace eosio;

class [[eosio::contract]] action_results : public contract {
public:
using contract::contract;

[[eosio::action]]
int actionresret() {
return 10;
}

private:
};
Binary file not shown.