Skip to content

Commit 2e39fdb

Browse files
authored
Merge pull request #140 from Wire-Network/feature/WIRE-207-subjective-cpu-payer
Add disable-subjective-payer-billing option
2 parents 77c4531 + c863c72 commit 2e39fdb

File tree

4 files changed

+23
-12
lines changed

4 files changed

+23
-12
lines changed

libraries/chain/include/sysio/chain/subjective_billing.hpp

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ class subjective_billing {
5151
using account_subjective_bill_cache = std::unordered_map<chain::account_name, subjective_billing_info>;
5252

5353
bool _disabled = false;
54+
bool _disabled_payer_billing = false;
5455
fc::microseconds _subjective_account_cpu_allowed{config::default_subjective_cpu_us};
5556
trx_cache_index _trx_cache_index;
5657
account_subjective_bill_cache _account_subjective_bill_cache;
@@ -120,6 +121,8 @@ class subjective_billing {
120121
fc::microseconds get_subjective_account_cpu_allowed() const { return _subjective_account_cpu_allowed; }
121122
void set_disabled(bool disable) { _disabled = disable; }
122123
bool is_disabled() const { return _disabled; }
124+
void disable_payer_billing(bool disable) { _disabled_payer_billing = disable; }
125+
bool is_payer_billing_disabled() const { return _disabled_payer_billing; }
123126
void disable_account( chain::account_name a ) { _disabled_accounts.emplace( a ); }
124127
bool is_account_disabled(const account_name& a ) const { return _disabled || _disabled_accounts.contains( a ); }
125128
bool is_any_account_disabled(const action_payers_t& accounts ) const {
@@ -133,10 +136,12 @@ class subjective_billing {
133136
if (_disabled) return;
134137
if (_trx_cache_index.contains(id)) return;
135138
account_subjective_cpu_bill_t account_subjective_cpu_bill;
136-
for (const auto& [a, b] : accounts_billing) {
137-
if (!_disabled_accounts.contains(a)) {
138-
account_subjective_cpu_bill[a] = fc::microseconds(b.cpu_usage_us);
139-
_account_subjective_bill_cache[a].pending_cpu_us += b.cpu_usage_us;
139+
if (!_disabled_payer_billing) {
140+
for (const auto& [a, b] : accounts_billing) {
141+
if (!_disabled_accounts.contains(a)) {
142+
account_subjective_cpu_bill[a] = fc::microseconds(b.cpu_usage_us);
143+
_account_subjective_bill_cache[a].pending_cpu_us += b.cpu_usage_us;
144+
}
140145
}
141146
}
142147
for (const auto& [a, b] : auth_cpu) {
@@ -156,9 +161,11 @@ class subjective_billing {
156161
void subjective_bill_failure( const accounts_billing_t& accounts_billing, const account_subjective_cpu_bill_t& auth_cpu, const fc::time_point& now ) {
157162
if (_disabled) return;
158163
const auto time_ordinal = time_ordinal_for(now);
159-
for (const auto& [a, b] : accounts_billing) {
160-
if (!_disabled_accounts.contains(a)) {
161-
_account_subjective_bill_cache[a].expired_accumulator.add(b.cpu_usage_us, time_ordinal, _expired_accumulator_average_window);
164+
if (!_disabled_payer_billing) {
165+
for (const auto& [a, b] : accounts_billing) {
166+
if (!_disabled_accounts.contains(a)) {
167+
_account_subjective_bill_cache[a].expired_accumulator.add(b.cpu_usage_us, time_ordinal, _expired_accumulator_average_window);
168+
}
162169
}
163170
}
164171
for (const auto& [a, b] : auth_cpu) {

libraries/chain/include/sysio/chain/transaction_context.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,6 @@ namespace sysio::chain {
205205
fc::microseconds leeway = fc::microseconds( config::default_subjective_cpu_leeway_us );
206206
cpu_usage_t billed_cpu_us;
207207
accounts_billing_t prev_accounts_billing;
208-
account_subjective_cpu_bill_t authorizers_cpu;
209208
bool explicit_billed_cpu_time = false;
210209

211210
transaction_checktime_timer transaction_timer;

libraries/chain/transaction_context.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -700,11 +700,13 @@ namespace sysio::chain {
700700
int64_t total_cpu_time_us = std::max( (now - pseudo_start).count(), static_cast<int64_t>(cfg.min_transaction_cpu_usage) );
701701
SYS_ASSERT(total_cpu_time_us - trace->total_cpu_usage_us >= 0, tx_cpu_usage_exceeded,
702702
"Invalid CPU usage calculation ${tt} - ${tu}", ("tt", total_cpu_time_us)("tu", trace->total_cpu_usage_us));
703+
account_subjective_cpu_bill_t authorizers_cpu;
703704
if (!billed_cpu_us.empty()) {
704705
assert(trace->action_traces.size() >= billed_cpu_us.size());
705706
// +1 so total is above min_transaction_cpu_usage
706707
int64_t delta_per_action = (( total_cpu_time_us - trace->total_cpu_usage_us ) / billed_cpu_us.size()) + 1;
707708
total_cpu_time_us = 0;
709+
bool subjectively_bill_payer_disabled = control.get_subjective_billing().is_payer_billing_disabled();
708710
auto trx_first_authorizer = packed_trx.get_transaction().first_authorizer(); // use if no authorizer
709711
for (auto&& [i, b] : std::views::enumerate(billed_cpu_us)) {
710712
// if exception thrown, action_traces may not be the same size as billed_cpu_us
@@ -717,7 +719,7 @@ namespace sysio::chain {
717719
auto first_auth = act_trace.act.first_authorizer();
718720
if (first_auth.empty())
719721
first_auth = trx_first_authorizer;
720-
if (first_auth != payer) // don't subjectively bill payer twice
722+
if (first_auth != payer || subjectively_bill_payer_disabled) // don't subjectively bill payer twice if billing payer
721723
authorizers_cpu[first_auth] += fc::microseconds{b.value};
722724
}
723725
}
@@ -734,7 +736,7 @@ namespace sysio::chain {
734736
} else {
735737
// if producing then trx is in objective cpu account billing. Also no block will be received to remove the billing.
736738
if (!control.is_producing_block()) {
737-
subjective_bill.subjective_bill(packed_trx.id(), packed_trx.expiration(), prev_accounts_billing, authorizers_cpu);
739+
subjective_bill.subjective_bill(packed_trx.id(), packed_trx.expiration(), accounts_billing, authorizers_cpu);
738740
}
739741
}
740742
}

plugins/producer_plugin/src/producer_plugin.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1308,6 +1308,8 @@ void producer_plugin::set_program_options(
13081308
"Maximum size (in MiB) of the incoming transaction queue. Exceeding this value will subjectively drop transaction with resource exhaustion.")
13091309
("disable-subjective-account-billing", boost::program_options::value<vector<string>>()->composing()->multitoken(),
13101310
"Account which is excluded from subjective CPU billing")
1311+
("disable-subjective-payer-billing", bpo::value<bool>()->default_value(false),
1312+
"Disable subjective CPU billing for all contract payer accounts")
13111313
("disable-subjective-p2p-billing", bpo::value<bool>()->default_value(true),
13121314
"Disable subjective CPU billing for P2P transactions")
13131315
("disable-subjective-api-billing", bpo::value<bool>()->default_value(true),
@@ -1431,8 +1433,9 @@ void producer_plugin_impl::plugin_initialize(const boost::program_options::varia
14311433
chain.get_mutable_subjective_billing().set_subjective_account_cpu_allowed(fc::microseconds(options.at("subjective-account-cpu-allowed-us").as<int64_t>()));
14321434
_disable_subjective_p2p_billing = options.at("disable-subjective-p2p-billing").as<bool>();
14331435
_disable_subjective_api_billing = options.at("disable-subjective-api-billing").as<bool>();
1434-
dlog("disable-subjective-p2p-billing: ${p2p}, disable-subjective-api-billing: ${api}",
1435-
("p2p", _disable_subjective_p2p_billing)("api", _disable_subjective_api_billing));
1436+
chain.get_mutable_subjective_billing().disable_payer_billing(options.at("disable-subjective-payer-billing").as<bool>());
1437+
dlog("disable-subjective-p2p-billing: ${p2p}, disable-subjective-api-billing: ${api}, disable-subjective-payer-billing: ${payer}",
1438+
("p2p", _disable_subjective_p2p_billing)("api", _disable_subjective_api_billing)("payer", chain.get_subjective_billing().is_payer_billing_disabled()));
14361439
if (_disable_subjective_p2p_billing && _disable_subjective_api_billing) {
14371440
chain.get_mutable_subjective_billing().set_disabled(true);
14381441
ilog("Subjective CPU billing disabled");

0 commit comments

Comments
 (0)