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

Res payer sig #10400

Merged
merged 7 commits into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
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
2 changes: 2 additions & 0 deletions libraries/chain/apply_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ void apply_context::execute_inline( action&& a ) {
try {
control.get_authorization_manager()
.check_authorization( {a},
{},
{},
{{receiver, config::eosio_code_name}},
control.pending_block_time() - trx_context.published,
Expand Down Expand Up @@ -525,6 +526,7 @@ void apply_context::schedule_deferred_transaction( const uint128_t& sender_id, a
try {
control.get_authorization_manager()
.check_authorization( trx.actions,
{},
{},
{{receiver, config::eosio_code_name}},
delay,
Expand Down
4 changes: 4 additions & 0 deletions libraries/chain/authorization_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -483,6 +483,7 @@ namespace eosio { namespace chain {
void
authorization_manager::check_authorization( const vector<action>& actions,
const flat_set<public_key_type>& provided_keys,
std::optional<resource_payer_t> payer,
const flat_set<permission_level>& provided_permissions,
fc::microseconds provided_delay,
const std::function<void()>& _checktime,
Expand Down Expand Up @@ -552,6 +553,9 @@ namespace eosio { namespace chain {
}
}
}
if (payer) {
permissions_to_satisfy.emplace(permission_level{payer->payer, config::active_name},effective_provided_delay);
}

// Now verify that all the declared authorizations are satisfied:

Expand Down
5 changes: 5 additions & 0 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1179,6 +1179,7 @@ struct controller_impl {
{
EOS_ASSERT(deadline != fc::time_point(), transaction_exception, "deadline cannot be uninitialized");


transaction_trace_ptr trace;
try {
auto start = fc::time_point::now();
Expand Down Expand Up @@ -1216,6 +1217,7 @@ struct controller_impl {

try {
const transaction& trn = trx->packed_trx()->get_transaction();

if( trx->implicit ) {
EOS_ASSERT( !explicit_net_usage_words, transaction_exception, "NET usage cannot be explicitly set for implicit transactions" );
trx_context.init_for_implicit_trx();
Expand All @@ -1234,9 +1236,12 @@ struct controller_impl {
trx_context.delay = fc::seconds(trn.delay_sec);

if( check_auth ) {
auto payer = trn.resource_payer_info(self.is_builtin_activated(builtin_protocol_feature_t::resource_payer));

authorization.check_authorization(
trn.actions,
trx->recovered_keys(),
payer,
{},
trx_context.delay,
[&trx_context](){ trx_context.checktime(); },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ namespace eosio { namespace chain {
void
check_authorization( const vector<action>& actions,
const flat_set<public_key_type>& provided_keys,
std::optional<resource_payer_t> payer,
const flat_set<permission_level>& provided_permissions = flat_set<permission_level>(),
fc::microseconds provided_delay = fc::microseconds(0),
const std::function<void()>& checktime = std::function<void()>(),
Expand Down
1 change: 1 addition & 0 deletions libraries/chain/webassembly/permission.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ namespace eosio { namespace chain { namespace webassembly {
.get_authorization_manager()
.check_authorization( trx.actions,
provided_keys,
{},
provided_permissions,
fc::seconds(trx.delay_sec),
std::bind(&transaction_context::checktime, &context.trx_context),
Expand Down
85 changes: 85 additions & 0 deletions unittests/resource_limits_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ BOOST_AUTO_TEST_SUITE(resource_limits_test)

namespace {
name respyr_acct = "respyr"_n;
name payee_acct = "payee"_n;

template<typename Transaction>
Transaction populate() {
Expand All @@ -584,6 +585,31 @@ BOOST_AUTO_TEST_SUITE(resource_limits_test)

return txn;
}

template<typename Transaction>
Transaction populate_payer_payee() {
Transaction txn;
txn.ref_block_num = 1;
txn.ref_block_prefix = 2;
txn.expiration.from_iso_string("2021-12-20T15:30");
txn.actions.emplace_back( vector<permission_level>{{payee_acct, config::active_name}}, payee_acct, "doit"_n, bytes{} );
txn.max_net_usage_words = 32;
txn.max_cpu_usage_ms = 10;

// Resource Payer Transaction Extension (with net and cpu different from those in transaction)
resource_payer resource_payer_trx_extension;
resource_payer_trx_extension.payer = respyr_acct;
resource_payer_trx_extension.max_net_bytes = 1024;
resource_payer_trx_extension.max_cpu_us = 30000;
resource_payer_trx_extension.max_memory_bytes = 0;
emplace_extension(
txn.transaction_extensions,
resource_payer::extension_id(),
fc::raw::pack( resource_payer_trx_extension )
);

return txn;
}
}

BOOST_FIXTURE_TEST_CASE(resource_payer_cpu_validation, resource_limits_fixture) try {
Expand Down Expand Up @@ -694,5 +720,64 @@ BOOST_AUTO_TEST_SUITE(resource_limits_test)
}

} FC_LOG_AND_RETHROW()
BOOST_FIXTURE_TEST_CASE(resource_payer_not_signed, resource_limits_fixture) try {
tester t( setup_policy::preactivate_feature_and_new_bios );

auto txn = populate_payer_payee<eosio::chain::signed_transaction>();

const auto& pfm = t.control->get_protocol_feature_manager();
const auto& d = pfm.get_builtin_digest(builtin_protocol_feature_t::resource_payer);
BOOST_REQUIRE(d);

t.preactivate_protocol_features( {*d} );
t.produce_block();

// now, get resource payer info having activated resource_payer protcol feature
auto res_pyr = txn.resource_payer_info( t.control->is_builtin_activated(builtin_protocol_feature_t::resource_payer) );
BOOST_CHECK_EQUAL(res_pyr != std::nullopt, true);

t.produce_blocks(2);
t.create_account( res_pyr->payer );
t.create_account( payee_acct);

t.set_code( res_pyr->payer, contracts::payloadless_wasm() );
t.produce_blocks(1);

t.set_transaction_headers( txn, t.DEFAULT_EXPIRATION_DELTA );
txn.sign( t.get_private_key(payee_acct, "active"), t.control->get_chain_id() );

BOOST_REQUIRE_THROW(t.push_transaction(txn), unsatisfied_authorization);

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(resource_payer_fully_signed, resource_limits_fixture) try {
tester t( setup_policy::preactivate_feature_and_new_bios );

auto txn = populate_payer_payee<eosio::chain::signed_transaction>();

const auto& pfm = t.control->get_protocol_feature_manager();
const auto& d = pfm.get_builtin_digest(builtin_protocol_feature_t::resource_payer);
BOOST_REQUIRE(d);

t.preactivate_protocol_features( {*d} );
t.produce_block();

// now, get resource payer info having activated resource_payer protcol feature
auto res_pyr = txn.resource_payer_info( t.control->is_builtin_activated(builtin_protocol_feature_t::resource_payer) );
BOOST_CHECK_EQUAL(res_pyr != std::nullopt, true);

t.produce_blocks(2);
t.create_account( res_pyr->payer );
t.create_account( payee_acct);

t.set_code( res_pyr->payer, contracts::payloadless_wasm() );
t.produce_blocks(1);

t.set_transaction_headers( txn, t.DEFAULT_EXPIRATION_DELTA );
txn.sign( t.get_private_key(res_pyr->payer, "active"), t.control->get_chain_id() );
txn.sign( t.get_private_key(payee_acct, "active"), t.control->get_chain_id() );

t.push_transaction(txn);

} FC_LOG_AND_RETHROW()
BOOST_AUTO_TEST_SUITE_END()