Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Ref #7: Check all declared auths get required
Browse files Browse the repository at this point in the history
  • Loading branch information
nathanielhourt committed Aug 1, 2017
1 parent 5b22f2e commit 856ab75
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 3 deletions.
10 changes: 7 additions & 3 deletions libraries/chain/chain_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,11 @@ void chain_controller::process_message( const ProcessedTransaction& trx, Account
apply_context apply_ctx(*this, _db, trx, message, code);
apply_message(apply_ctx);

// process_message recurses for each notified account, but we only want to run this check at the top level
if (code == message.code && (_skip_flags & skip_authority_check) == false)
EOS_ASSERT(apply_ctx.all_authorizations_used(), tx_irrelevant_auth,
"Message declared an authority it did not need", ("message", message));

output.notify.reserve( apply_ctx.notified.size() );

for( uint32_t i = 0; i < apply_ctx.notified.size(); ++i ) {
Expand Down Expand Up @@ -832,11 +837,10 @@ void chain_controller::initialize_chain(chain_initializer_interface& starter)
std::for_each(messages.begin(), messages.end(), [&](const Message& m) {
MessageOutput output;
ProcessedTransaction trx; /// dummy tranaction required for scope validation
trx.scope = { config::EosContractName, "inita" };
std::sort(trx.scope.begin(), trx.scope.end() );
with_skip_flags( skip_scope_check, [&](){
with_skip_flags(skip_scope_check | skip_transaction_signatures | skip_authority_check, [&](){
process_message(trx,m.code,m,output);
} );
});
});
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ class message_validate_context {
void require_authorization(const types::AccountName& account);
void require_scope(const types::AccountName& account)const;

bool all_authorizations_used() const;

const chain_controller& controller;
const chainbase::database& db; ///< database where state is stored
const chain::Transaction& trx; ///< used to gather the valid read/write scopes
Expand Down
5 changes: 5 additions & 0 deletions libraries/chain/message_handling_contexts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ void message_validate_context::require_authorization(const types::AccountName& a
auto itr = boost::find_if(msg.authorization, [&account](const auto& auth) { return auth.account == account; });
EOS_ASSERT(itr != msg.authorization.end(), tx_missing_auth,
"Transaction is missing required authorization from ${acct}", ("acct", account));
used_authorizations[itr - msg.authorization.begin()] = true;
}

void message_validate_context::require_scope(const types::AccountName& account)const {
Expand All @@ -26,6 +27,10 @@ void message_validate_context::require_scope(const types::AccountName& account)c
}
}

bool message_validate_context::all_authorizations_used() const {
return boost::algorithm::all_of_equal(used_authorizations, true);
}

bool apply_context::has_recipient( const types::AccountName& account )const {
if( msg.code == account ) return true;

Expand Down
22 changes: 22 additions & 0 deletions tests/tests/block_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,28 @@ BOOST_FIXTURE_TEST_CASE(trx_variant, testing_fixture) {
}
}

BOOST_FIXTURE_TEST_CASE(irrelevant_auth, testing_fixture) {
try {
Make_Blockchain(chain)
Make_Account(chain, joe);
chain.produce_blocks();

ProcessedTransaction trx;
trx.scope = sort_names({"joe", "inita"});
trx.emplaceMessage(config::EosContractName, vector<types::AccountPermission>{{"inita", "active"}},
"transfer", types::transfer{"inita", "joe", 50});
trx.expiration = chain.head_block_time() + 100;
trx.set_reference_block(chain.head_block_id());
chain.push_transaction(trx, chain_controller::skip_transaction_signatures);

chain.clear_pending();
chain.push_transaction(trx, chain_controller::skip_transaction_signatures);
chain.clear_pending();

trx.messages.front().authorization.emplace_back(types::AccountPermission{"initb", "active"});
BOOST_CHECK_THROW(chain.push_transaction(trx, chain_controller::skip_transaction_signatures), tx_irrelevant_auth);
} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(name_test) {
using eos::types::Name;
Name temp;
Expand Down

0 comments on commit 856ab75

Please sign in to comment.