From 7c3904bfae62f227fdaea2614cca9ed3ae9a8a9b Mon Sep 17 00:00:00 2001 From: root Date: Wed, 31 May 2017 20:45:25 +0000 Subject: [PATCH 01/20] adding get_operation_history_id --- libraries/app/database_api.cpp | 19 +++++++++++++++++++ .../app/include/graphene/app/database_api.hpp | 7 +++++++ 2 files changed, 26 insertions(+) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 32217826..7f280323 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -68,6 +68,7 @@ class database_api_impl : public std::enable_shared_from_this map> get_block_header_batch(const vector block_nums)const; optional get_block(uint32_t block_num)const; processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const; + operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; // Globals chain_property_object get_chain_properties()const; @@ -410,6 +411,24 @@ processed_transaction database_api_impl::get_transaction(uint32_t block_num, uin return opt_block->transactions[trx_num]; } +operation_history_id_type database_api::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const +{ + return my->get_operation_history_id( block_num, trx_in_block, op_in_trx ); +} + +operation_history_id_type database_api_impl::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const +{ + const simple_index& op_index = _db.get_index_type>(); + + for( const operation_history_object& op : op_index ) + { + if(op.block_num == block_num and op.trx_in_block == trx_in_block and op.op_in_trx == op_in_trx) { + return op.id; + } + } +} + + ////////////////////////////////////////////////////////////////////// // // // Globals // diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 1fe64a09..94296b86 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -185,6 +185,12 @@ class database_api */ optional get_recent_transaction_by_id( const transaction_id_type& id )const; + /** + * Given a block, transaction in block position and operation position in transaction, get the operation_history_id + */ + operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; + + ///////////// // Globals // ///////////// @@ -600,6 +606,7 @@ FC_API(graphene::app::database_api, (get_block) (get_transaction) (get_recent_transaction_by_id) + (get_operation_history_id) // Globals (get_chain_properties) From 615321cc18d8c1e2d88ca5723da68ba4a6b93bf7 Mon Sep 17 00:00:00 2001 From: root Date: Wed, 31 May 2017 23:11:29 +0000 Subject: [PATCH 02/20] added get_account_transaction_history_id and some fixes --- libraries/app/database_api.cpp | 20 +++++++++++++++++++ .../app/include/graphene/app/database_api.hpp | 5 +++++ 2 files changed, 25 insertions(+) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 7f280323..cd941b5c 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -69,6 +69,7 @@ class database_api_impl : public std::enable_shared_from_this optional get_block(uint32_t block_num)const; processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const; operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; + account_transaction_history_id_type get_account_transaction_history_id(operation_history_id_type operation_id)const; // Globals chain_property_object get_chain_properties()const; @@ -424,6 +425,25 @@ operation_history_id_type database_api_impl::get_operation_history_id(uint32_t b { if(op.block_num == block_num and op.trx_in_block == trx_in_block and op.op_in_trx == op_in_trx) { return op.id; + break; + } + } +} +account_transaction_history_id_type database_api::get_account_transaction_history_id(operation_history_id_type operation_id)const +{ + return my->get_account_transaction_history_id( operation_id ); +} + +account_transaction_history_id_type database_api_impl::get_account_transaction_history_id(operation_history_id_type operation_id)const +{ + const auto& ath_idx = _db.get_index_type(); + const auto& ath_by_seq_idx = ath_idx.indices().get(); + + for( const account_transaction_history_object& ath : ath_by_seq_idx ) + { + if(ath.operation_id == operation_id) { + return ath.id; + break; } } } diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 94296b86..131d2dc2 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -190,6 +190,10 @@ class database_api */ operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; + /** + * Given a operation_history_id, get the account_transaction_history_id + */ + account_transaction_history_id_type get_account_transaction_history_id(operation_history_id_type operation_id)const; ///////////// // Globals // @@ -607,6 +611,7 @@ FC_API(graphene::app::database_api, (get_transaction) (get_recent_transaction_by_id) (get_operation_history_id) + (get_account_transaction_history_id) // Globals (get_chain_properties) From 504aa5dccd88c8d3a55cd6f7ee80978d0bfa3f2c Mon Sep 17 00:00:00 2001 From: abitmore Date: Fri, 2 Jun 2017 16:12:53 +0000 Subject: [PATCH 03/20] Account history: option to prune old data (#292) --- libraries/app/api.cpp | 7 +- .../include/graphene/chain/account_object.hpp | 5 +- .../chain/operation_history_object.hpp | 4 + .../account_history_plugin.cpp | 174 ++++++++++++------ 4 files changed, 129 insertions(+), 61 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index 5281c0d9..d346e121 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -493,13 +493,14 @@ namespace graphene { namespace app { const auto& db = *_app.chain_database(); FC_ASSERT(limit <= 100); vector result; + const auto& stats = account(db).statistics(db); if( start == 0 ) - start = account(db).statistics(db).total_ops; + start = stats.total_ops; else - start = min( account(db).statistics(db).total_ops, start ); + start = min( stats.total_ops, start ); - if( start >= stop && start > 0 && limit > 0 ) + if( start >= stop && start > stats.removed_ops && limit > 0 ) { const auto& hist_idx = db.get_index_type(); const auto& by_seq_idx = hist_idx.indices().get(); diff --git a/libraries/chain/include/graphene/chain/account_object.hpp b/libraries/chain/include/graphene/chain/account_object.hpp index faf59e22..522cb7bc 100644 --- a/libraries/chain/include/graphene/chain/account_object.hpp +++ b/libraries/chain/include/graphene/chain/account_object.hpp @@ -50,7 +50,10 @@ namespace graphene { namespace chain { * Keep the most recent operation as a root pointer to a linked list of the transaction history. */ account_transaction_history_id_type most_recent_op; + /** Total operations related to this account. */ uint32_t total_ops = 0; + /** Total operations related to this account that has been removed from the database. */ + uint32_t removed_ops = 0; /** * When calculating votes it is necessary to know how much is stored in orders (and thus unavailable for @@ -386,7 +389,7 @@ FC_REFLECT_DERIVED( graphene::chain::account_statistics_object, (graphene::chain::object), (owner) (most_recent_op) - (total_ops) + (total_ops)(removed_ops) (total_core_in_orders) (lifetime_fees_paid) (pending_fees)(pending_vested_fees) diff --git a/libraries/chain/include/graphene/chain/operation_history_object.hpp b/libraries/chain/include/graphene/chain/operation_history_object.hpp index ecbbc58d..eae8a01e 100644 --- a/libraries/chain/include/graphene/chain/operation_history_object.hpp +++ b/libraries/chain/include/graphene/chain/operation_history_object.hpp @@ -102,6 +102,7 @@ namespace graphene { namespace chain { struct by_id; struct by_seq; struct by_op; +struct by_opid; typedef multi_index_container< account_transaction_history_object, indexed_by< @@ -117,6 +118,9 @@ typedef multi_index_container< member< account_transaction_history_object, account_id_type, &account_transaction_history_object::account>, member< account_transaction_history_object, operation_history_id_type, &account_transaction_history_object::operation_id> > + >, + ordered_non_unique< tag, + member< account_transaction_history_object, operation_history_id_type, &account_transaction_history_object::operation_id> > > > account_transaction_history_multi_index_type; diff --git a/libraries/plugins/account_history/account_history_plugin.cpp b/libraries/plugins/account_history/account_history_plugin.cpp index a5f90ea0..f1bba84d 100644 --- a/libraries/plugins/account_history/account_history_plugin.cpp +++ b/libraries/plugins/account_history/account_history_plugin.cpp @@ -66,6 +66,11 @@ class account_history_plugin_impl flat_set _tracked_accounts; bool _partial_operations = false; primary_index< simple_index< operation_history_object > >* _oho_index; + uint32_t _max_ops_per_account = -1; + private: + /** add one history record, then check and remove the earliest history record */ + void add_account_history( const account_id_type account_id, const operation_history_id_type op_id ); + }; account_history_plugin_impl::~account_history_plugin_impl() @@ -89,39 +94,26 @@ void account_history_plugin_impl::update_account_histories( const signed_block& } ) ); }; - if (_partial_operations) + if( !o_op.valid() || ( _max_ops_per_account == 0 && _partial_operations ) ) { - if( !o_op.valid() ) - { - _oho_index->use_next_id(); - continue; - } + // Note: the 2nd and 3rd checks above are for better performance, when the db is not clean, + // they will break consistency of account_stats.total_ops and removed_ops and most_recent_op + _oho_index->use_next_id(); + continue; } - else - { + else if( !_partial_operations ) // add to the operation history index oho = create_oho(); - if( !o_op.valid() ) - { - ilog( "removing failed operation with ID: ${id}", ("id", oho->id) ); - db.remove( *oho ); - continue; - } - } - const operation_history_object& op = *o_op; // get the set of accounts this operation applies to flat_set impacted; vector other; - operation_get_required_authorities( op.op, impacted, impacted, other ); + operation_get_required_authorities( op.op, impacted, impacted, other ); // fee_payer is added here if( op.op.which() == operation::tag< account_create_operation >::value ) - { - if (!oho.valid()) { oho = create_oho(); } - impacted.insert( oho->result.get() ); - } + impacted.insert( op.result.get() ); else graphene::app::operation_get_impacted_accounts( op.op, impacted ); @@ -129,48 +121,52 @@ void account_history_plugin_impl::update_account_histories( const signed_block& for( auto& item : a.account_auths ) impacted.insert( item.first ); - // for each operation this account applies to that is in the config link it into the history - if( _tracked_accounts.size() == 0 ) - { - if (!impacted.empty() && !oho.valid()) { oho = create_oho(); } - for( auto& account_id : impacted ) - { - // we don't do index_account_keys here anymore, because - // that indexing now happens in observers' post_evaluate() + // be here, either _max_ops_per_account > 0, or _partial_operations == false, or both + // if _partial_operations == false, oho should have been created above + // so the only case should be checked here is: + // whether need to create oho if _max_ops_per_account > 0 and _partial_operations == true - // add history - const auto& stats_obj = account_id(db).statistics(db); - const auto& ath = db.create( [&]( account_transaction_history_object& obj ){ - obj.operation_id = oho->id; - obj.account = account_id; - obj.sequence = stats_obj.total_ops+1; - obj.next = stats_obj.most_recent_op; - }); - db.modify( stats_obj, [&]( account_statistics_object& obj ){ - obj.most_recent_op = ath.id; - obj.total_ops = ath.sequence; - }); + // for each operation this account applies to that is in the config link it into the history + if( _tracked_accounts.size() == 0 ) // tracking all accounts + { + // if tracking all accounts, when impacted is not empty (although it will always be), + // still need to create oho if _max_ops_per_account > 0 and _partial_operations == true + // so always need to create oho if not done + if (!impacted.empty() && !oho.valid()) { oho = create_oho(); } + + if( _max_ops_per_account > 0 ) + { + // Note: the check above is for better performance, when the db is not clean, + // it breaks consistency of account_stats.total_ops and removed_ops and most_recent_op, + // but it ensures it's safe to remove old entries in add_account_history(...) + for( auto& account_id : impacted ) + { + // we don't do index_account_keys here anymore, because + // that indexing now happens in observers' post_evaluate() + + // add history + add_account_history( account_id, oho->id ); + } } } - else + else // tracking a subset of accounts { - for( auto account_id : _tracked_accounts ) + // whether need to create oho if _max_ops_per_account > 0 and _partial_operations == true ? + // the answer: only need to create oho if a tracked account is impacted and need to save history + + if( _max_ops_per_account > 0 ) { - if( impacted.find( account_id ) != impacted.end() ) + // Note: the check above is for better performance, when the db is not clean, + // it breaks consistency of account_stats.total_ops and removed_ops and most_recent_op, + // but it ensures it's safe to remove old entries in add_account_history(...) + for( auto account_id : _tracked_accounts ) { - if (!oho.valid()) { oho = create_oho(); } - // add history - const auto& stats_obj = account_id(db).statistics(db); - const auto& ath = db.create( [&]( account_transaction_history_object& obj ){ - obj.operation_id = oho->id; - obj.account = account_id; - obj.sequence = stats_obj.total_ops+1; - obj.next = stats_obj.most_recent_op; - }); - db.modify( stats_obj, [&]( account_statistics_object& obj ){ - obj.most_recent_op = ath.id; - obj.total_ops = ath.sequence; - }); + if( impacted.find( account_id ) != impacted.end() ) + { + if (!oho.valid()) { oho = create_oho(); } + // add history + add_account_history( account_id, oho->id ); + } } } } @@ -178,6 +174,66 @@ void account_history_plugin_impl::update_account_histories( const signed_block& _oho_index->use_next_id(); } } + +void account_history_plugin_impl::add_account_history( const account_id_type account_id, const operation_history_id_type op_id ) +{ + graphene::chain::database& db = database(); + const auto& stats_obj = account_id(db).statistics(db); + // add new entry + const auto& ath = db.create( [&]( account_transaction_history_object& obj ){ + obj.operation_id = op_id; + obj.account = account_id; + obj.sequence = stats_obj.total_ops + 1; + obj.next = stats_obj.most_recent_op; + }); + db.modify( stats_obj, [&]( account_statistics_object& obj ){ + obj.most_recent_op = ath.id; + obj.total_ops = ath.sequence; + }); + // remove the earliest account history entry if too many + // _max_ops_per_account is guaranteed to be non-zero outside + if( stats_obj.total_ops - stats_obj.removed_ops > _max_ops_per_account ) + { + // look for the earliest entry + const auto& his_idx = db.get_index_type(); + const auto& by_seq_idx = his_idx.indices().get(); + auto itr = by_seq_idx.lower_bound( boost::make_tuple( account_id, 0 ) ); + // make sure don't remove the one just added + if( itr != by_seq_idx.end() && itr->account == account_id && itr->id != ath.id ) + { + // if found, remove the entry, and adjust account stats object + const auto remove_op_id = itr->operation_id; + const auto itr_remove = itr; + ++itr; + db.remove( *itr_remove ); + db.modify( stats_obj, [&]( account_statistics_object& obj ){ + obj.removed_ops = obj.removed_ops + 1; + }); + // modify previous node's next pointer + // this should be always true, but just have a check here + if( itr != by_seq_idx.end() && itr->account == account_id ) + { + db.modify( *itr, [&]( account_transaction_history_object& obj ){ + obj.next = account_transaction_history_id_type(); + }); + } + // else need to modify the head pointer, but it shouldn't be true + + // remove the operation history entry (1.11.x) if configured and no reference left + if( _partial_operations ) + { + // check for references + const auto& by_opid_idx = his_idx.indices().get(); + if( by_opid_idx.find( remove_op_id ) == by_opid_idx.end() ) + { + // if no reference, remove + db.remove( remove_op_id(db) ); + } + } + } + } +} + } // end namespace detail @@ -207,6 +263,7 @@ void account_history_plugin::plugin_set_program_options( cli.add_options() ("track-account", boost::program_options::value>()->composing()->multitoken(), "Account ID to track history for (may specify multiple times)") ("partial-operations", boost::program_options::value(), "Keep only those operations in memory that are related to account history tracking") + ("max-ops-per-account", boost::program_options::value(), "Maximum number of operations per account will be kept in memory") ; cfg.add(cli); } @@ -221,6 +278,9 @@ void account_history_plugin::plugin_initialize(const boost::program_options::var if (options.count("partial-operations")) { my->_partial_operations = options["partial-operations"].as(); } + if (options.count("max-ops-per-account")) { + my->_max_ops_per_account = options["max-ops-per-account"].as(); + } } void account_history_plugin::plugin_startup() From 40c7a7ffa386c9418c70b0555de0bb46b2ea5d7c Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Fri, 2 Jun 2017 19:38:30 -0500 Subject: [PATCH 04/20] Fix warnings; #296 --- libraries/app/database_api.cpp | 21 +++++++++++-------- .../app/include/graphene/app/database_api.hpp | 4 ++-- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index cd941b5c..eec6348b 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -68,8 +68,8 @@ class database_api_impl : public std::enable_shared_from_this map> get_block_header_batch(const vector block_nums)const; optional get_block(uint32_t block_num)const; processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const; - operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; - account_transaction_history_id_type get_account_transaction_history_id(operation_history_id_type operation_id)const; + optional get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; + optional get_account_transaction_history_id(operation_history_id_type operation_id)const; // Globals chain_property_object get_chain_properties()const; @@ -412,29 +412,31 @@ processed_transaction database_api_impl::get_transaction(uint32_t block_num, uin return opt_block->transactions[trx_num]; } -operation_history_id_type database_api::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const +optional database_api::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const { return my->get_operation_history_id( block_num, trx_in_block, op_in_trx ); } -operation_history_id_type database_api_impl::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const +optional database_api_impl::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const { const simple_index& op_index = _db.get_index_type>(); for( const operation_history_object& op : op_index ) { - if(op.block_num == block_num and op.trx_in_block == trx_in_block and op.op_in_trx == op_in_trx) { + if(op.block_num == block_num && op.trx_in_block == trx_in_block && op.op_in_trx == op_in_trx) { return op.id; - break; } } + + return {}; } -account_transaction_history_id_type database_api::get_account_transaction_history_id(operation_history_id_type operation_id)const + +optional database_api::get_account_transaction_history_id(operation_history_id_type operation_id)const { return my->get_account_transaction_history_id( operation_id ); } -account_transaction_history_id_type database_api_impl::get_account_transaction_history_id(operation_history_id_type operation_id)const +optional database_api_impl::get_account_transaction_history_id(operation_history_id_type operation_id)const { const auto& ath_idx = _db.get_index_type(); const auto& ath_by_seq_idx = ath_idx.indices().get(); @@ -443,9 +445,10 @@ account_transaction_history_id_type database_api_impl::get_account_transaction_h { if(ath.operation_id == operation_id) { return ath.id; - break; } } + + return {}; } diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 131d2dc2..a7d1e877 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -188,12 +188,12 @@ class database_api /** * Given a block, transaction in block position and operation position in transaction, get the operation_history_id */ - operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; + optional get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; /** * Given a operation_history_id, get the account_transaction_history_id */ - account_transaction_history_id_type get_account_transaction_history_id(operation_history_id_type operation_id)const; + optional get_account_transaction_history_id(operation_history_id_type operation_id)const; ///////////// // Globals // From 06b18c4011426a79a5d9922d3b4490b2e0885475 Mon Sep 17 00:00:00 2001 From: abitmore Date: Sat, 3 Jun 2017 00:07:14 +0000 Subject: [PATCH 05/20] Fix Windows build. --- CMakeLists.txt | 5 ++++- libraries/chain/db_notify.cpp | 4 ++-- libraries/net/node.cpp | 8 ++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9a5d3667..49abfd29 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,13 +32,16 @@ if (USE_PCH) include (cotire) endif(USE_PCH) -list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libraries/fc/CMakeModules" ) +IF( NOT WIN32 ) + list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libraries/fc/CMakeModules" ) +ENDIF( NOT WIN32 ) list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/libraries/fc/GitVersionGen" ) include( GetGitRevisionDescription ) get_git_head_revision( GIT_REFSPEC GIT_SHA2 ) SET(BOOST_COMPONENTS) LIST(APPEND BOOST_COMPONENTS thread + iostreams date_time system filesystem diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index 7b5375cc..0dfb21c2 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -387,6 +387,6 @@ void database::notify_changed_objects() removed_objects(removed_ids, removed, removed_accounts_impacted); } } -} FC_CAPTURE_AND_LOG( () ) } +} FC_CAPTURE_AND_LOG( (0) ) } -} } \ No newline at end of file +} } diff --git a/libraries/net/node.cpp b/libraries/net/node.cpp index f9309123..5325c9b1 100644 --- a/libraries/net/node.cpp +++ b/libraries/net/node.cpp @@ -974,11 +974,7 @@ namespace graphene { namespace net { namespace detail { { throw; } - catch (const fc::exception& e) - { - elog("${e}", ("e", e)); - } - FC_CAPTURE_AND_LOG( () ) + FC_CAPTURE_AND_LOG( (0) ) }// while(!canceled) } @@ -4193,7 +4189,7 @@ namespace graphene { namespace net { namespace detail { // limit the rate at which we accept connections to mitigate DOS attacks fc::usleep( fc::milliseconds(10) ); - } FC_CAPTURE_AND_LOG( () ) + } FC_CAPTURE_AND_LOG( (0) ) } } // accept_loop() From a263279b7657436add324f7d0e26b3e9bbb834dd Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Sat, 3 Jun 2017 16:03:52 -0500 Subject: [PATCH 06/20] Revert "Fix warnings; #296" This reverts commit 40c7a7ffa386c9418c70b0555de0bb46b2ea5d7c. --- libraries/app/database_api.cpp | 21 ++++++++----------- .../app/include/graphene/app/database_api.hpp | 4 ++-- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index eec6348b..cd941b5c 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -68,8 +68,8 @@ class database_api_impl : public std::enable_shared_from_this map> get_block_header_batch(const vector block_nums)const; optional get_block(uint32_t block_num)const; processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const; - optional get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; - optional get_account_transaction_history_id(operation_history_id_type operation_id)const; + operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; + account_transaction_history_id_type get_account_transaction_history_id(operation_history_id_type operation_id)const; // Globals chain_property_object get_chain_properties()const; @@ -412,31 +412,29 @@ processed_transaction database_api_impl::get_transaction(uint32_t block_num, uin return opt_block->transactions[trx_num]; } -optional database_api::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const +operation_history_id_type database_api::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const { return my->get_operation_history_id( block_num, trx_in_block, op_in_trx ); } -optional database_api_impl::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const +operation_history_id_type database_api_impl::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const { const simple_index& op_index = _db.get_index_type>(); for( const operation_history_object& op : op_index ) { - if(op.block_num == block_num && op.trx_in_block == trx_in_block && op.op_in_trx == op_in_trx) { + if(op.block_num == block_num and op.trx_in_block == trx_in_block and op.op_in_trx == op_in_trx) { return op.id; + break; } } - - return {}; } - -optional database_api::get_account_transaction_history_id(operation_history_id_type operation_id)const +account_transaction_history_id_type database_api::get_account_transaction_history_id(operation_history_id_type operation_id)const { return my->get_account_transaction_history_id( operation_id ); } -optional database_api_impl::get_account_transaction_history_id(operation_history_id_type operation_id)const +account_transaction_history_id_type database_api_impl::get_account_transaction_history_id(operation_history_id_type operation_id)const { const auto& ath_idx = _db.get_index_type(); const auto& ath_by_seq_idx = ath_idx.indices().get(); @@ -445,10 +443,9 @@ optional database_api_impl::get_account_tra { if(ath.operation_id == operation_id) { return ath.id; + break; } } - - return {}; } diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index a7d1e877..131d2dc2 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -188,12 +188,12 @@ class database_api /** * Given a block, transaction in block position and operation position in transaction, get the operation_history_id */ - optional get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; + operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; /** * Given a operation_history_id, get the account_transaction_history_id */ - optional get_account_transaction_history_id(operation_history_id_type operation_id)const; + account_transaction_history_id_type get_account_transaction_history_id(operation_history_id_type operation_id)const; ///////////// // Globals // From f9f60770f9ecf6026fb61215ead5a06cb56be22e Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Sat, 3 Jun 2017 16:05:17 -0500 Subject: [PATCH 07/20] Revert "Merge branch 'goho' of git://github.com/oxarbitrage/bitshares-core into oxarbitrage-goho" This reverts commit 628652f3ebc5d9ae45ca0c68dd2a71d615581b72, reversing changes made to 568ceb189eca96e77e38c4059b83a504008d7e91. --- libraries/app/database_api.cpp | 39 ------------------- .../app/include/graphene/app/database_api.hpp | 12 ------ 2 files changed, 51 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index cd941b5c..32217826 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -68,8 +68,6 @@ class database_api_impl : public std::enable_shared_from_this map> get_block_header_batch(const vector block_nums)const; optional get_block(uint32_t block_num)const; processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const; - operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; - account_transaction_history_id_type get_account_transaction_history_id(operation_history_id_type operation_id)const; // Globals chain_property_object get_chain_properties()const; @@ -412,43 +410,6 @@ processed_transaction database_api_impl::get_transaction(uint32_t block_num, uin return opt_block->transactions[trx_num]; } -operation_history_id_type database_api::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const -{ - return my->get_operation_history_id( block_num, trx_in_block, op_in_trx ); -} - -operation_history_id_type database_api_impl::get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const -{ - const simple_index& op_index = _db.get_index_type>(); - - for( const operation_history_object& op : op_index ) - { - if(op.block_num == block_num and op.trx_in_block == trx_in_block and op.op_in_trx == op_in_trx) { - return op.id; - break; - } - } -} -account_transaction_history_id_type database_api::get_account_transaction_history_id(operation_history_id_type operation_id)const -{ - return my->get_account_transaction_history_id( operation_id ); -} - -account_transaction_history_id_type database_api_impl::get_account_transaction_history_id(operation_history_id_type operation_id)const -{ - const auto& ath_idx = _db.get_index_type(); - const auto& ath_by_seq_idx = ath_idx.indices().get(); - - for( const account_transaction_history_object& ath : ath_by_seq_idx ) - { - if(ath.operation_id == operation_id) { - return ath.id; - break; - } - } -} - - ////////////////////////////////////////////////////////////////////// // // // Globals // diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 131d2dc2..1fe64a09 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -185,16 +185,6 @@ class database_api */ optional get_recent_transaction_by_id( const transaction_id_type& id )const; - /** - * Given a block, transaction in block position and operation position in transaction, get the operation_history_id - */ - operation_history_id_type get_operation_history_id(uint32_t block_num, uint32_t trx_in_block, uint32_t op_in_trx)const; - - /** - * Given a operation_history_id, get the account_transaction_history_id - */ - account_transaction_history_id_type get_account_transaction_history_id(operation_history_id_type operation_id)const; - ///////////// // Globals // ///////////// @@ -610,8 +600,6 @@ FC_API(graphene::app::database_api, (get_block) (get_transaction) (get_recent_transaction_by_id) - (get_operation_history_id) - (get_account_transaction_history_id) // Globals (get_chain_properties) From 087d58f5f44a66e26e65ea72c524d11dd2222e2f Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Sat, 3 Jun 2017 16:25:22 -0500 Subject: [PATCH 08/20] Update docs submodule --- docs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs b/docs index d9994828..53678453 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit d99948280c6ae98a337be8ae93ab7182896d525c +Subproject commit 5367845313204adb588c33177adabcfa3cf41b27 From 1ce4d36532e7351ca1c737eb54fe26c4665005b6 Mon Sep 17 00:00:00 2001 From: Abit Date: Sun, 4 Jun 2017 01:47:02 +0200 Subject: [PATCH 09/20] Check block latency after logging. --- libraries/app/application.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index fb6d70aa..823ee6bc 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -524,8 +524,6 @@ namespace detail { std::vector& contained_transaction_message_ids) override { try { - auto latency = fc::time_point::now() - blk_msg.block.timestamp; - FC_ASSERT( (latency.count()/1000) > -5000, "Rejecting block with timestamp in the future" ); if (!sync_mode || blk_msg.block.block_num() % 10000 == 0) { const auto& witness = blk_msg.block.witness(*_chain_db); @@ -538,6 +536,8 @@ namespace detail { ("w",witness_account.name) ("i",last_irr)("d",blk_msg.block.block_num()-last_irr) ); } + auto latency = fc::time_point::now() - blk_msg.block.timestamp; + FC_ASSERT( (latency.count()/1000) > -5000, "Rejecting block with timestamp in the future" ); try { // TODO: in the case where this block is valid but on a fork that's too old for us to switch to, From df787c90621bb13b0b05dc2119aa117ef5a6e937 Mon Sep 17 00:00:00 2001 From: Abit Date: Mon, 5 Jun 2017 00:32:44 +0200 Subject: [PATCH 10/20] Fix latency check error --- libraries/app/application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index 823ee6bc..02b623d2 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -524,6 +524,7 @@ namespace detail { std::vector& contained_transaction_message_ids) override { try { + auto latency = fc::time_point::now() - blk_msg.block.timestamp; if (!sync_mode || blk_msg.block.block_num() % 10000 == 0) { const auto& witness = blk_msg.block.witness(*_chain_db); @@ -536,7 +537,6 @@ namespace detail { ("w",witness_account.name) ("i",last_irr)("d",blk_msg.block.block_num()-last_irr) ); } - auto latency = fc::time_point::now() - blk_msg.block.timestamp; FC_ASSERT( (latency.count()/1000) > -5000, "Rejecting block with timestamp in the future" ); try { From a62acbce4c062662258d349c51252ccc41bd10ac Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Sun, 4 Jun 2017 18:26:47 -0500 Subject: [PATCH 11/20] Add OpenSSL compatibility note to README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a7d22871..97bf058a 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,8 @@ To build after all dependencies are installed: cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo . make +**NOTE:** BitShares requires an [OpenSSL](https://www.openssl.org/) version in the 1.0.x series. OpenSSL 1.1.0 and newer are NOT supported. If your system OpenSSL version is newer, then you will need to manually provide an older version of OpenSSL and specify it to CMake using `-DOPENSSL_INCLUDE_DIR`, `-DOPENSSL_SSL_LIBRARY`, and `-DOPENSSL_CRYPTO_LIBRARY`. + **NOTE:** BitShares requires a [Boost](http://www.boost.org/) version in the range [1.57, 1.60]. Versions earlier than 1.57 or newer than 1.60 are NOT supported. If your system Boost version is newer, then you will need to manually build an older version of Boost and specify it to CMake using `DBOOST_ROOT`. From 848eb65ab1f9533c0ac5c3cae96acb01440c2234 Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Sun, 4 Jun 2017 18:28:04 -0500 Subject: [PATCH 12/20] Update submodules --- docs | 2 +- libraries/fc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs b/docs index 53678453..bd792d02 160000 --- a/docs +++ b/docs @@ -1 +1 @@ -Subproject commit 5367845313204adb588c33177adabcfa3cf41b27 +Subproject commit bd792d02c70e7686da2b27197eba4fd6df30477c diff --git a/libraries/fc b/libraries/fc index b94a338e..cb627980 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit b94a338e56475943eb9bcc79be60ed6afd586796 +Subproject commit cb627980a5ff5f65fe129414dd96d3c2bd51b095 From 9200cc83c3208c928f16420885ed2651c6ab45f6 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 8 Jun 2017 12:27:51 +0000 Subject: [PATCH 13/20] fix get_order_book --- libraries/app/database_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 32217826..a6c06e2b 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -1225,7 +1225,7 @@ order_book database_api_impl::get_order_book( const string& base, const string& order ord; ord.price = price_to_real( o.sell_price ); ord.quote = asset_to_real( o.for_sale, assets[1]->precision ); - ord.base = asset_to_real( share_type( ( uint64_t( o.for_sale.value ) * o.sell_price.quote.amount.value ) / o.sell_price.base.amount.value ), assets[0]->precision ); + ord.base = asset_to_real( share_type( ( uint128_t( o.for_sale.value ) * o.sell_price.quote.amount.value ) / o.sell_price.base.amount.value ), assets[0]->precision ); result.asks.push_back( ord ); } } From 773a2d0caf9eb75bbe2bc76c707ebf06228621cf Mon Sep 17 00:00:00 2001 From: oxarbitrage Date: Thu, 8 Jun 2017 18:43:36 -0300 Subject: [PATCH 14/20] get_full_accounts change allow 100 subscribed accounts instead of 99. --- libraries/app/database_api.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 32217826..28ac962a 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -618,7 +618,7 @@ std::map database_api_impl::get_full_accounts( const if( subscribe ) { - FC_ASSERT( std::distance(_subscribed_accounts.begin(), _subscribed_accounts.end()) < 100 ); + FC_ASSERT( std::distance(_subscribed_accounts.begin(), _subscribed_accounts.end()) <= 100 ); _subscribed_accounts.insert( account->get_id() ); subscribe_to_item( account->id ); } From 2b1f1b7f743640950ff09d09c0db1d032af7ff49 Mon Sep 17 00:00:00 2001 From: oxarbitrage Date: Sat, 10 Jun 2017 17:38:46 -0300 Subject: [PATCH 15/20] add commented GRAPHENE_TEST_NETWORK to config for issue https://github.com/bitshares/bitshares-core/issues/307 --- libraries/net/include/graphene/net/config.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/net/include/graphene/net/config.hpp b/libraries/net/include/graphene/net/config.hpp index d14bd825..f4b3013a 100644 --- a/libraries/net/include/graphene/net/config.hpp +++ b/libraries/net/include/graphene/net/config.hpp @@ -49,6 +49,10 @@ #define GRAPHENE_NET_PEER_DISCONNECT_TIMEOUT 20 +/* uncomment next line to use testnet seed ip and port */ +//#define GRAPHENE_TEST_NETWORK 1 + + #define GRAPHENE_NET_TEST_SEED_IP "104.236.44.210" // autogenerated #define GRAPHENE_NET_TEST_P2P_PORT 1700 #define GRAPHENE_NET_DEFAULT_P2P_PORT 1776 From 1939c7bff6109fdc5166529abede8006cc4dac1b Mon Sep 17 00:00:00 2001 From: oxarbitrage Date: Sat, 10 Jun 2017 17:39:48 -0300 Subject: [PATCH 16/20] remove extra space --- libraries/net/include/graphene/net/config.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/net/include/graphene/net/config.hpp b/libraries/net/include/graphene/net/config.hpp index f4b3013a..ec1e805d 100644 --- a/libraries/net/include/graphene/net/config.hpp +++ b/libraries/net/include/graphene/net/config.hpp @@ -52,7 +52,6 @@ /* uncomment next line to use testnet seed ip and port */ //#define GRAPHENE_TEST_NETWORK 1 - #define GRAPHENE_NET_TEST_SEED_IP "104.236.44.210" // autogenerated #define GRAPHENE_NET_TEST_P2P_PORT 1700 #define GRAPHENE_NET_DEFAULT_P2P_PORT 1776 From fab2794699e9e2f4ca05e016ec9d799ab798ef04 Mon Sep 17 00:00:00 2001 From: oxarbitrage Date: Sun, 11 Jun 2017 11:47:11 -0300 Subject: [PATCH 17/20] remove GRAPHENE_TEST_NETWORK_VERSION https://github.com/bitshares/bitshares-core/issues/307 --- libraries/net/node.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/net/node.cpp b/libraries/net/node.cpp index 5325c9b1..7d639878 100644 --- a/libraries/net/node.cpp +++ b/libraries/net/node.cpp @@ -4390,7 +4390,7 @@ namespace graphene { namespace net { namespace detail { _node_configuration = detail::node_configuration(); #ifdef GRAPHENE_TEST_NETWORK - uint32_t port = GRAPHENE_NET_TEST_P2P_PORT + GRAPHENE_TEST_NETWORK_VERSION; + uint32_t port = GRAPHENE_NET_TEST_P2P_PORT; #else uint32_t port = GRAPHENE_NET_DEFAULT_P2P_PORT; #endif From ea8f8964eb8f5c10d66a07a10aa2f1d300ef1629 Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Mon, 12 Jun 2017 18:22:34 -0300 Subject: [PATCH 18/20] Implement network_broadcast_api::broadcast_transaction_synchronous (ported from steem) --- libraries/app/api.cpp | 11 +++++++++++ libraries/app/include/graphene/app/api.hpp | 7 +++++++ 2 files changed, 18 insertions(+) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index d346e121..480f5c66 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -39,6 +39,7 @@ #include #include +#include namespace graphene { namespace app { @@ -159,6 +160,16 @@ namespace graphene { namespace app { _app.p2p_node()->broadcast_transaction(trx); } + fc::variant network_broadcast_api::broadcast_transaction_synchronous(const signed_transaction& trx) + { + fc::promise::ptr prom( new fc::promise() ); + broadcast_transaction_with_callback( [=]( const fc::variant& v ){ + prom->set_value(v); + }, trx ); + + return fc::future(prom).wait(); + } + void network_broadcast_api::broadcast_block( const signed_block& b ) { _app.chain_database()->push_block(b); diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index be511d3a..6b5830c9 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -195,6 +195,12 @@ namespace graphene { namespace app { */ void broadcast_transaction_with_callback( confirmation_callback cb, const signed_transaction& trx); + /** this version of broadcast transaction registers a callback method that will be called when the transaction is + * included into a block. The callback method includes the transaction id, block number, and transaction number in the + * block. + */ + fc::variant broadcast_transaction_synchronous(const signed_transaction& trx); + void broadcast_block( const signed_block& block ); /** @@ -394,6 +400,7 @@ FC_API(graphene::app::block_api, FC_API(graphene::app::network_broadcast_api, (broadcast_transaction) (broadcast_transaction_with_callback) + (broadcast_transaction_synchronous) (broadcast_block) ) FC_API(graphene::app::network_node_api, From b30755718242d5f19935316c49c525fb7e52f98d Mon Sep 17 00:00:00 2001 From: root Date: Wed, 14 Jun 2017 17:47:18 +0000 Subject: [PATCH 19/20] add simple pagination to get_asset_holders --- libraries/app/api.cpp | 16 +++++++++++++++- libraries/app/include/graphene/app/api.hpp | 2 +- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index d346e121..b7e37705 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -625,16 +625,25 @@ namespace graphene { namespace app { asset_api::asset_api(graphene::chain::database& db) : _db(db) { } asset_api::~asset_api() { } - vector asset_api::get_asset_holders( asset_id_type asset_id ) const { + vector asset_api::get_asset_holders( asset_id_type asset_id, uint32_t start, uint32_t limit ) const { + + FC_ASSERT(limit <= 100); const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) ); vector result; + uint32_t total_counter = 0; + uint32_t start_counter = 0; + for( const account_balance_object& bal : boost::make_iterator_range( range.first, range.second ) ) { + //wdump((bal)); if( bal.balance.value == 0 ) continue; + + start_counter++; + if( start >= start_counter ) continue; auto account = _db.find(bal.owner); @@ -644,6 +653,11 @@ namespace graphene { namespace app { aab.amount = bal.balance.value; result.push_back(aab); + + if(total_counter >= limit) break; + + total_counter++; + } return result; diff --git a/libraries/app/include/graphene/app/api.hpp b/libraries/app/include/graphene/app/api.hpp index be511d3a..923c870b 100644 --- a/libraries/app/include/graphene/app/api.hpp +++ b/libraries/app/include/graphene/app/api.hpp @@ -305,7 +305,7 @@ namespace graphene { namespace app { asset_api(graphene::chain::database& db); ~asset_api(); - vector get_asset_holders( asset_id_type asset_id )const; + vector get_asset_holders( asset_id_type asset_id, uint32_t start, uint32_t limit )const; int get_asset_holders_count( asset_id_type asset_id )const; vector get_all_asset_holders() const; From 38ac7cb4575c2d9a34f6df116647e29496a8536a Mon Sep 17 00:00:00 2001 From: Vikram Rajkumar Date: Wed, 14 Jun 2017 18:02:54 -0500 Subject: [PATCH 20/20] Cleanup #312 --- libraries/app/api.cpp | 101 ++++++++++++++++++++---------------------- 1 file changed, 48 insertions(+), 53 deletions(-) diff --git a/libraries/app/api.cpp b/libraries/app/api.cpp index b7e37705..ec12465a 100644 --- a/libraries/app/api.cpp +++ b/libraries/app/api.cpp @@ -426,13 +426,13 @@ namespace graphene { namespace app { return result; } - vector history_api::get_account_history( account_id_type account, - operation_history_id_type stop, - unsigned limit, + vector history_api::get_account_history( account_id_type account, + operation_history_id_type stop, + unsigned limit, operation_history_id_type start ) const { FC_ASSERT( _app.chain_database() ); - const auto& db = *_app.chain_database(); + const auto& db = *_app.chain_database(); FC_ASSERT( limit <= 100 ); vector result; const auto& stats = account(db).statistics(db); @@ -440,7 +440,7 @@ namespace graphene { namespace app { const account_transaction_history_object* node = &stats.most_recent_op(db); if( start == operation_history_id_type() ) start = node->operation_id; - + while(node && node->operation_id.instance.value > stop.instance.value && result.size() < limit) { if( node->operation_id.instance.value <= start.instance.value ) @@ -449,13 +449,13 @@ namespace graphene { namespace app { node = nullptr; else node = &node->next(db); } - + return result; } - - vector history_api::get_account_history_operations( account_id_type account, + + vector history_api::get_account_history_operations( account_id_type account, int operation_id, - operation_history_id_type start, + operation_history_id_type start, operation_history_id_type stop, unsigned limit) const { @@ -484,9 +484,9 @@ namespace graphene { namespace app { } - vector history_api::get_relative_account_history( account_id_type account, - uint32_t stop, - unsigned limit, + vector history_api::get_relative_account_history( account_id_type account, + uint32_t stop, + unsigned limit, uint32_t start) const { FC_ASSERT( _app.chain_database() ); @@ -507,7 +507,7 @@ namespace graphene { namespace app { auto itr = by_seq_idx.upper_bound( boost::make_tuple( account, start ) ); auto itr_stop = by_seq_idx.lower_bound( boost::make_tuple( account, stop ) ); - + do { --itr; @@ -550,14 +550,14 @@ namespace graphene { namespace app { } return result; } FC_CAPTURE_AND_RETHROW( (a)(b)(bucket_seconds)(start)(end) ) } - + crypto_api::crypto_api(){}; - + blind_signature crypto_api::blind_sign( const extended_private_key_type& key, const blinded_hash& hash, int i ) { return fc::ecc::extended_private_key( key ).blind_sign( hash, i ); } - + signature_type crypto_api::unblind_signature( const extended_private_key_type& key, const extended_public_key_type& bob, const blind_signature& sig, @@ -566,32 +566,32 @@ namespace graphene { namespace app { { return fc::ecc::extended_private_key( key ).unblind_signature( extended_public_key( bob ), sig, hash, i ); } - + commitment_type crypto_api::blind( const blind_factor_type& blind, uint64_t value ) { return fc::ecc::blind( blind, value ); } - + blind_factor_type crypto_api::blind_sum( const std::vector& blinds_in, uint32_t non_neg ) { return fc::ecc::blind_sum( blinds_in, non_neg ); } - + bool crypto_api::verify_sum( const std::vector& commits_in, const std::vector& neg_commits_in, int64_t excess ) { return fc::ecc::verify_sum( commits_in, neg_commits_in, excess ); } - + verify_range_result crypto_api::verify_range( const commitment_type& commit, const std::vector& proof ) { verify_range_result result; result.success = fc::ecc::verify_range( result.min_val, result.max_val, commit, proof ); return result; } - - std::vector crypto_api::range_proof_sign( uint64_t min_value, - const commitment_type& commit, - const blind_factor_type& commit_blind, + + std::vector crypto_api::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, @@ -599,23 +599,23 @@ namespace graphene { namespace app { { return fc::ecc::range_proof_sign( min_value, commit, commit_blind, nonce, base10_exp, min_bits, actual_value ); } - + verify_range_proof_rewind_result crypto_api::verify_range_proof_rewind( const blind_factor_type& nonce, - const commitment_type& commit, + const commitment_type& commit, const std::vector& proof ) { verify_range_proof_rewind_result result; - result.success = fc::ecc::verify_range_proof_rewind( result.blind_out, - result.value_out, - result.message_out, - nonce, - result.min_val, - result.max_val, - const_cast< commitment_type& >( commit ), + result.success = fc::ecc::verify_range_proof_rewind( result.blind_out, + result.value_out, + result.message_out, + nonce, + result.min_val, + result.max_val, + const_cast< commitment_type& >( commit ), proof ); return result; } - + range_proof_info crypto_api::range_get_info( const std::vector& proof ) { return fc::ecc::range_get_info( proof ); @@ -626,7 +626,6 @@ namespace graphene { namespace app { asset_api::~asset_api() { } vector asset_api::get_asset_holders( asset_id_type asset_id, uint32_t start, uint32_t limit ) const { - FC_ASSERT(limit <= 100); const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); @@ -634,18 +633,19 @@ namespace graphene { namespace app { vector result; - uint32_t total_counter = 0; - uint32_t start_counter = 0; - + uint32_t index = 0; for( const account_balance_object& bal : boost::make_iterator_range( range.first, range.second ) ) { - //wdump((bal)); - if( bal.balance.value == 0 ) continue; - - start_counter++; - if( start >= start_counter ) continue; + if( result.size() >= limit ) + break; - auto account = _db.find(bal.owner); + if( bal.balance.value == 0 ) + continue; + + if( index++ < start ) + continue; + + const auto account = _db.find(bal.owner); account_asset_balance aab; aab.name = account->name; @@ -653,11 +653,6 @@ namespace graphene { namespace app { aab.amount = bal.balance.value; result.push_back(aab); - - if(total_counter >= limit) break; - - total_counter++; - } return result; @@ -667,16 +662,16 @@ namespace graphene { namespace app { const auto& bal_idx = _db.get_index_type< account_balance_index >().indices().get< by_asset_balance >(); auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) ); - + int count = boost::distance(range) - 1; return count; } // function to get vector of system assets with holders count. vector asset_api::get_all_asset_holders() const { - + vector result; - + vector total_assets; for( const asset_object& asset_obj : _db.get_index_type().indices() ) { @@ -689,7 +684,7 @@ namespace graphene { namespace app { auto range = bal_idx.equal_range( boost::make_tuple( asset_id ) ); int count = boost::distance(range) - 1; - + asset_holders ah; ah.asset_id = asset_id; ah.count = count;