Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Implement ONLY_BILL_FIRST_AUTHORIZER protocol feature #7089

Merged
merged 5 commits into from
Apr 10, 2019
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,13 @@ struct controller_impl {
trx_context.init_for_deferred_trx( gtrx.published );

if( trx_context.enforce_whiteblacklist && pending->_block_status == controller::block_status::incomplete ) {
check_actor_list( trx_context.bill_to_accounts ); // Assumes bill_to_accounts is the set of actors authorizing the transaction
flat_set<account_name> actors;
for( const auto& act : trx_context.trx.actions ) {
for( const auto& auth : act.authorization ) {
actors.insert( auth.actor );
}
}
check_actor_list( actors );
}

trx_context.exec();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ enum class builtin_protocol_feature_t : uint32_t {
replace_deferred,
fix_linkauth_restriction,
disallow_empty_producer_schedule,
restrict_action_to_self
restrict_action_to_self,
only_bill_first_authorizer
};

struct protocol_feature_subjective_restrictions {
Expand Down
3 changes: 2 additions & 1 deletion libraries/chain/include/eosio/chain/transaction.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ namespace eosio { namespace chain {
bool allow_duplicate_keys = false) const;

uint32_t total_actions()const { return context_free_actions.size() + actions.size(); }
account_name first_authorizor()const {

account_name first_authorizer()const {
for( const auto& a : actions ) {
for( const auto& u : a.authorization )
return u.actor;
Expand Down
11 changes: 11 additions & 0 deletions libraries/chain/protocol_feature_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,17 @@ Builtin protocol feature: RESTRICT_ACTION_TO_SELF
Disallows bypass of authorization checks by unprivileged contracts when sending inline actions or deferred transactions.
The original protocol rules allow a bypass of authorization checks for actions sent by a contract to itself.
This protocol feature removes that bypass.
*/
{}
} )
( builtin_protocol_feature_t::only_bill_first_authorizer, builtin_protocol_feature_spec{
"ONLY_BILL_FIRST_AUTHORIZER",
fc::variant("2f1f13e291c79da5a2bbad259ed7c1f2d34f697ea460b14b565ac33b063b73e2").as<digest_type>(),
// SHA256 hash of the raw message below within the comment delimiters (do not modify message below).
/*
Builtin protocol feature: ONLY_BILL_FIRST_AUTHORIZER

Adds CPU and network bandwidth usage to only the first authorizer of a transaction.
*/
{}
} )
Expand Down
12 changes: 8 additions & 4 deletions libraries/chain/transaction_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,13 @@ namespace bacc = boost::accumulators;
validate_cpu_usage_to_bill( billed_cpu_time_us, false ); // Fail early if the amount to be billed is too high

// Record accounts to be billed for network and CPU usage
for( const auto& act : trx.actions ) {
for( const auto& auth : act.authorization ) {
bill_to_accounts.insert( auth.actor );
if( control.is_builtin_activated(builtin_protocol_feature_t::only_bill_first_authorizer) ) {
bill_to_accounts.insert( trx.first_authorizer() );
} else {
for( const auto& act : trx.actions ) {
for( const auto& auth : act.authorization ) {
bill_to_accounts.insert( auth.actor );
}
}
}
validate_ram_usage.reserve( bill_to_accounts.size() );
Expand Down Expand Up @@ -583,7 +587,7 @@ namespace bacc = boost::accumulators;
+ static_cast<uint64_t>(config::transaction_id_net_usage) ); // Will exit early if net usage cannot be payed.
}

auto first_auth = trx.first_authorizor();
auto first_auth = trx.first_authorizer();

uint32_t trx_size = 0;
const auto& cgto = control.mutable_db().create<generated_transaction_object>( [&]( auto& gto ) {
Expand Down
5 changes: 3 additions & 2 deletions unittests/auth_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,8 @@ BOOST_AUTO_TEST_CASE( any_auth ) { try {

BOOST_AUTO_TEST_CASE(no_double_billing) {
try {
TESTER chain;
validating_tester chain( validating_tester::default_config() );
chain.execute_setup_policy( setup_policy::preactivate_feature_and_new_bios );

chain.produce_block();

Expand Down Expand Up @@ -490,7 +491,7 @@ BOOST_AUTO_TEST_CASE( linkauth_special ) { try {
chain.create_account(N(tester));
chain.create_account(N(tester2));
chain.produce_blocks();

chain.push_action(config::system_account_name, updateauth::get_name(), tester_account, fc::mutable_variant_object()
("account", "tester")
("permission", "first")
Expand Down