diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 369dcf8a..e65c81c8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -19,7 +19,7 @@ build: - mkdir build - cd build - cmake -DCMAKE_BUILD_TYPE=Release .. - - make -j4 + - make -j$(nproc) artifacts: untracked: true paths: @@ -49,6 +49,7 @@ test: dependencies: - build script: + - ./build/libraries/fc/tests/all_tests - ./build/tests/betting_test --log_level=message - ./build/tests/chain_test --log_level=message - ./build/tests/cli_test --log_level=message diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f006aa0..27c29861 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,6 @@ LIST(APPEND BOOST_COMPONENTS thread system filesystem program_options - signals serialization chrono unit_test_framework diff --git a/README.md b/README.md index 3c5113fc..7ee5aa8b 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Following dependencies are needed for a clean install of Ubuntu 20.04: ``` sudo apt-get install \ apt-utils autoconf bash build-essential ca-certificates cmake dnsutils \ - doxygen expect git graphviz libboost1.67-all-dev libbz2-dev libcurl4-openssl-dev \ + doxygen expect git graphviz libboost-all-dev libbz2-dev libcurl4-openssl-dev \ libncurses-dev libreadline-dev libsnappy-dev libssl-dev libtool libzip-dev \ libzmq3-dev locales mc nano net-tools ntp openssh-server pkg-config perl \ python3 python3-jinja2 sudo wget @@ -27,10 +27,18 @@ cd $HOME/src git clone https://gitlab.com/PBSA/peerplays.git cd peerplays git submodule update --init --recursive + # If you want to build Mainnet node cmake -DCMAKE_BUILD_TYPE=Release + # If you want to build Testnet node cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_PEERPLAYS_TESTNET=1 + +# Update -j flag depending on your current system specs; +# Recommended 4GB of RAM per 1 CPU core +# make -j2 for 8GB RAM +# make -j4 for 16GB RAM +# make -j8 for 32GB RAM make -j$(nproc) make install # this can install the executable files under /usr/local diff --git a/clang-format.sh b/clang-format.sh index 3fbbf055..7f448285 100755 --- a/clang-format.sh +++ b/clang-format.sh @@ -3,3 +3,4 @@ find ./libraries/app -regex ".*[c|h]pp" | xargs clang-format -i find ./libraries/chain/hardfork.d -regex ".*hf" | xargs clang-format -i find ./libraries/plugins/peerplays_sidechain -regex ".*[c|h]pp" | xargs clang-format -i +find ./programs/cli_wallet -regex ".*[c|h]pp" | xargs clang-format -i diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 632f74b9..22fbfb6a 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -52,27 +52,19 @@ template class fc::api; namespace graphene { namespace app { -template -optional maybe_id( const string& name_or_id ) -{ - if( std::isdigit( name_or_id.front() ) ) - { - try - { +template +optional maybe_id(const string &name_or_id) { + if (std::isdigit(name_or_id.front())) { + try { return fc::variant(name_or_id, 1).as(1); - } - catch (const fc::exception&) - { // not an ID + } catch (const fc::exception &) { // not an ID } } return optional(); } -std::string object_id_to_string(object_id_type id) -{ - std::string object_id = fc::to_string(id.space()) - + "." + fc::to_string(id.type()) - + "." + fc::to_string(id.instance()); +std::string object_id_to_string(object_id_type id) { + std::string object_id = fc::to_string(id.space()) + "." + fc::to_string(id.type()) + "." + fc::to_string(id.instance()); return object_id; } @@ -170,14 +162,17 @@ public: // Witnesses vector> get_witnesses(const vector &witness_ids) const; + fc::optional get_witness_by_account_id(account_id_type account) const; fc::optional get_witness_by_account(const std::string account_id_or_name) const; map lookup_witness_accounts(const string &lower_bound_name, uint32_t limit) const; uint64_t get_witness_count() const; // Committee members vector> get_committee_members(const vector &committee_member_ids) const; + fc::optional get_committee_member_by_account_id(account_id_type account) const; fc::optional get_committee_member_by_account(const std::string account_id_or_name) const; map lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const; + uint64_t get_committee_member_count() const; // SON members vector> get_sons(const vector &son_ids) const; @@ -200,22 +195,24 @@ public: // Workers vector> get_workers(const vector &witness_ids) const; + vector get_workers_by_account_id(account_id_type account) const; vector get_workers_by_account(const std::string account_id_or_name) const; + map lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const; + uint64_t get_worker_count() const; // Votes vector lookup_vote_ids(const vector &votes) const; vector get_votes_ids(const string &account_name_or_id) const; - template - vector get_votes_objects(const vector &votes, unsigned int variant_max_depth = 1) const - { - static_assert( std::is_base_of::value, "Type must be an index type" ); + template + vector get_votes_objects(const vector &votes, unsigned int variant_max_depth = 1) const { + static_assert(std::is_base_of::value, "Type must be an index type"); vector result; const auto &idx = _db.get_index_type().indices().template get(); for (auto id : votes) { auto itr = idx.find(id); if (itr != idx.end()) - result.emplace_back(variant(*itr,variant_max_depth)); + result.emplace_back(variant(*itr, variant_max_depth)); } return result; } @@ -292,6 +289,8 @@ public: uint32_t api_limit_lookup_accounts = 1000; uint32_t api_limit_lookup_witness_accounts = 1000; uint32_t api_limit_lookup_committee_member_accounts = 1000; + uint32_t api_limit_lookup_son_accounts = 1000; + uint32_t api_limit_lookup_worker_accounts = 1000; uint32_t api_limit_get_trade_history = 100; uint32_t api_limit_get_trade_history_by_sequence = 100; @@ -1611,17 +1610,25 @@ vector> database_api_impl::get_witnesses(const vector database_api::get_witness_by_account_id(account_id_type account) const { + return my->get_witness_by_account_id(account); +} + +fc::optional database_api_impl::get_witness_by_account_id(account_id_type account) const { + const auto &idx = _db.get_index_type().indices().get(); + auto itr = idx.find(account); + if (itr != idx.end()) + return *itr; + return {}; +} + fc::optional database_api::get_witness_by_account(const std::string account_id_or_name) const { return my->get_witness_by_account(account_id_or_name); } fc::optional database_api_impl::get_witness_by_account(const std::string account_id_or_name) const { - const auto &idx = _db.get_index_type().indices().get(); const account_id_type account = get_account_from_string(account_id_or_name)->id; - auto itr = idx.find(account); - if (itr != idx.end()) - return *itr; - return {}; + return get_witness_by_account_id(account); } map database_api::lookup_witness_accounts(const string &lower_bound_name, uint32_t limit) const { @@ -1682,17 +1689,25 @@ vector> database_api_impl::get_committee_membe return result; } +fc::optional database_api::get_committee_member_by_account_id(account_id_type account) const { + return my->get_committee_member_by_account_id(account); +} + +fc::optional database_api_impl::get_committee_member_by_account_id(account_id_type account) const { + const auto &idx = _db.get_index_type().indices().get(); + auto itr = idx.find(account); + if (itr != idx.end()) + return *itr; + return {}; +} + fc::optional database_api::get_committee_member_by_account(const std::string account_id_or_name) const { return my->get_committee_member_by_account(account_id_or_name); } fc::optional database_api_impl::get_committee_member_by_account(const std::string account_id_or_name) const { - const auto &idx = _db.get_index_type().indices().get(); const account_id_type account = get_account_from_string(account_id_or_name)->id; - auto itr = idx.find(account); - if (itr != idx.end()) - return *itr; - return {}; + return get_committee_member_by_account_id(account); } map database_api::lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const { @@ -1723,6 +1738,14 @@ map database_api_impl::lookup_committee_member return committee_members_by_account_name; } +uint64_t database_api::get_committee_member_count() const { + return my->get_committee_member_count(); +} + +uint64_t database_api_impl::get_committee_member_count() const { + return _db.get_index_type().indices().size(); +} + ////////////////////////////////////////////////////////////////////// // // // SON members // @@ -1771,7 +1794,10 @@ map database_api::lookup_son_accounts(const string &lower_b } map database_api_impl::lookup_son_accounts(const string &lower_bound_name, uint32_t limit) const { - FC_ASSERT(limit <= 1000); + FC_ASSERT(limit <= api_limit_lookup_son_accounts, + "Number of querying accounts can not be greater than ${configured_limit}", + ("configured_limit", api_limit_lookup_son_accounts)); + const auto &sons_by_id = _db.get_index_type().indices().get(); // we want to order sons by account name, but that name is in the account object @@ -1927,10 +1953,22 @@ vector> database_api::get_workers(const vectorget_workers(worker_ids); } +vector database_api::get_workers_by_account_id(account_id_type account) const { + return my->get_workers_by_account_id(account); +} + vector database_api::get_workers_by_account(const std::string account_id_or_name) const { return my->get_workers_by_account(account_id_or_name); } +map database_api::lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const { + return my->lookup_worker_accounts(lower_bound_name, limit); +} + +uint64_t database_api::get_worker_count() const { + return my->get_worker_count(); +} + vector> database_api_impl::get_workers(const vector &worker_ids) const { vector> result; result.reserve(worker_ids.size()); @@ -1943,9 +1981,8 @@ vector> database_api_impl::get_workers(const vector database_api_impl::get_workers_by_account(const std::string account_id_or_name) const { +vector database_api_impl::get_workers_by_account_id(account_id_type account) const { const auto &idx = _db.get_index_type().indices().get(); - const account_id_type account = get_account_from_string(account_id_or_name)->id; auto itr = idx.find(account); vector result; @@ -1957,6 +1994,40 @@ vector database_api_impl::get_workers_by_account(const std::strin return result; } +vector database_api_impl::get_workers_by_account(const std::string account_id_or_name) const { + const account_id_type account = get_account_from_string(account_id_or_name)->id; + return get_workers_by_account_id(account); +} + +map database_api_impl::lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const { + FC_ASSERT(limit <= api_limit_lookup_worker_accounts, + "Number of querying accounts can not be greater than ${configured_limit}", + ("configured_limit", api_limit_lookup_worker_accounts)); + + const auto &workers_by_id = _db.get_index_type().indices().get(); + + // we want to order workers by account name, but that name is in the account object + // so the worker_index doesn't have a quick way to access it. + // get all the names and look them all up, sort them, then figure out what + // records to return. This could be optimized, but we expect the + // number of witnesses to be few and the frequency of calls to be rare + std::map workers_by_account_name; + for (const worker_object &worker : workers_by_id) + if (auto account_iter = _db.find(worker.worker_account)) + if (account_iter->name >= lower_bound_name) // we can ignore anything below lower_bound_name + workers_by_account_name.insert(std::make_pair(account_iter->name, worker.id)); + + auto end_iter = workers_by_account_name.begin(); + while (end_iter != workers_by_account_name.end() && limit--) + ++end_iter; + workers_by_account_name.erase(end_iter, workers_by_account_name.end()); + return workers_by_account_name; +} + +uint64_t database_api_impl::get_worker_count() const { + return _db.get_index_type().indices().size(); +} + ////////////////////////////////////////////////////////////////////// // // // Votes // @@ -2049,8 +2120,7 @@ vector database_api_impl::get_votes_ids(const string &account_name const account_object *account = get_account_from_string(account_name_or_id); //! Iterate throug votes and fill vector - for( const auto& vote : account->options.votes ) - { + for (const auto &vote : account->options.votes) { result.emplace_back(vote); } @@ -2060,16 +2130,16 @@ vector database_api_impl::get_votes_ids(const string &account_name votes_info database_api_impl::get_votes(const string &account_name_or_id) const { votes_info result; - const auto& votes_ids = get_votes_ids(account_name_or_id); - const auto& committee_ids = get_votes_objects(votes_ids); - const auto& witness_ids = get_votes_objects(votes_ids); - const auto& for_worker_ids = get_votes_objects(votes_ids); - const auto& against_worker_ids = get_votes_objects(votes_ids); - const auto& son_ids = get_votes_objects(votes_ids, 5); + const auto &votes_ids = get_votes_ids(account_name_or_id); + const auto &committee_ids = get_votes_objects(votes_ids); + const auto &witness_ids = get_votes_objects(votes_ids); + const auto &for_worker_ids = get_votes_objects(votes_ids); + const auto &against_worker_ids = get_votes_objects(votes_ids); + const auto &son_ids = get_votes_objects(votes_ids, 5); //! Fill votes info - if(!committee_ids.empty()) { - vector< votes_info_object > votes_for_committee_members; + if (!committee_ids.empty()) { + vector> votes_for_committee_members; votes_for_committee_members.reserve(committee_ids.size()); for (const auto &committee : committee_ids) { const auto &committee_obj = committee.as(2); @@ -2078,8 +2148,8 @@ votes_info database_api_impl::get_votes(const string &account_name_or_id) const result.votes_for_committee_members = std::move(votes_for_committee_members); } - if(!witness_ids.empty()) { - vector< votes_info_object > votes_for_witnesses; + if (!witness_ids.empty()) { + vector> votes_for_witnesses; votes_for_witnesses.reserve(witness_ids.size()); for (const auto &witness : witness_ids) { const auto &witness_obj = witness.as(2); @@ -2088,8 +2158,8 @@ votes_info database_api_impl::get_votes(const string &account_name_or_id) const result.votes_for_witnesses = std::move(votes_for_witnesses); } - if(!for_worker_ids.empty()) { - vector< votes_info_object > votes_for_workers; + if (!for_worker_ids.empty()) { + vector> votes_for_workers; votes_for_workers.reserve(for_worker_ids.size()); for (const auto &for_worker : for_worker_ids) { const auto &for_worker_obj = for_worker.as(2); @@ -2098,8 +2168,8 @@ votes_info database_api_impl::get_votes(const string &account_name_or_id) const result.votes_for_workers = std::move(votes_for_workers); } - if(!against_worker_ids.empty()) { - vector< votes_info_object > votes_against_workers; + if (!against_worker_ids.empty()) { + vector> votes_against_workers; votes_against_workers.reserve(against_worker_ids.size()); for (const auto &against_worker : against_worker_ids) { const auto &against_worker_obj = against_worker.as(2); @@ -2108,8 +2178,8 @@ votes_info database_api_impl::get_votes(const string &account_name_or_id) const result.votes_against_workers = std::move(votes_against_workers); } - if(!son_ids.empty()) { - vector< votes_info_object > votes_for_sons; + if (!son_ids.empty()) { + vector> votes_for_sons; votes_for_sons.reserve(son_ids.size()); for (const auto &son : son_ids) { const auto &son_obj = son.as(6); @@ -2125,10 +2195,9 @@ vector database_api_impl::get_voters_by_id(const vote_id_type &v vector result; //! We search all accounts that have voted for this vote_id - const auto& account_index = _db.get_index_type().indices().get(); - for( const auto& account: account_index ) - { - if(account.options.votes.count(vote_id) != 0) + const auto &account_index = _db.get_index_type().indices().get(); + for (const auto &account : account_index) { + if (account.options.votes.count(vote_id) != 0) result.emplace_back(account); } @@ -2143,83 +2212,78 @@ voters_info database_api_impl::get_voters(const string &account_name_or_id) cons std::string owner_account_id; //! Check if we have account by name - const auto& account_object = get_account_by_name(account_name_or_id); - if(account_object) { + const auto &account_object = get_account_by_name(account_name_or_id); + if (account_object) { //! It is account - owner_account_id = object_id_to_string( account_object->get_id() ); + owner_account_id = object_id_to_string(account_object->get_id()); owner_account_found = true; - } - else { + } else { //! Check if we have account id - const auto& account_id = maybe_id(account_name_or_id); - if(account_id) { + const auto &account_id = maybe_id(account_name_or_id); + if (account_id) { //! It may be account id - const auto& account_objects = get_accounts({account_name_or_id}); - if(!account_objects.empty()){ - const auto& account_object = account_objects.front(); - if(account_object) { + const auto &account_objects = get_accounts({account_name_or_id}); + if (!account_objects.empty()) { + const auto &account_object = account_objects.front(); + if (account_object) { //! It is account object - owner_account_id = object_id_to_string( account_object->get_id() ); + owner_account_id = object_id_to_string(account_object->get_id()); owner_account_found = true; } } - } - else { + } else { //! Check if we have committee member id - const auto& committee_member_id = maybe_id(account_name_or_id); - if(committee_member_id) { + const auto &committee_member_id = maybe_id(account_name_or_id); + if (committee_member_id) { //! It may be committee member id - const auto& committee_member_objects = get_committee_members({*committee_member_id}); - if(!committee_member_objects.empty()){ - const auto& committee_member_object = committee_member_objects.front(); - if(committee_member_object) { + const auto &committee_member_objects = get_committee_members({*committee_member_id}); + if (!committee_member_objects.empty()) { + const auto &committee_member_object = committee_member_objects.front(); + if (committee_member_object) { //! It is committee member object - owner_account_id = object_id_to_string( committee_member_object->committee_member_account ); + owner_account_id = object_id_to_string(committee_member_object->committee_member_account); owner_account_found = true; } } - } - else { + } else { //! Check if we have witness id - const auto& witness_id = maybe_id(account_name_or_id); - if(witness_id) { + const auto &witness_id = maybe_id(account_name_or_id); + if (witness_id) { //! It may be witness id - const auto& witness_objects = get_witnesses({*witness_id}); - if(!witness_objects.empty()){ - const auto& witness_object = witness_objects.front(); - if(witness_object) { + const auto &witness_objects = get_witnesses({*witness_id}); + if (!witness_objects.empty()) { + const auto &witness_object = witness_objects.front(); + if (witness_object) { //! It is witness object - owner_account_id = object_id_to_string( witness_object->witness_account ); + owner_account_id = object_id_to_string(witness_object->witness_account); owner_account_found = true; } } - } - else { + } else { //! Check if we have worker id - const auto& worker_id = maybe_id(account_name_or_id); - if(worker_id) { + const auto &worker_id = maybe_id(account_name_or_id); + if (worker_id) { //! It may be worker id - const auto& worker_objects = get_workers({*worker_id}); - if(!worker_objects.empty()){ - const auto& worker_object = worker_objects.front(); - if(worker_object) { + const auto &worker_objects = get_workers({*worker_id}); + if (!worker_objects.empty()) { + const auto &worker_object = worker_objects.front(); + if (worker_object) { //! It is worker object - owner_account_id = object_id_to_string( worker_object->worker_account ); + owner_account_id = object_id_to_string(worker_object->worker_account); owner_account_found = true; } } - } - else { + } else { //! Check if we have son id - const auto& son_id = maybe_id(account_name_or_id); - if(son_id) { + const auto &son_id = maybe_id(account_name_or_id); + if (son_id) { //! It may be son id - const auto& son_objects = get_sons({*son_id}); - if(!son_objects.empty()){ - const auto& son_object = son_objects.front(); - if(son_object) { + const auto &son_objects = get_sons({*son_id}); + if (!son_objects.empty()) { + const auto &son_object = son_objects.front(); + if (son_object) { //! It is son object - owner_account_id = object_id_to_string( son_object->son_account ); + owner_account_id = object_id_to_string(son_object->son_account); owner_account_found = true; } } @@ -2231,41 +2295,41 @@ voters_info database_api_impl::get_voters(const string &account_name_or_id) cons } //! We didn't find who it was - if(!owner_account_found) + if (!owner_account_found) FC_THROW_EXCEPTION(database_query_exception, "Wrong account_name_or_id: ${account_name_or_id}", ("account_name_or_id", account_name_or_id)); //! Fill voters_info - const auto& committee_member_object = get_committee_member_by_account(owner_account_id); - const auto& witness_object = get_witness_by_account(owner_account_id); - const auto& worker_objects = get_workers_by_account(owner_account_id); - const auto& son_object = get_son_by_account(owner_account_id); + const auto &committee_member_object = get_committee_member_by_account(owner_account_id); + const auto &witness_object = get_witness_by_account(owner_account_id); + const auto &worker_objects = get_workers_by_account(owner_account_id); + const auto &son_object = get_son_by_account(owner_account_id); //! Info for committee member voters - if(committee_member_object) { - const auto& committee_member_voters = get_voters_by_id(committee_member_object->vote_id); + if (committee_member_object) { + const auto &committee_member_voters = get_voters_by_id(committee_member_object->vote_id); voters_info_object voters_for_committee_member; voters_for_committee_member.vote_id = committee_member_object->vote_id; voters_for_committee_member.voters.reserve(committee_member_voters.size()); - for(const auto& voter: committee_member_voters) { + for (const auto &voter : committee_member_voters) { voters_for_committee_member.voters.emplace_back(voter.get_id()); } result.voters_for_committee_member = std::move(voters_for_committee_member); } //! Info for witness voters - if(witness_object) { - const auto& witness_voters = get_voters_by_id(witness_object->vote_id); + if (witness_object) { + const auto &witness_voters = get_voters_by_id(witness_object->vote_id); voters_info_object voters_for_witness; voters_for_witness.vote_id = witness_object->vote_id; voters_for_witness.voters.reserve(witness_voters.size()); - for(const auto& voter: witness_voters) { + for (const auto &voter : witness_voters) { voters_for_witness.voters.emplace_back(voter.get_id()); } result.voters_for_witness = std::move(voters_for_witness); } //! Info for worker voters - if(!worker_objects.empty()) { + if (!worker_objects.empty()) { vector voters_for_workers(worker_objects.size()); vector voters_against_workers(worker_objects.size()); for (const auto &worker_object : worker_objects) { @@ -2292,12 +2356,12 @@ voters_info database_api_impl::get_voters(const string &account_name_or_id) cons } //! Info for son voters - if(son_object) { - const auto& son_voters = get_voters_by_id(son_object->vote_id); + if (son_object) { + const auto &son_voters = get_voters_by_id(son_object->vote_id); voters_info_object voters_for_son; voters_for_son.vote_id = son_object->vote_id; voters_for_son.voters.reserve(son_voters.size()); - for(const auto& voter: son_voters) { + for (const auto &voter : son_voters) { voters_for_son.voters.emplace_back(voter.get_id()); } result.voters_for_son = std::move(voters_for_son); diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 0c9d10f2..93a2b88c 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -56,8 +56,8 @@ #include #include #include -#include #include +#include #include @@ -560,6 +560,13 @@ public: * @param account The ID of the account whose witness should be retrieved * @return The witness object, or null if the account does not have a witness */ + fc::optional get_witness_by_account_id(account_id_type account) const; + + /** + * @brief Get the witness owned by a given account + * @param account_id_or_name The ID or name of the account whose witness should be retrieved + * @return The witness object, or null if the account does not have a witness + */ fc::optional get_witness_by_account(const std::string account_name_or_id) const; /** @@ -588,6 +595,13 @@ public: */ vector> get_committee_members(const vector &committee_member_ids) const; + /** + * @brief Get the committee_member owned by a given account + * @param account The ID of the account whose committee_member should be retrieved + * @return The committee_member object, or null if the account does not have a committee_member + */ + fc::optional get_committee_member_by_account_id(account_id_type account) const; + /** * @brief Get the committee_member owned by a given account * @param account_id_or_name The ID or name of the account whose committee_member should be retrieved @@ -603,6 +617,11 @@ public: */ map lookup_committee_member_accounts(const string &lower_bound_name, uint32_t limit) const; + /** + * @brief Get the total number of committee_members registered with the blockchain + */ + uint64_t get_committee_member_count() const; + ///////////////// // SON members // ///////////////// @@ -625,7 +644,7 @@ public: /** * @brief Get the SON owned by a given account - * @param account The ID of the account whose SON should be retrieved + * @param account_id_or_name The ID of the account whose SON should be retrieved * @return The SON object, or null if the account does not have a SON */ fc::optional get_son_by_account(const std::string account_id_or_name) const; @@ -722,11 +741,31 @@ public: /** * @brief Return the worker objects associated with this account. - * @param account_id_or_name The ID or name of the account whose worker should be retrieved + * @param account The ID of the account whose workers should be retrieved + * @return The worker object or null if the account does not have a worker + */ + vector get_workers_by_account_id(account_id_type account) const; + + /** + * @brief Return the worker objects associated with this account. + * @param account_id_or_name The ID or name of the account whose workers should be retrieved * @return The worker object or null if the account does not have a worker */ vector get_workers_by_account(const std::string account_id_or_name) const; + /** + * @brief Get names and IDs for registered workers + * @param lower_bound_name Lower bound of the first name to return + * @param limit Maximum number of results to return -- must not exceed 1000 + * @return Map of worker names to corresponding IDs + */ + map lookup_worker_accounts(const string &lower_bound_name, uint32_t limit) const; + + /** + * @brief Get the total number of workers registered with the blockchain + */ + uint64_t get_worker_count() const; + /////////// // Votes // /////////// @@ -1086,14 +1125,17 @@ FC_API(graphene::app::database_api, // Witnesses (get_witnesses) + (get_witness_by_account_id) (get_witness_by_account) (lookup_witness_accounts) (get_witness_count) // Committee members (get_committee_members) + (get_committee_member_by_account_id) (get_committee_member_by_account) (lookup_committee_member_accounts) + (get_committee_member_count) // SON members (get_sons) @@ -1116,7 +1158,10 @@ FC_API(graphene::app::database_api, // Workers (get_workers) + (get_workers_by_account_id) (get_workers_by_account) + (lookup_worker_accounts) + (get_worker_count) // Votes (lookup_vote_ids) diff --git a/libraries/fc b/libraries/fc index 86b77c6e..1cc74059 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 86b77c6eb450f97a29c627d3fa9728e25bed933a +Subproject commit 1cc740598f5b7ec480ac76f60e19d0ccb1e1ac97 diff --git a/libraries/plugins/peerplays_sidechain/CMakeLists.txt b/libraries/plugins/peerplays_sidechain/CMakeLists.txt index bb74df29..66795016 100755 --- a/libraries/plugins/peerplays_sidechain/CMakeLists.txt +++ b/libraries/plugins/peerplays_sidechain/CMakeLists.txt @@ -23,19 +23,11 @@ add_library( peerplays_sidechain ) if (ENABLE_DEV_FEATURES) - set(ENABLE_MULTIPLE_SONS 1) set(ENABLE_PEERPLAYS_ASSET_DEPOSITS 1) endif() unset(ENABLE_DEV_FEATURES) unset(ENABLE_DEV_FEATURES CACHE) -if (ENABLE_MULTIPLE_SONS) - message ("Multiple SONs per software instance are supported") - target_compile_definitions(peerplays_sidechain PRIVATE ENABLE_MULTIPLE_SONS) -endif() -unset(ENABLE_MULTIPLE_SONS) -unset(ENABLE_MULTIPLE_SONS CACHE) - if (ENABLE_PEERPLAYS_ASSET_DEPOSITS) message ("Depositing Peerplays assets enabled") target_compile_definitions(peerplays_sidechain PRIVATE ENABLE_PEERPLAYS_ASSET_DEPOSITS) diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp index 9b08bc15..13eaf9a6 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler_bitcoin.hpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 67a1783f..26976676 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -176,12 +176,6 @@ void peerplays_sidechain_plugin_impl::plugin_initialize(const boost::program_opt } config_ready_son = config_ready_son && !sons.empty(); -#ifndef ENABLE_MULTIPLE_SONS - if (sons.size() > 1) { - FC_THROW("Invalid configuration, multiple SON IDs provided"); - } -#endif - if (options.count("peerplays-private-key")) { const std::vector key_id_to_wif_pair_strings = options["peerplays-private-key"].as>(); for (const std::string &key_id_to_wif_pair_string : key_id_to_wif_pair_strings) { diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 1ad0d9c8..04a0e604 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -871,16 +871,11 @@ zmq_listener::zmq_listener(std::string _ip, uint32_t _zmq) : std::vector zmq_listener::receive_multipart() { std::vector msgs; - int32_t more; - size_t more_size = sizeof(more); - while (true) { - zmq::message_t msg; - socket.recv(&msg, 0); - socket.getsockopt(ZMQ_RCVMORE, &more, &more_size); - - if (!more) - break; - msgs.push_back(std::move(msg)); + auto res = zmq::recv_multipart(socket, std::back_inserter(msgs)); + FC_ASSERT(res); + if (3 != *res) { + elog("zmq::recv_multipart returned: ${res}", ("res", *res)); + throw zmq::error_t(); } return msgs; @@ -902,6 +897,7 @@ void zmq_listener::handle_zmq() { const auto block_hash = boost::algorithm::hex(std::string(static_cast(msg[1].data()), msg[1].size())); event_received(block_hash); } catch (zmq::error_t &e) { + elog("handle_zmq recv_multipart exception ${str}", ("str", e.what())); } } } diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 4df3dea6..4b5013a8 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1346,6 +1346,21 @@ class wallet_api */ map list_committee_members(const string& lowerbound, uint32_t limit); + /** Lists all workers in the blockchain. + * This returns a list of all account names that own worker, and the associated worker id, + * sorted by name. This lists workers whether they are currently voted in or not. + * + * Use the \c lowerbound and limit parameters to page through the list. To retrieve all workers, + * start by setting \c lowerbound to the empty string \c "", and then each iteration, pass + * the last worker name returned as the \c lowerbound for the next \c list_workers() call. + * + * @param lowerbound the name of the first worker to return. If the named worker does not exist, + * the list will start at the worker that comes after \c lowerbound + * @param limit the maximum number of worker to return (max: 1000) + * @returns a list of worker mapping worker names to worker ids + */ + map list_workers(const string& lowerbound, uint32_t limit); + /** Returns information about the given SON. * @param owner_account the name or id of the SON account owner, or the id of the SON * @returns the information about the SON stored in the block chain @@ -1370,6 +1385,12 @@ class wallet_api */ committee_member_object get_committee_member(string owner_account); + /** Returns information about the given worker. + * @param owner_account the name or id of the worker account owner, or the id of the worker + * @returns the information about the workers stored in the block chain + */ + vector get_workers(string owner_account); + /** Creates a SON object owned by the given account. * @@ -2658,8 +2679,10 @@ FC_API( graphene::wallet::wallet_api, (get_witness) (is_witness) (get_committee_member) + (get_workers) (list_witnesses) (list_committee_members) + (list_workers) (create_son) (try_create_son) (update_son) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 0d865c78..71f6bc32 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -749,7 +749,7 @@ public: { std::string account_id = account_id_to_string(id); auto rec = _remote_db->get_accounts({account_id}).front(); - FC_ASSERT(rec); + FC_ASSERT(rec, "Accout id: ${account_id} doesn't exist", ("account_id", account_id)); return *rec; } account_object get_account(string account_name_or_id) const @@ -762,7 +762,7 @@ public: return get_account(*id); } else { auto rec = _remote_db->lookup_account_names({account_name_or_id}).front(); - FC_ASSERT( rec && rec->name == account_name_or_id ); + FC_ASSERT( rec && rec->name == account_name_or_id, "Account name or id: ${account_name_or_id} doesn't exist", ("account_name_or_id",account_name_or_id ) ); return *rec; } } @@ -1961,6 +1961,49 @@ public: FC_CAPTURE_AND_RETHROW( (owner_account) ) } + vector get_workers(string owner_account) + { + try + { + fc::optional worker_id = maybe_id(owner_account); + if (worker_id) + { + std::vector ids_to_get; + ids_to_get.push_back(*worker_id); + std::vector> worker_objects = _remote_db->get_workers(ids_to_get); + + if(!worker_objects.empty()) { + std::vector result; + for (const auto &worker_object : worker_objects) { + if (worker_object) + result.emplace_back(*worker_object); + } + return result; + } + else + FC_THROW("No workers is registered for id ${id}", ("id", owner_account)); + } + else + { + // then maybe it's the owner account + try + { + std::string owner_account_id = account_id_to_string(get_account_id(owner_account)); + auto workers = _remote_db->get_workers_by_account(owner_account_id); + if (!workers.empty()) + return workers; + else + FC_THROW("No workers is registered for account ${account}", ("account", owner_account)); + } + catch (const fc::exception&) + { + FC_THROW("No account or worker named ${account}", ("account", owner_account)); + } + } + } + FC_CAPTURE_AND_RETHROW( (owner_account) ) + } + bool is_witness(string owner_account) { try @@ -4471,6 +4514,7 @@ asset wallet_api::get_lottery_balance( asset_id_type lottery_id )const vector wallet_api::get_account_history(string name, int limit) const { + FC_ASSERT(my->get_account(name).name == name, "Account name: ${account_name} doesn't exist", ("account_name", name)); vector result; while (limit > 0) @@ -4525,6 +4569,8 @@ vector wallet_api::get_relative_account_history(string name, u { FC_ASSERT( start > 0 || limit <= 100 ); + FC_ASSERT(my->get_account(name).name == name, "Account name: ${account_name} doesn't exist", ("account_name", name)); + vector result; @@ -4700,7 +4746,7 @@ account_object wallet_api::get_account(string account_name_or_id) const asset_object wallet_api::get_asset(string asset_name_or_id) const { auto a = my->find_asset(asset_name_or_id); - FC_ASSERT(a); + FC_ASSERT(a, "Asset name or id: ${asset_name_or_id} doesn't exist", ("asset_name_or_id", asset_name_or_id) ); return *a; } @@ -4723,7 +4769,7 @@ asset_id_type wallet_api::get_asset_id(string asset_symbol_or_id) const bool wallet_api::import_key(string account_name_or_id, string wif_key) { - FC_ASSERT(!is_locked()); + FC_ASSERT(!is_locked(), "Wallet is locked, please unlock to get all operations available"); // backup wallet fc::optional optional_private_key = wif_to_key(wif_key); if (!optional_private_key) @@ -4742,7 +4788,7 @@ bool wallet_api::import_key(string account_name_or_id, string wif_key) map wallet_api::import_accounts( string filename, string password ) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); FC_ASSERT( fc::exists( filename ) ); const auto imported_keys = fc::json::from_file( filename ); @@ -4812,7 +4858,7 @@ map wallet_api::import_accounts( string filename, string password bool wallet_api::import_account_keys( string filename, string password, string src_account_name, string dest_account_name ) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); FC_ASSERT( fc::exists( filename ) ); bool is_my_account = false; @@ -5027,6 +5073,11 @@ map wallet_api::list_committee_members(const st return my->_remote_db->lookup_committee_member_accounts(lowerbound, limit); } +map wallet_api::list_workers(const string& lowerbound, uint32_t limit) +{ + return my->_remote_db->lookup_worker_accounts(lowerbound, limit); +} + son_object wallet_api::get_son(string owner_account) { return my->get_son(owner_account); @@ -5047,6 +5098,11 @@ committee_member_object wallet_api::get_committee_member(string owner_account) return my->get_committee_member(owner_account); } +vector wallet_api::get_workers(string owner_account) +{ + return my->get_workers(owner_account); +} + signed_transaction wallet_api::create_vesting_balance(string owner_account, string amount, string asset_symbol, @@ -5351,13 +5407,13 @@ operation wallet_api::get_prototype_operation(string operation_name) void wallet_api::dbg_make_uia(string creator, string symbol) { - FC_ASSERT(!is_locked()); + FC_ASSERT(!is_locked(), "Wallet is locked, please unlock to get all operations available"); my->dbg_make_uia(creator, symbol); } void wallet_api::dbg_make_mia(string creator, string symbol) { - FC_ASSERT(!is_locked()); + FC_ASSERT(!is_locked(), "Wallet is locked, please unlock to get all operations available"); my->dbg_make_mia(creator, symbol); } @@ -5393,7 +5449,7 @@ vector< variant > wallet_api::network_get_connected_peers() void wallet_api::flood_network(string prefix, uint32_t number_of_transactions) { - FC_ASSERT(!is_locked()); + FC_ASSERT(!is_locked(), "Wallet is locked, please unlock to get all operations available"); my->flood_network(prefix, number_of_transactions); } @@ -5872,13 +5928,13 @@ signed_transaction wallet_api::buy( string buyer_account, signed_transaction wallet_api::borrow_asset(string seller_name, string amount_to_sell, string asset_symbol, string amount_of_collateral, bool broadcast) { - FC_ASSERT(!is_locked()); + FC_ASSERT(!is_locked(), "Wallet is locked, please unlock to get all operations available"); return my->borrow_asset(seller_name, amount_to_sell, asset_symbol, amount_of_collateral, broadcast); } signed_transaction wallet_api::cancel_order(object_id_type order_id, bool broadcast) { - FC_ASSERT(!is_locked()); + FC_ASSERT(!is_locked(), "Wallet is locked, please unlock to get all operations available"); return my->cancel_order(order_id, broadcast); } @@ -5928,7 +5984,7 @@ map wallet_api::get_blind_accounts()const } map wallet_api::get_my_blind_accounts()const { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); map result; for( const auto& item : my->_wallet.labeled_keys ) { @@ -5940,7 +5996,7 @@ map wallet_api::get_my_blind_accounts()const public_key_type wallet_api::create_blind_account( string label, string brain_key ) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); auto label_itr = my->_wallet.labeled_keys.get().find(label); if( label_itr != my->_wallet.labeled_keys.get().end() ) @@ -6068,7 +6124,7 @@ blind_confirmation wallet_api::blind_transfer_help( string from_key_or_label, blind_confirmation confirm; try { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); public_key_type from_key = get_public_key(from_key_or_label); public_key_type to_key = get_public_key(to_key_or_label); @@ -6237,7 +6293,7 @@ blind_confirmation wallet_api::transfer_to_blind( string from_account_id_or_name vector> to_amounts, bool broadcast ) { try { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); idump((to_amounts)); blind_confirmation confirm; @@ -6317,7 +6373,7 @@ blind_confirmation wallet_api::transfer_to_blind( string from_account_id_or_name blind_receipt wallet_api::receive_blind_transfer( string confirmation_receipt, string opt_from, string opt_memo ) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); stealth_confirmation conf(confirmation_receipt); FC_ASSERT( conf.to ); @@ -6459,7 +6515,7 @@ signed_transaction wallet_api::propose_create_sport( internationalized_string_type name, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; sport_create_operation sport_create_op; @@ -6487,7 +6543,7 @@ signed_transaction wallet_api::propose_update_sport( fc::optional name, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; sport_update_operation sport_update_op; @@ -6515,7 +6571,7 @@ signed_transaction wallet_api::propose_delete_sport( sport_id_type sport_id, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; sport_delete_operation sport_delete_op; @@ -6543,7 +6599,7 @@ signed_transaction wallet_api::propose_create_event_group( sport_id_type sport_id, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; event_group_create_operation event_group_create_op; @@ -6573,7 +6629,7 @@ signed_transaction wallet_api::propose_update_event_group( fc::optional name, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; event_group_update_operation event_group_update_op; @@ -6602,7 +6658,7 @@ signed_transaction wallet_api::propose_delete_event_group( event_group_id_type event_group, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; event_group_delete_operation event_group_delete_op; @@ -6632,7 +6688,7 @@ signed_transaction wallet_api::propose_create_event( event_group_id_type event_group_id, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; event_create_operation event_create_op; @@ -6667,7 +6723,7 @@ signed_transaction wallet_api::propose_update_event( fc::optional start_time, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; event_update_operation event_update_op; @@ -6700,7 +6756,7 @@ signed_transaction wallet_api::propose_create_betting_market_rules( internationalized_string_type description, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; betting_market_rules_create_operation betting_market_rules_create_op; @@ -6730,7 +6786,7 @@ signed_transaction wallet_api::propose_update_betting_market_rules( fc::optional description, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; betting_market_rules_update_operation betting_market_rules_update_op; @@ -6762,7 +6818,7 @@ signed_transaction wallet_api::propose_create_betting_market_group( asset_id_type asset_id, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; betting_market_group_create_operation betting_market_group_create_op; @@ -6795,7 +6851,7 @@ signed_transaction wallet_api::propose_update_betting_market_group( fc::optional status, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; betting_market_group_update_operation betting_market_group_update_op; @@ -6827,7 +6883,7 @@ signed_transaction wallet_api::propose_create_betting_market( internationalized_string_type payout_condition, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; betting_market_create_operation betting_market_create_op; @@ -6859,7 +6915,7 @@ signed_transaction wallet_api::propose_update_betting_market( fc::optional payout_condition, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked() , "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; betting_market_update_operation betting_market_update_op; @@ -6891,7 +6947,7 @@ signed_transaction wallet_api::place_bet(string betting_account, double backer_multiplier, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); fc::optional asset_obj = get_asset(asset_symbol); FC_ASSERT(asset_obj, "Could not find asset matching ${asset}", ("asset", asset_symbol)); @@ -6916,7 +6972,7 @@ signed_transaction wallet_api::cancel_bet(string betting_account, bet_id_type bet_id, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; @@ -6939,7 +6995,7 @@ signed_transaction wallet_api::propose_resolve_betting_market_group( const std::map& resolutions, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; betting_market_group_resolve_operation betting_market_group_resolve_op; @@ -6967,7 +7023,7 @@ signed_transaction wallet_api::propose_cancel_betting_market_group( betting_market_group_id_type betting_market_group_id, bool broadcast /*= false*/) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); const chain_parameters& current_params = get_global_properties().parameters; betting_market_group_cancel_unmatched_bets_operation betting_market_group_cancel_unmatched_bets_op; @@ -6990,7 +7046,7 @@ signed_transaction wallet_api::propose_cancel_betting_market_group( signed_transaction wallet_api::tournament_create( string creator, tournament_options options, bool broadcast ) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); account_object creator_account_obj = get_account(creator); signed_transaction tx; @@ -7011,7 +7067,7 @@ signed_transaction wallet_api::tournament_join( string payer_account, string buy_in_asset_symbol, bool broadcast ) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); account_object payer_account_obj = get_account(payer_account); account_object player_account_obj = get_account(player_account); //graphene::chain::tournament_object tournament_obj = my->get_object(tournament_id); @@ -7038,7 +7094,7 @@ signed_transaction wallet_api::tournament_leave( string canceling_account, tournament_id_type tournament_id, bool broadcast) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); account_object player_account_obj = get_account(player_account); account_object canceling_account_obj = get_account(canceling_account); //graphene::chain::tournament_object tournament_obj = my->get_object(tournament_id); @@ -7083,7 +7139,7 @@ signed_transaction wallet_api::rps_throw(game_id_type game_id, rock_paper_scissors_gesture gesture, bool broadcast) { - FC_ASSERT( !is_locked() ); + FC_ASSERT( !is_locked(), "Wallet is locked, please unlock to get all operations available" ); // check whether the gesture is appropriate for the game we're playing graphene::chain::game_object game_obj = my->get_object(game_id); diff --git a/programs/cli_wallet/main.cpp b/programs/cli_wallet/main.cpp index 5a0ee3ba..e2f5a182 100644 --- a/programs/cli_wallet/main.cpp +++ b/programs/cli_wallet/main.cpp @@ -27,8 +27,18 @@ #include #include +#include +#include +#include +#include + +#include #include #include +#include +#include +#include +#include #include #include #include @@ -40,25 +50,14 @@ #include #include #include +#include #include #include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - #ifdef WIN32 -# include +#include #else -# include +#include #endif using namespace graphene::app; @@ -68,44 +67,57 @@ using namespace graphene::wallet; using namespace std; namespace bpo = boost::program_options; -int main( int argc, char** argv ) -{ +int main(int argc, char **argv) { try { boost::program_options::options_description opts; - opts.add_options() - ("help,h", "Print this help message and exit.") - ("version", "Display the version info and exit") - ("server-rpc-endpoint,s", bpo::value()->implicit_value("ws://127.0.0.1:8090"), "Server websocket RPC endpoint") - ("server-rpc-user,u", bpo::value(), "Server Username") - ("server-rpc-password,p", bpo::value(), "Server Password") - ("rpc-endpoint,r", bpo::value()->implicit_value("127.0.0.1:8091"), "Endpoint for wallet websocket RPC to listen on") - ("rpc-tls-endpoint,t", bpo::value()->implicit_value("127.0.0.1:8092"), "Endpoint for wallet websocket TLS RPC to listen on") - ("rpc-tls-certificate,c", bpo::value()->implicit_value("server.pem"), "PEM certificate for wallet websocket TLS RPC") - ("rpc-http-endpoint,H", bpo::value()->implicit_value("127.0.0.1:8093"), "Endpoint for wallet HTTP RPC to listen on") - ("daemon,d", "Run the wallet in daemon mode" ) - ("wallet-file,w", bpo::value()->implicit_value("wallet.json"), "wallet to load") - ("chain-id", bpo::value(), "chain ID to connect to"); + opts.add_options()("help,h", "Print this help message and exit."); + opts.add_options()("version,v", "Display the version info and exit"); + opts.add_options()("server-rpc-endpoint,s", bpo::value()->implicit_value("ws://127.0.0.1:8090"), "Server websocket RPC endpoint"); + opts.add_options()("server-rpc-user,u", bpo::value(), "Server Username"); + opts.add_options()("server-rpc-password,p", bpo::value(), "Server Password"); + opts.add_options()("rpc-endpoint,r", bpo::value()->implicit_value("127.0.0.1:8091"), "Endpoint for wallet websocket RPC to listen on"); + opts.add_options()("rpc-tls-endpoint,t", bpo::value()->implicit_value("127.0.0.1:8092"), "Endpoint for wallet websocket TLS RPC to listen on"); + opts.add_options()("rpc-tls-certificate,c", bpo::value()->implicit_value("server.pem"), "PEM certificate for wallet websocket TLS RPC"); + opts.add_options()("rpc-http-endpoint,H", bpo::value()->implicit_value("127.0.0.1:8093"), "Endpoint for wallet HTTP RPC to listen on"); + opts.add_options()("daemon,d", "Run the wallet in daemon mode"); + opts.add_options()("wallet-file,w", bpo::value()->implicit_value("wallet.json"), "wallet to load"); + opts.add_options()("chain-id", bpo::value(), "chain ID to connect to"); bpo::variables_map options; - bpo::store( bpo::parse_command_line(argc, argv, opts), options ); - - if( options.count("help") ) + try { + bpo::parsed_options po = bpo::command_line_parser(argc, argv).options(opts).allow_unregistered().run(); + std::vector unrecognized = bpo::collect_unrecognized(po.options, bpo::include_positional); + if (unrecognized.size() > 0) { + std::cout << "Unknown parameter(s): " << std::endl; + for (auto s : unrecognized) { + std::cout << " " << s << std::endl; + } + return 0; + } + bpo::store(po, options); + } + catch (const boost::program_options::invalid_command_line_syntax & e) + { + std::cout << e.what() << std::endl; + return 0; + } + + if (options.count("help")) { std::cout << opts << "\n"; return 0; } - if (options.count("version")) - { + if (options.count("version")) { std::string wallet_version(graphene::utilities::git_revision_description); const size_t pos = wallet_version.find('/'); - if( pos != std::string::npos && wallet_version.size() > pos ) - wallet_version = wallet_version.substr( pos + 1 ); - std::cerr << "Version: " << wallet_version << "\n"; - std::cerr << "Git Revision: " << graphene::utilities::git_revision_sha << "\n"; - std::cerr << "Built: " << __DATE__ " at " __TIME__ << "\n"; + if (pos != std::string::npos && wallet_version.size() > pos) + wallet_version = wallet_version.substr(pos + 1); + std::cout << "Version: " << wallet_version << "\n"; + std::cout << "Git Revision: " << graphene::utilities::git_revision_sha << "\n"; + std::cout << "Built: " << __DATE__ " at " __TIME__ << "\n"; std::cout << "SSL: " << OPENSSL_VERSION_TEXT << "\n"; std::cout << "Boost: " << boost::replace_all_copy(std::string(BOOST_LIB_VERSION), "_", ".") << "\n"; return 0; @@ -116,33 +128,33 @@ int main( int argc, char** argv ) fc::path log_dir = data_dir / "logs"; fc::file_appender::config ac; - ac.filename = log_dir / "rpc" / "rpc.log"; - ac.flush = true; - ac.rotate = true; - ac.rotation_interval = fc::hours( 1 ); - ac.rotation_limit = fc::days( 1 ); + ac.filename = log_dir / "rpc" / "rpc.log"; + ac.flush = true; + ac.rotate = true; + ac.rotation_interval = fc::hours(1); + ac.rotation_limit = fc::days(1); std::cout << "Logging RPC to file: " << (data_dir / ac.filename).preferred_string() << "\n"; - cfg.appenders.push_back(fc::appender_config( "default", "console", fc::variant(fc::console_appender::config(), 20))); - cfg.appenders.push_back(fc::appender_config( "rpc", "file", fc::variant(ac, 5))); + cfg.appenders.push_back(fc::appender_config("default", "console", fc::variant(fc::console_appender::config(), 20))); + cfg.appenders.push_back(fc::appender_config("rpc", "file", fc::variant(ac, 5))); - cfg.loggers = { fc::logger_config("default"), fc::logger_config( "rpc") }; + cfg.loggers = {fc::logger_config("default"), fc::logger_config("rpc")}; cfg.loggers.front().level = fc::log_level::warn; cfg.loggers.front().appenders = {"default"}; cfg.loggers.back().level = fc::log_level::info; cfg.loggers.back().appenders = {"rpc"}; - fc::configure_logging( cfg ); + fc::configure_logging(cfg); fc::ecc::private_key committee_private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("null_key"))); - idump( (key_to_wif( committee_private_key ) ) ); + idump((key_to_wif(committee_private_key))); fc::ecc::private_key nathan_private_key = fc::ecc::private_key::regenerate(fc::sha256::hash(string("nathan"))); public_key_type nathan_pub_key = nathan_private_key.get_public_key(); - idump( (nathan_pub_key) ); - idump( (key_to_wif( nathan_private_key ) ) ); + idump((nathan_pub_key)); + idump((key_to_wif(nathan_private_key))); // // TODO: We read wallet_data twice, once in main() to grab the @@ -152,153 +164,136 @@ int main( int argc, char** argv ) // wallet_data wdata; - fc::path wallet_file( options.count("wallet-file") ? options.at("wallet-file").as() : "wallet.json"); - if( fc::exists( wallet_file ) ) - { - wdata = fc::json::from_file( wallet_file ).as( GRAPHENE_MAX_NESTED_OBJECTS ); - if( options.count("chain-id") ) - { + fc::path wallet_file(options.count("wallet-file") ? options.at("wallet-file").as() : "wallet.json"); + if (fc::exists(wallet_file)) { + wdata = fc::json::from_file(wallet_file).as(GRAPHENE_MAX_NESTED_OBJECTS); + if (options.count("chain-id")) { // the --chain-id on the CLI must match the chain ID embedded in the wallet file - if( chain_id_type(options.at("chain-id").as()) != wdata.chain_id ) - { + if (chain_id_type(options.at("chain-id").as()) != wdata.chain_id) { std::cout << "Chain ID in wallet file does not match specified chain ID\n"; return 1; } } - } - else - { - if( options.count("chain-id") ) - { + } else { + if (options.count("chain-id")) { wdata.chain_id = chain_id_type(options.at("chain-id").as()); std::cout << "Starting a new wallet with chain ID " << wdata.chain_id.str() << " (from CLI)\n"; - } - else - { + } else { wdata.chain_id = graphene::egenesis::get_egenesis_chain_id(); std::cout << "Starting a new wallet with chain ID " << wdata.chain_id.str() << " (from egenesis)\n"; } } // but allow CLI to override - if( options.count("server-rpc-endpoint") ) + if (options.count("server-rpc-endpoint")) wdata.ws_server = options.at("server-rpc-endpoint").as(); - if( options.count("server-rpc-user") ) + if (options.count("server-rpc-user")) wdata.ws_user = options.at("server-rpc-user").as(); - if( options.count("server-rpc-password") ) + if (options.count("server-rpc-password")) wdata.ws_password = options.at("server-rpc-password").as(); fc::http::websocket_client client; idump((wdata.ws_server)); - auto con = client.connect( wdata.ws_server ); + auto con = client.connect(wdata.ws_server); auto apic = std::make_shared(con, GRAPHENE_MAX_NESTED_OBJECTS); - auto remote_api = apic->get_remote_api< login_api >(1); - edump((wdata.ws_user)(wdata.ws_password) ); - FC_ASSERT( remote_api->login( wdata.ws_user, wdata.ws_password ), "Failed to log in to API server" ); + auto remote_api = apic->get_remote_api(1); + edump((wdata.ws_user)(wdata.ws_password)); + FC_ASSERT(remote_api->login(wdata.ws_user, wdata.ws_password), "Failed to log in to API server"); - auto wapiptr = std::make_shared( wdata, remote_api ); - wapiptr->set_wallet_filename( wallet_file.generic_string() ); + auto wapiptr = std::make_shared(wdata, remote_api); + wapiptr->set_wallet_filename(wallet_file.generic_string()); wapiptr->load_wallet_file(); fc::api wapi(wapiptr); - auto wallet_cli = std::make_shared( GRAPHENE_MAX_NESTED_OBJECTS ); - for( auto& name_formatter : wapiptr->get_result_formatters() ) - wallet_cli->format_result( name_formatter.first, name_formatter.second ); + auto wallet_cli = std::make_shared(GRAPHENE_MAX_NESTED_OBJECTS); + for (auto &name_formatter : wapiptr->get_result_formatters()) + wallet_cli->format_result(name_formatter.first, name_formatter.second); - boost::signals2::scoped_connection closed_connection(con->closed.connect([wallet_cli]{ + boost::signals2::scoped_connection closed_connection(con->closed.connect([wallet_cli] { cerr << "Server has disconnected us.\n"; wallet_cli->stop(); })); (void)(closed_connection); - if( wapiptr->is_new() ) - { + if (wapiptr->is_new()) { std::cout << "Please use the set_password method to initialize a new wallet before continuing\n"; - wallet_cli->set_prompt( "new >>> " ); + wallet_cli->set_prompt("new >>> "); } else - wallet_cli->set_prompt( "locked >>> " ); + wallet_cli->set_prompt("locked >>> "); boost::signals2::scoped_connection locked_connection(wapiptr->lock_changed.connect([&](bool locked) { - wallet_cli->set_prompt( locked ? "locked >>> " : "unlocked >>> " ); + wallet_cli->set_prompt(locked ? "locked >>> " : "unlocked >>> "); })); std::shared_ptr _websocket_server; - if( options.count("rpc-endpoint") ) - { + if (options.count("rpc-endpoint")) { _websocket_server = std::make_shared(); - _websocket_server->on_connection([&wapi]( const fc::http::websocket_connection_ptr& c ){ + _websocket_server->on_connection([&wapi](const fc::http::websocket_connection_ptr &c) { std::cout << "here... \n"; - wlog("." ); + wlog("."); auto wsc = std::make_shared(c, GRAPHENE_MAX_NESTED_OBJECTS); wsc->register_api(wapi); - c->set_session_data( wsc ); + c->set_session_data(wsc); }); - ilog( "Listening for incoming RPC requests on ${p}", ("p", options.at("rpc-endpoint").as() )); - _websocket_server->listen( fc::ip::endpoint::from_string(options.at("rpc-endpoint").as()) ); + ilog("Listening for incoming RPC requests on ${p}", ("p", options.at("rpc-endpoint").as())); + _websocket_server->listen(fc::ip::endpoint::from_string(options.at("rpc-endpoint").as())); _websocket_server->start_accept(); } string cert_pem = "server.pem"; - if( options.count( "rpc-tls-certificate" ) ) + if (options.count("rpc-tls-certificate")) cert_pem = options.at("rpc-tls-certificate").as(); std::shared_ptr _websocket_tls_server; - if( options.count("rpc-tls-endpoint") ) - { + if (options.count("rpc-tls-endpoint")) { _websocket_tls_server = std::make_shared(cert_pem); - _websocket_tls_server->on_connection([&]( const fc::http::websocket_connection_ptr& c ){ + _websocket_tls_server->on_connection([&](const fc::http::websocket_connection_ptr &c) { auto wsc = std::make_shared(c, GRAPHENE_MAX_NESTED_OBJECTS); wsc->register_api(wapi); - c->set_session_data( wsc ); + c->set_session_data(wsc); }); - ilog( "Listening for incoming TLS RPC requests on ${p}", ("p", options.at("rpc-tls-endpoint").as() )); - _websocket_tls_server->listen( fc::ip::endpoint::from_string(options.at("rpc-tls-endpoint").as()) ); + ilog("Listening for incoming TLS RPC requests on ${p}", ("p", options.at("rpc-tls-endpoint").as())); + _websocket_tls_server->listen(fc::ip::endpoint::from_string(options.at("rpc-tls-endpoint").as())); _websocket_tls_server->start_accept(); } auto _http_server = std::make_shared(); - if( options.count("rpc-http-endpoint" ) ) - { - ilog( "Listening for incoming HTTP RPC requests on ${p}", ("p", options.at("rpc-http-endpoint").as() ) ); - _http_server->listen( fc::ip::endpoint::from_string( options.at( "rpc-http-endpoint" ).as() ) ); + if (options.count("rpc-http-endpoint")) { + ilog("Listening for incoming HTTP RPC requests on ${p}", ("p", options.at("rpc-http-endpoint").as())); + _http_server->listen(fc::ip::endpoint::from_string(options.at("rpc-http-endpoint").as())); // // due to implementation, on_request() must come AFTER listen() // _http_server->on_request( - [&wapi]( const fc::http::request& req, const fc::http::server::response& resp ) - { - std::shared_ptr< fc::rpc::http_api_connection > conn = - std::make_shared< fc::rpc::http_api_connection >( GRAPHENE_MAX_NESTED_OBJECTS ); - conn->register_api( wapi ); - conn->on_request( req, resp ); - } ); + [&wapi](const fc::http::request &req, const fc::http::server::response &resp) { + std::shared_ptr conn = + std::make_shared(GRAPHENE_MAX_NESTED_OBJECTS); + conn->register_api(wapi); + conn->on_request(req, resp); + }); } - if( !options.count( "daemon" ) ) - { - wallet_cli->register_api( wapi ); + if (!options.count("daemon")) { + wallet_cli->register_api(wapi); wallet_cli->start(); wallet_cli->wait(); - } - else - { - fc::promise::ptr exit_promise = new fc::promise("UNIX Signal Handler"); - fc::set_signal_handler([&exit_promise](int signal) { - exit_promise->set_value(signal); - }, SIGINT); + } else { + fc::promise::ptr exit_promise = new fc::promise("UNIX Signal Handler"); + fc::set_signal_handler([&exit_promise](int signal) { + exit_promise->set_value(signal); + }, + SIGINT); - ilog( "Entering Daemon Mode, ^C to exit" ); - exit_promise->wait(); + ilog("Entering Daemon Mode, ^C to exit"); + exit_promise->wait(); } wapi->save_wallet_file(wallet_file.generic_string()); locked_connection.disconnect(); closed_connection.disconnect(); - } - catch ( const fc::exception& e ) - { + } catch (const fc::exception &e) { std::cout << e.to_detail_string() << "\n"; return -1; } diff --git a/tests/benchmarks/genesis_allocation.cpp b/tests/benchmarks/genesis_allocation.cpp index 63e75db5..b212e2cc 100644 --- a/tests/benchmarks/genesis_allocation.cpp +++ b/tests/benchmarks/genesis_allocation.cpp @@ -27,7 +27,7 @@ #include -#include +#include using namespace graphene::chain;