提交 e453f396 编写于 作者: K Kayan

Merge branch 'subjectivelimit' of github.com:taokayan/eos into subjectivelimit

......@@ -651,7 +651,8 @@ struct controller_impl {
transaction_trace_ptr push_transaction( const transaction_metadata_ptr& trx,
fc::time_point deadline,
bool implicit,
uint32_t billed_cpu_time_us )
uint32_t billed_cpu_time_us,
bool subjective = true)
{
FC_ASSERT(deadline != fc::time_point(), "deadline cannot be uninitialized");
......@@ -668,7 +669,7 @@ struct controller_impl {
} else {
trx_context.init_for_input_trx( trx->packed_trx.get_unprunable_size(),
trx->packed_trx.get_prunable_size(),
trx->trx.signatures.size() );
trx->trx.signatures.size(), subjective);
}
if( trx_context.can_subjectively_fail && pending->_block_status == controller::block_status::incomplete ) {
......@@ -692,7 +693,7 @@ struct controller_impl {
}
trx_context.exec();
trx_context.finalize(); // Automatically rounds up network and CPU usage in trace and bills payers if successful
trx_context.finalize(subjective); // Automatically rounds up network and CPU usage in trace and bills payers if successful
auto restore = make_block_restore_point();
......@@ -837,7 +838,7 @@ struct controller_impl {
if( receipt.trx.contains<packed_transaction>() ) {
auto& pt = receipt.trx.get<packed_transaction>();
auto mtrx = std::make_shared<transaction_metadata>(pt);
trace = push_transaction( mtrx, fc::time_point::maximum(), false, receipt.cpu_usage_us );
trace = push_transaction( mtrx, fc::time_point::maximum(), false, receipt.cpu_usage_us, false);
} else if( receipt.trx.contains<transaction_id_type>() ) {
trace = push_scheduled_transaction( receipt.trx.get<transaction_id_type>(), fc::time_point::maximum(), receipt.cpu_usage_us );
} else {
......
......@@ -2,6 +2,7 @@
#include <eosio/chain/exceptions.hpp>
#include <eosio/chain/types.hpp>
#include <chainbase/chainbase.hpp>
#include <set>
namespace eosio { namespace chain { namespace resource_limits {
namespace impl {
......@@ -65,16 +66,22 @@ namespace eosio { namespace chain { namespace resource_limits {
uint64_t get_block_cpu_limit() const;
uint64_t get_block_net_limit() const;
int64_t get_account_cpu_limit( const account_name& name ) const;
int64_t get_account_net_limit( const account_name& name ) const;
int64_t get_account_cpu_limit( const account_name& name, bool subjective = true) const;
int64_t get_account_net_limit( const account_name& name, bool subjective = true) const;
account_resource_limit get_account_cpu_limit_ex( const account_name& name ) const;
account_resource_limit get_account_net_limit_ex( const account_name& name ) const;
account_resource_limit get_account_cpu_limit_ex( const account_name& name, bool subjective = true) const;
account_resource_limit get_account_net_limit_ex( const account_name& name, bool subjective = true) const;
int64_t get_account_ram_usage( const account_name& name ) const;
void add_greylist(const account_name &name);
void remove_greylist(const account_name &name);
bool is_greylisted(const account_name &name) const;
const std::set<account_name> &get_greylisted_account() const { return _greylisted_accounts; }
private:
chainbase::database& _db;
std::set<account_name> _greylisted_accounts; // #4368 access to extended CPU/Net virtual resources should be subjective
};
} } } /// eosio::chain
......
......@@ -6,7 +6,7 @@ namespace eosio { namespace chain {
class transaction_context {
private:
void init( uint64_t initial_net_usage );
void init( uint64_t initial_net_usage, bool subjective = true);
public:
......@@ -19,12 +19,13 @@ namespace eosio { namespace chain {
void init_for_input_trx( uint64_t packed_trx_unprunable_size,
uint64_t packed_trx_prunable_size,
uint32_t num_signatures );
uint32_t num_signatures,
bool subjective = true);
void init_for_deferred_trx( fc::time_point published );
void exec();
void finalize();
void finalize(bool subjective = true);
void squash();
void undo();
......
......@@ -334,12 +334,12 @@ uint64_t resource_limits_manager::get_block_net_limit() const {
return config.net_limit_parameters.max - state.pending_net_usage;
}
int64_t resource_limits_manager::get_account_cpu_limit( const account_name& name ) const {
auto arl = get_account_cpu_limit_ex(name);
int64_t resource_limits_manager::get_account_cpu_limit( const account_name& name, bool subjective ) const {
auto arl = get_account_cpu_limit_ex(name, subjective);
return arl.available;
}
account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const account_name& name ) const {
account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, bool subjective) const {
const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name);
......@@ -356,7 +356,7 @@ account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const
uint128_t window_size = config.account_cpu_usage_average_window;
uint128_t virtual_cpu_capacity_in_window = (uint128_t)state.virtual_cpu_limit * window_size;
uint128_t virtual_cpu_capacity_in_window = (uint128_t)((subjective && is_greylisted(name)) ? config.cpu_limit_parameters.max : state.virtual_cpu_limit) * window_size;
uint128_t user_weight = (uint128_t)cpu_weight;
uint128_t all_user_weight = (uint128_t)state.total_cpu_weight;
......@@ -373,12 +373,12 @@ account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const
return arl;
}
int64_t resource_limits_manager::get_account_net_limit( const account_name& name ) const {
auto arl = get_account_net_limit_ex(name);
int64_t resource_limits_manager::get_account_net_limit( const account_name& name, bool subjective) const {
auto arl = get_account_net_limit_ex(name, subjective);
return arl.available;
}
account_resource_limit resource_limits_manager::get_account_net_limit_ex( const account_name& name ) const {
account_resource_limit resource_limits_manager::get_account_net_limit_ex( const account_name& name, bool subjective) const {
const auto& config = _db.get<resource_limits_config_object>();
const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name);
......@@ -394,7 +394,7 @@ account_resource_limit resource_limits_manager::get_account_net_limit_ex( const
uint128_t window_size = config.account_net_usage_average_window;
uint128_t virtual_network_capacity_in_window = state.virtual_net_limit * window_size;
uint128_t virtual_network_capacity_in_window = (uint128_t)((subjective && is_greylisted(name)) ? config.net_limit_parameters.max : state.virtual_net_limit) * window_size;
uint128_t user_weight = (uint128_t)net_weight;
uint128_t all_user_weight = (uint128_t)state.total_net_weight;
......@@ -412,5 +412,16 @@ account_resource_limit resource_limits_manager::get_account_net_limit_ex( const
return arl;
}
bool resource_limits_manager::is_greylisted(const account_name &name) const {
return (_greylisted_accounts.find(name) != _greylisted_accounts.end());
}
void resource_limits_manager::add_greylist(const account_name &name) {
_greylisted_accounts.insert(name);
}
void resource_limits_manager::remove_greylist(const account_name &name) {
_greylisted_accounts.erase(name);
}
} } } /// eosio::chain::resource_limits
......@@ -27,7 +27,7 @@ namespace eosio { namespace chain {
FC_ASSERT( trx.transaction_extensions.size() == 0, "we don't support any extensions yet" );
}
void transaction_context::init(uint64_t initial_net_usage )
void transaction_context::init(uint64_t initial_net_usage, bool subjective)
{
FC_ASSERT( !is_initialized, "cannot initialize twice" );
const static int64_t large_number_no_overflow = std::numeric_limits<int64_t>::max()/2;
......@@ -88,10 +88,10 @@ namespace eosio { namespace chain {
int64_t account_net_limit = large_number_no_overflow;
int64_t account_cpu_limit = large_number_no_overflow;
for( const auto& a : bill_to_accounts ) {
auto net_limit = rl.get_account_net_limit(a);
auto net_limit = rl.get_account_net_limit(a, subjective);
if( net_limit >= 0 )
account_net_limit = std::min( account_net_limit, net_limit );
auto cpu_limit = rl.get_account_cpu_limit(a);
auto cpu_limit = rl.get_account_cpu_limit(a, subjective);
if( cpu_limit >= 0 )
account_cpu_limit = std::min( account_cpu_limit, cpu_limit );
}
......@@ -134,12 +134,13 @@ namespace eosio { namespace chain {
void transaction_context::init_for_implicit_trx( uint64_t initial_net_usage )
{
published = control.pending_block_time();
init( initial_net_usage );
init( initial_net_usage, false);
}
void transaction_context::init_for_input_trx( uint64_t packed_trx_unprunable_size,
uint64_t packed_trx_prunable_size,
uint32_t num_signatures )
uint32_t num_signatures,
bool subjective)
{
const auto& cfg = control.get_global_properties().configuration;
......@@ -168,7 +169,7 @@ namespace eosio { namespace chain {
control.validate_expiration( trx );
control.validate_tapos( trx );
control.validate_referenced_accounts( trx );
init( initial_net_usage );
init( initial_net_usage, subjective);
record_transaction( id, trx.expiration ); /// checks for dupes
}
......@@ -200,7 +201,7 @@ namespace eosio { namespace chain {
}
}
void transaction_context::finalize() {
void transaction_context::finalize(bool subjective) {
FC_ASSERT( is_initialized, "must first initialize" );
const static int64_t large_number_no_overflow = std::numeric_limits<int64_t>::max()/2;
......@@ -222,10 +223,10 @@ namespace eosio { namespace chain {
int64_t account_net_limit = large_number_no_overflow;
int64_t account_cpu_limit = large_number_no_overflow;
for( const auto& a : bill_to_accounts ) {
auto net_limit = rl.get_account_net_limit(a);
auto net_limit = rl.get_account_net_limit(a, subjective);
if( net_limit >= 0 )
account_net_limit = std::min( account_net_limit, net_limit );
auto cpu_limit = rl.get_account_cpu_limit(a);
auto cpu_limit = rl.get_account_cpu_limit(a, subjective);
if( cpu_limit >= 0 )
account_cpu_limit = std::min( account_cpu_limit, cpu_limit );
}
......
......@@ -76,6 +76,12 @@ void producer_api_plugin::plugin_startup() {
INVOKE_R_V(producer, get_runtime_options), 201),
CALL(producer, producer, update_runtime_options,
INVOKE_V_R(producer, update_runtime_options, producer_plugin::runtime_options), 201),
CALL(producer, producer, add_greylist_accounts,
INVOKE_V_R(producer, add_greylist_accounts, producer_plugin::greylist_params), 201),
CALL(producer, producer, remove_greylist_accounts,
INVOKE_V_R(producer, remove_greylist_accounts, producer_plugin::greylist_params), 201),
CALL(producer, producer, get_greylist,
INVOKE_R_V(producer, get_greylist), 201),
});
}
......
......@@ -23,6 +23,10 @@ public:
fc::optional<int32_t> max_irreversible_block_age;
};
struct greylist_params {
std::vector<account_name> accounts;
};
producer_plugin();
virtual ~producer_plugin();
......@@ -44,6 +48,10 @@ public:
void update_runtime_options(const runtime_options& options);
runtime_options get_runtime_options() const;
void add_greylist_accounts(const greylist_params& params);
void remove_greylist_accounts(const greylist_params& params);
greylist_params get_greylist() const;
signal<void(const chain::producer_confirmation&)> confirmed_block;
private:
std::shared_ptr<class producer_plugin_impl> my;
......@@ -52,3 +60,4 @@ private:
} //eosio
FC_REFLECT(eosio::producer_plugin::runtime_options, (max_transaction_time)(max_irreversible_block_age));
FC_REFLECT(eosio::producer_plugin::greylist_params, (accounts));
......@@ -433,6 +433,8 @@ void producer_plugin::set_program_options(
" KEOSD:<data> \tis the URL where keosd is available and the approptiate wallet(s) are unlocked")
("keosd-provider-timeout", boost::program_options::value<int32_t>()->default_value(5),
"Limits the maximum time (in milliseconds) that is allowd for sending blocks to a keosd provider for signing")
("greylist-account", boost::program_options::value<vector<string>>()->composing()->multitoken(),
"account that can not access to extended CPU/NET virtual resources")
;
config_file_options.add(producer_options);
}
......@@ -569,6 +571,15 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_
return my->on_incoming_transaction_async(trx, persist_until_expired, next );
});
if (options.count("greylist-account")) {
std::vector<std::string> greylist = options["greylist-account"].as<std::vector<std::string>>();
greylist_params param;
for (auto &a : greylist) {
param.accounts.push_back(account_name(a));
}
add_greylist_accounts(param);
}
} FC_LOG_AND_RETHROW() }
void producer_plugin::plugin_startup()
......@@ -667,7 +678,34 @@ producer_plugin::runtime_options producer_plugin::get_runtime_options() const {
};
}
void producer_plugin::add_greylist_accounts(const greylist_params& params) {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
auto& rm = chain.get_mutable_resource_limits_manager();
for (auto &acc : params.accounts) {
rm.add_greylist(acc);
}
}
void producer_plugin::remove_greylist_accounts(const greylist_params& params) {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
auto& rm = chain.get_mutable_resource_limits_manager();
for (auto &acc : params.accounts) {
rm.remove_greylist(acc);
}
}
producer_plugin::greylist_params producer_plugin::get_greylist() const {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
const auto& rm = chain.get_resource_limits_manager();
greylist_params result;
const auto& list = rm.get_greylisted_account();
result.accounts.reserve(list.size());
for (auto &acc: list) {
result.accounts.push_back(acc);
}
return result;
}
optional<fc::time_point> producer_plugin_impl::calculate_next_block_time(const account_name& producer_name) const {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册