Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add APIs to query for general asset info #1896

Draft
wants to merge 3 commits into
base: develop
Choose a base branch
from
Draft
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
17 changes: 17 additions & 0 deletions libraries/app/api_objects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,21 @@ market_ticker::market_ticker(const fc::time_point_sec& now,
quote_volume = "0";
}

general_asset_info::general_asset_info( const asset_object& a, const asset_bitasset_data_object* b )
: id(a.id), symbol(a.symbol), precision(a.precision), issuer(a.issuer)
{
if( id == asset_id_type() )
type = CORE;
else if( !b )
type = UIA;
else
{
if( b->is_prediction_market )
type = PM;
else
type = MPA;
backing_asset_id = b->options.short_backing_asset;
}
}

} } // graphene::app
150 changes: 150 additions & 0 deletions libraries/app/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -863,6 +863,30 @@ vector<optional<extended_asset_object>> database_api_impl::get_assets(
return result;
}

vector<optional<general_asset_info>> database_api::get_assets_general_info(
const vector<std::string>& asset_symbols_or_ids ) const
{
return my->get_assets_general_info( asset_symbols_or_ids );
}

vector<optional<general_asset_info>> database_api_impl::get_assets_general_info(
const vector<std::string>& asset_symbols_or_ids ) const
{
vector<optional<general_asset_info>> result; result.reserve(asset_symbols_or_ids.size());
std::transform(asset_symbols_or_ids.begin(), asset_symbols_or_ids.end(), std::back_inserter(result),
[this](std::string id_or_name) -> optional<general_asset_info> {

const asset_object* asset_obj = get_asset_from_string( id_or_name, false );
if( asset_obj == nullptr )
return {};
const asset_bitasset_data_object* bitasset = nullptr;
if( asset_obj->is_market_issued() )
bitasset = &asset_obj->bitasset_data(_db);
return general_asset_info( *asset_obj, bitasset );
});
return result;
}

vector<extended_asset_object> database_api::list_assets(const string& lower_bound_symbol, uint32_t limit)const
{
return my->list_assets( lower_bound_symbol, limit );
Expand All @@ -888,6 +912,132 @@ vector<extended_asset_object> database_api_impl::list_assets(const string& lower
return result;
}

vector<general_asset_info> database_api::list_assets_general_info(
optional<string> lower_bound_symbol,
optional<uint32_t> limit,
optional<general_asset_info::asset_type> type )const
{
return my->list_assets_general_info( lower_bound_symbol, limit, type );
}

vector<general_asset_info> database_api_impl::list_assets_general_info(
optional<string> lower_bound_symbol,
optional<uint32_t> olimit,
optional<general_asset_info::asset_type> type )const
{
uint32_t limit = olimit.valid() ? *olimit : 100;
uint64_t api_limit_get_assets = _app_options->api_limit_get_assets;
FC_ASSERT( limit <= api_limit_get_assets );

vector<general_asset_info> result;
if( limit == 0 )
return result;

result.reserve(limit);

if( !type.valid() || *type == general_asset_info::ALL )
{
const auto& assets_by_symbol = _db.get_index_type<asset_index>().indices().get<by_symbol>();
auto itr = lower_bound_symbol.valid() ? assets_by_symbol.lower_bound(*lower_bound_symbol)
: assets_by_symbol.begin();
for( ; limit > 0 && itr != assets_by_symbol.end(); ++itr, --limit )
{
const asset_object& asset_obj = *itr;
const asset_bitasset_data_object* bitasset = nullptr;
if( asset_obj.is_market_issued() )
bitasset = &asset_obj.bitasset_data(_db);
result.emplace_back( asset_obj, bitasset );
}
return result;
}

const asset_object& core_asset = _db.get_core_asset();
if( *type == general_asset_info::CORE )
{
if( !lower_bound_symbol.valid() || *lower_bound_symbol <= core_asset.symbol )
result.emplace_back( core_asset );
return result;
}

switch( *type )
{
case general_asset_info::UIA :
case general_asset_info::CORE_OR_UIA :
case general_asset_info::MPA_OR_PM :
{
const auto& assets_by_type_symbol = _db.get_index_type<asset_index>().indices().get<by_type_symbol>();
auto itr = assets_by_type_symbol.begin();
auto itr_end = assets_by_type_symbol.end();

if( *type == general_asset_info::MPA_OR_PM )
{
if( lower_bound_symbol.valid() )
itr = assets_by_type_symbol.lower_bound( boost::make_tuple( true, *lower_bound_symbol ) );
else
itr = assets_by_type_symbol.lower_bound( true );
}
else
{
itr_end = assets_by_type_symbol.lower_bound( true );
if( lower_bound_symbol.valid() )
itr = assets_by_type_symbol.lower_bound( boost::make_tuple( false, *lower_bound_symbol ) );
// else itr = assets_by_type_symbol.begin()
}

bool include_core = ( *type == general_asset_info::CORE_OR_UIA );
bool mpa_or_pm = ( *type == general_asset_info::MPA_OR_PM );

for( ; limit > 0 && itr != itr_end; ++itr )
{
const asset_object& asset_obj = *itr;
if( !include_core && (&asset_obj) == (&core_asset) )
continue;
const asset_bitasset_data_object* bitasset = nullptr;
if( mpa_or_pm )
bitasset = &asset_obj.bitasset_data(_db);
result.emplace_back( asset_obj, bitasset );
--limit;
}
break;
}
case general_asset_info::MPA :
case general_asset_info::PM :
{
const auto& bitassets_by_type_symbol = _db.get_index_type<asset_bitasset_data_index>().indices()
.get<by_type_symbol>();
auto itr = bitassets_by_type_symbol.begin();
auto itr_end = bitassets_by_type_symbol.end();

if( *type == general_asset_info::PM )
{
if( lower_bound_symbol.valid() )
itr = bitassets_by_type_symbol.lower_bound( boost::make_tuple( true, *lower_bound_symbol ) );
else
itr = bitassets_by_type_symbol.lower_bound( true );
}
else
{
itr_end = bitassets_by_type_symbol.lower_bound( true );
if( lower_bound_symbol.valid() )
itr = bitassets_by_type_symbol.lower_bound( boost::make_tuple( false, *lower_bound_symbol ) );
// else itr = bitassets_by_type_symbol.begin()
}

for( ; limit > 0 && itr != itr_end; ++itr, --limit )
{
const asset_bitasset_data_object& bitasset = *itr;
const asset_object& asset_obj = bitasset.asset_id(_db);
result.emplace_back( asset_obj, &bitasset );
}
break;
}
default: // nothing here
break;
}

return result;
}

uint64_t database_api::get_asset_count()const
{
return my->get_asset_count();
Expand Down
6 changes: 6 additions & 0 deletions libraries/app/database_api_impl.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,13 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
asset_id_type get_asset_id_from_string(const std::string& symbol_or_id)const;
vector<optional<extended_asset_object>> get_assets( const vector<std::string>& asset_symbols_or_ids,
optional<bool> subscribe )const;
vector<optional<general_asset_info>> get_assets_general_info(
const vector<std::string>& asset_symbols_or_ids ) const;
vector<extended_asset_object> list_assets(const string& lower_bound_symbol, uint32_t limit)const;
vector<general_asset_info> list_assets_general_info(
optional<string> lower_bound_symbol,
optional<uint32_t> limit,
optional<general_asset_info::asset_type> type )const;
vector<optional<extended_asset_object>> lookup_asset_symbols(const vector<string>& symbols_or_ids)const;
vector<extended_asset_object> get_assets_by_issuer(const std::string& issuer_name_or_id,
asset_id_type start, uint32_t limit)const;
Expand Down
31 changes: 31 additions & 0 deletions libraries/app/include/graphene/app/api_objects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,33 @@ namespace graphene { namespace app {
optional<share_type> total_backing_collateral;
};

/// General information of an asset
struct general_asset_info
{
/// General asset types
enum asset_type
{
CORE, ///< Core asset
UIA, ///< User-issued asset
MPA, ///< Market-pegged asset
PM, ///< Predition market
CORE_OR_UIA, ///< CORE or UIA, to be used as query parameter
MPA_OR_PM, ///< MPA or PM, to be used as query parameter
ALL ///< ALL, to be used as query parameter
};

general_asset_info() {}
explicit general_asset_info( const asset_object& a,
const asset_bitasset_data_object* b = nullptr );

asset_id_type id; ///< ID of this asset, i.e. "1.3.1"
string symbol; ///< Ticker symbol for this asset, i.e. "USD"
uint8_t precision = 0; ///< Maximum number of digits after the decimal point
account_id_type issuer; ///< ID of the account which created this asset
asset_type type; ///< Type of the asset
optional<asset_id_type> backing_asset_id; ///< ID of backing asset if this asset is a MPA or PM
};

} }

FC_REFLECT( graphene::app::more_data,
Expand Down Expand Up @@ -184,3 +211,7 @@ FC_REFLECT( graphene::app::market_trade, (sequence)(date)(price)(amount)(value)(

FC_REFLECT_DERIVED( graphene::app::extended_asset_object, (graphene::chain::asset_object),
(total_in_collateral)(total_backing_collateral) );

FC_REFLECT( graphene::app::general_asset_info, (id)(symbol)(precision)(issuer)(type)(backing_asset_id) )

FC_REFLECT_ENUM( graphene::app::general_asset_info::asset_type, (CORE)(UIA)(MPA)(PM)(CORE_OR_UIA)(MPA_OR_PM)(ALL) )
25 changes: 23 additions & 2 deletions libraries/app/include/graphene/app/database_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -386,13 +386,32 @@ class database_api
optional<bool> subscribe = optional<bool>() )const;

/**
* @brief Get assets alphabetically by symbol name
* @brief Get general info of a list of assets by symbol names or IDs
* @param asset_symbols_or_ids symbol names or IDs of the assets to retrieve
* @return General info of the assets corresponding to the provided symbol names or IDs
*/
vector<optional<general_asset_info>> get_assets_general_info(
const vector<std::string>& asset_symbols_or_ids ) const;

/**
* @brief Get assets alphabetically ordered by symbol name
* @param lower_bound_symbol Lower bound of symbol names to retrieve
* @param limit Maximum number of assets to fetch (must not exceed 101)
* @param limit Maximum number of assets to fetch
* @return The assets found
*/
vector<extended_asset_object> list_assets(const string& lower_bound_symbol, uint32_t limit)const;

/**
* @brief Get general info of assets alphabetically ordered by symbol name
* @param lower_bound_symbol Lower bound of symbol names to retrieve, optional, empty string if omitted
* @param limit Maximum number of assets to fetch, optional, @a 100 if omitted
* @param type type of assets to fetch, optional, @a ALL if omitted
* @return General info of the assets found
*/
vector<general_asset_info> list_assets_general_info( optional<string> lower_bound_symbol = {},
optional<uint32_t> limit = {},
optional<general_asset_info::asset_type> type = {} )const;

/**
* @brief Get a list of assets by symbol names or IDs
* @param symbols_or_ids symbol names or IDs of the assets to retrieve
Expand Down Expand Up @@ -943,7 +962,9 @@ FC_API(graphene::app::database_api,

// Assets
(get_assets)
(get_assets_general_info)
(list_assets)
(list_assets_general_info)
(lookup_asset_symbols)
(get_asset_count)
(get_assets_by_issuer)
Expand Down
1 change: 1 addition & 0 deletions libraries/chain/asset_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ object_id_type asset_create_evaluator::do_apply( const asset_create_operation& o
a.options = *op.bitasset_opts;
a.is_prediction_market = op.is_prediction_market;
a.asset_id = next_asset_id;
a.symbol = op.symbol;
}).id;

const asset_object& new_asset =
Expand Down
1 change: 1 addition & 0 deletions libraries/chain/asset_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::asset_dynamic_data_object, (gra

FC_REFLECT_DERIVED_NO_TYPENAME( graphene::chain::asset_bitasset_data_object, (graphene::db::object),
(asset_id)
(symbol)
(feeds)
(current_feed)
(current_feed_publication_time)
Expand Down
4 changes: 3 additions & 1 deletion libraries/chain/db_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -531,10 +531,12 @@ void database::init_genesis(const genesis_state_type& genesis_state)
++collateral_holder_number;
}

bitasset_data_id = create<asset_bitasset_data_object>([&core_asset,new_asset_id](asset_bitasset_data_object& b) {
bitasset_data_id = create<asset_bitasset_data_object>(
[&core_asset,new_asset_id,&asset](asset_bitasset_data_object& b) {
b.options.short_backing_asset = core_asset.id;
b.options.minimum_feeds = GRAPHENE_DEFAULT_MINIMUM_FEEDS;
b.asset_id = new_asset_id;
b.symbol = asset.symbol;
}).id;
}

Expand Down
Loading