提交 aa84de49 编写于 作者: K Kayan

refine pull request 4410

上级 f2f7bccf
...@@ -655,15 +655,14 @@ struct controller_impl { ...@@ -655,15 +655,14 @@ struct controller_impl {
transaction_trace_ptr push_transaction( const transaction_metadata_ptr& trx, transaction_trace_ptr push_transaction( const transaction_metadata_ptr& trx,
fc::time_point deadline, fc::time_point deadline,
bool implicit, 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"); FC_ASSERT(deadline != fc::time_point(), "deadline cannot be uninitialized");
transaction_trace_ptr trace; transaction_trace_ptr trace;
try { try {
transaction_context trx_context(self, trx->trx, trx->id); transaction_context trx_context(self, trx->trx, trx->id);
if (subjective && (bool)subjective_cpu_leeway) { if ((bool)subjective_cpu_leeway && pending->_block_status == controller::block_status::incomplete) {
trx_context.leeway = *subjective_cpu_leeway; trx_context.leeway = *subjective_cpu_leeway;
} }
trx_context.deadline = deadline; trx_context.deadline = deadline;
...@@ -676,7 +675,7 @@ struct controller_impl { ...@@ -676,7 +675,7 @@ struct controller_impl {
} else { } else {
trx_context.init_for_input_trx( trx->packed_trx.get_unprunable_size(), trx_context.init_for_input_trx( trx->packed_trx.get_unprunable_size(),
trx->packed_trx.get_prunable_size(), trx->packed_trx.get_prunable_size(),
trx->trx.signatures.size(), subjective); trx->trx.signatures.size());
} }
if( trx_context.can_subjectively_fail && pending->_block_status == controller::block_status::incomplete ) { if( trx_context.can_subjectively_fail && pending->_block_status == controller::block_status::incomplete ) {
...@@ -699,7 +698,7 @@ struct controller_impl { ...@@ -699,7 +698,7 @@ struct controller_impl {
); );
} }
trx_context.exec(); trx_context.exec();
trx_context.finalize(subjective); // Automatically rounds up network and CPU usage in trace and bills payers if successful trx_context.finalize(); // Automatically rounds up network and CPU usage in trace and bills payers if successful
auto restore = make_block_restore_point(); auto restore = make_block_restore_point();
...@@ -844,7 +843,7 @@ struct controller_impl { ...@@ -844,7 +843,7 @@ struct controller_impl {
if( receipt.trx.contains<packed_transaction>() ) { if( receipt.trx.contains<packed_transaction>() ) {
auto& pt = receipt.trx.get<packed_transaction>(); auto& pt = receipt.trx.get<packed_transaction>();
auto mtrx = std::make_shared<transaction_metadata>(pt); auto mtrx = std::make_shared<transaction_metadata>(pt);
trace = push_transaction( mtrx, fc::time_point::maximum(), false, receipt.cpu_usage_us, false); trace = push_transaction( mtrx, fc::time_point::maximum(), false, receipt.cpu_usage_us);
} else if( receipt.trx.contains<transaction_id_type>() ) { } 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 ); trace = push_scheduled_transaction( receipt.trx.get<transaction_id_type>(), fc::time_point::maximum(), receipt.cpu_usage_us );
} else { } else {
...@@ -1613,4 +1612,20 @@ void controller::set_subjective_cpu_leeway(fc::microseconds leeway) { ...@@ -1613,4 +1612,20 @@ void controller::set_subjective_cpu_leeway(fc::microseconds leeway) {
my->subjective_cpu_leeway = leeway; my->subjective_cpu_leeway = leeway;
} }
void controller::add_resource_greylist(const account_name &name) {
my->conf.resource_greylist.insert(name);
}
void controller::remove_resource_greylist(const account_name &name) {
my->conf.resource_greylist.erase(name);
}
bool controller::is_resource_greylisted(const account_name &name) const {
return my->conf.resource_greylist.find(name) != my->conf.resource_greylist.end();
}
const flat_set<account_name> &controller::get_resource_greylist() const {
return my->conf.resource_greylist;
}
} } /// eosio::chain } } /// eosio::chain
...@@ -61,6 +61,8 @@ namespace eosio { namespace chain { ...@@ -61,6 +61,8 @@ namespace eosio { namespace chain {
wasm_interface::vm_type wasm_runtime = chain::config::default_wasm_runtime; wasm_interface::vm_type wasm_runtime = chain::config::default_wasm_runtime;
db_read_mode read_mode = db_read_mode::SPECULATIVE; db_read_mode read_mode = db_read_mode::SPECULATIVE;
flat_set<account_name> resource_greylist;
}; };
enum class block_status { enum class block_status {
...@@ -178,7 +180,10 @@ namespace eosio { namespace chain { ...@@ -178,7 +180,10 @@ namespace eosio { namespace chain {
void check_key_list( const public_key_type& key )const; void check_key_list( const public_key_type& key )const;
bool is_producing_block()const; bool is_producing_block()const;
void add_resource_greylist(const account_name &name);
void remove_resource_greylist(const account_name &name);
bool is_resource_greylisted(const account_name &name) const;
const flat_set<account_name> &get_resource_greylist() const;
void validate_referenced_accounts( const transaction& t )const; void validate_referenced_accounts( const transaction& t )const;
void validate_expiration( const transaction& t )const; void validate_expiration( const transaction& t )const;
...@@ -262,4 +267,5 @@ FC_REFLECT( eosio::chain::controller::config, ...@@ -262,4 +267,5 @@ FC_REFLECT( eosio::chain::controller::config,
(contracts_console) (contracts_console)
(genesis) (genesis)
(wasm_runtime) (wasm_runtime)
(resource_greylist)
) )
...@@ -66,22 +66,16 @@ namespace eosio { namespace chain { namespace resource_limits { ...@@ -66,22 +66,16 @@ namespace eosio { namespace chain { namespace resource_limits {
uint64_t get_block_cpu_limit() const; uint64_t get_block_cpu_limit() const;
uint64_t get_block_net_limit() const; uint64_t get_block_net_limit() const;
int64_t get_account_cpu_limit( const account_name& name, bool subjective = true) const; int64_t get_account_cpu_limit( const account_name& name, bool elastic = true) const;
int64_t get_account_net_limit( const account_name& name, bool subjective = true) const; int64_t get_account_net_limit( const account_name& name, bool elastic = true) const;
account_resource_limit get_account_cpu_limit_ex( const account_name& name, bool subjective = true) const; account_resource_limit get_account_cpu_limit_ex( const account_name& name, bool elastic = true) const;
account_resource_limit get_account_net_limit_ex( const account_name& name, bool subjective = true) const; account_resource_limit get_account_net_limit_ex( const account_name& name, bool elastic = true) const;
int64_t get_account_ram_usage( const account_name& name ) 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: private:
chainbase::database& _db; chainbase::database& _db;
std::set<account_name> _greylisted_accounts; // #4368 access to extended CPU/Net virtual resources should be subjective
}; };
} } } /// eosio::chain } } } /// eosio::chain
......
...@@ -6,7 +6,7 @@ namespace eosio { namespace chain { ...@@ -6,7 +6,7 @@ namespace eosio { namespace chain {
class transaction_context { class transaction_context {
private: private:
void init( uint64_t initial_net_usage, bool subjective = true); void init( uint64_t initial_net_usage);
public: public:
...@@ -19,13 +19,12 @@ namespace eosio { namespace chain { ...@@ -19,13 +19,12 @@ namespace eosio { namespace chain {
void init_for_input_trx( uint64_t packed_trx_unprunable_size, void init_for_input_trx( uint64_t packed_trx_unprunable_size,
uint64_t packed_trx_prunable_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 init_for_deferred_trx( fc::time_point published );
void exec(); void exec();
void finalize(bool subjective = true); void finalize();
void squash(); void squash();
void undo(); void undo();
......
...@@ -334,12 +334,12 @@ uint64_t resource_limits_manager::get_block_net_limit() const { ...@@ -334,12 +334,12 @@ uint64_t resource_limits_manager::get_block_net_limit() const {
return config.net_limit_parameters.max - state.pending_net_usage; return config.net_limit_parameters.max - state.pending_net_usage;
} }
int64_t resource_limits_manager::get_account_cpu_limit( const account_name& name, bool subjective ) const { int64_t resource_limits_manager::get_account_cpu_limit( const account_name& name, bool elastic ) const {
auto arl = get_account_cpu_limit_ex(name, subjective); auto arl = get_account_cpu_limit_ex(name, elastic);
return arl.available; return arl.available;
} }
account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, bool subjective) const { account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, bool elastic) const {
const auto& state = _db.get<resource_limits_state_object>(); const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name); 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 ...@@ -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 window_size = config.account_cpu_usage_average_window;
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 virtual_cpu_capacity_in_window = (uint128_t)(elastic ? state.virtual_cpu_limit : config.cpu_limit_parameters.max) * window_size;
uint128_t user_weight = (uint128_t)cpu_weight; uint128_t user_weight = (uint128_t)cpu_weight;
uint128_t all_user_weight = (uint128_t)state.total_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 ...@@ -373,12 +373,12 @@ account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const
return arl; return arl;
} }
int64_t resource_limits_manager::get_account_net_limit( const account_name& name, bool subjective) const { int64_t resource_limits_manager::get_account_net_limit( const account_name& name, bool elastic) const {
auto arl = get_account_net_limit_ex(name, subjective); auto arl = get_account_net_limit_ex(name, elastic);
return arl.available; return arl.available;
} }
account_resource_limit resource_limits_manager::get_account_net_limit_ex( const account_name& name, bool subjective) const { account_resource_limit resource_limits_manager::get_account_net_limit_ex( const account_name& name, bool elastic) const {
const auto& config = _db.get<resource_limits_config_object>(); const auto& config = _db.get<resource_limits_config_object>();
const auto& state = _db.get<resource_limits_state_object>(); const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name); 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 ...@@ -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 window_size = config.account_net_usage_average_window;
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 virtual_network_capacity_in_window = (uint128_t)(elastic ? state.virtual_net_limit : config.net_limit_parameters.max) * window_size;
uint128_t user_weight = (uint128_t)net_weight; uint128_t user_weight = (uint128_t)net_weight;
uint128_t all_user_weight = (uint128_t)state.total_net_weight; uint128_t all_user_weight = (uint128_t)state.total_net_weight;
...@@ -412,16 +412,4 @@ account_resource_limit resource_limits_manager::get_account_net_limit_ex( const ...@@ -412,16 +412,4 @@ account_resource_limit resource_limits_manager::get_account_net_limit_ex( const
return arl; 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 } } } /// eosio::chain::resource_limits
...@@ -27,7 +27,7 @@ namespace eosio { namespace chain { ...@@ -27,7 +27,7 @@ namespace eosio { namespace chain {
FC_ASSERT( trx.transaction_extensions.size() == 0, "we don't support any extensions yet" ); FC_ASSERT( trx.transaction_extensions.size() == 0, "we don't support any extensions yet" );
} }
void transaction_context::init(uint64_t initial_net_usage, bool subjective) void transaction_context::init(uint64_t initial_net_usage)
{ {
FC_ASSERT( !is_initialized, "cannot initialize twice" ); FC_ASSERT( !is_initialized, "cannot initialize twice" );
const static int64_t large_number_no_overflow = std::numeric_limits<int64_t>::max()/2; const static int64_t large_number_no_overflow = std::numeric_limits<int64_t>::max()/2;
...@@ -88,10 +88,11 @@ namespace eosio { namespace chain { ...@@ -88,10 +88,11 @@ namespace eosio { namespace chain {
int64_t account_net_limit = large_number_no_overflow; int64_t account_net_limit = large_number_no_overflow;
int64_t account_cpu_limit = large_number_no_overflow; int64_t account_cpu_limit = large_number_no_overflow;
for( const auto& a : bill_to_accounts ) { for( const auto& a : bill_to_accounts ) {
auto net_limit = rl.get_account_net_limit(a, subjective); bool elastic = !(control.is_producing_block() && control.is_resource_greylisted(a));
auto net_limit = rl.get_account_net_limit(a, elastic);
if( net_limit >= 0 ) if( net_limit >= 0 )
account_net_limit = std::min( account_net_limit, net_limit ); account_net_limit = std::min( account_net_limit, net_limit );
auto cpu_limit = rl.get_account_cpu_limit(a, subjective); auto cpu_limit = rl.get_account_cpu_limit(a, elastic);
if( cpu_limit >= 0 ) if( cpu_limit >= 0 )
account_cpu_limit = std::min( account_cpu_limit, cpu_limit ); account_cpu_limit = std::min( account_cpu_limit, cpu_limit );
} }
...@@ -134,13 +135,12 @@ namespace eosio { namespace chain { ...@@ -134,13 +135,12 @@ namespace eosio { namespace chain {
void transaction_context::init_for_implicit_trx( uint64_t initial_net_usage ) void transaction_context::init_for_implicit_trx( uint64_t initial_net_usage )
{ {
published = control.pending_block_time(); published = control.pending_block_time();
init( initial_net_usage, false); init( initial_net_usage);
} }
void transaction_context::init_for_input_trx( uint64_t packed_trx_unprunable_size, void transaction_context::init_for_input_trx( uint64_t packed_trx_unprunable_size,
uint64_t packed_trx_prunable_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; const auto& cfg = control.get_global_properties().configuration;
...@@ -169,7 +169,7 @@ namespace eosio { namespace chain { ...@@ -169,7 +169,7 @@ namespace eosio { namespace chain {
control.validate_expiration( trx ); control.validate_expiration( trx );
control.validate_tapos( trx ); control.validate_tapos( trx );
control.validate_referenced_accounts( trx ); control.validate_referenced_accounts( trx );
init( initial_net_usage, subjective); init( initial_net_usage);
record_transaction( id, trx.expiration ); /// checks for dupes record_transaction( id, trx.expiration ); /// checks for dupes
} }
...@@ -201,7 +201,7 @@ namespace eosio { namespace chain { ...@@ -201,7 +201,7 @@ namespace eosio { namespace chain {
} }
} }
void transaction_context::finalize(bool subjective) { void transaction_context::finalize() {
FC_ASSERT( is_initialized, "must first initialize" ); FC_ASSERT( is_initialized, "must first initialize" );
const static int64_t large_number_no_overflow = std::numeric_limits<int64_t>::max()/2; const static int64_t large_number_no_overflow = std::numeric_limits<int64_t>::max()/2;
...@@ -223,10 +223,11 @@ namespace eosio { namespace chain { ...@@ -223,10 +223,11 @@ namespace eosio { namespace chain {
int64_t account_net_limit = large_number_no_overflow; int64_t account_net_limit = large_number_no_overflow;
int64_t account_cpu_limit = large_number_no_overflow; int64_t account_cpu_limit = large_number_no_overflow;
for( const auto& a : bill_to_accounts ) { for( const auto& a : bill_to_accounts ) {
auto net_limit = rl.get_account_net_limit(a, subjective); bool elastic = !(control.is_producing_block() && control.is_resource_greylisted(a));
auto net_limit = rl.get_account_net_limit(a, elastic);
if( net_limit >= 0 ) if( net_limit >= 0 )
account_net_limit = std::min( account_net_limit, net_limit ); account_net_limit = std::min( account_net_limit, net_limit );
auto cpu_limit = rl.get_account_cpu_limit(a, subjective); auto cpu_limit = rl.get_account_cpu_limit(a, elastic);
if( cpu_limit >= 0 ) if( cpu_limit >= 0 )
account_cpu_limit = std::min( account_cpu_limit, cpu_limit ); account_cpu_limit = std::min( account_cpu_limit, cpu_limit );
} }
......
...@@ -1158,8 +1158,9 @@ read_only::get_account_results read_only::get_account( const get_account_params& ...@@ -1158,8 +1158,9 @@ read_only::get_account_results read_only::get_account( const get_account_params&
result.last_code_update = a.last_code_update; result.last_code_update = a.last_code_update;
result.created = a.creation_date; result.created = a.creation_date;
result.net_limit = rm.get_account_net_limit_ex( result.account_name ); bool grelisted = db.is_resource_greylisted(result.account_name);
result.cpu_limit = rm.get_account_cpu_limit_ex( result.account_name ); result.net_limit = rm.get_account_net_limit_ex( result.account_name, !grelisted);
result.cpu_limit = rm.get_account_cpu_limit_ex( result.account_name, !grelisted);
result.ram_usage = rm.get_account_ram_usage( result.account_name ); result.ram_usage = rm.get_account_ram_usage( result.account_name );
const auto& permissions = d.get_index<permission_index,by_owner>(); const auto& permissions = d.get_index<permission_index,by_owner>();
......
...@@ -685,26 +685,22 @@ producer_plugin::runtime_options producer_plugin::get_runtime_options() const { ...@@ -685,26 +685,22 @@ producer_plugin::runtime_options producer_plugin::get_runtime_options() const {
void producer_plugin::add_greylist_accounts(const greylist_params& params) { void producer_plugin::add_greylist_accounts(const greylist_params& params) {
chain::controller& chain = app().get_plugin<chain_plugin>().chain(); chain::controller& chain = app().get_plugin<chain_plugin>().chain();
auto& rm = chain.get_mutable_resource_limits_manager();
for (auto &acc : params.accounts) { for (auto &acc : params.accounts) {
rm.add_greylist(acc); chain.add_resource_greylist(acc);
} }
} }
void producer_plugin::remove_greylist_accounts(const greylist_params& params) { void producer_plugin::remove_greylist_accounts(const greylist_params& params) {
chain::controller& chain = app().get_plugin<chain_plugin>().chain(); chain::controller& chain = app().get_plugin<chain_plugin>().chain();
auto& rm = chain.get_mutable_resource_limits_manager();
for (auto &acc : params.accounts) { for (auto &acc : params.accounts) {
rm.remove_greylist(acc); chain.remove_resource_greylist(acc);
} }
} }
producer_plugin::greylist_params producer_plugin::get_greylist() const { producer_plugin::greylist_params producer_plugin::get_greylist() const {
chain::controller& chain = app().get_plugin<chain_plugin>().chain(); chain::controller& chain = app().get_plugin<chain_plugin>().chain();
const auto& rm = chain.get_resource_limits_manager();
greylist_params result; greylist_params result;
const auto& list = rm.get_greylisted_account(); const auto& list = chain.get_resource_greylist();
result.accounts.reserve(list.size()); result.accounts.reserve(list.size());
for (auto &acc: list) { for (auto &acc: list) {
result.accounts.push_back(acc); result.accounts.push_back(acc);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册