From be4869a64d127dce1670e3a34e2ff8e2e0dd5778 Mon Sep 17 00:00:00 2001 From: obucina <11353193+obucina@users.noreply.github.com> Date: Sun, 17 May 2020 23:09:15 +0200 Subject: [PATCH 1/8] API endpoint for reading random numbers from the witness (#113) --- libraries/app/database_api.cpp | 19 +++++++++++++++++++ .../app/include/graphene/app/database_api.hpp | 15 +++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index df6458f3..35c2df3d 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -184,6 +184,9 @@ class database_api_impl : public std::enable_shared_from_this // gpos gpos_info get_gpos_info(const account_id_type account) const; + // rng + int64_t get_random_number(uint64_t bound) const; + //private: const account_object* get_account_from_string( const std::string& name_or_id, bool throw_if_not_found = true ) const; @@ -2303,6 +2306,22 @@ graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type return result; } +////////////////////////////////////////////////////////////////////// +// // +// Random numbers // +// // +////////////////////////////////////////////////////////////////////// + +int64_t database_api::get_random_number(uint64_t bound) const +{ + return my->get_random_number(bound); +} + +int64_t database_api_impl::get_random_number(uint64_t bound) const { + int64_t result = _db.get_random_bits(bound); + return result; +} + ////////////////////////////////////////////////////////////////////// // // // Private methods // diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index dc8aba52..da959d9b 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -709,9 +709,17 @@ class database_api */ gpos_info get_gpos_info(const account_id_type account) const; + ///////////////////////////// + // Random number generator // + ///////////////////////////// + /** + * @brief Returns the random number + * @param bound Upper bound of segment containing random number + * @return Random number from segment [0, bound) + */ + int64_t get_random_number(uint64_t bound) const; - -private: + private: std::shared_ptr< database_api_impl > my; }; @@ -848,4 +856,7 @@ FC_API(graphene::app::database_api, // gpos (get_gpos_info) + + // rngs + (get_random_number) ) From 56676b5a58b49897aef4a5e3b891012718e0fbde Mon Sep 17 00:00:00 2001 From: Srdjan Obucina Date: Mon, 18 May 2020 15:49:45 +0200 Subject: [PATCH 2/8] Implemented parametrized random number retrieval --- libraries/app/database_api.cpp | 42 ++++++++++++++++++- .../app/include/graphene/app/database_api.hpp | 11 +++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index 35c2df3d..bd028f6e 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -185,6 +185,7 @@ class database_api_impl : public std::enable_shared_from_this gpos_info get_gpos_info(const account_id_type account) const; // rng + vector get_random_number_ex(uint64_t minimum, uint64_t maximum, uint64_t selections, bool duplicates) const; int64_t get_random_number(uint64_t bound) const; //private: @@ -2312,14 +2313,51 @@ graphene::app::gpos_info database_api_impl::get_gpos_info(const account_id_type // // ////////////////////////////////////////////////////////////////////// +vector database_api::get_random_number_ex(uint64_t minimum, uint64_t maximum, uint64_t selections, bool duplicates) const +{ + return my->get_random_number_ex(minimum, maximum, selections, duplicates); +} + +vector database_api_impl::get_random_number_ex(uint64_t minimum, uint64_t maximum, uint64_t selections, bool duplicates) const +{ + FC_ASSERT( selections <= 100000 ); + if (duplicates == false) { + FC_ASSERT( maximum - minimum >= selections ); + } + + vector v; + v.reserve(selections); + + if (duplicates) { + for (uint64_t i = 0; i < selections; i++) { + int64_t rnd = _db.get_random_bits(maximum - minimum) + minimum; + v.push_back(rnd); + } + } else { + vector tmpv; + tmpv.reserve(selections); + for (uint64_t i = minimum; i < maximum; i++) { + tmpv.push_back(i); + } + + while (tmpv.size() > 0) { + uint64_t idx = _db.get_random_bits(tmpv.size()); + v.push_back(tmpv.at(idx)); + tmpv.erase(tmpv.begin() + idx); + } + } + + return v; +} + int64_t database_api::get_random_number(uint64_t bound) const { return my->get_random_number(bound); } int64_t database_api_impl::get_random_number(uint64_t bound) const { - int64_t result = _db.get_random_bits(bound); - return result; + vector v = get_random_number_ex(0, bound, 1, false); + return v.at(0); } ////////////////////////////////////////////////////////////////////// diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index da959d9b..405bbc58 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -712,6 +712,16 @@ class database_api ///////////////////////////// // Random number generator // ///////////////////////////// + /** + * @brief Returns the random number + * @param minimum Lower bound of segment containing random number + * @param maximum Upper bound of segment containing random number + * @param selections Number of random numbers to return + * @param duplicates Allow duplicated numbers + * @return Vector containing random numbers from segment [minimum, maximum) + */ + vector get_random_number_ex(uint64_t minimum, uint64_t maximum, uint64_t selections, bool duplicates) const; + /** * @brief Returns the random number * @param bound Upper bound of segment containing random number @@ -858,5 +868,6 @@ FC_API(graphene::app::database_api, (get_gpos_info) // rngs + (get_random_number_ex) (get_random_number) ) From 1f49d5b818e4bdd3192cc6411d1778475d4f8287 Mon Sep 17 00:00:00 2001 From: Roshan Syed Date: Tue, 19 May 2020 14:02:33 +0000 Subject: [PATCH 3/8] Update .gitlab-ci.yml --- .gitlab-ci.yml | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 42ec77fc..94966ab6 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -30,26 +30,4 @@ test: - ./tests/chain_test - ./tests/cli_test tags: - - builder - -code_quality: - stage: test - image: docker:stable - variables: - DOCKER_DRIVER: overlay2 - allow_failure: true - services: - - docker:stable-dind - script: - - export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/') - - docker run - --env SOURCE_CODE="$PWD" - --volume "$PWD":/code - --volume /var/run/docker.sock:/var/run/docker.sock - "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code - artifacts: - paths: [gl-code-quality-report.json] - expire_in: 1 week - except: - variables: - - $CODE_QUALITY_DISABLED + - builder \ No newline at end of file From d5eac3f1a70c6748890d31fc8e194dd34ecc9494 Mon Sep 17 00:00:00 2001 From: Srdjan Obucina Date: Thu, 21 May 2020 17:29:23 +0200 Subject: [PATCH 4/8] Introducing random number object, evaluator and operations --- libraries/chain/CMakeLists.txt | 2 + libraries/chain/db_init.cpp | 6 +++ libraries/chain/db_notify.cpp | 3 ++ .../graphene/chain/protocol/operations.hpp | 4 +- .../graphene/chain/protocol/random_number.hpp | 27 ++++++++++++ .../include/graphene/chain/protocol/types.hpp | 5 +++ .../chain/random_number_evaluator.hpp | 19 +++++++++ .../graphene/chain/random_number_object.hpp | 41 +++++++++++++++++++ libraries/chain/random_number_evaluator.cpp | 24 +++++++++++ 9 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 libraries/chain/include/graphene/chain/protocol/random_number.hpp create mode 100644 libraries/chain/include/graphene/chain/random_number_evaluator.hpp create mode 100644 libraries/chain/include/graphene/chain/random_number_object.hpp create mode 100644 libraries/chain/random_number_evaluator.cpp diff --git a/libraries/chain/CMakeLists.txt b/libraries/chain/CMakeLists.txt index 07f1ea0a..40fc2fa0 100644 --- a/libraries/chain/CMakeLists.txt +++ b/libraries/chain/CMakeLists.txt @@ -115,6 +115,8 @@ add_library( graphene_chain affiliate_payout.cpp + random_number_evaluator.cpp + ${HEADERS} ${PROTOCOL_HEADERS} "${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp" diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 4e30029b..23bb986c 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -49,6 +49,7 @@ #include #include #include +#include #include @@ -77,6 +78,7 @@ #include #include #include +#include #include @@ -169,6 +171,8 @@ const uint8_t betting_market_position_object::type_id; const uint8_t global_betting_statistics_object::space_id; const uint8_t global_betting_statistics_object::type_id; +const uint8_t random_number_object::space_id; +const uint8_t random_number_object::type_id; void database::initialize_evaluators() { @@ -243,6 +247,7 @@ void database::initialize_evaluators() register_evaluator(); register_evaluator(); register_evaluator(); + register_evaluator(); } void database::initialize_indexes() @@ -313,6 +318,7 @@ void database::initialize_indexes() add_index< primary_index >(); add_index< primary_index >(); + add_index< primary_index >(); } diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index e91eaa6b..7e17a301 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -293,6 +293,9 @@ struct get_impacted_account_visitor void operator()( const sweeps_vesting_claim_operation& op ) { _impacted.insert( op.account ); } + void operator()( const random_number_store_operation& op ) { + _impacted.insert( op.account ); + } }; void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set& result ) diff --git a/libraries/chain/include/graphene/chain/protocol/operations.hpp b/libraries/chain/include/graphene/chain/protocol/operations.hpp index cb9a83a1..98815980 100644 --- a/libraries/chain/include/graphene/chain/protocol/operations.hpp +++ b/libraries/chain/include/graphene/chain/protocol/operations.hpp @@ -45,6 +45,7 @@ #include #include #include +#include namespace graphene { namespace chain { @@ -135,7 +136,8 @@ namespace graphene { namespace chain { ticket_purchase_operation, lottery_reward_operation, lottery_end_operation, - sweeps_vesting_claim_operation + sweeps_vesting_claim_operation, + random_number_store_operation > operation; /// @} // operations group diff --git a/libraries/chain/include/graphene/chain/protocol/random_number.hpp b/libraries/chain/include/graphene/chain/protocol/random_number.hpp new file mode 100644 index 00000000..e5fbdeb2 --- /dev/null +++ b/libraries/chain/include/graphene/chain/protocol/random_number.hpp @@ -0,0 +1,27 @@ +#pragma once + +namespace graphene { namespace chain { + + struct random_number_store_operation : public base_operation + { + struct fee_parameters_type { uint64_t fee = 5000 * GRAPHENE_BLOCKCHAIN_PRECISION; }; + + asset fee; + + account_id_type account; + time_point_sec timestamp; + uint64_t random_number; + std::string data; + + account_id_type fee_payer()const { return account; } + }; + +} } // graphene::chain + +FC_REFLECT( graphene::chain::random_number_store_operation::fee_parameters_type, (fee) ) +FC_REFLECT( graphene::chain::random_number_store_operation, (fee) + (account) + (timestamp) + (random_number) + (data) ) + diff --git a/libraries/chain/include/graphene/chain/protocol/types.hpp b/libraries/chain/include/graphene/chain/protocol/types.hpp index 8ea3a8af..96847444 100644 --- a/libraries/chain/include/graphene/chain/protocol/types.hpp +++ b/libraries/chain/include/graphene/chain/protocol/types.hpp @@ -171,6 +171,7 @@ namespace graphene { namespace chain { betting_market_group_object_type, betting_market_object_type, bet_object_type, + random_number_object_type, OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types }; @@ -230,6 +231,7 @@ namespace graphene { namespace chain { class betting_market_group_object; class betting_market_object; class bet_object; + class random_number_object; typedef object_id< protocol_ids, account_object_type, account_object> account_id_type; typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type; @@ -256,6 +258,7 @@ namespace graphene { namespace chain { typedef object_id< protocol_ids, betting_market_group_object_type, betting_market_group_object> betting_market_group_id_type; typedef object_id< protocol_ids, betting_market_object_type, betting_market_object> betting_market_id_type; typedef object_id< protocol_ids, bet_object_type, bet_object> bet_id_type; + typedef object_id< protocol_ids, random_number_object_type, random_number_object> random_number_id_type; // implementation types class global_property_object; @@ -436,6 +439,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type, (betting_market_group_object_type) (betting_market_object_type) (bet_object_type) + (random_number_object_type) (OBJECT_TYPE_COUNT) ) FC_REFLECT_ENUM( graphene::chain::impl_object_type, @@ -505,6 +509,7 @@ FC_REFLECT_TYPENAME( graphene::chain::fba_accumulator_id_type ) FC_REFLECT_TYPENAME( graphene::chain::betting_market_position_id_type ) FC_REFLECT_TYPENAME( graphene::chain::global_betting_statistics_id_type ) FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type ) +FC_REFLECT_TYPENAME( graphene::chain::random_number_id_type ) FC_REFLECT( graphene::chain::void_t, ) diff --git a/libraries/chain/include/graphene/chain/random_number_evaluator.hpp b/libraries/chain/include/graphene/chain/random_number_evaluator.hpp new file mode 100644 index 00000000..a26b9f3e --- /dev/null +++ b/libraries/chain/include/graphene/chain/random_number_evaluator.hpp @@ -0,0 +1,19 @@ +#pragma once +#include +#include +#include +#include + +namespace graphene { namespace chain { + + class random_number_store_evaluator : public evaluator + { + public: + typedef random_number_store_operation operation_type; + + void_result do_evaluate( const random_number_store_operation& o ); + object_id_type do_apply( const random_number_store_operation& o ); + }; + +} } // graphene::chain + diff --git a/libraries/chain/include/graphene/chain/random_number_object.hpp b/libraries/chain/include/graphene/chain/random_number_object.hpp new file mode 100644 index 00000000..ea90fa6d --- /dev/null +++ b/libraries/chain/include/graphene/chain/random_number_object.hpp @@ -0,0 +1,41 @@ +#pragma once + +namespace graphene { namespace chain { + using namespace graphene::db; + + class random_number_object : public abstract_object + { + public: + static const uint8_t space_id = protocol_ids; + static const uint8_t type_id = random_number_object_type; + + account_id_type account; /* account who requested random number */ + time_point_sec timestamp; /* date and time when the number is read */ + uint64_t random_number; /* random number */ + std::string data; /* custom data in json format */ + }; + + struct by_account; + struct by_timestamp; + using random_number_multi_index_type = multi_index_container< + random_number_object, + indexed_by< + ordered_unique< tag, + member + >, + ordered_non_unique< tag, + member + >, + ordered_non_unique< tag, + member + > + > + >; + using random_number_index = generic_index; + +} } // graphene::chain + +FC_REFLECT_DERIVED( graphene::chain::random_number_object, (graphene::db::object), + (account) (timestamp) + (random_number) (data) ) + diff --git a/libraries/chain/random_number_evaluator.cpp b/libraries/chain/random_number_evaluator.cpp new file mode 100644 index 00000000..a8447da1 --- /dev/null +++ b/libraries/chain/random_number_evaluator.cpp @@ -0,0 +1,24 @@ +#include +#include + +namespace graphene { namespace chain { + +void_result random_number_store_evaluator::do_evaluate( const random_number_store_operation& op ) +{ try { + + return void_result(); +} FC_CAPTURE_AND_RETHROW( (op) ) } + +object_id_type random_number_store_evaluator::do_apply( const random_number_store_operation& op ) +{ try { + const auto& new_random_number_object = db().create( [&]( random_number_object& obj ) { + //obj.account = op.account; + //obj.timestamp = op.timestamp; + //obj.random_number = op.random_number; + //obj.data = op.data; + }); + return new_random_number_object.id; +} FC_CAPTURE_AND_RETHROW( (op) ) } + +} } // graphene::chain + From 29d6d7b1f9806c4b9a44790262ef9104b3c7b836 Mon Sep 17 00:00:00 2001 From: Srdjan Obucina Date: Mon, 25 May 2020 03:04:32 +0200 Subject: [PATCH 5/8] Random number wallet api with number storing --- libraries/app/database_api.cpp | 6 +- .../app/include/graphene/app/database_api.hpp | 2 +- .../graphene/chain/protocol/random_number.hpp | 4 +- .../graphene/chain/random_number_object.hpp | 2 +- libraries/chain/random_number_evaluator.cpp | 8 +- .../wallet/include/graphene/wallet/wallet.hpp | 184 ++++++++++-------- libraries/wallet/wallet.cpp | 131 +++++++++---- 7 files changed, 205 insertions(+), 132 deletions(-) diff --git a/libraries/app/database_api.cpp b/libraries/app/database_api.cpp index bd028f6e..f2f4e983 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -186,7 +186,7 @@ class database_api_impl : public std::enable_shared_from_this // rng vector get_random_number_ex(uint64_t minimum, uint64_t maximum, uint64_t selections, bool duplicates) const; - int64_t get_random_number(uint64_t bound) const; + uint64_t get_random_number(uint64_t bound) const; //private: const account_object* get_account_from_string( const std::string& name_or_id, @@ -2350,12 +2350,12 @@ vector database_api_impl::get_random_number_ex(uint64_t minimum, uint6 return v; } -int64_t database_api::get_random_number(uint64_t bound) const +uint64_t database_api::get_random_number(uint64_t bound) const { return my->get_random_number(bound); } -int64_t database_api_impl::get_random_number(uint64_t bound) const { +uint64_t database_api_impl::get_random_number(uint64_t bound) const { vector v = get_random_number_ex(0, bound, 1, false); return v.at(0); } diff --git a/libraries/app/include/graphene/app/database_api.hpp b/libraries/app/include/graphene/app/database_api.hpp index 405bbc58..842617d3 100644 --- a/libraries/app/include/graphene/app/database_api.hpp +++ b/libraries/app/include/graphene/app/database_api.hpp @@ -727,7 +727,7 @@ class database_api * @param bound Upper bound of segment containing random number * @return Random number from segment [0, bound) */ - int64_t get_random_number(uint64_t bound) const; + uint64_t get_random_number(uint64_t bound) const; private: std::shared_ptr< database_api_impl > my; diff --git a/libraries/chain/include/graphene/chain/protocol/random_number.hpp b/libraries/chain/include/graphene/chain/protocol/random_number.hpp index e5fbdeb2..3dbe487f 100644 --- a/libraries/chain/include/graphene/chain/protocol/random_number.hpp +++ b/libraries/chain/include/graphene/chain/protocol/random_number.hpp @@ -9,8 +9,7 @@ namespace graphene { namespace chain { asset fee; account_id_type account; - time_point_sec timestamp; - uint64_t random_number; + vector random_number; std::string data; account_id_type fee_payer()const { return account; } @@ -21,7 +20,6 @@ namespace graphene { namespace chain { FC_REFLECT( graphene::chain::random_number_store_operation::fee_parameters_type, (fee) ) FC_REFLECT( graphene::chain::random_number_store_operation, (fee) (account) - (timestamp) (random_number) (data) ) diff --git a/libraries/chain/include/graphene/chain/random_number_object.hpp b/libraries/chain/include/graphene/chain/random_number_object.hpp index ea90fa6d..3613d7a1 100644 --- a/libraries/chain/include/graphene/chain/random_number_object.hpp +++ b/libraries/chain/include/graphene/chain/random_number_object.hpp @@ -11,7 +11,7 @@ namespace graphene { namespace chain { account_id_type account; /* account who requested random number */ time_point_sec timestamp; /* date and time when the number is read */ - uint64_t random_number; /* random number */ + vector random_number; /* random number(s) */ std::string data; /* custom data in json format */ }; diff --git a/libraries/chain/random_number_evaluator.cpp b/libraries/chain/random_number_evaluator.cpp index a8447da1..acfab042 100644 --- a/libraries/chain/random_number_evaluator.cpp +++ b/libraries/chain/random_number_evaluator.cpp @@ -12,10 +12,10 @@ void_result random_number_store_evaluator::do_evaluate( const random_number_stor object_id_type random_number_store_evaluator::do_apply( const random_number_store_operation& op ) { try { const auto& new_random_number_object = db().create( [&]( random_number_object& obj ) { - //obj.account = op.account; - //obj.timestamp = op.timestamp; - //obj.random_number = op.random_number; - //obj.data = op.data; + obj.account = op.account; + obj.timestamp = db().head_block_time(); + obj.random_number = op.random_number; + obj.data = op.data; }); return new_random_number_object.id; } FC_CAPTURE_AND_RETHROW( (op) ) } diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 7f4c7859..ab785ee2 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -68,7 +68,7 @@ struct brain_key_info * the meta data about the receipt that helps the sender identify which receipt is * for the receiver and which is for the change address. */ -struct blind_confirmation +struct blind_confirmation { struct output { @@ -312,7 +312,7 @@ class wallet_api */ uint64_t get_account_count()const; /** Lists all accounts controlled by this wallet. - * This returns a list of the full account objects for all accounts whose private keys + * This returns a list of the full account objects for all accounts whose private keys * we possess. * @returns a list of account objects */ @@ -324,14 +324,14 @@ class wallet_api * start by setting \c lowerbound to the empty string \c "", and then each iteration, pass * the last account name returned as the \c lowerbound for the next \c list_accounts() call. * - * @param lowerbound the name of the first account to return. If the named account does not exist, + * @param lowerbound the name of the first account to return. If the named account does not exist, * the list will start at the account that comes after \c lowerbound * @param limit the maximum number of accounts to return (max: 1000) * @returns a list of accounts mapping account names to account ids */ map list_accounts(const string& lowerbound, uint32_t limit); /** List the balances of an account. - * Each account can have multiple balances, one for each type of asset owned by that + * Each account can have multiple balances, one for each type of asset owned by that * account. The returned list will only contain assets for which the account has a * nonzero balance * @param id the name or id of the account whose balances you want @@ -339,7 +339,7 @@ class wallet_api */ vector list_account_balances(const string& id); /** Lists all assets registered on the blockchain. - * + * * To list all assets, pass the empty string \c "" for the lowerbound to start * at the beginning of the list, and iterate as necessary. * @@ -350,12 +350,12 @@ class wallet_api vector list_assets(const string& lowerbound, uint32_t limit)const; /** Returns assets count registered on the blockchain. - * + * * @returns assets count */ uint64_t get_asset_count()const; - - + + vector get_lotteries( asset_id_type stop = asset_id_type(), unsigned limit = 100, asset_id_type start = asset_id_type() )const; @@ -391,7 +391,7 @@ class wallet_api vector get_limit_orders(string a, string b, uint32_t limit)const; vector get_call_orders(string a, uint32_t limit)const; vector get_settle_orders(string a, uint32_t limit)const; - + /** Returns the block chain's slowly-changing settings. * This object contains all of the properties of the blockchain that are fixed * or that change only once per maintenance interval (daily) such as the @@ -447,8 +447,8 @@ class wallet_api * Returns the blockchain object corresponding to the given id. * * This generic function can be used to retrieve any object from the blockchain - * that is assigned an ID. Certain types of objects have specialized convenience - * functions to return their objects -- e.g., assets have \c get_asset(), accounts + * that is assigned an ID. Certain types of objects have specialized convenience + * functions to return their objects -- e.g., assets have \c get_asset(), accounts * have \c get_account(), but this function will work for any object. * * @param id the id of the object to return @@ -456,7 +456,7 @@ class wallet_api */ variant get_object(object_id_type id) const; - /** Returns the current wallet filename. + /** Returns the current wallet filename. * * This is the filename that will be used when automatically saving the wallet. * @@ -532,21 +532,21 @@ class wallet_api * @ingroup Wallet Management */ bool is_new()const; - - /** Checks whether the wallet is locked (is unable to use its private keys). + + /** Checks whether the wallet is locked (is unable to use its private keys). * * This state can be changed by calling \c lock() or \c unlock(). * @return true if the wallet is locked * @ingroup Wallet Management */ bool is_locked()const; - + /** Locks the wallet immediately. * @ingroup Wallet Management */ void lock(); - - /** Unlocks the wallet. + + /** Unlocks the wallet. * * The wallet remain unlocked until the \c lock is called * or the program exits. @@ -554,7 +554,7 @@ class wallet_api * @ingroup Wallet Management */ void unlock(string password); - + /** Sets a new password on the wallet. * * The wallet must be either 'new' or 'unlocked' to @@ -567,7 +567,7 @@ class wallet_api * * The keys are printed in WIF format. You can import these keys into another wallet * using \c import_key() - * @returns a map containing the private keys, indexed by their public key + * @returns a map containing the private keys, indexed by their public key */ map dump_private_keys(); @@ -602,13 +602,13 @@ class wallet_api bool load_wallet_file(string wallet_filename = ""); /** Quitting from Peerplays wallet. - * + * * The current wallet will be closed. */ void quit(); /** Saves the current wallet to the given filename. - * + * * @warning This does not change the wallet filename that will be used for future * writes, so think of this function as 'Save a Copy As...' instead of * 'Save As...'. Use \c set_wallet_filename() to make the filename @@ -677,7 +677,7 @@ class wallet_api /** Imports the private key for an existing account. * * The private key must match either an owner key or an active key for the - * named account. + * named account. * * @see dump_private_keys() * @@ -780,7 +780,7 @@ class wallet_api * @param to the name or id of the account receiving the funds * @param amount the amount to send (in nominal units -- to send half of a BTS, specify 0.5) * @param asset_symbol the symbol or id of the asset to send - * @param memo a memo to attach to the transaction. The memo will be encrypted in the + * @param memo a memo to attach to the transaction. The memo will be encrypted in the * transaction and readable for the receiver. There is no length limit * other than the limit imposed by maximum transaction size, but transaction * increase with transaction size @@ -855,7 +855,7 @@ class wallet_api * who sent it. * * @param opt_from - if not empty and the sender is a unknown public key, then the unknown public key will be given the label opt_from - * @param confirmation_receipt - a base58 encoded stealth confirmation + * @param confirmation_receipt - a base58 encoded stealth confirmation */ blind_receipt receive_blind_transfer( string confirmation_receipt, string opt_from, string opt_memo ); @@ -863,18 +863,18 @@ class wallet_api * Transfers a public balance from @from to one or more blinded balances using a * stealth transfer. */ - blind_confirmation transfer_to_blind( string from_account_id_or_name, + blind_confirmation transfer_to_blind( string from_account_id_or_name, string asset_symbol, /** map from key or label to amount */ - vector> to_amounts, + vector> to_amounts, bool broadcast = false ); /** * Transfers funds from a set of blinded balances to a public account balance. */ - blind_confirmation transfer_from_blind( + blind_confirmation transfer_from_blind( string from_blind_account_key_or_label, - string to_account_id_or_name, + string to_account_id_or_name, string amount, string asset_symbol, bool broadcast = false ); @@ -890,14 +890,14 @@ class wallet_api /** Place a limit order attempting to sell one asset for another. * - * Buying and selling are the same operation on Graphene; if you want to buy BTS + * Buying and selling are the same operation on Graphene; if you want to buy BTS * with USD, you should sell USD for BTS. * * The blockchain will attempt to sell the \c symbol_to_sell for as - * much \c symbol_to_receive as possible, as long as the price is at - * least \c min_to_receive / \c amount_to_sell. + * much \c symbol_to_receive as possible, as long as the price is at + * least \c min_to_receive / \c amount_to_sell. * - * In addition to the transaction fees, market fees will apply as specified + * In addition to the transaction fees, market fees will apply as specified * by the issuer of both the selling asset and the receiving asset as * a percentage of the amount exchanged. * @@ -910,16 +910,16 @@ class wallet_api * * @todo Allow order expiration to be set here. Document default/max expiration time * - * @param seller_account the account providing the asset being sold, and which will + * @param seller_account the account providing the asset being sold, and which will * receive the proceeds of the sale. * @param amount_to_sell the amount of the asset being sold to sell (in nominal units) * @param symbol_to_sell the name or id of the asset to sell * @param min_to_receive the minimum amount you are willing to receive in return for * selling the entire amount_to_sell * @param symbol_to_receive the name or id of the asset you wish to receive - * @param timeout_sec if the order does not fill immediately, this is the length of - * time the order will remain on the order books before it is - * cancelled and the un-spent funds are returned to the seller's + * @param timeout_sec if the order does not fill immediately, this is the length of + * time the order will remain on the order books before it is + * cancelled and the un-spent funds are returned to the seller's * account * @param fill_or_kill if true, the order will only be included in the blockchain * if it is filled immediately; if false, an open order will be @@ -936,12 +936,12 @@ class wallet_api uint32_t timeout_sec = 0, bool fill_or_kill = false, bool broadcast = false); - + /** Place a limit order attempting to sell one asset for another. - * + * * This API call abstracts away some of the details of the sell_asset call to be more * user friendly. All orders placed with sell never timeout and will not be killed if they - * cannot be filled immediately. If you wish for one of these parameters to be different, + * cannot be filled immediately. If you wish for one of these parameters to be different, * then sell_asset should be used instead. * * @param seller_account the account providing the asset being sold, and which will @@ -951,7 +951,7 @@ class wallet_api * @param rate The rate in base:quote at which you want to sell. * @param amount The amount of base you want to sell. * @param broadcast true to broadcast the transaction on the network. - * @returns The signed transaction selling the funds. + * @returns The signed transaction selling the funds. */ signed_transaction sell( string seller_account, string base, @@ -959,7 +959,7 @@ class wallet_api double rate, double amount, bool broadcast ); - + /** Place a limit order attempting to buy one asset with another. * * This API call abstracts away some of the details of the sell_asset call to be more @@ -1014,14 +1014,14 @@ class wallet_api * Right now this function is difficult to use because you must provide raw JSON data * structures for the options objects, and those include prices and asset ids. * - * @param issuer the name or id of the account who will pay the fee and become the + * @param issuer the name or id of the account who will pay the fee and become the * issuer of the new asset. This can be updated later * @param symbol the ticker symbol of the new asset * @param precision the number of digits of precision to the right of the decimal point, * must be less than or equal to 12 * @param common asset options required for all new assets. - * Note that core_exchange_rate technically needs to store the asset ID of - * this new asset. Since this ID is not known at the time this operation is + * Note that core_exchange_rate technically needs to store the asset ID of + * this new asset. Since this ID is not known at the time this operation is * created, create this price as though the new asset has instance ID 1, and * the chain will overwrite it with the new asset's ID. * @param bitasset_opts options specific to BitAssets. This may be null unless the @@ -1041,7 +1041,7 @@ class wallet_api asset_options common, lottery_asset_options lottery_opts, bool broadcast = false); - + signed_transaction buy_ticket( asset_id_type lottery, account_id_type buyer, uint64_t tickets_to_buy ); /** Issue new shares of an asset. @@ -1059,8 +1059,8 @@ class wallet_api bool broadcast = false); /** Update the core options on an asset. - * There are a number of options which all assets in the network use. These options are - * enumerated in the asset_object::asset_options struct. This command is used to update + * There are a number of options which all assets in the network use. These options are + * enumerated in the asset_object::asset_options struct. This command is used to update * these options for an existing asset. * * @note This operation cannot be used to update BitAsset-specific options. For these options, @@ -1124,7 +1124,7 @@ class wallet_api signed_transaction update_asset_feed_producers(string symbol, flat_set new_feed_producers, bool broadcast = false); - + /** Publishes a price feed for the named asset. * * Price feed providers use this command to publish their price feeds for market-issued assets. A price feed is @@ -1152,7 +1152,7 @@ class wallet_api /** Pay into the fee pool for the given asset. * - * User-issued assets can optionally have a pool of the core asset which is + * User-issued assets can optionally have a pool of the core asset which is * automatically used to pay transaction fees for any transaction using that * asset (using the asset's core exchange rate). * @@ -1193,7 +1193,7 @@ class wallet_api * used as backing for other bitassets, those bitassets will be force settled at their current * feed price. * - * @note this operation is used only by the asset issuer, \c settle_asset() may be used by + * @note this operation is used only by the asset issuer, \c settle_asset() may be used by * any user owning the asset * * @param symbol the name or id of the asset to force settlement on @@ -1261,7 +1261,7 @@ class wallet_api * @returns the signed transaction registering a committee_member */ signed_transaction create_committee_member(string owner_account, - string url, + string url, bool broadcast = false); /** Lists all witnesses registered in the blockchain. @@ -1272,7 +1272,7 @@ class wallet_api * start by setting \c lowerbound to the empty string \c "", and then each iteration, pass * the last witness name returned as the \c lowerbound for the next \c list_witnesss() call. * - * @param lowerbound the name of the first witness to return. If the named witness does not exist, + * @param lowerbound the name of the first witness to return. If the named witness does not exist, * the list will start at the witness that comes after \c lowerbound * @param limit the maximum number of witnesss to return (max: 1000) * @returns a list of witnesss mapping witness names to witness ids @@ -1287,7 +1287,7 @@ class wallet_api * start by setting \c lowerbound to the empty string \c "", and then each iteration, pass * the last committee_member name returned as the \c lowerbound for the next \c list_committee_members() call. * - * @param lowerbound the name of the first committee_member to return. If the named committee_member does not exist, + * @param lowerbound the name of the first committee_member to return. If the named committee_member does not exist, * the list will start at the committee_member that comes after \c lowerbound * @param limit the maximum number of committee_members to return (max: 1000) * @returns a list of committee_members mapping committee_member names to committee_member ids @@ -1413,7 +1413,7 @@ class wallet_api /** Vote for a given committee_member. * - * An account can publish a list of all committee_memberes they approve of. This + * An account can publish a list of all committee_memberes they approve of. This * command allows you to add or remove committee_memberes from this list. * Each account's vote is weighted according to the number of shares of the * core asset owned by that account at the time the votes are tallied. @@ -1423,7 +1423,7 @@ class wallet_api * * @param voting_account the name or id of the account who is voting with their shares * @param committee_member the name or id of the committee_member' owner account - * @param approve true if you wish to vote in favor of that committee_member, false to + * @param approve true if you wish to vote in favor of that committee_member, false to * remove your vote in favor of that committee_member * @param broadcast true if you wish to broadcast the transaction * @return the signed transaction changing your vote for the given committee_member @@ -1435,7 +1435,7 @@ class wallet_api /** Vote for a given witness. * - * An account can publish a list of all witnesses they approve of. This + * An account can publish a list of all witnesses they approve of. This * command allows you to add or remove witnesses from this list. * Each account's vote is weighted according to the number of shares of the * core asset owned by that account at the time the votes are tallied. @@ -1445,7 +1445,7 @@ class wallet_api * * @param voting_account the name or id of the account who is voting with their shares * @param witness the name or id of the witness' owner account - * @param approve true if you wish to vote in favor of that witness, false to + * @param approve true if you wish to vote in favor of that witness, false to * remove your vote in favor of that witness * @param broadcast true if you wish to broadcast the transaction * @return the signed transaction changing your vote for the given witness @@ -1457,12 +1457,12 @@ class wallet_api /** Change your witness votes. * - * An account can publish a list of all witnesses they approve of. + * An account can publish a list of all witnesses they approve of. * Each account's vote is weighted according to the number of shares of the * core asset owned by that account at the time the votes are tallied. - * This command allows you to add or remove one or more witnesses from this list + * This command allows you to add or remove one or more witnesses from this list * in one call. When you are changing your vote on several witnesses, this - * may be easier than multiple `vote_for_witness` and + * may be easier than multiple `vote_for_witness` and * `set_desired_witness_and_committee_member_count` calls. * * @note you cannot vote against a witness, you can only vote for the witness @@ -1477,7 +1477,7 @@ class wallet_api * you currently approve). This list can be empty. * @param desired_number_of_witnesses the number of witnesses you believe the network * should have. You must vote for at least this many - * witnesses. You can set this to 0 to abstain from + * witnesses. You can set this to 0 to abstain from * voting on the number of witnesses. * @param broadcast true if you wish to broadcast the transaction * @return the signed transaction changing your vote for the given witnesses @@ -1508,23 +1508,23 @@ class wallet_api signed_transaction set_voting_proxy(string account_to_modify, optional voting_account, bool broadcast = false); - + /** Set your vote for the number of witnesses and committee_members in the system. * - * Each account can voice their opinion on how many committee_members and how many + * Each account can voice their opinion on how many committee_members and how many * witnesses there should be in the active committee_member/active witness list. These * are independent of each other. You must vote your approval of at least as many * committee_members or witnesses as you claim there should be (you can't say that there should - * be 20 committee_members but only vote for 10). + * be 20 committee_members but only vote for 10). * - * There are maximum values for each set in the blockchain parameters (currently + * There are maximum values for each set in the blockchain parameters (currently * defaulting to 1001). * * This setting can be changed at any time. If your account has a voting proxy * set, your preferences will be ignored. * * @param account_to_modify the name or id of the account to update - * @param number_of_committee_members the number + * @param number_of_committee_members the number * * @param broadcast true if you wish to broadcast the transaction * @return the signed transaction changing your vote proxy settings @@ -1577,16 +1577,16 @@ class wallet_api /** Returns an uninitialized object representing a given blockchain operation. * - * This returns a default-initialized object of the given type; it can be used + * This returns a default-initialized object of the given type; it can be used * during early development of the wallet when we don't yet have custom commands for - * creating all of the operations the blockchain supports. + * creating all of the operations the blockchain supports. * * Any operation the blockchain supports can be created using the transaction builder's - * \c add_operation_to_builder_transaction() , but to do that from the CLI you need to + * \c add_operation_to_builder_transaction() , but to do that from the CLI you need to * know what the JSON form of the operation looks like. This will give you a template * you can fill in. It's better than nothing. - * - * @param operation_type the type of operation to return, must be one of the + * + * @param operation_type the type of operation to return, must be one of the * operations defined in `graphene/chain/operations.hpp` * (e.g., "global_parameters_update_operation") * @return a default-constructed operation of the given type @@ -1611,7 +1611,7 @@ class wallet_api bool broadcast = false); /** Propose a fee change. - * + * * @param proposing_account The account paying the fee to propose the tx * @param expiration_time Timestamp specifying when the proposal will either take effect or expire. * @param changed_values Map of operation type to new fee. Operations may be specified by name or ID. @@ -1653,7 +1653,33 @@ class wallet_api const approval_delta& delta, bool broadcast /* = false */ ); - + + /** Get random numbers + * @brief Returns the random number + * @param minimum Lower bound of segment containing random number + * @param maximum Upper bound of segment containing random number + * @param selections Number of random numbers to return + * @param duplicates Allow duplicated numbers + * @param broadcast true if you wish to broadcast the transaction + * @return the signed version of the transaction + * @return Vector containing random numbers from segment [minimum, maximum) + */ + vector get_random_number_ex(string account, + uint64_t minimum, + uint64_t maximum, + uint64_t selections, + bool duplicates, + bool broadcast); + + /** Get random number + * @brief Returns the random number + * @param bound Upper bound of segment containing random number + * @return Random number from segment [0, bound) + */ + uint64_t get_random_number(string account, + uint64_t bound, + bool broadcast); + order_book get_order_book( const string& base, const string& quote, unsigned limit = 50); asset get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id); @@ -1692,7 +1718,7 @@ class wallet_api sport_id_type sport_id, fc::optional name, bool broadcast = false); - + signed_transaction propose_delete_sport( const string& proposing_account, fc::time_point_sec expiration_time, @@ -1719,7 +1745,7 @@ class wallet_api fc::time_point_sec expiration_time, event_group_id_type event_group, bool broadcast = false); - + signed_transaction propose_create_event( const string& proposing_account, fc::time_point_sec expiration_time, @@ -1790,7 +1816,7 @@ class wallet_api fc::optional payout_condition, bool broadcast = false); - /** Place a bet + /** Place a bet * @param bettor the account placing the bet * @param betting_market_id the market on which to bet * @param back_or_lay back or lay @@ -1866,7 +1892,7 @@ class wallet_api tournament_state state); /** Get specific information about a tournament - * @param tournament_id the ID of the tournament + * @param tournament_id the ID of the tournament */ tournament_object get_tournament(tournament_id_type id); @@ -1984,7 +2010,7 @@ FC_REFLECT_DERIVED( graphene::wallet::signed_block_with_info, (graphene::chain:: FC_REFLECT_DERIVED( graphene::wallet::vesting_balance_object_with_info, (graphene::chain::vesting_balance_object), (allowed_withdraw)(allowed_withdraw_time) ) -FC_REFLECT( graphene::wallet::operation_detail, +FC_REFLECT( graphene::wallet::operation_detail, (memo)(description)(op) ) FC_API( graphene::wallet::wallet_api, @@ -2094,6 +2120,8 @@ FC_API( graphene::wallet::wallet_api, (propose_fee_change) (propose_dividend_asset_update) (approve_proposal) + (get_random_number_ex) + (get_random_number) (dbg_make_uia) (dbg_make_mia) (dbg_push_blocks) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 0bbf305a..227a347d 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -615,7 +615,7 @@ public: throw fc::canceled_exception(); } - + bool copy_wallet_file( string destination_filename ) { fc::path src_path = get_wallet_filename(); @@ -907,7 +907,7 @@ public: const rock_paper_scissors_game_details& rps_details = game_obj.game_details.get(); for (unsigned i = 0; i < 2; ++i) { - if (rps_details.commit_moves.at(i) && + if (rps_details.commit_moves.at(i) && !rps_details.reveal_moves.at(i)) // if this player has committed but not revealed { const account_id_type& account_id = game_obj.players[i]; @@ -927,7 +927,7 @@ public: if (iter != _wallet.committed_game_moves.end()) { const rock_paper_scissors_throw_reveal& reveal = iter->second; - + game_move_operation move_operation; move_operation.game_id = game_obj.id; move_operation.player_account_id = account_id; @@ -970,7 +970,7 @@ public: } } FC_RETHROW_EXCEPTIONS(warn, "") } - // Cache all matches in the tournament, which will also register us for + // Cache all matches in the tournament, which will also register us for // updates on those matches void monitor_matches_in_tournament(const tournament_object& tournament_obj) { try { @@ -1127,8 +1127,8 @@ public: dlog( "validated successfully tmp wallet file ${fn}", ("fn", tmp_wallet_filename) ); fc::rename( tmp_wallet_filename, wallet_filename ); dlog( "renamed successfully tmp wallet file ${fn}", ("fn", tmp_wallet_filename) ); - } - else + } + else { FC_THROW("tmp wallet file cannot be validated ${fn}", ("fn", tmp_wallet_filename) ); } @@ -1527,7 +1527,7 @@ public: return sign_transaction( tx, broadcast ); } FC_CAPTURE_AND_RETHROW( (issuer)(symbol)(common)(broadcast) ) } - + signed_transaction buy_ticket( asset_id_type lottery, account_id_type buyer, uint64_t tickets_to_buy ) { try { auto asset_obj = get_asset( lottery ); @@ -1538,7 +1538,7 @@ public: top.buyer = buyer; top.tickets_to_buy = tickets_to_buy; top.amount = asset( asset_obj.lottery_options->ticket_price.amount * tickets_to_buy, asset_obj.lottery_options->ticket_price.asset_id ); - + signed_transaction tx; tx.operations.push_back( top ); set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees); @@ -1546,8 +1546,8 @@ public: return sign_transaction( tx, true ); } FC_CAPTURE_AND_RETHROW( (lottery)(tickets_to_buy) ) } - - + + signed_transaction update_asset(string symbol, optional new_issuer, asset_options new_options, @@ -2102,13 +2102,13 @@ public: fc::optional vbid = maybe_id(witness_name); if( !vbid ) { - if (is_witness(witness_name)) + if (is_witness(witness_name)) { witness_object wit = get_witness( witness_name ); FC_ASSERT( wit.pay_vb, "Account ${account} has no core Token ${TOKEN} vested and thus its not allowed to withdraw.", ("account", witness_name)("TOKEN", GRAPHENE_SYMBOL)); vbid = wit.pay_vb; } - else + else FC_THROW("Account ${account} has no core Token ${TOKEN} vested and thus its not allowed to withdraw.", ("account", witness_name)("TOKEN", GRAPHENE_SYMBOL)); } @@ -2151,14 +2151,14 @@ public: if( !vbid ) { vbos = _remote_db->get_vesting_balances( account_name ); - if( vbos.size() == 0 ) + if( vbos.size() == 0 ) FC_THROW("Account ${account} has no core TOKEN vested and thus its not allowed to withdraw.", ("account", account_name)); } - //whether it is a witness or user, keep it in a container and iterate over to process all vesting balances and types + //whether it is a witness or user, keep it in a container and iterate over to process all vesting balances and types if(!vbos.size()) vbos.emplace_back( get_object(*vbid) ); - + for (const vesting_balance_object& vesting_balance_obj: vbos) { if(vesting_balance_obj.balance_type == vesting_balance_type::gpos) { @@ -2188,7 +2188,7 @@ public: bool broadcast /* = false */) { try { std::vector vbo_info = get_vesting_balances(voting_account); - + time_point_sec now = time_point::now(); if(now >= HARDFORK_GPOS_TIME) //can be removed after GPOS HARDFORK time pass { @@ -2215,7 +2215,7 @@ public: const auto vesting_subperiod = _remote_db->get_global_properties().parameters.gpos_subperiod(); const auto gpos_start_time = fc::time_point_sec(_remote_db->get_global_properties().parameters.gpos_period_start()); const auto subperiod_start_time = gpos_start_time.sec_since_epoch() + (gpos_info.current_subperiod - 1) * vesting_subperiod; - + if (!insert_result.second && (gpos_info.last_voted_time.sec_since_epoch() >= subperiod_start_time)) FC_THROW("Account ${account} was already voting for committee_member ${committee_member} in the current GPOS sub-period", ("account", voting_account)("committee_member", committee_member)); else @@ -2252,7 +2252,7 @@ public: bool broadcast /* = false */) { try { std::vector vbo_info = get_vesting_balances(voting_account); - + time_point_sec now = time_point::now(); if(now >= HARDFORK_GPOS_TIME) //can be removed after GPOS HARDFORK time pass { @@ -2263,7 +2263,7 @@ public: } account_object voting_account_object = get_account(voting_account); - + fc::optional witness_obj = _remote_db->get_witness_by_account(witness); if (!witness_obj) FC_THROW("Account ${witness} is not registered as a witness", ("witness", witness)); @@ -2279,7 +2279,7 @@ public: const auto vesting_subperiod = _remote_db->get_global_properties().parameters.gpos_subperiod(); const auto gpos_start_time = fc::time_point_sec(_remote_db->get_global_properties().parameters.gpos_period_start()); const auto subperiod_start_time = gpos_start_time.sec_since_epoch() + (gpos_info.current_subperiod - 1) * vesting_subperiod; - + if (!insert_result.second && (gpos_info.last_voted_time.sec_since_epoch() >= subperiod_start_time)) FC_THROW("Account ${account} was already voting for witness ${witness} in the current GPOS sub-period", ("account", voting_account)("witness", witness)); else @@ -2297,7 +2297,7 @@ public: if (!votes_removed) FC_THROW("Account ${account} has not voted for witness ${witness}", ("account", voting_account)("witness", witness)); } - + account_update_operation account_update_op; account_update_op.account = voting_account_object.id; account_update_op.new_options = voting_account_object.options; @@ -2906,7 +2906,7 @@ public: { unsigned row_offset = (1 << round) - 1; unsigned row_vertical_spacing = 1 << (round + 1); - if (row >= row_offset && + if (row >= row_offset && (row - row_offset) % row_vertical_spacing == 0) { unsigned player_number_in_round = (row - row_offset) / row_vertical_spacing; @@ -2920,7 +2920,7 @@ public: if (round == num_rounds) { match_object match = get_object(tournament_details.matches[num_matches - 1]); - if (match.get_state() == match_state::match_complete && + if (match.get_state() == match_state::match_complete && !match.match_winners.empty()) { assert(match.match_winners.size() == 1); @@ -3242,6 +3242,38 @@ public: return sign_transaction(tx, broadcast); } + vector get_random_number_ex(string account, + uint64_t minimum, + uint64_t maximum, + uint64_t selections, + bool duplicates, + bool broadcast) + { + + vector v = _remote_db->get_random_number_ex(minimum, maximum, selections, duplicates); + + random_number_store_operation op; + op.account = get_account(account).id; + op.random_number = v; + op.data = ""; + + signed_transaction trx; + trx.operations.push_back(op); + set_operation_fees( trx, _remote_db->get_global_properties().parameters.current_fees ); + trx.validate(); + sign_transaction( trx, broadcast ); + + return v; + } + + uint64_t get_random_number(string account, + uint64_t bound, + bool broadcast) + { + vector v = get_random_number_ex(account, 0, bound, 1, false, broadcast); + return v.at(0); + } + void dbg_make_uia(string creator, string symbol) { asset_options opts; @@ -3599,7 +3631,7 @@ std::string operation_printer::operator()(const bet_place_operation& op)const auto asset = wallet.get_asset(op.amount_to_bet.asset_id); auto bettor = wallet.get_account(op.bettor_id); - out << bettor.name << " placed a " << fc::json::to_string(op.back_or_lay) << " bet for " + out << bettor.name << " placed a " << fc::json::to_string(op.back_or_lay) << " bet for " << asset.amount_to_pretty_string(op.amount_to_bet) << " at odds " << ((double)op.backer_multiplier / GRAPHENE_BETTING_ODDS_PRECISION) << " on market " << fc::json::to_string(op.betting_market_id) << " fee: " << fee_asset.amount_to_pretty_string(op.fee); @@ -3742,7 +3774,7 @@ vector wallet_api::get_account_lotteries( account_id_type issuer, return my->_remote_db->get_account_lotteries( issuer, stop, limit, start ); } -asset wallet_api::get_lottery_balance( asset_id_type lottery_id )const +asset wallet_api::get_lottery_balance( asset_id_type lottery_id )const { return my->_remote_db->get_lottery_balance( lottery_id ); } @@ -3750,7 +3782,7 @@ asset wallet_api::get_lottery_balance( asset_id_type lottery_id )const vector wallet_api::get_account_history(string name, int limit) const { vector result; - + while (limit > 0) { bool skip_first_row = false; @@ -3801,9 +3833,9 @@ vector wallet_api::get_account_history(string name, int limit) vector wallet_api::get_relative_account_history(string name, uint32_t stop, int limit, uint32_t start)const { - + FC_ASSERT( start > 0 || limit <= 100 ); - + vector result; while( limit > 0 ) @@ -4541,7 +4573,22 @@ signed_transaction wallet_api::approve_proposal( return my->approve_proposal( fee_paying_account, proposal_id, delta, broadcast ); } +vector wallet_api::get_random_number_ex(string account, + uint64_t minimum, + uint64_t maximum, + uint64_t selections, + bool duplicates, + bool broadcast) +{ + return my->get_random_number_ex( account, minimum, maximum, selections, duplicates, broadcast ); +} +uint64_t wallet_api::get_random_number(string account, + uint64_t bound, + bool broadcast) +{ + return my->get_random_number( account, bound, broadcast ); +} global_property_object wallet_api::get_global_properties() const @@ -5512,22 +5559,22 @@ signed_transaction wallet_api::propose_delete_sport( { FC_ASSERT( !is_locked() ); const chain_parameters& current_params = get_global_properties().parameters; - + sport_delete_operation sport_delete_op; sport_delete_op.sport_id = sport_id; - + proposal_create_operation prop_op; prop_op.expiration_time = expiration_time; prop_op.review_period_seconds = current_params.committee_proposal_review_period; prop_op.fee_paying_account = get_account(proposing_account).id; prop_op.proposed_ops.emplace_back( sport_delete_op ); current_params.current_fees->set_fee( prop_op.proposed_ops.back().op ); - + signed_transaction tx; tx.operations.push_back(prop_op); my->set_operation_fees(tx, current_params.current_fees); tx.validate(); - + return my->sign_transaction(tx, broadcast); } @@ -5590,7 +5637,7 @@ signed_transaction wallet_api::propose_update_event_group( return my->sign_transaction(tx, broadcast); } - + signed_transaction wallet_api::propose_delete_event_group( const string& proposing_account, fc::time_point_sec expiration_time, @@ -5599,22 +5646,22 @@ signed_transaction wallet_api::propose_delete_event_group( { FC_ASSERT( !is_locked() ); const chain_parameters& current_params = get_global_properties().parameters; - + event_group_delete_operation event_group_delete_op; event_group_delete_op.event_group_id = event_group; - + proposal_create_operation prop_op; prop_op.expiration_time = expiration_time; prop_op.review_period_seconds = current_params.committee_proposal_review_period; prop_op.fee_paying_account = get_account(proposing_account).id; prop_op.proposed_ops.emplace_back( event_group_delete_op ); current_params.current_fees->set_fee( prop_op.proposed_ops.back().op ); - + signed_transaction tx; tx.operations.push_back(prop_op); my->set_operation_fees(tx, current_params.current_fees); tx.validate(); - + return my->sign_transaction(tx, broadcast); } @@ -5999,10 +6046,10 @@ signed_transaction wallet_api::tournament_create( string creator, tournament_opt return my->sign_transaction( tx, broadcast ); } -signed_transaction wallet_api::tournament_join( string payer_account, - string player_account, - tournament_id_type tournament_id, - string buy_in_amount, +signed_transaction wallet_api::tournament_join( string payer_account, + string player_account, + tournament_id_type tournament_id, + string buy_in_amount, string buy_in_asset_symbol, bool broadcast ) { @@ -6084,7 +6131,7 @@ signed_transaction wallet_api::rps_throw(game_id_type game_id, graphene::chain::game_object game_obj = my->get_object(game_id); graphene::chain::match_object match_obj = my->get_object(game_obj.match_id); graphene::chain::tournament_object tournament_obj = my->get_object(match_obj.tournament_id); - graphene::chain::rock_paper_scissors_game_options game_options = + graphene::chain::rock_paper_scissors_game_options game_options = tournament_obj.options.game_options.get(); if ((int)gesture >= game_options.number_of_gestures) FC_THROW("Gesture ${gesture} not supported in this game", ("gesture", gesture)); From 01758b1c47b3e86f0bed1cce0da13e2bef0bb003 Mon Sep 17 00:00:00 2001 From: Srdjan Obucina Date: Thu, 28 May 2020 12:35:33 +0200 Subject: [PATCH 6/8] Fix problem with returning more random numbers than requested --- 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 f2f4e983..8faa788d 100644 --- a/libraries/app/database_api.cpp +++ b/libraries/app/database_api.cpp @@ -2340,7 +2340,7 @@ vector database_api_impl::get_random_number_ex(uint64_t minimum, uint6 tmpv.push_back(i); } - while (tmpv.size() > 0) { + for (uint64_t i = 0; (i < selections) && (tmpv.size() > 0); i++) { uint64_t idx = _db.get_random_bits(tmpv.size()); v.push_back(tmpv.at(idx)); tmpv.erase(tmpv.begin() + idx); From 600cb79dad18d24eaeda178af1c4cfaa0ae376a9 Mon Sep 17 00:00:00 2001 From: Roshan Syed Date: Fri, 5 Jun 2020 11:48:03 +0000 Subject: [PATCH 7/8] Updated .gitlab-ci.yml with deploy for rng --- .gitlab-ci.yml | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 94966ab6..84995f5a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,6 +4,7 @@ include: stages: - build - test + - deploy build: stage: build @@ -30,4 +31,15 @@ test: - ./tests/chain_test - ./tests/cli_test tags: - - builder \ No newline at end of file + - builder + +deploy-rng: + stage: deploy + dependencies: + - build + script: + - mv ./programs/witness_node/witness_node /tmp + - ansible-playbook /usr/local/bin/update-witness.yml + - sh /usr/local/bin/update-info.sh + - sh /usr/local/bin/cleanup.sh + when: manual From f66cc53f9e5de59493a02c036e671ffa7ead5cc9 Mon Sep 17 00:00:00 2001 From: Roshan Syed Date: Fri, 5 Jun 2020 12:31:31 +0000 Subject: [PATCH 8/8] Update .gitlab-ci.yml --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 84995f5a..0fd510c9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,3 +43,5 @@ deploy-rng: - sh /usr/local/bin/update-info.sh - sh /usr/local/bin/cleanup.sh when: manual + tags: + - rng-cc