BitShares-Core  6.1.0
BitShares blockchain implementation and command-line interface software
api.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 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 #include <cctype>
25 
26 #include <graphene/app/api.hpp>
28 
29 #include "database_api_helper.hxx"
30 
31 #include <fc/crypto/base64.hpp>
33 #include <fc/thread/future.hpp>
34 
46 
47 
48 namespace graphene { namespace app {
49 
50  login_api::login_api(application& a)
51  :_app(a)
52  {
53  // Nothing to do
54  }
55 
56  variant login_api::login(const optional<string>& o_user, const optional<string>& o_password)
57  {
58  if( !o_user && !o_password )
59  return uint32_t(1); // Note: hard code it here for backward compatibility
60 
61  FC_ASSERT( o_user.valid() && o_password.valid(), "Must provide both user and password" );
62  string user = *o_user;
63 
65  if( !acc.valid() )
66  return logout();
67  if( acc->password_hash_b64 != "*" )
68  {
69  std::string password_salt = fc::base64_decode( acc->password_salt_b64 );
70  std::string acc_password_hash = fc::base64_decode( acc->password_hash_b64 );
71 
72  string password = *o_password;
73  fc::sha256 hash_obj = fc::sha256::hash( password + password_salt );
74  if( hash_obj.data_size() != acc_password_hash.length() )
75  return logout();
76  if( memcmp( hash_obj.data(), acc_password_hash.c_str(), hash_obj.data_size() ) != 0 )
77  return logout();
78  }
79 
80  // Ideally, we should clean up the API sets that the previous user registered but the new user
81  // no longer has access to.
82  // However, the shared pointers to these objects are already saved elsewhere (in FC),
83  // so we are unable to clean up, so it does not make sense to reset the optional fields here.
84 
85  _allowed_apis = acc->allowed_apis;
86  return true;
87  }
88 
90  {
91  // Ideally, we should clean up the API sets that the previous user registered.
92  // However, the shared pointers to these objects are already saved elsewhere (in FC),
93  // so we are unable to clean up, so it does not make sense to reset the optional fields here.
94  _allowed_apis.clear();
95  return false;
96  }
97 
98  string login_api::get_info() const
99  {
100  return _app.get_node_info();
101  }
102 
104  {
105  bool is_allowed = !_allowed_apis.empty();
106  FC_ASSERT( is_allowed, "Access denied, please login" );
107  return _app.get_options();
108  }
109 
110  flat_set<string> login_api::get_available_api_sets() const
111  {
112  return _allowed_apis;
113  }
114 
116  {
117  bool is_allowed = ( _allowed_apis.find("database_api") != _allowed_apis.end() );
118  return is_allowed;
119  }
120 
121  // block_api
122  block_api::block_api(const graphene::chain::database& db) : _db(db) { /* Nothing to do */ }
123 
124  vector<optional<signed_block>> block_api::get_blocks(uint32_t block_num_from, uint32_t block_num_to)const
125  {
126  FC_ASSERT( block_num_to >= block_num_from );
127  vector<optional<signed_block>> res;
128  for(uint32_t block_num=block_num_from; block_num<=block_num_to; block_num++) {
129  res.push_back(_db.fetch_block_by_number(block_num));
130  }
131  return res;
132  }
133 
135  {
136  _applied_block_connection = _app.chain_database()->applied_block.connect(
137  [this](const signed_block& b){ on_applied_block(b); });
138  }
139 
141  {
142  if( _callbacks.size() )
143  {
145  auto capture_this = shared_from_this();
146  for( uint32_t trx_num = 0; trx_num < b.transactions.size(); ++trx_num )
147  {
148  const auto& trx = b.transactions[trx_num];
149  auto id = trx.id();
150  auto itr = _callbacks.find(id);
151  if( itr != _callbacks.end() )
152  {
153  auto block_num = b.block_num();
154  auto& callback = _callbacks.find(id)->second;
155  auto v = fc::variant( transaction_confirmation{ id, block_num, trx_num, trx },
157  fc::async( [capture_this,v,callback]() {
158  callback(v);
159  } );
160  }
161  }
162  }
163  }
164 
165  void network_broadcast_api::broadcast_transaction(const precomputable_transaction& trx)
166  {
167  FC_ASSERT( _app.p2p_node() != nullptr, "Not connected to P2P network, can't broadcast!" );
168  _app.chain_database()->precompute_parallel( trx ).wait();
169  _app.chain_database()->push_transaction(trx);
170  _app.p2p_node()->broadcast_transaction(trx);
171  }
172 
174  {
177  prom->set_value(v);
178  }, trx );
179 
180  return fc::future<fc::variant>(prom).wait();
181  }
182 
184  {
185  FC_ASSERT( _app.p2p_node() != nullptr, "Not connected to P2P network, can't broadcast!" );
186  _app.chain_database()->precompute_parallel( b ).wait();
187  _app.chain_database()->push_block(b);
188  _app.p2p_node()->broadcast( net::block_message( b ));
189  }
190 
192  {
193  FC_ASSERT( _app.p2p_node() != nullptr, "Not connected to P2P network, can't broadcast!" );
194  _app.chain_database()->precompute_parallel( trx ).wait();
195  _callbacks[trx.id()] = cb;
196  _app.chain_database()->push_transaction(trx);
197  _app.p2p_node()->broadcast_transaction(trx);
198  }
199 
201  {
202  // Nothing to do
203  }
204 
206  {
207  FC_ASSERT( _app.p2p_node() != nullptr, "No P2P network!" );
208  fc::mutable_variant_object result = _app.p2p_node()->network_get_info();
209  result["connection_count"] = _app.p2p_node()->get_connection_count();
210  return result;
211  }
212 
214  {
215  if( _app.p2p_node() != nullptr )
216  _app.p2p_node()->add_node(ep);
217  }
218 
219  std::vector<net::peer_status> network_node_api::get_connected_peers() const
220  {
221  if( _app.p2p_node() != nullptr )
222  return _app.p2p_node()->get_connected_peers();
223  return {};
224  }
225 
226  std::vector<net::potential_peer_record> network_node_api::get_potential_peers() const
227  {
228  if( _app.p2p_node() != nullptr )
229  return _app.p2p_node()->get_potential_peers();
230  return {};
231  }
232 
234  {
235  FC_ASSERT( _app.p2p_node() != nullptr, "No P2P network!" );
236  return _app.p2p_node()->get_advanced_node_parameters();
237  }
238 
240  {
241  FC_ASSERT( _app.p2p_node() != nullptr, "No P2P network!" );
242  return _app.p2p_node()->set_advanced_node_parameters(params);
243  }
244 
246  {
247  bool is_allowed = ( _allowed_apis.find("network_broadcast_api") != _allowed_apis.end() );
248  FC_ASSERT( is_allowed, "Access denied" );
249  if( !_network_broadcast_api )
250  {
251  _network_broadcast_api = std::make_shared< network_broadcast_api >( std::ref( _app ) );
252  }
253  return *_network_broadcast_api;
254  }
255 
257  {
258  bool is_allowed = ( _allowed_apis.find("block_api") != _allowed_apis.end() );
259  FC_ASSERT( is_allowed, "Access denied" );
260  if( !_block_api )
261  {
262  _block_api = std::make_shared< block_api >( std::ref( *_app.chain_database() ) );
263  }
264  return *_block_api;
265  }
266 
268  {
269  bool is_allowed = ( _allowed_apis.find("network_node_api") != _allowed_apis.end() );
270  FC_ASSERT( is_allowed, "Access denied" );
271  if( !_network_node_api )
272  {
273  _network_node_api = std::make_shared< network_node_api >( std::ref(_app) );
274  }
275  return *_network_node_api;
276  }
277 
279  {
280  bool is_allowed = ( _allowed_apis.find("database_api") != _allowed_apis.end() );
281  FC_ASSERT( is_allowed, "Access denied" );
282  if( !_database_api )
283  {
284  _database_api = std::make_shared< database_api >( std::ref( *_app.chain_database() ),
285  &( _app.get_options() ) );
286  }
287  return *_database_api;
288  }
289 
291  {
292  bool is_allowed = ( _allowed_apis.find("history_api") != _allowed_apis.end() );
293  FC_ASSERT( is_allowed, "Access denied" );
294  if( !_history_api )
295  {
296  _history_api = std::make_shared< history_api >( _app );
297  }
298  return *_history_api;
299  }
300 
302  {
303  bool is_allowed = ( _allowed_apis.find("crypto_api") != _allowed_apis.end() );
304  FC_ASSERT( is_allowed, "Access denied" );
305  if( !_crypto_api )
306  {
307  _crypto_api = std::make_shared< crypto_api >();
308  }
309  return *_crypto_api;
310  }
311 
313  {
314  bool is_allowed = ( _allowed_apis.find("asset_api") != _allowed_apis.end() );
315  FC_ASSERT( is_allowed, "Access denied" );
316  if( !_asset_api )
317  {
318  _asset_api = std::make_shared< asset_api >( _app );
319  }
320  return *_asset_api;
321  }
322 
324  {
325  bool is_allowed = ( _allowed_apis.find("orders_api") != _allowed_apis.end() );
326  FC_ASSERT( is_allowed, "Access denied" );
327  if( !_orders_api )
328  {
329  _orders_api = std::make_shared< orders_api >( std::ref( _app ) );
330  }
331  return *_orders_api;
332  }
333 
335  {
336  bool is_allowed = ( _allowed_apis.find("debug_api") != _allowed_apis.end() );
337  FC_ASSERT( is_allowed, "Access denied" );
338  // can only use this API set if the plugin was loaded
339  bool plugin_enabled = !!_app.get_plugin( "debug_witness" );
340  FC_ASSERT( plugin_enabled, "The debug_witness plugin is not enabled" );
341  if( ! _debug_api )
342  {
343  _debug_api = std::make_shared< graphene::debug_witness::debug_api >( std::ref(_app) );
344  }
345  return *_debug_api;
346  }
347 
349  {
350  bool is_allowed = ( _allowed_apis.find("custom_operations_api") != _allowed_apis.end() );
351  FC_ASSERT( is_allowed, "Access denied" );
352  // can only use this API set if the plugin was loaded
353  bool plugin_enabled = !!_app.get_plugin( "custom_operations" );
354  FC_ASSERT( plugin_enabled, "The custom_operations plugin is not enabled" );
355  if( !_custom_operations_api )
356  {
357  _custom_operations_api = std::make_shared< custom_operations_api >( std::ref( _app ) );
358  }
359  return *_custom_operations_api;
360  }
361 
363  {
364  if( !_dummy_api )
365  {
366  _dummy_api = std::make_shared< dummy_api >();
367  }
368  return *_dummy_api;
369  }
370 
372  : _app(app)
373  { // Nothing else to do
374  }
375 
376  vector<order_history_object> history_api::get_fill_order_history( const std::string& asset_a,
377  const std::string& asset_b,
378  uint32_t limit )const
379  {
380  auto market_hist_plugin = _app.get_plugin<market_history_plugin>( "market_history" );
381  FC_ASSERT( market_hist_plugin, "Market history plugin is not enabled" );
382  FC_ASSERT(_app.chain_database());
383  const auto& db = *_app.chain_database();
384  database_api_helper db_api_helper( _app );
385  asset_id_type a = db_api_helper.get_asset_from_string( asset_a )->get_id();
386  asset_id_type b = db_api_helper.get_asset_from_string( asset_b )->get_id();
387  if( a > b ) std::swap(a,b);
388  const auto& history_idx = db.get_index_type<graphene::market_history::history_index>().indices().get<by_key>();
389  history_key hkey;
390  hkey.base = a;
391  hkey.quote = b;
392  hkey.sequence = std::numeric_limits<int64_t>::min();
393 
394  auto itr = history_idx.lower_bound( hkey );
395  vector<order_history_object> result;
396  while( itr != history_idx.end() && result.size() < limit )
397  {
398  if( itr->key.base != a || itr->key.quote != b ) break;
399  result.push_back( *itr );
400  ++itr;
401  }
402 
403  return result;
404  }
405 
406  vector<operation_history_object> history_api::get_account_history( const std::string& account_id_or_name,
407  operation_history_id_type stop,
408  uint32_t limit,
409  operation_history_id_type start ) const
410  {
411  FC_ASSERT( _app.chain_database(), "database unavailable" );
412  const auto& db = *_app.chain_database();
413 
414  const auto configured_limit = _app.get_options().api_limit_get_account_history;
415  FC_ASSERT( limit <= configured_limit,
416  "limit can not be greater than ${configured_limit}",
417  ("configured_limit", configured_limit) );
418 
419  vector<operation_history_object> result;
420  if( start == operation_history_id_type() )
421  // Note: this means we can hardly use ID 0 as start to query for exactly the object with ID 0
422  start = operation_history_id_type::max();
423  if( start < stop )
424  return result;
425 
426  account_id_type account;
427  try {
428  database_api_helper db_api_helper( _app );
429  account = db_api_helper.get_account_from_string(account_id_or_name)->get_id();
430  } catch(...) { return result; }
431 
432  if(_app.is_plugin_enabled("elasticsearch")) {
433  auto es = _app.get_plugin<elasticsearch::elasticsearch_plugin>("elasticsearch");
434  if(es.get()->get_running_mode() != elasticsearch::mode::only_save) {
435  if(!_app.elasticsearch_thread)
436  _app.elasticsearch_thread= std::make_shared<fc::thread>("elasticsearch");
437 
438  return _app.elasticsearch_thread->async([&es, account, stop, limit, start]() {
439  return es->get_account_history(account, stop, limit, start);
440  }, "thread invoke for method " BOOST_PP_STRINGIZE(method_name)).wait();
441  }
442  }
443 
444  const auto& by_op_idx = db.get_index_type<account_history_index>().indices().get<by_op>();
445  auto itr = by_op_idx.lower_bound( boost::make_tuple( account, start ) );
446  auto itr_end = by_op_idx.lower_bound( boost::make_tuple( account, stop ) );
447 
448  while( itr != itr_end && result.size() < limit )
449  {
450  result.emplace_back( itr->operation_id(db) );
451  ++itr;
452  }
453  // Deal with a special case : include the object with ID 0 when it fits
454  if( 0 == stop.instance.value && result.size() < limit && itr != by_op_idx.end() )
455  {
456  const auto& obj = *itr;
457  if( obj.account == account )
458  result.emplace_back( obj.operation_id(db) );
459  }
460 
461  return result;
462  }
463 
464  vector<operation_history_object> history_api::get_account_history_by_time(
465  const std::string& account_name_or_id,
466  const optional<uint32_t>& olimit,
467  const optional<fc::time_point_sec>& ostart ) const
468  {
469  FC_ASSERT( _app.chain_database(), "database unavailable" );
470  const auto& db = *_app.chain_database();
471 
472  const auto configured_limit = _app.get_options().api_limit_get_account_history;
473  uint32_t limit = olimit.valid() ? *olimit : configured_limit;
474  FC_ASSERT( limit <= configured_limit,
475  "limit can not be greater than ${configured_limit}",
476  ("configured_limit", configured_limit) );
477 
478  vector<operation_history_object> result;
479  account_id_type account;
480  try {
481  database_api_helper db_api_helper( _app );
482  account = db_api_helper.get_account_from_string(account_name_or_id)->get_id();
483  } catch( const fc::exception& ) { return result; }
484 
485  fc::time_point_sec start = ostart.valid() ? *ostart : fc::time_point_sec::maximum();
486 
487  const auto& op_hist_idx = db.get_index_type<operation_history_index>().indices().get<by_time>();
488  auto op_hist_itr = op_hist_idx.lower_bound( start );
489  if( op_hist_itr == op_hist_idx.end() )
490  return result;
491 
492  const auto& acc_hist_idx = db.get_index_type<account_history_index>().indices().get<by_op>();
493  auto itr = acc_hist_idx.lower_bound( boost::make_tuple( account, op_hist_itr->get_id() ) );
494  auto itr_end = acc_hist_idx.upper_bound( account );
495 
496  while( itr != itr_end && result.size() < limit )
497  {
498  result.emplace_back( itr->operation_id(db) );
499  ++itr;
500  }
501 
502  return result;
503  }
504 
505  vector<operation_history_object> history_api::get_account_history_operations(
506  const std::string& account_id_or_name,
507  int64_t operation_type,
508  operation_history_id_type start,
509  operation_history_id_type stop,
510  uint32_t limit ) const
511  {
512  FC_ASSERT( _app.chain_database(), "database unavailable" );
513  const auto& db = *_app.chain_database();
514 
515  const auto configured_limit = _app.get_options().api_limit_get_account_history_operations;
516  FC_ASSERT( limit <= configured_limit,
517  "limit can not be greater than ${configured_limit}",
518  ("configured_limit", configured_limit) );
519 
520  vector<operation_history_object> result;
521  account_id_type account;
522  try {
523  database_api_helper db_api_helper( _app );
524  account = db_api_helper.get_account_from_string(account_id_or_name)->get_id();
525  } catch(...) { return result; }
526  const auto& stats = account(db).statistics(db);
527  if( stats.most_recent_op == account_history_id_type() ) return result;
528  const account_history_object* node = &stats.most_recent_op(db);
529  if( start == operation_history_id_type() )
530  start = node->operation_id;
531 
532  while(node && node->operation_id.instance.value > stop.instance.value && result.size() < limit)
533  {
534  if( node->operation_id.instance.value <= start.instance.value ) {
535 
536  if(node->operation_id(db).op.which() == operation_type)
537  result.push_back( node->operation_id(db) );
538  }
539  if( node->next == account_history_id_type() )
540  node = nullptr;
541  else node = &node->next(db);
542  }
543  if( stop.instance.value == 0 && result.size() < limit ) {
544  const auto* head = db.find(account_history_id_type());
545  if (head != nullptr && head->account == account && head->operation_id(db).op.which() == operation_type)
546  result.push_back(head->operation_id(db));
547  }
548  return result;
549  }
550 
551 
552  vector<operation_history_object> history_api::get_relative_account_history( const std::string& account_id_or_name,
553  uint64_t stop,
554  uint32_t limit,
555  uint64_t start ) const
556  {
557  FC_ASSERT( _app.chain_database(), "database unavailable" );
558  const auto& db = *_app.chain_database();
559 
560  const auto configured_limit = _app.get_options().api_limit_get_relative_account_history;
561  FC_ASSERT( limit <= configured_limit,
562  "limit can not be greater than ${configured_limit}",
563  ("configured_limit", configured_limit) );
564 
565  vector<operation_history_object> result;
566  account_id_type account;
567  try {
568  database_api_helper db_api_helper( _app );
569  account = db_api_helper.get_account_from_string(account_id_or_name)->get_id();
570  } catch(...) { return result; }
571  const auto& stats = account(db).statistics(db);
572  if( start == 0 )
573  start = stats.total_ops;
574  else
575  start = std::min( stats.total_ops, start );
576 
577  if( start >= stop && start > stats.removed_ops && limit > 0 )
578  {
579  const auto& hist_idx = db.get_index_type<account_history_index>();
580  const auto& by_seq_idx = hist_idx.indices().get<by_seq>();
581 
582  auto itr = by_seq_idx.upper_bound( boost::make_tuple( account, start ) );
583  auto itr_stop = by_seq_idx.lower_bound( boost::make_tuple( account, stop ) );
584 
585  do
586  {
587  --itr;
588  result.push_back( itr->operation_id(db) );
589  }
590  while ( itr != itr_stop && result.size() < limit );
591  }
592  return result;
593  }
594 
595  vector<operation_history_object> history_api::get_block_operation_history(
596  uint32_t block_num,
597  const optional<uint16_t>& trx_in_block ) const
598  {
599  FC_ASSERT( _app.chain_database(), "database unavailable" );
600  const auto& db = *_app.chain_database();
601  const auto& idx = db.get_index_type<operation_history_index>().indices().get<by_block>();
602  auto range = trx_in_block.valid() ? idx.equal_range( boost::make_tuple( block_num, *trx_in_block ) )
603  : idx.equal_range( block_num );
604  vector<operation_history_object> result;
605  std::copy( range.first, range.second, std::back_inserter( result ) );
606  return result;
607  }
608 
609  vector<operation_history_object> history_api::get_block_operations_by_time(
610  const optional<fc::time_point_sec>& start ) const
611  {
612  FC_ASSERT( _app.chain_database(), "database unavailable" );
613  const auto& db = *_app.chain_database();
614  const auto& idx = db.get_index_type<operation_history_index>().indices().get<by_time>();
615  auto itr = start.valid() ? idx.lower_bound( *start ) : idx.begin();
616 
617  vector<operation_history_object> result;
618  if( itr == idx.end() )
619  return result;
620 
621  auto itr_end = idx.upper_bound( itr->block_time );
622 
623  std::copy( itr, itr_end, std::back_inserter( result ) );
624 
625  return result;
626  }
627 
628  flat_set<uint32_t> history_api::get_market_history_buckets()const
629  {
630  auto market_hist_plugin = _app.get_plugin<market_history_plugin>( "market_history" );
631  FC_ASSERT( market_hist_plugin, "Market history plugin is not enabled" );
632  return market_hist_plugin->tracked_buckets();
633  }
634 
636  const std::string& account_id_or_name,
637  const flat_set<uint16_t>& operation_types,
638  uint32_t start, uint32_t limit )const
639  {
640  const auto configured_limit = _app.get_options().api_limit_get_account_history_by_operations;
641  FC_ASSERT( limit <= configured_limit,
642  "limit can not be greater than ${configured_limit}",
643  ("configured_limit", configured_limit) );
644 
646  vector<operation_history_object> objs = get_relative_account_history( account_id_or_name, start, limit,
647  limit + start - 1 );
648  result.total_count = objs.size();
649 
650  if( operation_types.empty() )
651  result.operation_history_objs = std::move(objs);
652  else
653  {
654  for( const operation_history_object &o : objs )
655  {
656  if( operation_types.find(o.op.which()) != operation_types.end() ) {
657  result.operation_history_objs.push_back(o);
658  }
659  }
660  }
661 
662  return result;
663  }
664 
665  vector<bucket_object> history_api::get_market_history( const std::string& asset_a, const std::string& asset_b,
666  uint32_t bucket_seconds,
667  const fc::time_point_sec& start,
668  const fc::time_point_sec& end )const
669  { try {
670 
671  auto market_hist_plugin = _app.get_plugin<market_history_plugin>( "market_history" );
672  FC_ASSERT( market_hist_plugin, "Market history plugin is not enabled" );
673  FC_ASSERT(_app.chain_database());
674 
675  const auto& db = *_app.chain_database();
676  database_api_helper db_api_helper( _app );
677  asset_id_type a = db_api_helper.get_asset_from_string( asset_a )->get_id();
678  asset_id_type b = db_api_helper.get_asset_from_string( asset_b )->get_id();
679  vector<bucket_object> result;
680  const auto configured_limit = _app.get_options().api_limit_get_market_history;
681  result.reserve( configured_limit );
682 
683  if( a > b ) std::swap(a,b);
684 
685  const auto& bidx = db.get_index_type<bucket_index>();
686  const auto& by_key_idx = bidx.indices().get<by_key>();
687 
688  auto itr = by_key_idx.lower_bound( bucket_key( a, b, bucket_seconds, start ) );
689  while( itr != by_key_idx.end() && itr->key.open <= end && result.size() < configured_limit )
690  {
691  if( !(itr->key.base == a && itr->key.quote == b && itr->key.seconds == bucket_seconds) )
692  {
693  return result;
694  }
695  result.push_back(*itr);
696  ++itr;
697  }
698  return result;
699  } FC_CAPTURE_AND_RETHROW( (asset_a)(asset_b)(bucket_seconds)(start)(end) ) }
700 
701  static uint32_t validate_get_lp_history_params( const application& _app, const optional<uint32_t>& olimit )
702  {
703  FC_ASSERT( _app.get_options().has_market_history_plugin, "Market history plugin is not enabled." );
704 
705  const auto configured_limit = _app.get_options().api_limit_get_liquidity_pool_history;
706  uint32_t limit = olimit.valid() ? *olimit : configured_limit;
707  FC_ASSERT( limit <= configured_limit,
708  "limit can not be greater than ${configured_limit}",
709  ("configured_limit", configured_limit) );
710 
711  FC_ASSERT( _app.chain_database(), "Internal error: the chain database is not availalbe" );
712 
713  return limit;
714  }
715 
716  vector<liquidity_pool_history_object> history_api::get_liquidity_pool_history(
717  liquidity_pool_id_type pool_id,
718  const optional<fc::time_point_sec>& start,
719  const optional<fc::time_point_sec>& stop,
720  const optional<uint32_t>& olimit,
721  const optional<int64_t>& operation_type )const
722  { try {
723  uint32_t limit = validate_get_lp_history_params( _app, olimit );
724 
725  vector<liquidity_pool_history_object> result;
726 
727  if( 0 == limit || ( start.valid() && stop.valid() && *start <= *stop ) ) // empty result
728  return result;
729 
730  const auto& db = *_app.chain_database();
731 
732  const auto& hist_idx = db.get_index_type<liquidity_pool_history_index>();
733 
734  if( operation_type.valid() ) // one operation type
735  {
736  const auto& idx = hist_idx.indices().get<by_pool_op_type_time>();
737  auto itr = start.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *operation_type, *start ) )
738  : idx.lower_bound( boost::make_tuple( pool_id, *operation_type ) );
739  auto itr_stop = stop.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *operation_type, *stop ) )
740  : idx.upper_bound( boost::make_tuple( pool_id, *operation_type ) );
741  while( itr != itr_stop && result.size() < limit )
742  {
743  result.push_back( *itr );
744  ++itr;
745  }
746  }
747  else // all operation types
748  {
749  const auto& idx = hist_idx.indices().get<by_pool_time>();
750  auto itr = start.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *start ) )
751  : idx.lower_bound( pool_id );
752  auto itr_stop = stop.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *stop ) )
753  : idx.upper_bound( pool_id );
754  while( itr != itr_stop && result.size() < limit )
755  {
756  result.push_back( *itr );
757  ++itr;
758  }
759  }
760 
761  return result;
762 
763  } FC_CAPTURE_AND_RETHROW( (pool_id)(start)(stop)(olimit)(operation_type) ) }
764 
765  vector<liquidity_pool_history_object> history_api::get_liquidity_pool_history_by_sequence(
766  liquidity_pool_id_type pool_id,
767  const optional<uint64_t>& start,
768  const optional<fc::time_point_sec>& stop,
769  const optional<uint32_t>& olimit,
770  const optional<int64_t>& operation_type )const
771  { try {
772  uint32_t limit = validate_get_lp_history_params( _app, olimit );
773 
774  vector<liquidity_pool_history_object> result;
775 
776  if( 0 == limit ) // empty result
777  return result;
778 
779  const auto& db = *_app.chain_database();
780 
781  const auto& hist_idx = db.get_index_type<liquidity_pool_history_index>();
782 
783  if( operation_type.valid() ) // one operation type
784  {
785  const auto& idx = hist_idx.indices().get<by_pool_op_type_seq>();
786  const auto& idx_t = hist_idx.indices().get<by_pool_op_type_time>();
787  auto itr = start.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *operation_type, *start ) )
788  : idx.lower_bound( boost::make_tuple( pool_id, *operation_type ) );
789  if( itr == idx.end() || itr->pool != pool_id || itr->op_type != *operation_type ) // empty result
790  return result;
791  if( stop.valid() && itr->time <= *stop ) // empty result
792  return result;
793  auto itr_temp = stop.valid() ? idx_t.lower_bound( boost::make_tuple( pool_id, *operation_type, *stop ) )
794  : idx_t.upper_bound( boost::make_tuple( pool_id, *operation_type ) );
795  auto itr_stop = ( itr_temp == idx_t.end() ? idx.end() : idx.iterator_to( *itr_temp ) );
796  while( itr != itr_stop && result.size() < limit )
797  {
798  result.push_back( *itr );
799  ++itr;
800  }
801  }
802  else // all operation types
803  {
804  const auto& idx = hist_idx.indices().get<by_pool_seq>();
805  const auto& idx_t = hist_idx.indices().get<by_pool_time>();
806  auto itr = start.valid() ? idx.lower_bound( boost::make_tuple( pool_id, *start ) )
807  : idx.lower_bound( pool_id );
808  if( itr == idx.end() || itr->pool != pool_id ) // empty result
809  return result;
810  if( stop.valid() && itr->time <= *stop ) // empty result
811  return result;
812  auto itr_temp = stop.valid() ? idx_t.lower_bound( boost::make_tuple( pool_id, *stop ) )
813  : idx_t.upper_bound( pool_id );
814  auto itr_stop = ( itr_temp == idx_t.end() ? idx.end() : idx.iterator_to( *itr_temp ) );
815  while( itr != itr_stop && result.size() < limit )
816  {
817  result.push_back( *itr );
818  ++itr;
819  }
820  }
821 
822  return result;
823 
824  } FC_CAPTURE_AND_RETHROW( (pool_id)(start)(stop)(olimit)(operation_type) ) }
825 
826 
828  {
829  return fc::ecc::blind( blind, value );
830  }
831 
832  fc::ecc::blind_factor_type crypto_api::blind_sum( const std::vector<blind_factor_type>& blinds_in,
833  uint32_t non_neg ) const
834  {
835  return fc::ecc::blind_sum( blinds_in, non_neg );
836  }
837 
838  bool crypto_api::verify_sum( const std::vector<commitment_type>& commits_in,
839  const std::vector<commitment_type>& neg_commits_in,
840  int64_t excess ) const
841  {
842  return fc::ecc::verify_sum( commits_in, neg_commits_in, excess );
843  }
844 
846  const std::vector<char>& proof ) const
847  {
848  verify_range_result result;
849  result.success = fc::ecc::verify_range( result.min_val, result.max_val, commit, proof );
850  return result;
851  }
852 
853  std::vector<char> crypto_api::range_proof_sign( uint64_t min_value,
854  const commitment_type& commit,
855  const blind_factor_type& commit_blind,
856  const blind_factor_type& nonce,
857  int8_t base10_exp,
858  uint8_t min_bits,
859  uint64_t actual_value ) const
860  {
861  return fc::ecc::range_proof_sign( min_value, commit, commit_blind, nonce, base10_exp, min_bits, actual_value );
862  }
863 
865  const blind_factor_type& nonce,
866  const commitment_type& commit,
867  const std::vector<char>& proof ) const
868  {
871  result.value_out,
872  result.message_out,
873  nonce,
874  result.min_val,
875  result.max_val,
876  const_cast< commitment_type& >( commit ),
877  proof );
878  return result;
879  }
880 
881  fc::ecc::range_proof_info crypto_api::range_get_info( const std::vector<char>& proof ) const
882  {
883  return fc::ecc::range_get_info( proof );
884  }
885 
886  // asset_api
888  : _app(app),
889  _db( *app.chain_database() )
890  { // Nothing else to do
891  }
892 
893  vector<asset_api::account_asset_balance> asset_api::get_asset_holders( const std::string& asset_symbol_or_id,
894  uint32_t start, uint32_t limit ) const
895  {
896  const auto configured_limit = _app.get_options().api_limit_get_asset_holders;
897  FC_ASSERT( limit <= configured_limit,
898  "limit can not be greater than ${configured_limit}",
899  ("configured_limit", configured_limit) );
900 
901  database_api_helper db_api_helper( _app );
902  asset_id_type asset_id = db_api_helper.get_asset_from_string( asset_symbol_or_id )->get_id();
903  const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >();
904  auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) );
905 
906  vector<account_asset_balance> result;
907 
908  uint32_t index = 0;
909  for( const account_balance_object& bal : boost::make_iterator_range( range.first, range.second ) )
910  {
911  if( result.size() >= limit )
912  break;
913 
914  if( bal.balance.value == 0 )
915  continue;
916 
917  if( index++ < start )
918  continue;
919 
920  const auto account = _db.find(bal.owner);
921 
923  aab.name = account->name;
924  aab.account_id = account->id;
925  aab.amount = bal.balance.value;
926 
927  result.push_back(aab);
928  }
929 
930  return result;
931  }
932  // get number of asset holders.
933  int64_t asset_api::get_asset_holders_count( const std::string& asset_symbol_or_id ) const {
934  const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >();
935  database_api_helper db_api_helper( _app );
936  asset_id_type asset_id = db_api_helper.get_asset_from_string( asset_symbol_or_id )->get_id();
937  auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) );
938 
939  int64_t count = boost::distance(range) - 1;
940 
941  return count;
942  }
943  // function to get vector of system assets with holders count.
944  vector<asset_api::asset_holders> asset_api::get_all_asset_holders() const {
945  vector<asset_holders> result;
946  vector<asset_id_type> total_assets;
947  for( const asset_object& asset_obj : _db.get_index_type<asset_index>().indices() )
948  {
949  const auto& dasset_obj = asset_obj.dynamic_asset_data_id(_db);
950 
951  asset_id_type asset_id;
952  asset_id = dasset_obj.id;
953 
954  const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >();
955  auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) );
956 
957  int64_t count = boost::distance(range) - 1;
958 
959  asset_holders ah;
960  ah.asset_id = asset_id;
961  ah.count = count;
962 
963  result.push_back(ah);
964  }
965 
966  return result;
967  }
968 
969  // orders_api
971  : _app(app)
972  { // Nothing else to do
973  }
974 
975  flat_set<uint16_t> orders_api::get_tracked_groups()const
976  {
977  auto plugin = _app.get_plugin<grouped_orders_plugin>( "grouped_orders" );
978  FC_ASSERT( plugin );
979  return plugin->tracked_groups();
980  }
981 
982  vector< orders_api::limit_order_group > orders_api::get_grouped_limit_orders( const std::string& base_asset,
983  const std::string& quote_asset,
984  uint16_t group,
985  const optional<price>& start,
986  uint32_t limit )const
987  {
988  const auto configured_limit = _app.get_options().api_limit_get_grouped_limit_orders;
989  FC_ASSERT( limit <= configured_limit,
990  "limit can not be greater than ${configured_limit}",
991  ("configured_limit", configured_limit) );
992 
993  auto plugin = _app.get_plugin<graphene::grouped_orders::grouped_orders_plugin>( "grouped_orders" );
994  FC_ASSERT( plugin );
995  const auto& limit_groups = plugin->limit_order_groups();
996  vector< limit_order_group > result;
997 
998  database_api_helper db_api_helper( _app );
999  asset_id_type base_asset_id = db_api_helper.get_asset_from_string( base_asset )->get_id();
1000  asset_id_type quote_asset_id = db_api_helper.get_asset_from_string( quote_asset )->get_id();
1001 
1002  price max_price = price::max( base_asset_id, quote_asset_id );
1003  price min_price = price::min( base_asset_id, quote_asset_id );
1004  if( start.valid() && !start->is_null() )
1005  max_price = std::max( std::min( max_price, *start ), min_price );
1006 
1007  auto itr = limit_groups.lower_bound( limit_order_group_key( group, max_price ) );
1008  // use an end iterator to try to avoid expensive price comparison
1009  auto end = limit_groups.upper_bound( limit_order_group_key( group, min_price ) );
1010  while( itr != end && result.size() < limit )
1011  {
1012  result.emplace_back( *itr );
1013  ++itr;
1014  }
1015  return result;
1016  }
1017 
1018  // custom operations api
1020  : _app(app)
1021  { // Nothing else to do
1022  }
1023 
1024  vector<account_storage_object> custom_operations_api::get_storage_info(
1025  const optional<std::string>& o_account_name_or_id,
1026  const optional<std::string>& catalog,
1027  const optional<std::string>& key,
1028  const optional<uint32_t>& limit,
1029  const optional<account_storage_id_type>& start_id )const
1030  {
1032  FC_ASSERT( plugin, "The custom_operations plugin is not enabled" );
1033 
1034  database_api_helper db_api_helper( _app );
1035  const auto& storage_index = _app.chain_database()->get_index_type<account_storage_index>().indices();
1036 
1037  if( o_account_name_or_id.valid() )
1038  {
1039  const string& account_name_or_id = *o_account_name_or_id;
1040  const account_id_type account_id = db_api_helper.get_account_from_string(account_name_or_id)->get_id();
1041  if( catalog.valid() )
1042  {
1043  if( key.valid() )
1044  return db_api_helper.get_objects_by_x< account_storage_object,
1047  storage_index.get<by_account_catalog_key>(),
1048  limit, start_id, account_id, *catalog, *key );
1049  else
1050  return db_api_helper.get_objects_by_x< account_storage_object,
1053  storage_index.get<by_account_catalog>(),
1054  limit, start_id, account_id, *catalog );
1055  }
1056  else
1057  {
1058  FC_ASSERT( !key.valid(), "Can not specify key if catalog is not specified" );
1059  return db_api_helper.get_objects_by_x< account_storage_object,
1062  storage_index.get<custom_operations::by_account>(),
1063  limit, start_id, account_id );
1064  }
1065  }
1066  else if( catalog.valid() )
1067  {
1068  if( key.valid() )
1069  return db_api_helper.get_objects_by_x< account_storage_object,
1072  storage_index.get<by_catalog_key>(),
1073  limit, start_id, *catalog, *key );
1074  else
1075  return db_api_helper.get_objects_by_x< account_storage_object,
1078  storage_index.get<by_catalog>(),
1079  limit, start_id, *catalog );
1080  }
1081  else
1082  {
1083  FC_ASSERT( !key.valid(), "Can not specify key if catalog is not specified" );
1084  return db_api_helper.get_objects_by_x< account_storage_object,
1087  storage_index.get<by_id>(),
1088  limit, start_id );
1089  }
1090 
1091  }
1092 
1093 } } // graphene::app
fc::api< asset_api > asset()
Retrieve the asset API set.
Definition: api.cpp:312
const application_options & get_options() const
fc::optional< api_access_info > get_api_access_info(const string &username) const
bool verify_sum(const std::vector< commitment_type > &commits_in, const std::vector< commitment_type > &neg_commits_in, int64_t excess) const
Verifies that commits + neg_commits + excess == 0.
Definition: api.cpp:838
Tracks the balance of a single account/asset pairThis object is indexed on owner and asset_type so th...
std::shared_ptr< fc::thread > elasticsearch_thread
fc::variant broadcast_transaction_synchronous(const precomputable_transaction &trx)
Definition: api.cpp:173
auto async(Functor &&f, const char *desc FC_TASK_NAME_DEFAULT_ARG, priority prio=priority()) -> fc::future< decltype(f())>
Definition: thread.hpp:227
vector< operation_history_object > get_account_history(const std::string &account_name_or_id, operation_history_id_type stop=operation_history_id_type(), uint32_t limit=application_options::get_default().api_limit_get_account_history, operation_history_id_type start=operation_history_id_type()) const
Get the history of operations related to the specified account.
Definition: api.cpp:406
static ptr create(const char *desc FC_TASK_NAME_DEFAULT_ARG)
Definition: future.hpp:114
a placeholder for the result of an asynchronous operation.
Definition: future.hpp:211
fc::api< network_broadcast_api > network_broadcast()
Retrieve the network broadcast API set.
Definition: api.cpp:245
virtual void open(const fc::path &db)=0
void broadcast_transaction_with_callback(confirmation_callback cb, const precomputable_transaction &trx)
Definition: api.cpp:191
std::shared_ptr< chain::database > chain_database() const
bool verify_range(uint64_t &min_val, uint64_t &max_val, const commitment_type &commit, const range_proof_type &proof)
void on_applied_block(const signed_block &b)
Not reflected, thus not accessible to API clients.
Definition: api.cpp:140
static constexpr size_t data_size()
Definition: sha256.hpp:21
bool is_plugin_enabled(const string &name) const
T wait(boost::signals2::signal< void(T)> &sig, const microseconds &timeout_us=microseconds::maximum())
Definition: signals.hpp:38
const index_type & indices() const
bool verify_sum(const std::vector< commitment_type > &commits, const std::vector< commitment_type > &neg_commits, int64_t excess)
#define GRAPHENE_MAX_NESTED_OBJECTS
Definition: config.hpp:33
tracks the history of all logical operations on blockchain stateAll operations and virtual operations...
fc::api< block_api > block()
Retrieve the network block API set.
Definition: api.cpp:256
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
An order-perserving dictionary of variant&#39;s.
const IndexType & get_index_type() const
price min() const
Definition: asset.hpp:125
Definition: api.cpp:48
range_proof_info range_get_info(const range_proof_type &proof)
fc::sha256 blind_factor_type
Definition: elliptic.hpp:21
void set_advanced_node_parameters(const fc::variant_object &params)
Set advanced node parameters, such as desired and max number of connections.
Definition: api.cpp:239
std::vector< char > range_proof_sign(uint64_t min_value, const commitment_type &commit, const blind_factor_type &commit_blind, const blind_factor_type &nonce, int8_t base10_exp, uint8_t min_bits, uint64_t actual_value) const
Proves with respect to min_value the range for pedersen commitment which has the provided blinding fa...
Definition: api.cpp:853
vector< operation_history_object > get_account_history_by_time(const std::string &account_name_or_id, const optional< uint32_t > &limit=optional< uint32_t >(), const optional< fc::time_point_sec > &start=optional< fc::time_point_sec >()) const
Get the history of operations related to the specified account no later than the specified time...
Definition: api.cpp:464
vector< order_history_object > get_fill_order_history(const std::string &a, const std::string &b, uint32_t limit) const
Get details of order executions occurred most recently in a trading pair.
Definition: api.cpp:376
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
fc::api< network_node_api > network_node()
Retrieve the network node API set.
Definition: api.cpp:267
flat_set< uint16_t > get_tracked_groups() const
Get tracked groups configured by the server.
Definition: api.cpp:975
history_operation_detail get_account_history_by_operations(const std::string &account_name_or_id, const flat_set< uint16_t > &operation_types, uint32_t start, uint32_t limit) const
Get the history of operations related to the specified account filtering by operation types...
Definition: api.cpp:635
account_history_id_type next
the operation position within the given account
char * data() const
Definition: sha256.cpp:29
fc::api< dummy_api > dummy()
Retrieve a dummy API set, not reflected.
Definition: api.cpp:362
network_node_api(application &a)
Definition: api.cpp:200
std::shared_ptr< abstract_plugin > get_plugin(const string &name) const
vector< liquidity_pool_history_object > get_liquidity_pool_history(liquidity_pool_id_type pool_id, const optional< fc::time_point_sec > &start=optional< fc::time_point_sec >(), const optional< fc::time_point_sec > &stop=optional< fc::time_point_sec >(), const optional< uint32_t > &limit=optional< uint32_t >(), const optional< int64_t > &operation_type=optional< int64_t >()) const
Get history of a liquidity pool.
Definition: api.cpp:716
static sha256 hash(const char *d, uint32_t dlen)
Definition: sha256.cpp:41
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
price max() const
Definition: asset.hpp:124
void broadcast_transaction(const precomputable_transaction &trx)
Broadcast a transaction to the network.
Definition: api.cpp:165
operation_history_id_type operation_id
the account this operation applies to
const asset_object * get_asset_from_string(const std::string &symbol_or_id, bool throw_if_not_found=true) const
vector< account_storage_object > get_storage_info(const optional< std::string > &account_name_or_id=optional< std::string >(), const optional< std::string > &catalog=optional< std::string >(), const optional< std::string > &key=optional< std::string >(), const optional< uint32_t > &limit=optional< uint32_t >(), const optional< account_storage_id_type > &start_id=optional< account_storage_id_type >()) const
Get stored objects.
Definition: api.cpp:1024
fc::ecc::commitment_type blind(const fc::ecc::blind_factor_type &blind, uint64_t value) const
Generates a pedersen commitment: *commit = blind * G + value * G2. The commitment is 33 bytes...
Definition: api.cpp:827
std::vector< net::potential_peer_record > get_potential_peers() const
Return list of potential peers.
Definition: api.cpp:226
uint32_t block_num() const
Definition: block.hpp:34
commitment_type blind(const blind_factor_type &blind, uint64_t value)
string get_info() const
Retrive the node info string configured by the node operator.
Definition: api.cpp:98
asset_api(graphene::app::application &app)
Definition: api.cpp:887
static time_point_sec maximum()
Definition: time.hpp:86
verify_range_proof_rewind_result verify_range_proof_rewind(const blind_factor_type &nonce, const fc::ecc::commitment_type &commit, const std::vector< char > &proof) const
Verifies range proof rewind for 33-byte pedersen commitment.
Definition: api.cpp:864
object_id< SpaceID, TypeID > get_id() const
Definition: object.hpp:113
const T * find(const object_id_type &id) const
fc::variant_object get_advanced_node_parameters() const
Get advanced node parameters, such as desired and max number of connections.
Definition: api.cpp:233
void add_node(const fc::ip::endpoint &ep)
add_node Connect to a new peer
Definition: api.cpp:213
application_options get_config() const
Retrieve configured application options.
Definition: api.cpp:103
bool valid() const
Definition: optional.hpp:186
const object & get(object_id_type id) const
Definition: index.hpp:110
fc::api< database_api > database()
Retrieve the database API set.
Definition: api.cpp:278
a node in a linked list of operation_history_objectsAccount history is important for users and wallet...
vector< OBJ_TYPE > get_objects_by_x(T application_options::*app_opt_member_ptr, const INDEX_TYPE &idx, const optional< uint32_t > &olimit, const optional< OBJ_ID_TYPE > &ostart_id, X... x) const
void set_value(const T &v)
Definition: future.hpp:136
zero_initialized_array< unsigned char, 33 > commitment_type
Definition: elliptic.hpp:22
void broadcast_block(const signed_block &block)
Broadcast a signed block to the network.
Definition: api.cpp:183
std::function< void(variant)> confirmation_callback
Definition: api.hpp:343
history_api(application &app)
Definition: api.cpp:371
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
int64_t get_asset_holders_count(const std::string &asset_symbol_or_id) const
Get asset holders count for a specific asset.
Definition: api.cpp:933
fc::api< graphene::debug_witness::debug_api > debug()
Retrieve the debug API set.
Definition: api.cpp:334
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object&#39;s.
Definition: variant.hpp:198
vector< asset_holders > get_all_asset_holders() const
Get all asset holders.
Definition: api.cpp:944
fc::api< history_api > history()
Retrieve the history API set.
Definition: api.cpp:290
block_api(const graphene::chain::database &db)
Definition: api.cpp:122
const account_object * get_account_from_string(const std::string &name_or_id, bool throw_if_not_found=true) const
fc::variant_object get_info() const
Return general network information, such as p2p port.
Definition: api.cpp:205
variant login(const optional< string > &user, const optional< string > &password)
Authenticate to the RPC server, or retrieve the API set ID of the login API set.
Definition: api.cpp:56
custom_operations_api(application &app)
Definition: api.cpp:1019
bool verify_range_proof_rewind(blind_factor_type &blind_out, uint64_t &value_out, string &message_out, const blind_factor_type &nonce, uint64_t &min_val, uint64_t &max_val, commitment_type commit, const range_proof_type &proof)
vector< operation_history_object > get_account_history_operations(const std::string &account_name_or_id, int64_t operation_type, operation_history_id_type start=operation_history_id_type(), operation_history_id_type stop=operation_history_id_type(), uint32_t limit=application_options::get_default().api_limit_get_account_history_operations) const
Get the history of operations related to the specified account filtering by operation type...
Definition: api.cpp:505
fc::ecc::range_proof_info range_get_info(const std::vector< char > &proof) const
Gets "range proof" info. The cli_wallet includes functionality for sending blind transfers in which t...
Definition: api.cpp:881
flat_set< uint32_t > get_market_history_buckets() const
Get OHLCV time bucket lengths supported (configured) by this API server.
Definition: api.cpp:628
flat_set< string > get_available_api_sets() const
Retrieve a list of API sets that the user has access to.
Definition: api.cpp:110
tracks the parameters of an assetAll assets have a globally unique symbol name that controls how they...
range_proof_type range_proof_sign(uint64_t min_value, const commitment_type &commit, const blind_factor_type &commit_blind, const blind_factor_type &nonce, int8_t base10_exp, uint8_t min_bits, uint64_t actual_value)
vector< operation_history_object > get_block_operation_history(uint32_t block_num, const optional< uint16_t > &trx_in_block={}) const
Get all operations within a block or a transaction, including virtual operations. ...
Definition: api.cpp:595
blind_factor_type blind_sum(const std::vector< blind_factor_type > &blinds, uint32_t non_neg)
fc::api< crypto_api > crypto()
Retrieve the cryptography API set.
Definition: api.cpp:301
vector< bucket_object > get_market_history(const std::string &a, const std::string &b, uint32_t bucket_seconds, const fc::time_point_sec &start, const fc::time_point_sec &end) const
Get OHLCV data of a trading pair in a time range.
Definition: api.cpp:665
vector< account_asset_balance > get_asset_holders(const std::string &asset_symbol_or_id, uint32_t start, uint32_t limit) const
Get asset holders for a specific asset.
Definition: api.cpp:893
vector< operation_history_object > get_block_operations_by_time(const optional< fc::time_point_sec > &start=optional< fc::time_point_sec >()) const
Get all operations, including virtual operations, within the most recent block (no later than the spe...
Definition: api.cpp:609
std::vector< net::peer_status > get_connected_peers() const
Get status of all current connections to peers.
Definition: api.cpp:219
vector< operation_history_object > operation_history_objs
Definition: api.hpp:77
orders_api(application &app)
Definition: api.cpp:970
verify_range_result verify_range(const fc::ecc::commitment_type &commit, const std::vector< char > &proof) const
Verifies range proof for 33-byte pedersen commitment.
Definition: api.cpp:845
bool is_database_api_allowed() const
Check whether database_api is allowed, not reflected.
Definition: api.cpp:115
std::string base64_decode(const std::string &encoded_string)
Definition: base64.cpp:96
vector< operation_history_object > get_relative_account_history(const std::string &account_name_or_id, uint64_t stop=0, uint32_t limit=application_options::get_default().api_limit_get_relative_account_history, uint64_t start=0) const
Get the history of operations related to the specified account referenced by an event numbering speci...
Definition: api.cpp:552
abstract base class for accessing objects indexed in various ways.
Definition: index.hpp:70
fc::ecc::blind_factor_type blind_sum(const std::vector< blind_factor_type > &blinds_in, uint32_t non_neg) const
Get sha-256 blind factor type.
Definition: api.cpp:832
void copy(const path &from, const path &to)
Definition: filesystem.cpp:241
fc::api< orders_api > orders()
Retrieve the orders API set.
Definition: api.cpp:323
const string & get_node_info() const
fc::api< custom_operations_api > custom_operations()
Retrieve the custom operations API set.
Definition: api.cpp:348
vector< limit_order_group > get_grouped_limit_orders(const std::string &base_asset, const std::string &quote_asset, uint16_t group, const optional< price > &start, uint32_t limit) const
Get grouped limit orders in given market.
Definition: api.cpp:982
vector< processed_transaction > transactions
Definition: block.hpp:68
object_id< account_storage_object::space_id, account_storage_object::type_id > account_storage_id_type
vector< liquidity_pool_history_object > get_liquidity_pool_history_by_sequence(liquidity_pool_id_type pool_id, const optional< uint64_t > &start=optional< uint64_t >(), const optional< fc::time_point_sec > &stop=optional< fc::time_point_sec >(), const optional< uint32_t > &limit=optional< uint32_t >(), const optional< int64_t > &operation_type=optional< int64_t >()) const
Get history of a liquidity pool.
Definition: api.cpp:765
std::shared_ptr< promise< T > > ptr
Definition: future.hpp:111
optional< signed_block > fetch_block_by_number(uint32_t num) const
Definition: db_block.cpp:76
vector< optional< signed_block > > get_blocks(uint32_t block_num_from, uint32_t block_num_to) const
Get signed blocks.
Definition: api.cpp:124
bool logout()
Log out.
Definition: api.cpp:89
An order-perserving dictionary of variant&#39;s.
T value
Definition: safe.hpp:22
Definition: api.hpp:120
network_broadcast_api(application &a)
Definition: api.cpp:134