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