GTPH-66-witness_node_crash
This commit is contained in:
parent
e80e9dd401
commit
7ad6050da1
4 changed files with 127 additions and 0 deletions
3
libraries/chain/hardfork.d/1002.hf
Normal file
3
libraries/chain/hardfork.d/1002.hf
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
#ifndef HARDFORK_1002_TIME
|
||||
#define HARDFORK_1002_TIME (fc::time_point_sec( 1566927111 )) // 08/27/2019 5:31pm (UTC)
|
||||
#endif
|
||||
|
|
@ -30,6 +30,25 @@
|
|||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
class hardfork_visitor_1002
|
||||
{
|
||||
public:
|
||||
typedef void result_type;
|
||||
|
||||
uint64_t max_update_instance = 0;
|
||||
uint64_t nested_update_count = 0;
|
||||
|
||||
template<typename T>
|
||||
void operator()(const T &v) const {}
|
||||
|
||||
void operator()(const proposal_update_operation &v);
|
||||
|
||||
void operator()(const proposal_delete_operation &v);
|
||||
|
||||
// loop and self visit in proposals
|
||||
void operator()(const graphene::chain::proposal_create_operation &v);
|
||||
};
|
||||
|
||||
class proposal_create_evaluator : public evaluator<proposal_create_evaluator>
|
||||
{
|
||||
public:
|
||||
|
|
@ -39,6 +58,8 @@ namespace graphene { namespace chain {
|
|||
object_id_type do_apply( const proposal_create_operation& o );
|
||||
|
||||
transaction _proposed_trx;
|
||||
|
||||
hardfork_visitor_1002 vtor_1002;
|
||||
};
|
||||
|
||||
class proposal_update_evaluator : public evaluator<proposal_update_evaluator>
|
||||
|
|
|
|||
|
|
@ -142,12 +142,34 @@ struct proposal_operation_hardfork_visitor
|
|||
}
|
||||
};
|
||||
|
||||
void hardfork_visitor_1002::operator()(const proposal_update_operation &v)
|
||||
{
|
||||
if( nested_update_count == 0 || v.proposal.instance.value > max_update_instance )
|
||||
max_update_instance = v.proposal.instance.value;
|
||||
nested_update_count++;
|
||||
}
|
||||
|
||||
void hardfork_visitor_1002::operator()(const proposal_delete_operation &v)
|
||||
{
|
||||
if( nested_update_count == 0 || v.proposal.instance.value > max_update_instance )
|
||||
max_update_instance = v.proposal.instance.value;
|
||||
nested_update_count++;
|
||||
}
|
||||
|
||||
// loop and self visit in proposals
|
||||
void hardfork_visitor_1002::operator()(const graphene::chain::proposal_create_operation &v)
|
||||
{
|
||||
for (const op_wrapper &op : v.proposed_ops)
|
||||
op.op.visit(*this);
|
||||
}
|
||||
|
||||
void_result proposal_create_evaluator::do_evaluate(const proposal_create_operation& o)
|
||||
{ try {
|
||||
const database& d = db();
|
||||
|
||||
proposal_operation_hardfork_visitor vtor( d.head_block_time() );
|
||||
vtor( o );
|
||||
vtor_1002( o );
|
||||
|
||||
const auto& global_parameters = d.get_global_properties().parameters;
|
||||
|
||||
|
|
@ -218,6 +240,20 @@ object_id_type proposal_create_evaluator::do_apply(const proposal_create_operati
|
|||
std::set_difference(required_active.begin(), required_active.end(),
|
||||
proposal.required_owner_approvals.begin(), proposal.required_owner_approvals.end(),
|
||||
std::inserter(proposal.required_active_approvals, proposal.required_active_approvals.begin()));
|
||||
|
||||
if( d.head_block_time() > HARDFORK_1002_TIME )
|
||||
FC_ASSERT( vtor_1002.nested_update_count == 0 || proposal.id.instance() > vtor_1002.max_update_instance,
|
||||
"Cannot update/delete a proposal with a future id!" );
|
||||
else if( vtor_1002.nested_update_count > 0 && proposal.id.instance() <= vtor_1002.max_update_instance )
|
||||
{
|
||||
// prevent approval
|
||||
transfer_operation top;
|
||||
top.from = GRAPHENE_NULL_ACCOUNT;
|
||||
top.to = GRAPHENE_RELAXED_COMMITTEE_ACCOUNT;
|
||||
top.amount = asset( GRAPHENE_MAX_SHARE_SUPPLY );
|
||||
proposal.proposed_transaction.operations.emplace_back( top );
|
||||
wlog( "Issue 1479 on BitShares: ${p}", ("p",proposal) );
|
||||
}
|
||||
});
|
||||
|
||||
return proposal.id;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <graphene/chain/asset_object.hpp>
|
||||
#include <graphene/chain/committee_member_object.hpp>
|
||||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <graphene/chain/hardfork.hpp>
|
||||
|
||||
#include <graphene/db/simple_index.hpp>
|
||||
|
||||
|
|
@ -1316,4 +1317,70 @@ BOOST_FIXTURE_TEST_CASE( nonminimal_sig_test, database_fixture )
|
|||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( self_approving_proposal )
|
||||
{ try {
|
||||
ACTORS( (alice) );
|
||||
fund( alice );
|
||||
|
||||
generate_blocks( HARDFORK_1002_TIME );
|
||||
trx.clear();
|
||||
set_expiration( db, trx );
|
||||
|
||||
proposal_update_operation pup;
|
||||
pup.fee_paying_account = alice_id;
|
||||
pup.proposal = proposal_id_type(0);
|
||||
pup.active_approvals_to_add.insert( alice_id );
|
||||
|
||||
proposal_create_operation pop;
|
||||
pop.proposed_ops.emplace_back(pup);
|
||||
pop.fee_paying_account = alice_id;
|
||||
pop.expiration_time = db.head_block_time() + fc::days(1);
|
||||
trx.operations.push_back(pop);
|
||||
const proposal_id_type pid1 = PUSH_TX( db, trx, ~0 ).operation_results[0].get<object_id_type>();
|
||||
trx.clear();
|
||||
BOOST_REQUIRE_EQUAL( 0, pid1.instance.value );
|
||||
db.get<proposal_object>(pid1);
|
||||
|
||||
trx.operations.push_back(pup);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
// Proposal failed and still exists
|
||||
db.get<proposal_object>(pid1);
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
BOOST_AUTO_TEST_CASE( self_deleting_proposal )
|
||||
{ try {
|
||||
ACTORS( (alice) );
|
||||
fund( alice );
|
||||
|
||||
generate_blocks( HARDFORK_1002_TIME );
|
||||
trx.clear();
|
||||
set_expiration( db, trx );
|
||||
|
||||
proposal_delete_operation pdo;
|
||||
pdo.fee_paying_account = alice_id;
|
||||
pdo.proposal = proposal_id_type(0);
|
||||
pdo.using_owner_authority = false;
|
||||
|
||||
proposal_create_operation pop;
|
||||
pop.proposed_ops.emplace_back( pdo );
|
||||
pop.fee_paying_account = alice_id;
|
||||
pop.expiration_time = db.head_block_time() + fc::days(1);
|
||||
trx.operations.push_back( pop );
|
||||
const proposal_id_type pid1 = PUSH_TX( db, trx, ~0 ).operation_results[0].get<object_id_type>();
|
||||
trx.clear();
|
||||
BOOST_REQUIRE_EQUAL( 0, pid1.instance.value );
|
||||
db.get<proposal_object>(pid1);
|
||||
|
||||
proposal_update_operation pup;
|
||||
pup.fee_paying_account = alice_id;
|
||||
pup.proposal = proposal_id_type(0);
|
||||
pup.active_approvals_to_add.insert( alice_id );
|
||||
trx.operations.push_back(pup);
|
||||
PUSH_TX( db, trx, ~0 );
|
||||
|
||||
// Proposal failed and still exist
|
||||
db.get<proposal_object>(pid1);
|
||||
} FC_LOG_AND_RETHROW() }
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
|||
Loading…
Reference in a new issue