提交 6b48fcf0 编写于 作者: A Anton Perkov

eosio.msig contract: proposals table separated into two tables (now it's...

eosio.msig contract: proposals table separated into two tables (now it's possible to upgrade system contract using 8Mb of shared memory) #3136
上级 f5e6a07f
......@@ -92,10 +92,16 @@
"base": "",
"fields": [
{"name": "proposal_name", "type": "name"},
{"name": "requested_approvals", "type": "permission_level[]"},
{"name": "provided_approvals", "type": "permission_level[]"},
{"name": "packed_transaction", "type": "bytes"}
]
},{
"name": "approvals_info",
"base": "",
"fields": [
{"name": "proposal_name", "type": "name"},
{"name": "requested_approvals", "type": "permission_level[]"},
{"name": "provided_approvals", "type": "permission_level[]"}
]
}
],
"actions": [{
......@@ -127,6 +133,12 @@
"index_type": "i64",
"key_names" : ["proposal_name"],
"key_types" : ["name"]
},{
"name": "approvals",
"type": "approvals_info",
"index_type": "i64",
"key_names" : ["proposal_name"],
"key_types" : ["name"]
}
],
"ricardian_clauses": []
......
......@@ -50,38 +50,41 @@ void multisig::propose() {
proptable.emplace( proposer, [&]( auto& prop ) {
prop.proposal_name = proposal_name;
prop.packed_transaction = bytes( buffer+trx_pos, buffer+size );
prop.requested_approvals = std::move(requested);
});
approvals apptable( _self, proposer );
apptable.emplace( proposer, [&]( auto& a ) {
a.proposal_name = proposal_name;
a.requested_approvals = std::move(requested);
});
}
void multisig::approve( account_name proposer, name proposal_name, permission_level level ) {
require_auth( level );
proposals proptable( _self, proposer );
auto prop_it = proptable.find( proposal_name );
eosio_assert( prop_it != proptable.end(), "proposal not found" );
approvals apptable( _self, proposer );
auto& apps = apptable.get( proposal_name, "proposal not found" );
auto itr = std::find( prop_it->requested_approvals.begin(), prop_it->requested_approvals.end(), level );
eosio_assert( itr != prop_it->requested_approvals.end(), "approval is not on the list of requested approvals" );
auto itr = std::find( apps.requested_approvals.begin(), apps.requested_approvals.end(), level );
eosio_assert( itr != apps.requested_approvals.end(), "approval is not on the list of requested approvals" );
proptable.modify( prop_it, proposer, [&]( auto& mprop ) {
mprop.provided_approvals.push_back( level );
mprop.requested_approvals.erase( itr );
apptable.modify( apps, proposer, [&]( auto& a ) {
a.provided_approvals.push_back( level );
a.requested_approvals.erase( itr );
});
}
void multisig::unapprove( account_name proposer, name proposal_name, permission_level level ) {
require_auth( level );
proposals proptable( _self, proposer );
auto prop_it = proptable.find( proposal_name );
eosio_assert( prop_it != proptable.end(), "proposal not found" );
auto itr = std::find( prop_it->provided_approvals.begin(), prop_it->provided_approvals.end(), level );
eosio_assert( itr != prop_it->provided_approvals.end(), "no approval previously granted" );
proptable.modify( prop_it, proposer, [&]( auto& mprop ) {
mprop.requested_approvals.push_back(level);
mprop.provided_approvals.erase(itr);
approvals apptable( _self, proposer );
auto& apps = apptable.get( proposal_name, "proposal not found" );
auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level );
eosio_assert( itr != apps.provided_approvals.end(), "no approval previously granted" );
apptable.modify( apps, proposer, [&]( auto& a ) {
a.requested_approvals.push_back(level);
a.provided_approvals.erase(itr);
});
}
......@@ -89,38 +92,44 @@ void multisig::cancel( account_name proposer, name proposal_name, account_name c
require_auth( canceler );
proposals proptable( _self, proposer );
auto prop_it = proptable.find( proposal_name );
eosio_assert( prop_it != proptable.end(), "proposal not found" );
auto& prop = proptable.get( proposal_name, "proposal not found" );
if( canceler != proposer ) {
eosio_assert( unpack<transaction_header>( prop_it->packed_transaction ).expiration < eosio::time_point_sec(now()), "cannot cancel until expiration" );
eosio_assert( unpack<transaction_header>( prop.packed_transaction ).expiration < eosio::time_point_sec(now()), "cannot cancel until expiration" );
}
proptable.erase(prop_it);
approvals apptable( _self, proposer );
auto& apps = apptable.get( proposal_name, "proposal not found" );
proptable.erase(prop);
apptable.erase(apps);
}
void multisig::exec( account_name proposer, name proposal_name, account_name executer ) {
require_auth( executer );
proposals proptable( _self, proposer );
auto prop_it = proptable.find( proposal_name );
eosio_assert( prop_it != proptable.end(), "proposal not found" );
auto& prop = proptable.get( proposal_name, "proposal not found" );
approvals apptable( _self, proposer );
auto& apps = apptable.get( proposal_name, "proposal not found" );
transaction_header trx_header;
datastream<const char*> ds( prop_it->packed_transaction.data(), prop_it->packed_transaction.size() );
datastream<const char*> ds( prop.packed_transaction.data(), prop.packed_transaction.size() );
ds >> trx_header;
eosio_assert( trx_header.expiration >= eosio::time_point_sec(now()), "transaction expired" );
bytes packed_provided_approvals = pack(prop_it->provided_approvals);
auto res = ::check_transaction_authorization( prop_it->packed_transaction.data(), prop_it->packed_transaction.size(),
bytes packed_provided_approvals = pack(apps.provided_approvals);
auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(),
(const char*)0, 0,
packed_provided_approvals.data(), packed_provided_approvals.size()
);
eosio_assert( res > 0, "transaction authorization failed" );
send_deferred( (uint128_t(proposer) << 64) | proposal_name, executer, prop_it->packed_transaction.data(), prop_it->packed_transaction.size() );
send_deferred( (uint128_t(proposer) << 64) | proposal_name, executer, prop.packed_transaction.data(), prop.packed_transaction.size() );
proptable.erase(prop_it);
proptable.erase(prop);
apptable.erase(apps);
}
} /// namespace eosio
......
......@@ -17,13 +17,20 @@ namespace eosio {
private:
struct proposal {
name proposal_name;
vector<permission_level> requested_approvals;
vector<permission_level> provided_approvals;
vector<char> packed_transaction;
auto primary_key()const { return proposal_name.value; }
};
typedef eosio::multi_index<N(proposal),proposal> proposals;
struct approvals_info {
name proposal_name;
vector<permission_level> requested_approvals;
vector<permission_level> provided_approvals;
auto primary_key()const { return proposal_name.value; }
};
typedef eosio::multi_index<N(approvals),approvals_info> approvals;
};
} /// namespace eosio
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册