Skip to content

Commit ab54bcb

Browse files
Merge pull request #1629 from nathanhourt/issue-210-hardfork
Issue #210: Check required_auths on custom_operation
2 parents d98c38a + e4a1018 commit ab54bcb

16 files changed

+446
-298
lines changed

libraries/app/database_api.cpp

+48-42
Original file line numberDiff line numberDiff line change
@@ -2270,34 +2270,36 @@ set<address> database_api::get_potential_address_signatures( const signed_transa
22702270

22712271
set<public_key_type> database_api_impl::get_potential_signatures( const signed_transaction& trx )const
22722272
{
2273-
bool allow_non_immediate_owner = ( _db.head_block_time() >= HARDFORK_CORE_584_TIME );
2273+
auto chain_time = _db.head_block_time();
2274+
bool allow_non_immediate_owner = ( chain_time >= HARDFORK_CORE_584_TIME );
2275+
bool ignore_custom_op_reqd_auths = MUST_IGNORE_CUSTOM_OP_REQD_AUTHS( chain_time );
2276+
22742277
set<public_key_type> result;
2275-
trx.get_required_signatures(
2276-
_db.get_chain_id(),
2277-
flat_set<public_key_type>(),
2278-
[&]( account_id_type id )
2279-
{
2280-
const auto& auth = id(_db).active;
2281-
for( const auto& k : auth.get_keys() )
2282-
result.insert(k);
2283-
return &auth;
2284-
},
2285-
[&]( account_id_type id )
2286-
{
2287-
const auto& auth = id(_db).owner;
2288-
for( const auto& k : auth.get_keys() )
2289-
result.insert(k);
2290-
return &auth;
2291-
},
2292-
allow_non_immediate_owner,
2293-
_db.get_global_properties().parameters.max_authority_depth
2294-
);
2278+
auto get_active = [this, &result]( account_id_type id ){
2279+
const auto& auth = id( _db ).active;
2280+
for( const auto& k : auth.get_keys() )
2281+
result.insert( k );
2282+
return &auth;
2283+
};
2284+
auto get_owner = [this, &result]( account_id_type id ){
2285+
const auto& auth = id( _db ).owner;
2286+
for( const auto& k : auth.get_keys() )
2287+
result.insert( k );
2288+
return &auth;
2289+
};
2290+
2291+
trx.get_required_signatures( _db.get_chain_id(),
2292+
flat_set<public_key_type>(),
2293+
get_active, get_owner,
2294+
allow_non_immediate_owner,
2295+
ignore_custom_op_reqd_auths,
2296+
_db.get_global_properties().parameters.max_authority_depth );
22952297

22962298
// Insert keys in required "other" authories
22972299
flat_set<account_id_type> required_active;
22982300
flat_set<account_id_type> required_owner;
22992301
vector<authority> other;
2300-
trx.get_required_authorities( required_active, required_owner, other );
2302+
trx.get_required_authorities( required_active, required_owner, other, ignore_custom_op_reqd_auths );
23012303
for( const auto& auth : other )
23022304
for( const auto& key : auth.get_keys() )
23032305
result.insert( key );
@@ -2307,26 +2309,30 @@ set<public_key_type> database_api_impl::get_potential_signatures( const signed_t
23072309

23082310
set<address> database_api_impl::get_potential_address_signatures( const signed_transaction& trx )const
23092311
{
2312+
auto chain_time = _db.head_block_time();
2313+
bool allow_non_immediate_owner = ( chain_time >= HARDFORK_CORE_584_TIME );
2314+
bool ignore_custom_op_reqd_auths = MUST_IGNORE_CUSTOM_OP_REQD_AUTHS( chain_time );
2315+
23102316
set<address> result;
2311-
trx.get_required_signatures(
2312-
_db.get_chain_id(),
2313-
flat_set<public_key_type>(),
2314-
[&]( account_id_type id )
2315-
{
2316-
const auto& auth = id(_db).active;
2317-
for( const auto& k : auth.get_addresses() )
2318-
result.insert(k);
2319-
return &auth;
2320-
},
2321-
[&]( account_id_type id )
2322-
{
2323-
const auto& auth = id(_db).owner;
2324-
for( const auto& k : auth.get_addresses() )
2325-
result.insert(k);
2326-
return &auth;
2327-
},
2328-
_db.get_global_properties().parameters.max_authority_depth
2329-
);
2317+
auto get_active = [this, &result]( account_id_type id ){
2318+
const auto& auth = id( _db ).active;
2319+
for( const auto& k : auth.get_addresses() )
2320+
result.insert( k );
2321+
return &auth;
2322+
};
2323+
auto get_owner = [this, &result]( account_id_type id ) {
2324+
const auto& auth = id( _db ).owner;
2325+
for (const auto& k : auth.get_addresses())
2326+
result.insert( k );
2327+
return &auth;
2328+
};
2329+
2330+
trx.get_required_signatures( _db.get_chain_id(),
2331+
flat_set<public_key_type>(),
2332+
get_active, get_owner,
2333+
allow_non_immediate_owner,
2334+
ignore_custom_op_reqd_auths,
2335+
_db.get_global_properties().parameters.max_authority_depth );
23302336
return result;
23312337
}
23322338

@@ -2365,7 +2371,7 @@ bool database_api_impl::verify_account_authority( const string& account_name_or_
23652371
graphene::chain::verify_authority(ops, keys,
23662372
[this]( account_id_type id ){ return &id(_db).active; },
23672373
[this]( account_id_type id ){ return &id(_db).owner; },
2368-
true );
2374+
true, MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(_db.head_block_time()) );
23692375
}
23702376
catch (fc::exception& ex)
23712377
{

libraries/chain/db_block.cpp

+6-7
Original file line numberDiff line numberDiff line change
@@ -644,13 +644,12 @@ processed_transaction database::_apply_transaction(const signed_transaction& trx
644644
if( !(skip & skip_transaction_signatures) )
645645
{
646646
bool allow_non_immediate_owner = ( head_block_time() >= HARDFORK_CORE_584_TIME );
647-
auto get_active = [&]( account_id_type id ) { return &id(*this).active; };
648-
auto get_owner = [&]( account_id_type id ) { return &id(*this).owner; };
649-
trx.verify_authority( chain_id,
650-
get_active,
651-
get_owner,
652-
allow_non_immediate_owner,
653-
get_global_properties().parameters.max_authority_depth );
647+
auto get_active = [this]( account_id_type id ) { return &id(*this).active; };
648+
auto get_owner = [this]( account_id_type id ) { return &id(*this).owner; };
649+
650+
trx.verify_authority(chain_id, get_active, get_owner, allow_non_immediate_owner,
651+
MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(head_block_time()),
652+
get_global_properties().parameters.max_authority_depth);
654653
}
655654

656655
//Skip all manner of expiration and TaPoS checking if we're on block 1; It's impossible that the transaction is

libraries/chain/db_notify.cpp

+30-18
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <graphene/chain/vesting_balance_object.hpp>
1818
#include <graphene/chain/transaction_history_object.hpp>
1919
#include <graphene/chain/impacted.hpp>
20+
#include <graphene/chain/hardfork.hpp>
2021

2122
using namespace fc;
2223
using namespace graphene::chain;
@@ -25,8 +26,13 @@ using namespace graphene::chain;
2526
struct get_impacted_account_visitor
2627
{
2728
flat_set<account_id_type>& _impacted;
28-
get_impacted_account_visitor( flat_set<account_id_type>& impact ):_impacted(impact) {}
29-
typedef void result_type;
29+
bool _ignore_custom_op_reqd_auths;
30+
31+
get_impacted_account_visitor( flat_set<account_id_type>& impact, bool ignore_custom_operation_required_auths )
32+
: _impacted( impact ), _ignore_custom_op_reqd_auths( ignore_custom_operation_required_auths )
33+
{}
34+
35+
using result_type = void;
3036

3137
void operator()( const transfer_operation& op )
3238
{
@@ -154,7 +160,7 @@ struct get_impacted_account_visitor
154160
_impacted.insert( op.fee_payer() ); // fee_paying_account
155161
vector<authority> other;
156162
for( const auto& proposed_op : op.proposed_ops )
157-
operation_get_required_authorities( proposed_op.op, _impacted, _impacted, other );
163+
operation_get_required_authorities( proposed_op.op, _impacted, _impacted, other, _ignore_custom_op_reqd_auths );
158164
for( auto& o : other )
159165
add_authority_accounts( _impacted, o );
160166
}
@@ -214,6 +220,8 @@ struct get_impacted_account_visitor
214220
void operator()( const custom_operation& op )
215221
{
216222
_impacted.insert( op.fee_payer() ); // payer
223+
if( !_ignore_custom_op_reqd_auths )
224+
_impacted.insert( op.required_auths.begin(), op.required_auths.end() );
217225
}
218226
void operator()( const assert_operation& op )
219227
{
@@ -283,20 +291,17 @@ struct get_impacted_account_visitor
283291
}
284292
};
285293

286-
void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
287-
{
288-
get_impacted_account_visitor vtor = get_impacted_account_visitor( result );
294+
void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result, bool ignore_custom_operation_required_auths ) {
295+
get_impacted_account_visitor vtor = get_impacted_account_visitor( result, ignore_custom_operation_required_auths );
289296
op.visit( vtor );
290297
}
291298

292-
void graphene::chain::transaction_get_impacted_accounts( const transaction& tx, flat_set<account_id_type>& result )
293-
{
299+
void graphene::chain::transaction_get_impacted_accounts( const transaction& tx, flat_set<account_id_type>& result, bool ignore_custom_operation_required_auths ) {
294300
for( const auto& op : tx.operations )
295-
operation_get_impacted_accounts( op, result );
301+
operation_get_impacted_accounts( op, result, ignore_custom_operation_required_auths );
296302
}
297303

298-
void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accounts )
299-
{
304+
void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accounts, bool ignore_custom_operation_required_auths ) {
300305
if( obj->id.space() == protocol_ids )
301306
{
302307
switch( (object_type)obj->id.type() )
@@ -342,12 +347,14 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
342347
} case proposal_object_type:{
343348
const auto& aobj = dynamic_cast<const proposal_object*>(obj);
344349
FC_ASSERT( aobj != nullptr );
345-
transaction_get_impacted_accounts( aobj->proposed_transaction, accounts );
350+
transaction_get_impacted_accounts( aobj->proposed_transaction, accounts,
351+
ignore_custom_operation_required_auths );
346352
break;
347353
} case operation_history_object_type:{
348354
const auto& aobj = dynamic_cast<const operation_history_object*>(obj);
349355
FC_ASSERT( aobj != nullptr );
350-
operation_get_impacted_accounts( aobj->op, accounts );
356+
operation_get_impacted_accounts( aobj->op, accounts,
357+
ignore_custom_operation_required_auths );
351358
break;
352359
} case withdraw_permission_object_type:{
353360
const auto& aobj = dynamic_cast<const withdraw_permission_object*>(obj);
@@ -404,7 +411,8 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
404411
} case impl_transaction_history_object_type:{
405412
const auto& aobj = dynamic_cast<const transaction_history_object*>(obj);
406413
FC_ASSERT( aobj != nullptr );
407-
transaction_get_impacted_accounts( aobj->trx, accounts );
414+
transaction_get_impacted_accounts( aobj->trx, accounts,
415+
ignore_custom_operation_required_auths );
408416
break;
409417
} case impl_blinded_balance_object_type:{
410418
const auto& aobj = dynamic_cast<const blinded_balance_object*>(obj);
@@ -458,6 +466,7 @@ void database::notify_changed_objects()
458466
if( _undo_db.enabled() )
459467
{
460468
const auto& head_undo = _undo_db.head();
469+
auto chain_time = head_block_time();
461470

462471
// New
463472
if( !new_objects.empty() )
@@ -469,7 +478,8 @@ void database::notify_changed_objects()
469478
new_ids.push_back(item);
470479
auto obj = find_object(item);
471480
if(obj != nullptr)
472-
get_relevant_accounts(obj, new_accounts_impacted);
481+
get_relevant_accounts(obj, new_accounts_impacted,
482+
MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(chain_time));
473483
}
474484

475485
if( new_ids.size() )
@@ -484,7 +494,8 @@ void database::notify_changed_objects()
484494
for( const auto& item : head_undo.old_values )
485495
{
486496
changed_ids.push_back(item.first);
487-
get_relevant_accounts(item.second.get(), changed_accounts_impacted);
497+
get_relevant_accounts(item.second.get(), changed_accounts_impacted,
498+
MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(chain_time));
488499
}
489500

490501
if( changed_ids.size() )
@@ -502,11 +513,12 @@ void database::notify_changed_objects()
502513
removed_ids.emplace_back( item.first );
503514
auto obj = item.second.get();
504515
removed.emplace_back( obj );
505-
get_relevant_accounts(obj, removed_accounts_impacted);
516+
get_relevant_accounts(obj, removed_accounts_impacted,
517+
MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(chain_time));
506518
}
507519

508520
if( removed_ids.size() )
509-
GRAPHENE_TRY_NOTIFY( removed_objects, removed_ids, removed, removed_accounts_impacted)
521+
GRAPHENE_TRY_NOTIFY( removed_objects, removed_ids, removed, removed_accounts_impacted )
510522
}
511523
}
512524
} FC_CAPTURE_AND_LOG( (0) ) }
+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// #210 Check authorities on custom_operation
2+
#ifndef HARDFORK_CORE_210_TIME
3+
#define HARDFORK_CORE_210_TIME (fc::time_point_sec(1893456000)) // Jan 1 00:00:00 2030 (Not yet scheduled)
4+
// Bugfix: pre-HF 210, custom_operation's required_auths field was ignored.
5+
#define MUST_IGNORE_CUSTOM_OP_REQD_AUTHS(chain_time) (chain_time <= HARDFORK_CORE_210_TIME)
6+
#endif

libraries/chain/include/graphene/chain/impacted.hpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,12 @@
3030

3131
namespace graphene { namespace chain {
3232

33-
void operation_get_impacted_accounts(
34-
const graphene::chain::operation& op,
35-
fc::flat_set<graphene::chain::account_id_type>& result );
33+
void operation_get_impacted_accounts( const graphene::chain::operation& op,
34+
fc::flat_set<graphene::chain::account_id_type>& result,
35+
bool ignore_custom_operation_required_auths );
3636

37-
void transaction_get_impacted_accounts(
38-
const graphene::chain::transaction& tx,
39-
fc::flat_set<graphene::chain::account_id_type>& result
40-
);
37+
void transaction_get_impacted_accounts( const graphene::chain::transaction& tx,
38+
fc::flat_set<graphene::chain::account_id_type>& result,
39+
bool ignore_custom_operation_required_auths );
4140

42-
} } // graphene::app
41+
} } // graphene::app

libraries/chain/include/graphene/chain/proposal_evaluator.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ namespace graphene { namespace chain {
5656
object_id_type do_apply( const proposal_create_operation& o );
5757

5858
transaction _proposed_trx;
59+
flat_set<account_id_type> _required_active_auths;
60+
flat_set<account_id_type> _required_owner_auths;
5961

6062
hardfork_visitor_1479 vtor_1479;
6163
};

0 commit comments

Comments
 (0)