From 1a51624235d46a3ac703dd779e6d9f361cf84cf8 Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Thu, 11 Jan 2018 18:33:08 -0500 Subject: [PATCH] properly use the account for read locks in data accesses, rename some "scopes" to locks where appropriate --- libraries/chain/apply_context.cpp | 35 ++++++++++--------- .../include/eosio/chain/apply_context.hpp | 2 +- .../chain/include/eosio/chain/exceptions.hpp | 4 +-- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/libraries/chain/apply_context.cpp b/libraries/chain/apply_context.cpp index 2e95bef61..50be4ba5b 100644 --- a/libraries/chain/apply_context.cpp +++ b/libraries/chain/apply_context.cpp @@ -34,24 +34,25 @@ void apply_context::exec_one() std::sort(_write_scopes.begin(), _write_scopes.end()); } - if (_read_scopes.empty()) { - std::sort(_read_scopes.begin(), _read_scopes.end()); + if (_read_locks.empty()) { + std::sort(_read_locks.begin(), _read_locks.end()); // remove any write_scopes - auto r_iter = _read_scopes.begin(); - for( auto w_iter = _write_scopes.cbegin(); (w_iter != _write_scopes.cend()) && (r_iter != _read_scopes.end()); ++w_iter) { - while(r_iter != _read_scopes.end() && *r_iter < *w_iter) { + auto r_iter = _read_locks.begin(); + for( auto w_iter = _write_scopes.cbegin(); (w_iter != _write_scopes.cend()) && (r_iter != _read_locks.end()); ++w_iter) { + shard_lock w_lock = {receiver, *w_iter}; + while(r_iter != _read_locks.end() && *r_iter < w_lock ) { ++r_iter; } - if (*r_iter == *w_iter) { - r_iter = _read_scopes.erase(r_iter); + if (*r_iter == w_lock) { + r_iter = _read_locks.erase(r_iter); } } } // create a receipt for this vector data_access; - data_access.reserve(_write_scopes.size() + _read_scopes.size()); + data_access.reserve(_write_scopes.size() + _read_locks.size()); for (const auto& scope: _write_scopes) { auto key = boost::make_tuple(scope, receiver); const auto& scope_sequence = mutable_controller.get_database().find(key); @@ -74,19 +75,19 @@ void apply_context::exec_one() } } - for (const auto& scope: _read_scopes) { - auto key = boost::make_tuple(scope, receiver); + for (const auto& lock: _read_locks) { + auto key = boost::make_tuple(lock.scope, lock.account); const auto& scope_sequence = mutable_controller.get_database().find(key); if (scope_sequence == nullptr) { - data_access.emplace_back(data_access_info{data_access_info::read, scope, 0}); + data_access.emplace_back(data_access_info{data_access_info::read, lock.scope, 0}); } else { - data_access.emplace_back(data_access_info{data_access_info::read, scope, scope_sequence->sequence}); + data_access.emplace_back(data_access_info{data_access_info::read, lock.scope, scope_sequence->sequence}); } } results.applied_actions.emplace_back(action_trace {receiver, act, _pending_console_output.str(), 0, 0, move(data_access)}); _pending_console_output = std::ostringstream(); - _read_scopes.clear(); + _read_locks.clear(); _write_scopes.clear(); } @@ -132,7 +133,7 @@ static bool locks_contain(const vector& locks, const account_name& a void apply_context::require_write_lock(const scope_name& scope) { if (allowed_write_locks) { - EOS_ASSERT( locks_contain(*allowed_write_locks, receiver, scope), tx_missing_write_scope, "missing write scope ${scope}", ("scope",scope) ); + EOS_ASSERT( locks_contain(*allowed_write_locks, receiver, scope), tx_missing_write_lock, "missing write lock \"${a}::${s}\"", ("a", receiver)("s",scope) ); } if (!scopes_contain(_write_scopes, scope)) { @@ -142,11 +143,11 @@ void apply_context::require_write_lock(const scope_name& scope) { void apply_context::require_read_lock(const account_name& account, const scope_name& scope) { if (allowed_read_locks) { - EOS_ASSERT( locks_contain(*allowed_read_locks, account, scope), tx_missing_read_scope, "missing read scope ${scope}", ("scope",scope) ); + EOS_ASSERT( locks_contain(*allowed_read_locks, account, scope), tx_missing_read_lock, "missing read lock \"${a}::${s}\"", ("a", account)("s",scope) ); } - if (!scopes_contain(_read_scopes, scope)) { - _read_scopes.emplace_back(scope); + if (!locks_contain(_read_locks, account, scope)) { + _read_locks.emplace_back(shard_lock{account, scope}); } } diff --git a/libraries/chain/include/eosio/chain/apply_context.hpp b/libraries/chain/include/eosio/chain/apply_context.hpp index 52bb7aefe..47f97c106 100644 --- a/libraries/chain/include/eosio/chain/apply_context.hpp +++ b/libraries/chain/include/eosio/chain/apply_context.hpp @@ -193,7 +193,7 @@ class apply_context { vector _inline_actions; ///< queued inline messages std::ostringstream _pending_console_output; - vector _read_scopes; + vector _read_locks; vector _write_scopes; }; diff --git a/libraries/chain/include/eosio/chain/exceptions.hpp b/libraries/chain/include/eosio/chain/exceptions.hpp index 1ab167592..0919f778c 100644 --- a/libraries/chain/include/eosio/chain/exceptions.hpp +++ b/libraries/chain/include/eosio/chain/exceptions.hpp @@ -41,8 +41,8 @@ namespace eosio { namespace chain { FC_DECLARE_DERIVED_EXCEPTION( unsatisfied_permission, eosio::chain::transaction_exception, 3030017, "Unsatisfied permission" ) FC_DECLARE_DERIVED_EXCEPTION( tx_msgs_auth_exceeded, eosio::chain::transaction_exception, 3030018, "Number of transaction messages per authorized account has been exceeded" ) FC_DECLARE_DERIVED_EXCEPTION( tx_msgs_code_exceeded, eosio::chain::transaction_exception, 3030019, "Number of transaction messages per code account has been exceeded" ) - FC_DECLARE_DERIVED_EXCEPTION( tx_missing_read_scope, eosio::chain::transaction_exception, 3030020, "missing required read scope" ) - FC_DECLARE_DERIVED_EXCEPTION( tx_missing_write_scope, eosio::chain::transaction_exception, 3030021, "missing required write scope" ) + FC_DECLARE_DERIVED_EXCEPTION( tx_missing_read_lock, eosio::chain::transaction_exception, 3030020, "missing required read lock" ) + FC_DECLARE_DERIVED_EXCEPTION( tx_missing_write_lock, eosio::chain::transaction_exception, 3030021, "missing required write lock" ) FC_DECLARE_DERIVED_EXCEPTION( wasm_execution_error, eosio::chain::transaction_exception, 3030022, "Runtime Error Processing WASM" ) FC_DECLARE_DERIVED_EXCEPTION( account_name_exists_exception, eosio::chain::action_validate_exception, 3040001, "account name already exists" ) -- GitLab