BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
database_api.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
24 
26 
27 #include "database_api_impl.hxx"
28 
29 #include <graphene/app/util.hpp>
31 #include <graphene/chain/hardfork.hpp>
34 
35 #include <fc/crypto/hex.hpp>
37 
38 #include <boost/range/iterator_range.hpp>
39 
40 #include <cctype>
41 
43 
44 namespace graphene { namespace app {
45 
47 // //
48 // Constructors //
49 // //
51 
52 database_api::database_api( graphene::chain::database& db, const application_options* app_options )
53 : my( std::make_shared<database_api_impl>( db, app_options ) )
54 { // Nothing else to do
55 }
56 
57 database_api::~database_api() = default;
58 
60 :_db(db), _app_options(app_options)
61 { // Nothing else to do
62 }
63 
65 :_db( *app.chain_database() ), _app_options( &app.get_options() )
66 { // Nothing else to do
67 }
68 
70 :database_api_helper( db, app_options )
71 {
72  dlog("creating database api ${x}", ("x",int64_t(this)) );
73  _new_connection = _db.new_objects.connect([this](const vector<object_id_type>& ids,
74  const flat_set<account_id_type>& impacted_accounts) {
75  on_objects_new(ids, impacted_accounts);
76  });
77  _change_connection = _db.changed_objects.connect([this](const vector<object_id_type>& ids,
78  const flat_set<account_id_type>& impacted_accounts) {
79  on_objects_changed(ids, impacted_accounts);
80  });
81  _removed_connection = _db.removed_objects.connect([this](const vector<object_id_type>& ids,
82  const vector<const object*>& objs,
83  const flat_set<account_id_type>& impacted_accounts) {
84  on_objects_removed(ids, objs, impacted_accounts);
85  });
87 
88  _pending_trx_connection = _db.on_pending_transaction.connect([this](const signed_transaction& trx ){
91  });
92  try
93  {
95  .get_secondary_index<graphene::api_helper_indexes::amount_in_collateral_index>();
96  }
97  catch( const fc::assert_exception& )
98  {
100  }
101 
102  try
103  {
105  .get_secondary_index<graphene::api_helper_indexes::asset_in_liquidity_pools_index>();
106  }
107  catch( const fc::assert_exception& )
108  {
110  }
111 
112  try
113  {
115  .get_secondary_index<graphene::api_helper_indexes::next_object_ids_index>();
116  }
117  catch( const fc::assert_exception& )
118  {
119  next_object_ids_index = nullptr;
120  }
121 
122 }
123 
125 {
126  dlog("freeing database api ${x}", ("x",int64_t(this)) );
127 }
128 
130 // //
131 // Objects //
132 // //
134 
135 fc::variants database_api::get_objects( const vector<object_id_type>& ids, optional<bool> subscribe )const
136 {
137  return my->get_objects( ids, subscribe );
138 }
139 
140 fc::variants database_api_impl::get_objects( const vector<object_id_type>& ids, optional<bool> subscribe )const
141 {
142  bool to_subscribe = get_whether_to_subscribe( subscribe );
143 
144  fc::variants result;
145  result.reserve(ids.size());
146 
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))
150  {
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();
154  }
155  return {};
156  });
157 
158  return result;
159 }
160 
162 // //
163 // Subscriptions //
164 // //
166 
167 void database_api::set_subscribe_callback( std::function<void(const variant&)> cb, bool notify_remove_create )
168 {
169  my->set_subscribe_callback( cb, notify_remove_create );
170 }
171 
172 void database_api_impl::set_subscribe_callback( std::function<void(const variant&)> cb, bool notify_remove_create )
173 {
174  if( notify_remove_create )
175  {
177  "Subscribing to universal object creation and removal is disallowed in this server." );
178  }
179 
180  cancel_all_subscriptions(false, false);
181 
182  _subscribe_callback = cb;
183  _notify_remove_create = notify_remove_create;
184 }
185 
187 {
188  my->set_auto_subscription( enable );
189 }
190 
192 {
194 }
195 
196 void database_api::set_pending_transaction_callback( std::function<void(const variant&)> cb )
197 {
198  my->set_pending_transaction_callback( cb );
199 }
200 
201 void database_api_impl::set_pending_transaction_callback( std::function<void(const variant&)> cb )
202 {
204 }
205 
206 void database_api::set_block_applied_callback( std::function<void(const variant& block_id)> cb )
207 {
208  my->set_block_applied_callback( cb );
209 }
210 
211 void database_api_impl::set_block_applied_callback( std::function<void(const variant& block_id)> cb )
212 {
214 }
215 
217 {
218  my->cancel_all_subscriptions(true, true);
219 }
220 
221 void database_api_impl::cancel_all_subscriptions( bool reset_callback, bool reset_market_subscriptions )
222 {
223  if ( reset_callback )
224  _subscribe_callback = std::function<void(const fc::variant&)>();
225 
226  if ( reset_market_subscriptions )
227  _market_subscriptions.clear();
228 
229  _notify_remove_create = false;
230  _subscribed_accounts.clear();
231  static fc::bloom_parameters param(10000, 1.0/100, 1024*8*8*2);
233 }
234 
236 // //
237 // Blocks and transactions //
238 // //
240 
241 optional<maybe_signed_block_header> database_api::get_block_header(
242  uint32_t block_num, const optional<bool>& with_witness_signature )const
243 {
244  bool with_signature = ( with_witness_signature.valid() && *with_witness_signature );
245  return my->get_block_header( block_num, with_signature );
246 }
247 
248 optional<maybe_signed_block_header> database_api_impl::get_block_header(
249  uint32_t block_num, bool with_witness_signature )const
250 {
251  auto result = _db.fetch_block_by_number(block_num);
252  if(result)
253  return maybe_signed_block_header( *result, with_witness_signature );
254  return {};
255 }
256 
257 map<uint32_t, optional<maybe_signed_block_header>> database_api::get_block_header_batch(
258  const vector<uint32_t>& block_nums, const optional<bool>& with_witness_signatures )const
259 {
260  bool with_signatures = ( with_witness_signatures.valid() && *with_witness_signatures );
261  return my->get_block_header_batch( block_nums, with_signatures );
262 }
263 
264 map<uint32_t, optional<maybe_signed_block_header>> database_api_impl::get_block_header_batch(
265  const vector<uint32_t>& block_nums, bool with_witness_signatures )const
266 {
267  map<uint32_t, optional<maybe_signed_block_header>> results;
268  for (const uint32_t block_num : block_nums)
269  {
270  results[block_num] = get_block_header( block_num, with_witness_signatures );
271  }
272  return results;
273 }
274 
275 optional<signed_block> database_api::get_block(uint32_t block_num)const
276 {
277  return my->get_block( block_num );
278 }
279 
280 optional<signed_block> database_api_impl::get_block(uint32_t block_num)const
281 {
282  return _db.fetch_block_by_number(block_num);
283 }
284 
285 processed_transaction database_api::get_transaction( uint32_t block_num, uint32_t trx_in_block )const
286 {
287  return my->get_transaction( block_num, trx_in_block );
288 }
289 
290 optional<signed_transaction> database_api::get_recent_transaction_by_id( const transaction_id_type& id )const
291 {
292  try {
293  return my->_db.get_recent_transaction( id );
294  } catch ( ... ) {
295  return optional<signed_transaction>();
296  }
297 }
298 
299 processed_transaction database_api_impl::get_transaction(uint32_t block_num, uint32_t trx_num)const
300 {
301  auto opt_block = _db.fetch_block_by_number(block_num);
302  FC_ASSERT( opt_block );
303  FC_ASSERT( opt_block->transactions.size() > trx_num );
304  return opt_block->transactions[trx_num];
305 }
306 
308 // //
309 // Globals //
310 // //
312 
314 {
315  return my->get_chain_properties();
316 }
317 
319 {
320  return _db.get(chain_property_id_type());
321 }
322 
324 {
325  return my->get_global_properties();
326 }
327 
329 {
330  return _db.get(global_property_id_type());
331 }
332 
334 {
335  return my->get_config();
336 }
337 
339 {
341 }
342 
344 {
345  return my->get_chain_id();
346 }
347 
349 {
350  return _db.get_chain_id();
351 }
352 
354 {
355  return my->get_dynamic_global_properties();
356 }
357 
359 {
360  return _db.get(dynamic_global_property_id_type());
361 }
362 
363 object_id_type database_api::get_next_object_id( uint8_t space_id, uint8_t type_id,
364  bool with_pending_transactions )const
365 {
366  return my->get_next_object_id( space_id, type_id, with_pending_transactions );
367 }
368 
369 object_id_type database_api_impl::get_next_object_id( uint8_t space_id, uint8_t type_id,
370  bool with_pending_transactions )const
371 {
372  if( with_pending_transactions )
373  return _db.get_index( space_id, type_id ).get_next_id();
374 
375  FC_ASSERT( next_object_ids_index, "api_helper_indexes plugin is not enabled on this server." );
376 
377  return next_object_ids_index->get_next_id( space_id, type_id );
378 }
379 
381 // //
382 // Keys //
383 // //
385 
386 vector<flat_set<account_id_type>> database_api::get_key_references( vector<public_key_type> key )const
387 {
388  return my->get_key_references( key );
389 }
390 
394 vector<flat_set<account_id_type>> database_api_impl::get_key_references( vector<public_key_type> keys )const
395 {
396  // api_helper_indexes plugin is required for accessing the secondary index
398  "api_helper_indexes plugin is not enabled on this server." );
399 
400  const auto configured_limit = _app_options->api_limit_get_key_references;
401  FC_ASSERT( keys.size() <= configured_limit,
402  "Number of querying keys can not be greater than ${configured_limit}",
403  ("configured_limit", configured_limit) );
404 
405  const auto& idx = _db.get_index_type<account_index>();
406  const auto& aidx = dynamic_cast<const base_primary_index&>(idx);
407  const auto& refs = aidx.get_secondary_index<graphene::chain::account_member_index>();
408 
409  vector< flat_set<account_id_type> > final_result;
410  final_result.reserve(keys.size());
411 
412  for( auto& key : keys )
413  {
414  address a1( pts_address(key, false) ); // version = 56 (default)
415  address a2( pts_address(key, true) ); // version = 56 (default)
416  address a3( pts_address(key, false, 0) );
417  address a4( pts_address(key, true, 0) );
418  address a5( key );
419 
420  flat_set<account_id_type> result;
421 
422  for( auto& a : {a1,a2,a3,a4,a5} )
423  {
424  auto itr = refs.account_to_address_memberships.find(a);
425  if( itr != refs.account_to_address_memberships.end() )
426  {
427  result.reserve( result.size() + itr->second.size() );
428  for( auto item : itr->second )
429  {
430  result.insert(item);
431  }
432  }
433  }
434 
435  auto itr = refs.account_to_key_memberships.find(key);
436  if( itr != refs.account_to_key_memberships.end() )
437  {
438  result.reserve( result.size() + itr->second.size() );
439  for( auto item : itr->second ) result.insert(item);
440  }
441  final_result.emplace_back( std::move(result) );
442  }
443 
444  return final_result;
445 }
446 
447 bool database_api::is_public_key_registered(string public_key) const
448 {
449  return my->is_public_key_registered(public_key);
450 }
451 
452 bool database_api_impl::is_public_key_registered(string public_key) const
453 {
454  // Short-circuit
455  if (public_key.empty()) {
456  return false;
457  }
458 
459  // Search among all keys using an existing map of *current* account keys
460  public_key_type key;
461  try {
462  key = public_key_type(public_key);
463  } catch ( ... ) {
464  // An invalid public key was detected
465  return false;
466  }
467 
468  // api_helper_indexes plugin is required for accessing the secondary index
470  "api_helper_indexes plugin is not enabled on this server." );
471 
472  const auto& idx = _db.get_index_type<account_index>();
473  const auto& aidx = dynamic_cast<const base_primary_index&>(idx);
474  const auto& refs = aidx.get_secondary_index<graphene::chain::account_member_index>();
475  auto itr = refs.account_to_key_memberships.find(key);
476  bool is_known = itr != refs.account_to_key_memberships.end();
477 
478  return is_known;
479 }
480 
482 // //
483 // Accounts //
484 // //
486 
487 account_id_type database_api::get_account_id_from_string(const std::string& name_or_id)const
488 {
489  return my->get_account_from_string( name_or_id )->get_id();
490 }
491 
492 vector<optional<account_object>> database_api::get_accounts( const vector<std::string>& account_names_or_ids,
493  optional<bool> subscribe )const
494 {
495  return my->get_accounts( account_names_or_ids, subscribe );
496 }
497 
498 vector<optional<account_object>> database_api_impl::get_accounts( const vector<std::string>& account_names_or_ids,
499  optional<bool> subscribe )const
500 {
501  bool to_subscribe = get_whether_to_subscribe( subscribe );
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> {
505 
506  const account_object *account = get_account_from_string(id_or_name, false);
507  if(account == nullptr)
508  return {};
509  if( to_subscribe )
510  subscribe_to_item( account->id );
511  return *account;
512  });
513  return result;
514 }
515 
516 std::map<string, full_account, std::less<>> database_api::get_full_accounts( const vector<string>& names_or_ids,
517  const optional<bool>& subscribe )const
518 {
519  return my->get_full_accounts( names_or_ids, subscribe );
520 }
521 
522 std::map<std::string, full_account, std::less<>> database_api_impl::get_full_accounts(
523  const vector<std::string>& names_or_ids, const optional<bool>& subscribe )
524 {
525  FC_ASSERT( _app_options, "Internal error" );
526  const auto configured_limit = _app_options->api_limit_get_full_accounts;
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) );
530 
531  bool to_subscribe = get_whether_to_subscribe( subscribe );
532 
533  std::map<std::string, full_account, std::less<>> results;
534 
535  for (const std::string& account_name_or_id : names_or_ids)
536  {
537  const account_object* account = get_account_from_string(account_name_or_id, false);
538  if( !account )
539  continue;
540 
542  {
543  _subscribed_accounts.insert( account->get_id() );
544  subscribe_to_item( account->id );
545  }
546 
547  full_account acnt;
548  acnt.account = *account;
549  acnt.statistics = account->statistics(_db);
550  acnt.registrar_name = account->registrar(_db).name;
551  acnt.referrer_name = account->referrer(_db).name;
552  acnt.lifetime_referrer_name = account->lifetime_referrer(_db).name;
553  acnt.votes = lookup_vote_ids( vector<vote_id_type>( account->options.votes.begin(),
554  account->options.votes.end() ) );
555 
556  if (account->cashback_vb)
557  {
558  acnt.cashback_balance = account->cashback_balance(_db);
559  }
560 
561  size_t api_limit_get_full_accounts_lists = static_cast<size_t>(
563 
564  // Add the account's proposals (if the data is available)
566  {
567  const auto& proposal_idx = _db.get_index_type< primary_index< proposal_index > >();
568  const auto& proposals_by_account = proposal_idx.get_secondary_index<
570 
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() )
573  {
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 )
577  {
578  if(acnt.proposals.size() >= api_limit_get_full_accounts_lists) {
579  acnt.more_data_available.proposals = true;
580  break;
581  }
582  acnt.proposals.push_back(proposal_id(_db));
583  }
584  }
585  }
586 
587  // Add the account's balances
588  const auto& balances = _db.get_index_type< primary_index< account_balance_index > >().
589  get_secondary_index< balances_by_account_index >().get_account_balances( account->get_id() );
590  for( const auto& balance : balances )
591  {
592  if(acnt.balances.size() >= api_limit_get_full_accounts_lists) {
593  acnt.more_data_available.balances = true;
594  break;
595  }
596  acnt.balances.emplace_back(*balance.second);
597  }
598 
599  // Add the account's vesting balances
600  auto vesting_range = _db.get_index_type<vesting_balance_index>().indices().get<by_account>()
601  .equal_range(account->get_id());
602  for(auto itr = vesting_range.first; itr != vesting_range.second; ++itr)
603  {
604  if(acnt.vesting_balances.size() >= api_limit_get_full_accounts_lists) {
606  break;
607  }
608  acnt.vesting_balances.emplace_back(*itr);
609  }
610 
611  // Add the account's orders
612  auto order_range = _db.get_index_type<limit_order_index>().indices().get<by_account>()
613  .equal_range(account->get_id());
614  for(auto itr = order_range.first; itr != order_range.second; ++itr)
615  {
616  if(acnt.limit_orders.size() >= api_limit_get_full_accounts_lists) {
617  acnt.more_data_available.limit_orders = true;
618  break;
619  }
620  acnt.limit_orders.emplace_back(*itr);
621  }
622  auto call_range = _db.get_index_type<call_order_index>().indices().get<by_account>()
623  .equal_range(account->get_id());
624  for(auto itr = call_range.first; itr != call_range.second; ++itr)
625  {
626  if(acnt.call_orders.size() >= api_limit_get_full_accounts_lists) {
627  acnt.more_data_available.call_orders = true;
628  break;
629  }
630  acnt.call_orders.emplace_back(*itr);
631  }
632  auto settle_range = _db.get_index_type<force_settlement_index>().indices().get<by_account>()
633  .equal_range(account->get_id());
634  for(auto itr = settle_range.first; itr != settle_range.second; ++itr)
635  {
636  if(acnt.settle_orders.size() >= api_limit_get_full_accounts_lists) {
638  break;
639  }
640  acnt.settle_orders.emplace_back(*itr);
641  }
642 
643  // get assets issued by user
644  auto asset_range = _db.get_index_type<asset_index>().indices().get<by_issuer>().equal_range(account->get_id());
645  for(auto itr = asset_range.first; itr != asset_range.second; ++itr)
646  {
647  if(acnt.assets.size() >= api_limit_get_full_accounts_lists) {
648  acnt.more_data_available.assets = true;
649  break;
650  }
651  acnt.assets.emplace_back(itr->get_id());
652  }
653 
654  // get withdraws permissions
655  auto withdraw_indices = _db.get_index_type<withdraw_permission_index>().indices();
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)
658  {
659  if(acnt.withdraws_from.size() >= api_limit_get_full_accounts_lists) {
661  break;
662  }
663  acnt.withdraws_from.emplace_back(*itr);
664  }
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)
667  {
668  if(acnt.withdraws_to.size() >= api_limit_get_full_accounts_lists) {
669  acnt.more_data_available.withdraws_to = true;
670  break;
671  }
672  acnt.withdraws_to.emplace_back(*itr);
673  }
674 
675  // get htlcs
676  auto htlc_from_range = _db.get_index_type<htlc_index>().indices().get<by_from_id>()
677  .equal_range(account->get_id());
678  for(auto itr = htlc_from_range.first; itr != htlc_from_range.second; ++itr)
679  {
680  if(acnt.htlcs_from.size() >= api_limit_get_full_accounts_lists) {
681  acnt.more_data_available.htlcs_from = true;
682  break;
683  }
684  acnt.htlcs_from.emplace_back(*itr);
685  }
686  auto htlc_to_range = _db.get_index_type<htlc_index>().indices().get<by_to_id>().equal_range(account->get_id());
687  for(auto itr = htlc_to_range.first; itr != htlc_to_range.second; ++itr)
688  {
689  if(acnt.htlcs_to.size() >= api_limit_get_full_accounts_lists) {
690  acnt.more_data_available.htlcs_to = true;
691  break;
692  }
693  acnt.htlcs_to.emplace_back(*itr);
694  }
695 
696  results[account_name_or_id] = acnt;
697  }
698  return results;
699 }
700 
701 vector<account_statistics_object> database_api::get_top_voters(uint32_t limit)const
702 {
703  return my->get_top_voters( limit );
704 }
705 
706 vector<account_statistics_object> database_api_impl::get_top_voters(uint32_t limit)const
707 {
708  FC_ASSERT( _app_options, "Internal error" );
709  const auto configured_limit = _app_options->api_limit_get_top_voters;
710  FC_ASSERT( limit <= configured_limit,
711  "limit can not be greater than ${configured_limit}",
712  ("configured_limit", configured_limit) );
713 
714  vector<account_statistics_object> result;
715 
716  auto last_vote_tally_time = _db.get_dynamic_global_properties().last_vote_tally_time;
717  const auto& idx = _db.get_index_type<account_stats_index>().indices().get<by_voting_power_active>();
718 
719  for(auto itr = idx.begin(); result.size() < limit && itr != idx.end() && itr->vote_tally_time >= last_vote_tally_time; ++itr)
720  {
721  result.emplace_back(*itr);
722  }
723 
724  return result;
725 }
726 
727 optional<account_object> database_api::get_account_by_name( string name )const
728 {
729  return my->get_account_by_name( name );
730 }
731 
732 optional<account_object> database_api_impl::get_account_by_name( string name )const
733 {
734  const auto& idx = _db.get_index_type<account_index>().indices().get<by_name>();
735  auto itr = idx.find(name);
736  if (itr != idx.end())
737  return *itr;
738  return optional<account_object>();
739 }
740 
741 vector<account_id_type> database_api::get_account_references( const std::string account_id_or_name )const
742 {
743  return my->get_account_references( account_id_or_name );
744 }
745 
746 vector<account_id_type> database_api_impl::get_account_references( const std::string account_id_or_name )const
747 {
748  // api_helper_indexes plugin is required for accessing the secondary index
750  "api_helper_indexes plugin is not enabled on this server." );
751 
752  const auto& idx = _db.get_index_type<account_index>();
753  const auto& aidx = dynamic_cast<const base_primary_index&>(idx);
754  const auto& refs = aidx.get_secondary_index<graphene::chain::account_member_index>();
755  const account_id_type account_id = get_account_from_string(account_id_or_name)->get_id();
756  auto itr = refs.account_to_account_memberships.find(account_id);
757  vector<account_id_type> result;
758 
759  if( itr != refs.account_to_account_memberships.end() )
760  {
761  result.reserve( itr->second.size() );
762  for( auto item : itr->second ) result.push_back(item);
763  }
764  return result;
765 }
766 
767 vector<optional<account_object>> database_api::lookup_account_names(const vector<string>& account_names)const
768 {
769  return my->lookup_account_names( account_names );
770 }
771 
772 vector<optional<account_object>> database_api_impl::lookup_account_names(const vector<string>& account_names)const
773 {
774  return get_accounts( account_names, false );
775 }
776 
777 map<string, account_id_type, std::less<>> database_api::lookup_accounts( const string& lower_bound_name,
778  uint32_t limit,
779  const optional<bool>& subscribe )const
780 {
781  return my->lookup_accounts( lower_bound_name, limit, subscribe );
782 }
783 
784 map<string, account_id_type, std::less<>> database_api_impl::lookup_accounts( const string& lower_bound_name,
785  uint32_t limit,
786  const optional<bool>& subscribe )const
787 {
788  FC_ASSERT( _app_options, "Internal error" );
789  const auto configured_limit = _app_options->api_limit_lookup_accounts;
790  FC_ASSERT( limit <= configured_limit,
791  "limit can not be greater than ${configured_limit}",
792  ("configured_limit", configured_limit) );
793 
794  const auto& accounts_by_name = _db.get_index_type<account_index>().indices().get<by_name>();
795  map<string, account_id_type, std::less<>> result;
796 
797  if( limit == 0 ) // shortcut to save a database query
798  return result;
799  // In addition to the common auto-subscription rules, here we auto-subscribe if only look for one account
800  bool to_subscribe = (limit == 1 && get_whether_to_subscribe( subscribe ));
801  for( auto itr = accounts_by_name.lower_bound(lower_bound_name);
802  limit > 0 && itr != accounts_by_name.end();
803  ++itr, --limit )
804  {
805  result.insert(make_pair(itr->name, itr->get_id()));
806  if( to_subscribe )
807  subscribe_to_item( itr->id );
808  }
809 
810  return result;
811 }
812 
814 {
815  return my->get_account_count();
816 }
817 
819 {
820  return _db.get_index_type<account_index>().indices().size();
821 }
822 
824 // //
825 // Balances //
826 // //
828 
829 vector<asset> database_api::get_account_balances( const std::string& account_name_or_id,
830  const flat_set<asset_id_type>& assets )const
831 {
832  return my->get_account_balances( account_name_or_id, assets );
833 }
834 
835 vector<asset> database_api_impl::get_account_balances( const std::string& account_name_or_id,
836  const flat_set<asset_id_type>& assets )const
837 {
838  const account_object* account = get_account_from_string(account_name_or_id);
839  account_id_type acnt = account->get_id();
840  vector<asset> result;
841  if (assets.empty())
842  {
843  // if the caller passes in an empty list of assets, return balances for all assets the account owns
845  const auto& balances = balance_index.get_secondary_index< balances_by_account_index >()
846  .get_account_balances( acnt );
847  for( const auto& balance : balances )
848  result.push_back( balance.second->get_balance() );
849  }
850  else
851  {
852  result.reserve(assets.size());
853 
854  std::transform(assets.begin(), assets.end(), std::back_inserter(result),
855  [this, acnt](asset_id_type id) { return _db.get_balance(acnt, id); });
856  }
857 
858  return result;
859 }
860 
861 vector<asset> database_api::get_named_account_balances( const std::string& name,
862  const flat_set<asset_id_type>& assets )const
863 {
864  return my->get_account_balances( name, assets );
865 }
866 
867 vector<balance_object> database_api::get_balance_objects( const vector<address>& addrs )const
868 {
869  return my->get_balance_objects( addrs );
870 }
871 
872 vector<balance_object> database_api_impl::get_balance_objects( const vector<address>& addrs )const
873 {
874  try
875  {
876  const auto& bal_idx = _db.get_index_type<balance_index>();
877  const auto& by_owner_idx = bal_idx.indices().get<by_owner>();
878 
879  vector<balance_object> result;
880 
881  for( const auto& owner : addrs )
882  {
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 )
885  {
886  result.push_back( *itr );
887  ++itr;
888  }
889  }
890  return result;
891  }
892  FC_CAPTURE_AND_RETHROW( (addrs) )
893 }
894 
895 vector<asset> database_api::get_vested_balances( const vector<balance_id_type>& objs )const
896 {
897  return my->get_vested_balances( objs );
898 }
899 
900 vector<asset> database_api_impl::get_vested_balances( const vector<balance_id_type>& objs )const
901 {
902  try
903  {
904  vector<asset> result;
905  result.reserve( objs.size() );
906  auto now = _db.head_block_time();
907  for( auto obj : objs )
908  result.push_back( obj(_db).available( now ) );
909  return result;
910  } FC_CAPTURE_AND_RETHROW( (objs) )
911 }
912 
913 vector<vesting_balance_object> database_api::get_vesting_balances( const std::string account_id_or_name )const
914 {
915  return my->get_vesting_balances( account_id_or_name );
916 }
917 
918 vector<vesting_balance_object> database_api_impl::get_vesting_balances( const std::string account_id_or_name )const
919 {
920  try
921  {
922  const account_id_type account_id = get_account_from_string(account_id_or_name)->get_id();
923  vector<vesting_balance_object> result;
924  auto vesting_range = _db.get_index_type<vesting_balance_index>().indices().get<by_account>()
925  .equal_range(account_id);
926  std::for_each(vesting_range.first, vesting_range.second,
927  [&result](const vesting_balance_object& balance) {
928  result.emplace_back(balance);
929  });
930  return result;
931  }
932  FC_CAPTURE_AND_RETHROW( (account_id_or_name) );
933 }
934 
936 // //
937 // Assets //
938 // //
940 
941 asset_id_type database_api::get_asset_id_from_string(const std::string& symbol_or_id)const
942 {
943  return my->get_asset_from_string( symbol_or_id )->get_id();
944 }
945 
946 vector<optional<extended_asset_object>> database_api::get_assets(
947  const vector<std::string>& asset_symbols_or_ids,
948  optional<bool> subscribe )const
949 {
950  return my->get_assets( asset_symbols_or_ids, subscribe );
951 }
952 
953 vector<optional<extended_asset_object>> database_api_impl::get_assets(
954  const vector<std::string>& asset_symbols_or_ids,
955  optional<bool> subscribe )const
956 {
957  bool to_subscribe = get_whether_to_subscribe( subscribe );
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> {
961 
962  const asset_object* asset_obj = get_asset_from_string( id_or_name, false );
963  if( asset_obj == nullptr )
964  return {};
965  if( to_subscribe )
966  subscribe_to_item( asset_obj->id );
967  return extend_asset( *asset_obj );
968  });
969  return result;
970 }
971 
972 vector<extended_asset_object> database_api::list_assets(const string& lower_bound_symbol, uint32_t limit)const
973 {
974  return my->list_assets( lower_bound_symbol, limit );
975 }
976 
977 vector<extended_asset_object> database_api_impl::list_assets(const string& lower_bound_symbol, uint32_t limit)const
978 {
979  FC_ASSERT( _app_options, "Internal error" );
980  const auto configured_limit = _app_options->api_limit_get_assets;
981  FC_ASSERT( limit <= configured_limit,
982  "limit can not be greater than ${configured_limit}",
983  ("configured_limit", configured_limit) );
984 
985  const auto& assets_by_symbol = _db.get_index_type<asset_index>().indices().get<by_symbol>();
986  vector<extended_asset_object> result;
987  result.reserve(limit);
988 
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 )
992  result.emplace_back( extend_asset( *itr ) );
993 
994  return result;
995 }
996 
998 {
999  return my->get_asset_count();
1000 }
1001 
1003 {
1004  return _db.get_index_type<asset_index>().indices().size();
1005 }
1006 
1007 vector<extended_asset_object> database_api::get_assets_by_issuer(const std::string& issuer_name_or_id,
1008  asset_id_type start, uint32_t limit)const
1009 {
1010  return my->get_assets_by_issuer(issuer_name_or_id, start, limit);
1011 }
1012 
1013 vector<extended_asset_object> database_api_impl::get_assets_by_issuer(const std::string& issuer_name_or_id,
1014  asset_id_type start, uint32_t limit)const
1015 {
1016  FC_ASSERT( _app_options, "Internal error" );
1017  const auto configured_limit = _app_options->api_limit_get_assets;
1018  FC_ASSERT( limit <= configured_limit,
1019  "limit can not be greater than ${configured_limit}",
1020  ("configured_limit", configured_limit) );
1021 
1022  vector<extended_asset_object> result;
1023  const account_id_type account = get_account_from_string(issuer_name_or_id)->get_id();
1024  const auto& asset_idx = _db.get_index_type<asset_index>().indices().get<by_issuer>();
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)
1028  {
1029  result.emplace_back( extend_asset( *asset_itr ) );
1030  ++asset_itr;
1031  }
1032  return result;
1033 }
1034 
1035 vector<optional<extended_asset_object>> database_api::lookup_asset_symbols(
1036  const vector<string>& symbols_or_ids )const
1037 {
1038  return my->lookup_asset_symbols( symbols_or_ids );
1039 }
1040 
1041 vector<optional<extended_asset_object>> database_api_impl::lookup_asset_symbols(
1042  const vector<string>& symbols_or_ids )const
1043 {
1044  return get_assets( symbols_or_ids, false );
1045 }
1046 
1048 // //
1049 // Markets / feeds //
1050 // //
1052 
1053 vector<limit_order_object> database_api::get_limit_orders(std::string a, std::string b, uint32_t limit)const
1054 {
1055  return my->get_limit_orders( a, b, limit );
1056 }
1057 
1058 vector<limit_order_object> database_api_impl::get_limit_orders( const std::string& a, const std::string& b,
1059  uint32_t limit )const
1060 {
1061  FC_ASSERT( _app_options, "Internal error" );
1062  const auto configured_limit = _app_options->api_limit_get_limit_orders;
1063  FC_ASSERT( limit <= configured_limit,
1064  "limit can not be greater than ${configured_limit}",
1065  ("configured_limit", configured_limit) );
1066 
1067  const asset_id_type asset_a_id = get_asset_from_string(a)->get_id();
1068  const asset_id_type asset_b_id = get_asset_from_string(b)->get_id();
1069 
1070  return get_limit_orders(asset_a_id, asset_b_id, limit);
1071 }
1072 
1073 vector<limit_order_object> database_api::get_limit_orders_by_account( const string& account_name_or_id,
1074  const optional<uint32_t>& limit, const optional<limit_order_id_type>& start_id )
1075 {
1076  return my->get_limit_orders_by_account( account_name_or_id, limit, start_id );
1077 }
1078 
1079 vector<limit_order_object> database_api_impl::get_limit_orders_by_account( const string& account_name_or_id,
1080  const optional<uint32_t>& olimit, const optional<limit_order_id_type>& ostart_id )
1081 {
1082  FC_ASSERT( _app_options, "Internal error" );
1083  const auto configured_limit = _app_options->api_limit_get_limit_orders_by_account;
1084  uint32_t limit = olimit.valid() ? *olimit : configured_limit;
1085  FC_ASSERT( limit <= configured_limit,
1086  "limit can not be greater than ${configured_limit}",
1087  ("configured_limit", configured_limit) );
1088 
1089  vector<limit_order_object> results;
1090 
1091  const account_object* account = get_account_from_string(account_name_or_id);
1092  if (account == nullptr)
1093  return results;
1094 
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 };
1097 
1098  const auto& index_by_account = _db.get_index_type<limit_order_index>().indices().get<by_account>();
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() );
1101 
1102  results.reserve( limit );
1103  uint32_t count = 0;
1104  for ( ; lower_itr != upper_itr && count < limit; ++lower_itr, ++count)
1105  {
1106  const limit_order_object &order = *lower_itr;
1107  results.emplace_back(order);
1108  }
1109 
1110  return results;
1111 }
1112 
1113 vector<limit_order_object> database_api::get_account_limit_orders(
1114  const string& account_name_or_id, const string &base, const string &quote,
1115  uint32_t limit, optional<limit_order_id_type> ostart_id, optional<price> ostart_price )
1116 {
1117  return my->get_account_limit_orders( account_name_or_id, base, quote, limit, ostart_id, ostart_price );
1118 }
1119 
1121  const string& account_name_or_id, const string &base, const string &quote,
1122  uint32_t limit, optional<limit_order_id_type> ostart_id, optional<price> ostart_price )
1123 {
1124  FC_ASSERT( _app_options, "Internal error" );
1125  const auto configured_limit = _app_options->api_limit_get_account_limit_orders;
1126  FC_ASSERT( limit <= configured_limit,
1127  "limit can not be greater than ${configured_limit}",
1128  ("configured_limit", configured_limit) );
1129 
1130  vector<limit_order_object> results;
1131  uint32_t count = 0;
1132 
1133  const account_object* account = get_account_from_string(account_name_or_id);
1134  if (account == nullptr)
1135  return results;
1136 
1137  auto assets = lookup_asset_symbols( {base, quote} );
1138  FC_ASSERT( assets[0], "Invalid base asset symbol: ${s}", ("s",base) );
1139  FC_ASSERT( assets[1], "Invalid quote asset symbol: ${s}", ("s",quote) );
1140 
1141  auto base_id = assets[0]->get_id();
1142  auto quote_id = assets[1]->get_id();
1143 
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");
1147  }
1148 
1149  const auto& index_by_account = _db.get_index_type<limit_order_index>().indices().get<by_account_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;
1152 
1153  // if both order_id and price are invalid, query the first page
1154  if ( !ostart_id.valid() && !ostart_price.valid() )
1155  {
1156  lower_itr = index_by_account.lower_bound(std::make_tuple(account->get_id(), price::max(base_id, quote_id)));
1157  }
1158  else if ( ostart_id.valid() )
1159  {
1160  object_id_type start_id { *ostart_id };
1161  // in case of the order been deleted during page querying
1162  const limit_order_object *p_loo = _db.find(*ostart_id);
1163 
1164  if ( !p_loo )
1165  {
1166  if ( ostart_price.valid() )
1167  {
1168  lower_itr = index_by_account.lower_bound(std::make_tuple(account->get_id(), *ostart_price, start_id));
1169  }
1170  else
1171  {
1172  // start order id been deleted, yet not provided price either
1173  FC_THROW("Order id invalid (maybe just been canceled?), and start price not provided");
1174  }
1175  }
1176  else
1177  {
1178  const limit_order_object &loo = *p_loo;
1179 
1180  // in case of the order not belongs to specified account or market
1181  FC_ASSERT(loo.sell_price.base.asset_id == base_id, "Order base asset inconsistent");
1182  FC_ASSERT(loo.sell_price.quote.asset_id == quote_id, "Order quote asset inconsistent with order");
1183  FC_ASSERT(loo.seller == account->get_id(), "Order not owned by specified account");
1184 
1185  lower_itr = index_by_account.lower_bound(std::make_tuple(account->get_id(), loo.sell_price, start_id));
1186  }
1187  }
1188  else
1189  {
1190  // if reach here start_price must be valid
1191  lower_itr = index_by_account.lower_bound(std::make_tuple(account->get_id(), *ostart_price));
1192  }
1193 
1194  upper_itr = index_by_account.upper_bound(std::make_tuple(account->get_id(), price::min(base_id, quote_id)));
1195 
1196  // Add the account's orders
1197  for ( ; lower_itr != upper_itr && count < limit; ++lower_itr, ++count)
1198  {
1199  const limit_order_object &order = *lower_itr;
1200  results.emplace_back(order);
1201  }
1202 
1203  return results;
1204 }
1205 
1206 vector<call_order_object> database_api::get_call_orders(const std::string& a, uint32_t limit)const
1207 {
1208  return my->get_call_orders( a, limit );
1209 }
1210 
1211 vector<call_order_object> database_api_impl::get_call_orders(const std::string& a, uint32_t limit)const
1212 {
1213  FC_ASSERT( _app_options, "Internal error" );
1214  const auto configured_limit = _app_options->api_limit_get_call_orders;
1215  FC_ASSERT( limit <= configured_limit,
1216  "limit can not be greater than ${configured_limit}",
1217  ("configured_limit", configured_limit) );
1218 
1219  const asset_object* mia = get_asset_from_string(a);
1220  const auto& call_index = _db.get_index_type<call_order_index>().indices().get<by_collateral>();
1221  price index_price = price::min( mia->bitasset_data(_db).options.short_backing_asset, mia->get_id() );
1222 
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 )
1227  {
1228  result.emplace_back(*itr_min);
1229  ++itr_min;
1230  }
1231  return result;
1232 }
1233 
1234 vector<call_order_object> database_api::get_call_orders_by_account(const std::string& account_name_or_id,
1235  asset_id_type start, uint32_t limit)const
1236 {
1237  return my->get_call_orders_by_account( account_name_or_id, start, limit );
1238 }
1239 
1240 vector<call_order_object> database_api_impl::get_call_orders_by_account(const std::string& account_name_or_id,
1241  asset_id_type start, uint32_t limit)const
1242 {
1243  FC_ASSERT( _app_options, "Internal error" );
1244  const auto configured_limit = _app_options->api_limit_get_call_orders;
1245  FC_ASSERT( limit <= configured_limit,
1246  "limit can not be greater than ${configured_limit}",
1247  ("configured_limit", configured_limit) );
1248 
1249  vector<call_order_object> result;
1250  const account_id_type account = get_account_from_string(account_name_or_id)->get_id();
1251  const auto& call_idx = _db.get_index_type<call_order_index>().indices().get<by_account>();
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)
1255  {
1256  result.push_back(*call_itr);
1257  ++call_itr;
1258  }
1259  return result;
1260 }
1261 
1262 vector<force_settlement_object> database_api::get_settle_orders(const std::string& a, uint32_t limit)const
1263 {
1264  return my->get_settle_orders( a, limit );
1265 }
1266 
1267 vector<force_settlement_object> database_api_impl::get_settle_orders(const std::string& a, uint32_t limit)const
1268 {
1269  FC_ASSERT( _app_options, "Internal error" );
1270  const auto configured_limit = _app_options->api_limit_get_settle_orders;
1271  FC_ASSERT( limit <= configured_limit,
1272  "limit can not be greater than ${configured_limit}",
1273  ("configured_limit", configured_limit) );
1274 
1275  const asset_id_type asset_a_id = get_asset_from_string(a)->get_id();
1276  const auto& settle_index = _db.get_index_type<force_settlement_index>().indices().get<by_expiration>();
1277  const asset_object& mia = _db.get(asset_a_id);
1278 
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 )
1283  {
1284  result.emplace_back(*itr_min);
1285  ++itr_min;
1286  }
1287  return result;
1288 }
1289 
1290 vector<force_settlement_object> database_api::get_settle_orders_by_account(
1291  const std::string& account_name_or_id,
1292  force_settlement_id_type start,
1293  uint32_t limit )const
1294 {
1295  return my->get_settle_orders_by_account( account_name_or_id, start, limit);
1296 }
1297 
1298 vector<force_settlement_object> database_api_impl::get_settle_orders_by_account(
1299  const std::string& account_name_or_id,
1300  force_settlement_id_type start,
1301  uint32_t limit )const
1302 {
1303  FC_ASSERT( _app_options, "Internal error" );
1304  const auto configured_limit = _app_options->api_limit_get_settle_orders;
1305  FC_ASSERT( limit <= configured_limit,
1306  "limit can not be greater than ${configured_limit}",
1307  ("configured_limit", configured_limit) );
1308 
1309  vector<force_settlement_object> result;
1310  const account_id_type account = get_account_from_string(account_name_or_id)->get_id();
1311  const auto& settle_idx = _db.get_index_type<force_settlement_index>().indices().get<by_account>();
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)
1315  {
1316  result.push_back(*settle_itr);
1317  ++settle_itr;
1318  }
1319  return result;
1320 }
1321 
1322 
1323 vector<call_order_object> database_api::get_margin_positions( const std::string& account_name_or_id )const
1324 {
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 );
1328 }
1329 
1330 vector<collateral_bid_object> database_api::get_collateral_bids( const std::string& asset,
1331  uint32_t limit, uint32_t start )const
1332 {
1333  return my->get_collateral_bids( asset, limit, start );
1334 }
1335 
1336 vector<collateral_bid_object> database_api_impl::get_collateral_bids( const std::string& asset_id_or_symbol,
1337  uint32_t limit, uint32_t skip )const
1338 { try {
1339  FC_ASSERT( _app_options, "Internal error" );
1340  const auto configured_limit = _app_options->api_limit_get_collateral_bids;
1341  FC_ASSERT( limit <= configured_limit,
1342  "limit can not be greater than ${configured_limit}",
1343  ("configured_limit", configured_limit) );
1344 
1345  const asset_object& swan = *get_asset_from_string(asset_id_or_symbol);
1346  FC_ASSERT( swan.is_market_issued(), "Asset is not a MPA" );
1347  const asset_id_type asset_id = swan.get_id();
1348  const auto& idx = _db.get_index_type<collateral_bid_index>().indices().get<by_price>();
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 )
1354  {
1355  result.push_back(*itr);
1356  }
1357  return result;
1358 } FC_CAPTURE_AND_RETHROW( (asset_id_or_symbol)(limit)(skip) ) }
1359 
1360 void database_api::subscribe_to_market( std::function<void(const variant&)> callback,
1361  const std::string& a, const std::string& b )
1362 {
1363  my->subscribe_to_market( callback, a, b );
1364 }
1365 
1366 void database_api_impl::subscribe_to_market( std::function<void(const variant&)> callback,
1367  const std::string& a, const std::string& b )
1368 {
1369  auto asset_a_id = get_asset_from_string(a)->get_id();
1370  auto asset_b_id = get_asset_from_string(b)->get_id();
1371 
1372  if(asset_a_id > asset_b_id) std::swap(asset_a_id,asset_b_id);
1373  FC_ASSERT(asset_a_id != asset_b_id);
1374  _market_subscriptions[ std::make_pair(asset_a_id,asset_b_id) ] = callback;
1375 }
1376 
1377 void database_api::unsubscribe_from_market(const std::string& a, const std::string& b)
1378 {
1379  my->unsubscribe_from_market( a, b );
1380 }
1381 
1382 void database_api_impl::unsubscribe_from_market(const std::string& a, const std::string& b)
1383 {
1384  auto asset_a_id = get_asset_from_string(a)->get_id();
1385  auto asset_b_id = get_asset_from_string(b)->get_id();
1386 
1387  if(a > b) std::swap(asset_a_id,asset_b_id);
1388  FC_ASSERT(asset_a_id != asset_b_id);
1389  _market_subscriptions.erase(std::make_pair(asset_a_id,asset_b_id));
1390 }
1391 
1392 market_ticker database_api::get_ticker( const string& base, const string& quote )const
1393 {
1394  return my->get_ticker( base, quote );
1395 }
1396 
1397 market_ticker database_api_impl::get_ticker( const string& base, const string& quote, bool skip_order_book )const
1398 {
1399  FC_ASSERT( _app_options && _app_options->has_market_history_plugin, "Market history plugin is not enabled." );
1400 
1401  const auto assets = lookup_asset_symbols( {base, quote} );
1402 
1403  FC_ASSERT( assets[0], "Invalid base asset symbol: ${s}", ("s",base) );
1404  FC_ASSERT( assets[1], "Invalid quote asset symbol: ${s}", ("s",quote) );
1405 
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 );
1409  const auto& ticker_idx = _db.get_index_type<market_ticker_index>().indices().get<by_market>();
1410  auto itr = ticker_idx.find( std::make_tuple( base_id, quote_id ) );
1411  const fc::time_point_sec now = _db.head_block_time();
1412  if( itr != ticker_idx.end() )
1413  {
1414  order_book orders;
1415  if (!skip_order_book)
1416  {
1417  orders = get_order_book(assets[0]->symbol, assets[1]->symbol, 1);
1418  }
1419  return market_ticker(*itr, now, *assets[0], *assets[1], orders);
1420  }
1421  // if no ticker is found for this market we return an empty ticker
1422  market_ticker empty_result(now, *assets[0], *assets[1]);
1423  return empty_result;
1424 }
1425 
1426 market_volume database_api::get_24_volume( const string& base, const string& quote )const
1427 {
1428  return my->get_24_volume( base, quote );
1429 }
1430 
1431 market_volume database_api_impl::get_24_volume( const string& base, const string& quote )const
1432 {
1433  const auto& ticker = get_ticker( base, quote, true );
1434 
1435  market_volume result;
1436  result.time = ticker.time;
1437  result.base = ticker.base;
1438  result.quote = ticker.quote;
1439  result.base_volume = ticker.base_volume;
1440  result.quote_volume = ticker.quote_volume;
1441 
1442  return result;
1443 }
1444 
1445 order_book database_api::get_order_book( const string& base, const string& quote, uint32_t limit )const
1446 {
1447  return my->get_order_book( base, quote, limit );
1448 }
1449 
1450 order_book database_api_impl::get_order_book( const string& base, const string& quote, uint32_t limit )const
1451 {
1452  FC_ASSERT( _app_options, "Internal error" );
1453  const auto configured_limit = _app_options->api_limit_get_order_book;
1454  FC_ASSERT( limit <= configured_limit,
1455  "limit can not be greater than ${configured_limit}",
1456  ("configured_limit", configured_limit) );
1457 
1458  order_book result( base, quote );
1459 
1460  auto assets = lookup_asset_symbols( {base, quote} );
1461  FC_ASSERT( assets[0], "Invalid base asset symbol: ${s}", ("s",base) );
1462  FC_ASSERT( assets[1], "Invalid quote asset symbol: ${s}", ("s",quote) );
1463 
1464  auto base_id = assets[0]->get_id();
1465  auto quote_id = assets[1]->get_id();
1466  auto orders = get_limit_orders( base_id, quote_id, limit );
1467 
1468  for( const auto& o : orders )
1469  {
1470  auto order_price = price_to_string( o.sell_price, *assets[0], *assets[1] );
1471  if( o.sell_price.base.asset_id == base_id )
1472  {
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 );
1479  }
1480  else
1481  {
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 );
1488  }
1489  }
1490 
1491  return result;
1492 }
1493 
1494 vector<market_ticker> database_api::get_top_markets(uint32_t limit)const
1495 {
1496  return my->get_top_markets(limit);
1497 }
1498 
1499 vector<market_ticker> database_api_impl::get_top_markets(uint32_t limit)const
1500 {
1501  FC_ASSERT( _app_options && _app_options->has_market_history_plugin, "Market history plugin is not enabled." );
1502 
1503  const auto configured_limit = _app_options->api_limit_get_top_markets;
1504  FC_ASSERT( limit <= configured_limit,
1505  "limit can not be greater than ${configured_limit}",
1506  ("configured_limit", configured_limit) );
1507 
1508  const auto& volume_idx = _db.get_index_type<market_ticker_index>().indices().get<by_volume>();
1509  auto itr = volume_idx.rbegin();
1510  vector<market_ticker> result;
1511  result.reserve(limit);
1512  const fc::time_point_sec now = _db.head_block_time();
1513 
1514  while( itr != volume_idx.rend() && result.size() < limit)
1515  {
1516  const asset_object base = itr->base(_db);
1517  const asset_object quote = itr->quote(_db);
1518  order_book orders;
1519  orders = get_order_book(base.symbol, quote.symbol, 1);
1520 
1521  result.emplace_back(market_ticker(*itr, now, base, quote, orders));
1522  ++itr;
1523  }
1524  return result;
1525 }
1526 
1527 vector<market_trade> database_api::get_trade_history( const string& base,
1528  const string& quote,
1529  fc::time_point_sec start,
1530  fc::time_point_sec stop,
1531  uint32_t limit )const
1532 {
1533  return my->get_trade_history( base, quote, start, stop, limit );
1534 }
1535 
1536 vector<market_trade> database_api_impl::get_trade_history( const string& base,
1537  const string& quote,
1538  fc::time_point_sec start,
1539  fc::time_point_sec stop,
1540  uint32_t limit )const
1541 {
1542  FC_ASSERT( _app_options && _app_options->has_market_history_plugin, "Market history plugin is not enabled." );
1543 
1544  const auto configured_limit = _app_options->api_limit_get_trade_history;
1545  FC_ASSERT( limit <= configured_limit,
1546  "limit can not be greater than ${configured_limit}",
1547  ("configured_limit", configured_limit) );
1548 
1549  auto assets = lookup_asset_symbols( {base, quote} );
1550  FC_ASSERT( assets[0], "Invalid base asset symbol: ${s}", ("s",base) );
1551  FC_ASSERT( assets[1], "Invalid quote asset symbol: ${s}", ("s",quote) );
1552 
1553  auto base_id = assets[0]->get_id();
1554  auto quote_id = assets[1]->get_id();
1555 
1556  if( base_id > quote_id ) std::swap( base_id, quote_id );
1557 
1558  if ( start.sec_since_epoch() == 0 )
1560 
1561  uint32_t count = 0;
1562  const auto& history_idx = _db.get_index_type<market_history::history_index>().indices().get<by_market_time>();
1563  auto itr = history_idx.lower_bound( std::make_tuple( base_id, quote_id, start ) );
1564  vector<market_trade> result;
1565 
1566  while( itr != history_idx.end() && count < limit
1567  && !( itr->key.base != base_id || itr->key.quote != quote_id || itr->time < stop ) )
1568  {
1569  {
1570  market_trade trade;
1571 
1572  if( assets[0]->id == itr->op.receives.asset_id )
1573  {
1574  trade.amount = assets[1]->amount_to_string( itr->op.pays );
1575  trade.value = assets[0]->amount_to_string( itr->op.receives );
1576  }
1577  else
1578  {
1579  trade.amount = assets[1]->amount_to_string( itr->op.receives );
1580  trade.value = assets[0]->amount_to_string( itr->op.pays );
1581  }
1582 
1583  trade.date = itr->time;
1584  trade.price = price_to_string( itr->op.fill_price, *assets[0], *assets[1] );
1585 
1586  if( itr->op.is_maker )
1587  {
1588  trade.sequence = -itr->key.sequence;
1589  trade.side1_account_id = itr->op.account_id;
1590  if(itr->op.receives.asset_id == assets[0]->id)
1591  trade.type = "sell";
1592  else
1593  trade.type = "buy";
1594  }
1595  else
1596  trade.side2_account_id = itr->op.account_id;
1597 
1598  auto next_itr = std::next(itr);
1599  // Trades are usually tracked in each direction, exception: for global settlement only one side is recorded
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 )
1602  { // next_itr now could be the other direction // FIXME not 100% sure
1603  if( next_itr->op.is_maker )
1604  {
1605  trade.sequence = -next_itr->key.sequence;
1606  trade.side1_account_id = next_itr->op.account_id;
1607  if(next_itr->op.receives.asset_id == assets[0]->id)
1608  trade.type = "sell";
1609  else
1610  trade.type = "buy";
1611  }
1612  else
1613  trade.side2_account_id = next_itr->op.account_id;
1614  // skip the other direction
1615  itr = next_itr;
1616  }
1617 
1618  result.push_back( trade );
1619  ++count;
1620  }
1621 
1622  ++itr;
1623  }
1624 
1625  return result;
1626 }
1627 
1629  const string& base,
1630  const string& quote,
1631  int64_t start,
1632  fc::time_point_sec stop,
1633  uint32_t limit )const
1634 {
1635  return my->get_trade_history_by_sequence( base, quote, start, stop, limit );
1636 }
1637 
1639  const string& base,
1640  const string& quote,
1641  int64_t start,
1642  fc::time_point_sec stop,
1643  uint32_t limit )const
1644 {
1645  FC_ASSERT( _app_options && _app_options->has_market_history_plugin, "Market history plugin is not enabled." );
1646 
1647  const auto configured_limit = _app_options->api_limit_get_trade_history_by_sequence;
1648  FC_ASSERT( limit <= configured_limit,
1649  "limit can not be greater than ${configured_limit}",
1650  ("configured_limit", configured_limit) );
1651 
1652  FC_ASSERT( start >= 0 );
1653  int64_t start_seq = -start;
1654 
1655  auto assets = lookup_asset_symbols( {base, quote} );
1656  FC_ASSERT( assets[0], "Invalid base asset symbol: ${s}", ("s",base) );
1657  FC_ASSERT( assets[1], "Invalid quote asset symbol: ${s}", ("s",quote) );
1658 
1659  auto base_id = assets[0]->get_id();
1660  auto quote_id = assets[1]->get_id();
1661 
1662  if( base_id > quote_id ) std::swap( base_id, quote_id );
1663  const auto& history_idx = _db.get_index_type<graphene::market_history::history_index>().indices().get<by_key>();
1664  history_key hkey;
1665  hkey.base = base_id;
1666  hkey.quote = quote_id;
1667  hkey.sequence = start_seq;
1668 
1669  uint32_t count = 0;
1670  auto itr = history_idx.lower_bound( hkey );
1671  vector<market_trade> result;
1672 
1673  while( itr != history_idx.end() && count < limit
1674  && !( itr->key.base != base_id || itr->key.quote != quote_id || itr->time < stop ) )
1675  {
1676  if( itr->key.sequence == start_seq ) // found the key, should skip this and the other direction if found
1677  {
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 )
1681  { // next_itr now could be the other direction // FIXME not 100% sure
1682  // skip the other direction
1683  itr = next_itr;
1684  }
1685  }
1686  else
1687  {
1688  market_trade trade;
1689 
1690  if( assets[0]->id == itr->op.receives.asset_id )
1691  {
1692  trade.amount = assets[1]->amount_to_string( itr->op.pays );
1693  trade.value = assets[0]->amount_to_string( itr->op.receives );
1694  }
1695  else
1696  {
1697  trade.amount = assets[1]->amount_to_string( itr->op.receives );
1698  trade.value = assets[0]->amount_to_string( itr->op.pays );
1699  }
1700 
1701  trade.date = itr->time;
1702  trade.price = price_to_string( itr->op.fill_price, *assets[0], *assets[1] );
1703 
1704  if( itr->op.is_maker )
1705  {
1706  trade.sequence = -itr->key.sequence;
1707  trade.side1_account_id = itr->op.account_id;
1708  if(itr->op.receives.asset_id == assets[0]->id)
1709  trade.type = "sell";
1710  else
1711  trade.type = "buy";
1712  }
1713  else
1714  trade.side2_account_id = itr->op.account_id;
1715 
1716  auto next_itr = std::next(itr);
1717  // Trades are usually tracked in each direction, exception: for global settlement only one side is recorded
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 )
1720  { // next_itr now could be the other direction // FIXME not 100% sure
1721  if( next_itr->op.is_maker )
1722  {
1723  trade.sequence = -next_itr->key.sequence;
1724  trade.side1_account_id = next_itr->op.account_id;
1725  if(next_itr->op.receives.asset_id == assets[0]->id)
1726  trade.type = "sell";
1727  else
1728  trade.type = "buy";
1729  }
1730  else
1731  trade.side2_account_id = next_itr->op.account_id;
1732  // skip the other direction
1733  itr = next_itr;
1734  }
1735 
1736  result.push_back( trade );
1737  ++count;
1738  }
1739 
1740  ++itr;
1741  }
1742 
1743  return result;
1744 }
1745 
1747 // //
1748 // Liquidity pools //
1749 // //
1751 
1752 vector<extended_liquidity_pool_object> database_api::list_liquidity_pools(
1753  const optional<uint32_t>& limit,
1754  const optional<liquidity_pool_id_type>& start_id,
1755  const optional<bool>& with_statistics )const
1756 {
1757  return my->get_liquidity_pools_by_asset_x<by_id>(
1758  limit,
1759  start_id,
1760  with_statistics );
1761 }
1762 
1763 vector<extended_liquidity_pool_object> database_api::get_liquidity_pools_by_asset_a(
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
1768 {
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>(
1771  limit,
1772  start_id,
1773  with_statistics,
1774  asset_id );
1775 }
1776 
1777 vector<extended_liquidity_pool_object> database_api::get_liquidity_pools_by_asset_b(
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
1782 {
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>(
1785  limit,
1786  start_id,
1787  with_statistics,
1788  asset_id );
1789 }
1790 
1791 vector<extended_liquidity_pool_object> database_api::get_liquidity_pools_by_one_asset(
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
1796 {
1797  return my->get_liquidity_pools_by_one_asset(
1798  asset_symbol_or_id,
1799  limit,
1800  start_id,
1801  with_statistics );
1802 }
1803 
1804 vector<extended_liquidity_pool_object> database_api_impl::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
1809 {
1810  // api_helper_indexes plugin is required for accessing the secondary index
1812  "api_helper_indexes plugin is not enabled on this server." );
1813 
1814  const auto configured_limit = _app_options->api_limit_get_liquidity_pools;
1815  uint32_t limit = olimit.valid() ? *olimit : configured_limit;
1816  FC_ASSERT( limit <= configured_limit,
1817  "limit can not be greater than ${configured_limit}",
1818  ("configured_limit", configured_limit) );
1819 
1820  asset_id_type aid = get_asset_from_string(asset_symbol_or_id)->get_id();
1821 
1822  FC_ASSERT( asset_in_liquidity_pools_index, "Internal error" );
1824 
1825  liquidity_pool_id_type start_id = ostart_id.valid() ? *ostart_id : liquidity_pool_id_type();
1826 
1827  auto itr = pools.lower_bound( start_id );
1828 
1829  bool with_stats = ( with_statistics.valid() && *with_statistics );
1830 
1831  vector<extended_liquidity_pool_object> results;
1832 
1833  results.reserve( limit );
1834  while( itr != pools.end() && results.size() < limit )
1835  {
1836  results.emplace_back( extend_liquidity_pool( (*itr)(_db), with_stats ) );
1837  ++itr;
1838  }
1839 
1840  return results;
1841 }
1842 
1843 vector<extended_liquidity_pool_object> database_api::get_liquidity_pools_by_both_assets(
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
1849 {
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>(
1855  limit,
1856  start_id,
1857  with_statistics,
1858  asset_id_a,
1859  asset_id_b );
1860 }
1861 
1862 vector<optional<extended_liquidity_pool_object>> database_api::get_liquidity_pools(
1863  const vector<liquidity_pool_id_type>& ids,
1864  const optional<bool>& subscribe,
1865  const optional<bool>& with_statistics )const
1866 {
1867  return my->get_liquidity_pools(
1868  ids,
1869  subscribe,
1870  with_statistics );
1871 }
1872 
1873 vector<optional<extended_liquidity_pool_object>> database_api_impl::get_liquidity_pools(
1874  const vector<liquidity_pool_id_type>& ids,
1875  const optional<bool>& subscribe,
1876  const optional<bool>& with_statistics )const
1877 {
1878  FC_ASSERT( _app_options, "Internal error" );
1879  const auto configured_limit = _app_options->api_limit_get_liquidity_pools;
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) );
1883 
1884  bool with_stats = ( with_statistics.valid() && *with_statistics );
1885 
1886  bool to_subscribe = get_whether_to_subscribe( subscribe );
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> {
1891 
1892  if(auto o = _db.find(id))
1893  {
1894  auto ext_obj = extend_liquidity_pool( *o, with_stats );
1895  if( to_subscribe )
1896  {
1897  subscribe_to_item( id );
1898  if( ext_obj.statistics.valid() )
1899  subscribe_to_item( ext_obj.statistics->id );
1900  }
1901  return ext_obj;
1902  }
1903  return {};
1904  });
1905  return result;
1906 }
1907 
1908 vector<optional<extended_liquidity_pool_object>> database_api::get_liquidity_pools_by_share_asset(
1909  const vector<std::string>& asset_symbols_or_ids,
1910  const optional<bool>& subscribe,
1911  const optional<bool>& with_statistics )const
1912 {
1913  return my->get_liquidity_pools_by_share_asset(
1914  asset_symbols_or_ids,
1915  subscribe,
1916  with_statistics );
1917 }
1918 
1919 vector<optional<extended_liquidity_pool_object>> database_api_impl::get_liquidity_pools_by_share_asset(
1920  const vector<std::string>& asset_symbols_or_ids,
1921  const optional<bool>& subscribe,
1922  const optional<bool>& with_statistics )const
1923 {
1924  FC_ASSERT( _app_options, "Internal error" );
1925  const auto configured_limit = _app_options->api_limit_get_liquidity_pools;
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) );
1929 
1930  bool with_stats = ( with_statistics.valid() && *with_statistics );
1931 
1932  bool to_subscribe = get_whether_to_subscribe( subscribe );
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> {
1936 
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() )
1939  return {};
1940  const liquidity_pool_object& lp_obj = (*asset_obj->for_liquidity_pool)(_db);
1941  auto ext_obj = extend_liquidity_pool( lp_obj, with_stats );
1942  if( to_subscribe )
1943  {
1944  subscribe_to_item( lp_obj.id );
1945  if( ext_obj.statistics.valid() )
1946  subscribe_to_item( ext_obj.statistics->id );
1947  }
1948  return ext_obj;
1949  });
1950  return result;
1951 }
1952 
1953 vector<extended_liquidity_pool_object> database_api::get_liquidity_pools_by_owner(
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
1958 {
1959  return my->get_liquidity_pools_by_owner(
1960  account_name_or_id,
1961  limit,
1962  start_id,
1963  with_statistics );
1964 }
1965 
1966 vector<extended_liquidity_pool_object> database_api_impl::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
1971 {
1972  FC_ASSERT( _app_options, "Internal error" );
1973  const auto configured_limit = _app_options->api_limit_get_liquidity_pools;
1974  uint32_t limit = olimit.valid() ? *olimit : configured_limit;
1975  FC_ASSERT( limit <= configured_limit,
1976  "limit can not be greater than ${configured_limit}",
1977  ("configured_limit", configured_limit) );
1978 
1979  bool with_stats = ( with_statistics.valid() && *with_statistics );
1980 
1981  vector<extended_liquidity_pool_object> results;
1982 
1983  account_id_type owner = get_account_from_string(account_name_or_id)->get_id();
1984 
1985  asset_id_type start_asset_id = ostart_id.valid() ? *ostart_id : asset_id_type();
1986  object_id_type start_id { start_asset_id };
1987 
1988  // get assets owned by account
1989  const auto& idx = _db.get_index_type<asset_index>().indices().get<by_issuer>();
1990  auto lower_itr = idx.lower_bound( std::make_tuple( owner, start_id ) );
1991  auto upper_itr = idx.upper_bound( owner );
1992 
1993  results.reserve( limit );
1994  for ( ; lower_itr != upper_itr && results.size() < limit; ++lower_itr )
1995  {
1996  const asset_object& asset_obj = *lower_itr;
1997  if( !asset_obj.is_liquidity_pool_share_asset() ) // TODO improve performance
1998  continue;
1999  results.emplace_back( extend_liquidity_pool( (*asset_obj.for_liquidity_pool)(_db), with_stats ) );
2000  }
2001 
2002  return results;
2003 }
2004 
2006 // //
2007 // SameT Funds //
2008 // //
2010 
2011 vector<samet_fund_object> database_api::list_samet_funds(
2012  const optional<uint32_t>& limit,
2013  const optional<samet_fund_id_type>& start_id )const
2014 {
2015  const auto& idx = my->_db.get_index_type<samet_fund_index>().indices().get<by_id>();
2016  return my->get_objects_by_x< samet_fund_object,
2017  samet_fund_id_type
2019  idx, limit, start_id );
2020 }
2021 
2022 vector<samet_fund_object> database_api::get_samet_funds_by_owner(
2023  const std::string& account_name_or_id,
2024  const optional<uint32_t>& limit,
2025  const optional<samet_fund_id_type>& start_id )const
2026 {
2027  account_id_type owner = my->get_account_from_string(account_name_or_id)->get_id();
2028  const auto& idx = my->_db.get_index_type<samet_fund_index>().indices().get<by_owner>();
2029  return my->get_objects_by_x< samet_fund_object,
2030  samet_fund_id_type
2032  idx, limit, start_id, owner );
2033 }
2034 
2035 vector<samet_fund_object> database_api::get_samet_funds_by_asset(
2036  const std::string& asset_symbol_or_id,
2037  const optional<uint32_t>& limit,
2038  const optional<samet_fund_id_type>& start_id )const
2039 {
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>();
2042  return my->get_objects_by_x< samet_fund_object,
2043  samet_fund_id_type
2045  idx, limit, start_id, asset_type );
2046 }
2047 
2048 
2050 // //
2051 // Credit offers and credit deals //
2052 // //
2054 
2055 vector<credit_offer_object> database_api::list_credit_offers(
2056  const optional<uint32_t>& limit,
2057  const optional<credit_offer_id_type>& start_id )const
2058 {
2059  const auto& idx = my->_db.get_index_type<credit_offer_index>().indices().get<by_id>();
2060  return my->get_objects_by_x< credit_offer_object,
2061  credit_offer_id_type
2063  idx, limit, start_id );
2064 }
2065 
2066 vector<credit_offer_object> database_api::get_credit_offers_by_owner(
2067  const std::string& account_name_or_id,
2068  const optional<uint32_t>& limit,
2069  const optional<credit_offer_id_type>& start_id )const
2070 {
2071  account_id_type owner = my->get_account_from_string(account_name_or_id)->get_id();
2072  const auto& idx = my->_db.get_index_type<credit_offer_index>().indices().get<by_owner>();
2073  return my->get_objects_by_x< credit_offer_object,
2074  credit_offer_id_type
2076  idx, limit, start_id, owner );
2077 }
2078 
2079 vector<credit_offer_object> database_api::get_credit_offers_by_asset(
2080  const std::string& asset_symbol_or_id,
2081  const optional<uint32_t>& limit,
2082  const optional<credit_offer_id_type>& start_id )const
2083 {
2084  asset_id_type asset_type = my->get_asset_from_string(asset_symbol_or_id)->get_id();
2085  const auto& idx = my->_db.get_index_type<credit_offer_index>().indices().get<by_asset_type>();
2086  return my->get_objects_by_x< credit_offer_object,
2087  credit_offer_id_type
2089  idx, limit, start_id, asset_type );
2090 }
2091 
2092 vector<credit_deal_object> database_api::list_credit_deals(
2093  const optional<uint32_t>& limit,
2094  const optional<credit_deal_id_type>& start_id )const
2095 {
2096  const auto& idx = my->_db.get_index_type<credit_deal_index>().indices().get<by_id>();
2097  return my->get_objects_by_x< credit_deal_object,
2098  credit_deal_id_type
2100  idx, limit, start_id );
2101 }
2102 
2104  const credit_offer_id_type& offer_id,
2105  const optional<uint32_t>& limit,
2106  const optional<credit_deal_id_type>& start_id )const
2107 {
2108  const auto& idx = my->_db.get_index_type<credit_deal_index>().indices().get<by_offer_id>();
2109  return my->get_objects_by_x< credit_deal_object,
2110  credit_deal_id_type
2112  idx, limit, start_id, offer_id );
2113 }
2114 
2116  const std::string& account_name_or_id,
2117  const optional<uint32_t>& limit,
2118  const optional<credit_deal_id_type>& start_id )const
2119 {
2120  account_id_type owner = my->get_account_from_string(account_name_or_id)->get_id();
2121  const auto& idx = my->_db.get_index_type<credit_deal_index>().indices().get<by_offer_owner>();
2122  return my->get_objects_by_x< credit_deal_object,
2123  credit_deal_id_type
2125  idx, limit, start_id, owner );
2126 }
2127 
2129  const std::string& account_name_or_id,
2130  const optional<uint32_t>& limit,
2131  const optional<credit_deal_id_type>& start_id )const
2132 {
2133  account_id_type borrower = my->get_account_from_string(account_name_or_id)->get_id();
2134  const auto& idx = my->_db.get_index_type<credit_deal_index>().indices().get<by_borrower>();
2135  return my->get_objects_by_x< credit_deal_object,
2136  credit_deal_id_type
2138  idx, limit, start_id, borrower );
2139 }
2140 
2142  const std::string& asset_symbol_or_id,
2143  const optional<uint32_t>& limit,
2144  const optional<credit_deal_id_type>& start_id )const
2145 {
2146  asset_id_type asset_type = my->get_asset_from_string(asset_symbol_or_id)->get_id();
2147  const auto& idx = my->_db.get_index_type<credit_deal_index>().indices().get<by_debt_asset>();
2148  return my->get_objects_by_x< credit_deal_object,
2149  credit_deal_id_type
2151  idx, limit, start_id, asset_type );
2152 }
2153 
2155  const std::string& asset_symbol_or_id,
2156  const optional<uint32_t>& limit,
2157  const optional<credit_deal_id_type>& start_id )const
2158 {
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>();
2161  return my->get_objects_by_x< credit_deal_object,
2162  credit_deal_id_type
2164  idx, limit, start_id, asset_type );
2165 }
2166 
2167 
2169 // //
2170 // Witnesses //
2171 // //
2173 
2174 vector<optional<witness_object>> database_api::get_witnesses(const vector<witness_id_type>& witness_ids)const
2175 {
2176  return my->get_witnesses( witness_ids );
2177 }
2178 
2179 vector<optional<witness_object>> database_api_impl::get_witnesses(const vector<witness_id_type>& witness_ids)const
2180 {
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))
2185  return *o;
2186  return {};
2187  });
2188  return result;
2189 }
2190 
2191 fc::optional<witness_object> database_api::get_witness_by_account(const std::string& account_id_or_name)const
2192 {
2193  return my->get_witness_by_account( account_id_or_name );
2194 }
2195 
2197 {
2198  const auto& idx = _db.get_index_type<witness_index>().indices().get<by_account>();
2199  const account_id_type account = get_account_from_string(account_id_or_name)->get_id();
2200  auto itr = idx.find(account);
2201  if( itr != idx.end() )
2202  return *itr;
2203  return {};
2204 }
2205 
2206 map<string, witness_id_type, std::less<>> database_api::lookup_witness_accounts( const string& lower_bound_name,
2207  uint32_t limit )const
2208 {
2209  return my->lookup_witness_accounts( lower_bound_name, limit );
2210 }
2211 
2212 map<string, witness_id_type, std::less<>> database_api_impl::lookup_witness_accounts( const string& lower_bound_name,
2213  uint32_t limit )const
2214 {
2215  FC_ASSERT( _app_options, "Internal error" );
2216  const auto configured_limit = _app_options->api_limit_lookup_witness_accounts;
2217  FC_ASSERT( limit <= configured_limit,
2218  "limit can not be greater than ${configured_limit}",
2219  ("configured_limit", configured_limit) );
2220 
2221  const auto& witnesses_by_id = _db.get_index_type<witness_index>().indices().get<by_id>();
2222 
2223  // we want to order witnesses by account name, but that name is in the account object
2224  // so the witness_index doesn't have a quick way to access it.
2225  // get all the names and look them all up, sort them, then figure out what
2226  // records to return. This could be optimized, but we expect the
2227  // number of witnesses to be few and the frequency of calls to be rare
2228  // TODO optimize
2229  std::map<std::string, witness_id_type, std::less<>> witnesses_by_account_name;
2230  for (const witness_object& witness : witnesses_by_id)
2231  if (auto account_iter = _db.find(witness.witness_account))
2232  if (account_iter->name >= lower_bound_name) // we can ignore anything below lower_bound_name
2233  witnesses_by_account_name.insert(std::make_pair(account_iter->name, witness.get_id()));
2234 
2235  auto end_iter = witnesses_by_account_name.begin();
2236  while( end_iter != witnesses_by_account_name.end() && limit > 0 )
2237  {
2238  ++end_iter;
2239  --limit;
2240  }
2241  witnesses_by_account_name.erase(end_iter, witnesses_by_account_name.end());
2242  return witnesses_by_account_name;
2243 }
2244 
2246 {
2247  return my->get_witness_count();
2248 }
2249 
2251 {
2252  return _db.get_index_type<witness_index>().indices().size();
2253 }
2254 
2256 // //
2257 // Committee members //
2258 // //
2260 
2261 vector<optional<committee_member_object>> database_api::get_committee_members(
2262  const vector<committee_member_id_type>& committee_member_ids )const
2263 {
2264  return my->get_committee_members( committee_member_ids );
2265 }
2266 
2267 vector<optional<committee_member_object>> database_api_impl::get_committee_members(
2268  const vector<committee_member_id_type>& committee_member_ids )const
2269 {
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))
2274  return *o;
2275  return {};
2276  });
2277  return result;
2278 }
2279 
2281  const std::string& account_id_or_name )const
2282 {
2283  return my->get_committee_member_by_account( account_id_or_name );
2284 }
2285 
2287  const std::string& account_id_or_name )const
2288 {
2289  const auto& idx = _db.get_index_type<committee_member_index>().indices().get<by_account>();
2290  const account_id_type account = get_account_from_string(account_id_or_name)->get_id();
2291  auto itr = idx.find(account);
2292  if( itr != idx.end() )
2293  return *itr;
2294  return {};
2295 }
2296 
2297 map<string, committee_member_id_type, std::less<>> database_api::lookup_committee_member_accounts(
2298  const string& lower_bound_name, uint32_t limit )const
2299 {
2300  return my->lookup_committee_member_accounts( lower_bound_name, limit );
2301 }
2302 
2303 map<string, committee_member_id_type, std::less<>> database_api_impl::lookup_committee_member_accounts(
2304  const string& lower_bound_name, uint32_t limit )const
2305 {
2306  FC_ASSERT( _app_options, "Internal error" );
2307  const auto configured_limit = _app_options->api_limit_lookup_committee_member_accounts;
2308  FC_ASSERT( limit <= configured_limit,
2309  "limit can not be greater than ${configured_limit}",
2310  ("configured_limit", configured_limit) );
2311 
2312  const auto& committee_members_by_id = _db.get_index_type<committee_member_index>().indices().get<by_id>();
2313 
2314  // we want to order committee_members by account name, but that name is in the account object
2315  // so the committee_member_index doesn't have a quick way to access it.
2316  // get all the names and look them all up, sort them, then figure out what
2317  // records to return. This could be optimized, but we expect the
2318  // number of committee_members to be few and the frequency of calls to be rare
2319  // TODO optimize
2320  std::map<std::string, committee_member_id_type, std::less<>> committee_members_by_account_name;
2321  for (const committee_member_object& committee_member : committee_members_by_id)
2322  if (auto account_iter = _db.find(committee_member.committee_member_account))
2323  if (account_iter->name >= lower_bound_name) // we can ignore anything below lower_bound_name
2324  committee_members_by_account_name.insert(std::make_pair(account_iter->name, committee_member.get_id()));
2325 
2326  auto end_iter = committee_members_by_account_name.begin();
2327  while( end_iter != committee_members_by_account_name.end() && limit > 0 )
2328  {
2329  ++end_iter;
2330  --limit;
2331  }
2332  committee_members_by_account_name.erase(end_iter, committee_members_by_account_name.end());
2333  return committee_members_by_account_name;
2334 }
2335 
2337 {
2338  return my->get_committee_count();
2339 }
2340 
2342 {
2343  return _db.get_index_type<committee_member_index>().indices().size();
2344 }
2345 
2346 
2348 // //
2349 // Workers //
2350 // //
2352 
2353 vector<worker_object> database_api::get_all_workers( const optional<bool>& is_expired )const
2354 {
2355  return my->get_all_workers( is_expired );
2356 }
2357 
2358 vector<worker_object> database_api_impl::get_all_workers( const optional<bool>& is_expired )const
2359 {
2360  vector<worker_object> result;
2361 
2362  if( !is_expired.valid() ) // query for all workers
2363  {
2364  const auto& workers_idx = _db.get_index_type<worker_index>().indices().get<by_id>();
2365  result.reserve( workers_idx.size() );
2366  for( const auto& w : workers_idx )
2367  {
2368  result.push_back( w );
2369  }
2370  }
2371  else // query for workers that are expired only or not expired only
2372  {
2373  const time_point_sec now = _db.head_block_time();
2374  const auto& workers_idx = _db.get_index_type<worker_index>().indices().get<by_end_date>();
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 )
2378  {
2379  result.push_back( *itr );
2380  }
2381  }
2382 
2383  return result;
2384 }
2385 
2386 vector<worker_object> database_api::get_workers_by_account(const std::string& account_id_or_name)const
2387 {
2388  return my->get_workers_by_account( account_id_or_name );
2389 }
2390 
2391 vector<worker_object> database_api_impl::get_workers_by_account(const std::string& account_id_or_name)const
2392 {
2393  vector<worker_object> result;
2394  const auto& workers_idx = _db.get_index_type<worker_index>().indices().get<by_account>();
2395 
2396  const account_id_type account = get_account_from_string(account_id_or_name)->get_id();
2397  auto range = workers_idx.equal_range(account);
2398  for(auto itr = range.first; itr != range.second; ++itr)
2399  {
2400  result.push_back( *itr );
2401  }
2402  return result;
2403 }
2404 
2406 {
2407  return my->get_worker_count();
2408 }
2409 
2411 {
2412  return _db.get_index_type<worker_index>().indices().size();
2413 }
2414 
2415 
2416 
2418 // //
2419 // Votes //
2420 // //
2422 
2423 vector<variant> database_api::lookup_vote_ids( const vector<vote_id_type>& votes )const
2424 {
2425  return my->lookup_vote_ids( votes );
2426 }
2427 
2428 vector<variant> database_api_impl::lookup_vote_ids( const vector<vote_id_type>& votes )const
2429 {
2430  FC_ASSERT( _app_options, "Internal error" );
2431  const auto configured_limit = _app_options->api_limit_lookup_vote_ids;
2432  FC_ASSERT( votes.size() <= configured_limit,
2433  "Number of querying votes can not be greater than ${configured_limit}",
2434  ("configured_limit", configured_limit) );
2435 
2436  const auto& witness_idx = _db.get_index_type<witness_index>().indices().get<by_vote_id>();
2437  const auto& committee_idx = _db.get_index_type<committee_member_index>().indices().get<by_vote_id>();
2438  const auto& for_worker_idx = _db.get_index_type<worker_index>().indices().get<by_vote_for>();
2439  const auto& against_worker_idx = _db.get_index_type<worker_index>().indices().get<by_vote_against>();
2440 
2441  vector<variant> result;
2442  result.reserve( votes.size() );
2443  for( auto id : votes )
2444  {
2445  switch( id.type() )
2446  {
2448  {
2449  auto itr = committee_idx.find( id );
2450  if( itr != committee_idx.end() )
2451  result.emplace_back( variant( *itr, 2 ) ); // Depth of committee_member_object is 1, add 1 to be safe
2452  else
2453  result.emplace_back( variant() );
2454  break;
2455  }
2456  case vote_id_type::witness:
2457  {
2458  auto itr = witness_idx.find( id );
2459  if( itr != witness_idx.end() )
2460  result.emplace_back( variant( *itr, 2 ) ); // Depth of witness_object is 1, add 1 here to be safe
2461  else
2462  result.emplace_back( variant() );
2463  break;
2464  }
2465  case vote_id_type::worker:
2466  {
2467  auto itr = for_worker_idx.find( id );
2468  if( itr != for_worker_idx.end() ) {
2469  result.emplace_back( variant( *itr, 4 ) ); // Depth of worker_object is 3, add 1 here to be safe.
2470  // If we want to extract the balance object inside,
2471  // need to increase this value
2472  }
2473  else {
2474  auto itr = against_worker_idx.find( id );
2475  if( itr != against_worker_idx.end() ) {
2476  result.emplace_back( variant( *itr, 4 ) ); // Depth of worker_object is 3, add 1 here to be safe.
2477  // If we want to extract the balance object inside,
2478  // need to increase this value
2479  }
2480  else {
2481  result.emplace_back( variant() );
2482  }
2483  }
2484  break;
2485  }
2486  case vote_id_type::VOTE_TYPE_COUNT: break; // supress unused enum value warnings
2487  default:
2488  FC_CAPTURE_AND_THROW( fc::out_of_range_exception, (id) );
2489  }
2490  }
2491  return result;
2492 }
2493 
2495 // //
2496 // Authority / validation //
2497 // //
2499 
2500 std::string database_api::get_transaction_hex(const signed_transaction& trx)const
2501 {
2502  return my->get_transaction_hex( trx );
2503 }
2504 
2505 std::string database_api_impl::get_transaction_hex(const signed_transaction& trx)const
2506 {
2507  return fc::to_hex(fc::raw::pack(trx));
2508 }
2509 
2511  const transaction &trx) const
2512 {
2513  return my->get_transaction_hex_without_sig(trx);
2514 }
2515 
2517  const transaction &trx) const
2518 {
2519  return fc::to_hex(fc::raw::pack(trx));
2520 }
2521 
2522 set<public_key_type> database_api::get_required_signatures( const signed_transaction& trx,
2523  const flat_set<public_key_type>& available_keys )const
2524 {
2525  return my->get_required_signatures( trx, available_keys );
2526 }
2527 
2528 set<public_key_type> database_api_impl::get_required_signatures( const signed_transaction& trx,
2529  const flat_set<public_key_type>& available_keys )const
2530 {
2531  auto chain_time = _db.head_block_time();
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 );
2534  auto result = trx.get_required_signatures( _db.get_chain_id(),
2535  available_keys,
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,
2541  return result;
2542 }
2543 
2544 set<public_key_type> database_api::get_potential_signatures( const signed_transaction& trx )const
2545 {
2546  return my->get_potential_signatures( trx );
2547 }
2548 set<address> database_api::get_potential_address_signatures( const signed_transaction& trx )const
2549 {
2550  return my->get_potential_address_signatures( trx );
2551 }
2552 
2553 set<public_key_type> database_api_impl::get_potential_signatures( const signed_transaction& trx )const
2554 {
2555  auto chain_time = _db.head_block_time();
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 );
2558 
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() )
2563  result.insert( k );
2564  return &auth;
2565  };
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() )
2569  result.insert( k );
2570  return &auth;
2571  };
2572 
2573  trx.get_required_signatures( _db.get_chain_id(),
2574  flat_set<public_key_type>(),
2575  get_active, get_owner,
2576  allow_non_immediate_owner,
2577  ignore_custom_op_reqd_auths,
2579 
2580  // Insert keys in required "other" authories
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 );
2588 
2589  return result;
2590 }
2591 
2592 set<address> database_api_impl::get_potential_address_signatures( const signed_transaction& trx )const
2593 {
2594  auto chain_time = _db.head_block_time();
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 );
2597 
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() )
2602  result.insert( k );
2603  return &auth;
2604  };
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())
2608  result.insert( k );
2609  return &auth;
2610  };
2611 
2612  trx.get_required_signatures( _db.get_chain_id(),
2613  flat_set<public_key_type>(),
2614  get_active, get_owner,
2615  allow_non_immediate_owner,
2616  ignore_custom_op_reqd_auths,
2618  return result;
2619 }
2620 
2621 bool database_api::verify_authority( const signed_transaction& trx )const
2622 {
2623  return my->verify_authority( trx );
2624 }
2625 
2626 bool database_api_impl::verify_authority( const signed_transaction& trx )const
2627 {
2628  bool allow_non_immediate_owner = ( _db.head_block_time() >= HARDFORK_CORE_584_TIME );
2629  trx.verify_authority( _db.get_chain_id(),
2630  [this]( account_id_type id ){ return &id(_db).active; },
2631  [this]( account_id_type id ){ return &id(_db).owner; },
2632  [this]( account_id_type id, const operation& op, rejected_predicate_map* rejects ) {
2633  return _db.get_viable_custom_authorities(id, op, rejects); },
2634  allow_non_immediate_owner,
2636  return true;
2637 }
2638 
2639 bool database_api::verify_account_authority( const string& account_name_or_id,
2640  const flat_set<public_key_type>& signers )const
2641 {
2642  return my->verify_account_authority( account_name_or_id, signers );
2643 }
2644 
2645 bool database_api_impl::verify_account_authority( const string& account_name_or_id,
2646  const flat_set<public_key_type>& keys )const
2647 {
2648  // create a dummy transfer
2649  transfer_operation op;
2650  op.from = get_account_from_string(account_name_or_id)->get_id();
2651  std::vector<operation> ops;
2652  ops.emplace_back(op);
2653 
2654  try
2655  {
2657  [this]( account_id_type id ){ return &id(_db).active; },
2658  [this]( account_id_type id ){ return &id(_db).owner; },
2659  // Use a no-op lookup for custom authorities; we don't want it even if one does apply for our dummy op
2660  [](auto, auto, auto*) { return vector<authority>(); },
2661  true, MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(_db.head_block_time()) );
2662  }
2663  catch (fc::exception& ex)
2664  {
2665  return false;
2666  }
2667 
2668  return true;
2669 }
2670 
2671 processed_transaction database_api::validate_transaction( const signed_transaction& trx )const
2672 {
2673  return my->validate_transaction( trx );
2674 }
2675 
2677 {
2678  return _db.validate_transaction(trx);
2679 }
2680 
2681 vector< fc::variant > database_api::get_required_fees( const vector<operation>& ops,
2682  const std::string& asset_id_or_symbol )const
2683 {
2684  return my->get_required_fees( ops, asset_id_or_symbol );
2685 }
2686 
2692 {
2694  const fee_schedule& _current_fee_schedule,
2695  const price& _core_exchange_rate,
2696  uint32_t _max_recursion
2697  )
2698  : current_fee_schedule(_current_fee_schedule),
2699  core_exchange_rate(_core_exchange_rate),
2700  max_recursion(_max_recursion)
2701  {}
2702 
2704  {
2706  {
2707  return set_proposal_create_op_fees( op );
2708  }
2709  else
2710  {
2711  asset fee = current_fee_schedule.set_fee( op, core_exchange_rate );
2712  fc::variant result;
2714  return result;
2715  }
2716  }
2717 
2719  {
2720  proposal_create_operation& op = proposal_create_op.get<proposal_create_operation>();
2721  std::pair< asset, fc::variants > result;
2722  for( op_wrapper& prop_op : op.proposed_ops )
2723  {
2726  result.second.push_back( set_op_fees( prop_op.op ) );
2728  }
2729  // we need to do this on the boxed version, which is why we use
2730  // two mutually recursive functions instead of a visitor
2731  result.first = current_fee_schedule.set_fee( proposal_create_op, core_exchange_rate );
2732  fc::variant vresult;
2733  fc::to_variant( result, vresult, GRAPHENE_NET_MAX_NESTED_OBJECTS );
2734  return vresult;
2735  }
2736 
2737  const fee_schedule& current_fee_schedule;
2739  uint32_t max_recursion;
2740  uint32_t current_recursion = 0;
2741 };
2742 
2743 vector< fc::variant > database_api_impl::get_required_fees( const vector<operation>& ops,
2744  const std::string& asset_id_or_symbol )const
2745 {
2746  vector< operation > _ops = ops;
2747  //
2748  // we copy the ops because we need to mutate an operation to reliably
2749  // determine its fee, see #435
2750  //
2751 
2752  vector< fc::variant > result;
2753  result.reserve(ops.size());
2754  const asset_object& a = *get_asset_from_string(asset_id_or_symbol);
2755  get_required_fees_helper helper(
2759  for( operation& op : _ops )
2760  {
2761  result.push_back( helper.set_op_fees( op ) );
2762  }
2763  return result;
2764 }
2765 
2767 // //
2768 // Proposed transactions //
2769 // //
2771 
2772 vector<proposal_object> database_api::get_proposed_transactions( const std::string account_id_or_name )const
2773 {
2774  return my->get_proposed_transactions( account_id_or_name );
2775 }
2776 
2777 vector<proposal_object> database_api_impl::get_proposed_transactions( const std::string account_id_or_name )const
2778 {
2779  // api_helper_indexes plugin is required for accessing the secondary index
2781  "api_helper_indexes plugin is not enabled on this server." );
2782 
2783  const auto& proposal_idx = _db.get_index_type< primary_index< proposal_index > >();
2784  const auto& proposals_by_account = proposal_idx.get_secondary_index<graphene::chain::required_approval_index>();
2785 
2786  vector<proposal_object> result;
2787  const account_id_type id = get_account_from_string(account_id_or_name)->get_id();
2788 
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() )
2791  {
2792  result.reserve( required_approvals_itr->second.size() );
2793  for( auto proposal_id : required_approvals_itr->second )
2794  {
2795  result.push_back( proposal_id(_db) );
2796  }
2797  }
2798  return result;
2799 }
2800 
2802 // //
2803 // Blinded balances //
2804 // //
2806 
2807 vector<blinded_balance_object> database_api::get_blinded_balances(
2808  const flat_set<commitment_type>& commitments )const
2809 {
2810  return my->get_blinded_balances( commitments );
2811 }
2812 
2813 vector<blinded_balance_object> database_api_impl::get_blinded_balances(
2814  const flat_set<commitment_type>& commitments )const
2815 {
2816  vector<blinded_balance_object> result; result.reserve(commitments.size());
2817  const auto& bal_idx = _db.get_index_type<blinded_balance_index>();
2818  const auto& by_commitment_idx = bal_idx.indices().get<by_commitment>();
2819  for( const auto& c : commitments )
2820  {
2821  auto itr = by_commitment_idx.find( c );
2822  if( itr != by_commitment_idx.end() )
2823  result.push_back( *itr );
2824  }
2825  return result;
2826 }
2827 
2829 // //
2830 // Withdrawals //
2831 // //
2833 
2834 vector<withdraw_permission_object> database_api::get_withdraw_permissions_by_giver(
2835  const std::string account_id_or_name,
2836  withdraw_permission_id_type start,
2837  uint32_t limit)const
2838 {
2839  return my->get_withdraw_permissions_by_giver( account_id_or_name, start, limit );
2840 }
2841 
2842 vector<withdraw_permission_object> database_api_impl::get_withdraw_permissions_by_giver(
2843  const std::string account_id_or_name,
2844  withdraw_permission_id_type start,
2845  uint32_t limit)const
2846 {
2847  FC_ASSERT( _app_options, "Internal error" );
2848  const auto configured_limit = _app_options->api_limit_get_withdraw_permissions_by_giver;
2849  FC_ASSERT( limit <= configured_limit,
2850  "limit can not be greater than ${configured_limit}",
2851  ("configured_limit", configured_limit) );
2852 
2853  vector<withdraw_permission_object> result;
2854 
2855  const auto& withdraw_idx = _db.get_index_type<withdraw_permission_index>().indices().get<by_from>();
2856  auto withdraw_index_end = withdraw_idx.end();
2857  const account_id_type account = get_account_from_string(account_id_or_name)->get_id();
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 )
2861  {
2862  result.push_back(*withdraw_itr);
2863  ++withdraw_itr;
2864  }
2865  return result;
2866 }
2867 
2868 vector<withdraw_permission_object> database_api::get_withdraw_permissions_by_recipient(
2869  const std::string account_id_or_name,
2870  withdraw_permission_id_type start,
2871  uint32_t limit)const
2872 {
2873  return my->get_withdraw_permissions_by_recipient( account_id_or_name, start, limit );
2874 }
2875 
2877  const std::string account_id_or_name,
2878  withdraw_permission_id_type start,
2879  uint32_t limit)const
2880 {
2881  FC_ASSERT( _app_options, "Internal error" );
2882  const auto configured_limit = _app_options->api_limit_get_withdraw_permissions_by_recipient;
2883  FC_ASSERT( limit <= configured_limit,
2884  "limit can not be greater than ${configured_limit}",
2885  ("configured_limit", configured_limit) );
2886 
2887  vector<withdraw_permission_object> result;
2888 
2889  const auto& withdraw_idx = _db.get_index_type<withdraw_permission_index>().indices().get<by_authorized>();
2890  auto withdraw_index_end = withdraw_idx.end();
2891  const account_id_type account = get_account_from_string(account_id_or_name)->get_id();
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)
2894  {
2895  result.push_back(*withdraw_itr);
2896  ++withdraw_itr;
2897  }
2898  return result;
2899 }
2900 
2902 // //
2903 // HTLC //
2904 // //
2906 
2907 optional<htlc_object> database_api::get_htlc( htlc_id_type id, optional<bool> subscribe )const
2908 {
2909  return my->get_htlc( id, subscribe );
2910 }
2911 
2912 fc::optional<htlc_object> database_api_impl::get_htlc( htlc_id_type id, optional<bool> subscribe )const
2913 {
2914  auto obj = get_objects( { object_id_type(id) }, subscribe ).front();
2915  if ( !obj.is_null() )
2916  {
2917  return fc::optional<htlc_object>(obj.template as<htlc_object>(GRAPHENE_MAX_NESTED_OBJECTS));
2918  }
2919  return fc::optional<htlc_object>();
2920 }
2921 
2922 vector<htlc_object> database_api::get_htlc_by_from( const std::string account_id_or_name,
2923  htlc_id_type start, uint32_t limit )const
2924 {
2925  return my->get_htlc_by_from(account_id_or_name, start, limit);
2926 }
2927 
2928 vector<htlc_object> database_api_impl::get_htlc_by_from( const std::string account_id_or_name,
2929  htlc_id_type start, uint32_t limit ) const
2930 {
2931  FC_ASSERT( _app_options, "Internal error" );
2932  const auto configured_limit = _app_options->api_limit_get_htlc_by;
2933  FC_ASSERT( limit <= configured_limit,
2934  "limit can not be greater than ${configured_limit}",
2935  ("configured_limit", configured_limit) );
2936 
2937  vector<htlc_object> result;
2938 
2939  const auto& htlc_idx = _db.get_index_type< htlc_index >().indices().get< by_from_id >();
2940  auto htlc_index_end = htlc_idx.end();
2941  const account_id_type account = get_account_from_string(account_id_or_name)->get_id();
2942  auto htlc_itr = htlc_idx.lower_bound(boost::make_tuple(account, object_id_type(start)));
2943 
2944  while(htlc_itr != htlc_index_end && htlc_itr->transfer.from == account && result.size() < limit)
2945  {
2946  result.push_back(*htlc_itr);
2947  ++htlc_itr;
2948  }
2949  return result;
2950 }
2951 
2952 vector<htlc_object> database_api::get_htlc_by_to( const std::string account_id_or_name,
2953  htlc_id_type start, uint32_t limit )const
2954 {
2955  return my->get_htlc_by_to(account_id_or_name, start, limit);
2956 }
2957 
2958 vector<htlc_object> database_api_impl::get_htlc_by_to( const std::string account_id_or_name,
2959  htlc_id_type start, uint32_t limit ) const
2960 {
2961  FC_ASSERT( _app_options, "Internal error" );
2962  const auto configured_limit = _app_options->api_limit_get_htlc_by;
2963  FC_ASSERT( limit <= configured_limit,
2964  "limit can not be greater than ${configured_limit}",
2965  ("configured_limit", configured_limit) );
2966 
2967  vector<htlc_object> result;
2968 
2969  const auto& htlc_idx = _db.get_index_type< htlc_index >().indices().get< by_to_id >();
2970  auto htlc_index_end = htlc_idx.end();
2971  const account_id_type account = get_account_from_string(account_id_or_name)->get_id();
2972  auto htlc_itr = htlc_idx.lower_bound(boost::make_tuple(account, object_id_type(start)));
2973 
2974  while(htlc_itr != htlc_index_end && htlc_itr->transfer.to == account && result.size() < limit)
2975  {
2976  result.push_back(*htlc_itr);
2977  ++htlc_itr;
2978  }
2979  return result;
2980 }
2981 
2982 vector<htlc_object> database_api::list_htlcs(const htlc_id_type start, uint32_t limit)const
2983 {
2984  return my->list_htlcs(start, limit);
2985 }
2986 
2987 vector<htlc_object> database_api_impl::list_htlcs(const htlc_id_type start, uint32_t limit) const
2988 {
2989  FC_ASSERT( _app_options, "Internal error" );
2990  const auto configured_limit = _app_options->api_limit_list_htlcs;
2991  FC_ASSERT( limit <= configured_limit,
2992  "limit can not be greater than ${configured_limit}",
2993  ("configured_limit", configured_limit) );
2994 
2995  vector<htlc_object> result;
2996  const auto& htlc_idx = _db.get_index_type<htlc_index>().indices().get<by_id>();
2997  auto itr = htlc_idx.lower_bound(object_id_type(start));
2998  while(itr != htlc_idx.end() && result.size() < limit)
2999  {
3000  result.push_back(*itr);
3001  ++itr;
3002  }
3003  return result;
3004 }
3005 
3007 // //
3008 // Tickets //
3009 // //
3011 
3012 vector<ticket_object> database_api::list_tickets(
3013  const optional<uint32_t>& limit,
3014  const optional<ticket_id_type>& start_id )const
3015 {
3016  const auto& idx = my->_db.get_index_type<ticket_index>().indices().get<by_id>();
3017  return my->get_objects_by_x< ticket_object,
3018  ticket_id_type
3020  idx, limit, start_id );
3021 }
3022 
3024  const std::string& account_name_or_id,
3025  const optional<uint32_t>& limit,
3026  const optional<ticket_id_type>& start_id )const
3027 {
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>();
3030  return my->get_objects_by_x< ticket_object,
3031  ticket_id_type
3033  idx, limit, start_id, account );
3034 }
3035 
3037 // //
3038 // Private methods //
3039 // //
3041 
3042 const account_object* database_api_helper::get_account_from_string( const std::string& name_or_id,
3043  bool throw_if_not_found ) const
3044 {
3045  // TODO cache the result to avoid repeatly fetching from db
3046  if( name_or_id.empty() )
3047  {
3048  if( throw_if_not_found )
3049  FC_THROW_EXCEPTION( fc::assert_exception, "no such account" );
3050  else
3051  return nullptr;
3052  }
3053  const account_object* account_ptr = nullptr;
3054  if( 0 != std::isdigit(name_or_id[0]) )
3055  account_ptr = _db.find(fc::variant(name_or_id, 1).as<account_id_type>(1));
3056  else
3057  {
3058  const auto& idx = _db.get_index_type<account_index>().indices().get<by_name>();
3059  auto itr = idx.find(name_or_id);
3060  if (itr != idx.end())
3061  account_ptr = &(*itr);
3062  }
3063  if(throw_if_not_found)
3064  FC_ASSERT( account_ptr, "no such account" );
3065  return account_ptr;
3066 }
3067 
3068 const asset_object* database_api_helper::get_asset_from_string( const std::string& symbol_or_id,
3069  bool throw_if_not_found ) const
3070 {
3071  // TODO cache the result to avoid repeatly fetching from db
3072  if( symbol_or_id.empty() )
3073  {
3074  if( throw_if_not_found )
3075  FC_THROW_EXCEPTION( fc::assert_exception, "no such asset" );
3076  else
3077  return nullptr;
3078  }
3079  const asset_object* asset_ptr = nullptr;
3080  if( 0 != std::isdigit(symbol_or_id[0]) )
3081  asset_ptr = _db.find(fc::variant(symbol_or_id, 1).as<asset_id_type>(1));
3082  else
3083  {
3084  const auto& idx = _db.get_index_type<asset_index>().indices().get<by_symbol>();
3085  auto itr = idx.find(symbol_or_id);
3086  if (itr != idx.end())
3087  asset_ptr = &(*itr);
3088  }
3089  if(throw_if_not_found)
3090  FC_ASSERT( asset_ptr, "no such asset" );
3091  return asset_ptr;
3092 }
3093 
3094 // helper function
3095 vector<optional<extended_asset_object>> database_api_impl::get_assets( const vector<asset_id_type>& asset_ids,
3096  optional<bool> subscribe )const
3097 {
3098  bool to_subscribe = get_whether_to_subscribe( subscribe );
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))
3103  {
3104  if( to_subscribe )
3105  subscribe_to_item( id );
3106  return extend_asset( *o );
3107  }
3108  return {};
3109  });
3110  return result;
3111 }
3112 
3113 // helper function
3114 vector<limit_order_object> database_api_impl::get_limit_orders( const asset_id_type a, const asset_id_type b,
3115  const uint32_t limit )const
3116 {
3117  FC_ASSERT( _app_options, "Internal error" );
3118  const auto configured_limit = _app_options->api_limit_get_limit_orders;
3119  FC_ASSERT( limit <= configured_limit,
3120  "limit can not be greater than ${configured_limit}",
3121  ("configured_limit", configured_limit) );
3122 
3123  const auto& limit_order_idx = _db.get_index_type<limit_order_index>();
3124  const auto& limit_price_idx = limit_order_idx.indices().get<by_price>();
3125 
3126  vector<limit_order_object> result;
3127  result.reserve(limit*2);
3128 
3129  uint32_t count = 0;
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)
3133  {
3134  result.push_back(*limit_itr);
3135  ++limit_itr;
3136  ++count;
3137  }
3138  count = 0;
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)
3142  {
3143  result.push_back(*limit_itr);
3144  ++limit_itr;
3145  ++count;
3146  }
3147 
3148  return result;
3149 }
3150 
3151 bool database_api_impl::is_impacted_account( const flat_set<account_id_type>& accounts)
3152 {
3153  if( _subscribed_accounts.empty() || accounts.empty() )
3154  return false;
3155 
3156  return std::any_of(accounts.begin(), accounts.end(), [this](const account_id_type& account) {
3157  return _subscribed_accounts.find(account) != _subscribed_accounts.end();
3158  });
3159 }
3160 
3161 void database_api_impl::broadcast_updates( const vector<variant>& updates )
3162 {
3163  if( !updates.empty() && _subscribe_callback ) {
3164  auto capture_this = shared_from_this();
3165  fc::async([capture_this,updates](){
3166  if(capture_this->_subscribe_callback)
3167  capture_this->_subscribe_callback( fc::variant(updates) );
3168  });
3169  }
3170 }
3171 
3173 {
3174  if( !queue.empty() )
3175  {
3176  auto capture_this = shared_from_this();
3177  fc::async([capture_this, this, queue](){
3178  for( const auto& item : queue )
3179  {
3180  auto sub = _market_subscriptions.find(item.first);
3181  if( sub != _market_subscriptions.end() )
3182  sub->second( fc::variant(item.second ) );
3183  }
3184  });
3185  }
3186 }
3187 
3188 void database_api_impl::on_objects_removed( const vector<object_id_type>& ids,
3189  const vector<const object*>& objs,
3190  const flat_set<account_id_type>& impacted_accounts )
3191 {
3192  handle_object_changed(_notify_remove_create, false, ids, 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;});
3197 
3198  if (it != objs.end())
3199  return *it;
3200 
3201  return nullptr;
3202  }
3203  );
3204 }
3205 
3206 void database_api_impl::on_objects_new( const vector<object_id_type>& ids,
3207  const flat_set<account_id_type>& impacted_accounts )
3208 {
3209  handle_object_changed(_notify_remove_create, true, ids, impacted_accounts,
3210  std::bind(&object_database::find_object, &_db, std::placeholders::_1)
3211  );
3212 }
3213 
3214 void database_api_impl::on_objects_changed( const vector<object_id_type>& ids,
3215  const flat_set<account_id_type>& impacted_accounts )
3216 {
3217  handle_object_changed(false, true, ids, impacted_accounts,
3218  std::bind(&object_database::find_object, &_db, std::placeholders::_1)
3219  );
3220 }
3221 
3223  bool full_object,
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 )
3227 {
3228  if( _subscribe_callback )
3229  {
3230  vector<variant> updates;
3231 
3232  for(auto id : ids)
3233  {
3234  if( force_notify || is_subscribed_to_item(id) || is_impacted_account(impacted_accounts) )
3235  {
3236  if( full_object )
3237  {
3238  auto obj = find_object(id);
3239  if( obj )
3240  {
3241  updates.emplace_back( obj->to_variant() );
3242  }
3243  }
3244  else
3245  {
3246  updates.emplace_back( fc::variant( id, 1 ) );
3247  }
3248  }
3249  }
3250 
3251  if( !updates.empty() )
3252  broadcast_updates(updates);
3253  }
3254 
3255  if( !_market_subscriptions.empty() )
3256  {
3257  market_queue_type broadcast_queue;
3258 
3259  for(auto id : ids)
3260  {
3261  if( id.is<call_order_id_type>() )
3262  {
3263  enqueue_if_subscribed_to_market<call_order_object>( find_object(id), broadcast_queue, full_object );
3264  }
3265  else if( id.is<limit_order_id_type>() )
3266  {
3267  enqueue_if_subscribed_to_market<limit_order_object>( find_object(id), broadcast_queue, full_object );
3268  }
3269  else if( id.is<force_settlement_id_type>() )
3270  {
3271  enqueue_if_subscribed_to_market<force_settlement_object>( find_object(id), broadcast_queue,
3272  full_object );
3273  }
3274  }
3275 
3276  if( !broadcast_queue.empty() )
3277  broadcast_market_updates(broadcast_queue);
3278  }
3279 }
3280 
3285 {
3287  {
3288  auto capture_this = shared_from_this();
3289  block_id_type block_id = _db.head_block_id();
3290  fc::async([this,capture_this,block_id](){
3291  _block_applied_callback(fc::variant(block_id, 1));
3292  });
3293  }
3294 
3295  if( _market_subscriptions.empty() )
3296  return;
3297 
3298  const auto& ops = _db.get_applied_operations();
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)
3301  {
3302  if( !o_op.valid() )
3303  continue;
3304  const operation_history_object& op = *o_op;
3305 
3306  optional< std::pair<asset_id_type,asset_id_type> > market;
3307  switch(op.op.which())
3308  {
3309  /* This is sent via the object_changed callback
3310  case operation::tag<limit_order_create_operation>::value:
3311  market = op.op.get<limit_order_create_operation>().get_market();
3312  break;
3313  */
3314  case operation::tag<fill_order_operation>::value:
3315  market = op.op.get<fill_order_operation>().get_market();
3316  break;
3317  /*
3318  case operation::tag<limit_order_cancel_operation>::value:
3319  */
3320  default: break;
3321  }
3322  if( market.valid() && _market_subscriptions.count(*market) > 0 )
3323  // FIXME this may cause fill_order_operation be pushed before order creation
3324  subscribed_markets_ops[*market].emplace_back(std::make_pair(op.op, op.result));
3325  }
3327  auto capture_this = shared_from_this();
3328  fc::async([this,capture_this,subscribed_markets_ops](){
3329  for(auto item : subscribed_markets_ops)
3330  {
3331  auto itr = _market_subscriptions.find(item.first);
3332  if(itr != _market_subscriptions.end())
3333  itr->second(fc::variant(item.second, GRAPHENE_NET_MAX_NESTED_OBJECTS));
3334  }
3335  });
3336 }
3337 
3338 } } // graphene::app
graphene::app::database_api_impl::get_objects
fc::variants get_objects(const vector< object_id_type > &ids, optional< bool > subscribe) const
Definition: database_api.cpp:140
graphene::app::order
Definition: api_objects.hpp:82
graphene::app::database_api::get_potential_signatures
set< public_key_type > get_potential_signatures(const signed_transaction &trx) const
Definition: database_api.cpp:2544
graphene::app::database_api::get_credit_deals_by_collateral_asset
vector< credit_deal_object > get_credit_deals_by_collateral_asset(const std::string &asset_symbol_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< credit_deal_id_type > &start_id=optional< credit_deal_id_type >()) const
Get a list of credit deals by the symbol or ID of the collateral asset type.
Definition: database_api.cpp:2154
graphene::app::database_api_impl::lookup_committee_member_accounts
map< string, committee_member_id_type, std::less<> > lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const
Definition: database_api.cpp:2303
graphene::app::database_api::get_withdraw_permissions_by_giver
vector< withdraw_permission_object > get_withdraw_permissions_by_giver(const std::string account_name_or_id, withdraw_permission_id_type start, uint32_t limit) const
Get non expired withdraw permission objects for a giver(ex:recurring customer)
Definition: database_api.cpp:2834
graphene::app::database_api_impl::get_limit_orders_by_account
vector< limit_order_object > get_limit_orders_by_account(const string &account_name_or_id, const optional< uint32_t > &limit, const optional< limit_order_id_type > &start_id)
Definition: database_api.cpp:1079
graphene::db::object_database::find_object
const object * find_object(const object_id_type &id) const
Definition: object_database.cpp:43
fc::time_point_sec::sec_since_epoch
uint32_t sec_since_epoch() const
Definition: time.hpp:90
graphene::app::database_api_impl::get_block
optional< signed_block > get_block(uint32_t block_num) const
Definition: database_api.cpp:280
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
graphene::app::market_ticker
Definition: api_objects.hpp:112
graphene::app::database_api_impl::get_order_book
order_book get_order_book(const string &base, const string &quote, uint32_t limit) const
Definition: database_api.cpp:1450
graphene::app::database_api_impl::on_applied_block
void on_applied_block()
Definition: database_api.cpp:3284
graphene::api_helper_indexes::next_object_ids_index::get_next_id
object_id_type get_next_id(uint8_t space_id, uint8_t type_id) const
Definition: api_helper_indexes.cpp:250
graphene::app::database_api_impl::get_witness_count
uint64_t get_witness_count() const
Definition: database_api.cpp:2250
fc::variant_object
An order-perserving dictionary of variant's.
Definition: variant_object.hpp:20
graphene::db::object::id
object_id_type id
Definition: object.hpp:69
graphene::app::database_api_impl::_removed_connection
boost::signals2::scoped_connection _removed_connection
Definition: database_api_impl.hxx:428
graphene::app::database_api_impl::get_committee_members
vector< optional< committee_member_object > > get_committee_members(const vector< committee_member_id_type > &committee_member_ids) const
Definition: database_api.cpp:2267
graphene::app::database_api_impl::get_liquidity_pools_by_share_asset
vector< optional< extended_liquidity_pool_object > > get_liquidity_pools_by_share_asset(const vector< std::string > &asset_symbols_or_ids, const optional< bool > &subscribe, const optional< bool > &with_statistics) const
Definition: database_api.cpp:1919
graphene::chain::limit_order_object::sell_price
price sell_price
The seller's asking price.
Definition: market_object.hpp:51
graphene::app::database_api::lookup_asset_symbols
vector< optional< extended_asset_object > > lookup_asset_symbols(const vector< string > &symbols_or_ids) const
Get a list of assets by symbol names or IDs.
Definition: database_api.cpp:1035
graphene::app::database_api_helper::get_asset_from_string
const asset_object * get_asset_from_string(const std::string &symbol_or_id, bool throw_if_not_found=true) const
Definition: database_api.cpp:3068
graphene::app::database_api_impl::_subscribe_callback
std::function< void(const fc::variant &)> _subscribe_callback
Definition: database_api_impl.hxx:422
graphene::chain::dynamic_global_property_object
Maintains global state information (committee_member list, current fees)
Definition: global_property_object.hpp:62
graphene::app::database_api_impl::lookup_account_names
vector< optional< account_object > > lookup_account_names(const vector< string > &account_names) const
Definition: database_api.cpp:772
graphene::chain::database
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
graphene::app::database_api::get_chain_id
chain_id_type get_chain_id() const
Get the chain ID.
Definition: database_api.cpp:343
graphene::app::more_data::limit_orders
bool limit_orders
Definition: api_objects.hpp:48
graphene::app::database_api_impl::get_asset_count
uint64_t get_asset_count() const
Definition: database_api.cpp:1002
graphene::app::database_api_impl::get_account_limit_orders
vector< limit_order_object > get_account_limit_orders(const string &account_name_or_id, const string &base, const string &quote, uint32_t limit, optional< limit_order_id_type > ostart_id, optional< price > ostart_price)
Definition: database_api.cpp:1120
graphene::app::database_api::get_trade_history_by_sequence
vector< market_trade > get_trade_history_by_sequence(const string &base, const string &quote, int64_t start, fc::time_point_sec stop, uint32_t limit=application_options::get_default().api_limit_get_trade_history_by_sequence) const
Get market transactions occurred in the market base:quote, ordered by time, most recent first.
Definition: database_api.cpp:1628
graphene::chain::database::get_chain_id
const chain_id_type & get_chain_id() const
Definition: db_getter.cpp:87
graphene::app::full_account::lifetime_referrer_name
string lifetime_referrer_name
Definition: api_objects.hpp:65
graphene::app::database_api::get_liquidity_pools_by_asset_a
vector< extended_liquidity_pool_object > get_liquidity_pools_by_asset_a(const std::string &asset_symbol_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< liquidity_pool_id_type > &start_id=optional< liquidity_pool_id_type >(), const optional< bool > &with_statistics=false) const
Get a list of liquidity pools by the symbol or ID of the first asset in the pool.
Definition: database_api.cpp:1763
graphene::app::database_api_impl::get_blinded_balances
vector< blinded_balance_object > get_blinded_balances(const flat_set< commitment_type > &commitments) const
Definition: database_api.cpp:2813
graphene::protocol::rejected_predicate_map
map< custom_authority_id_type, rejected_predicate > rejected_predicate_map
Definition: transaction.hpp:31
graphene::protocol::fill_order_operation
Definition: market.hpp:206
graphene::app::database_api_impl
Definition: database_api_impl.hxx:36
graphene::app::database_api_impl::verify_account_authority
bool verify_account_authority(const string &account_name_or_id, const flat_set< public_key_type > &signers) const
Definition: database_api.cpp:2645
fc::exception
Used to generate a useful error report when an exception is thrown.
Definition: exception.hpp:56
graphene::chain::credit_deal_object
A credit deal describes the details of a borrower's borrowing of funds from a credit offer.
Definition: credit_offer_object.hpp:104
graphene::chain::asset_object::for_liquidity_pool
optional< liquidity_pool_id_type > for_liquidity_pool
The ID of the liquidity pool if the asset is the share asset of a liquidity pool.
Definition: asset_object.hpp:147
graphene::app::database_api::get_chain_properties
chain_property_object get_chain_properties() const
Retrieve the graphene::chain::chain_property_object associated with the chain.
Definition: database_api.cpp:313
graphene::chain::database::head_block_time
time_point_sec head_block_time() const
Definition: db_getter.cpp:67
graphene::chain::credit_offer_object
A credit offer is a fund that can be used by other accounts who provide certain collateral.
Definition: credit_offer_object.hpp:39
graphene::app::database_api::lookup_accounts
map< string, account_id_type, std::less<> > lookup_accounts(const string &lower_bound_name, uint32_t limit, const optional< bool > &subscribe=optional< bool >()) const
Get names and IDs for registered accounts.
Definition: database_api.cpp:777
graphene::app::database_api_impl::unsubscribe_from_market
void unsubscribe_from_market(const std::string &a, const std::string &b)
Definition: database_api.cpp:1382
graphene::app::application_options::api_limit_get_collateral_bids
uint32_t api_limit_get_collateral_bids
Definition: application.hpp:69
graphene::chain::account_object::lifetime_referrer
account_id_type lifetime_referrer
The lifetime member at the top of the referral tree. Receives a percentage of referral rewards.
Definition: account_object.hpp:198
graphene::app::database_api_impl::list_assets
vector< extended_asset_object > list_assets(const string &lower_bound_symbol, uint32_t limit) const
Definition: database_api.cpp:977
graphene::app::application_options::api_limit_lookup_vote_ids
uint32_t api_limit_lookup_vote_ids
Definition: application.hpp:73
graphene::app::database_api_impl::get_required_fees
vector< fc::variant > get_required_fees(const vector< operation > &ops, const std::string &asset_id_or_symbol) const
Definition: database_api.cpp:2743
graphene::protocol::vote_id_type::witness
@ witness
Definition: vote.hpp:61
graphene::db::object_database::get
const T & get(const object_id_type &id) const
Definition: object_database.hpp:119
graphene::protocol::price
The price struct stores asset prices in the BitShares system.
Definition: asset.hpp:108
graphene::app::database_api_impl::list_htlcs
vector< htlc_object > list_htlcs(const htlc_id_type lower_bound_id, uint32_t limit) const
Definition: database_api.cpp:2987
graphene::app::database_api::get_key_references
vector< flat_set< account_id_type > > get_key_references(vector< public_key_type > keys) const
Get all accounts that refer to the specified public keys in their owner authority,...
Definition: database_api.cpp:386
graphene::app::application_options::api_limit_get_tickets
uint32_t api_limit_get_tickets
Definition: application.hpp:78
graphene::chain::operation_history_object::op
operation op
Definition: operation_history_object.hpp:58
graphene::db::primary_index
Wraps a derived index to intercept calls to create, modify, and remove so that callbacks may be fired...
Definition: index.hpp:312
graphene::app::database_api::lookup_witness_accounts
map< string, witness_id_type, std::less<> > lookup_witness_accounts(const string &lower_bound_name, uint32_t limit) const
Get names and IDs for registered witnesses.
Definition: database_api.cpp:2206
graphene::chain::asset_object::bitasset_data
const asset_bitasset_data_object & bitasset_data(const DB &db) const
Definition: asset_object.hpp:166
graphene::chain::samet_fund_object
A SameT Fund is a fund which can be used by a borrower and have to be repaid in the same transaction.
Definition: samet_fund_object.hpp:39
fc::static_variant< transfer_operation, limit_order_create_operation, limit_order_cancel_operation, call_order_update_operation, fill_order_operation, account_create_operation, account_update_operation, account_whitelist_operation, account_upgrade_operation, account_transfer_operation, asset_create_operation, asset_update_operation, asset_update_bitasset_operation, asset_update_feed_producers_operation, asset_issue_operation, asset_reserve_operation, asset_fund_fee_pool_operation, asset_settle_operation, asset_global_settle_operation, asset_publish_feed_operation, witness_create_operation, witness_update_operation, proposal_create_operation, proposal_update_operation, proposal_delete_operation, withdraw_permission_create_operation, withdraw_permission_update_operation, withdraw_permission_claim_operation, withdraw_permission_delete_operation, committee_member_create_operation, committee_member_update_operation, committee_member_update_global_parameters_operation, vesting_balance_create_operation, vesting_balance_withdraw_operation, worker_create_operation, custom_operation, assert_operation, balance_claim_operation, override_transfer_operation, transfer_to_blind_operation, blind_transfer_operation, transfer_from_blind_operation, asset_settle_cancel_operation, asset_claim_fees_operation, fba_distribute_operation, bid_collateral_operation, execute_bid_operation, asset_claim_pool_operation, asset_update_issuer_operation, htlc_create_operation, htlc_redeem_operation, htlc_redeemed_operation, htlc_extend_operation, htlc_refund_operation, custom_authority_create_operation, custom_authority_update_operation, custom_authority_delete_operation, ticket_create_operation, ticket_update_operation, liquidity_pool_create_operation, liquidity_pool_delete_operation, liquidity_pool_deposit_operation, liquidity_pool_withdraw_operation, liquidity_pool_exchange_operation, samet_fund_create_operation, samet_fund_delete_operation, samet_fund_update_operation, samet_fund_borrow_operation, samet_fund_repay_operation, credit_offer_create_operation, credit_offer_delete_operation, credit_offer_update_operation, credit_offer_accept_operation, credit_deal_repay_operation, credit_deal_expired_operation, liquidity_pool_update_operation, credit_deal_update_operation, limit_order_update_operation >
graphene::app::database_api_impl::get_block_header
optional< maybe_signed_block_header > get_block_header(uint32_t block_num, bool with_witness_signature) const
Definition: database_api.cpp:248
pts_address.hpp
graphene::app::database_api_impl::lookup_vote_ids
vector< variant > lookup_vote_ids(const vector< vote_id_type > &votes) const
Definition: database_api.cpp:2428
graphene::app::more_data::htlcs_to
bool htlcs_to
Definition: api_objects.hpp:56
graphene::app::database_api_impl::is_public_key_registered
bool is_public_key_registered(string public_key) const
Definition: database_api.cpp:452
graphene::app::database_api::get_24_volume
market_volume get_24_volume(const string &base, const string &quote) const
Returns the 24 hour volume for the market assetA:assetB.
Definition: database_api.cpp:1426
graphene::app::application_options::api_limit_get_samet_funds
uint32_t api_limit_get_samet_funds
Definition: application.hpp:80
graphene::chain::ticket_object
a ticket for governance voting
Definition: ticket_object.hpp:62
graphene::protocol::transaction_id_type
fc::ripemd160 transaction_id_type
Definition: types.hpp:306
graphene::app::database_api::set_block_applied_callback
void set_block_applied_callback(std::function< void(const variant &block_id)> cb)
Register a callback handle which will get notified when a block is pushed to database.
Definition: database_api.cpp:206
graphene::app::database_api_impl::subscribe_to_item
void subscribe_to_item(const T &item) const
Definition: database_api_impl.hxx:341
graphene::app::application_options::api_limit_get_limit_orders_by_account
uint32_t api_limit_get_limit_orders_by_account
Definition: application.hpp:63
graphene::db::base_primary_index::get_secondary_index
const T & get_secondary_index() const
Definition: index.hpp:179
graphene::app::database_api_impl::get_vesting_balances
vector< vesting_balance_object > get_vesting_balances(const std::string account_id_or_name) const
Definition: database_api.cpp:918
graphene::app::database_api_impl::get_dynamic_global_properties
dynamic_global_property_object get_dynamic_global_properties() const
Definition: database_api.cpp:358
graphene::chain::global_property_object::parameters
chain_parameters parameters
Definition: global_property_object.hpp:44
graphene::app::database_api_impl::set_block_applied_callback
void set_block_applied_callback(std::function< void(const variant &block_id)> cb)
Definition: database_api.cpp:211
graphene::app::database_api_impl::next_object_ids_index
const graphene::api_helper_indexes::next_object_ids_index * next_object_ids_index
Definition: database_api_impl.hxx:436
graphene::app::database_api_impl::get_workers_by_account
vector< worker_object > get_workers_by_account(const std::string &account_id_or_name) const
Definition: database_api.cpp:2391
graphene::app::database_api_impl::lookup_asset_symbols
vector< optional< extended_asset_object > > lookup_asset_symbols(const vector< string > &symbols_or_ids) const
Definition: database_api.cpp:1041
FC_THROW
#define FC_THROW( ...)
Definition: exception.hpp:366
graphene::app::market_trade::side2_account_id
account_id_type side2_account_id
Definition: api_objects.hpp:158
graphene::app::database_api_helper::_app_options
const application_options * _app_options
Definition: database_api_helper.hxx:36
graphene::app::application_options::api_limit_get_withdraw_permissions_by_giver
uint32_t api_limit_get_withdraw_permissions_by_giver
Definition: application.hpp:76
fc::bloom_filter
Definition: bloom_filter.hpp:179
graphene::app::database_api_impl::set_auto_subscription
void set_auto_subscription(bool enable)
Definition: database_api.cpp:191
graphene::chain::get_config
fc::variant_object get_config()
Definition: get_config.cpp:31
graphene::chain::asset_object::is_liquidity_pool_share_asset
bool is_liquidity_pool_share_asset() const
Definition: asset_object.hpp:86
graphene::app::database_api::cancel_all_subscriptions
void cancel_all_subscriptions()
Stop receiving any notifications.
Definition: database_api.cpp:216
graphene::app::full_account::statistics
account_statistics_object statistics
Definition: api_objects.hpp:62
graphene::chain::database::get_viable_custom_authorities
vector< authority > get_viable_custom_authorities(account_id_type account, const operation &op, rejected_predicate_map *rejected_authorities=nullptr) const
Get a list of custom authorities which can validate the provided operation for the provided account.
Definition: db_getter.cpp:102
graphene::app::database_api::lookup_account_names
vector< optional< account_object > > lookup_account_names(const vector< string > &account_names) const
Get a list of accounts by name.
Definition: database_api.cpp:767
graphene::app::database_api::get_proposed_transactions
vector< proposal_object > get_proposed_transactions(const std::string account_name_or_id) const
return a set of proposed transactions (aka proposals) that the specified account can add approval to ...
Definition: database_api.cpp:2772
graphene::app::more_data::call_orders
bool call_orders
Definition: api_objects.hpp:49
GRAPHENE_NET_MAX_NESTED_OBJECTS
#define GRAPHENE_NET_MAX_NESTED_OBJECTS
Definition: config.hpp:112
graphene::app::database_api::verify_authority
bool verify_authority(const signed_transaction &trx) const
Definition: database_api.cpp:2621
graphene::app::database_api::get_liquidity_pools_by_owner
vector< extended_liquidity_pool_object > get_liquidity_pools_by_owner(const std::string &account_name_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< asset_id_type > &start_id=optional< asset_id_type >(), const optional< bool > &with_statistics=false) const
Get a list of liquidity pools by the name or ID of the owner account.
Definition: database_api.cpp:1953
graphene::app::database_api_impl::set_pending_transaction_callback
void set_pending_transaction_callback(std::function< void(const variant &)> cb)
Definition: database_api.cpp:201
graphene::app::database_api::get_settle_orders
vector< force_settlement_object > get_settle_orders(const std::string &a, uint32_t limit) const
Get forced settlement orders in a given asset.
Definition: database_api.cpp:1262
hex.hpp
graphene::app::application_options::api_limit_lookup_committee_member_accounts
uint32_t api_limit_lookup_committee_member_accounts
Definition: application.hpp:72
graphene::app::database_api::get_account_balances
vector< asset > get_account_balances(const std::string &account_name_or_id, const flat_set< asset_id_type > &assets) const
Get an account's balances in various assets.
Definition: database_api.cpp:829
graphene::protocol::asset_options::core_exchange_rate
price core_exchange_rate
Definition: asset_ops.hpp:72
graphene::app::database_api_impl::get_collateral_bids
vector< collateral_bid_object > get_collateral_bids(const std::string &asset, uint32_t limit, uint32_t start) const
Definition: database_api.cpp:1336
graphene::app::maybe_signed_block_header
Definition: api_objects.hpp:180
graphene::app::order_book::asks
vector< order > asks
Definition: api_objects.hpp:107
get_config.hpp
graphene::app::full_account::account
account_object account
Definition: api_objects.hpp:61
graphene::chain::database::removed_objects
fc::signal< void(const vector< object_id_type > &, const vector< const object * > &, const flat_set< account_id_type > &)> removed_objects
Definition: database.hpp:648
graphene::app::database_api_impl::get_top_markets
vector< market_ticker > get_top_markets(uint32_t limit) const
Definition: database_api.cpp:1499
graphene::app::database_api_impl::get_trade_history
vector< market_trade > get_trade_history(const string &base, const string &quote, fc::time_point_sec start, fc::time_point_sec stop, uint32_t limit) const
Definition: database_api.cpp:1536
graphene::protocol::pts_address
Definition: pts_address.hpp:41
graphene::app::database_api_impl::validate_transaction
processed_transaction validate_transaction(const signed_transaction &trx) const
Definition: database_api.cpp:2676
graphene::db::primary_index::find
const object * find(object_id_type id) const override
Definition: index.hpp:335
graphene::app::database_api::list_credit_deals
vector< credit_deal_object > list_credit_deals(const optional< uint32_t > &limit=optional< uint32_t >(), const optional< credit_deal_id_type > &start_id=optional< credit_deal_id_type >()) const
Get a list of credit deals.
Definition: database_api.cpp:2092
graphene::chain::account_object::registrar
account_id_type registrar
The account that paid the fee to register this account. Receives a percentage of referral rewards.
Definition: account_object.hpp:194
graphene::app::database_api_impl::get_htlc
optional< htlc_object > get_htlc(htlc_id_type id, optional< bool > subscribe) const
Definition: database_api.cpp:2912
fc::sha256
Definition: sha256.hpp:10
graphene::app::database_api_impl::_notify_remove_create
bool _notify_remove_create
Definition: database_api_impl.hxx:416
graphene::app::market_volume::quote_volume
string quote_volume
Definition: api_objects.hpp:146
graphene::chain::asset_object
tracks the parameters of an asset
Definition: asset_object.hpp:75
graphene::app::database_api::get_account_by_name
optional< account_object > get_account_by_name(string name) const
Get info of an account by name.
Definition: database_api.cpp:727
graphene::app::database_api::get_vested_balances
vector< asset > get_vested_balances(const vector< balance_id_type > &objs) const
Calculate how much assets in the given balance objects are able to be claimed at current head block t...
Definition: database_api.cpp:895
graphene::app::database_api::lookup_committee_member_accounts
map< string, committee_member_id_type, std::less<> > lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const
Get names and IDs for registered committee_members.
Definition: database_api.cpp:2297
graphene::app::market_trade::date
fc::time_point_sec date
Definition: api_objects.hpp:152
graphene::app::full_account::balances
vector< account_balance_object > balances
Definition: api_objects.hpp:68
graphene::app::database_api::get_htlc
optional< htlc_object > get_htlc(htlc_id_type id, optional< bool > subscribe=optional< bool >()) const
Get HTLC object.
Definition: database_api.cpp:2907
graphene::app::full_account::limit_orders
vector< limit_order_object > limit_orders
Definition: api_objects.hpp:70
api_connection.hpp
graphene::chain::asset_object::symbol
string symbol
Ticker symbol for this asset, i.e. "USD".
Definition: asset_object.hpp:131
graphene::market_history::history_key
Definition: market_history_plugin.hpp:103
graphene::app::database_api_impl::lookup_accounts
map< string, account_id_type, std::less<> > lookup_accounts(const string &lower_bound_name, uint32_t limit, const optional< bool > &subscribe) const
Definition: database_api.cpp:784
graphene::app::database_api_impl::get_settle_orders_by_account
vector< force_settlement_object > get_settle_orders_by_account(const std::string &account_name_or_id, force_settlement_id_type start, uint32_t limit) const
Definition: database_api.cpp:1298
graphene::app::database_api::get_asset_count
uint64_t get_asset_count() const
Get assets count.
Definition: database_api.cpp:997
graphene::chain::database::get_applied_operations
const vector< optional< operation_history_object > > & get_applied_operations() const
Definition: db_block.cpp:566
graphene::chain::balances_by_account_index
This secondary index will allow fast access to the balance objects that belonging to an account.
Definition: account_object.hpp:361
graphene::chain::limit_order_object::seller
account_id_type seller
Who is selling.
Definition: market_object.hpp:49
graphene::app::database_api::get_liquidity_pools_by_share_asset
vector< optional< extended_liquidity_pool_object > > get_liquidity_pools_by_share_asset(const vector< std::string > &asset_symbols_or_ids, const optional< bool > &subscribe=optional< bool >(), const optional< bool > &with_statistics=false) const
Get a list of liquidity pools by their share asset symbols or IDs.
Definition: database_api.cpp:1908
graphene::app::database_api::set_auto_subscription
void set_auto_subscription(bool enable)
Set auto-subscription behavior of follow-up API queries.
Definition: database_api.cpp:186
graphene::app::database_api_impl::get_worker_count
uint64_t get_worker_count() const
Definition: database_api.cpp:2410
graphene::chain::dynamic_global_property_object::last_vote_tally_time
time_point_sec last_vote_tally_time
Definition: global_property_object.hpp:71
graphene::chain::database::applied_block
fc::signal< void(const signed_block &)> applied_block
Definition: database.hpp:624
graphene::app::database_api_impl::get_account_by_name
optional< account_object > get_account_by_name(string name) const
Definition: database_api.cpp:732
graphene::app::database_api::get_dynamic_global_properties
dynamic_global_property_object get_dynamic_global_properties() const
Retrieve the current graphene::chain::dynamic_global_property_object.
Definition: database_api.cpp:353
graphene::app::application_options::api_limit_list_htlcs
uint32_t api_limit_list_htlcs
Definition: application.hpp:74
graphene::app::database_api_impl::get_potential_signatures
set< public_key_type > get_potential_signatures(const signed_transaction &trx) const
Definition: database_api.cpp:2553
graphene::app::database_api_impl::get_chain_id
chain_id_type get_chain_id() const
Definition: database_api.cpp:348
graphene::app::more_data::assets
bool assets
Definition: api_objects.hpp:52
graphene::app::database_api::get_samet_funds_by_asset
vector< samet_fund_object > get_samet_funds_by_asset(const std::string &asset_symbol_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< samet_fund_id_type > &start_id=optional< samet_fund_id_type >()) const
Get a list of SameT Funds by the symbol or ID of the asset type.
Definition: database_api.cpp:2035
graphene::app::get_required_fees_helper::current_fee_schedule
const fee_schedule & current_fee_schedule
Definition: database_api.cpp:2737
graphene::app::application_options::api_limit_get_full_accounts_subscribe
uint32_t api_limit_get_full_accounts_subscribe
Definition: application.hpp:60
graphene::db::base_primary_index
Definition: index.hpp:152
graphene::app::database_api::get_ticker
market_ticker get_ticker(const string &base, const string &quote) const
Returns the ticker for the market assetA:assetB.
Definition: database_api.cpp:1392
graphene::app::database_api_impl::cancel_all_subscriptions
void cancel_all_subscriptions(bool reset_callback, bool reset_market_subscriptions)
Definition: database_api.cpp:221
graphene::chain::database::on_pending_transaction
fc::signal< void(const signed_transaction &)> on_pending_transaction
Definition: database.hpp:630
graphene::app::database_api::get_assets_by_issuer
vector< extended_asset_object > get_assets_by_issuer(const std::string &issuer_name_or_id, asset_id_type start, uint32_t limit) const
Get assets issued (owned) by a given account.
Definition: database_api.cpp:1007
graphene::app::database_api::verify_account_authority
bool verify_account_authority(const string &account_name_or_id, const flat_set< public_key_type > &signers) const
Verify that the public keys have enough authority to approve an operation for this account.
Definition: database_api.cpp:2639
graphene::chain::account_member_index
This secondary index will allow a reverse lookup of all accounts that a particular key or account is ...
Definition: account_object.hpp:330
graphene::chain::database::changed_objects
fc::signal< void(const vector< object_id_type > &, const flat_set< account_id_type > &)> changed_objects
Definition: database.hpp:642
graphene::protocol::verify_authority
void verify_authority(const vector< operation > &ops, const flat_set< public_key_type > &sigs, const std::function< const authority *(account_id_type)> &get_active, const std::function< const authority *(account_id_type)> &get_owner, const custom_authority_lookup &get_custom, bool allow_non_immediate_owner, bool ignore_custom_operation_required_auths, uint32_t max_recursion=GRAPHENE_MAX_SIG_CHECK_DEPTH, bool allow_committee=false, const flat_set< account_id_type > &active_approvals=flat_set< account_id_type >(), const flat_set< account_id_type > &owner_approvals=flat_set< account_id_type >())
Definition: transaction.cpp:269
graphene::app::database_api::get_block_header
optional< maybe_signed_block_header > get_block_header(uint32_t block_num, const optional< bool > &with_witness_signature=optional< bool >()) const
Retrieve a block header.
Definition: database_api.cpp:241
graphene::app::application
Definition: application.hpp:91
graphene::db::object_database::find
const T * find(const object_id_type &id) const
Definition: object_database.hpp:126
fc::to_hex
std::string to_hex(const char *d, uint32_t s)
Definition: hex.cpp:17
graphene::app::database_api::validate_transaction
processed_transaction validate_transaction(const signed_transaction &trx) const
Validates a transaction against the current state without broadcasting it on the network.
Definition: database_api.cpp:2671
graphene::protocol::op_wrapper::op
operation op
Definition: operations.hpp:156
graphene::app::database_api::get_objects
fc::variants get_objects(const vector< object_id_type > &ids, optional< bool > subscribe=optional< bool >()) const
Get the objects corresponding to the provided IDs.
Definition: database_api.cpp:135
graphene::app::database_api::get_credit_deals_by_borrower
vector< credit_deal_object > get_credit_deals_by_borrower(const std::string &account_name_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< credit_deal_id_type > &start_id=optional< credit_deal_id_type >()) const
Get a list of credit deals by the name or ID of a borrower account.
Definition: database_api.cpp:2128
graphene::app::application_options::api_limit_get_htlc_by
uint32_t api_limit_get_htlc_by
Definition: application.hpp:75
graphene::app::full_account::assets
vector< asset_id_type > assets
Definition: api_objects.hpp:74
graphene::app::database_api_impl::extend_asset
extended_asset_object extend_asset(ASSET &&a) const
Definition: database_api_impl.hxx:232
graphene::protocol::vote_id_type::committee
@ committee
Definition: vote.hpp:60
graphene::app::database_api_helper::database_api_helper
database_api_helper(graphene::chain::database &db, const application_options *app_options)
Definition: database_api.cpp:59
graphene::app::more_data::vesting_balances
bool vesting_balances
Definition: api_objects.hpp:47
graphene::chain::vesting_balance_object
Definition: vesting_balance_object.hpp:151
graphene::app::database_api_impl::get_liquidity_pools_by_owner
vector< extended_liquidity_pool_object > get_liquidity_pools_by_owner(const std::string &account_name_or_id, const optional< uint32_t > &limit, const optional< asset_id_type > &start_id, const optional< bool > &with_statistics) const
Definition: database_api.cpp:1966
graphene::app::application_options::api_limit_get_key_references
uint32_t api_limit_get_key_references
Definition: application.hpp:57
graphene::app::database_api::get_account_references
vector< account_id_type > get_account_references(const std::string account_name_or_id) const
Get all accounts that refer to the specified account in their owner or active authorities.
Definition: database_api.cpp:741
graphene::app::full_account::vesting_balances
vector< vesting_balance_object > vesting_balances
Definition: api_objects.hpp:69
graphene::app::full_account::withdraws_from
vector< withdraw_permission_object > withdraws_from
Definition: api_objects.hpp:75
graphene::chain::database::head_block_id
block_id_type head_block_id() const
Definition: db_getter.cpp:77
graphene::app::market_volume
Definition: api_objects.hpp:140
graphene::app::full_account::withdraws_to
vector< withdraw_permission_object > withdraws_to
Definition: api_objects.hpp:76
graphene::app::database_api_impl::get_whether_to_subscribe
bool get_whether_to_subscribe(optional< bool > subscribe) const
Definition: database_api_impl.hxx:317
graphene::app::database_api::get_tickets_by_account
vector< ticket_object > get_tickets_by_account(const std::string &account_name_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< ticket_id_type > &start_id=optional< ticket_id_type >()) const
Get a list of tickets by the name or ID of the owner account.
Definition: database_api.cpp:3023
graphene::market_history::history_key::base
asset_id_type base
Definition: market_history_plugin.hpp:104
graphene::app::market_trade::price
string price
Definition: api_objects.hpp:153
graphene::app::database_api::get_committee_members
vector< optional< committee_member_object > > get_committee_members(const vector< committee_member_id_type > &committee_member_ids) const
Get a list of committee_members by ID.
Definition: database_api.cpp:2261
graphene::app::database_api::get_account_limit_orders
vector< limit_order_object > get_account_limit_orders(const string &account_name_or_id, const string &base, const string &quote, uint32_t limit=application_options::get_default().api_limit_get_account_limit_orders, optional< limit_order_id_type > ostart_id=optional< limit_order_id_type >(), optional< price > ostart_price=optional< price >())
Fetch all orders relevant to the specified account and specified market, result orders are sorted des...
Definition: database_api.cpp:1113
graphene::chain::account_object::options
account_options options
Definition: account_object.hpp:222
graphene::app::market_queue_type
std::map< std::pair< graphene::chain::asset_id_type, graphene::chain::asset_id_type >, std::vector< fc::variant > > market_queue_type
Definition: database_api_impl.hxx:34
graphene::app::database_api::get_margin_positions
vector< call_order_object > get_margin_positions(const std::string &account_name_or_id) const
Get open margin positions of a given account.
Definition: database_api.cpp:1323
graphene::app::database_api::get_top_markets
vector< market_ticker > get_top_markets(uint32_t limit) const
Returns vector of tickers sorted by reverse base_volume.
Definition: database_api.cpp:1494
graphene::app::database_api::get_liquidity_pools_by_one_asset
vector< extended_liquidity_pool_object > get_liquidity_pools_by_one_asset(const std::string &asset_symbol_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< liquidity_pool_id_type > &start_id=optional< liquidity_pool_id_type >(), const optional< bool > &with_statistics=false) const
Get a list of liquidity pools by the symbol or ID of one asset in the pool.
Definition: database_api.cpp:1791
graphene::db::generic_index::find
const object * find(object_id_type id) const override
Definition: generic_index.hpp:98
graphene::app::database_api::get_credit_offers_by_owner
vector< credit_offer_object > get_credit_offers_by_owner(const std::string &account_name_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< credit_offer_id_type > &start_id=optional< credit_offer_id_type >()) const
Get a list of credit offers by the name or ID of the owner account.
Definition: database_api.cpp:2066
graphene::app::database_api_impl::get_assets_by_issuer
vector< extended_asset_object > get_assets_by_issuer(const std::string &issuer_name_or_id, asset_id_type start, uint32_t limit) const
Definition: database_api.cpp:1013
graphene::app::database_api::get_asset_id_from_string
asset_id_type get_asset_id_from_string(const std::string &symbol_or_id) const
Get asset ID from an asset symbol or ID.
Definition: database_api.cpp:941
graphene::db::index::get
const object & get(object_id_type id) const
Definition: index.hpp:110
graphene::chain::database::current_fee_schedule
const fee_schedule & current_fee_schedule() const
Definition: db_getter.cpp:62
dlog
#define dlog(FORMAT,...)
Definition: logger.hpp:100
graphene::db::generic_index::indices
const index_type & indices() const
Definition: generic_index.hpp:115
graphene::app::market_volume::time
time_point_sec time
Definition: api_objects.hpp:142
graphene::app::database_api::get_balance_objects
vector< balance_object > get_balance_objects(const vector< address > &addrs) const
Return all unclaimed balance objects for a list of addresses.
Definition: database_api.cpp:867
fc::variants
std::vector< variant > variants
Definition: variant.hpp:170
graphene::app::database_api_impl::get_global_properties
global_property_object get_global_properties() const
Definition: database_api.cpp:328
graphene::app::application_options::api_limit_get_call_orders
uint32_t api_limit_get_call_orders
Definition: application.hpp:67
graphene::chain::account_object
This class represents an account on the object graph.
Definition: account_object.hpp:180
graphene::app::database_api_impl::on_objects_changed
void on_objects_changed(const vector< object_id_type > &ids, const flat_set< account_id_type > &impacted_accounts)
Definition: database_api.cpp:3214
graphene::app::get_required_fees_helper::get_required_fees_helper
get_required_fees_helper(const fee_schedule &_current_fee_schedule, const price &_core_exchange_rate, uint32_t _max_recursion)
Definition: database_api.cpp:2693
graphene::app::database_api::get_transaction_hex_without_sig
std::string get_transaction_hex_without_sig(const transaction &trx) const
Get a hexdump of the serialized binary form of a signatures-stripped transaction.
Definition: database_api.cpp:2510
graphene::app::database_api_impl::get_withdraw_permissions_by_giver
vector< withdraw_permission_object > get_withdraw_permissions_by_giver(const std::string account_id_or_name, withdraw_permission_id_type start, uint32_t limit) const
Definition: database_api.cpp:2842
graphene::app::full_account::referrer_name
string referrer_name
Definition: api_objects.hpp:64
graphene::app::database_api::get_required_signatures
set< public_key_type > get_required_signatures(const signed_transaction &trx, const flat_set< public_key_type > &available_keys) const
Definition: database_api.cpp:2522
graphene::app::database_api::get_assets
vector< optional< extended_asset_object > > get_assets(const vector< std::string > &asset_symbols_or_ids, optional< bool > subscribe=optional< bool >()) const
Get a list of assets by symbol names or IDs.
Definition: database_api.cpp:946
graphene::app::database_api_impl::set_subscribe_callback
void set_subscribe_callback(std::function< void(const variant &)> cb, bool notify_remove_create)
Definition: database_api.cpp:172
fc::time_point_sec
Definition: time.hpp:74
graphene::protocol::asset::asset_id
asset_id_type asset_id
Definition: asset.hpp:37
graphene::app::database_api::get_witness_by_account
fc::optional< witness_object > get_witness_by_account(const std::string &account_name_or_id) const
Get the witness owned by a given account.
Definition: database_api.cpp:2191
graphene::app::database_api::get_accounts
vector< optional< account_object > > get_accounts(const vector< std::string > &account_names_or_ids, optional< bool > subscribe=optional< bool >()) const
Get a list of accounts by names or IDs.
Definition: database_api.cpp:492
graphene::app::database_api_impl::get_call_orders
vector< call_order_object > get_call_orders(const std::string &a, uint32_t limit) const
Definition: database_api.cpp:1211
graphene::app::application_options::api_limit_get_full_accounts
uint32_t api_limit_get_full_accounts
Definition: application.hpp:58
graphene::protocol::transfer_operation
Transfers an amount of one asset from one account to another.
Definition: transfer.hpp:45
graphene::app::database_api_impl::verify_authority
bool verify_authority(const signed_transaction &trx) const
Definition: database_api.cpp:2626
graphene::protocol::vote_id_type::worker
@ worker
Definition: vote.hpp:62
fc::async
auto async(Functor &&f, const char *desc FC_TASK_NAME_DEFAULT_ARG, priority prio=priority()) -> fc::future< decltype(f())>
Definition: thread.hpp:227
graphene::app::database_api::list_htlcs
vector< htlc_object > list_htlcs(const htlc_id_type start, uint32_t limit) const
Get all HTLCs.
Definition: database_api.cpp:2982
graphene::chain::by_expiration
Definition: proposal_object.hpp:86
graphene::chain::account_object::cashback_vb
optional< vesting_balance_id_type > cashback_vb
Definition: account_object.hpp:265
graphene::protocol::account_options::votes
flat_set< vote_id_type > votes
Definition: account.hpp:58
graphene::app::database_api_impl::get_top_voters
vector< account_statistics_object > get_top_voters(uint32_t limit) const
Definition: database_api.cpp:706
graphene::app::database_api_impl::get_transaction_hex
std::string get_transaction_hex(const signed_transaction &trx) const
Definition: database_api.cpp:2505
graphene::app::market_volume::base
string base
Definition: api_objects.hpp:143
graphene::app::database_api::get_call_orders
vector< call_order_object > get_call_orders(const std::string &a, uint32_t limit) const
Get call orders (aka margin positions) for a given asset.
Definition: database_api.cpp:1206
fc::ripemd160
Definition: ripemd160.hpp:11
graphene::app::market_volume::quote
string quote
Definition: api_objects.hpp:144
graphene::app::database_api::get_call_orders_by_account
vector< call_order_object > get_call_orders_by_account(const std::string &account_name_or_id, asset_id_type start, uint32_t limit) const
Get call orders (aka margin positions) of a given account.
Definition: database_api.cpp:1234
graphene::app::database_api::get_credit_deals_by_offer_id
vector< credit_deal_object > get_credit_deals_by_offer_id(const credit_offer_id_type &offer_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< credit_deal_id_type > &start_id=optional< credit_deal_id_type >()) const
Get a list of credit deals by the ID of a credit offer.
Definition: database_api.cpp:2103
graphene::app::database_api_impl::get_committee_count
uint64_t get_committee_count() const
Definition: database_api.cpp:2341
graphene::app::database_api_impl::get_call_orders_by_account
vector< call_order_object > get_call_orders_by_account(const std::string &account_name_or_id, asset_id_type start, uint32_t limit) const
Definition: database_api.cpp:1240
graphene::app::full_account::htlcs_from
vector< htlc_object > htlcs_from
Definition: api_objects.hpp:77
graphene::app::database_api::get_required_fees
vector< fc::variant > get_required_fees(const vector< operation > &ops, const std::string &asset_symbol_or_id) const
For each operation calculate the required fee in the specified asset type.
Definition: database_api.cpp:2681
graphene::app::full_account::cashback_balance
optional< vesting_balance_object > cashback_balance
Definition: api_objects.hpp:67
graphene::app::database_api_impl::get_ticker
market_ticker get_ticker(const string &base, const string &quote, bool skip_order_book=false) const
Definition: database_api.cpp:1397
graphene::app::database_api_impl::get_24_volume
market_volume get_24_volume(const string &base, const string &quote) const
Definition: database_api.cpp:1431
fc::to_variant
void to_variant(const flat_set< T, A... > &var, variant &vo, uint32_t _max_depth)
Definition: flat.hpp:105
graphene::app::application_options::api_limit_get_liquidity_pools
uint32_t api_limit_get_liquidity_pools
Definition: application.hpp:79
graphene::app::database_api_impl::get_committee_member_by_account
fc::optional< committee_member_object > get_committee_member_by_account(const std::string &account_id_or_name) const
Definition: database_api.cpp:2286
graphene::app::database_api::set_pending_transaction_callback
void set_pending_transaction_callback(std::function< void(const variant &signed_transaction_object)> cb)
Register a callback handle which will get notified when a transaction is pushed to database.
Definition: database_api.cpp:196
graphene::app::database_api::get_committee_member_by_account
fc::optional< committee_member_object > get_committee_member_by_account(const string &account_name_or_id) const
Get the committee_member owned by a given account.
Definition: database_api.cpp:2280
graphene::app::database_api::get_config
fc::variant_object get_config() const
Retrieve compile-time constants.
Definition: database_api.cpp:333
graphene::app::full_account::votes
vector< variant > votes
Definition: api_objects.hpp:66
graphene::app::application_options::api_limit_get_account_limit_orders
uint32_t api_limit_get_account_limit_orders
Definition: application.hpp:64
graphene::app::database_api_impl::handle_object_changed
void handle_object_changed(bool force_notify, bool full_object, const vector< object_id_type > &ids, const flat_set< account_id_type > &impacted_accounts, std::function< const object *(object_id_type id)> find_object)
Definition: database_api.cpp:3222
graphene::app::database_api::subscribe_to_market
void subscribe_to_market(std::function< void(const variant &)> callback, const std::string &a, const std::string &b)
Request notification when the active orders in the market between two assets changes.
Definition: database_api.cpp:1360
graphene::app::database_api::get_order_book
order_book get_order_book(const string &base, const string &quote, uint32_t limit=application_options::get_default().api_limit_get_order_book) const
Returns the order book for the market base:quote.
Definition: database_api.cpp:1445
graphene::app::database_api::get_trade_history
vector< market_trade > get_trade_history(const string &base, const string &quote, fc::time_point_sec start, fc::time_point_sec stop, uint32_t limit=application_options::get_default().api_limit_get_trade_history) const
Get market transactions occurred in the market base:quote, ordered by time, most recent first.
Definition: database_api.cpp:1527
graphene::app::database_api_impl::lookup_witness_accounts
map< string, witness_id_type, std::less<> > lookup_witness_accounts(const string &lower_bound_name, uint32_t limit) const
Definition: database_api.cpp:2212
graphene::app::database_api_impl::database_api_impl
database_api_impl(graphene::chain::database &db, const application_options *app_options)
Definition: database_api.cpp:69
GET_REQUIRED_FEES_MAX_RECURSION
#define GET_REQUIRED_FEES_MAX_RECURSION
Definition: database_api_impl.hxx:29
graphene::app::database_api::get_workers_by_account
vector< worker_object > get_workers_by_account(const std::string &account_name_or_id) const
Get the workers owned by a given account.
Definition: database_api.cpp:2386
graphene::protocol::chain_parameters::max_authority_depth
uint8_t max_authority_depth
Definition: chain_parameters.hpp:80
graphene::chain::required_approval_index
tracks all of the proposal objects that requrie approval of an individual account.
Definition: proposal_object.hpp:68
graphene::app::database_api_impl::amount_in_collateral_index
const graphene::api_helper_indexes::amount_in_collateral_index * amount_in_collateral_index
Definition: database_api_impl.hxx:434
graphene::app::database_api_impl::get_htlc_by_to
vector< htlc_object > get_htlc_by_to(const std::string account_id_or_name, htlc_id_type start, uint32_t limit) const
Definition: database_api.cpp:2958
graphene::app::database_api::get_limit_orders_by_account
vector< limit_order_object > get_limit_orders_by_account(const string &account_name_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< limit_order_id_type > &start_id=optional< limit_order_id_type >())
Fetch open limit orders in all markets relevant to the specified account, ordered by ID.
Definition: database_api.cpp:1073
graphene::app::application_options::api_limit_get_withdraw_permissions_by_recipient
uint32_t api_limit_get_withdraw_permissions_by_recipient
Definition: application.hpp:77
graphene::app::application_options::api_limit_get_full_accounts_lists
uint32_t api_limit_get_full_accounts_lists
Definition: application.hpp:59
graphene::app::database_api::get_account_id_from_string
account_id_type get_account_id_from_string(const std::string &name_or_id) const
Get account object from a name or ID.
Definition: database_api.cpp:487
graphene::app::more_data::proposals
bool proposals
Definition: api_objects.hpp:51
graphene::app::database_api_impl::asset_in_liquidity_pools_index
const graphene::api_helper_indexes::asset_in_liquidity_pools_index * asset_in_liquidity_pools_index
Definition: database_api_impl.hxx:435
graphene::app::database_api_impl::extend_liquidity_pool
extended_liquidity_pool_object extend_liquidity_pool(LP &&a, bool with_stats) const
Definition: database_api_impl.hxx:262
graphene::app::database_api::get_liquidity_pools_by_asset_b
vector< extended_liquidity_pool_object > get_liquidity_pools_by_asset_b(const std::string &asset_symbol_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< liquidity_pool_id_type > &start_id=optional< liquidity_pool_id_type >(), const optional< bool > &with_statistics=false) const
Get a list of liquidity pools by the symbol or ID of the second asset in the pool.
Definition: database_api.cpp:1777
graphene::protocol::share_type
safe< int64_t > share_type
Definition: types.hpp:309
graphene::app::database_api_impl::_subscribe_filter
fc::bloom_filter _subscribe_filter
Definition: database_api_impl.hxx:419
graphene::app::application_options::api_limit_get_limit_orders
uint32_t api_limit_get_limit_orders
Definition: application.hpp:62
graphene::app::order_book
Definition: api_objects.hpp:102
graphene::app::database_api::get_credit_deals_by_offer_owner
vector< credit_deal_object > get_credit_deals_by_offer_owner(const std::string &account_name_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< credit_deal_id_type > &start_id=optional< credit_deal_id_type >()) const
Get a list of credit deals by the name or ID of a credit offer owner account.
Definition: database_api.cpp:2115
graphene::app::get_required_fees_helper::set_op_fees
fc::variant set_op_fees(operation &op)
Definition: database_api.cpp:2703
graphene::app::database_api::get_credit_deals_by_debt_asset
vector< credit_deal_object > get_credit_deals_by_debt_asset(const std::string &asset_symbol_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< credit_deal_id_type > &start_id=optional< credit_deal_id_type >()) const
Get a list of credit deals by the symbol or ID of the debt asset type.
Definition: database_api.cpp:2141
graphene::protocol::transfer_operation::from
account_id_type from
Account to transfer asset from.
Definition: transfer.hpp:54
graphene::app::database_api_impl::_applied_block_connection
boost::signals2::scoped_connection _applied_block_connection
Definition: database_api_impl.hxx:429
graphene::app::database_api::get_transaction_hex
std::string get_transaction_hex(const signed_transaction &trx) const
Get a hexdump of the serialized binary form of a transaction.
Definition: database_api.cpp:2500
fc::typelist::transform
typename impl::transform< List, Transformer >::type transform
Transform elements of a typelist.
Definition: typelist.hpp:170
graphene::app::database_api_impl::is_impacted_account
bool is_impacted_account(const flat_set< account_id_type > &accounts)
Definition: database_api.cpp:3151
graphene::app::application_options::api_limit_get_credit_offers
uint32_t api_limit_get_credit_offers
Definition: application.hpp:81
graphene::app::database_api::list_tickets
vector< ticket_object > list_tickets(const optional< uint32_t > &limit=optional< uint32_t >(), const optional< ticket_id_type > &start_id=optional< ticket_id_type >()) const
Get a list of tickets.
Definition: database_api.cpp:3012
graphene::app::database_api_impl::get_account_count
uint64_t get_account_count() const
Definition: database_api.cpp:818
graphene::app::database_api_impl::get_chain_properties
chain_property_object get_chain_properties() const
Definition: database_api.cpp:318
graphene::app::database_api_impl::get_witness_by_account
fc::optional< witness_object > get_witness_by_account(const std::string &account_id_or_name) const
Definition: database_api.cpp:2196
graphene::app::database_api::get_htlc_by_from
vector< htlc_object > get_htlc_by_from(const std::string account_name_or_id, htlc_id_type start, uint32_t limit) const
Get non expired HTLC objects using the sender account.
Definition: database_api.cpp:2922
graphene::app::database_api::get_witnesses
vector< optional< witness_object > > get_witnesses(const vector< witness_id_type > &witness_ids) const
Get a list of witnesses by ID.
Definition: database_api.cpp:2174
graphene::app::database_api::get_potential_address_signatures
set< address > get_potential_address_signatures(const signed_transaction &trx) const
Definition: database_api.cpp:2548
graphene::app::database_api_impl::get_witnesses
vector< optional< witness_object > > get_witnesses(const vector< witness_id_type > &witness_ids) const
Definition: database_api.cpp:2179
graphene::app::database_api_impl::get_block_header_batch
map< uint32_t, optional< maybe_signed_block_header > > get_block_header_batch(const vector< uint32_t > &block_nums, bool with_witness_signatures) const
Definition: database_api.cpp:264
graphene::app::database_api_impl::on_objects_new
void on_objects_new(const vector< object_id_type > &ids, const flat_set< account_id_type > &impacted_accounts)
Definition: database_api.cpp:3206
graphene::app::database_api_impl::get_next_object_id
object_id_type get_next_object_id(uint8_t space_id, uint8_t type_id, bool with_pending_transactions) const
Definition: database_api.cpp:369
graphene::app::database_api_impl::on_objects_removed
void on_objects_removed(const vector< object_id_type > &ids, const vector< const object * > &objs, const flat_set< account_id_type > &impacted_accounts)
Definition: database_api.cpp:3188
graphene::app::application_options::api_limit_get_settle_orders
uint32_t api_limit_get_settle_orders
Definition: application.hpp:68
fc::time_point::now
static time_point now()
Definition: time.cpp:13
graphene::app::database_api_impl::broadcast_market_updates
void broadcast_market_updates(const market_queue_type &queue)
Definition: database_api.cpp:3172
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
graphene::app::market_trade::side1_account_id
account_id_type side1_account_id
Definition: api_objects.hpp:157
graphene::chain::database::validate_transaction
processed_transaction validate_transaction(const signed_transaction &trx)
Definition: db_block.cpp:307
graphene::app::market_trade
Definition: api_objects.hpp:149
graphene::app::database_api::get_htlc_by_to
vector< htlc_object > get_htlc_by_to(const std::string account_name_or_id, htlc_id_type start, uint32_t limit) const
Get non expired HTLC objects using the receiver account.
Definition: database_api.cpp:2952
graphene::protocol::processed_transaction
captures the result of evaluating the operations contained in the transaction
Definition: transaction.hpp:292
graphene::db::index::get_next_id
virtual object_id_type get_next_id() const =0
graphene::app::application_options::api_limit_get_assets
uint32_t api_limit_get_assets
Definition: application.hpp:55
graphene::app::database_api_impl::broadcast_updates
void broadcast_updates(const vector< variant > &updates)
Definition: database_api.cpp:3161
graphene::app::application_options::api_limit_get_trade_history_by_sequence
uint32_t api_limit_get_trade_history_by_sequence
Definition: application.hpp:52
graphene::app::database_api_impl::get_settle_orders
vector< force_settlement_object > get_settle_orders(const std::string &a, uint32_t limit) const
Definition: database_api.cpp:1267
graphene::app::database_api_impl::_pending_trx_callback
std::function< void(const fc::variant &)> _pending_trx_callback
Definition: database_api_impl.hxx:423
graphene::app::get_required_fees_helper::core_exchange_rate
const price & core_exchange_rate
Definition: database_api.cpp:2738
fc::static_variant::is_type
bool is_type() const
Definition: static_variant.hpp:332
fc::variant
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition: variant.hpp:198
graphene::app::database_api::~database_api
~database_api()
graphene::chain::liquidity_pool_object
A liquidity pool.
Definition: liquidity_pool_object.hpp:44
graphene::app::database_api::get_blinded_balances
vector< blinded_balance_object > get_blinded_balances(const flat_set< commitment_type > &commitments) const
return the set of blinded balance objects by commitment ID
Definition: database_api.cpp:2807
graphene::app::database_api_impl::get_config
fc::variant_object get_config() const
Definition: database_api.cpp:338
graphene::app::full_account::proposals
vector< proposal_object > proposals
Definition: api_objects.hpp:73
graphene::app::market_trade::sequence
int64_t sequence
Definition: api_objects.hpp:151
graphene::app::database_api::get_collateral_bids
vector< collateral_bid_object > get_collateral_bids(const std::string &a, uint32_t limit, uint32_t start) const
Get collateral_bid_objects for a given asset.
Definition: database_api.cpp:1330
graphene::app::application_options::has_market_history_plugin
bool has_market_history_plugin
Definition: application.hpp:44
graphene::app::database_api::get_committee_count
uint64_t get_committee_count() const
Get the total number of committee registered with the blockchain.
Definition: database_api.cpp:2336
fc::static_variant::get
X & get()
Definition: static_variant.hpp:236
graphene::app::database_api::get_full_accounts
map< string, full_account, std::less<> > get_full_accounts(const vector< string > &names_or_ids, const optional< bool > &subscribe=optional< bool >()) const
Fetch objects relevant to the specified accounts and optionally subscribe to updates.
Definition: database_api.cpp:516
graphene::app::database_api_impl::get_limit_orders
vector< limit_order_object > get_limit_orders(const std::string &a, const std::string &b, uint32_t limit) const
Definition: database_api.cpp:1058
graphene::app::database_api::list_assets
vector< extended_asset_object > list_assets(const string &lower_bound_symbol, uint32_t limit) const
Get assets alphabetically by symbol name.
Definition: database_api.cpp:972
std
Definition: zeroed_array.hpp:76
graphene::app::database_api::get_account_count
uint64_t get_account_count() const
Get the total number of accounts registered with the blockchain.
Definition: database_api.cpp:813
graphene::protocol::price::max
price max() const
Definition: asset.hpp:124
graphene::app::database_api_impl::_enabled_auto_subscription
bool _enabled_auto_subscription
Definition: database_api_impl.hxx:417
graphene::app::database_api_impl::_new_connection
boost::signals2::scoped_connection _new_connection
Definition: database_api_impl.hxx:426
graphene::app::database_api::get_top_voters
vector< account_statistics_object > get_top_voters(uint32_t limit) const
Returns vector of voting power sorted by reverse vp_active.
Definition: database_api.cpp:701
fc::static_variant::which
tag_type which() const
Definition: static_variant.hpp:329
graphene::app::database_api_impl::get_liquidity_pools_by_one_asset
vector< extended_liquidity_pool_object > get_liquidity_pools_by_one_asset(const std::string &asset_symbol_or_id, const optional< uint32_t > &limit, const optional< liquidity_pool_id_type > &start_id, const optional< bool > &with_statistics) const
Definition: database_api.cpp:1804
graphene::app::database_api_impl::get_proposed_transactions
vector< proposal_object > get_proposed_transactions(const std::string account_id_or_name) const
Definition: database_api.cpp:2777
fc::bloom_parameters
Definition: bloom_filter.hpp:46
graphene::app::database_api_impl::~database_api_impl
virtual ~database_api_impl()
Definition: database_api.cpp:124
FC_CAPTURE_AND_THROW
#define FC_CAPTURE_AND_THROW(EXCEPTION_TYPE,...)
Definition: exception.hpp:357
graphene::app::get_required_fees_helper::set_proposal_create_op_fees
fc::variant set_proposal_create_op_fees(operation &proposal_create_op)
Definition: database_api.cpp:2718
graphene::chain::global_property_object
Maintains global state information (committee_member list, current fees)
Definition: global_property_object.hpp:40
graphene::app::market_trade::amount
string amount
Definition: api_objects.hpp:154
graphene::app::database_api::get_worker_count
uint64_t get_worker_count() const
Get the total number of workers registered with the blockchain.
Definition: database_api.cpp:2405
graphene::app::price_to_string
std::string price_to_string(const graphene::protocol::price &_price, const uint8_t base_precision, const uint8_t quote_precision)
Definition: util.cpp:68
graphene::app::full_account::htlcs_to
vector< htlc_object > htlcs_to
Definition: api_objects.hpp:78
graphene::chain::operation_history_object::result
operation_result result
Definition: operation_history_object.hpp:59
graphene::app::database_api::get_transaction
processed_transaction get_transaction(uint32_t block_num, uint32_t trx_in_block) const
used to fetch an individual transaction.
Definition: database_api.cpp:285
GRAPHENE_MAX_NESTED_OBJECTS
#define GRAPHENE_MAX_NESTED_OBJECTS
Definition: config.hpp:33
graphene::app::database_api_impl::get_full_accounts
map< string, full_account, std::less<> > get_full_accounts(const vector< string > &names_or_ids, const optional< bool > &subscribe)
Definition: database_api.cpp:522
graphene::app::more_data::withdraws_from
bool withdraws_from
Definition: api_objects.hpp:53
graphene::app::database_api_impl::get_transaction
processed_transaction get_transaction(uint32_t block_num, uint32_t trx_in_block) const
Definition: database_api.cpp:299
graphene::protocol::op_wrapper
necessary to support nested operations inside the proposal_create_operation
Definition: operations.hpp:153
graphene::app::more_data::htlcs_from
bool htlcs_from
Definition: api_objects.hpp:55
graphene::app::database_api::get_block_header_batch
map< uint32_t, optional< maybe_signed_block_header > > get_block_header_batch(const vector< uint32_t > &block_nums, const optional< bool > &with_witness_signatures=optional< bool >()) const
Retrieve multiple block headers by block numbers.
Definition: database_api.cpp:257
graphene::app::database_api_impl::subscribe_to_market
void subscribe_to_market(std::function< void(const variant &)> callback, const std::string &a, const std::string &b)
Definition: database_api.cpp:1366
graphene::app::database_api::get_settle_orders_by_account
vector< force_settlement_object > get_settle_orders_by_account(const std::string &account_name_or_id, force_settlement_id_type start, uint32_t limit) const
Get forced settlement orders of a given account.
Definition: database_api.cpp:1290
graphene::app::database_api::get_global_properties
global_property_object get_global_properties() const
Retrieve the current graphene::chain::global_property_object.
Definition: database_api.cpp:323
graphene::app::database_api::get_credit_offers_by_asset
vector< credit_offer_object > get_credit_offers_by_asset(const std::string &asset_symbol_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< credit_offer_id_type > &start_id=optional< credit_offer_id_type >()) const
Get a list of credit offers by the symbol or ID of the asset type.
Definition: database_api.cpp:2079
graphene::app::database_api_impl::get_trade_history_by_sequence
vector< market_trade > get_trade_history_by_sequence(const string &base, const string &quote, int64_t start, fc::time_point_sec stop, uint32_t limit) const
Definition: database_api.cpp:1638
graphene::chain::witness_object
Definition: witness_object.hpp:32
graphene::app::application_options::api_limit_get_top_markets
uint32_t api_limit_get_top_markets
Definition: application.hpp:54
graphene::protocol::price::base
asset base
Definition: asset.hpp:113
graphene::app::database_api::get_block
optional< signed_block > get_block(uint32_t block_num) const
Retrieve a full, signed block.
Definition: database_api.cpp:275
graphene::chain::account_object::statistics
account_statistics_id_type statistics
Definition: account_object.hpp:229
graphene::app::database_api::unsubscribe_from_market
void unsubscribe_from_market(const std::string &a, const std::string &b)
Unsubscribe from updates to a given market.
Definition: database_api.cpp:1377
graphene::app::market_volume::base_volume
string base_volume
Definition: api_objects.hpp:145
graphene::db::generic_index
Definition: generic_index.hpp:43
graphene::app::database_api::list_credit_offers
vector< credit_offer_object > list_credit_offers(const optional< uint32_t > &limit=optional< uint32_t >(), const optional< credit_offer_id_type > &start_id=optional< credit_offer_id_type >()) const
Get a list of credit offers.
Definition: database_api.cpp:2055
restriction_predicate.hpp
graphene::protocol::price::min
price min() const
Definition: asset.hpp:125
graphene::db::object_database::get_index
const index & get_index() const
Definition: object_database.hpp:83
graphene::chain::account_member_index::account_to_key_memberships
map< public_key_type, set< account_id_type >, pubkey_comparator > account_to_key_memberships
Definition: account_object.hpp:341
graphene::db::abstract_object::get_id
object_id< SpaceID, TypeID > get_id() const
Definition: object.hpp:113
graphene::app::database_api::get_named_account_balances
vector< asset > get_named_account_balances(const std::string &name, const flat_set< asset_id_type > &assets) const
Semantically equivalent to get_account_balances.
Definition: database_api.cpp:861
graphene::app::database_api::get_samet_funds_by_owner
vector< samet_fund_object > get_samet_funds_by_owner(const std::string &account_name_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< samet_fund_id_type > &start_id=optional< samet_fund_id_type >()) const
Get a list of SameT Funds by the name or ID of the owner account.
Definition: database_api.cpp:2022
graphene::app::database_api_impl::get_vested_balances
vector< asset > get_vested_balances(const vector< balance_id_type > &objs) const
Definition: database_api.cpp:900
database_api.hpp
graphene::chain::database::get_global_properties
const global_property_object & get_global_properties() const
Definition: db_getter.cpp:47
graphene::app::database_api::set_subscribe_callback
void set_subscribe_callback(std::function< void(const variant &)> cb, bool notify_remove_create)
Register a callback handle which then can be used to subscribe to object database changes.
Definition: database_api.cpp:167
graphene::app::database_api_helper::_db
graphene::chain::database & _db
Definition: database_api_helper.hxx:35
graphene::app::database_api::list_samet_funds
vector< samet_fund_object > list_samet_funds(const optional< uint32_t > &limit=optional< uint32_t >(), const optional< samet_fund_id_type > &start_id=optional< samet_fund_id_type >()) const
Get a list of SameT Funds.
Definition: database_api.cpp:2011
graphene::app::database_api_impl::get_required_signatures
set< public_key_type > get_required_signatures(const signed_transaction &trx, const flat_set< public_key_type > &available_keys) const
Definition: database_api.cpp:2528
graphene::app::database_api_impl::get_potential_address_signatures
set< address > get_potential_address_signatures(const signed_transaction &trx) const
Definition: database_api.cpp:2592
graphene::app::database_api::get_liquidity_pools_by_both_assets
vector< extended_liquidity_pool_object > get_liquidity_pools_by_both_assets(const std::string &asset_symbol_or_id_a, const std::string &asset_symbol_or_id_b, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< liquidity_pool_id_type > &start_id=optional< liquidity_pool_id_type >(), const optional< bool > &with_statistics=false) const
Get a list of liquidity pools by the symbols or IDs of the two assets in the pool.
Definition: database_api.cpp:1843
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
graphene::app::database_api::get_limit_orders
vector< limit_order_object > get_limit_orders(std::string a, std::string b, uint32_t limit) const
Get limit orders in a given market.
Definition: database_api.cpp:1053
graphene::app::application_options::api_limit_get_top_voters
uint32_t api_limit_get_top_voters
Definition: application.hpp:61
graphene::api_helper_indexes::asset_in_liquidity_pools_index::get_liquidity_pools_by_asset
const flat_set< liquidity_pool_id_type > & get_liquidity_pools_by_asset(const asset_id_type &a) const
Definition: api_helper_indexes.cpp:124
graphene::app::database_api::get_all_workers
vector< worker_object > get_all_workers(const optional< bool > &is_expired=optional< bool >()) const
Get workers.
Definition: database_api.cpp:2353
graphene::app::database_api_impl::_block_applied_callback
std::function< void(const fc::variant &)> _block_applied_callback
Definition: database_api_impl.hxx:424
graphene::app::database_api::list_liquidity_pools
vector< extended_liquidity_pool_object > list_liquidity_pools(const optional< uint32_t > &limit=optional< uint32_t >(), const optional< liquidity_pool_id_type > &start_id=optional< liquidity_pool_id_type >(), const optional< bool > &with_statistics=false) const
Get a list of liquidity pools.
Definition: database_api.cpp:1752
graphene::app::database_api::get_witness_count
uint64_t get_witness_count() const
Get the total number of witnesses registered with the blockchain.
Definition: database_api.cpp:2245
graphene::app::market_trade::value
string value
Definition: api_objects.hpp:155
graphene::app::database_api::lookup_vote_ids
vector< variant > lookup_vote_ids(const vector< vote_id_type > &votes) const
Given a set of votes, return the objects they are voting for.
Definition: database_api.cpp:2423
graphene::chain::chain_property_object
Definition: chain_property_object.hpp:33
graphene::chain::account_object::referrer
account_id_type referrer
The account credited as referring this account. Receives a percentage of referral rewards.
Definition: account_object.hpp:196
graphene::app::order_book::bids
vector< order > bids
Definition: api_objects.hpp:106
graphene::app::database_api_impl::is_subscribed_to_item
bool is_subscribed_to_item(const T &item) const
Definition: database_api_impl.hxx:354
graphene::protocol::proposal_create_operation::proposed_ops
vector< op_wrapper > proposed_ops
Definition: proposal.hpp:79
FC_THROW_EXCEPTION
#define FC_THROW_EXCEPTION(EXCEPTION, FORMAT,...)
Definition: exception.hpp:379
graphene::app::market_trade::type
string type
Definition: api_objects.hpp:156
graphene::protocol::asset
Definition: asset.hpp:31
graphene::chain::asset_object::options
asset_options options
Definition: asset_object.hpp:137
graphene::chain::database::fetch_block_by_number
optional< signed_block > fetch_block_by_number(uint32_t num) const
Definition: db_block.cpp:76
graphene::app::application_options::api_limit_lookup_witness_accounts
uint32_t api_limit_lookup_witness_accounts
Definition: application.hpp:71
graphene::app::database_api_impl::_pending_trx_connection
boost::signals2::scoped_connection _pending_trx_connection
Definition: database_api_impl.hxx:430
graphene::app::database_api_impl::get_account_balances
vector< asset > get_account_balances(const std::string &account_name_or_id, const flat_set< asset_id_type > &assets) const
Definition: database_api.cpp:835
graphene::app::full_account::settle_orders
vector< force_settlement_object > settle_orders
Definition: api_objects.hpp:72
graphene::app::application_options::api_limit_get_trade_history
uint32_t api_limit_get_trade_history
Definition: application.hpp:51
graphene::protocol::signed_block
Definition: block.hpp:64
graphene::protocol::proposal_create_operation
The proposal_create_operation creates a transaction proposal, for use in multi-sig scenarios.
Definition: proposal.hpp:70
graphene::chain::asset_object::is_market_issued
bool is_market_issued() const
Definition: asset_object.hpp:84
graphene::db::object_database::get_index_type
const IndexType & get_index_type() const
Definition: object_database.hpp:77
graphene::chain::database::get_dynamic_global_properties
const dynamic_global_property_object & get_dynamic_global_properties() const
Definition: db_getter.cpp:57
graphene::protocol::vote_id_type::VOTE_TYPE_COUNT
@ VOTE_TYPE_COUNT
Definition: vote.hpp:63
graphene::app::application_options::api_limit_lookup_accounts
uint32_t api_limit_lookup_accounts
Definition: application.hpp:70
graphene::app::database_api::get_vesting_balances
vector< vesting_balance_object > get_vesting_balances(const std::string account_name_or_id) const
Return all vesting balance objects owned by an account.
Definition: database_api.cpp:913
graphene::app::database_api::get_liquidity_pools
vector< optional< extended_liquidity_pool_object > > get_liquidity_pools(const vector< liquidity_pool_id_type > &ids, const optional< bool > &subscribe=optional< bool >(), const optional< bool > &with_statistics=false) const
Get a list of liquidity pools by their IDs.
Definition: database_api.cpp:1862
graphene::app::more_data::settle_orders
bool settle_orders
Definition: api_objects.hpp:50
graphene::app::application_options::api_limit_get_order_book
uint32_t api_limit_get_order_book
Definition: application.hpp:66
graphene::app::get_required_fees_helper
Definition: database_api.cpp:2691
graphene::app::get_required_fees_helper::max_recursion
uint32_t max_recursion
Definition: database_api.cpp:2739
graphene::app::database_api_impl::get_accounts
vector< optional< account_object > > get_accounts(const vector< std::string > &account_names_or_ids, optional< bool > subscribe) const
Definition: database_api.cpp:498
graphene::chain::limit_order_object
an offer to sell an amount of an asset at a specified exchange rate by a certain time
Definition: market_object.hpp:45
graphene::app::database_api::get_withdraw_permissions_by_recipient
vector< withdraw_permission_object > get_withdraw_permissions_by_recipient(const std::string account_name_or_id, withdraw_permission_id_type start, uint32_t limit) const
Get non expired withdraw permission objects for a recipient(ex:service provider)
Definition: database_api.cpp:2868
fc::api< graphene::app::database_api >
graphene::chain::database::new_objects
fc::signal< void(const vector< object_id_type > &, const flat_set< account_id_type > &)> new_objects
Definition: database.hpp:636
graphene::app::more_data::balances
bool balances
Definition: api_objects.hpp:46
graphene::protocol::bitasset_options::short_backing_asset
asset_id_type short_backing_asset
Definition: asset_ops.hpp:171
graphene::app::get_required_fees_helper::current_recursion
uint32_t current_recursion
Definition: database_api.cpp:2740
graphene::app::database_api_impl::_change_connection
boost::signals2::scoped_connection _change_connection
Definition: database_api_impl.hxx:427
graphene::app::database_api_impl::_market_subscriptions
map< pair< asset_id_type, asset_id_type >, std::function< void(const variant &)> > _market_subscriptions
Definition: database_api_impl.hxx:432
graphene::chain::vesting_balance_type::witness
@ witness
graphene::app::database_api::get_recent_transaction_by_id
optional< signed_transaction > get_recent_transaction_by_id(const transaction_id_type &txid) const
Definition: database_api.cpp:290
graphene::app::database_api_impl::get_htlc_by_from
vector< htlc_object > get_htlc_by_from(const std::string account_id_or_name, htlc_id_type start, uint32_t limit) const
Definition: database_api.cpp:2928
database_api_impl.hxx
graphene::app::full_account
Definition: api_objects.hpp:59
graphene::app::database_api_impl::get_withdraw_permissions_by_recipient
vector< withdraw_permission_object > get_withdraw_permissions_by_recipient(const std::string account_id_or_name, withdraw_permission_id_type start, uint32_t limit) const
Definition: database_api.cpp:2876
graphene::protocol::price::quote
asset quote
Definition: asset.hpp:114
graphene
Definition: api.cpp:48
graphene::app::database_api_impl::get_assets
vector< optional< extended_asset_object > > get_assets(const vector< std::string > &asset_symbols_or_ids, optional< bool > subscribe) const
Definition: database_api.cpp:953
graphene::app::database_api_impl::get_balance_objects
vector< balance_object > get_balance_objects(const vector< address > &addrs) const
Definition: database_api.cpp:872
graphene::app::more_data::withdraws_to
bool withdraws_to
Definition: api_objects.hpp:54
util.hpp
graphene::chain::asset_bitasset_data_object::options
bitasset_options options
The tunable options for BitAssets are stored in this field.
Definition: asset_object.hpp:263
graphene::app::database_api_impl::get_account_references
vector< account_id_type > get_account_references(const std::string account_id_or_name) const
Definition: database_api.cpp:746
graphene::app::application_options
Definition: application.hpp:38
fc::typelist::runtime::for_each
void for_each(list< Types... >, Callable c)
Invoke the provided callable with an argument wrapper<Type>() for each type in the list.
Definition: typelist.hpp:257
graphene::app::database_api_impl::get_all_workers
vector< worker_object > get_all_workers(const optional< bool > &is_expired) const
Definition: database_api.cpp:2358
graphene::chain::account_object::cashback_balance
const vesting_balance_object & cashback_balance(const DB &db) const
Definition: account_object.hpp:297
fc::raw::pack
void pack(Stream &s, const flat_set< T, A... > &value, uint32_t _max_depth)
Definition: flat.hpp:11
graphene::app::application_options::enable_subscribe_to_all
bool enable_subscribe_to_all
Definition: application.hpp:41
graphene::app::application_options::has_api_helper_indexes_plugin
bool has_api_helper_indexes_plugin
Definition: application.hpp:43
graphene::chain::operation_history_object
tracks the history of all logical operations on blockchain state
Definition: operation_history_object.hpp:48
graphene::app::database_api_impl::get_transaction_hex_without_sig
std::string get_transaction_hex_without_sig(const transaction &trx) const
Definition: database_api.cpp:2516
graphene::app::database_api_impl::_subscribed_accounts
std::set< account_id_type > _subscribed_accounts
Definition: database_api_impl.hxx:420
graphene::app::database_api_helper
Definition: database_api_helper.hxx:28
graphene::app::full_account::more_data_available
more_data more_data_available
Definition: api_objects.hpp:79
graphene::protocol::operation
fc::static_variant< transfer_operation, limit_order_create_operation, limit_order_cancel_operation, call_order_update_operation, fill_order_operation, account_create_operation, account_update_operation, account_whitelist_operation, account_upgrade_operation, account_transfer_operation, asset_create_operation, asset_update_operation, asset_update_bitasset_operation, asset_update_feed_producers_operation, asset_issue_operation, asset_reserve_operation, asset_fund_fee_pool_operation, asset_settle_operation, asset_global_settle_operation, asset_publish_feed_operation, witness_create_operation, witness_update_operation, proposal_create_operation, proposal_update_operation, proposal_delete_operation, withdraw_permission_create_operation, withdraw_permission_update_operation, withdraw_permission_claim_operation, withdraw_permission_delete_operation, committee_member_create_operation, committee_member_update_operation, committee_member_update_global_parameters_operation, vesting_balance_create_operation, vesting_balance_withdraw_operation, worker_create_operation, custom_operation, assert_operation, balance_claim_operation, override_transfer_operation, transfer_to_blind_operation, blind_transfer_operation, transfer_from_blind_operation, asset_settle_cancel_operation, asset_claim_fees_operation, fba_distribute_operation, bid_collateral_operation, execute_bid_operation, asset_claim_pool_operation, asset_update_issuer_operation, htlc_create_operation, htlc_redeem_operation, htlc_redeemed_operation, htlc_extend_operation, htlc_refund_operation, custom_authority_create_operation, custom_authority_update_operation, custom_authority_delete_operation, ticket_create_operation, ticket_update_operation, liquidity_pool_create_operation, liquidity_pool_delete_operation, liquidity_pool_deposit_operation, liquidity_pool_withdraw_operation, liquidity_pool_exchange_operation, samet_fund_create_operation, samet_fund_delete_operation, samet_fund_update_operation, samet_fund_borrow_operation, samet_fund_repay_operation, credit_offer_create_operation, credit_offer_delete_operation, credit_offer_update_operation, credit_offer_accept_operation, credit_deal_repay_operation, credit_deal_expired_operation, liquidity_pool_update_operation, credit_deal_update_operation, limit_order_update_operation > operation
Definition: operations.hpp:134
graphene::app::database_api::is_public_key_registered
bool is_public_key_registered(string public_key) const
Definition: database_api.cpp:447
graphene::app::database_api_impl::get_key_references
vector< flat_set< account_id_type > > get_key_references(vector< public_key_type > key) const
Definition: database_api.cpp:394
graphene::app::full_account::registrar_name
string registrar_name
Definition: api_objects.hpp:63
graphene::chain::committee_member_object
tracks information about a committee_member account.
Definition: committee_member_object.hpp:43
graphene::app::database_api_impl::get_liquidity_pools
vector< optional< extended_liquidity_pool_object > > get_liquidity_pools(const vector< liquidity_pool_id_type > &ids, const optional< bool > &subscribe, const optional< bool > &with_statistics) const
Definition: database_api.cpp:1873
graphene::app::full_account::call_orders
vector< call_order_object > call_orders
Definition: api_objects.hpp:71
graphene::app::database_api_helper::get_account_from_string
const account_object * get_account_from_string(const std::string &name_or_id, bool throw_if_not_found=true) const
Definition: database_api.cpp:3042
graphene::app::database_api::get_next_object_id
object_id_type get_next_object_id(uint8_t space_id, uint8_t type_id, bool with_pending_transactions) const
Get the next object ID in an object space.
Definition: database_api.cpp:363