GRPH-60 Added Recursion guard to be 2*witness_node_count
This commit is contained in:
parent
dea5a973ba
commit
31d8e68d89
4 changed files with 79 additions and 2 deletions
|
|
@ -325,6 +325,24 @@ processed_transaction database::validate_transaction( const signed_transaction&
|
|||
return _apply_transaction( trx );
|
||||
}
|
||||
|
||||
class push_proposal_nesting_guard {
|
||||
public:
|
||||
push_proposal_nesting_guard( uint32_t& nesting_counter, const database& db )
|
||||
: orig_value(nesting_counter), counter(nesting_counter)
|
||||
{
|
||||
FC_ASSERT( counter < db.get_global_properties().active_witnesses.size() * 2, "Max proposal nesting depth exceeded!" );
|
||||
counter++;
|
||||
}
|
||||
~push_proposal_nesting_guard()
|
||||
{
|
||||
if( --counter != orig_value )
|
||||
elog( "Unexpected proposal nesting count value: ${n} != ${o}", ("n",counter)("o",orig_value) );
|
||||
}
|
||||
private:
|
||||
const uint32_t orig_value;
|
||||
uint32_t& counter;
|
||||
};
|
||||
|
||||
processed_transaction database::push_proposal(const proposal_object& proposal)
|
||||
{ try {
|
||||
transaction_evaluation_state eval_state(this);
|
||||
|
|
@ -336,6 +354,9 @@ processed_transaction database::push_proposal(const proposal_object& proposal)
|
|||
size_t old_applied_ops_size = _applied_ops.size();
|
||||
|
||||
try {
|
||||
push_proposal_nesting_guard guard( _push_proposal_nesting_depth, *this );
|
||||
if( _undo_db.size() >= _undo_db.max_size() )
|
||||
_undo_db.set_max_size( _undo_db.size() + 1 );
|
||||
auto session = _undo_db.start_undo_session(true);
|
||||
for( auto& op : proposal.proposed_transaction.operations )
|
||||
eval_state.operation_results.emplace_back(apply_operation(eval_state, op));
|
||||
|
|
|
|||
|
|
@ -544,6 +544,8 @@ namespace graphene { namespace chain {
|
|||
node_property_object _node_property_object;
|
||||
fc::hash_ctr_rng<secret_hash_type, 20> _random_number_generator;
|
||||
bool _slow_replays = false;
|
||||
// Counts nested proposal updates
|
||||
uint32_t _push_proposal_nesting_depth = 0;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
|
|
|
|||
|
|
@ -89,7 +89,8 @@ void proposal_update_operation::get_required_authorities( vector<authority>& o )
|
|||
auth.key_auths[k] = 1;
|
||||
auth.weight_threshold = auth.key_auths.size();
|
||||
|
||||
o.emplace_back( std::move(auth) );
|
||||
if( auth.weight_threshold > 0 )
|
||||
o.emplace_back( std::move(auth) );
|
||||
}
|
||||
|
||||
void proposal_update_operation::get_required_active_authorities( flat_set<account_id_type>& a )const
|
||||
|
|
|
|||
|
|
@ -894,7 +894,6 @@ BOOST_FIXTURE_TEST_CASE( max_authority_membership, database_fixture )
|
|||
});
|
||||
|
||||
transaction tx;
|
||||
processed_transaction ptx;
|
||||
|
||||
private_key_type committee_key = init_account_priv_key;
|
||||
// Sam is the creator of accounts
|
||||
|
|
@ -1313,4 +1312,58 @@ BOOST_FIXTURE_TEST_CASE( nonminimal_sig_test, database_fixture )
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( nested_execution )
|
||||
{ try {
|
||||
ACTORS( (alice)(bob) );
|
||||
fund( alice );
|
||||
|
||||
generate_blocks( fc::time_point::now() + fc::hours(1) );
|
||||
set_expiration( db, trx );
|
||||
|
||||
const auto& gpo = db.get_global_properties();
|
||||
|
||||
proposal_create_operation pco;
|
||||
pco.expiration_time = db.head_block_time() + fc::minutes(1);
|
||||
pco.fee_paying_account = alice_id;
|
||||
proposal_id_type inner;
|
||||
{
|
||||
transfer_operation top;
|
||||
top.from = alice_id;
|
||||
top.to = bob_id;
|
||||
top.amount = asset( 10 );
|
||||
pco.proposed_ops.emplace_back( top );
|
||||
trx.operations.push_back( pco );
|
||||
inner = PUSH_TX( db, trx, ~0 ).operation_results.front().get<object_id_type>();
|
||||
trx.clear();
|
||||
pco.proposed_ops.clear();
|
||||
}
|
||||
|
||||
std::vector<proposal_id_type> nested;
|
||||
nested.push_back( inner );
|
||||
for( size_t i = 0; i < gpo.active_witnesses.size() * 2; i++ )
|
||||
{
|
||||
proposal_update_operation pup;
|
||||
pup.fee_paying_account = alice_id;
|
||||
pup.proposal = nested.back();
|
||||
pup.active_approvals_to_add.insert( alice_id );
|
||||
pco.proposed_ops.emplace_back( pup );
|
||||
trx.operations.push_back( pco );
|
||||
nested.push_back( PUSH_TX( db, trx, ~0 ).operation_results.front().get<object_id_type>() );
|
||||
trx.clear();
|
||||
pco.proposed_ops.clear();
|
||||
}
|
||||
|
||||
|
||||
proposal_update_operation pup;
|
||||
pup.fee_paying_account = alice_id;
|
||||
pup.proposal = nested.back();
|
||||
pup.active_approvals_to_add.insert( alice_id );
|
||||
trx.operations.push_back( pup );
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
for( size_t i = 1; i < nested.size(); i++ )
|
||||
BOOST_CHECK_THROW( db.get<proposal_object>( nested[i] ), fc::assert_exception ); // executed successfully -> object removed
|
||||
db.get<proposal_object>( inner ); // asn't executed -> object exists, doesn't throw
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
|||
Loading…
Reference in a new issue