31 #include <graphene/chain/hardfork.hpp>
38 #include <boost/range/iterator_range.hpp>
60 :_db(db), _app_options(app_options)
65 :_db( *app.chain_database() ), _app_options( &app.get_options() )
72 dlog(
"creating database api ${x}", (
"x",int64_t(
this)) );
74 const flat_set<account_id_type>& impacted_accounts) {
78 const flat_set<account_id_type>& impacted_accounts) {
82 const vector<const object*>& objs,
83 const flat_set<account_id_type>& impacted_accounts) {
95 .get_secondary_index<graphene::api_helper_indexes::amount_in_collateral_index>();
97 catch(
const fc::assert_exception& )
105 .get_secondary_index<graphene::api_helper_indexes::asset_in_liquidity_pools_index>();
107 catch(
const fc::assert_exception& )
115 .get_secondary_index<graphene::api_helper_indexes::next_object_ids_index>();
117 catch(
const fc::assert_exception& )
126 dlog(
"freeing database api ${x}", (
"x",int64_t(
this)) );
137 return my->get_objects( ids, subscribe );
145 result.reserve(ids.size());
147 std::transform(ids.begin(), ids.end(), std::back_inserter(result),
148 [
this,to_subscribe](object_id_type
id) ->
fc::variant {
149 if(auto obj = _db.find_object(id))
151 if( to_subscribe && !id.is<operation_history_id_type>() && !id.is<account_history_id_type>() )
152 this->subscribe_to_item( id );
153 return obj->to_variant();
169 my->set_subscribe_callback( cb, notify_remove_create );
174 if( notify_remove_create )
177 "Subscribing to universal object creation and removal is disallowed in this server." );
188 my->set_auto_subscription( enable );
198 my->set_pending_transaction_callback( cb );
208 my->set_block_applied_callback( cb );
218 my->cancel_all_subscriptions(
true,
true);
223 if ( reset_callback )
226 if ( reset_market_subscriptions )
242 uint32_t block_num,
const optional<bool>& with_witness_signature )
const
244 bool with_signature = ( with_witness_signature.valid() && *with_witness_signature );
245 return my->get_block_header( block_num, with_signature );
249 uint32_t block_num,
bool with_witness_signature )
const
258 const vector<uint32_t>& block_nums,
const optional<bool>& with_witness_signatures )
const
260 bool with_signatures = ( with_witness_signatures.valid() && *with_witness_signatures );
261 return my->get_block_header_batch( block_nums, with_signatures );
265 const vector<uint32_t>& block_nums,
bool with_witness_signatures )
const
267 map<uint32_t, optional<maybe_signed_block_header>> results;
268 for (
const uint32_t block_num : block_nums)
270 results[block_num] =
get_block_header( block_num, with_witness_signatures );
277 return my->get_block( block_num );
287 return my->get_transaction( block_num, trx_in_block );
293 return my->_db.get_recent_transaction(
id );
295 return optional<signed_transaction>();
303 FC_ASSERT( opt_block->transactions.size() > trx_num );
304 return opt_block->transactions[trx_num];
315 return my->get_chain_properties();
320 return _db.
get(chain_property_id_type());
325 return my->get_global_properties();
330 return _db.
get(global_property_id_type());
335 return my->get_config();
345 return my->get_chain_id();
355 return my->get_dynamic_global_properties();
360 return _db.
get(dynamic_global_property_id_type());
364 bool with_pending_transactions )
const
366 return my->get_next_object_id( space_id, type_id, with_pending_transactions );
370 bool with_pending_transactions )
const
372 if( with_pending_transactions )
388 return my->get_key_references( key );
398 "api_helper_indexes plugin is not enabled on this server." );
401 FC_ASSERT( keys.size() <= configured_limit,
402 "Number of querying keys can not be greater than ${configured_limit}",
403 (
"configured_limit", configured_limit) );
409 vector< flat_set<account_id_type> > final_result;
410 final_result.reserve(keys.size());
412 for(
auto& key : keys )
420 flat_set<account_id_type> result;
422 for(
auto& a : {a1,a2,a3,a4,a5} )
424 auto itr = refs.account_to_address_memberships.find(a);
425 if( itr != refs.account_to_address_memberships.end() )
427 result.reserve( result.size() + itr->second.size() );
428 for(
auto item : itr->second )
435 auto itr = refs.account_to_key_memberships.find(key);
436 if( itr != refs.account_to_key_memberships.end() )
438 result.reserve( result.size() + itr->second.size() );
439 for(
auto item : itr->second ) result.insert(item);
441 final_result.emplace_back( std::move(result) );
449 return my->is_public_key_registered(public_key);
455 if (public_key.empty()) {
462 key = public_key_type(public_key);
470 "api_helper_indexes plugin is not enabled on this server." );
489 return my->get_account_from_string( name_or_id )->get_id();
493 optional<bool> subscribe )
const
495 return my->get_accounts( account_names_or_ids, subscribe );
499 optional<bool> subscribe )
const
502 vector<optional<account_object>> result; result.reserve(account_names_or_ids.size());
503 std::transform(account_names_or_ids.begin(), account_names_or_ids.end(), std::back_inserter(result),
504 [
this,to_subscribe](std::string id_or_name) -> optional<account_object> {
506 const account_object *account = get_account_from_string(id_or_name, false);
507 if(account == nullptr)
517 const optional<bool>& subscribe )
const
519 return my->get_full_accounts( names_or_ids, subscribe );
523 const vector<std::string>& names_or_ids,
const optional<bool>& subscribe )
527 FC_ASSERT( names_or_ids.size() <= configured_limit,
528 "Number of querying accounts can not be greater than ${configured_limit}",
529 (
"configured_limit", configured_limit) );
533 std::map<std::string, full_account, std::less<>> results;
535 for (
const std::string& account_name_or_id : names_or_ids)
561 size_t api_limit_get_full_accounts_lists =
static_cast<size_t>(
571 auto required_approvals_itr = proposals_by_account._account_to_proposals.
find( account->
get_id() );
572 if( required_approvals_itr != proposals_by_account._account_to_proposals.end() )
574 acnt.
proposals.reserve( std::min(required_approvals_itr->second.size(),
575 api_limit_get_full_accounts_lists) );
576 for(
auto proposal_id : required_approvals_itr->second )
578 if(acnt.
proposals.size() >= api_limit_get_full_accounts_lists) {
589 get_secondary_index< balances_by_account_index >().get_account_balances( account->
get_id() );
590 for(
const auto& balance : balances )
592 if(acnt.
balances.size() >= api_limit_get_full_accounts_lists) {
596 acnt.
balances.emplace_back(*balance.second);
601 .equal_range(account->
get_id());
602 for(
auto itr = vesting_range.first; itr != vesting_range.second; ++itr)
613 .equal_range(account->
get_id());
614 for(
auto itr = order_range.first; itr != order_range.second; ++itr)
616 if(acnt.
limit_orders.size() >= api_limit_get_full_accounts_lists) {
623 .equal_range(account->
get_id());
624 for(
auto itr = call_range.first; itr != call_range.second; ++itr)
626 if(acnt.
call_orders.size() >= api_limit_get_full_accounts_lists) {
633 .equal_range(account->
get_id());
634 for(
auto itr = settle_range.first; itr != settle_range.second; ++itr)
636 if(acnt.
settle_orders.size() >= api_limit_get_full_accounts_lists) {
645 for(
auto itr = asset_range.first; itr != asset_range.second; ++itr)
647 if(acnt.
assets.size() >= api_limit_get_full_accounts_lists) {
651 acnt.
assets.emplace_back(itr->get_id());
656 auto withdraw_from_range = withdraw_indices.get<by_from>().equal_range(account->
get_id());
657 for(
auto itr = withdraw_from_range.first; itr != withdraw_from_range.second; ++itr)
659 if(acnt.
withdraws_from.size() >= api_limit_get_full_accounts_lists) {
665 auto withdraw_authorized_range = withdraw_indices.get<by_authorized>().equal_range(account->
get_id());
666 for(
auto itr = withdraw_authorized_range.first; itr != withdraw_authorized_range.second; ++itr)
668 if(acnt.
withdraws_to.size() >= api_limit_get_full_accounts_lists) {
677 .equal_range(account->
get_id());
678 for(
auto itr = htlc_from_range.first; itr != htlc_from_range.second; ++itr)
680 if(acnt.
htlcs_from.size() >= api_limit_get_full_accounts_lists) {
687 for(
auto itr = htlc_to_range.first; itr != htlc_to_range.second; ++itr)
689 if(acnt.
htlcs_to.size() >= api_limit_get_full_accounts_lists) {
696 results[account_name_or_id] = acnt;
703 return my->get_top_voters( limit );
711 "limit can not be greater than ${configured_limit}",
712 (
"configured_limit", configured_limit) );
714 vector<account_statistics_object> result;
719 for(
auto itr = idx.begin(); result.size() < limit && itr != idx.end() && itr->vote_tally_time >= last_vote_tally_time; ++itr)
721 result.emplace_back(*itr);
729 return my->get_account_by_name( name );
735 auto itr = idx.find(name);
736 if (itr != idx.end())
738 return optional<account_object>();
743 return my->get_account_references( account_id_or_name );
750 "api_helper_indexes plugin is not enabled on this server." );
756 auto itr = refs.account_to_account_memberships.find(account_id);
757 vector<account_id_type> result;
759 if( itr != refs.account_to_account_memberships.end() )
761 result.reserve( itr->second.size() );
762 for(
auto item : itr->second ) result.push_back(item);
769 return my->lookup_account_names( account_names );
779 const optional<bool>& subscribe )
const
781 return my->lookup_accounts( lower_bound_name, limit, subscribe );
786 const optional<bool>& subscribe )
const
791 "limit can not be greater than ${configured_limit}",
792 (
"configured_limit", configured_limit) );
795 map<string, account_id_type, std::less<>> result;
801 for(
auto itr = accounts_by_name.lower_bound(lower_bound_name);
802 limit > 0 && itr != accounts_by_name.end();
805 result.insert(make_pair(itr->name, itr->get_id()));
815 return my->get_account_count();
830 const flat_set<asset_id_type>& assets )
const
832 return my->get_account_balances( account_name_or_id, assets );
836 const flat_set<asset_id_type>& assets )
const
839 account_id_type acnt = account->
get_id();
840 vector<asset> result;
847 for(
const auto& balance : balances )
848 result.push_back( balance.second->get_balance() );
852 result.reserve(assets.size());
854 std::transform(assets.begin(), assets.end(), std::back_inserter(result),
855 [
this, acnt](asset_id_type
id) { return _db.get_balance(acnt, id); });
862 const flat_set<asset_id_type>& assets )
const
864 return my->get_account_balances( name, assets );
869 return my->get_balance_objects( addrs );
877 const auto& by_owner_idx = bal_idx.
indices().get<by_owner>();
879 vector<balance_object> result;
881 for(
const auto& owner : addrs )
883 auto itr = by_owner_idx.lower_bound( boost::make_tuple( owner, asset_id_type(0) ) );
884 while( itr != by_owner_idx.end() && itr->owner == owner )
886 result.push_back( *itr );
897 return my->get_vested_balances( objs );
904 vector<asset> result;
905 result.reserve( objs.size() );
907 for(
auto obj : objs )
908 result.push_back( obj(
_db).available( now ) );
915 return my->get_vesting_balances( account_id_or_name );
923 vector<vesting_balance_object> result;
925 .equal_range(account_id);
928 result.emplace_back(balance);
943 return my->get_asset_from_string( symbol_or_id )->get_id();
947 const vector<std::string>& asset_symbols_or_ids,
948 optional<bool> subscribe )
const
950 return my->get_assets( asset_symbols_or_ids, subscribe );
954 const vector<std::string>& asset_symbols_or_ids,
955 optional<bool> subscribe )
const
958 vector<optional<extended_asset_object>> result; result.reserve(asset_symbols_or_ids.size());
959 std::transform(asset_symbols_or_ids.begin(), asset_symbols_or_ids.end(), std::back_inserter(result),
960 [
this,to_subscribe](std::string id_or_name) -> optional<extended_asset_object> {
962 const asset_object* asset_obj = get_asset_from_string( id_or_name, false );
963 if( asset_obj == nullptr )
974 return my->list_assets( lower_bound_symbol, limit );
982 "limit can not be greater than ${configured_limit}",
983 (
"configured_limit", configured_limit) );
986 vector<extended_asset_object> result;
987 result.reserve(limit);
989 auto itr = assets_by_symbol.lower_bound(lower_bound_symbol);
990 auto end = assets_by_symbol.end();
991 for( ; limit > 0 && itr != end; ++itr, --limit )
999 return my->get_asset_count();
1008 asset_id_type start, uint32_t limit)
const
1010 return my->get_assets_by_issuer(issuer_name_or_id, start, limit);
1014 asset_id_type start, uint32_t limit)
const
1019 "limit can not be greater than ${configured_limit}",
1020 (
"configured_limit", configured_limit) );
1022 vector<extended_asset_object> result;
1025 auto asset_index_end = asset_idx.end();
1026 auto asset_itr = asset_idx.lower_bound(boost::make_tuple(account, object_id_type(start)));
1027 while(asset_itr != asset_index_end && asset_itr->issuer == account && result.size() < limit)
1036 const vector<string>& symbols_or_ids )
const
1038 return my->lookup_asset_symbols( symbols_or_ids );
1042 const vector<string>& symbols_or_ids )
const
1055 return my->get_limit_orders( a, b, limit );
1059 uint32_t limit )
const
1064 "limit can not be greater than ${configured_limit}",
1065 (
"configured_limit", configured_limit) );
1074 const optional<uint32_t>& limit,
const optional<limit_order_id_type>& start_id )
1076 return my->get_limit_orders_by_account( account_name_or_id, limit, start_id );
1080 const optional<uint32_t>& olimit,
const optional<limit_order_id_type>& ostart_id )
1084 uint32_t limit = olimit.valid() ? *olimit : configured_limit;
1086 "limit can not be greater than ${configured_limit}",
1087 (
"configured_limit", configured_limit) );
1089 vector<limit_order_object> results;
1092 if (account ==
nullptr)
1095 limit_order_id_type start_order_id = ostart_id.valid() ? *ostart_id : limit_order_id_type();
1096 object_id_type start_id { start_order_id };
1099 auto lower_itr = index_by_account.lower_bound( std::make_tuple( account->
get_id(), start_id ) );
1100 auto upper_itr = index_by_account.upper_bound( account->
get_id() );
1102 results.reserve( limit );
1104 for ( ; lower_itr != upper_itr && count < limit; ++lower_itr, ++count)
1107 results.emplace_back(
order);
1114 const string& account_name_or_id,
const string &base,
const string "e,
1115 uint32_t limit, optional<limit_order_id_type> ostart_id, optional<price> ostart_price )
1117 return my->get_account_limit_orders( account_name_or_id, base, quote, limit, ostart_id, ostart_price );
1121 const string& account_name_or_id,
const string &base,
const string "e,
1122 uint32_t limit, optional<limit_order_id_type> ostart_id, optional<price> ostart_price )
1127 "limit can not be greater than ${configured_limit}",
1128 (
"configured_limit", configured_limit) );
1130 vector<limit_order_object> results;
1134 if (account ==
nullptr)
1138 FC_ASSERT( assets[0],
"Invalid base asset symbol: ${s}", (
"s",base) );
1139 FC_ASSERT( assets[1],
"Invalid quote asset symbol: ${s}", (
"s",quote) );
1141 auto base_id = assets[0]->get_id();
1142 auto quote_id = assets[1]->get_id();
1144 if (ostart_price.valid()) {
1145 FC_ASSERT(ostart_price->base.asset_id == base_id,
"Base asset inconsistent with start price");
1146 FC_ASSERT(ostart_price->quote.asset_id == quote_id,
"Quote asset inconsistent with start price");
1150 limit_order_multi_index_type::index<by_account_price>::type::const_iterator lower_itr;
1151 limit_order_multi_index_type::index<by_account_price>::type::const_iterator upper_itr;
1154 if ( !ostart_id.valid() && !ostart_price.valid() )
1156 lower_itr = index_by_account.lower_bound(std::make_tuple(account->
get_id(),
price::max(base_id, quote_id)));
1158 else if ( ostart_id.valid() )
1160 object_id_type start_id { *ostart_id };
1166 if ( ostart_price.valid() )
1168 lower_itr = index_by_account.lower_bound(std::make_tuple(account->
get_id(), *ostart_price, start_id));
1173 FC_THROW(
"Order id invalid (maybe just been canceled?), and start price not provided");
1185 lower_itr = index_by_account.lower_bound(std::make_tuple(account->
get_id(), loo.
sell_price, start_id));
1191 lower_itr = index_by_account.lower_bound(std::make_tuple(account->
get_id(), *ostart_price));
1194 upper_itr = index_by_account.upper_bound(std::make_tuple(account->
get_id(),
price::min(base_id, quote_id)));
1197 for ( ; lower_itr != upper_itr && count < limit; ++lower_itr, ++count)
1200 results.emplace_back(
order);
1208 return my->get_call_orders( a, limit );
1216 "limit can not be greater than ${configured_limit}",
1217 (
"configured_limit", configured_limit) );
1223 vector< call_order_object> result;
1224 auto itr_min = call_index.lower_bound(index_price);
1225 auto itr_max = call_index.upper_bound(index_price.max());
1226 while( itr_min != itr_max && result.size() < limit )
1228 result.emplace_back(*itr_min);
1235 asset_id_type start, uint32_t limit)
const
1237 return my->get_call_orders_by_account( account_name_or_id, start, limit );
1241 asset_id_type start, uint32_t limit)
const
1246 "limit can not be greater than ${configured_limit}",
1247 (
"configured_limit", configured_limit) );
1249 vector<call_order_object> result;
1252 auto call_index_end = call_idx.end();
1253 auto call_itr = call_idx.lower_bound(boost::make_tuple(account, start));
1254 while(call_itr != call_index_end && call_itr->borrower == account && result.size() < limit)
1256 result.push_back(*call_itr);
1264 return my->get_settle_orders( a, limit );
1272 "limit can not be greater than ${configured_limit}",
1273 (
"configured_limit", configured_limit) );
1279 vector<force_settlement_object> result;
1280 auto itr_min = settle_index.lower_bound(mia.get_id());
1281 auto itr_max = settle_index.upper_bound(mia.get_id());
1282 while( itr_min != itr_max && result.size() < limit )
1284 result.emplace_back(*itr_min);
1291 const std::string& account_name_or_id,
1292 force_settlement_id_type start,
1293 uint32_t limit )
const
1295 return my->get_settle_orders_by_account( account_name_or_id, start, limit);
1299 const std::string& account_name_or_id,
1300 force_settlement_id_type start,
1301 uint32_t limit )
const
1306 "limit can not be greater than ${configured_limit}",
1307 (
"configured_limit", configured_limit) );
1309 vector<force_settlement_object> result;
1312 auto settle_index_end = settle_idx.end();
1313 auto settle_itr = settle_idx.lower_bound(boost::make_tuple(account, object_id_type(start)));
1314 while(settle_itr != settle_index_end && settle_itr->owner == account && result.size() < limit)
1316 result.push_back(*settle_itr);
1325 FC_ASSERT( my->_app_options,
"Internal error" );
1326 return my->get_call_orders_by_account( account_name_or_id, asset_id_type(),
1327 my->_app_options->api_limit_get_call_orders );
1331 uint32_t limit, uint32_t start )
const
1333 return my->get_collateral_bids(
asset, limit, start );
1337 uint32_t limit, uint32_t skip )
const
1342 "limit can not be greater than ${configured_limit}",
1343 (
"configured_limit", configured_limit) );
1347 const asset_id_type asset_id = swan.
get_id();
1349 auto itr = idx.lower_bound( asset_id );
1350 auto end = idx.upper_bound( asset_id );
1351 vector<collateral_bid_object> result;
1352 while( skip > 0 && itr != end ) { ++itr; --skip; }
1353 for( ; itr != end && limit > 0; ++itr, --limit )
1355 result.push_back(*itr);
1361 const std::string& a,
const std::string& b )
1363 my->subscribe_to_market( callback, a, b );
1367 const std::string& a,
const std::string& b )
1372 if(asset_a_id > asset_b_id) std::swap(asset_a_id,asset_b_id);
1379 my->unsubscribe_from_market( a, b );
1387 if(a > b) std::swap(asset_a_id,asset_b_id);
1394 return my->get_ticker( base, quote );
1403 FC_ASSERT( assets[0],
"Invalid base asset symbol: ${s}", (
"s",base) );
1404 FC_ASSERT( assets[1],
"Invalid quote asset symbol: ${s}", (
"s",quote) );
1406 auto base_id = assets[0]->get_id();
1407 auto quote_id = assets[1]->get_id();
1408 if( base_id > quote_id ) std::swap( base_id, quote_id );
1410 auto itr = ticker_idx.find( std::make_tuple( base_id, quote_id ) );
1412 if( itr != ticker_idx.end() )
1415 if (!skip_order_book)
1417 orders =
get_order_book(assets[0]->symbol, assets[1]->symbol, 1);
1419 return market_ticker(*itr, now, *assets[0], *assets[1], orders);
1423 return empty_result;
1428 return my->get_24_volume( base, quote );
1433 const auto& ticker =
get_ticker( base, quote,
true );
1436 result.
time = ticker.time;
1437 result.
base = ticker.base;
1438 result.
quote = ticker.quote;
1447 return my->get_order_book( base, quote, limit );
1455 "limit can not be greater than ${configured_limit}",
1456 (
"configured_limit", configured_limit) );
1461 FC_ASSERT( assets[0],
"Invalid base asset symbol: ${s}", (
"s",base) );
1462 FC_ASSERT( assets[1],
"Invalid quote asset symbol: ${s}", (
"s",quote) );
1464 auto base_id = assets[0]->get_id();
1465 auto quote_id = assets[1]->get_id();
1468 for(
const auto& o : orders )
1470 auto order_price =
price_to_string( o.sell_price, *assets[0], *assets[1] );
1471 if( o.sell_price.base.asset_id == base_id )
1473 auto quote_amt = assets[1]->amount_to_string(
share_type( fc::uint128_t( o.for_sale.value )
1474 * o.sell_price.quote.amount.value
1475 / o.sell_price.base.amount.value ) );
1476 auto base_amt = assets[0]->amount_to_string( o.for_sale );
1477 result.
bids.emplace_back( order_price, quote_amt, base_amt, o.get_id(),
1478 o.seller, o.seller(
_db).name, o.expiration );
1482 auto quote_amt = assets[1]->amount_to_string( o.for_sale );
1483 auto base_amt = assets[0]->amount_to_string(
share_type( fc::uint128_t( o.for_sale.value )
1484 * o.sell_price.quote.amount.value
1485 / o.sell_price.base.amount.value ) );
1486 result.
asks.emplace_back( order_price, quote_amt, base_amt, o.get_id(),
1487 o.seller, o.seller(
_db).name, o.expiration );
1496 return my->get_top_markets(limit);
1505 "limit can not be greater than ${configured_limit}",
1506 (
"configured_limit", configured_limit) );
1509 auto itr = volume_idx.rbegin();
1510 vector<market_ticker> result;
1511 result.reserve(limit);
1514 while( itr != volume_idx.rend() && result.size() < limit)
1521 result.emplace_back(
market_ticker(*itr, now, base, quote, orders));
1528 const string& quote,
1531 uint32_t limit )
const
1533 return my->get_trade_history( base, quote, start, stop, limit );
1537 const string& quote,
1540 uint32_t limit )
const
1546 "limit can not be greater than ${configured_limit}",
1547 (
"configured_limit", configured_limit) );
1550 FC_ASSERT( assets[0],
"Invalid base asset symbol: ${s}", (
"s",base) );
1551 FC_ASSERT( assets[1],
"Invalid quote asset symbol: ${s}", (
"s",quote) );
1553 auto base_id = assets[0]->get_id();
1554 auto quote_id = assets[1]->get_id();
1556 if( base_id > quote_id ) std::swap( base_id, quote_id );
1563 auto itr = history_idx.lower_bound( std::make_tuple( base_id, quote_id, start ) );
1564 vector<market_trade> result;
1566 while( itr != history_idx.end() && count < limit
1567 && !( itr->key.base != base_id || itr->key.quote != quote_id || itr->time < stop ) )
1572 if( assets[0]->
id == itr->op.receives.asset_id )
1574 trade.
amount = assets[1]->amount_to_string( itr->op.pays );
1575 trade.
value = assets[0]->amount_to_string( itr->op.receives );
1579 trade.
amount = assets[1]->amount_to_string( itr->op.receives );
1580 trade.
value = assets[0]->amount_to_string( itr->op.pays );
1583 trade.
date = itr->time;
1586 if( itr->op.is_maker )
1588 trade.
sequence = -itr->key.sequence;
1590 if(itr->op.receives.asset_id == assets[0]->id)
1591 trade.
type =
"sell";
1598 auto next_itr = std::next(itr);
1600 if( next_itr != history_idx.end() && next_itr->key.base == base_id && next_itr->key.quote == quote_id
1601 && next_itr->time == itr->time && next_itr->op.is_maker != itr->op.is_maker )
1603 if( next_itr->op.is_maker )
1605 trade.
sequence = -next_itr->key.sequence;
1607 if(next_itr->op.receives.asset_id == assets[0]->id)
1608 trade.
type =
"sell";
1618 result.push_back( trade );
1630 const string& quote,
1633 uint32_t limit )
const
1635 return my->get_trade_history_by_sequence( base, quote, start, stop, limit );
1640 const string& quote,
1643 uint32_t limit )
const
1649 "limit can not be greater than ${configured_limit}",
1650 (
"configured_limit", configured_limit) );
1653 int64_t start_seq = -start;
1656 FC_ASSERT( assets[0],
"Invalid base asset symbol: ${s}", (
"s",base) );
1657 FC_ASSERT( assets[1],
"Invalid quote asset symbol: ${s}", (
"s",quote) );
1659 auto base_id = assets[0]->get_id();
1660 auto quote_id = assets[1]->get_id();
1662 if( base_id > quote_id ) std::swap( base_id, quote_id );
1665 hkey.
base = base_id;
1666 hkey.quote = quote_id;
1667 hkey.sequence = start_seq;
1670 auto itr = history_idx.lower_bound( hkey );
1671 vector<market_trade> result;
1673 while( itr != history_idx.end() && count < limit
1674 && !( itr->key.base != base_id || itr->key.quote != quote_id || itr->time < stop ) )
1676 if( itr->key.sequence == start_seq )
1678 auto next_itr = std::next(itr);
1679 if( next_itr != history_idx.end() && next_itr->key.base == base_id && next_itr->key.quote == quote_id
1680 && next_itr->time == itr->time && next_itr->op.is_maker != itr->op.is_maker )
1690 if( assets[0]->
id == itr->op.receives.asset_id )
1692 trade.
amount = assets[1]->amount_to_string( itr->op.pays );
1693 trade.
value = assets[0]->amount_to_string( itr->op.receives );
1697 trade.
amount = assets[1]->amount_to_string( itr->op.receives );
1698 trade.
value = assets[0]->amount_to_string( itr->op.pays );
1701 trade.
date = itr->time;
1704 if( itr->op.is_maker )
1706 trade.
sequence = -itr->key.sequence;
1708 if(itr->op.receives.asset_id == assets[0]->id)
1709 trade.
type =
"sell";
1716 auto next_itr = std::next(itr);
1718 if( next_itr != history_idx.end() && next_itr->key.base == base_id && next_itr->key.quote == quote_id
1719 && next_itr->time == itr->time && next_itr->op.is_maker != itr->op.is_maker )
1721 if( next_itr->op.is_maker )
1723 trade.
sequence = -next_itr->key.sequence;
1725 if(next_itr->op.receives.asset_id == assets[0]->id)
1726 trade.
type =
"sell";
1736 result.push_back( trade );
1753 const optional<uint32_t>& limit,
1754 const optional<liquidity_pool_id_type>& start_id,
1755 const optional<bool>& with_statistics )
const
1757 return my->get_liquidity_pools_by_asset_x<by_id>(
1764 const std::string& asset_symbol_or_id,
1765 const optional<uint32_t>& limit,
1766 const optional<liquidity_pool_id_type>& start_id,
1767 const optional<bool>& with_statistics )
const
1769 asset_id_type asset_id = my->get_asset_from_string(asset_symbol_or_id)->get_id();
1770 return my->get_liquidity_pools_by_asset_x<by_asset_a>(
1778 const std::string& asset_symbol_or_id,
1779 const optional<uint32_t>& limit,
1780 const optional<liquidity_pool_id_type>& start_id,
1781 const optional<bool>& with_statistics )
const
1783 asset_id_type asset_id = my->get_asset_from_string(asset_symbol_or_id)->get_id();
1784 return my->get_liquidity_pools_by_asset_x<by_asset_b>(
1792 const std::string& asset_symbol_or_id,
1793 const optional<uint32_t>& limit,
1794 const optional<liquidity_pool_id_type>& start_id,
1795 const optional<bool>& with_statistics )
const
1797 return my->get_liquidity_pools_by_one_asset(
1805 const std::string& asset_symbol_or_id,
1806 const optional<uint32_t>& olimit,
1807 const optional<liquidity_pool_id_type>& ostart_id,
1808 const optional<bool>& with_statistics )
const
1812 "api_helper_indexes plugin is not enabled on this server." );
1815 uint32_t limit = olimit.valid() ? *olimit : configured_limit;
1817 "limit can not be greater than ${configured_limit}",
1818 (
"configured_limit", configured_limit) );
1825 liquidity_pool_id_type start_id = ostart_id.valid() ? *ostart_id : liquidity_pool_id_type();
1827 auto itr = pools.lower_bound( start_id );
1829 bool with_stats = ( with_statistics.valid() && *with_statistics );
1831 vector<extended_liquidity_pool_object> results;
1833 results.reserve( limit );
1834 while( itr != pools.end() && results.size() < limit )
1844 const std::string& asset_symbol_or_id_a,
1845 const std::string& asset_symbol_or_id_b,
1846 const optional<uint32_t>& limit,
1847 const optional<liquidity_pool_id_type>& start_id,
1848 const optional<bool>& with_statistics )
const
1850 asset_id_type asset_id_a = my->get_asset_from_string(asset_symbol_or_id_a)->get_id();
1851 asset_id_type asset_id_b = my->get_asset_from_string(asset_symbol_or_id_b)->get_id();
1852 if( asset_id_a > asset_id_b )
1853 std::swap( asset_id_a, asset_id_b );
1854 return my->get_liquidity_pools_by_asset_x<by_asset_ab>(
1863 const vector<liquidity_pool_id_type>& ids,
1864 const optional<bool>& subscribe,
1865 const optional<bool>& with_statistics )
const
1867 return my->get_liquidity_pools(
1874 const vector<liquidity_pool_id_type>& ids,
1875 const optional<bool>& subscribe,
1876 const optional<bool>& with_statistics )
const
1880 FC_ASSERT( ids.size() <= configured_limit,
1881 "size of the querying list can not be greater than ${configured_limit}",
1882 (
"configured_limit", configured_limit) );
1884 bool with_stats = ( with_statistics.valid() && *with_statistics );
1887 vector<optional<extended_liquidity_pool_object>> result; result.reserve(ids.size());
1888 std::transform(ids.begin(), ids.end(), std::back_inserter(result),
1889 [
this,to_subscribe,with_stats](liquidity_pool_id_type
id)
1890 -> optional<extended_liquidity_pool_object> {
1892 if(auto o = _db.find(id))
1894 auto ext_obj = extend_liquidity_pool( *o, with_stats );
1897 subscribe_to_item( id );
1898 if( ext_obj.statistics.valid() )
1899 subscribe_to_item( ext_obj.statistics->id );
1909 const vector<std::string>& asset_symbols_or_ids,
1910 const optional<bool>& subscribe,
1911 const optional<bool>& with_statistics )
const
1913 return my->get_liquidity_pools_by_share_asset(
1914 asset_symbols_or_ids,
1920 const vector<std::string>& asset_symbols_or_ids,
1921 const optional<bool>& subscribe,
1922 const optional<bool>& with_statistics )
const
1926 FC_ASSERT( asset_symbols_or_ids.size() <= configured_limit,
1927 "size of the querying list can not be greater than ${configured_limit}",
1928 (
"configured_limit", configured_limit) );
1930 bool with_stats = ( with_statistics.valid() && *with_statistics );
1933 vector<optional<extended_liquidity_pool_object>> result; result.reserve(asset_symbols_or_ids.size());
1934 std::transform(asset_symbols_or_ids.begin(), asset_symbols_or_ids.end(), std::back_inserter(result),
1935 [
this,to_subscribe,with_stats](std::string id_or_name) -> optional<extended_liquidity_pool_object> {
1937 const asset_object* asset_obj = get_asset_from_string( id_or_name, false );
1938 if( asset_obj == nullptr || !asset_obj->is_liquidity_pool_share_asset() )
1945 if( ext_obj.statistics.valid() )
1954 const std::string& account_name_or_id,
1955 const optional<uint32_t>& limit,
1956 const optional<asset_id_type>& start_id,
1957 const optional<bool>& with_statistics )
const
1959 return my->get_liquidity_pools_by_owner(
1967 const std::string& account_name_or_id,
1968 const optional<uint32_t>& olimit,
1969 const optional<asset_id_type>& ostart_id,
1970 const optional<bool>& with_statistics )
const
1974 uint32_t limit = olimit.valid() ? *olimit : configured_limit;
1976 "limit can not be greater than ${configured_limit}",
1977 (
"configured_limit", configured_limit) );
1979 bool with_stats = ( with_statistics.valid() && *with_statistics );
1981 vector<extended_liquidity_pool_object> results;
1985 asset_id_type start_asset_id = ostart_id.valid() ? *ostart_id : asset_id_type();
1986 object_id_type start_id { start_asset_id };
1990 auto lower_itr = idx.lower_bound( std::make_tuple( owner, start_id ) );
1991 auto upper_itr = idx.upper_bound( owner );
1993 results.reserve( limit );
1994 for ( ; lower_itr != upper_itr && results.size() < limit; ++lower_itr )
2012 const optional<uint32_t>& limit,
2013 const optional<samet_fund_id_type>& start_id )
const
2019 idx, limit, start_id );
2023 const std::string& account_name_or_id,
2024 const optional<uint32_t>& limit,
2025 const optional<samet_fund_id_type>& start_id )
const
2027 account_id_type owner = my->get_account_from_string(account_name_or_id)->get_id();
2032 idx, limit, start_id, owner );
2036 const std::string& asset_symbol_or_id,
2037 const optional<uint32_t>& limit,
2038 const optional<samet_fund_id_type>& start_id )
const
2040 asset_id_type asset_type = my->get_asset_from_string(asset_symbol_or_id)->get_id();
2041 const auto& idx = my->_db.get_index_type<
samet_fund_index>().indices().
get<by_asset_type>();
2045 idx, limit, start_id, asset_type );
2056 const optional<uint32_t>& limit,
2057 const optional<credit_offer_id_type>& start_id )
const
2061 credit_offer_id_type
2063 idx, limit, start_id );
2067 const std::string& account_name_or_id,
2068 const optional<uint32_t>& limit,
2069 const optional<credit_offer_id_type>& start_id )
const
2071 account_id_type owner = my->get_account_from_string(account_name_or_id)->get_id();
2074 credit_offer_id_type
2076 idx, limit, start_id, owner );
2080 const std::string& asset_symbol_or_id,
2081 const optional<uint32_t>& limit,
2082 const optional<credit_offer_id_type>& start_id )
const
2084 asset_id_type asset_type = my->get_asset_from_string(asset_symbol_or_id)->get_id();
2087 credit_offer_id_type
2089 idx, limit, start_id, asset_type );
2093 const optional<uint32_t>& limit,
2094 const optional<credit_deal_id_type>& start_id )
const
2100 idx, limit, start_id );
2104 const credit_offer_id_type& offer_id,
2105 const optional<uint32_t>& limit,
2106 const optional<credit_deal_id_type>& start_id )
const
2112 idx, limit, start_id, offer_id );
2116 const std::string& account_name_or_id,
2117 const optional<uint32_t>& limit,
2118 const optional<credit_deal_id_type>& start_id )
const
2120 account_id_type owner = my->get_account_from_string(account_name_or_id)->get_id();
2125 idx, limit, start_id, owner );
2129 const std::string& account_name_or_id,
2130 const optional<uint32_t>& limit,
2131 const optional<credit_deal_id_type>& start_id )
const
2133 account_id_type borrower = my->get_account_from_string(account_name_or_id)->get_id();
2138 idx, limit, start_id, borrower );
2142 const std::string& asset_symbol_or_id,
2143 const optional<uint32_t>& limit,
2144 const optional<credit_deal_id_type>& start_id )
const
2146 asset_id_type asset_type = my->get_asset_from_string(asset_symbol_or_id)->get_id();
2151 idx, limit, start_id, asset_type );
2155 const std::string& asset_symbol_or_id,
2156 const optional<uint32_t>& limit,
2157 const optional<credit_deal_id_type>& start_id )
const
2159 asset_id_type asset_type = my->get_asset_from_string(asset_symbol_or_id)->get_id();
2160 const auto& idx = my->_db.get_index_type<
credit_deal_index>().indices().
get<by_collateral_asset>();
2164 idx, limit, start_id, asset_type );
2176 return my->get_witnesses( witness_ids );
2181 vector<optional<witness_object>> result; result.reserve(witness_ids.size());
2182 std::transform(witness_ids.begin(), witness_ids.end(), std::back_inserter(result),
2183 [
this](witness_id_type
id) -> optional<witness_object> {
2184 if(auto o = _db.find(id))
2193 return my->get_witness_by_account( account_id_or_name );
2200 auto itr = idx.find(account);
2201 if( itr != idx.end() )
2207 uint32_t limit )
const
2209 return my->lookup_witness_accounts( lower_bound_name, limit );
2213 uint32_t limit )
const
2218 "limit can not be greater than ${configured_limit}",
2219 (
"configured_limit", configured_limit) );
2229 std::map<std::string, witness_id_type, std::less<>> witnesses_by_account_name;
2232 if (account_iter->name >= lower_bound_name)
2233 witnesses_by_account_name.insert(std::make_pair(account_iter->name,
witness.get_id()));
2235 auto end_iter = witnesses_by_account_name.begin();
2236 while( end_iter != witnesses_by_account_name.end() && limit > 0 )
2241 witnesses_by_account_name.erase(end_iter, witnesses_by_account_name.end());
2242 return witnesses_by_account_name;
2247 return my->get_witness_count();
2262 const vector<committee_member_id_type>& committee_member_ids )
const
2264 return my->get_committee_members( committee_member_ids );
2268 const vector<committee_member_id_type>& committee_member_ids )
const
2270 vector<optional<committee_member_object>> result; result.reserve(committee_member_ids.size());
2271 std::transform(committee_member_ids.begin(), committee_member_ids.end(), std::back_inserter(result),
2272 [
this](committee_member_id_type
id) -> optional<committee_member_object> {
2273 if(auto o = _db.find(id))
2281 const std::string& account_id_or_name )
const
2283 return my->get_committee_member_by_account( account_id_or_name );
2287 const std::string& account_id_or_name )
const
2291 auto itr = idx.find(account);
2292 if( itr != idx.end() )
2298 const string& lower_bound_name, uint32_t limit )
const
2300 return my->lookup_committee_member_accounts( lower_bound_name, limit );
2304 const string& lower_bound_name, uint32_t limit )
const
2309 "limit can not be greater than ${configured_limit}",
2310 (
"configured_limit", configured_limit) );
2320 std::map<std::string, committee_member_id_type, std::less<>> committee_members_by_account_name;
2322 if (
auto account_iter =
_db.
find(committee_member.committee_member_account))
2323 if (account_iter->name >= lower_bound_name)
2324 committee_members_by_account_name.insert(std::make_pair(account_iter->name, committee_member.get_id()));
2326 auto end_iter = committee_members_by_account_name.begin();
2327 while( end_iter != committee_members_by_account_name.end() && limit > 0 )
2332 committee_members_by_account_name.erase(end_iter, committee_members_by_account_name.end());
2333 return committee_members_by_account_name;
2338 return my->get_committee_count();
2355 return my->get_all_workers( is_expired );
2360 vector<worker_object> result;
2362 if( !is_expired.valid() )
2365 result.reserve( workers_idx.size() );
2366 for(
const auto& w : workers_idx )
2368 result.push_back( w );
2375 auto itr = *is_expired ? workers_idx.begin() : workers_idx.lower_bound( now );
2376 auto end = *is_expired ? workers_idx.upper_bound( now ) : workers_idx.end();
2377 for( ; itr != end; ++itr )
2379 result.push_back( *itr );
2388 return my->get_workers_by_account( account_id_or_name );
2393 vector<worker_object> result;
2397 auto range = workers_idx.equal_range(account);
2398 for(
auto itr = range.first; itr != range.second; ++itr)
2400 result.push_back( *itr );
2407 return my->get_worker_count();
2425 return my->lookup_vote_ids( votes );
2432 FC_ASSERT( votes.size() <= configured_limit,
2433 "Number of querying votes can not be greater than ${configured_limit}",
2434 (
"configured_limit", configured_limit) );
2441 vector<variant> result;
2442 result.reserve( votes.size() );
2443 for(
auto id : votes )
2449 auto itr = committee_idx.find(
id );
2450 if( itr != committee_idx.end() )
2451 result.emplace_back( variant( *itr, 2 ) );
2453 result.emplace_back( variant() );
2458 auto itr = witness_idx.find(
id );
2459 if( itr != witness_idx.end() )
2460 result.emplace_back( variant( *itr, 2 ) );
2462 result.emplace_back( variant() );
2467 auto itr = for_worker_idx.find(
id );
2468 if( itr != for_worker_idx.end() ) {
2469 result.emplace_back( variant( *itr, 4 ) );
2474 auto itr = against_worker_idx.find(
id );
2475 if( itr != against_worker_idx.end() ) {
2476 result.emplace_back( variant( *itr, 4 ) );
2481 result.emplace_back( variant() );
2502 return my->get_transaction_hex( trx );
2511 const transaction &trx)
const
2513 return my->get_transaction_hex_without_sig(trx);
2517 const transaction &trx)
const
2523 const flat_set<public_key_type>& available_keys )
const
2525 return my->get_required_signatures( trx, available_keys );
2529 const flat_set<public_key_type>& available_keys )
const
2532 bool allow_non_immediate_owner = ( chain_time >= HARDFORK_CORE_584_TIME );
2533 bool ignore_custom_op_reqd_auths = MUST_IGNORE_CUSTOM_OP_REQD_AUTHS( chain_time );
2536 [&]( account_id_type
id ){ return &id(_db).active; },
2537 [&]( account_id_type
id ){ return &id(_db).owner; },
2538 allow_non_immediate_owner,
2539 ignore_custom_op_reqd_auths,
2546 return my->get_potential_signatures( trx );
2550 return my->get_potential_address_signatures( trx );
2556 bool allow_non_immediate_owner = ( chain_time >= HARDFORK_CORE_584_TIME );
2557 bool ignore_custom_op_reqd_auths = MUST_IGNORE_CUSTOM_OP_REQD_AUTHS( chain_time );
2559 set<public_key_type> result;
2560 auto get_active = [
this, &result]( account_id_type id ){
2561 const auto& auth = id(
_db ).active;
2562 for(
const auto& k : auth.get_keys() )
2566 auto get_owner = [
this, &result]( account_id_type id ){
2567 const auto& auth = id(
_db ).owner;
2568 for(
const auto& k : auth.get_keys() )
2574 flat_set<public_key_type>(),
2575 get_active, get_owner,
2576 allow_non_immediate_owner,
2577 ignore_custom_op_reqd_auths,
2581 flat_set<account_id_type> required_active;
2582 flat_set<account_id_type> required_owner;
2583 vector<authority> other;
2584 trx.get_required_authorities( required_active, required_owner, other, ignore_custom_op_reqd_auths );
2585 for(
const auto& auth : other )
2586 for(
const auto& key : auth.get_keys() )
2587 result.insert( key );
2595 bool allow_non_immediate_owner = ( chain_time >= HARDFORK_CORE_584_TIME );
2596 bool ignore_custom_op_reqd_auths = MUST_IGNORE_CUSTOM_OP_REQD_AUTHS( chain_time );
2598 set<address> result;
2599 auto get_active = [
this, &result]( account_id_type id ){
2600 const auto& auth = id(
_db ).active;
2601 for(
const auto& k : auth.get_addresses() )
2605 auto get_owner = [
this, &result]( account_id_type id ) {
2606 const auto& auth = id(
_db ).owner;
2607 for (
const auto& k : auth.get_addresses())
2613 flat_set<public_key_type>(),
2614 get_active, get_owner,
2615 allow_non_immediate_owner,
2616 ignore_custom_op_reqd_auths,
2623 return my->verify_authority( trx );
2628 bool allow_non_immediate_owner = (
_db.
head_block_time() >= HARDFORK_CORE_584_TIME );
2630 [
this]( account_id_type id ){
return &id(
_db).active; },
2631 [
this]( account_id_type id ){
return &id(
_db).owner; },
2634 allow_non_immediate_owner,
2640 const flat_set<public_key_type>& signers )
const
2642 return my->verify_account_authority( account_name_or_id, signers );
2646 const flat_set<public_key_type>& keys )
const
2651 std::vector<operation> ops;
2652 ops.emplace_back(op);
2657 [
this]( account_id_type
id ){
return &id(
_db).active; },
2658 [
this]( account_id_type id ){
return &id(
_db).owner; },
2660 [](
auto,
auto,
auto*) {
return vector<authority>(); },
2673 return my->validate_transaction( trx );
2682 const std::string& asset_id_or_symbol )
const
2684 return my->get_required_fees( ops, asset_id_or_symbol );
2694 const fee_schedule& _current_fee_schedule,
2695 const price& _core_exchange_rate,
2696 uint32_t _max_recursion
2721 std::pair< asset, fc::variants > result;
2744 const std::string& asset_id_or_symbol )
const
2746 vector< operation > _ops = ops;
2752 vector< fc::variant > result;
2753 result.reserve(ops.size());
2774 return my->get_proposed_transactions( account_id_or_name );
2781 "api_helper_indexes plugin is not enabled on this server." );
2786 vector<proposal_object> result;
2789 auto required_approvals_itr = proposals_by_account._account_to_proposals.
find(
id );
2790 if( required_approvals_itr != proposals_by_account._account_to_proposals.end() )
2792 result.reserve( required_approvals_itr->second.size() );
2793 for(
auto proposal_id : required_approvals_itr->second )
2795 result.push_back( proposal_id(
_db) );
2808 const flat_set<commitment_type>& commitments )
const
2810 return my->get_blinded_balances( commitments );
2814 const flat_set<commitment_type>& commitments )
const
2816 vector<blinded_balance_object> result; result.reserve(commitments.size());
2818 const auto& by_commitment_idx = bal_idx.
indices().get<by_commitment>();
2819 for(
const auto& c : commitments )
2821 auto itr = by_commitment_idx.
find( c );
2822 if( itr != by_commitment_idx.end() )
2823 result.push_back( *itr );
2835 const std::string account_id_or_name,
2836 withdraw_permission_id_type start,
2837 uint32_t limit)
const
2839 return my->get_withdraw_permissions_by_giver( account_id_or_name, start, limit );
2843 const std::string account_id_or_name,
2844 withdraw_permission_id_type start,
2845 uint32_t limit)
const
2850 "limit can not be greater than ${configured_limit}",
2851 (
"configured_limit", configured_limit) );
2853 vector<withdraw_permission_object> result;
2856 auto withdraw_index_end = withdraw_idx.end();
2858 auto withdraw_itr = withdraw_idx.lower_bound(boost::make_tuple(account, object_id_type(start)));
2859 while( withdraw_itr != withdraw_index_end && withdraw_itr->withdraw_from_account == account
2860 && result.size() < limit )
2862 result.push_back(*withdraw_itr);
2869 const std::string account_id_or_name,
2870 withdraw_permission_id_type start,
2871 uint32_t limit)
const
2873 return my->get_withdraw_permissions_by_recipient( account_id_or_name, start, limit );
2877 const std::string account_id_or_name,
2878 withdraw_permission_id_type start,
2879 uint32_t limit)
const
2884 "limit can not be greater than ${configured_limit}",
2885 (
"configured_limit", configured_limit) );
2887 vector<withdraw_permission_object> result;
2890 auto withdraw_index_end = withdraw_idx.end();
2892 auto withdraw_itr = withdraw_idx.lower_bound(boost::make_tuple(account, object_id_type(start)));
2893 while(withdraw_itr != withdraw_index_end && withdraw_itr->authorized_account == account && result.size() < limit)
2895 result.push_back(*withdraw_itr);
2909 return my->get_htlc(
id, subscribe );
2914 auto obj =
get_objects( { object_id_type(
id) }, subscribe ).front();
2915 if ( !obj.is_null() )
2923 htlc_id_type start, uint32_t limit )
const
2925 return my->get_htlc_by_from(account_id_or_name, start, limit);
2929 htlc_id_type start, uint32_t limit )
const
2934 "limit can not be greater than ${configured_limit}",
2935 (
"configured_limit", configured_limit) );
2937 vector<htlc_object> result;
2940 auto htlc_index_end = htlc_idx.end();
2942 auto htlc_itr = htlc_idx.lower_bound(boost::make_tuple(account, object_id_type(start)));
2944 while(htlc_itr != htlc_index_end && htlc_itr->transfer.from == account && result.size() < limit)
2946 result.push_back(*htlc_itr);
2953 htlc_id_type start, uint32_t limit )
const
2955 return my->get_htlc_by_to(account_id_or_name, start, limit);
2959 htlc_id_type start, uint32_t limit )
const
2964 "limit can not be greater than ${configured_limit}",
2965 (
"configured_limit", configured_limit) );
2967 vector<htlc_object> result;
2970 auto htlc_index_end = htlc_idx.end();
2972 auto htlc_itr = htlc_idx.lower_bound(boost::make_tuple(account, object_id_type(start)));
2974 while(htlc_itr != htlc_index_end && htlc_itr->transfer.to == account && result.size() < limit)
2976 result.push_back(*htlc_itr);
2984 return my->list_htlcs(start, limit);
2992 "limit can not be greater than ${configured_limit}",
2993 (
"configured_limit", configured_limit) );
2995 vector<htlc_object> result;
2997 auto itr = htlc_idx.lower_bound(object_id_type(start));
2998 while(itr != htlc_idx.end() && result.size() < limit)
3000 result.push_back(*itr);
3013 const optional<uint32_t>& limit,
3014 const optional<ticket_id_type>& start_id )
const
3016 const auto& idx = my->_db.get_index_type<
ticket_index>().indices().
get<by_id>();
3020 idx, limit, start_id );
3024 const std::string& account_name_or_id,
3025 const optional<uint32_t>& limit,
3026 const optional<ticket_id_type>& start_id )
const
3028 account_id_type account = my->get_account_from_string(account_name_or_id)->get_id();
3029 const auto& idx = my->_db.get_index_type<
ticket_index>().indices().
get<by_account>();
3033 idx, limit, start_id, account );
3043 bool throw_if_not_found )
const
3046 if( name_or_id.empty() )
3048 if( throw_if_not_found )
3054 if( 0 != std::isdigit(name_or_id[0]) )
3059 auto itr = idx.find(name_or_id);
3060 if (itr != idx.end())
3061 account_ptr = &(*itr);
3063 if(throw_if_not_found)
3064 FC_ASSERT( account_ptr,
"no such account" );
3069 bool throw_if_not_found )
const
3072 if( symbol_or_id.empty() )
3074 if( throw_if_not_found )
3080 if( 0 != std::isdigit(symbol_or_id[0]) )
3085 auto itr = idx.find(symbol_or_id);
3086 if (itr != idx.end())
3087 asset_ptr = &(*itr);
3089 if(throw_if_not_found)
3090 FC_ASSERT( asset_ptr,
"no such asset" );
3096 optional<bool> subscribe )
const
3099 vector<optional<extended_asset_object>> result; result.reserve(asset_ids.size());
3100 std::transform(asset_ids.begin(), asset_ids.end(), std::back_inserter(result),
3101 [
this,to_subscribe](asset_id_type
id) -> optional<extended_asset_object> {
3102 if(auto o = _db.find(id))
3105 subscribe_to_item( id );
3106 return extend_asset( *o );
3115 const uint32_t limit )
const
3120 "limit can not be greater than ${configured_limit}",
3121 (
"configured_limit", configured_limit) );
3124 const auto& limit_price_idx = limit_order_idx.
indices().get<by_price>();
3126 vector<limit_order_object> result;
3127 result.reserve(limit*2);
3130 auto limit_itr = limit_price_idx.lower_bound(
price::max(a,b));
3131 auto limit_end = limit_price_idx.upper_bound(
price::min(a,b));
3132 while(limit_itr != limit_end && count < limit)
3134 result.push_back(*limit_itr);
3139 limit_itr = limit_price_idx.lower_bound(
price::max(b,a));
3140 limit_end = limit_price_idx.upper_bound(
price::min(b,a));
3141 while(limit_itr != limit_end && count < limit)
3143 result.push_back(*limit_itr);
3156 return std::any_of(accounts.begin(), accounts.end(), [
this](
const account_id_type& account) {
3157 return _subscribed_accounts.find(account) != _subscribed_accounts.end();
3164 auto capture_this = shared_from_this();
3166 if(capture_this->_subscribe_callback)
3167 capture_this->_subscribe_callback(
fc::variant(updates) );
3174 if( !queue.empty() )
3176 auto capture_this = shared_from_this();
3177 fc::async([capture_this,
this, queue](){
3178 for(
const auto& item : queue )
3189 const vector<const object*>& objs,
3190 const flat_set<account_id_type>& impacted_accounts )
3193 [objs](object_id_type
id) ->
const object* {
3194 auto it = std::find_if(
3195 objs.begin(), objs.end(),
3196 [
id](
const object* o) {return o != nullptr && o->id == id;});
3198 if (it != objs.end())
3207 const flat_set<account_id_type>& impacted_accounts )
3215 const flat_set<account_id_type>& impacted_accounts )
3224 const vector<object_id_type>& ids,
3225 const flat_set<account_id_type>& impacted_accounts,
3226 std::function<
const object*(object_id_type
id)> find_object )
3230 vector<variant> updates;
3238 auto obj = find_object(
id);
3241 updates.emplace_back( obj->to_variant() );
3251 if( !updates.empty() )
3261 if(
id.is<call_order_id_type>() )
3263 enqueue_if_subscribed_to_market<call_order_object>( find_object(
id), broadcast_queue, full_object );
3265 else if(
id.is<limit_order_id_type>() )
3267 enqueue_if_subscribed_to_market<limit_order_object>( find_object(
id), broadcast_queue, full_object );
3269 else if(
id.is<force_settlement_id_type>() )
3271 enqueue_if_subscribed_to_market<force_settlement_object>( find_object(
id), broadcast_queue,
3276 if( !broadcast_queue.empty() )
3288 auto capture_this = shared_from_this();
3290 fc::async([
this,capture_this,block_id](){
3299 map< std::pair<asset_id_type,asset_id_type>, vector<pair<operation, operation_result>> > subscribed_markets_ops;
3300 for(
const optional< operation_history_object >& o_op : ops)
3306 optional< std::pair<asset_id_type,asset_id_type> > market;
3314 case operation::tag<fill_order_operation>::value:
3324 subscribed_markets_ops[*market].emplace_back(std::make_pair(op.
op, op.
result));
3327 auto capture_this = shared_from_this();
3328 fc::async([
this,capture_this,subscribed_markets_ops](){
3329 for(
auto item : subscribed_markets_ops)