10 ignore<name> proposal_name,
11 ignore<std::vector<permission_level>> requested,
12 ignore<transaction> trx )
16 std::vector<permission_level> _requested;
19 _ds >> _proposer >> _proposal_name >> _requested;
21 const char* trx_pos = _ds.pos();
22 size_t size = _ds.remaining();
25 require_auth( _proposer );
29 proposals proptable( get_self(), _proposer.value );
30 check( proptable.find( _proposal_name.value ) == proptable.end(),
"proposal with the same name exists" );
32 auto packed_requested = pack(_requested);
33 auto res = check_transaction_authorization(
36 packed_requested.data(), packed_requested.size()
39 check( res > 0,
"transaction authorization failed" );
41 std::vector<char> pkd_trans;
42 pkd_trans.resize(size);
43 memcpy((
char*)pkd_trans.data(), trx_pos, size);
44 proptable.emplace( _proposer, [&](
auto& prop ) {
45 prop.proposal_name = _proposal_name;
46 prop.packed_transaction = pkd_trans;
49 approvals apptable( get_self(), _proposer.value );
50 apptable.emplace( _proposer, [&](
auto&
a ) {
51 a.proposal_name = _proposal_name;
52 a.requested_approvals.reserve( _requested.size() );
53 for (
auto& level : _requested ) {
60 const sysio::binary_extension<sysio::checksum256>& proposal_hash )
62 require_auth( level );
65 proposals proptable( get_self(), proposer.value );
66 auto& prop = proptable.get( proposal_name.value,
"proposal not found" );
67 assert_sha256( prop.packed_transaction.data(), prop.packed_transaction.size(), *proposal_hash );
70 approvals apptable( get_self(), proposer.value );
71 auto apps_it = apptable.find( proposal_name.value );
72 if ( apps_it != apptable.end() ) {
73 auto itr = std::find_if( apps_it->requested_approvals.begin(), apps_it->requested_approvals.end(), [&](
const approval&
a) { return a.level == level; } );
74 check( itr != apps_it->requested_approvals.end(),
"approval is not on the list of requested approvals" );
76 apptable.modify( apps_it, proposer, [&](
auto&
a ) {
77 a.provided_approvals.push_back( approval{ level, current_time_point() } );
78 a.requested_approvals.erase( itr );
81 old_approvals old_apptable( get_self(), proposer.value );
82 auto& apps = old_apptable.get( proposal_name.value,
"proposal not found" );
84 auto itr = std::find( apps.requested_approvals.begin(), apps.requested_approvals.end(), level );
85 check( itr != apps.requested_approvals.end(),
"approval is not on the list of requested approvals" );
87 old_apptable.modify( apps, proposer, [&](
auto&
a ) {
88 a.provided_approvals.push_back( level );
89 a.requested_approvals.erase( itr );
95 require_auth( level );
97 approvals apptable( get_self(), proposer.value );
98 auto apps_it = apptable.find( proposal_name.value );
99 if ( apps_it != apptable.end() ) {
100 auto itr = std::find_if( apps_it->provided_approvals.begin(), apps_it->provided_approvals.end(), [&](
const approval&
a) { return a.level == level; } );
101 check( itr != apps_it->provided_approvals.end(),
"no approval previously granted" );
102 apptable.modify( apps_it, proposer, [&](
auto&
a ) {
103 a.requested_approvals.push_back( approval{ level, current_time_point() } );
104 a.provided_approvals.erase( itr );
107 old_approvals old_apptable( get_self(), proposer.value );
108 auto& apps = old_apptable.get( proposal_name.value,
"proposal not found" );
109 auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level );
110 check( itr != apps.provided_approvals.end(),
"no approval previously granted" );
111 old_apptable.modify( apps, proposer, [&](
auto&
a ) {
112 a.requested_approvals.push_back( level );
113 a.provided_approvals.erase( itr );
119 require_auth( canceler );
121 proposals proptable( get_self(), proposer.value );
122 auto& prop = proptable.get( proposal_name.value,
"proposal not found" );
124 if( canceler != proposer ) {
125 check( unpack<transaction_header>( prop.packed_transaction ).expiration <
sysio::time_point_sec(current_time_point()),
"cannot cancel until expiration" );
127 proptable.erase(prop);
130 approvals apptable( get_self(), proposer.value );
131 auto apps_it = apptable.find( proposal_name.value );
132 if ( apps_it != apptable.end() ) {
133 apptable.erase(apps_it);
135 old_approvals old_apptable( get_self(), proposer.value );
136 auto apps_it = old_apptable.find( proposal_name.value );
137 check( apps_it != old_apptable.end(),
"proposal not found" );
138 old_apptable.erase(apps_it);
143 require_auth( executer );
145 proposals proptable( get_self(), proposer.value );
146 auto& prop = proptable.get( proposal_name.value,
"proposal not found" );
152 approvals apptable( get_self(), proposer.value );
153 auto apps_it = apptable.find( proposal_name.value );
154 std::vector<permission_level> approvals;
155 invalidations inv_table( get_self(), get_self().
value );
156 if ( apps_it != apptable.end() ) {
157 approvals.reserve( apps_it->provided_approvals.size() );
158 for (
auto&
p : apps_it->provided_approvals ) {
159 auto it = inv_table.find(
p.level.actor.value );
160 if ( it == inv_table.end() || it->last_invalidation_time <
p.time ) {
161 approvals.push_back(
p.level);
164 apptable.erase(apps_it);
166 old_approvals old_apptable( get_self(), proposer.value );
167 auto& apps = old_apptable.get( proposal_name.value,
"proposal not found" );
168 for (
auto& level : apps.provided_approvals ) {
169 auto it = inv_table.find( level.actor.value );
170 if ( it == inv_table.end() ) {
171 approvals.push_back( level );
174 old_apptable.erase(apps);
176 auto packed_provided_approvals = pack(approvals);
177 auto res = check_transaction_authorization(
178 prop.packed_transaction.data(), prop.packed_transaction.size(),
180 packed_provided_approvals.data(), packed_provided_approvals.size()
183 check( res > 0,
"transaction authorization failed" );
185 send_deferred( (
uint128_t(proposer.value) << 64) | proposal_name.value, executer,
186 prop.packed_transaction.data(), prop.packed_transaction.size() );
188 proptable.erase(prop);
192 require_auth( account );
193 invalidations inv_table( get_self(), get_self().
value );
194 auto it = inv_table.find( account.value );
195 if ( it == inv_table.end() ) {
196 inv_table.emplace( account, [&](
auto& i) {
198 i.last_invalidation_time = current_time_point();
201 inv_table.modify( it, account, [&](
auto& i) {
202 i.last_invalidation_time = current_time_point();