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

unit test for RESTRICT_ACTION_TO_SELF protocol feature (6705 ) #7092

Merged
merged 4 commits into from
Apr 10, 2019
Merged
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions unittests/contracts.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ namespace eosio {
MAKE_READ_WASM_ABI(noop, noop, test-contracts)
MAKE_READ_WASM_ABI(payloadless, payloadless, test-contracts)
MAKE_READ_WASM_ABI(proxy, proxy, test-contracts)
MAKE_READ_WASM_ABI(restrict_action_test, restrict_action_test, test-contracts)
MAKE_READ_WASM_ABI(snapshot_test, snapshot_test, test-contracts)
MAKE_READ_WASM_ABI(test_api, test_api, test-contracts)
MAKE_READ_WASM_ABI(test_api_db, test_api_db, test-contracts)
Expand Down
60 changes: 60 additions & 0 deletions unittests/protocol_feature_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -607,4 +607,64 @@ BOOST_AUTO_TEST_CASE( disallow_empty_producer_schedule_test ) { try {

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE( restrict_action_to_self_test ) { try {
tester c( setup_policy::preactivate_feature_and_new_bios );

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

c.create_accounts( {N(testacc), N(acctonotify), N(alice)} );
c.set_code( N(testacc), contracts::restrict_action_test_wasm() );
c.set_abi( N(testacc), contracts::restrict_action_test_abi().data() );

c.set_code( N(acctonotify), contracts::restrict_action_test_wasm() );
c.set_abi( N(acctonotify), contracts::restrict_action_test_abi().data() );

// Before the protocol feature is preactivated
// - Sending inline action to self = no problem
// - Sending deferred trx to self = throw subjective exception
// - Sending inline action to self from notification = throw subjective exception
// - Sending deferred trx to self from notification = throw subjective exception
BOOST_CHECK_NO_THROW( c.push_action( N(testacc), N(sendinline), N(alice), mutable_variant_object()("authorizer", "alice")) );
BOOST_REQUIRE_EXCEPTION( c.push_action( N(testacc), N(senddefer), N(alice),
mutable_variant_object()("authorizer", "alice")("senderid", 0)),
subjective_block_production_exception,
fc_exception_message_starts_with( "Authorization failure with sent deferred transaction" ) );

BOOST_REQUIRE_EXCEPTION( c.push_action( N(testacc), N(notifyinline), N(alice),
mutable_variant_object()("acctonotify", "acctonotify")("authorizer", "alice")),
subjective_block_production_exception,
fc_exception_message_starts_with( "Authorization failure with inline action sent to self" ) );

BOOST_REQUIRE_EXCEPTION( c.push_action( N(testacc), N(notifydefer), N(alice),
mutable_variant_object()("acctonotify", "acctonotify")("authorizer", "alice")("senderid", 1)),
subjective_block_production_exception,
fc_exception_message_starts_with( "Authorization failure with sent deferred transaction" ) );

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

// After the protocol feature is preactivated, all the 4 cases will throw an objective unsatisfied_authorization exception
BOOST_REQUIRE_EXCEPTION( c.push_action( N(testacc), N(sendinline), N(alice), mutable_variant_object()("authorizer", "alice") ),
unsatisfied_authorization,
fc_exception_message_starts_with( "transaction declares authority" ) );

BOOST_REQUIRE_EXCEPTION( c.push_action( N(testacc), N(senddefer), N(alice),
mutable_variant_object()("authorizer", "alice")("senderid", 3)),
unsatisfied_authorization,
fc_exception_message_starts_with( "transaction declares authority" ) );

BOOST_REQUIRE_EXCEPTION( c.push_action( N(testacc), N(notifyinline), N(alice),
mutable_variant_object()("acctonotify", "acctonotify")("authorizer", "alice") ),
unsatisfied_authorization,
fc_exception_message_starts_with( "transaction declares authority" ) );

BOOST_REQUIRE_EXCEPTION( c.push_action( N(testacc), N(notifydefer), N(alice),
mutable_variant_object()("acctonotify", "acctonotify")("authorizer", "alice")("senderid", 4)),
unsatisfied_authorization,
fc_exception_message_starts_with( "transaction declares authority" ) );

} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_SUITE_END()
1 change: 1 addition & 0 deletions unittests/test-contracts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ add_subdirectory( integration_test )
add_subdirectory( noop )
add_subdirectory( payloadless )
add_subdirectory( proxy )
add_subdirectory( restrict_action_test )
add_subdirectory( snapshot_test )
add_subdirectory( test_api )
add_subdirectory( test_api_db )
Expand Down
6 changes: 6 additions & 0 deletions unittests/test-contracts/restrict_action_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
if( EOSIO_COMPILE_TEST_CONTRACTS )
add_contract( restrict_action_test restrict_action_test restrict_action_test.cpp )
else()
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/restrict_action_test.wasm ${CMAKE_CURRENT_BINARY_DIR}/restrict_action_test.wasm COPYONLY )
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/restrict_action_test.abi ${CMAKE_CURRENT_BINARY_DIR}/restrict_action_test.abi COPYONLY )
endif()
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
{
"____comment": "This file was generated with eosio-abigen. DO NOT EDIT ",
"version": "eosio::abi/1.1",
"types": [],
"structs": [
{
"name": "noop",
"base": "",
"fields": []
},
{
"name": "notifydefer",
"base": "",
"fields": [
{
"name": "acctonotify",
"type": "name"
},
{
"name": "authorizer",
"type": "name"
},
{
"name": "senderid",
"type": "uint32"
}
]
},
{
"name": "notifyinline",
"base": "",
"fields": [
{
"name": "acctonotify",
"type": "name"
},
{
"name": "authorizer",
"type": "name"
}
]
},
{
"name": "senddefer",
"base": "",
"fields": [
{
"name": "authorizer",
"type": "name"
},
{
"name": "senderid",
"type": "uint32"
}
]
},
{
"name": "sendinline",
"base": "",
"fields": [
{
"name": "authorizer",
"type": "name"
}
]
}
],
"actions": [
{
"name": "noop",
"type": "noop",
"ricardian_contract": ""
},
{
"name": "notifydefer",
"type": "notifydefer",
"ricardian_contract": ""
},
{
"name": "notifyinline",
"type": "notifyinline",
"ricardian_contract": ""
},
{
"name": "senddefer",
"type": "senddefer",
"ricardian_contract": ""
},
{
"name": "sendinline",
"type": "sendinline",
"ricardian_contract": ""
}
],
"tables": [],
"ricardian_clauses": [],
"variants": []
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @file
* @copyright defined in eos/LICENSE
*/
#include "restrict_action_test.hpp"
#include <eosio/transaction.hpp>

using namespace eosio;

void restrict_action_test::noop( ) {

}

void restrict_action_test::sendinline( name authorizer ) {
action(
permission_level{authorizer,"active"_n},
get_self(),
"noop"_n,
std::make_tuple()
).send();
}

void restrict_action_test::senddefer( name authorizer, uint32_t senderid ) {
transaction trx;
trx.actions.emplace_back(
permission_level{authorizer,"active"_n},
get_self(),
"noop"_n,
std::make_tuple()
);
trx.send(senderid, get_self());
}

void restrict_action_test::notifyinline( name acctonotify, name authorizer ) {
require_recipient(acctonotify);
}

void restrict_action_test::notifydefer( name acctonotify, name authorizer, uint32_t senderid ) {
require_recipient(acctonotify);
}

void restrict_action_test::on_notify_inline( name acctonotify, name authorizer ) {
sendinline(authorizer);
}

void restrict_action_test::on_notify_defer( name acctonotify, name authorizer, uint32_t senderid ) {
senddefer(authorizer, senderid);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* @file
* @copyright defined in eos/LICENSE
*/
#pragma once

#include <eosio/eosio.hpp>

class [[eosio::contract]] restrict_action_test : public eosio::contract {
public:
using eosio::contract::contract;

[[eosio::action]]
void noop( );

[[eosio::action]]
void sendinline( eosio::name authorizer );

[[eosio::action]]
void senddefer( eosio::name authorizer, uint32_t senderid );


[[eosio::action]]
void notifyinline( eosio::name acctonotify, eosio::name authorizer );

[[eosio::action]]
void notifydefer( eosio::name acctonotify, eosio::name authorizer, uint32_t senderid );

[[eosio::on_notify("testacc::notifyinline")]]
void on_notify_inline( eosio::name acctonotify, eosio::name authorizer );

[[eosio::on_notify("testacc::notifydefer")]]
void on_notify_defer( eosio::name acctonotify, eosio::name authorizer, uint32_t senderid );
};
Binary file not shown.