diff --git a/plugins/http_plugin/http_plugin.cpp b/plugins/http_plugin/http_plugin.cpp index e4ef905479c..18e71faf9dd 100644 --- a/plugins/http_plugin/http_plugin.cpp +++ b/plugins/http_plugin/http_plugin.cpp @@ -722,11 +722,13 @@ namespace eosio { } catch (fc::exception& e) { error_results results{500, "Internal Service Error", error_results::error_info(e, verbose_http_errors)}; cb( 500, fc::variant( results )); - if (e.code() != chain::greylist_net_usage_exceeded::code_value && e.code() != chain::greylist_cpu_usage_exceeded::code_value) { + if (e.code() != chain::greylist_net_usage_exceeded::code_value && + e.code() != chain::greylist_cpu_usage_exceeded::code_value && + e.code() != fc::timeout_exception::code_value ) { fc_elog( logger, "FC Exception encountered while processing ${api}.${call}", ("api", api_name)( "call", call_name ) ); - fc_dlog( logger, "Exception Details: ${e}", ("e", e.to_detail_string()) ); } + fc_dlog( logger, "Exception Details: ${e}", ("e", e.to_detail_string()) ); } catch (std::exception& e) { error_results results{500, "Internal Service Error", error_results::error_info(fc::exception( FC_LOG_MESSAGE( error, e.what())), verbose_http_errors)}; cb( 500, fc::variant( results )); @@ -768,6 +770,10 @@ namespace eosio { return result; } + fc::microseconds http_plugin::get_max_response_time()const { + return my->max_response_time; + } + std::istream& operator>>(std::istream& in, https_ecdh_curve_t& curve) { std::string s; in >> s; diff --git a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp index 515ae6c796a..298f8f7cc8a 100644 --- a/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp +++ b/plugins/http_plugin/include/eosio/http_plugin/http_plugin.hpp @@ -97,7 +97,10 @@ namespace eosio { get_supported_apis_result get_supported_apis()const; - private: + /// @return the configured http-max-response-time-ms + fc::microseconds get_max_response_time()const; + + private: std::shared_ptr my; }; diff --git a/plugins/trace_api_plugin/include/eosio/trace_api/abi_data_handler.hpp b/plugins/trace_api_plugin/include/eosio/trace_api/abi_data_handler.hpp index d6c2355f59a..2277ef5f244 100644 --- a/plugins/trace_api_plugin/include/eosio/trace_api/abi_data_handler.hpp +++ b/plugins/trace_api_plugin/include/eosio/trace_api/abi_data_handler.hpp @@ -18,7 +18,7 @@ namespace eosio { */ class abi_data_handler { public: - explicit abi_data_handler( exception_handler except_handler = {} ) + explicit abi_data_handler( exception_handler except_handler ) :except_handler( std::move( except_handler ) ) { } @@ -37,7 +37,7 @@ namespace eosio { * @param yield - a yield function to allow cooperation during long running tasks * @return variant representing the `data` field of the action interpreted by known ABIs OR an empty variant */ - fc::variant process_data( const action_trace_v0& action, const yield_function& yield = {}); + fc::variant process_data( const action_trace_v0& action, const yield_function& yield ); /** * Utility class that allows mulitple request_handlers to share the same abi_data_handler @@ -48,7 +48,7 @@ namespace eosio { :handler(handler) {} - fc::variant process_data( const action_trace_v0& action, const yield_function& yield = {}) { + fc::variant process_data( const action_trace_v0& action, const yield_function& yield ) { return handler->process_data(action, yield); } diff --git a/plugins/trace_api_plugin/test/test_data_handlers.cpp b/plugins/trace_api_plugin/test/test_data_handlers.cpp index e1f521dc994..221d45e81d9 100644 --- a/plugins/trace_api_plugin/test/test_data_handlers.cpp +++ b/plugins/trace_api_plugin/test/test_data_handlers.cpp @@ -15,10 +15,10 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto action = action_trace_v0 { 0, "alice"_n, "alice"_n, "foo"_n, {}, {} }; - abi_data_handler handler; + abi_data_handler handler(exception_handler{}); auto expected = fc::variant(); - auto actual = handler.process_data(action); + auto actual = handler.process_data(action, [](){}); BOOST_TEST(to_kv(expected) == to_kv(actual), boost::test_tools::per_element()); } @@ -28,10 +28,10 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto action = action_trace_v0 { 0, "alice"_n, "alice"_n, "foo"_n, {}, {0x00, 0x01, 0x02, 0x03} }; - abi_data_handler handler; + abi_data_handler handler(exception_handler{}); auto expected = fc::variant(); - auto actual = handler.process_data(action); + auto actual = handler.process_data(action, [](){}); BOOST_TEST(to_kv(expected) == to_kv(actual), boost::test_tools::per_element()); } @@ -52,8 +52,8 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) {}, {}, {} ); abi.version = "eosio::abi/1."; - - abi_data_handler handler; + + abi_data_handler handler(exception_handler{}); handler.add_abi("alice"_n, abi); fc::variant expected = fc::mutable_variant_object() @@ -62,7 +62,7 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) ("c", 2) ("d", 3); - auto actual = handler.process_data(action); + auto actual = handler.process_data(action, [](){}); BOOST_TEST(to_kv(expected) == to_kv(actual), boost::test_tools::per_element()); } @@ -84,12 +84,12 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) ); abi.version = "eosio::abi/1."; - abi_data_handler handler; + abi_data_handler handler(exception_handler{}); handler.add_abi("alice"_n, abi); auto expected = fc::variant(); - auto actual = handler.process_data(action); + auto actual = handler.process_data(action, [](){}); BOOST_TEST(to_kv(expected) == to_kv(actual), boost::test_tools::per_element()); } @@ -117,7 +117,7 @@ BOOST_AUTO_TEST_SUITE(abi_data_handler_tests) auto expected = fc::variant(); - auto actual = handler.process_data(action); + auto actual = handler.process_data(action, [](){}); BOOST_TEST(to_kv(expected) == to_kv(actual), boost::test_tools::per_element()); BOOST_TEST(log_called); diff --git a/plugins/trace_api_plugin/trace_api_plugin.cpp b/plugins/trace_api_plugin/trace_api_plugin.cpp index 473b1e2c0d3..5e705e7a35b 100644 --- a/plugins/trace_api_plugin/trace_api_plugin.cpp +++ b/plugins/trace_api_plugin/trace_api_plugin.cpp @@ -184,15 +184,30 @@ struct trace_api_rpc_plugin_impl : public std::enable_shared_from_this( shared_store_provider(common->store), abi_data_handler::shared_provider(data_handler) ); } + fc::time_point calc_deadline( const fc::microseconds& max_serialization_time ) { + fc::time_point deadline = fc::time_point::now(); + if( max_serialization_time > fc::microseconds::maximum() - deadline.time_since_epoch() ) { + deadline = fc::time_point::maximum(); + } else { + deadline += max_serialization_time; + } + return deadline; + } + void plugin_startup() { auto& http = app().get_plugin(); - http.add_handler("/v1/trace_api/get_block", [wthis=weak_from_this()](std::string, std::string body, url_response_callback cb){ + fc::microseconds max_response_time = http.get_max_response_time(); + + http.add_handler("/v1/trace_api/get_block", + [wthis=weak_from_this(), max_response_time](std::string, std::string body, url_response_callback cb) + { auto that = wthis.lock(); if (!that) { return; @@ -223,7 +238,8 @@ struct trace_api_rpc_plugin_impl : public std::enable_shared_from_thisreq_handler->get_block_trace(*block_number); + const auto deadline = that->calc_deadline( max_response_time ); + auto resp = that->req_handler->get_block_trace(*block_number, [deadline]() { FC_CHECK_DEADLINE(deadline); }); if (resp.is_null()) { error_results results{404, "Block trace missing"}; cb( 404, fc::variant( results ));