Compare commits

...

10 commits

Author SHA1 Message Date
Srdjan Obucina
b284d10f21 Merge branch 'develop' into feature/rng 2020-08-11 01:22:45 +02:00
Roshan Syed
f66cc53f9e Update .gitlab-ci.yml 2020-06-05 12:31:31 +00:00
Roshan Syed
600cb79dad Updated .gitlab-ci.yml with deploy for rng 2020-06-05 11:48:03 +00:00
Srdjan Obucina
01758b1c47 Fix problem with returning more random numbers than requested 2020-05-28 12:35:33 +02:00
Srdjan Obucina
9444935c38 Merge branch 'feature/rng' of https://github.com/peerplays-network/peerplays into feature/rng 2020-05-25 03:17:41 +02:00
Srdjan Obucina
29d6d7b1f9 Random number wallet api with number storing 2020-05-25 03:12:52 +02:00
Srdjan Obucina
d5eac3f1a7 Introducing random number object, evaluator and operations 2020-05-22 03:34:25 +02:00
Roshan Syed
1f49d5b818 Update .gitlab-ci.yml 2020-05-19 14:02:33 +00:00
Srdjan Obucina
56676b5a58 Implemented parametrized random number retrieval 2020-05-18 15:49:45 +02:00
obucina
be4869a64d
API endpoint for reading random numbers from the witness (#113) 2020-05-17 23:09:15 +02:00
13 changed files with 411 additions and 122 deletions

View file

@ -217,6 +217,10 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
vector<offer_history_object> get_offer_history_by_item(const offer_history_id_type lower_id, const nft_id_type item, uint32_t limit) const; vector<offer_history_object> get_offer_history_by_item(const offer_history_id_type lower_id, const nft_id_type item, uint32_t limit) const;
vector<offer_history_object> get_offer_history_by_bidder(const offer_history_id_type lower_id, const account_id_type bidder_account_id, uint32_t limit) const; vector<offer_history_object> get_offer_history_by_bidder(const offer_history_id_type lower_id, const account_id_type bidder_account_id, uint32_t limit) const;
// rng
vector<uint64_t> get_random_number_ex(uint64_t minimum, uint64_t maximum, uint64_t selections, bool duplicates) const;
uint64_t get_random_number(uint64_t bound) const;
//private: //private:
const account_object* get_account_from_string( const std::string& name_or_id, const account_object* get_account_from_string( const std::string& name_or_id,
bool throw_if_not_found = true ) const; bool throw_if_not_found = true ) const;
@ -2888,6 +2892,60 @@ vector<offer_history_object> database_api_impl::get_offer_history_by_bidder(cons
return result; return result;
} }
//////////////////////////////////////////////////////////////////////
// //
// Random numbers //
// //
//////////////////////////////////////////////////////////////////////
vector<uint64_t> 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<uint64_t> 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<uint64_t> 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<uint64_t> tmpv;
tmpv.reserve(selections);
for (uint64_t i = minimum; i < maximum; i++) {
tmpv.push_back(i);
}
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);
}
}
return v;
}
uint64_t database_api::get_random_number(uint64_t bound) const
{
return my->get_random_number(bound);
}
uint64_t database_api_impl::get_random_number(uint64_t bound) const {
vector<uint64_t> v = get_random_number_ex(0, bound, 1, false);
return v.at(0);
}
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// // // //
// Private methods // // Private methods //

View file

@ -829,7 +829,28 @@ class database_api
vector<offer_history_object> get_offer_history_by_issuer(const offer_history_id_type lower_id, const account_id_type issuer_account_id, uint32_t limit) const; vector<offer_history_object> get_offer_history_by_issuer(const offer_history_id_type lower_id, const account_id_type issuer_account_id, uint32_t limit) const;
vector<offer_history_object> get_offer_history_by_item(const offer_history_id_type lower_id, const nft_id_type item, uint32_t limit) const; vector<offer_history_object> get_offer_history_by_item(const offer_history_id_type lower_id, const nft_id_type item, uint32_t limit) const;
vector<offer_history_object> get_offer_history_by_bidder(const offer_history_id_type lower_id, const account_id_type bidder_account_id, uint32_t limit) const; vector<offer_history_object> get_offer_history_by_bidder(const offer_history_id_type lower_id, const account_id_type bidder_account_id, uint32_t limit) const;
private:
/////////////////////////////
// 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<uint64_t> 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
* @return Random number from segment [0, bound)
*/
uint64_t get_random_number(uint64_t bound) const;
private:
std::shared_ptr< database_api_impl > my; std::shared_ptr< database_api_impl > my;
}; };
@ -999,4 +1020,8 @@ FC_API(graphene::app::database_api,
(get_offer_history_by_issuer) (get_offer_history_by_issuer)
(get_offer_history_by_item) (get_offer_history_by_item)
(get_offer_history_by_bidder) (get_offer_history_by_bidder)
// rngs
(get_random_number_ex)
(get_random_number)
) )

View file

@ -125,6 +125,8 @@ add_library( graphene_chain
nft_evaluator.cpp nft_evaluator.cpp
protocol/nft.cpp protocol/nft.cpp
random_number_evaluator.cpp
${HEADERS} ${HEADERS}
${PROTOCOL_HEADERS} ${PROTOCOL_HEADERS}
"${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp" "${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp"

View file

@ -52,6 +52,7 @@
#include <graphene/chain/custom_permission_object.hpp> #include <graphene/chain/custom_permission_object.hpp>
#include <graphene/chain/custom_account_authority_object.hpp> #include <graphene/chain/custom_account_authority_object.hpp>
#include <graphene/chain/offer_object.hpp> #include <graphene/chain/offer_object.hpp>
#include <graphene/chain/random_number_object.hpp>
#include <graphene/chain/nft_object.hpp> #include <graphene/chain/nft_object.hpp>
@ -85,6 +86,7 @@
#include <graphene/chain/custom_account_authority_evaluator.hpp> #include <graphene/chain/custom_account_authority_evaluator.hpp>
#include <graphene/chain/offer_evaluator.hpp> #include <graphene/chain/offer_evaluator.hpp>
#include <graphene/chain/nft_evaluator.hpp> #include <graphene/chain/nft_evaluator.hpp>
#include <graphene/chain/random_number_evaluator.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp> #include <graphene/chain/protocol/fee_schedule.hpp>
@ -186,6 +188,9 @@ const uint8_t offer_object::type_id;
const uint8_t offer_history_object::space_id; const uint8_t offer_history_object::space_id;
const uint8_t offer_history_object::type_id; const uint8_t offer_history_object::type_id;
const uint8_t random_number_object::space_id;
const uint8_t random_number_object::type_id;
void database::initialize_evaluators() void database::initialize_evaluators()
{ {
_operation_evaluators.resize(255); _operation_evaluators.resize(255);
@ -275,6 +280,7 @@ void database::initialize_evaluators()
register_evaluator<nft_safe_transfer_from_evaluator>(); register_evaluator<nft_safe_transfer_from_evaluator>();
register_evaluator<nft_approve_evaluator>(); register_evaluator<nft_approve_evaluator>();
register_evaluator<nft_set_approval_for_all_evaluator>(); register_evaluator<nft_set_approval_for_all_evaluator>();
register_evaluator<random_number_store_evaluator>();
} }
void database::initialize_indexes() void database::initialize_indexes()
@ -353,6 +359,7 @@ void database::initialize_indexes()
add_index< primary_index<lottery_balance_index > >(); add_index< primary_index<lottery_balance_index > >();
add_index< primary_index<sweeps_vesting_balance_index > >(); add_index< primary_index<sweeps_vesting_balance_index > >();
add_index< primary_index<offer_history_index > >(); add_index< primary_index<offer_history_index > >();
add_index< primary_index<random_number_index > >();
} }

View file

@ -344,6 +344,9 @@ struct get_impacted_account_visitor
void operator()( const finalize_offer_operation& op ) { void operator()( const finalize_offer_operation& op ) {
_impacted.insert( op.fee_paying_account ); _impacted.insert( op.fee_paying_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<account_id_type>& result ) void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )

View file

@ -49,6 +49,7 @@
#include <graphene/chain/protocol/custom_account_authority.hpp> #include <graphene/chain/protocol/custom_account_authority.hpp>
#include <graphene/chain/protocol/offer.hpp> #include <graphene/chain/protocol/offer.hpp>
#include <graphene/chain/protocol/nft_ops.hpp> #include <graphene/chain/protocol/nft_ops.hpp>
#include <graphene/chain/protocol/random_number.hpp>
namespace graphene { namespace chain { namespace graphene { namespace chain {
@ -155,7 +156,8 @@ namespace graphene { namespace chain {
nft_mint_operation, nft_mint_operation,
nft_safe_transfer_from_operation, nft_safe_transfer_from_operation,
nft_approve_operation, nft_approve_operation,
nft_set_approval_for_all_operation nft_set_approval_for_all_operation,
random_number_store_operation
> operation; > operation;
/// @} // operations group /// @} // operations group

View file

@ -0,0 +1,25 @@
#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;
vector<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)
(random_number)
(data) )

View file

@ -176,6 +176,7 @@ namespace graphene { namespace chain {
offer_object_type, offer_object_type,
nft_metadata_type, nft_metadata_type,
nft_object_type, nft_object_type,
random_number_object_type,
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
}; };
@ -241,6 +242,7 @@ namespace graphene { namespace chain {
class offer_object; class offer_object;
class nft_metadata_object; class nft_metadata_object;
class nft_object; class nft_object;
class random_number_object;
typedef object_id< protocol_ids, account_object_type, account_object> account_id_type; 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; typedef object_id< protocol_ids, asset_object_type, asset_object> asset_id_type;
@ -272,6 +274,7 @@ namespace graphene { namespace chain {
typedef object_id< protocol_ids, offer_object_type, offer_object> offer_id_type; typedef object_id< protocol_ids, offer_object_type, offer_object> offer_id_type;
typedef object_id< protocol_ids, nft_metadata_type, nft_metadata_object> nft_metadata_id_type; typedef object_id< protocol_ids, nft_metadata_type, nft_metadata_object> nft_metadata_id_type;
typedef object_id< protocol_ids, nft_object_type, nft_object> nft_id_type; typedef object_id< protocol_ids, nft_object_type, nft_object> nft_id_type;
typedef object_id< protocol_ids, random_number_object_type, random_number_object> random_number_id_type;
// implementation types // implementation types
class global_property_object; class global_property_object;
@ -459,6 +462,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
(offer_object_type) (offer_object_type)
(nft_metadata_type) (nft_metadata_type)
(nft_object_type) (nft_object_type)
(random_number_object_type)
(OBJECT_TYPE_COUNT) (OBJECT_TYPE_COUNT)
) )
FC_REFLECT_ENUM( graphene::chain::impl_object_type, FC_REFLECT_ENUM( graphene::chain::impl_object_type,
@ -535,6 +539,7 @@ FC_REFLECT_TYPENAME( graphene::chain::custom_account_authority_id_type )
FC_REFLECT_TYPENAME( graphene::chain::offer_history_id_type ) FC_REFLECT_TYPENAME( graphene::chain::offer_history_id_type )
FC_REFLECT_TYPENAME( graphene::chain::nft_metadata_id_type ) FC_REFLECT_TYPENAME( graphene::chain::nft_metadata_id_type )
FC_REFLECT_TYPENAME( graphene::chain::nft_id_type ) FC_REFLECT_TYPENAME( graphene::chain::nft_id_type )
FC_REFLECT_TYPENAME( graphene::chain::random_number_id_type )
FC_REFLECT( graphene::chain::void_t, ) FC_REFLECT( graphene::chain::void_t, )

View file

@ -0,0 +1,19 @@
#pragma once
#include <graphene/chain/database.hpp>
#include <graphene/chain/evaluator.hpp>
#include <graphene/chain/protocol/operations.hpp>
#include <graphene/chain/protocol/types.hpp>
namespace graphene { namespace chain {
class random_number_store_evaluator : public evaluator<random_number_store_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

View file

@ -0,0 +1,41 @@
#pragma once
namespace graphene { namespace chain {
using namespace graphene::db;
class random_number_object : public abstract_object<random_number_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 */
vector<uint64_t> random_number; /* random number(s) */
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<by_id>,
member<object, object_id_type, &object::id>
>,
ordered_non_unique< tag<by_account>,
member<random_number_object, account_id_type, &random_number_object::account>
>,
ordered_non_unique< tag<by_timestamp>,
member<random_number_object, time_point_sec, &random_number_object::timestamp>
>
>
>;
using random_number_index = generic_index<random_number_object, random_number_multi_index_type>;
} } // graphene::chain
FC_REFLECT_DERIVED( graphene::chain::random_number_object, (graphene::db::object),
(account) (timestamp)
(random_number) (data) )

View file

@ -0,0 +1,24 @@
#include <graphene/chain/random_number_evaluator.hpp>
#include <graphene/chain/random_number_object.hpp>
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>( [&]( random_number_object& obj ) {
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) ) }
} } // graphene::chain

View file

@ -1654,6 +1654,32 @@ class wallet_api
bool broadcast /* = false */ 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<uint64_t> 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); 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); asset get_total_matched_bet_amount_for_betting_market_group(betting_market_group_id_type group_id);
@ -1926,6 +1952,7 @@ class wallet_api
vector<custom_account_authority_object> get_custom_account_authorities_by_permission_id(custom_permission_id_type permission_id) const; vector<custom_account_authority_object> get_custom_account_authorities_by_permission_id(custom_permission_id_type permission_id) const;
vector<custom_account_authority_object> get_custom_account_authorities_by_permission_name(string owner, string permission_name) const; vector<custom_account_authority_object> get_custom_account_authorities_by_permission_name(string owner, string permission_name) const;
vector<authority> get_active_custom_account_authorities_by_operation(string owner, int operation_type) const; vector<authority> get_active_custom_account_authorities_by_operation(string owner, int operation_type) const;
///////// /////////
// NFT // // NFT //
///////// /////////
@ -2312,6 +2339,8 @@ FC_API( graphene::wallet::wallet_api,
(propose_fee_change) (propose_fee_change)
(propose_dividend_asset_update) (propose_dividend_asset_update)
(approve_proposal) (approve_proposal)
(get_random_number_ex)
(get_random_number)
(dbg_make_uia) (dbg_make_uia)
(dbg_make_mia) (dbg_make_mia)
(dbg_push_blocks) (dbg_push_blocks)

View file

@ -3376,6 +3376,38 @@ public:
return _remote_db->get_active_custom_account_authorities_by_operation(get_account(owner).id, operation_type); return _remote_db->get_active_custom_account_authorities_by_operation(get_account(owner).id, operation_type);
} }
vector<uint64_t> get_random_number_ex(string account,
uint64_t minimum,
uint64_t maximum,
uint64_t selections,
bool duplicates,
bool broadcast)
{
vector<uint64_t> 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<uint64_t> v = get_random_number_ex(account, 0, bound, 1, false, broadcast);
return v.at(0);
}
void dbg_make_uia(string creator, string symbol) void dbg_make_uia(string creator, string symbol)
{ {
asset_options opts; asset_options opts;
@ -4754,6 +4786,23 @@ vector<authority> wallet_api::get_active_custom_account_authorities_by_operation
return my->get_active_custom_account_authorities_by_operation(owner, operation_type); return my->get_active_custom_account_authorities_by_operation(owner, operation_type);
} }
vector<uint64_t> 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 global_property_object wallet_api::get_global_properties() const
{ {
return my->get_global_properties(); return my->get_global_properties();