diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index b01438cde3..3cec7094e4 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -606,6 +606,25 @@ namespace graphene { namespace app { return result; } + vector history_api::get_block_operations_by_time( + const optional& start ) const + { + FC_ASSERT( _app.chain_database(), "database unavailable" ); + const auto& db = *_app.chain_database(); + const auto& idx = db.get_index_type().indices().get(); + auto itr = start.valid() ? idx.lower_bound( *start ) : idx.begin(); + + vector result; + if( itr == idx.end() ) + return result; + + auto itr_end = idx.upper_bound( itr->block_time ); + + std::copy( itr, itr_end, std::back_inserter( result ) ); + + return result; + } + flat_set history_api::get_market_history_buckets()const { auto market_hist_plugin = _app.get_plugin( "market_history" ); diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index a4054b897f..ad92678ab2 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -171,22 +171,37 @@ namespace graphene { namespace app { uint64_t start = 0) const; /** - * @brief Get all operations inside a block or a transaction, including virtual operations + * @brief Get all operations within a block or a transaction, including virtual operations * @param block_num the number (height) of the block to fetch * @param trx_in_block the sequence of a transaction in the block, starts from @a 0, optional. * If specified, will return only operations of that transaction. * If omitted, will return all operations in the specified block. * @return a list of @a operation_history objects ordered by ID * - * @note the data is fetched from @a account_history plugin, thus the result is possible to - * be incomplete due to the @a partial-operations option configured in the API node. - * For complete data, it is recommended to query from ElasticSearch where data is - * maintained by @a elastic_search plugin. + * @note the data is fetched from the @a account_history plugin, so results may be + * incomplete due to the @a partial-operations option configured in the API node. + * To get complete data, it is recommended to query from ElasticSearch where the data is + * maintained by the @a elastic_search plugin. */ vector get_block_operation_history( uint32_t block_num, const optional& trx_in_block = {} ) const; + /** + * @brief Get all operations, including virtual operations, within the most recent block + * (no later than the specified time) containing at least one operation + * @param start time point, optional, if omitted, the data of the latest block containing at least + * one operation will be returned + * @return a list of @a operation_history objects ordered by ID in descending order + * + * @note the data is fetched from the @a account_history plugin, so results may be + * incomplete or incorrect due to the @a partial-operations option configured in the API node. + * To get complete data, it is recommended to query from ElasticSearch where the data is + * maintained by the @a elastic_search plugin. + */ + vector get_block_operations_by_time( + const optional& start = optional() ) const; + /** * @brief Get details of order executions occurred most recently in a trading pair * @param a Asset symbol or ID in a trading pair @@ -814,6 +829,7 @@ FC_API(graphene::app::history_api, (get_account_history_operations) (get_relative_account_history) (get_block_operation_history) + (get_block_operations_by_time) (get_fill_order_history) (get_market_history) (get_market_history_buckets) diff --git a/tests/tests/history_api_tests.cpp b/tests/tests/history_api_tests.cpp index 815f8a616d..143d2e3369 100644 --- a/tests/tests/history_api_tests.cpp +++ b/tests/tests/history_api_tests.cpp @@ -96,6 +96,42 @@ BOOST_AUTO_TEST_CASE(get_account_history) { histories = hist_api.get_block_operation_history(head_block_num, 1u); BOOST_CHECK_EQUAL(histories.size(), 1u); + // get_block_operations_by_time + auto time1 = db.head_block_time(); + histories = hist_api.get_block_operations_by_time(time1); + BOOST_CHECK_EQUAL(histories.size(), 3u); + + histories = hist_api.get_block_operations_by_time(time1 + fc::seconds(1)); + BOOST_CHECK_EQUAL(histories.size(), 3u); + + histories = hist_api.get_block_operations_by_time(time1 - fc::seconds(1)); + BOOST_CHECK_EQUAL(histories.size(), 0u); + + generate_block(); + auto time2 = db.head_block_time(); + + histories = hist_api.get_block_operations_by_time(time1); + BOOST_CHECK_EQUAL(histories.size(), 3u); + + histories = hist_api.get_block_operations_by_time(time1 - fc::seconds(1)); + BOOST_CHECK_EQUAL(histories.size(), 0u); + + histories = hist_api.get_block_operations_by_time(time2); + BOOST_CHECK_EQUAL(histories.size(), 3u); + + create_bitasset("USX", account_id_type()); + generate_block(); + auto time3 = db.head_block_time(); + + histories = hist_api.get_block_operations_by_time(time2); + BOOST_CHECK_EQUAL(histories.size(), 3u); + + histories = hist_api.get_block_operations_by_time(time3); + BOOST_CHECK_EQUAL(histories.size(), 1u); + + histories = hist_api.get_block_operations_by_time(time3 + fc::seconds(1)); + BOOST_CHECK_EQUAL(histories.size(), 1u); + } catch (fc::exception &e) { edump((e.to_detail_string())); throw;