Skip to content

Commit

Permalink
Merge branch 'develop' into 'beatrice'
Browse files Browse the repository at this point in the history
Alpha release 06.03.2023

See merge request PBSA/peerplays!215
  • Loading branch information
Vlad Dobromyslov committed Mar 6, 2023
2 parents 142cf5b + c421453 commit f32a51d
Show file tree
Hide file tree
Showing 22 changed files with 1,023 additions and 410 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ RUN \
RUN \
git clone https://github.com/libbitcoin/libbitcoin-build.git && \
cd libbitcoin-build && \
git reset --hard 92c215fc1ffa272bab4d485d369d0306db52d69d && \
./generate3.sh && \
cd ../libbitcoin-explorer && \
./install.sh && \
Expand Down
1 change: 1 addition & 0 deletions Dockerfile.18.04
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ RUN \
RUN \
git clone https://github.com/libbitcoin/libbitcoin-build.git && \
cd libbitcoin-build && \
git reset --hard 92c215fc1ffa272bab4d485d369d0306db52d69d && \
./generate3.sh && \
cd ../libbitcoin-explorer && \
./install.sh && \
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ libbitcoin-explorer setup:
```
git clone https://github.com/libbitcoin/libbitcoin-build.git
cd libbitcoin-build
git reset --hard 92c215fc1ffa272bab4d485d369d0306db52d69d
./generate3.sh
cd ../libbitcoin-explorer
sudo ./install.sh
Expand Down
118 changes: 108 additions & 10 deletions libraries/chain/account_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,54 @@ void verify_authority_accounts( const database& db, const authority& a )
}
}

void verify_account_votes( const database& db, const account_options& options )
// Overwrites the num_son values from the origin to the destination for those sidechains which are found in the origin.
// Keeps the values of num_son for the sidechains which are found in the destination, but not in the origin.
// Returns false if an error is detected.
bool merge_num_sons( flat_map<sidechain_type, uint16_t>& destination,
const flat_map<sidechain_type, uint16_t>& origin,
fc::optional<time_point_sec> head_block_time = {})
{
const auto active_sidechains = head_block_time.valid() ? active_sidechain_types(*head_block_time) : all_sidechain_types;
bool success = true;

for (const auto &ns : origin)
{
destination[ns.first] = ns.second;
if (active_sidechains.find(ns.first) == active_sidechains.end())
{
success = false;
}
}

return success;
}

flat_map<sidechain_type, uint16_t> count_SON_votes_per_sidechain( const flat_set<vote_id_type>& votes )
{
flat_map<sidechain_type, uint16_t> SON_votes_per_sidechain = account_options::ext::empty_num_son();

for (const auto &vote : votes)
{
switch (vote.type())
{
case vote_id_type::son_bitcoin:
SON_votes_per_sidechain[sidechain_type::bitcoin]++;
break;
case vote_id_type::son_hive:
SON_votes_per_sidechain[sidechain_type::hive]++;
break;
case vote_id_type::son_ethereum:
SON_votes_per_sidechain[sidechain_type::ethereum]++;
break;
default:
break;
}
}

return SON_votes_per_sidechain;
}

void verify_account_votes( const database& db, const account_options& options, fc::optional<account_object> account = {} )
{
// ensure account's votes satisfy requirements
// NB only the part of vote checking that requires chain state is here,
Expand All @@ -69,14 +116,40 @@ void verify_account_votes( const database& db, const account_options& options )
FC_ASSERT( options.num_committee <= chain_params.maximum_committee_count,
"Voted for more committee members than currently allowed (${c})", ("c", chain_params.maximum_committee_count) );
FC_ASSERT( chain_params.extensions.value.maximum_son_count.valid() , "Invalid maximum son count" );

flat_map<sidechain_type, uint16_t> merged_num_sons = account_options::ext::empty_num_son();

// Merge with existing account if exists
if ( account.valid() && account->options.extensions.value.num_son.valid())
{
merge_num_sons( merged_num_sons, *account->options.extensions.value.num_son, db.head_block_time() );
}

// Apply update operation on top
if ( options.extensions.value.num_son.valid() )
{
for(const auto& num_sons : *options.extensions.value.num_son)
{
FC_ASSERT( num_sons.second <= *chain_params.extensions.value.maximum_son_count,
"Voted for more sons than currently allowed (${c})", ("c", *chain_params.extensions.value.maximum_son_count) );
}
merge_num_sons( merged_num_sons, *options.extensions.value.num_son, db.head_block_time() );
}

for(const auto& num_sons : merged_num_sons)
{
FC_ASSERT( num_sons.second <= *chain_params.extensions.value.maximum_son_count,
"Voted for more sons than currently allowed (${c})", ("c", *chain_params.extensions.value.maximum_son_count) );
}

// Count the votes for SONs and confirm that the account did not vote for less SONs than num_son
flat_map<sidechain_type, uint16_t> SON_votes_per_sidechain = count_SON_votes_per_sidechain(options.votes);

for (const auto& number_of_votes : SON_votes_per_sidechain)
{
// Number of votes of account_options are also checked in account_options::do_evaluate,
// but there we are checking the value before merging num_sons, so the values should be checked again
const auto sidechain = number_of_votes.first;
FC_ASSERT( number_of_votes.second >= merged_num_sons[sidechain],
"Voted for less sons than specified in num_son (votes ${v} < num_son ${ns}) for sidechain ${s}",
("v", number_of_votes.second) ("ns", merged_num_sons[sidechain]) ("s", sidechain) );
}

FC_ASSERT( db.find_object(options.voting_account), "Invalid proxy account specified." );

uint32_t max_vote_id = gpo.next_available_vote_id;
Expand Down Expand Up @@ -191,9 +264,10 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
obj.active = o.active;
obj.options = o.options;

if (!obj.options.extensions.value.num_son.valid())
obj.options.extensions.value.num_son = account_options::ext::empty_num_son();
if ( o.options.extensions.value.num_son.valid() )
{
obj.options.extensions.value = account_options::ext();
merge_num_sons( *obj.options.extensions.value.num_son, *o.options.extensions.value.num_son );
}

obj.statistics = d.create<account_statistics_object>([&obj](account_statistics_object& s){
Expand Down Expand Up @@ -295,7 +369,7 @@ void_result account_update_evaluator::do_evaluate( const account_update_operatio
acnt = &o.account(d);

if( o.new_options.valid() )
verify_account_votes( d, *o.new_options );
verify_account_votes( d, *o.new_options, *acnt );

return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }
Expand Down Expand Up @@ -334,7 +408,31 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
a.active = *o.active;
a.top_n_control_flags = 0;
}
if( o.new_options ) a.options = *o.new_options;

// New num_son structure initialized to 0
flat_map<sidechain_type, uint16_t> new_num_son = account_options::ext::empty_num_son();

// If num_son of existing object is valid, we should merge the existing data
if ( a.options.extensions.value.num_son.valid() )
{
merge_num_sons( new_num_son, *a.options.extensions.value.num_son );
}

// If num_son of the operation are valid, they should merge the existing data
if ( o.new_options )
{
const auto new_options = *o.new_options;

if ( new_options.extensions.value.num_son.valid() )
{
merge_num_sons( new_num_son, *new_options.extensions.value.num_son );
}

a.options = *o.new_options;
}

a.options.extensions.value.num_son = new_num_son;

if( o.extensions.value.owner_special_authority.valid() )
{
a.owner_special_authority = *(o.extensions.value.owner_special_authority);
Expand Down
15 changes: 11 additions & 4 deletions libraries/chain/include/graphene/chain/protocol/account.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,21 +36,28 @@ namespace graphene { namespace chain {
bool is_cheap_name( const string& n );

/// These are the fields which can be updated by the active authority.
struct account_options
struct account_options
{
struct ext
{
/// The number of active son members this account votes the blockchain should appoint
/// Must not exceed the actual number of son members voted for in @ref votes
optional< flat_map<sidechain_type, uint16_t> > num_son = []{
optional< flat_map<sidechain_type, uint16_t> > num_son;

/// Returns and empty num_son map with all sidechains
static flat_map<sidechain_type, uint16_t> empty_num_son()
{
flat_map<sidechain_type, uint16_t> num_son;
for(const auto& active_sidechain_type : all_sidechain_types){
for(const auto& active_sidechain_type : all_sidechain_types)
{
num_son[active_sidechain_type] = 0;
}

return num_son;
}();
}
};


/// The memo key is the key this account will typically use to encrypt/sign transaction memos and other non-
/// validated account activities. This field is here to prevent confusion if the active authority has zero or
/// multiple keys in it.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace graphene
// Buyer purchasing lottery tickets
account_id_type buyer;
// count of tickets to buy
uint64_t tickets_to_buy;
share_type tickets_to_buy;
// amount that can spent
asset amount;

Expand Down Expand Up @@ -83,4 +83,4 @@ FC_REFLECT(graphene::chain::nft_lottery_reward_operation::fee_parameters_type, (
FC_REFLECT(graphene::chain::nft_lottery_end_operation::fee_parameters_type, (fee))
FC_REFLECT(graphene::chain::nft_lottery_token_purchase_operation, (fee)(lottery_id)(buyer)(tickets_to_buy)(amount)(extensions))
FC_REFLECT(graphene::chain::nft_lottery_reward_operation, (fee)(lottery_id)(winner)(amount)(win_percentage)(is_benefactor_reward)(winner_ticket_id)(extensions))
FC_REFLECT(graphene::chain::nft_lottery_end_operation, (fee)(lottery_id)(extensions))
FC_REFLECT(graphene::chain::nft_lottery_end_operation, (fee)(lottery_id)(extensions))
4 changes: 2 additions & 2 deletions libraries/chain/nft_lottery_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ namespace graphene

auto lottery_options = lottery_md_obj.lottery_data->lottery_options;
FC_ASSERT(lottery_options.ticket_price.asset_id == op.amount.asset_id);
FC_ASSERT((double)op.amount.amount.value / lottery_options.ticket_price.amount.value == (double)op.tickets_to_buy);
FC_ASSERT(op.tickets_to_buy * lottery_options.ticket_price.amount.value == op.amount.amount.value);
return void_result();
}
FC_CAPTURE_AND_RETHROW((op))
Expand Down Expand Up @@ -142,4 +142,4 @@ namespace graphene
FC_CAPTURE_AND_RETHROW((op))
}
} // namespace chain
} // namespace graphene
} // namespace graphene
Loading

0 comments on commit f32a51d

Please sign in to comment.