From 04b3d7e45dff36409ba12a88b6f035cfec385a50 Mon Sep 17 00:00:00 2001 From: 766C6164 Date: Sun, 24 Jul 2022 22:11:57 -0400 Subject: [PATCH 1/3] Added indication of subjective in err msg --- .../eosio/chain/transaction_context.hpp | 6 +-- libraries/chain/transaction_context.cpp | 52 +++++++++++++------ 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/libraries/chain/include/eosio/chain/transaction_context.hpp b/libraries/chain/include/eosio/chain/transaction_context.hpp index 778234fa2e..f71f7a813e 100644 --- a/libraries/chain/include/eosio/chain/transaction_context.hpp +++ b/libraries/chain/include/eosio/chain/transaction_context.hpp @@ -111,9 +111,9 @@ namespace eosio { namespace chain { void schedule_transaction(); void record_transaction( const transaction_id_type& id, fc::time_point_sec expire ); - void validate_cpu_usage_to_bill( int64_t billed_us, int64_t account_cpu_limit, bool check_minimum )const; - void validate_account_cpu_usage( int64_t billed_us, int64_t account_cpu_limit )const; - void validate_account_cpu_usage_estimate( int64_t billed_us, int64_t account_cpu_limit )const; + void validate_cpu_usage_to_bill( int64_t billed_us, int64_t account_cpu_limit, bool check_minimum, int64_t subjective_billed_us )const; + void validate_account_cpu_usage( int64_t billed_us, int64_t account_cpu_limit, int64_t subjective_billed_us )const; + void validate_account_cpu_usage_estimate( int64_t billed_us, int64_t account_cpu_limit, int64_t subjective_billed_us )const; void disallow_transaction_extensions( const char* error_msg )const; diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index 593984e371..28a78a27f1 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -138,7 +138,7 @@ namespace eosio { namespace chain { initial_objective_duration_limit = objective_duration_limit; if( explicit_billed_cpu_time ) - validate_cpu_usage_to_bill( billed_cpu_time_us, std::numeric_limits::max(), false ); // Fail early if the amount to be billed is too high + validate_cpu_usage_to_bill( billed_cpu_time_us, std::numeric_limits::max(), false, subjective_cpu_bill_us); // Fail early if the amount to be billed is too high // Record accounts to be billed for network and CPU usage if( control.is_builtin_activated(builtin_protocol_feature_t::only_bill_first_authorizer) ) { @@ -204,7 +204,7 @@ namespace eosio { namespace chain { if( validate_account_cpu_limit > 0 ) validate_account_cpu_limit -= EOS_PERCENT( validate_account_cpu_limit, 10 * config::percent_1 ); if( validate_account_cpu_limit < 0 ) validate_account_cpu_limit = 0; - validate_account_cpu_usage_estimate( billed_cpu_time_us, validate_account_cpu_limit ); + validate_account_cpu_usage_estimate( billed_cpu_time_us, validate_account_cpu_limit, subjective_cpu_bill_us ); } eager_net_limit = (eager_net_limit/8)*8; // Round down to nearest multiple of word size (8 bytes) so check_net_usage can be efficient @@ -370,7 +370,7 @@ namespace eosio { namespace chain { update_billed_cpu_time( now ); - validate_cpu_usage_to_bill( billed_cpu_time_us, account_cpu_limit, true ); + validate_cpu_usage_to_bill( billed_cpu_time_us, account_cpu_limit, true, subjective_cpu_bill_us ); rl.add_transaction_usage( bill_to_accounts, static_cast(billed_cpu_time_us), net_usage, block_timestamp_type(control.pending_block_time()).slot ); // Should never fail @@ -462,7 +462,7 @@ namespace eosio { namespace chain { transaction_timer.start(_deadline); } - void transaction_context::validate_cpu_usage_to_bill( int64_t billed_us, int64_t account_cpu_limit, bool check_minimum )const { + void transaction_context::validate_cpu_usage_to_bill( int64_t billed_us, int64_t account_cpu_limit, bool check_minimum, int64_t subjective_billed_us )const { if (!control.skip_trx_checks()) { if( check_minimum ) { const auto& cfg = control.get_global_properties().configuration; @@ -472,11 +472,11 @@ namespace eosio { namespace chain { ); } - validate_account_cpu_usage( billed_us, account_cpu_limit ); + validate_account_cpu_usage( billed_us, account_cpu_limit, subjective_billed_us ); } } - void transaction_context::validate_account_cpu_usage( int64_t billed_us, int64_t account_cpu_limit )const { + void transaction_context::validate_account_cpu_usage( int64_t billed_us, int64_t account_cpu_limit, int64_t subjective_billed_us )const { if( (billed_us > 0) && !control.skip_trx_checks() ) { const bool cpu_limited_by_account = (account_cpu_limit <= objective_duration_limit.count()); @@ -496,17 +496,26 @@ namespace eosio { namespace chain { } else { // exceeds trx.max_cpu_usage_ms or cfg.max_transaction_cpu_usage if objective_duration_limit is greater const int64_t cpu_limit = (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); - EOS_ASSERT( billed_us <= cpu_limit, - tx_cpu_usage_exceeded, - "billed CPU time (${billed} us) is greater than the maximum billable CPU time for the transaction (${billable} us)", - ("billed", billed_us)( "billable", cpu_limit ) - ); + if( subjective_billed_us > 0 ) { + EOS_ASSERT( billed_us <= cpu_limit, + tx_cpu_usage_exceeded, + "billed CPU time (${billed} us) is greater than the maximum billable CPU time for the transaction (${billable} us) with a subjective cpu of (${subjective} us)", + ("billed", billed_us)( "billable", cpu_limit )( "subjective", subjective_billed_us ) + ); + } + else { + EOS_ASSERT( billed_us <= cpu_limit, + tx_cpu_usage_exceeded, + "billed CPU time (${billed} us) is greater than the maximum billable CPU time for the transaction (${billable} us)", + ("billed", billed_us)( "billable", cpu_limit ) + ); + } } } } } - void transaction_context::validate_account_cpu_usage_estimate( int64_t prev_billed_us, int64_t account_cpu_limit )const { + void transaction_context::validate_account_cpu_usage_estimate( int64_t prev_billed_us, int64_t account_cpu_limit, int64_t subjective_billed_us )const { // prev_billed_us can be 0, but so can account_cpu_limit if( (prev_billed_us >= 0) && !control.skip_trx_checks() ) { const bool cpu_limited_by_account = (account_cpu_limit <= objective_duration_limit.count()); @@ -527,11 +536,20 @@ namespace eosio { namespace chain { } else { // exceeds trx.max_cpu_usage_ms or cfg.max_transaction_cpu_usage if objective_duration_limit is greater const int64_t cpu_limit = (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); - EOS_ASSERT( prev_billed_us < cpu_limit, - tx_cpu_usage_exceeded, - "estimated CPU time (${billed} us) is not less than the maximum billable CPU time for the transaction (${billable} us)", - ("billed", prev_billed_us)( "billable", cpu_limit ) - ); + if( subjective_billed_us > 0 ) { + EOS_ASSERT( prev_billed_us < cpu_limit, + tx_cpu_usage_exceeded, + "estimated CPU time (${billed} us) is not less than the maximum billable CPU time for the transaction (${billable} us) with a subjective cpu of (${subjective} us)", + ("billed", prev_billed_us)( "billable", cpu_limit )( "subjective", subjective_billed_us ) + ); + } + else { + EOS_ASSERT( prev_billed_us < cpu_limit, + tx_cpu_usage_exceeded, + "estimated CPU time (${billed} us) is not less than the maximum billable CPU time for the transaction (${billable} us)", + ("billed", prev_billed_us)( "billable", cpu_limit ) + ); + } } } } From b49476c7e74a460d3e9e0bddb4919826254add3c Mon Sep 17 00:00:00 2001 From: 766C6164 Date: Tue, 9 Aug 2022 21:37:32 -0400 Subject: [PATCH 2/3] Update graylisted and checktime() msgs --- libraries/chain/transaction_context.cpp | 91 ++++++++++++------------- 1 file changed, 42 insertions(+), 49 deletions(-) diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index 28a78a27f1..20b9a475d3 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -417,14 +417,19 @@ namespace eosio { namespace chain { "not enough time left in block to complete executing transaction ${billing_timer}us", ("now", now)("deadline", _deadline)("start", start)("billing_timer", now - pseudo_start) ); } else if( deadline_exception_code == tx_cpu_usage_exceeded::code_value ) { + std::string assert_msg = "transaction was executing for too long ${billing_timer}us"; + if (subjective_cpu_bill_us > 0) { + assert_msg += " with a subjective cpu of (${subjective} us)"; + } if (cpu_limit_due_to_greylist) { + assert_msg = "greylisted " + assert_msg; EOS_THROW( greylist_cpu_usage_exceeded, - "greylisted transaction was executing for too long ${billing_timer}us", - ("now", now)("deadline", _deadline)("start", start)("billing_timer", now - pseudo_start) ); + assert_msg, + ("now", now)("deadline", _deadline)("start", start)("billing_timer", now - pseudo_start)( "subjective", subjective_cpu_bill_us) ); } else { EOS_THROW( tx_cpu_usage_exceeded, - "transaction was executing for too long ${billing_timer}us", - ("now", now)("deadline", _deadline)("start", start)("billing_timer", now - pseudo_start) ); + assert_msg, + ("now", now)("deadline", _deadline)("start", start)("billing_timer", now - pseudo_start)("subjective", subjective_cpu_bill_us) ); } } else if( deadline_exception_code == leeway_deadline_exception::code_value ) { EOS_THROW( leeway_deadline_exception, @@ -487,30 +492,24 @@ namespace eosio { namespace chain { ("billed", billed_us)( "billable", objective_duration_limit.count() ) ); } else { - if( cpu_limit_due_to_greylist && cpu_limited_by_account ) { - EOS_ASSERT( billed_us <= account_cpu_limit, - greylist_cpu_usage_exceeded, - "billed CPU time (${billed} us) is greater than the maximum greylisted billable CPU time for the transaction (${billable} us)", - ("billed", billed_us)( "billable", account_cpu_limit ) - ); - } else { + auto check_cpu_limit = [&](bool graylisted, bool subjective) { + std::string assert_msg = "billed CPU time (${billed} us) is greater than the maximum"; + assert_msg += graylisted ? " greylisted" : ""; + assert_msg += " billable CPU time for the transaction (${billable} us)"; + assert_msg += subjective ? " with a subjective cpu of (${subjective} us)" : ""; // exceeds trx.max_cpu_usage_ms or cfg.max_transaction_cpu_usage if objective_duration_limit is greater - const int64_t cpu_limit = (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); - if( subjective_billed_us > 0 ) { - EOS_ASSERT( billed_us <= cpu_limit, - tx_cpu_usage_exceeded, - "billed CPU time (${billed} us) is greater than the maximum billable CPU time for the transaction (${billable} us) with a subjective cpu of (${subjective} us)", - ("billed", billed_us)( "billable", cpu_limit )( "subjective", subjective_billed_us ) - ); - } - else { - EOS_ASSERT( billed_us <= cpu_limit, + auto limit = graylisted ? account_cpu_limit : (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); + if (graylisted) + EOS_ASSERT( billed_us <= limit, + greylist_cpu_usage_exceeded, + assert_msg, + ("billed", billed_us)("billable", limit)("subjective", subjective_billed_us)); + else + EOS_ASSERT( billed_us <= limit, tx_cpu_usage_exceeded, - "billed CPU time (${billed} us) is greater than the maximum billable CPU time for the transaction (${billable} us)", - ("billed", billed_us)( "billable", cpu_limit ) - ); - } - } + assert_msg, ("billed", billed_us)("billable", limit)("subjective", subjective_billed_us)); + }; + check_cpu_limit(cpu_limit_due_to_greylist && cpu_limited_by_account, subjective_billed_us > 0); // graylisted, subjective } } } @@ -526,31 +525,25 @@ namespace eosio { namespace chain { "estimated CPU time (${billed} us) is not less than the billable CPU time left in the block (${billable} us)", ("billed", prev_billed_us)( "billable", objective_duration_limit.count() ) ); - } else { - if( cpu_limit_due_to_greylist && cpu_limited_by_account ) { - EOS_ASSERT( prev_billed_us < account_cpu_limit, - greylist_cpu_usage_exceeded, - "estimated CPU time (${billed} us) is not less than the maximum greylisted billable CPU time for the transaction (${billable} us)", - ("billed", prev_billed_us)( "billable", account_cpu_limit ) - ); - } else { + } else { + auto check_cpu_limit = [&](bool graylisted, bool subjective) { + std::string assert_msg = "estimated CPU time (${billed} us) is not less than the maximum"; + assert_msg += graylisted ? " greylisted" : ""; + assert_msg += " billable CPU time for the transaction (${billable} us)"; + assert_msg += subjective ? " with a subjective cpu of (${subjective} us)" : ""; // exceeds trx.max_cpu_usage_ms or cfg.max_transaction_cpu_usage if objective_duration_limit is greater - const int64_t cpu_limit = (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); - if( subjective_billed_us > 0 ) { - EOS_ASSERT( prev_billed_us < cpu_limit, + auto limit = graylisted ? account_cpu_limit : (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); + if (graylisted) + EOS_ASSERT( prev_billed_us < limit, + greylist_cpu_usage_exceeded, + assert_msg, + ("billed", prev_billed_us)("billable", limit)("subjective", subjective_billed_us)); + else + EOS_ASSERT( prev_billed_us < limit, tx_cpu_usage_exceeded, - "estimated CPU time (${billed} us) is not less than the maximum billable CPU time for the transaction (${billable} us) with a subjective cpu of (${subjective} us)", - ("billed", prev_billed_us)( "billable", cpu_limit )( "subjective", subjective_billed_us ) - ); - } - else { - EOS_ASSERT( prev_billed_us < cpu_limit, - tx_cpu_usage_exceeded, - "estimated CPU time (${billed} us) is not less than the maximum billable CPU time for the transaction (${billable} us)", - ("billed", prev_billed_us)( "billable", cpu_limit ) - ); - } - } + assert_msg, ("billed", prev_billed_us)("billable", limit)("subjective", subjective_billed_us)); + }; + check_cpu_limit(cpu_limit_due_to_greylist && cpu_limited_by_account, subjective_billed_us > 0); // graylisted, subjective } } } From 68e932685a800543e5cf780cd35d00f771efe696 Mon Sep 17 00:00:00 2001 From: 766C6164 Date: Wed, 10 Aug 2022 10:19:23 -0400 Subject: [PATCH 3/3] Do not generate assert msg when bot asserting --- libraries/chain/transaction_context.cpp | 62 ++++++++++++++----------- 1 file changed, 35 insertions(+), 27 deletions(-) diff --git a/libraries/chain/transaction_context.cpp b/libraries/chain/transaction_context.cpp index 20b9a475d3..ac4479874c 100644 --- a/libraries/chain/transaction_context.cpp +++ b/libraries/chain/transaction_context.cpp @@ -492,24 +492,28 @@ namespace eosio { namespace chain { ("billed", billed_us)( "billable", objective_duration_limit.count() ) ); } else { - auto check_cpu_limit = [&](bool graylisted, bool subjective) { + auto assert_msg = [&](bool graylisted, bool subjective) { std::string assert_msg = "billed CPU time (${billed} us) is greater than the maximum"; assert_msg += graylisted ? " greylisted" : ""; assert_msg += " billable CPU time for the transaction (${billable} us)"; assert_msg += subjective ? " with a subjective cpu of (${subjective} us)" : ""; - // exceeds trx.max_cpu_usage_ms or cfg.max_transaction_cpu_usage if objective_duration_limit is greater - auto limit = graylisted ? account_cpu_limit : (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); - if (graylisted) - EOS_ASSERT( billed_us <= limit, - greylist_cpu_usage_exceeded, - assert_msg, - ("billed", billed_us)("billable", limit)("subjective", subjective_billed_us)); - else - EOS_ASSERT( billed_us <= limit, - tx_cpu_usage_exceeded, - assert_msg, ("billed", billed_us)("billable", limit)("subjective", subjective_billed_us)); + return assert_msg; }; - check_cpu_limit(cpu_limit_due_to_greylist && cpu_limited_by_account, subjective_billed_us > 0); // graylisted, subjective + auto graylisted = cpu_limit_due_to_greylist && cpu_limited_by_account; + auto subjective = subjective_billed_us > 0; + // exceeds trx.max_cpu_usage_ms or cfg.max_transaction_cpu_usage if objective_duration_limit is greater + auto limit = graylisted ? account_cpu_limit : (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); + + if (graylisted) + EOS_ASSERT( billed_us <= limit, + greylist_cpu_usage_exceeded, + assert_msg(graylisted, subjective), + ("billed", billed_us)("billable", limit)("subjective", subjective_billed_us)); + else + EOS_ASSERT( billed_us <= limit, + tx_cpu_usage_exceeded, + assert_msg(graylisted, subjective), + ("billed", billed_us)("billable", limit)("subjective", subjective_billed_us)); } } } @@ -525,25 +529,29 @@ namespace eosio { namespace chain { "estimated CPU time (${billed} us) is not less than the billable CPU time left in the block (${billable} us)", ("billed", prev_billed_us)( "billable", objective_duration_limit.count() ) ); - } else { - auto check_cpu_limit = [&](bool graylisted, bool subjective) { + } else { + auto assert_msg = [&](bool graylisted, bool subjective) { std::string assert_msg = "estimated CPU time (${billed} us) is not less than the maximum"; assert_msg += graylisted ? " greylisted" : ""; assert_msg += " billable CPU time for the transaction (${billable} us)"; assert_msg += subjective ? " with a subjective cpu of (${subjective} us)" : ""; - // exceeds trx.max_cpu_usage_ms or cfg.max_transaction_cpu_usage if objective_duration_limit is greater - auto limit = graylisted ? account_cpu_limit : (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); - if (graylisted) - EOS_ASSERT( prev_billed_us < limit, - greylist_cpu_usage_exceeded, - assert_msg, - ("billed", prev_billed_us)("billable", limit)("subjective", subjective_billed_us)); - else - EOS_ASSERT( prev_billed_us < limit, - tx_cpu_usage_exceeded, - assert_msg, ("billed", prev_billed_us)("billable", limit)("subjective", subjective_billed_us)); + return assert_msg; }; - check_cpu_limit(cpu_limit_due_to_greylist && cpu_limited_by_account, subjective_billed_us > 0); // graylisted, subjective + auto graylisted = cpu_limit_due_to_greylist && cpu_limited_by_account; + auto subjective = subjective_billed_us > 0; + // exceeds trx.max_cpu_usage_ms or cfg.max_transaction_cpu_usage if objective_duration_limit is greater + auto limit = graylisted ? account_cpu_limit : (cpu_limited_by_account ? account_cpu_limit : objective_duration_limit.count()); + + if (graylisted) + EOS_ASSERT( prev_billed_us < limit, + greylist_cpu_usage_exceeded, + assert_msg(graylisted, subjective), + ("billed", prev_billed_us)("billable", limit)("subjective", subjective_billed_us)); + else + EOS_ASSERT( prev_billed_us < limit, + tx_cpu_usage_exceeded, + assert_msg(graylisted, subjective), + ("billed", prev_billed_us)("billable", limit)("subjective", subjective_billed_us)); } } }