add secondary index to get proposals relevant to a particular account
This commit is contained in:
parent
2ee9b01d3f
commit
681f0923fe
9 changed files with 97 additions and 30 deletions
2
docs
2
docs
|
|
@ -1 +1 @@
|
|||
Subproject commit b893895d05b4f0d448aabd4f1d2112a7e35e1354
|
||||
Subproject commit 71ed2984b71d57cab13cdf12074cff150edc1d3d
|
||||
|
|
@ -122,7 +122,10 @@ void database::initialize_indexes()
|
|||
add_index< primary_index<witness_index> >();
|
||||
add_index< primary_index<limit_order_index > >();
|
||||
add_index< primary_index<call_order_index > >();
|
||||
add_index< primary_index<proposal_index > >();
|
||||
|
||||
auto prop_index = add_index< primary_index<proposal_index > >();
|
||||
prop_index->add_secondary_index<required_approval_index>();
|
||||
|
||||
add_index< primary_index<withdraw_permission_index > >();
|
||||
add_index< primary_index<simple_index<vesting_balance_object> > >();
|
||||
add_index< primary_index<worker_index> >();
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ void database::clear_expired_proposals()
|
|||
const proposal_object& proposal = *proposal_expiration_index.begin();
|
||||
processed_transaction result;
|
||||
try {
|
||||
if( proposal.is_authorized_to_execute(this) )
|
||||
if( proposal.is_authorized_to_execute(*this) )
|
||||
{
|
||||
result = push_proposal(proposal);
|
||||
//TODO: Do something with result so plugins can process it.
|
||||
|
|
|
|||
|
|
@ -46,7 +46,31 @@ class proposal_object : public abstract_object<proposal_object>
|
|||
flat_set<account_id_type> available_owner_approvals;
|
||||
flat_set<key_id_type> available_key_approvals;
|
||||
|
||||
bool is_authorized_to_execute(database* db)const;
|
||||
bool is_authorized_to_execute(database& db)const;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief tracks all of the proposal objects that requrie approval of
|
||||
* an individual account.
|
||||
*
|
||||
* @ingroup object
|
||||
* @ingroup protocol
|
||||
*
|
||||
* This is a secondary index on the proposal_index
|
||||
*
|
||||
* @note the set of required approvals is constant
|
||||
*/
|
||||
class required_approval_index : public secondary_index
|
||||
{
|
||||
public:
|
||||
virtual void object_inserted( const object& obj ) override;
|
||||
virtual void object_removed( const object& obj ) override;
|
||||
virtual void about_to_modify( const object& before ) override{};
|
||||
virtual void object_modified( const object& after ) override{};
|
||||
|
||||
void remove( account_id_type a, proposal_id_type p );
|
||||
|
||||
map<account_id_type, set<proposal_id_type> > _account_to_proposals;
|
||||
};
|
||||
|
||||
struct by_expiration{};
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ void_result proposal_update_evaluator::do_apply(const proposal_update_operation&
|
|||
if( _proposal->review_period_time )
|
||||
return void_result();
|
||||
|
||||
if( _proposal->is_authorized_to_execute(&d) )
|
||||
if( _proposal->is_authorized_to_execute(d) )
|
||||
{
|
||||
// All required approvals are satisfied. Execute!
|
||||
_executed_proposal = true;
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
bool proposal_object::is_authorized_to_execute(database* db) const
|
||||
bool proposal_object::is_authorized_to_execute(database& db) const
|
||||
{
|
||||
transaction_evaluation_state dry_run_eval(db);
|
||||
transaction_evaluation_state dry_run_eval(&db);
|
||||
dry_run_eval._is_proposed_trx = true;
|
||||
std::transform(available_active_approvals.begin(), available_active_approvals.end(),
|
||||
std::inserter(dry_run_eval.approved_by, dry_run_eval.approved_by.end()), [](object_id_type id) {
|
||||
|
|
@ -44,13 +44,53 @@ bool proposal_object::is_authorized_to_execute(database* db) const
|
|||
|
||||
// Check all required approvals. If any of them are unsatisfied, return false.
|
||||
for( const auto& id : required_active_approvals )
|
||||
if( !dry_run_eval.check_authority(id(*db), authority::active) )
|
||||
if( !dry_run_eval.check_authority(id(db), authority::active) )
|
||||
return false;
|
||||
for( const auto& id : required_owner_approvals )
|
||||
if( !dry_run_eval.check_authority(id(*db), authority::owner) )
|
||||
if( !dry_run_eval.check_authority(id(db), authority::owner) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void required_approval_index::object_inserted( const object& obj )
|
||||
{
|
||||
assert( dynamic_cast<const proposal_object*>(&obj) );
|
||||
const proposal_object& p = static_cast<const proposal_object&>(obj);
|
||||
|
||||
for( const auto& a : p.required_active_approvals )
|
||||
_account_to_proposals[a].insert( p.id );
|
||||
for( const auto& a : p.required_owner_approvals )
|
||||
_account_to_proposals[a].insert( p.id );
|
||||
for( const auto& a : p.available_active_approvals )
|
||||
_account_to_proposals[a].insert( p.id );
|
||||
for( const auto& a : p.available_owner_approvals )
|
||||
_account_to_proposals[a].insert( p.id );
|
||||
}
|
||||
|
||||
void required_approval_index::remove( account_id_type a, proposal_id_type p )
|
||||
{
|
||||
auto itr = _account_to_proposals.find(a);
|
||||
if( itr != _account_to_proposals.end() )
|
||||
itr->second.erase(p);
|
||||
if( itr->second.size() == 0 )
|
||||
_account_to_proposals.erase(itr);
|
||||
}
|
||||
|
||||
void required_approval_index::object_removed( const object& obj )
|
||||
{
|
||||
assert( dynamic_cast<const proposal_object*>(&obj) );
|
||||
const proposal_object& p = static_cast<const proposal_object&>(obj);
|
||||
|
||||
for( const auto& a : p.required_active_approvals )
|
||||
remove( a, p.id );
|
||||
for( const auto& a : p.required_owner_approvals )
|
||||
remove( a, p.id );
|
||||
for( const auto& a : p.available_active_approvals )
|
||||
remove( a, p.id );
|
||||
for( const auto& a : p.available_owner_approvals )
|
||||
remove( a, p.id );
|
||||
}
|
||||
|
||||
} } // graphene::chain
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit fe7eed6bebac28313e4e7350eb77f8da27f6a427
|
||||
Subproject commit a8b85f6dcc4558b7a9913b59ef5dc19f3b5e62ca
|
||||
|
|
@ -383,12 +383,12 @@ BOOST_AUTO_TEST_CASE( genesis_authority )
|
|||
BOOST_CHECK(prop.review_period_time && *prop.review_period_time == pop.expiration_time - *pop.review_period_seconds);
|
||||
BOOST_CHECK(prop.proposed_transaction.operations.size() == 1);
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 0);
|
||||
BOOST_CHECK(!db.get<proposal_object>(prop.id).is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!db.get<proposal_object>(prop.id).is_authorized_to_execute(db));
|
||||
|
||||
generate_block();
|
||||
BOOST_REQUIRE(db.find_object(prop.id));
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 0);
|
||||
BOOST_CHECK(!db.get<proposal_object>(prop.id).is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!db.get<proposal_object>(prop.id).is_authorized_to_execute(db));
|
||||
trx.operations.clear();
|
||||
trx.signatures.clear();
|
||||
proposal_update_operation uop;
|
||||
|
|
@ -409,7 +409,7 @@ BOOST_AUTO_TEST_CASE( genesis_authority )
|
|||
trx.signatures[key_id_type(6)] = trx.signatures[key_id_type(1)];
|
||||
db.push_transaction(trx);
|
||||
BOOST_CHECK_EQUAL(get_balance(nathan, asset_id_type()(db)), 0);
|
||||
BOOST_CHECK(db.get<proposal_object>(prop.id).is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(db.get<proposal_object>(prop.id).is_authorized_to_execute(db));
|
||||
|
||||
generate_blocks(*prop.review_period_time);
|
||||
uop.key_approvals_to_add = {key_id_type(7)};
|
||||
|
|
@ -457,7 +457,7 @@ BOOST_FIXTURE_TEST_CASE( fired_delegates, database_fixture )
|
|||
sign(trx, key_id_type(), genesis_key);
|
||||
const proposal_object& prop = db.get<proposal_object>(PUSH_TX( db, trx ).operation_results.front().get<object_id_type>());
|
||||
proposal_id_type pid = prop.id;
|
||||
BOOST_CHECK(!pid(db).is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!pid(db).is_authorized_to_execute(db));
|
||||
|
||||
//Genesis key approves of the proposal.
|
||||
proposal_update_operation uop;
|
||||
|
|
@ -484,7 +484,7 @@ BOOST_FIXTURE_TEST_CASE( fired_delegates, database_fixture )
|
|||
trx.signatures[key_id_type(9)] = trx.signatures[key_id_type(1)];
|
||||
trx.sign(key_id_type(), genesis_key);
|
||||
PUSH_TX( db, trx );
|
||||
BOOST_CHECK(pid(db).is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(pid(db).is_authorized_to_execute(db));
|
||||
|
||||
//Time passes... the proposal is now in its review period.
|
||||
generate_blocks(*pid(db).review_period_time);
|
||||
|
|
@ -492,7 +492,7 @@ BOOST_FIXTURE_TEST_CASE( fired_delegates, database_fixture )
|
|||
fc::time_point_sec maintenance_time = db.get_dynamic_global_properties().next_maintenance_time;
|
||||
BOOST_CHECK_LT(maintenance_time.sec_since_epoch(), pid(db).expiration_time.sec_since_epoch());
|
||||
//Yay! The proposal to give nathan more money is authorized.
|
||||
BOOST_CHECK(pid(db).is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(pid(db).is_authorized_to_execute(db));
|
||||
|
||||
nathan = &get_account("nathan");
|
||||
// no money yet
|
||||
|
|
@ -515,7 +515,7 @@ BOOST_FIXTURE_TEST_CASE( fired_delegates, database_fixture )
|
|||
//Time passes... the set of active delegates gets updated.
|
||||
generate_blocks(maintenance_time);
|
||||
//The proposal is no longer authorized, because the active delegates got changed.
|
||||
BOOST_CHECK(!pid(db).is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!pid(db).is_authorized_to_execute(db));
|
||||
// still no money
|
||||
BOOST_CHECK_EQUAL(get_balance(*nathan, asset_id_type()(db)), 5000);
|
||||
|
||||
|
|
@ -563,7 +563,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_two_accounts, database_fixture )
|
|||
const proposal_object& prop = *db.get_index_type<proposal_index>().indices().begin();
|
||||
BOOST_CHECK(prop.required_active_approvals.size() == 2);
|
||||
BOOST_CHECK(prop.required_owner_approvals.size() == 0);
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
|
||||
{
|
||||
proposal_id_type pid = prop.id;
|
||||
|
|
@ -577,7 +577,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_two_accounts, database_fixture )
|
|||
trx.clear();
|
||||
|
||||
BOOST_CHECK(db.find_object(pid) != nullptr);
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
|
||||
uop.active_approvals_to_add = {dan.get_id()};
|
||||
trx.operations.push_back(uop);
|
||||
|
|
@ -627,7 +627,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture )
|
|||
const proposal_object& prop = *db.get_index_type<proposal_index>().indices().begin();
|
||||
BOOST_CHECK(prop.required_active_approvals.size() == 2);
|
||||
BOOST_CHECK(prop.required_owner_approvals.size() == 0);
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
|
||||
{
|
||||
proposal_update_operation uop;
|
||||
|
|
@ -638,7 +638,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture )
|
|||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
BOOST_CHECK_EQUAL(prop.available_active_approvals.size(), 1);
|
||||
|
||||
std::swap(uop.active_approvals_to_add, uop.active_approvals_to_remove);
|
||||
|
|
@ -646,7 +646,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_delete, database_fixture )
|
|||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
BOOST_CHECK_EQUAL(prop.available_active_approvals.size(), 0);
|
||||
}
|
||||
|
||||
|
|
@ -705,7 +705,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture )
|
|||
const proposal_object& prop = *db.get_index_type<proposal_index>().indices().begin();
|
||||
BOOST_CHECK_EQUAL(prop.required_active_approvals.size(), 1);
|
||||
BOOST_CHECK_EQUAL(prop.required_owner_approvals.size(), 1);
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
|
||||
{
|
||||
proposal_update_operation uop;
|
||||
|
|
@ -716,7 +716,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture )
|
|||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
BOOST_CHECK_EQUAL(prop.available_owner_approvals.size(), 1);
|
||||
|
||||
std::swap(uop.owner_approvals_to_add, uop.owner_approvals_to_remove);
|
||||
|
|
@ -724,7 +724,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_delete, database_fixture )
|
|||
trx.sign(nathan_key_obj.id,nathan_key);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
BOOST_CHECK_EQUAL(prop.available_owner_approvals.size(), 0);
|
||||
}
|
||||
|
||||
|
|
@ -784,7 +784,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
|
|||
const proposal_object& prop = *db.get_index_type<proposal_index>().indices().begin();
|
||||
BOOST_CHECK_EQUAL(prop.required_active_approvals.size(), 1);
|
||||
BOOST_CHECK_EQUAL(prop.required_owner_approvals.size(), 1);
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
|
||||
{
|
||||
proposal_id_type pid = prop.id;
|
||||
|
|
@ -797,7 +797,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
|
|||
trx.sign(dan_key_obj.id,dan_key);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
BOOST_CHECK_EQUAL(prop.available_key_approvals.size(), 1);
|
||||
|
||||
std::swap(uop.key_approvals_to_add, uop.key_approvals_to_remove);
|
||||
|
|
@ -806,7 +806,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
|
|||
trx.sign(dan_key_obj.id,dan_key);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
BOOST_CHECK_EQUAL(prop.available_key_approvals.size(), 0);
|
||||
|
||||
std::swap(uop.key_approvals_to_add, uop.key_approvals_to_remove);
|
||||
|
|
@ -817,7 +817,7 @@ BOOST_FIXTURE_TEST_CASE( proposal_owner_authority_complete, database_fixture )
|
|||
trx.sign(dan_key_obj.id,dan_key);
|
||||
PUSH_TX( db, trx );
|
||||
trx.clear();
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(!prop.is_authorized_to_execute(db));
|
||||
BOOST_CHECK_EQUAL(prop.available_key_approvals.size(), 1);
|
||||
|
||||
uop.key_approvals_to_add.clear();
|
||||
|
|
|
|||
|
|
@ -611,7 +611,7 @@ BOOST_FIXTURE_TEST_CASE( change_block_interval, database_fixture )
|
|||
trx.sign(get_account("init6").active.get_keys().front(),delegate_priv_key);
|
||||
trx.sign(get_account("init7").active.get_keys().front(),delegate_priv_key);
|
||||
db.push_transaction(trx);
|
||||
BOOST_CHECK(proposal_id_type()(db).is_authorized_to_execute(&db));
|
||||
BOOST_CHECK(proposal_id_type()(db).is_authorized_to_execute(db));
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL(db.get_global_properties().parameters.block_interval, 5);
|
||||
|
|
|
|||
Loading…
Reference in a new issue