58 if( !o_user && !o_password )
66 if( acc->password_hash_b64 !=
"*" )
83 _allowed_apis = acc->allowed_apis;
92 _allowed_apis.clear();
103 bool is_allowed = !_allowed_apis.empty();
104 FC_ASSERT( is_allowed,
"Access denied, please login" );
110 return _allowed_apis;
115 bool is_allowed = ( _allowed_apis.find(
"database_api") != _allowed_apis.end() );
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++) {
134 _applied_block_connection = _app.
chain_database()->applied_block.connect(
140 if( _callbacks.size() )
143 auto capture_this = shared_from_this();
144 for( uint32_t trx_num = 0; trx_num < b.
transactions.size(); ++trx_num )
148 auto itr = _callbacks.find(
id);
149 if( itr != _callbacks.end() )
152 auto& callback = _callbacks.find(
id)->second;
165 FC_ASSERT( _app.
p2p_node() !=
nullptr,
"Not connected to P2P network, can't broadcast!" );
168 _app.
p2p_node()->broadcast_transaction(trx);
183 FC_ASSERT( _app.
p2p_node() !=
nullptr,
"Not connected to P2P network, can't broadcast!" );
191 FC_ASSERT( _app.
p2p_node() !=
nullptr,
"Not connected to P2P network, can't broadcast!" );
193 _callbacks[trx.id()] = cb;
195 _app.
p2p_node()->broadcast_transaction(trx);
207 result[
"connection_count"] = _app.
p2p_node()->get_connection_count();
220 return _app.
p2p_node()->get_connected_peers();
227 return _app.
p2p_node()->get_potential_peers();
234 return _app.
p2p_node()->get_advanced_node_parameters();
240 return _app.
p2p_node()->set_advanced_node_parameters(params);
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 )
249 _network_broadcast_api = std::make_shared< network_broadcast_api >( std::ref( _app ) );
251 return *_network_broadcast_api;
256 bool is_allowed = ( _allowed_apis.find(
"block_api") != _allowed_apis.end() );
257 FC_ASSERT( is_allowed,
"Access denied" );
260 _block_api = std::make_shared< block_api >( std::ref( *_app.
chain_database() ) );
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 )
271 _network_node_api = std::make_shared< network_node_api >( std::ref(_app) );
273 return *_network_node_api;
278 bool is_allowed = ( _allowed_apis.find(
"database_api") != _allowed_apis.end() );
279 FC_ASSERT( is_allowed,
"Access denied" );
282 _database_api = std::make_shared< database_api >( std::ref( *_app.
chain_database() ),
285 return *_database_api;
290 bool is_allowed = ( _allowed_apis.find(
"history_api") != _allowed_apis.end() );
291 FC_ASSERT( is_allowed,
"Access denied" );
294 _history_api = std::make_shared< history_api >( _app );
296 return *_history_api;
301 bool is_allowed = ( _allowed_apis.find(
"crypto_api") != _allowed_apis.end() );
302 FC_ASSERT( is_allowed,
"Access denied" );
305 _crypto_api = std::make_shared< crypto_api >();
312 bool is_allowed = ( _allowed_apis.find(
"asset_api") != _allowed_apis.end() );
313 FC_ASSERT( is_allowed,
"Access denied" );
316 _asset_api = std::make_shared< asset_api >( _app );
323 bool is_allowed = ( _allowed_apis.find(
"orders_api") != _allowed_apis.end() );
324 FC_ASSERT( is_allowed,
"Access denied" );
327 _orders_api = std::make_shared< orders_api >( std::ref( _app ) );
334 bool is_allowed = ( _allowed_apis.find(
"debug_api") != _allowed_apis.end() );
335 FC_ASSERT( is_allowed,
"Access denied" );
337 bool plugin_enabled = !!_app.
get_plugin(
"debug_witness" );
338 FC_ASSERT( plugin_enabled,
"The debug_witness plugin is not enabled" );
341 _debug_api = std::make_shared< graphene::debug_witness::debug_api >( std::ref(_app) );
348 bool is_allowed = ( _allowed_apis.find(
"custom_operations_api") != _allowed_apis.end() );
349 FC_ASSERT( is_allowed,
"Access denied" );
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 )
355 _custom_operations_api = std::make_shared< custom_operations_api >( std::ref( _app ) );
357 return *_custom_operations_api;
364 _dummy_api = std::make_shared< dummy_api >();
375 const std::string& asset_b,
376 uint32_t limit )
const
379 FC_ASSERT( market_hist_plugin,
"Market history plugin is not enabled" );
385 if( a > b ) std::swap(a,b);
390 hkey.sequence = std::numeric_limits<int64_t>::min();
392 auto itr = history_idx.lower_bound( hkey );
393 vector<order_history_object> result;
394 while( itr != history_idx.end() && result.size() < limit )
396 if( itr->key.base != a || itr->key.quote != b )
break;
397 result.push_back( *itr );
405 operation_history_id_type stop,
407 operation_history_id_type start )
const
414 "limit can not be greater than ${configured_limit}",
415 (
"configured_limit", configured_limit) );
417 vector<operation_history_object> result;
418 if( start == operation_history_id_type() )
420 start = operation_history_id_type::max();
424 account_id_type account;
428 }
catch(...) {
return result; }
437 return es->get_account_history(account, stop, limit, start);
438 },
"thread invoke for method " BOOST_PP_STRINGIZE(method_name)).
wait();
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 ) );
446 while( itr != itr_end && result.size() < limit )
448 result.emplace_back( itr->operation_id(db) );
452 if( 0 == stop.instance.value && result.size() < limit && itr != by_op_idx.end() )
454 const auto& obj = *itr;
455 if( obj.account == account )
456 result.emplace_back( obj.operation_id(db) );
463 const std::string& account_name_or_id,
464 const optional<uint32_t>& olimit,
465 const optional<fc::time_point_sec>& ostart )
const
471 uint32_t limit = olimit.valid() ? *olimit : configured_limit;
473 "limit can not be greater than ${configured_limit}",
474 (
"configured_limit", configured_limit) );
476 vector<operation_history_object> result;
477 account_id_type account;
486 auto op_hist_itr = op_hist_idx.lower_bound( start );
487 if( op_hist_itr == op_hist_idx.end() )
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 );
494 while( itr != itr_end && result.size() < limit )
496 result.emplace_back( itr->operation_id(db) );
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
515 "limit can not be greater than ${configured_limit}",
516 (
"configured_limit", configured_limit) );
518 vector<operation_history_object> result;
519 account_id_type account;
523 }
catch(...) {
return result; }
524 const auto& stats = account(db).statistics(db);
525 if( stats.most_recent_op == account_history_id_type() )
return result;
527 if( start == operation_history_id_type() )
530 while(node && node->
operation_id.instance.value > stop.instance.value && result.size() < limit)
532 if( node->
operation_id.instance.value <= start.instance.value ) {
537 if( node->
next == account_history_id_type() )
539 else node = &node->
next(db);
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));
553 uint64_t start )
const
560 "limit can not be greater than ${configured_limit}",
561 (
"configured_limit", configured_limit) );
563 vector<operation_history_object> result;
564 account_id_type account;
568 }
catch(...) {
return result; }
569 const auto& stats = account(db).statistics(db);
571 start = stats.total_ops;
573 start = std::min( stats.total_ops, start );
575 if( start >= stop && start > stats.removed_ops && limit > 0 )
578 const auto& by_seq_idx = hist_idx.
indices().get<by_seq>();
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 ) );
586 result.push_back( itr->operation_id(db) );
588 while ( itr != itr_stop && result.size() < limit );
595 const optional<uint16_t>& trx_in_block )
const
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 ) );
608 const optional<fc::time_point_sec>& start )
const
613 auto itr = start.valid() ? idx.lower_bound( *start ) : idx.begin();
615 vector<operation_history_object> result;
616 if( itr == idx.end() )
619 auto itr_end = idx.upper_bound( itr->block_time );
621 std::copy( itr, itr_end, std::back_inserter( result ) );
629 FC_ASSERT( market_hist_plugin,
"Market history plugin is not enabled" );
630 return market_hist_plugin->tracked_buckets();
634 const std::string& account_id_or_name,
635 const flat_set<uint16_t>& operation_types,
636 uint32_t start, uint32_t limit )
const
640 "limit can not be greater than ${configured_limit}",
641 (
"configured_limit", configured_limit) );
648 if( operation_types.empty() )
654 if( operation_types.find(o.op.which()) != operation_types.end() ) {
664 uint32_t bucket_seconds,
670 FC_ASSERT( market_hist_plugin,
"Market history plugin is not enabled" );
677 vector<bucket_object> result;
679 result.reserve( configured_limit );
681 if( a > b ) std::swap(a,b);
684 const auto& by_key_idx = bidx.
indices().get<by_key>();
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 )
689 if( !(itr->key.base == a && itr->key.quote == b && itr->key.seconds == bucket_seconds) )
693 result.push_back(*itr);
704 uint32_t limit = olimit.
valid() ? *olimit : configured_limit;
706 "limit can not be greater than ${configured_limit}",
707 (
"configured_limit", configured_limit) );
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
721 uint32_t limit = validate_get_lp_history_params( _app, olimit );
723 vector<liquidity_pool_history_object> result;
725 if( 0 == limit || ( start.valid() && stop.valid() && *start <= *stop ) )
732 if( operation_type.valid() )
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 )
741 result.push_back( *itr );
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 )
754 result.push_back( *itr );
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
770 uint32_t limit = validate_get_lp_history_params( _app, olimit );
772 vector<liquidity_pool_history_object> result;
781 if( operation_type.valid() )
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 )
789 if( stop.valid() && itr->time <= *stop )
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 )
796 result.push_back( *itr );
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 )
808 if( stop.valid() && itr->time <= *stop )
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 )
815 result.push_back( *itr );
831 uint32_t non_neg )
const
837 const std::vector<commitment_type>& neg_commits_in,
838 int64_t excess )
const
844 const std::vector<char>& proof )
const
857 uint64_t actual_value )
const
865 const std::vector<char>& proof )
const
887 _db( *app.chain_database() )
892 uint32_t start, uint32_t limit )
const
896 "limit can not be greater than ${configured_limit}",
897 (
"configured_limit", configured_limit) );
902 auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) );
904 vector<account_asset_balance> result;
909 if( result.size() >= limit )
912 if( bal.balance.value == 0 )
915 if(
index++ < start )
918 const auto account = _db.
find(bal.owner);
921 aab.
name = account->name;
925 result.push_back(aab);
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 ) );
937 int64_t count = boost::distance(range) - 1;
943 vector<asset_holders> result;
944 vector<asset_id_type> total_assets;
947 const auto& dasset_obj = asset_obj.dynamic_asset_data_id(_db);
949 asset_id_type asset_id;
950 asset_id = dasset_obj.id;
953 auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) );
955 int64_t count = boost::distance(range) - 1;
961 result.push_back(ah);
977 return plugin->tracked_groups();
981 const std::string& quote_asset,
983 const optional<price>& start,
984 uint32_t limit )
const
988 "limit can not be greater than ${configured_limit}",
989 (
"configured_limit", configured_limit) );
993 const auto& limit_groups =
plugin->limit_order_groups();
994 vector< limit_order_group > result;
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 );
1008 while( itr != end && result.size() < limit )
1010 result.emplace_back( *itr );
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
1035 if( o_account_name_or_id.valid() )
1037 const string& account_name_or_id = *o_account_name_or_id;
1039 if( catalog.valid() )
1045 storage_index.get<by_account_catalog_key>(),
1046 limit, start_id, account_id, *catalog, *key );
1051 storage_index.get<by_account_catalog>(),
1052 limit, start_id, account_id, *catalog );
1056 FC_ASSERT( !key.valid(),
"Can not specify key if catalog is not specified" );
1060 storage_index.get<custom_operations::by_account>(),
1061 limit, start_id, account_id );
1064 else if( catalog.valid() )
1070 storage_index.get<by_catalog_key>(),
1071 limit, start_id, *catalog, *key );
1076 storage_index.get<by_catalog>(),
1077 limit, start_id, *catalog );
1081 FC_ASSERT( !key.valid(),
"Can not specify key if catalog is not specified" );
1085 storage_index.get<by_id>(),