Skip to content

Commit

Permalink
Add APIs to query for history of liquidity pools
Browse files Browse the repository at this point in the history
- get_liquidity_pool_history
- get_liquidity_pool_history_by_sequence
  • Loading branch information
abitmore committed Nov 10, 2020
1 parent d541f82 commit 5cc05fd
Show file tree
Hide file tree
Showing 5 changed files with 225 additions and 8 deletions.
121 changes: 121 additions & 0 deletions libraries/app/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -546,6 +546,127 @@ namespace graphene { namespace app {
return result;
} FC_CAPTURE_AND_RETHROW( (asset_a)(asset_b)(bucket_seconds)(start)(end) ) }

vector<liquidity_pool_history_object> history_api::get_liquidity_pool_history(
liquidity_pool_id_type pool_id,
optional<fc::time_point_sec> start,
optional<fc::time_point_sec> stop,
optional<uint32_t> olimit,
optional<int64_t> operation_type )const
{ try {
FC_ASSERT( _app.get_options().has_market_history_plugin, "Market history plugin is not enabled." );

uint32_t limit = olimit.valid() ? *olimit : 101;

const auto configured_limit = _app.get_options().api_limit_get_account_history_by_operations;
FC_ASSERT( limit <= configured_limit,
"limit can not be greater than ${configured_limit}",
("configured_limit", configured_limit) );

FC_ASSERT( _app.chain_database(), "Internal error: the chain database is not availalbe" );

const auto& db = *_app.chain_database();

vector<liquidity_pool_history_object> result;

if( limit == 0 || ( start.valid() && stop.valid() && *start <= *stop ) ) // empty result
return result;

const auto& hist_idx = db.get_index_type<liquidity_pool_history_index>();

if( operation_type.valid() ) // one operation type
{
const auto& idx = hist_idx.indices().get<by_pool_op_type_time>();
auto itr = start.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *operation_type, *start ) )
: idx.lower_bound( boost::make_tuple( pool_id, *operation_type ) );
auto itr_stop = stop.valid() ? idx.upper_bound( boost::make_tuple( pool_id, *operation_type, *stop ) )
: idx.upper_bound( boost::make_tuple( pool_id, *operation_type ) );
while( itr != itr_stop && result.size() < limit )
{
result.push_back( *itr );
++itr;
}
}
else // all operation types
{
const auto& idx = hist_idx.indices().get<by_pool_time>();
auto itr = start.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *start ) )
: idx.lower_bound( pool_id );
auto itr_stop = stop.valid() ? idx.upper_bound( boost::make_tuple( pool_id, *stop ) )
: idx.upper_bound( pool_id );
while( itr != itr_stop && result.size() < limit )
{
result.push_back( *itr );
++itr;
}
}

return result;

} FC_CAPTURE_AND_RETHROW( (pool_id)(start)(stop)(olimit)(operation_type) ) }

vector<liquidity_pool_history_object> history_api::get_liquidity_pool_history_by_sequence(
liquidity_pool_id_type pool_id,
optional<uint64_t> start,
optional<fc::time_point_sec> stop,
optional<uint32_t> olimit,
optional<int64_t> operation_type )const
{ try {
FC_ASSERT( _app.get_options().has_market_history_plugin, "Market history plugin is not enabled." );

uint32_t limit = olimit.valid() ? *olimit : 101;

const auto configured_limit = _app.get_options().api_limit_get_account_history_by_operations;
FC_ASSERT( limit <= configured_limit,
"limit can not be greater than ${configured_limit}",
("configured_limit", configured_limit) );

FC_ASSERT( _app.chain_database(), "Internal error: the chain database is not availalbe" );

const auto& db = *_app.chain_database();

vector<liquidity_pool_history_object> result;

if( limit == 0 ) // empty result
return result;

const auto& hist_idx = db.get_index_type<liquidity_pool_history_index>();

if( operation_type.valid() ) // one operation type
{
const auto& idx = hist_idx.indices().get<by_pool_op_type_seq>();
const auto& idx_t = hist_idx.indices().get<by_pool_op_type_time>();
auto itr = start.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *operation_type, *start ) )
: idx.lower_bound( boost::make_tuple( pool_id, *operation_type ) );
auto itr_temp = stop.valid() ? idx_t.upper_bound( boost::make_tuple( pool_id, *operation_type, *stop ) )
: idx_t.upper_bound( boost::make_tuple( pool_id, *operation_type ) );
auto itr_stop = ( itr_temp == idx_t.end() ? idx.end() : idx.iterator_to( *itr_temp ) );
while( itr != itr_stop && result.size() < limit )
{
result.push_back( *itr );
++itr;
}
}
else // all operation types
{
const auto& idx = hist_idx.indices().get<by_pool_seq>();
const auto& idx_t = hist_idx.indices().get<by_pool_time>();
auto itr = start.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *start ) )
: idx.lower_bound( pool_id );
auto itr_temp = stop.valid() ? idx_t.upper_bound( boost::make_tuple( pool_id, *stop ) )
: idx_t.upper_bound( pool_id );
auto itr_stop = ( itr_temp == idx_t.end() ? idx.end() : idx.iterator_to( *itr_temp ) );
while( itr != itr_stop && result.size() < limit )
{
result.push_back( *itr );
++itr;
}
}

return result;

} FC_CAPTURE_AND_RETHROW( (pool_id)(start)(stop)(olimit)(operation_type) ) }


crypto_api::crypto_api(){};

commitment_type crypto_api::blind( const blind_factor_type& blind, uint64_t value )
Expand Down
20 changes: 13 additions & 7 deletions libraries/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -326,11 +326,15 @@ void application_impl::set_api_limit() {
if(_options->count("api-limit-get-withdraw-permissions-by-recipient")) {
_app_options.api_limit_get_withdraw_permissions_by_recipient = _options->at("api-limit-get-withdraw-permissions-by-recipient").as<uint64_t>();
}
if(_options->count("api-limit-get-liquidity-pools")) {
if(_options->count("api-limit-get-tickets") > 0) {
_app_options.api_limit_get_tickets = _options->at("api-limit-get-tickets").as<uint64_t>();
}
if(_options->count("api-limit-get-liquidity-pools") > 0) {
_app_options.api_limit_get_liquidity_pools = _options->at("api-limit-get-liquidity-pools").as<uint64_t>();
}
if(_options->count("api-limit-get-tickets")) {
_app_options.api_limit_get_tickets = _options->at("api-limit-get-tickets").as<uint64_t>();
if(_options->count("api-limit-get-liquidity-pool-history") > 0) {
_app_options.api_limit_get_liquidity_pool_history =
_options->at("api-limit-get-liquidity-pool-history").as<uint64_t>();
}
}

Expand Down Expand Up @@ -1060,10 +1064,12 @@ void application::set_program_options(boost::program_options::options_descriptio
"For database_api_impl::get_withdraw_permissions_by_giver to set max limit value")
("api-limit-get-withdraw-permissions-by-recipient",boost::program_options::value<uint64_t>()->default_value(101),
"For database_api_impl::get_withdraw_permissions_by_recipient to set max limit value")
("api-limit-get-liquidity-pools",boost::program_options::value<uint64_t>()->default_value(101),
"For database_api_impl::get_liquidity_pools_* to set max limit value")
("api-limit-get-tickets",boost::program_options::value<uint64_t>()->default_value(101),
"For database_api_impl::get_tickets_* to set max limit value")
("api-limit-get-tickets", boost::program_options::value<uint64_t>()->default_value(101),
"Set maximum limit value for database APIs which query for tickets")
("api-limit-get-liquidity-pools", boost::program_options::value<uint64_t>()->default_value(101),
"Set maximum limit value for database APIs which query for liquidity pools")
("api-limit-get-liquidity-pool-history", boost::program_options::value<uint64_t>()->default_value(101),
"Set maximum limit value for APIs which query for history of liquidity pools")
;
command_line_options.add(configuration_file_options);
command_line_options.add_options()
Expand Down
61 changes: 61 additions & 0 deletions libraries/app/include/graphene/app/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,65 @@ namespace graphene { namespace app {
* it means this API server supports OHLCV data aggregated in 5-minute buckets.
*/
flat_set<uint32_t> get_market_history_buckets()const;

/**
* @brief Get history of a liquidity pool
* @param pool_id ID of the liquidity pool to query
* @param start A UNIX timestamp. Optional.
* If specified, only the operations occurred not later than this time will be returned.
* @param stop A UNIX timestamp. Optional.
* If specified, only the operations occurred later than this time will be returned.
* @param limit Maximum quantity of operations in the history to retrieve.
* Optional. If not specified, at most 101 records will be returned.
* @param operation_type Optional. If specified, only the operations whose type is the specified type
* will be returned. Otherwise all operations will be returned.
* @return operation history of the liquidity pool, ordered by time, most recent first.
*
* @note
* 1. The time must be UTC. The range is (stop, start].
* 2. In case when there are more than 100 operations occurred in the same second, this API only returns
* the most recent records, the rest records can be retrieved with the
* @ref get_liquidity_pool_history_by_sequence API.
* 3. List of operation type code: 59-creation, 60-deletion, 61-deposit, 62-withdrawal, 63-exchange.
* 4. Can only omit one or more arguments in the end of the list, but not one or more in the middle.
* If need to not specify an individual argument, can specify \c null in the place.
*/
vector<liquidity_pool_history_object> get_liquidity_pool_history(
liquidity_pool_id_type pool_id,
optional<fc::time_point_sec> start = optional<fc::time_point_sec>(),
optional<fc::time_point_sec> stop = optional<fc::time_point_sec>(),
optional<uint32_t> limit = 101,
optional<int64_t> operation_type = optional<int64_t>() )const;

/**
* @brief Get history of a liquidity pool
* @param pool_id ID of the liquidity pool to query
* @param start An Integer. Optional.
* If specified, only the operations whose sequences are not greater than this will be returned.
* @param stop A UNIX timestamp. Optional.
* If specified, only operations occurred later than this time will be returned.
* @param limit Maximum quantity of operations in the history to retrieve.
* Optional. If not specified, at most 101 records will be returned.
* @param operation_type Optional. If specified, only the operations whose type is the specified type
* will be returned. Otherwise all operations will be returned.
* @return operation history of the liquidity pool, ordered by time, most recent first.
*
* @note
* 1. The time must be UTC. The range is (stop, start].
* 2. In case when there are more than 100 operations occurred in the same second, this API only returns
* the most recent records, the rest records can be retrieved with the
* @ref get_liquidity_pool_history_by_sequence API.
* 3. List of operation type code: 59-creation, 60-deletion, 61-deposit, 62-withdrawal, 63-exchange.
* 4. Can only omit one or more arguments in the end of the list, but not one or more in the middle.
* If need to not specify an individual argument, can specify \c null in the place.
*/
vector<liquidity_pool_history_object> get_liquidity_pool_history_by_sequence(
liquidity_pool_id_type pool_id,
optional<uint64_t> start = optional<uint64_t>(),
optional<fc::time_point_sec> stop = optional<fc::time_point_sec>(),
optional<uint32_t> limit = 101,
optional<int64_t> operation_type = optional<int64_t>() )const;

private:
application& _app;
graphene::app::database_api database_api;
Expand Down Expand Up @@ -645,6 +704,8 @@ FC_API(graphene::app::history_api,
(get_fill_order_history)
(get_market_history)
(get_market_history_buckets)
(get_liquidity_pool_history)
(get_liquidity_pool_history_by_sequence)
)
FC_API(graphene::app::block_api,
(get_blocks)
Expand Down
3 changes: 2 additions & 1 deletion libraries/app/include/graphene/app/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ namespace graphene { namespace app {
uint64_t api_limit_get_trade_history_by_sequence = 100;
uint64_t api_limit_get_withdraw_permissions_by_giver = 101;
uint64_t api_limit_get_withdraw_permissions_by_recipient = 101;
uint64_t api_limit_get_liquidity_pools = 101;
uint64_t api_limit_get_tickets = 101;
uint64_t api_limit_get_liquidity_pools = 101;
uint64_t api_limit_get_liquidity_pool_history = 101;
};

class application
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ struct liquidity_pool_history_object : public abstract_object<liquidity_pool_his

struct by_pool_seq;
struct by_pool_time;
struct by_pool_op_type_seq;
struct by_pool_op_type_time;

typedef multi_index_container<
liquidity_pool_history_object,
Expand All @@ -262,6 +264,32 @@ typedef multi_index_container<
std::greater< time_point_sec >,
std::greater< uint64_t >
>
>,
ordered_unique< tag<by_pool_op_type_seq>,
composite_key< liquidity_pool_history_object,
member<liquidity_pool_history_object, liquidity_pool_id_type, &liquidity_pool_history_object::pool>,
member<liquidity_pool_history_object, int64_t, &liquidity_pool_history_object::op_type>,
member<liquidity_pool_history_object, uint64_t, &liquidity_pool_history_object::sequence>
>,
composite_key_compare<
std::less< liquidity_pool_id_type >,
std::less< int64_t >,
std::greater< uint64_t >
>
>,
ordered_unique< tag<by_pool_op_type_time>,
composite_key< liquidity_pool_history_object,
member<liquidity_pool_history_object, liquidity_pool_id_type, &liquidity_pool_history_object::pool>,
member<liquidity_pool_history_object, int64_t, &liquidity_pool_history_object::op_type>,
member<liquidity_pool_history_object, time_point_sec, &liquidity_pool_history_object::time>,
member<liquidity_pool_history_object, uint64_t, &liquidity_pool_history_object::sequence>
>,
composite_key_compare<
std::less< liquidity_pool_id_type >,
std::less< int64_t >,
std::greater< time_point_sec >,
std::greater< uint64_t >
>
>
>
> liquidity_pool_history_multi_index_type;
Expand Down

0 comments on commit 5cc05fd

Please sign in to comment.