From acce9d1a2a59ec5dcd17ebd46a6b4e0320be4508 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Apr 2019 17:51:04 -0400 Subject: [PATCH 1/4] rename parent_action_ordinal to closest_unnotified_ancestor_action_ordinal in action_trace --- libraries/chain/include/eosio/chain/trace.hpp | 10 ++- .../eosio/chain/transaction_context.hpp | 6 +- libraries/chain/trace.cpp | 8 +- libraries/chain/transaction_context.cpp | 18 +++-- plugins/chain_plugin/chain_plugin.cpp | 34 +++++---- .../state_history_serialization.hpp | 2 +- .../state_history_plugin_abi.cpp | 2 +- unittests/api_tests.cpp | 76 +++++++++---------- 8 files changed, 86 insertions(+), 70 deletions(-) diff --git a/libraries/chain/include/eosio/chain/trace.hpp b/libraries/chain/include/eosio/chain/trace.hpp index 5331bef1563..e60b8333a31 100644 --- a/libraries/chain/include/eosio/chain/trace.hpp +++ b/libraries/chain/include/eosio/chain/trace.hpp @@ -25,14 +25,16 @@ namespace eosio { namespace chain { struct action_trace { action_trace( const transaction_trace& trace, const action& act, account_name receiver, bool context_free, - uint32_t action_ordinal, uint32_t creator_action_ordinal, uint32_t parent_action_ordinal ); + uint32_t action_ordinal, uint32_t creator_action_ordinal, + uint32_t closest_unnotified_ancestor_action_ordinal ); action_trace( const transaction_trace& trace, action&& act, account_name receiver, bool context_free, - uint32_t action_ordinal, uint32_t creator_action_ordinal, uint32_t parent_action_ordinal ); + uint32_t action_ordinal, uint32_t creator_action_ordinal, + uint32_t closest_unnotified_ancestor_action_ordinal ); action_trace(){} fc::unsigned_int action_ordinal; fc::unsigned_int creator_action_ordinal; - fc::unsigned_int parent_action_ordinal; + fc::unsigned_int closest_unnotified_ancestor_action_ordinal; fc::optional receipt; action_name receiver; action act; @@ -70,7 +72,7 @@ FC_REFLECT( eosio::chain::account_delta, (account)(delta) ) FC_REFLECT( eosio::chain::action_trace, - (action_ordinal)(creator_action_ordinal)(parent_action_ordinal)(receipt) + (action_ordinal)(creator_action_ordinal)(closest_unnotified_ancestor_action_ordinal)(receipt) (receiver)(act)(context_free)(elapsed)(console)(trx_id)(block_num)(block_time) (producer_block_id)(account_ram_deltas)(except) ) diff --git a/libraries/chain/include/eosio/chain/transaction_context.hpp b/libraries/chain/include/eosio/chain/transaction_context.hpp index bbfe53810f6..a3779d439a3 100644 --- a/libraries/chain/include/eosio/chain/transaction_context.hpp +++ b/libraries/chain/include/eosio/chain/transaction_context.hpp @@ -69,15 +69,15 @@ namespace eosio { namespace chain { /** invalidates any action_trace references returned by get_action_trace */ uint32_t schedule_action( const action& act, account_name receiver, bool context_free, - uint32_t creator_action_ordinal, uint32_t parent_action_ordinal ); + uint32_t creator_action_ordinal, uint32_t closest_unnotified_ancestor_action_ordinal ); /** invalidates any action_trace references returned by get_action_trace */ uint32_t schedule_action( action&& act, account_name receiver, bool context_free, - uint32_t creator_action_ordinal, uint32_t parent_action_ordinal ); + uint32_t creator_action_ordinal, uint32_t closest_unnotified_ancestor_action_ordinal ); /** invalidates any action_trace references returned by get_action_trace */ uint32_t schedule_action( uint32_t action_ordinal, account_name receiver, bool context_free, - uint32_t creator_action_ordinal, uint32_t parent_action_ordinal ); + uint32_t creator_action_ordinal, uint32_t closest_unnotified_ancestor_action_ordinal ); void execute_action( uint32_t action_ordinal, uint32_t recurse_depth ); diff --git a/libraries/chain/trace.cpp b/libraries/chain/trace.cpp index 2379018518f..44a7ba94cfd 100644 --- a/libraries/chain/trace.cpp +++ b/libraries/chain/trace.cpp @@ -8,11 +8,11 @@ namespace eosio { namespace chain { action_trace::action_trace( const transaction_trace& trace, const action& act, account_name receiver, bool context_free, - uint32_t action_ordinal, uint32_t creator_action_ordinal, uint32_t parent_action_ordinal + uint32_t action_ordinal, uint32_t creator_action_ordinal, uint32_t closest_unnotified_ancestor_action_ordinal ) :action_ordinal( action_ordinal ) ,creator_action_ordinal( creator_action_ordinal ) -,parent_action_ordinal( parent_action_ordinal ) +,closest_unnotified_ancestor_action_ordinal( closest_unnotified_ancestor_action_ordinal ) ,receiver( receiver ) ,act( act ) ,context_free( context_free ) @@ -24,11 +24,11 @@ action_trace::action_trace( action_trace::action_trace( const transaction_trace& trace, action&& act, account_name receiver, bool context_free, - uint32_t action_ordinal, uint32_t creator_action_ordinal, uint32_t parent_action_ordinal + uint32_t action_ordinal, uint32_t creator_action_ordinal, uint32_t closest_unnotified_ancestor_action_ordinal ) :action_ordinal( action_ordinal ) ,creator_action_ordinal( creator_action_ordinal ) -,parent_action_ordinal( parent_action_ordinal ) +,closest_unnotified_ancestor_action_ordinal( closest_unnotified_ancestor_action_ordinal ) ,receiver( receiver ) ,act( std::move(act) ) ,context_free( context_free ) diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index 2f196687d1f..4380192a7d8 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -595,29 +595,34 @@ namespace bacc = boost::accumulators; } uint32_t transaction_context::schedule_action( const action& act, account_name receiver, bool context_free, - uint32_t creator_action_ordinal, uint32_t parent_action_ordinal ) + uint32_t creator_action_ordinal, + uint32_t closest_unnotified_ancestor_action_ordinal ) { uint32_t new_action_ordinal = trace->action_traces.size() + 1; trace->action_traces.emplace_back( *trace, act, receiver, context_free, - new_action_ordinal, creator_action_ordinal, parent_action_ordinal ); + new_action_ordinal, creator_action_ordinal, + closest_unnotified_ancestor_action_ordinal ); return new_action_ordinal; } uint32_t transaction_context::schedule_action( action&& act, account_name receiver, bool context_free, - uint32_t creator_action_ordinal, uint32_t parent_action_ordinal ) + uint32_t creator_action_ordinal, + uint32_t closest_unnotified_ancestor_action_ordinal ) { uint32_t new_action_ordinal = trace->action_traces.size() + 1; trace->action_traces.emplace_back( *trace, std::move(act), receiver, context_free, - new_action_ordinal, creator_action_ordinal, parent_action_ordinal ); + new_action_ordinal, creator_action_ordinal, + closest_unnotified_ancestor_action_ordinal ); return new_action_ordinal; } uint32_t transaction_context::schedule_action( uint32_t action_ordinal, account_name receiver, bool context_free, - uint32_t creator_action_ordinal, uint32_t parent_action_ordinal ) + uint32_t creator_action_ordinal, + uint32_t closest_unnotified_ancestor_action_ordinal ) { uint32_t new_action_ordinal = trace->action_traces.size() + 1; @@ -628,7 +633,8 @@ namespace bacc = boost::accumulators; // The reserve above is required so that the emplace_back below does not invalidate the provided_action reference. trace->action_traces.emplace_back( *trace, provided_action, receiver, context_free, - new_action_ordinal, creator_action_ordinal, parent_action_ordinal ); + new_action_ordinal, creator_action_ordinal, + closest_unnotified_ancestor_action_ordinal ); return new_action_ordinal; } diff --git a/plugins/chain_plugin/chain_plugin.cpp b/plugins/chain_plugin/chain_plugin.cpp index e245e3017fd..dec98b41b55 100644 --- a/plugins/chain_plugin/chain_plugin.cpp +++ b/plugins/chain_plugin/chain_plugin.cpp @@ -1899,34 +1899,42 @@ void read_write::push_transaction(const read_write::push_transaction_params& par try { output = db.to_variant_with_abi( *trx_trace_ptr, abi_serializer_max_time ); - // Create map of (parent_action_ordinal, global_sequence) with action trace + // Create map of (closest_unnotified_ancestor_action_ordinal, global_sequence) with action trace std::map< std::pair, fc::mutable_variant_object > act_traces_map; for( const auto& act_trace : output["action_traces"].get_array() ) { if (act_trace["receipt"].is_null() && act_trace["except"].is_null()) continue; - auto parent_action_ordinal = act_trace["parent_action_ordinal"].as().value; + auto closest_unnotified_ancestor_action_ordinal = + act_trace["closest_unnotified_ancestor_action_ordinal"].as().value; auto global_sequence = act_trace["receipt"].is_null() ? std::numeric_limits::max() : act_trace["receipt"]["global_sequence"].as(); - act_traces_map.emplace( std::make_pair( parent_action_ordinal, global_sequence ), + act_traces_map.emplace( std::make_pair( closest_unnotified_ancestor_action_ordinal, + global_sequence ), act_trace.get_object() ); } - std::function(uint32_t)> convert_act_trace_to_tree_struct = [&](uint32_t parent_action_ordinal) { + std::function(uint32_t)> convert_act_trace_to_tree_struct = + [&](uint32_t closest_unnotified_ancestor_action_ordinal) { vector restructured_act_traces; - auto it = act_traces_map.lower_bound( std::make_pair(parent_action_ordinal, 0) ); - for( ; it != act_traces_map.end() && it->first.first == parent_action_ordinal; ++it ) { + auto it = act_traces_map.lower_bound( + std::make_pair( closest_unnotified_ancestor_action_ordinal, 0) + ); + for( ; + it != act_traces_map.end() && it->first.first == closest_unnotified_ancestor_action_ordinal; ++it ) + { auto& act_trace_mvo = it->second; auto action_ordinal = act_trace_mvo["action_ordinal"].as().value; act_trace_mvo["inline_traces"] = convert_act_trace_to_tree_struct(action_ordinal); if (act_trace_mvo["receipt"].is_null()) { - act_trace_mvo["receipt"] = fc::mutable_variant_object()("abi_sequence", 0) - ("act_digest", digest_type::hash(trx_trace_ptr->action_traces[action_ordinal-1].act)) - ("auth_sequence", flat_map()) - ("code_sequence", 0) - ("global_sequence", 0) - ("receiver", act_trace_mvo["receiver"]) - ("recv_sequence", 0); + act_trace_mvo["receipt"] = fc::mutable_variant_object() + ("abi_sequence", 0) + ("act_digest", digest_type::hash(trx_trace_ptr->action_traces[action_ordinal-1].act)) + ("auth_sequence", flat_map()) + ("code_sequence", 0) + ("global_sequence", 0) + ("receiver", act_trace_mvo["receiver"]) + ("recv_sequence", 0); } restructured_act_traces.push_back( std::move(act_trace_mvo) ); } diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp index 3251abef7fb..99356baea25 100644 --- a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp @@ -482,7 +482,7 @@ datastream& operator<<(datastream& ds, const history_serial_wrapper(obj.obj.action_ordinal)); fc::raw::pack(ds, as_type(obj.obj.creator_action_ordinal)); - fc::raw::pack(ds, as_type(obj.obj.parent_action_ordinal)); + fc::raw::pack(ds, as_type(obj.obj.closest_unnotified_ancestor_action_ordinal)); fc::raw::pack(ds, bool(obj.obj.receipt)); if (obj.obj.receipt) { fc::raw::pack(ds, make_history_serial_wrapper(obj.db, as_type(*obj.obj.receipt))); diff --git a/plugins/state_history_plugin/state_history_plugin_abi.cpp b/plugins/state_history_plugin/state_history_plugin_abi.cpp index b35882a7b83..b0a2f5b79e1 100644 --- a/plugins/state_history_plugin/state_history_plugin_abi.cpp +++ b/plugins/state_history_plugin/state_history_plugin_abi.cpp @@ -95,7 +95,7 @@ extern const char* const state_history_plugin_abi = R"({ "name": "action_trace_v0", "fields": [ { "name": "action_ordinal", "type": "varuint32" }, { "name": "creator_action_ordinal", "type": "varuint32" }, - { "name": "parent_action_ordinal", "type": "varuint32" }, + { "name": "closest_unnotified_ancestor_action_ordinal", "type": "varuint32" }, { "name": "receipt", "type": "action_receipt?" }, { "name": "receiver", "type": "name" }, { "name": "act", "type": "action" }, diff --git a/unittests/api_tests.cpp b/unittests/api_tests.cpp index 04d2a69fffb..151bf82ebcf 100644 --- a/unittests/api_tests.cpp +++ b/unittests/api_tests.cpp @@ -2086,7 +2086,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { set_code( N(erin), contracts::test_api_wasm() ); produce_blocks(1); - transaction_trace_ptr txn_trace = CALL_TEST_FUNCTION_SCOPE( *this, "test_action", "test_action_ordinal1", + transaction_trace_ptr txn_trace = CALL_TEST_FUNCTION_SCOPE( *this, "test_action", "test_action_ordinal1", {}, vector{ N(testapi)}); BOOST_REQUIRE_EQUAL( validate(), true ); @@ -2097,7 +2097,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { auto &atrace = txn_trace->action_traces; BOOST_REQUIRE_EQUAL((int)atrace[0].action_ordinal, 1); BOOST_REQUIRE_EQUAL((int)atrace[0].creator_action_ordinal, 0); - BOOST_REQUIRE_EQUAL((int)atrace[0].parent_action_ordinal, 0); + BOOST_REQUIRE_EQUAL((int)atrace[0].closest_unnotified_ancestor_action_ordinal, 0); BOOST_REQUIRE_EQUAL(atrace[0].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[0].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[0].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2106,7 +2106,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[1].action_ordinal,2); BOOST_REQUIRE_EQUAL((int)atrace[1].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[1].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[1].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[1].receiver.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[1].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[1].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2115,7 +2115,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[2].action_ordinal, 3); BOOST_REQUIRE_EQUAL((int)atrace[2].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[2].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[2].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[2].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[2].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[2].act.name.value, TEST_METHOD("test_action", "test_action_ordinal2")); @@ -2124,7 +2124,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[3].action_ordinal, 4); BOOST_REQUIRE_EQUAL((int)atrace[3].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[3].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[3].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[3].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[3].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[3].act.name.value, TEST_METHOD("test_action", "test_action_ordinal3")); @@ -2133,7 +2133,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[4].action_ordinal, 5); BOOST_REQUIRE_EQUAL((int)atrace[4].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[4].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[4].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[4].receiver.value, N(charlie)); BOOST_REQUIRE_EQUAL(atrace[4].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[4].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2142,7 +2142,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[5].action_ordinal, 6); BOOST_REQUIRE_EQUAL((int)atrace[5].creator_action_ordinal, 2); - BOOST_REQUIRE_EQUAL((int)atrace[5].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[5].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[5].receiver.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[5].act.account.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[5].act.name.value, TEST_METHOD("test_action", "test_action_ordinal_foo")); @@ -2151,7 +2151,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[6].action_ordinal, 7); BOOST_REQUIRE_EQUAL((int)atrace[6].creator_action_ordinal,2); - BOOST_REQUIRE_EQUAL((int)atrace[6].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[6].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[6].receiver.value, N(david)); BOOST_REQUIRE_EQUAL(atrace[6].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[6].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2160,7 +2160,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[7].action_ordinal, 8); BOOST_REQUIRE_EQUAL((int)atrace[7].creator_action_ordinal, 5); - BOOST_REQUIRE_EQUAL((int)atrace[7].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[7].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[7].receiver.value, N(charlie)); BOOST_REQUIRE_EQUAL(atrace[7].act.account.value, N(charlie)); BOOST_REQUIRE_EQUAL(atrace[7].act.name.value, TEST_METHOD("test_action", "test_action_ordinal_bar")); @@ -2169,7 +2169,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[8].action_ordinal, 9); BOOST_REQUIRE_EQUAL((int)atrace[8].creator_action_ordinal, 3); - BOOST_REQUIRE_EQUAL((int)atrace[8].parent_action_ordinal, 3); + BOOST_REQUIRE_EQUAL((int)atrace[8].closest_unnotified_ancestor_action_ordinal, 3); BOOST_REQUIRE_EQUAL(atrace[8].receiver.value, N(david)); BOOST_REQUIRE_EQUAL(atrace[8].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[8].act.name.value, TEST_METHOD("test_action", "test_action_ordinal2")); @@ -2178,7 +2178,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[9].action_ordinal, 10); BOOST_REQUIRE_EQUAL((int)atrace[9].creator_action_ordinal, 3); - BOOST_REQUIRE_EQUAL((int)atrace[9].parent_action_ordinal, 3); + BOOST_REQUIRE_EQUAL((int)atrace[9].closest_unnotified_ancestor_action_ordinal, 3); BOOST_REQUIRE_EQUAL(atrace[9].receiver.value, N(erin)); BOOST_REQUIRE_EQUAL(atrace[9].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[9].act.name.value, TEST_METHOD("test_action", "test_action_ordinal2")); @@ -2187,7 +2187,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_test, TESTER) { try { BOOST_REQUIRE_EQUAL((int)atrace[10].action_ordinal, 11); BOOST_REQUIRE_EQUAL((int)atrace[10].creator_action_ordinal, 3); - BOOST_REQUIRE_EQUAL((int)atrace[10].parent_action_ordinal, 3); + BOOST_REQUIRE_EQUAL((int)atrace[10].closest_unnotified_ancestor_action_ordinal, 3); BOOST_REQUIRE_EQUAL(atrace[10].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[10].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[10].act.name.value, TEST_METHOD("test_action", "test_action_ordinal4")); @@ -2221,7 +2221,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest1, TESTER) { try { create_account(N(fail1) ); // <- make first action fails in the middle produce_blocks(1); - transaction_trace_ptr txn_trace = + transaction_trace_ptr txn_trace = CALL_TEST_FUNCTION_NO_THROW( *this, "test_action", "test_action_ordinal1", {}); BOOST_REQUIRE_EQUAL( validate(), true ); @@ -2231,10 +2231,10 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest1, TESTER) { try { auto &atrace = txn_trace->action_traces; - // fails here after creating one notify action and one inline action + // fails here after creating one notify action and one inline action BOOST_REQUIRE_EQUAL((int)atrace[0].action_ordinal, 1); BOOST_REQUIRE_EQUAL((int)atrace[0].creator_action_ordinal, 0); - BOOST_REQUIRE_EQUAL((int)atrace[0].parent_action_ordinal, 0); + BOOST_REQUIRE_EQUAL((int)atrace[0].closest_unnotified_ancestor_action_ordinal, 0); BOOST_REQUIRE_EQUAL(atrace[0].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[0].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[0].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2245,7 +2245,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest1, TESTER) { try { // not executed BOOST_REQUIRE_EQUAL((int)atrace[1].action_ordinal, 2); BOOST_REQUIRE_EQUAL((int)atrace[1].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[1].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[1].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[1].receiver.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[1].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[1].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2255,7 +2255,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest1, TESTER) { try { // not executed BOOST_REQUIRE_EQUAL((int)atrace[2].action_ordinal, 3); BOOST_REQUIRE_EQUAL((int)atrace[2].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[2].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[2].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[2].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[2].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[2].act.name.value, TEST_METHOD("test_action", "test_action_ordinal2")); @@ -2289,7 +2289,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest2, TESTER) { try { create_account(N(fail3) ); // <- make action 3 fails in the middle produce_blocks(1); - transaction_trace_ptr txn_trace = + transaction_trace_ptr txn_trace = CALL_TEST_FUNCTION_NO_THROW( *this, "test_action", "test_action_ordinal1", {}); BOOST_REQUIRE_EQUAL( validate(), true ); @@ -2302,7 +2302,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest2, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[0].action_ordinal, 1); BOOST_REQUIRE_EQUAL((int)atrace[0].creator_action_ordinal, 0); - BOOST_REQUIRE_EQUAL((int)atrace[0].parent_action_ordinal, 0); + BOOST_REQUIRE_EQUAL((int)atrace[0].closest_unnotified_ancestor_action_ordinal, 0); BOOST_REQUIRE_EQUAL(atrace[0].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[0].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[0].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2313,7 +2313,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest2, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[1].action_ordinal,2); BOOST_REQUIRE_EQUAL((int)atrace[1].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[1].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[1].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[1].receiver.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[1].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[1].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2323,7 +2323,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest2, TESTER) { try { // not executed BOOST_REQUIRE_EQUAL((int)atrace[2].action_ordinal, 3); BOOST_REQUIRE_EQUAL((int)atrace[2].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[2].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[2].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[2].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[2].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[2].act.name.value, TEST_METHOD("test_action", "test_action_ordinal2")); @@ -2333,7 +2333,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest2, TESTER) { try { // not executed BOOST_REQUIRE_EQUAL((int)atrace[3].action_ordinal, 4); BOOST_REQUIRE_EQUAL((int)atrace[3].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[3].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[3].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[3].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[3].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[3].act.name.value, TEST_METHOD("test_action", "test_action_ordinal3")); @@ -2343,7 +2343,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest2, TESTER) { try { // hey exception is here BOOST_REQUIRE_EQUAL((int)atrace[4].action_ordinal, 5); BOOST_REQUIRE_EQUAL((int)atrace[4].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[4].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[4].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[4].receiver.value, N(charlie)); BOOST_REQUIRE_EQUAL(atrace[4].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[4].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2354,7 +2354,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest2, TESTER) { try { // not executed BOOST_REQUIRE_EQUAL((int)atrace[5].action_ordinal, 6); BOOST_REQUIRE_EQUAL((int)atrace[5].creator_action_ordinal, 2); - BOOST_REQUIRE_EQUAL((int)atrace[5].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[5].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[5].receiver.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[5].act.account.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[5].act.name.value, TEST_METHOD("test_action", "test_action_ordinal_foo")); @@ -2364,7 +2364,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest2, TESTER) { try { // not executed BOOST_REQUIRE_EQUAL((int)atrace[6].action_ordinal, 7); BOOST_REQUIRE_EQUAL((int)atrace[6].creator_action_ordinal,2); - BOOST_REQUIRE_EQUAL((int)atrace[6].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[6].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[6].receiver.value, N(david)); BOOST_REQUIRE_EQUAL(atrace[6].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[6].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2374,7 +2374,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest2, TESTER) { try { // not executed BOOST_REQUIRE_EQUAL((int)atrace[7].action_ordinal, 8); BOOST_REQUIRE_EQUAL((int)atrace[7].creator_action_ordinal, 5); - BOOST_REQUIRE_EQUAL((int)atrace[7].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[7].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[7].receiver.value, N(charlie)); BOOST_REQUIRE_EQUAL(atrace[7].act.account.value, N(charlie)); BOOST_REQUIRE_EQUAL(atrace[7].act.name.value, TEST_METHOD("test_action", "test_action_ordinal_bar")); @@ -2408,7 +2408,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { create_account(N(failnine) ); // <- make action 9 fails in the middle produce_blocks(1); - transaction_trace_ptr txn_trace = + transaction_trace_ptr txn_trace = CALL_TEST_FUNCTION_NO_THROW( *this, "test_action", "test_action_ordinal1", {}); BOOST_REQUIRE_EQUAL( validate(), true ); @@ -2421,7 +2421,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[0].action_ordinal, 1); BOOST_REQUIRE_EQUAL((int)atrace[0].creator_action_ordinal, 0); - BOOST_REQUIRE_EQUAL((int)atrace[0].parent_action_ordinal, 0); + BOOST_REQUIRE_EQUAL((int)atrace[0].closest_unnotified_ancestor_action_ordinal, 0); BOOST_REQUIRE_EQUAL(atrace[0].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[0].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[0].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2432,7 +2432,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[1].action_ordinal,2); BOOST_REQUIRE_EQUAL((int)atrace[1].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[1].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[1].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[1].receiver.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[1].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[1].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2442,7 +2442,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[2].action_ordinal, 3); BOOST_REQUIRE_EQUAL((int)atrace[2].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[2].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[2].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[2].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[2].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[2].act.name.value, TEST_METHOD("test_action", "test_action_ordinal2")); @@ -2452,7 +2452,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // fails here BOOST_REQUIRE_EQUAL((int)atrace[3].action_ordinal, 4); BOOST_REQUIRE_EQUAL((int)atrace[3].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[3].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[3].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[3].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[3].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[3].act.name.value, TEST_METHOD("test_action", "test_action_ordinal3")); @@ -2463,7 +2463,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[4].action_ordinal, 5); BOOST_REQUIRE_EQUAL((int)atrace[4].creator_action_ordinal, 1); - BOOST_REQUIRE_EQUAL((int)atrace[4].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[4].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[4].receiver.value, N(charlie)); BOOST_REQUIRE_EQUAL(atrace[4].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[4].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2473,7 +2473,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // not executed BOOST_REQUIRE_EQUAL((int)atrace[5].action_ordinal, 6); BOOST_REQUIRE_EQUAL((int)atrace[5].creator_action_ordinal, 2); - BOOST_REQUIRE_EQUAL((int)atrace[5].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[5].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[5].receiver.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[5].act.account.value, N(bob)); BOOST_REQUIRE_EQUAL(atrace[5].act.name.value, TEST_METHOD("test_action", "test_action_ordinal_foo")); @@ -2483,7 +2483,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[6].action_ordinal, 7); BOOST_REQUIRE_EQUAL((int)atrace[6].creator_action_ordinal,2); - BOOST_REQUIRE_EQUAL((int)atrace[6].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[6].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[6].receiver.value, N(david)); BOOST_REQUIRE_EQUAL(atrace[6].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[6].act.name.value, TEST_METHOD("test_action", "test_action_ordinal1")); @@ -2493,7 +2493,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // not executed BOOST_REQUIRE_EQUAL((int)atrace[7].action_ordinal, 8); BOOST_REQUIRE_EQUAL((int)atrace[7].creator_action_ordinal, 5); - BOOST_REQUIRE_EQUAL((int)atrace[7].parent_action_ordinal, 1); + BOOST_REQUIRE_EQUAL((int)atrace[7].closest_unnotified_ancestor_action_ordinal, 1); BOOST_REQUIRE_EQUAL(atrace[7].receiver.value, N(charlie)); BOOST_REQUIRE_EQUAL(atrace[7].act.account.value, N(charlie)); BOOST_REQUIRE_EQUAL(atrace[7].act.name.value, TEST_METHOD("test_action", "test_action_ordinal_bar")); @@ -2503,7 +2503,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[8].action_ordinal, 9); BOOST_REQUIRE_EQUAL((int)atrace[8].creator_action_ordinal, 3); - BOOST_REQUIRE_EQUAL((int)atrace[8].parent_action_ordinal, 3); + BOOST_REQUIRE_EQUAL((int)atrace[8].closest_unnotified_ancestor_action_ordinal, 3); BOOST_REQUIRE_EQUAL(atrace[8].receiver.value, N(david)); BOOST_REQUIRE_EQUAL(atrace[8].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[8].act.name.value, TEST_METHOD("test_action", "test_action_ordinal2")); @@ -2513,7 +2513,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[9].action_ordinal, 10); BOOST_REQUIRE_EQUAL((int)atrace[9].creator_action_ordinal, 3); - BOOST_REQUIRE_EQUAL((int)atrace[9].parent_action_ordinal, 3); + BOOST_REQUIRE_EQUAL((int)atrace[9].closest_unnotified_ancestor_action_ordinal, 3); BOOST_REQUIRE_EQUAL(atrace[9].receiver.value, N(erin)); BOOST_REQUIRE_EQUAL(atrace[9].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[9].act.name.value, TEST_METHOD("test_action", "test_action_ordinal2")); @@ -2523,7 +2523,7 @@ BOOST_FIXTURE_TEST_CASE(action_ordinal_failtest3, TESTER) { try { // executed BOOST_REQUIRE_EQUAL((int)atrace[10].action_ordinal, 11); BOOST_REQUIRE_EQUAL((int)atrace[10].creator_action_ordinal, 3); - BOOST_REQUIRE_EQUAL((int)atrace[10].parent_action_ordinal, 3); + BOOST_REQUIRE_EQUAL((int)atrace[10].closest_unnotified_ancestor_action_ordinal, 3); BOOST_REQUIRE_EQUAL(atrace[10].receiver.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[10].act.account.value, N(testapi)); BOOST_REQUIRE_EQUAL(atrace[10].act.name.value, TEST_METHOD("test_action", "test_action_ordinal4")); From 0d5f3d768c87faafbea5ab89e2ee27bc756756d1 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Apr 2019 18:37:14 -0400 Subject: [PATCH 2/4] remove closest_unnotified_ancestor_action_ordinal from state_history_plugin --- .../eosio/state_history_plugin/state_history_serialization.hpp | 1 - plugins/state_history_plugin/state_history_plugin_abi.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp index 99356baea25..9b22a0ab6c2 100644 --- a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp @@ -482,7 +482,6 @@ datastream& operator<<(datastream& ds, const history_serial_wrapper(obj.obj.action_ordinal)); fc::raw::pack(ds, as_type(obj.obj.creator_action_ordinal)); - fc::raw::pack(ds, as_type(obj.obj.closest_unnotified_ancestor_action_ordinal)); fc::raw::pack(ds, bool(obj.obj.receipt)); if (obj.obj.receipt) { fc::raw::pack(ds, make_history_serial_wrapper(obj.db, as_type(*obj.obj.receipt))); diff --git a/plugins/state_history_plugin/state_history_plugin_abi.cpp b/plugins/state_history_plugin/state_history_plugin_abi.cpp index b0a2f5b79e1..f53fe3759e3 100644 --- a/plugins/state_history_plugin/state_history_plugin_abi.cpp +++ b/plugins/state_history_plugin/state_history_plugin_abi.cpp @@ -95,7 +95,6 @@ extern const char* const state_history_plugin_abi = R"({ "name": "action_trace_v0", "fields": [ { "name": "action_ordinal", "type": "varuint32" }, { "name": "creator_action_ordinal", "type": "varuint32" }, - { "name": "closest_unnotified_ancestor_action_ordinal", "type": "varuint32" }, { "name": "receipt", "type": "action_receipt?" }, { "name": "receiver", "type": "name" }, { "name": "act", "type": "action" }, From c3817b3f965aaf3d7ac3be5809893ef17aa770f6 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Apr 2019 19:06:40 -0400 Subject: [PATCH 3/4] add error_code to transaction and action traces #6898 --- libraries/chain/apply_context.cpp | 8 +++- libraries/chain/controller.cpp | 40 ++++++++++++++++++- .../chain/include/eosio/chain/controller.hpp | 2 + libraries/chain/include/eosio/chain/trace.hpp | 6 ++- .../state_history_serialization.hpp | 2 + .../state_history_plugin_abi.cpp | 4 +- unittests/api_tests.cpp | 11 +++++ 7 files changed, 68 insertions(+), 5 deletions(-) diff --git a/libraries/chain/apply_context.cpp b/libraries/chain/apply_context.cpp index ba1f2b2d521..616c8e31dac 100644 --- a/libraries/chain/apply_context.cpp +++ b/libraries/chain/apply_context.cpp @@ -82,7 +82,13 @@ void apply_context::exec_one() } catch( const wasm_exit& ) {} } } FC_RETHROW_EXCEPTIONS( warn, "pending console output: ${console}", ("console", _pending_console_output) ) - } catch( fc::exception& e ) { + } catch( const eosio_assert_code_exception& e ) { + action_trace& trace = trx_context.get_action_trace( action_ordinal ); + trace.error_code = controller::convert_exception_to_error_code( e ); + trace.except = e; + finalize_trace( trace, start ); + throw; + } catch( const fc::exception& e ) { action_trace& trace = trx_context.get_action_trace( action_ordinal ); trace.except = e; finalize_trace( trace, start ); diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index c3ee723308b..bccad2c784b 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -981,6 +981,11 @@ struct controller_impl { return trace; } catch( const protocol_feature_bad_block_exception& ) { throw; + } catch( const eosio_assert_code_exception& e ) { + cpu_time_to_bill_us = trx_context.update_billed_cpu_time( fc::time_point::now() ); + trace->error_code = controller::convert_exception_to_error_code( e ); + trace->except = e; + trace->except_ptr = std::current_exception(); } catch( const fc::exception& e ) { cpu_time_to_bill_us = trx_context.update_billed_cpu_time( fc::time_point::now() ); trace->except = e; @@ -1123,6 +1128,11 @@ struct controller_impl { return trace; } catch( const protocol_feature_bad_block_exception& ) { throw; + } catch( const eosio_assert_code_exception& e ) { + trace->error_code = controller::convert_exception_to_error_code( e ); + trace->except = e; + trace->except_ptr = std::current_exception(); + trace->elapsed = fc::time_point::now() - trx_context.start; } catch( const fc::exception& e ) { cpu_time_to_bill_us = trx_context.update_billed_cpu_time( fc::time_point::now() ); trace->except = e; @@ -1314,7 +1324,11 @@ struct controller_impl { unapplied_transactions.erase( trx->signed_id ); } return trace; - } catch (const fc::exception& e) { + } catch( const eosio_assert_code_exception& e ) { + trace->error_code = controller::convert_exception_to_error_code( e ); + trace->except = e; + trace->except_ptr = std::current_exception(); + } catch( const fc::exception& e ) { trace->except = e; trace->except_ptr = std::current_exception(); } @@ -2983,6 +2997,30 @@ bool controller::all_subjective_mitigations_disabled()const { return my->conf.disable_all_subjective_mitigations; } +fc::optional controller::convert_exception_to_error_code( const eosio_assert_code_exception& e ) { + const auto& logs = e.get_log(); + + if( logs.size() == 0 ) return {}; + + const auto msg = logs[0].get_message(); + + auto pos = msg.find( ": " ); + + if( pos == std::string::npos || (pos + 2) >= msg.size() ) return {}; + + pos += 2; + + uint64_t error_code = 0; + + try { + error_code = std::strtoull( msg.c_str() + pos, nullptr, 10 ); + } catch( ... ) { + return {}; + } + + return error_code; +} + /// Protocol feature activation handlers: template<> diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index fc6d28132f5..31b6ae4b830 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -275,6 +275,8 @@ namespace eosio { namespace chain { void add_to_ram_correction( account_name account, uint64_t ram_bytes ); bool all_subjective_mitigations_disabled()const; + static fc::optional convert_exception_to_error_code( const eosio_assert_code_exception& e ); + signal pre_accepted_block; signal accepted_block_header; signal accepted_block; diff --git a/libraries/chain/include/eosio/chain/trace.hpp b/libraries/chain/include/eosio/chain/trace.hpp index e60b8333a31..0db1be762ff 100644 --- a/libraries/chain/include/eosio/chain/trace.hpp +++ b/libraries/chain/include/eosio/chain/trace.hpp @@ -47,6 +47,7 @@ namespace eosio { namespace chain { fc::optional producer_block_id; flat_set account_ram_deltas; fc::optional except; + fc::optional error_code; }; struct transaction_trace { @@ -63,6 +64,7 @@ namespace eosio { namespace chain { transaction_trace_ptr failed_dtrx_trace; fc::optional except; + fc::optional error_code; std::exception_ptr except_ptr; }; @@ -74,8 +76,8 @@ FC_REFLECT( eosio::chain::account_delta, FC_REFLECT( eosio::chain::action_trace, (action_ordinal)(creator_action_ordinal)(closest_unnotified_ancestor_action_ordinal)(receipt) (receiver)(act)(context_free)(elapsed)(console)(trx_id)(block_num)(block_time) - (producer_block_id)(account_ram_deltas)(except) ) + (producer_block_id)(account_ram_deltas)(except)(error_code) ) FC_REFLECT( eosio::chain::transaction_trace, (id)(block_num)(block_time)(producer_block_id) (receipt)(elapsed)(net_usage)(scheduled) - (action_traces)(account_ram_delta)(failed_dtrx_trace)(except) ) + (action_traces)(account_ram_delta)(failed_dtrx_trace)(except)(error_code) ) diff --git a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp index 9b22a0ab6c2..5893c49dde4 100644 --- a/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp +++ b/plugins/state_history_plugin/include/eosio/state_history_plugin/state_history_serialization.hpp @@ -497,6 +497,7 @@ datastream& operator<<(datastream& ds, const history_serial_wrapperto_string(); fc::raw::pack(ds, as_type>(e)); + fc::raw::pack(ds, as_type>(obj.obj.error_code)); return ds; } @@ -533,6 +534,7 @@ datastream& operator<<(datastream& if (obj.obj.except) e = obj.obj.except->to_string(); fc::raw::pack(ds, as_type>(e)); + fc::raw::pack(ds, as_type>(obj.obj.error_code)); fc::raw::pack(ds, bool(obj.obj.failed_dtrx_trace)); if (obj.obj.failed_dtrx_trace) { diff --git a/plugins/state_history_plugin/state_history_plugin_abi.cpp b/plugins/state_history_plugin/state_history_plugin_abi.cpp index f53fe3759e3..74c7f8d7520 100644 --- a/plugins/state_history_plugin/state_history_plugin_abi.cpp +++ b/plugins/state_history_plugin/state_history_plugin_abi.cpp @@ -102,7 +102,8 @@ extern const char* const state_history_plugin_abi = R"({ { "name": "elapsed", "type": "int64" }, { "name": "console", "type": "string" }, { "name": "account_ram_deltas", "type": "account_delta[]" }, - { "name": "except", "type": "string?" } + { "name": "except", "type": "string?" }, + { "name": "error_code", "type": "uint64?" } ] }, { @@ -117,6 +118,7 @@ extern const char* const state_history_plugin_abi = R"({ { "name": "action_traces", "type": "action_trace[]" }, { "name": "account_ram_delta", "type": "account_delta?" }, { "name": "except", "type": "string?" }, + { "name": "error_code", "type": "uint64?" }, { "name": "failed_dtrx_trace", "type": "transaction_trace?" } ] }, diff --git a/unittests/api_tests.cpp b/unittests/api_tests.cpp index 151bf82ebcf..f2e20a948dc 100644 --- a/unittests/api_tests.cpp +++ b/unittests/api_tests.cpp @@ -2046,6 +2046,17 @@ BOOST_FIXTURE_TEST_CASE(eosio_assert_code_tests, TESTER) { try { BOOST_CHECK_EXCEPTION( CALL_TEST_FUNCTION( *this, "test_action", "test_assert_code", fc::raw::pack((uint64_t)42) ), eosio_assert_code_exception, eosio_assert_code_is(42) ); + + auto trace = CALL_TEST_FUNCTION_NO_THROW( *this, "test_action", "test_assert_code", fc::raw::pack((uint64_t)42) ); + BOOST_REQUIRE( trace ); + BOOST_REQUIRE( trace->except ); + BOOST_REQUIRE( trace->error_code ); + BOOST_REQUIRE_EQUAL( *trace->error_code, 42 ); + BOOST_REQUIRE_EQUAL( trace->action_traces.size(), 1 ); + BOOST_REQUIRE( trace->action_traces[0].except ); + BOOST_REQUIRE( trace->action_traces[0].error_code ); + BOOST_REQUIRE_EQUAL( *trace->action_traces[0].error_code, 42 ); + produce_block(); auto omsg1 = abis.get_error_message(1); From 7eebf69574bca5a093563751174a52ba24d68c7f Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 11 Apr 2019 13:35:05 -0400 Subject: [PATCH 4/4] store uint64_t error_code in eosio_assert_code_exception rather than extracting it from the string message #6898 --- libraries/chain/apply_context.cpp | 7 +-- libraries/chain/controller.cpp | 43 ++++--------------- .../chain/include/eosio/chain/controller.hpp | 2 +- .../chain/include/eosio/chain/exceptions.hpp | 38 +++++++++++++++- libraries/chain/wasm_interface.cpp | 8 +++- 5 files changed, 53 insertions(+), 45 deletions(-) diff --git a/libraries/chain/apply_context.cpp b/libraries/chain/apply_context.cpp index 616c8e31dac..5badd7185d0 100644 --- a/libraries/chain/apply_context.cpp +++ b/libraries/chain/apply_context.cpp @@ -82,14 +82,9 @@ void apply_context::exec_one() } catch( const wasm_exit& ) {} } } FC_RETHROW_EXCEPTIONS( warn, "pending console output: ${console}", ("console", _pending_console_output) ) - } catch( const eosio_assert_code_exception& e ) { - action_trace& trace = trx_context.get_action_trace( action_ordinal ); - trace.error_code = controller::convert_exception_to_error_code( e ); - trace.except = e; - finalize_trace( trace, start ); - throw; } catch( const fc::exception& e ) { action_trace& trace = trx_context.get_action_trace( action_ordinal ); + trace.error_code = controller::convert_exception_to_error_code( e ); trace.except = e; finalize_trace( trace, start ); throw; diff --git a/libraries/chain/controller.cpp b/libraries/chain/controller.cpp index bccad2c784b..e3721ef4726 100644 --- a/libraries/chain/controller.cpp +++ b/libraries/chain/controller.cpp @@ -981,13 +981,9 @@ struct controller_impl { return trace; } catch( const protocol_feature_bad_block_exception& ) { throw; - } catch( const eosio_assert_code_exception& e ) { - cpu_time_to_bill_us = trx_context.update_billed_cpu_time( fc::time_point::now() ); - trace->error_code = controller::convert_exception_to_error_code( e ); - trace->except = e; - trace->except_ptr = std::current_exception(); } catch( const fc::exception& e ) { cpu_time_to_bill_us = trx_context.update_billed_cpu_time( fc::time_point::now() ); + trace->error_code = controller::convert_exception_to_error_code( e ); trace->except = e; trace->except_ptr = std::current_exception(); } @@ -1128,13 +1124,9 @@ struct controller_impl { return trace; } catch( const protocol_feature_bad_block_exception& ) { throw; - } catch( const eosio_assert_code_exception& e ) { - trace->error_code = controller::convert_exception_to_error_code( e ); - trace->except = e; - trace->except_ptr = std::current_exception(); - trace->elapsed = fc::time_point::now() - trx_context.start; } catch( const fc::exception& e ) { cpu_time_to_bill_us = trx_context.update_billed_cpu_time( fc::time_point::now() ); + trace->error_code = controller::convert_exception_to_error_code( e ); trace->except = e; trace->except_ptr = std::current_exception(); trace->elapsed = fc::time_point::now() - trx_context.start; @@ -1324,11 +1316,8 @@ struct controller_impl { unapplied_transactions.erase( trx->signed_id ); } return trace; - } catch( const eosio_assert_code_exception& e ) { - trace->error_code = controller::convert_exception_to_error_code( e ); - trace->except = e; - trace->except_ptr = std::current_exception(); } catch( const fc::exception& e ) { + trace->error_code = controller::convert_exception_to_error_code( e ); trace->except = e; trace->except_ptr = std::current_exception(); } @@ -2997,28 +2986,12 @@ bool controller::all_subjective_mitigations_disabled()const { return my->conf.disable_all_subjective_mitigations; } -fc::optional controller::convert_exception_to_error_code( const eosio_assert_code_exception& e ) { - const auto& logs = e.get_log(); - - if( logs.size() == 0 ) return {}; - - const auto msg = logs[0].get_message(); - - auto pos = msg.find( ": " ); - - if( pos == std::string::npos || (pos + 2) >= msg.size() ) return {}; - - pos += 2; - - uint64_t error_code = 0; - - try { - error_code = std::strtoull( msg.c_str() + pos, nullptr, 10 ); - } catch( ... ) { - return {}; - } +fc::optional controller::convert_exception_to_error_code( const fc::exception& e ) { + const eosio_assert_code_exception* e_ptr = dynamic_cast( &e ); + + if( e_ptr == nullptr ) return {}; - return error_code; + return e_ptr->error_code; } /// Protocol feature activation handlers: diff --git a/libraries/chain/include/eosio/chain/controller.hpp b/libraries/chain/include/eosio/chain/controller.hpp index 31b6ae4b830..43d1f1637c9 100644 --- a/libraries/chain/include/eosio/chain/controller.hpp +++ b/libraries/chain/include/eosio/chain/controller.hpp @@ -275,7 +275,7 @@ namespace eosio { namespace chain { void add_to_ram_correction( account_name account, uint64_t ram_bytes ); bool all_subjective_mitigations_disabled()const; - static fc::optional convert_exception_to_error_code( const eosio_assert_code_exception& e ); + static fc::optional convert_exception_to_error_code( const fc::exception& e ); signal pre_accepted_block; signal accepted_block_header; diff --git a/libraries/chain/include/eosio/chain/exceptions.hpp b/libraries/chain/include/eosio/chain/exceptions.hpp index a80213e0425..51ab7e9f6c6 100644 --- a/libraries/chain/include/eosio/chain/exceptions.hpp +++ b/libraries/chain/include/eosio/chain/exceptions.hpp @@ -68,6 +68,42 @@ { throw( effect_type( e.what(), e.get_log() ) ); } +#define FC_DECLARE_DERIVED_EXCEPTION_WITH_ERROR_CODE( TYPE, BASE, CODE, WHAT ) \ + class TYPE : public BASE \ + { \ + public: \ + enum code_enum { \ + code_value = CODE, \ + }; \ + explicit TYPE( int64_t code, const std::string& name_value, const std::string& what_value ) \ + :BASE( code, name_value, what_value ){} \ + explicit TYPE( fc::log_message&& m, int64_t code, const std::string& name_value, const std::string& what_value ) \ + :BASE( std::move(m), code, name_value, what_value ){} \ + explicit TYPE( fc::log_messages&& m, int64_t code, const std::string& name_value, const std::string& what_value )\ + :BASE( std::move(m), code, name_value, what_value ){}\ + explicit TYPE( const fc::log_messages& m, int64_t code, const std::string& name_value, const std::string& what_value )\ + :BASE( m, code, name_value, what_value ){}\ + TYPE( const std::string& what_value, const fc::log_messages& m ) \ + :BASE( m, CODE, BOOST_PP_STRINGIZE(TYPE), what_value ){} \ + TYPE( fc::log_message&& m ) \ + :BASE( fc::move(m), CODE, BOOST_PP_STRINGIZE(TYPE), WHAT ){}\ + TYPE( fc::log_messages msgs ) \ + :BASE( fc::move( msgs ), CODE, BOOST_PP_STRINGIZE(TYPE), WHAT ) {} \ + TYPE( const TYPE& c ) \ + :BASE(c),error_code(c.error_code) {} \ + TYPE( const BASE& c ) \ + :BASE(c){} \ + TYPE():BASE(CODE, BOOST_PP_STRINGIZE(TYPE), WHAT){}\ + \ + virtual std::shared_ptr dynamic_copy_exception()const\ + { return std::make_shared( *this ); } \ + virtual NO_RETURN void dynamic_rethrow_exception()const \ + { if( code() == CODE ) throw *this;\ + else fc::exception::dynamic_rethrow_exception(); \ + } \ + fc::optional error_code; \ + }; + namespace eosio { namespace chain { FC_DECLARE_EXCEPTION( chain_exception, @@ -207,7 +243,7 @@ namespace eosio { namespace chain { 3050002, "Invalid Action Arguments" ) FC_DECLARE_DERIVED_EXCEPTION( eosio_assert_message_exception, action_validate_exception, 3050003, "eosio_assert_message assertion failure" ) - FC_DECLARE_DERIVED_EXCEPTION( eosio_assert_code_exception, action_validate_exception, + FC_DECLARE_DERIVED_EXCEPTION_WITH_ERROR_CODE( eosio_assert_code_exception, action_validate_exception, 3050004, "eosio_assert_code assertion failure" ) FC_DECLARE_DERIVED_EXCEPTION( action_not_found_exception, action_validate_exception, 3050005, "Action can not be found" ) diff --git a/libraries/chain/wasm_interface.cpp b/libraries/chain/wasm_interface.cpp index 004a7326e83..54feb1b6a87 100644 --- a/libraries/chain/wasm_interface.cpp +++ b/libraries/chain/wasm_interface.cpp @@ -960,8 +960,12 @@ class context_free_system_api : public context_aware_api { void eosio_assert_code( bool condition, uint64_t error_code ) { if( BOOST_UNLIKELY( !condition ) ) { - EOS_THROW( eosio_assert_code_exception, - "assertion failure with error code: ${error_code}", ("error_code", error_code) ); + eosio_assert_code_exception e( FC_LOG_MESSAGE( error, + "assertion failure with error code: ${error_code}", + ("error_code", error_code) + ) ); + e.error_code = error_code; + throw e; } }