This repository has been archived by the owner on Aug 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5548 from EOSIO/taokayan-blk_abi
fix abi serialization exception in get block
- Loading branch information
Showing
3 changed files
with
151 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
#include <boost/test/unit_test.hpp> | ||
#include <boost/algorithm/string/predicate.hpp> | ||
|
||
#include <eosio/testing/tester.hpp> | ||
#include <eosio/chain/abi_serializer.hpp> | ||
#include <eosio/chain/wasm_eosio_constraints.hpp> | ||
#include <eosio/chain/resource_limits.hpp> | ||
#include <eosio/chain/exceptions.hpp> | ||
#include <eosio/chain/wast_to_wasm.hpp> | ||
#include <eosio/chain_plugin/chain_plugin.hpp> | ||
|
||
#include <asserter/asserter.wast.hpp> | ||
#include <asserter/asserter.abi.hpp> | ||
|
||
#include <stltest/stltest.wast.hpp> | ||
#include <stltest/stltest.abi.hpp> | ||
|
||
#include <noop/noop.wast.hpp> | ||
#include <noop/noop.abi.hpp> | ||
|
||
#include <eosio.system/eosio.system.wast.hpp> | ||
#include <eosio.system/eosio.system.abi.hpp> | ||
|
||
#include <fc/io/fstream.hpp> | ||
|
||
#include <Runtime/Runtime.h> | ||
|
||
#include <fc/variant_object.hpp> | ||
#include <fc/io/json.hpp> | ||
|
||
#include <array> | ||
#include <utility> | ||
|
||
#ifdef NON_VALIDATING_TEST | ||
#define TESTER tester | ||
#else | ||
#define TESTER validating_tester | ||
#endif | ||
|
||
using namespace eosio; | ||
using namespace eosio::chain; | ||
using namespace eosio::testing; | ||
using namespace fc; | ||
|
||
BOOST_AUTO_TEST_SUITE(chain_plugin_tests) | ||
|
||
BOOST_FIXTURE_TEST_CASE( get_block_with_invalid_abi, TESTER ) try { | ||
produce_blocks(2); | ||
|
||
create_accounts( {N(asserter)} ); | ||
produce_block(); | ||
|
||
// setup contract and abi | ||
set_code(N(asserter), asserter_wast); | ||
set_abi(N(asserter), asserter_abi); | ||
produce_blocks(1); | ||
|
||
auto resolver = [&,this]( const account_name& name ) -> optional<abi_serializer> { | ||
try { | ||
const auto& accnt = this->control->db().get<account_object,by_name>( name ); | ||
abi_def abi; | ||
if (abi_serializer::to_abi(accnt.abi, abi)) { | ||
return abi_serializer(abi, abi_serializer_max_time); | ||
} | ||
return optional<abi_serializer>(); | ||
} FC_RETHROW_EXCEPTIONS(error, "resolver failed at chain_plugin_tests::abi_invalid_type"); | ||
}; | ||
|
||
// abi should be resolved | ||
BOOST_REQUIRE_EQUAL(true, resolver(N(asserter)).valid()); | ||
|
||
// make an action using the valid contract & abi | ||
variant pretty_trx = mutable_variant_object() | ||
("actions", variants({ | ||
mutable_variant_object() | ||
("account", "asserter") | ||
("name", "procassert") | ||
("authorization", variants({ | ||
mutable_variant_object() | ||
("actor", "asserter") | ||
("permission", name(config::active_name).to_string()) | ||
})) | ||
("data", mutable_variant_object() | ||
("condition", 1) | ||
("message", "Should Not Assert!") | ||
) | ||
}) | ||
); | ||
signed_transaction trx; | ||
abi_serializer::from_variant(pretty_trx, trx, resolver, abi_serializer_max_time); | ||
set_transaction_headers(trx); | ||
trx.sign( get_private_key( N(asserter), "active" ), control->get_chain_id() ); | ||
push_transaction( trx ); | ||
produce_blocks(1); | ||
|
||
// retrieve block num | ||
uint32_t headnum = this->control->head_block_num(); | ||
|
||
char headnumstr[20]; | ||
sprintf(headnumstr, "%d", headnum); | ||
chain_apis::read_only::get_block_params param{headnumstr}; | ||
chain_apis::read_only plugin(*(this->control), fc::microseconds(INT_MAX)); | ||
|
||
// block should be decoded successfully | ||
std::string block_str = json::to_pretty_string(plugin.get_block(param)); | ||
BOOST_TEST(block_str.find("procassert") != std::string::npos); | ||
BOOST_TEST(block_str.find("condition") != std::string::npos); | ||
BOOST_TEST(block_str.find("Should Not Assert!") != std::string::npos); | ||
BOOST_TEST(block_str.find("011253686f756c64204e6f742041737365727421") != std::string::npos); //action data | ||
|
||
// set an invalid abi (int8->xxxx) | ||
std::string abi2 = asserter_abi; | ||
auto pos = abi2.find("int8"); | ||
BOOST_TEST(pos != std::string::npos); | ||
abi2.replace(pos, 4, "xxxx"); | ||
set_abi(N(asserter), abi2.c_str()); | ||
produce_blocks(1); | ||
|
||
// resolving the invalid abi result in exception | ||
BOOST_CHECK_THROW(resolver(N(asserter)), invalid_type_inside_abi); | ||
|
||
// get the same block as string, results in decode failed(invalid abi) but not exception | ||
std::string block_str2 = json::to_pretty_string(plugin.get_block(param)); | ||
BOOST_TEST(block_str2.find("procassert") != std::string::npos); | ||
BOOST_TEST(block_str2.find("condition") == std::string::npos); // decode failed | ||
BOOST_TEST(block_str2.find("Should Not Assert!") == std::string::npos); // decode failed | ||
BOOST_TEST(block_str2.find("011253686f756c64204e6f742041737365727421") != std::string::npos); //action data | ||
|
||
} FC_LOG_AND_RETHROW() /// get_block_with_invalid_abi | ||
|
||
BOOST_AUTO_TEST_SUITE_END() | ||
|