From cafceaa6d7c8aba6bb36d12e0a02c53263fbd952 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 28 Dec 2022 15:04:53 -0600 Subject: [PATCH] GH-260 Add is_code_cached method to wasm_interface and use in api_tests. --- .../include/eosio/chain/wasm_interface.hpp | 3 +++ .../eosio/chain/wasm_interface_private.hpp | 5 +++++ libraries/chain/wasm_interface.cpp | 4 ++++ .../testing/include/eosio/testing/tester.hpp | 2 ++ libraries/testing/tester.cpp | 7 +++++++ unittests/api_tests.cpp | 18 +++++++++--------- 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/libraries/chain/include/eosio/chain/wasm_interface.hpp b/libraries/chain/include/eosio/chain/wasm_interface.hpp index 85a959a70b..d0294b75b5 100644 --- a/libraries/chain/include/eosio/chain/wasm_interface.hpp +++ b/libraries/chain/include/eosio/chain/wasm_interface.hpp @@ -63,6 +63,9 @@ namespace eosio { namespace chain { //Immediately exits currently running wasm. UB is called when no wasm running void exit(); + //Returns true if the code is cached + size_t is_code_cached(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version) const; + // If substitute_apply is set, then apply calls it before doing anything else. If substitute_apply returns true, // then apply returns immediately. std::function parse_initial_memory(const Module& module) { std::vector mem_image; diff --git a/libraries/chain/wasm_interface.cpp b/libraries/chain/wasm_interface.cpp index 49d5e26d12..a9ccf7a478 100644 --- a/libraries/chain/wasm_interface.cpp +++ b/libraries/chain/wasm_interface.cpp @@ -108,6 +108,10 @@ namespace eosio { namespace chain { my->runtime_interface->immediately_exit_currently_running_module(); } + size_t wasm_interface::is_code_cached(const digest_type& code_hash, const uint8_t& vm_type, const uint8_t& vm_version) const { + return my->is_code_cached(code_hash, vm_type, vm_version); + } + wasm_instantiated_module_interface::~wasm_instantiated_module_interface() {} wasm_runtime_interface::~wasm_runtime_interface() {} diff --git a/libraries/testing/include/eosio/testing/tester.hpp b/libraries/testing/include/eosio/testing/tester.hpp index fa588124e0..3d3b4e9dbe 100644 --- a/libraries/testing/include/eosio/testing/tester.hpp +++ b/libraries/testing/include/eosio/testing/tester.hpp @@ -307,6 +307,8 @@ namespace eosio { namespace testing { void set_code( account_name name, const vector wasm, const private_key_type* signer = nullptr ); void set_abi( account_name name, const char* abi_json, const private_key_type* signer = nullptr ); + bool is_code_cached( account_name name ) const; + bool chain_has_transaction( const transaction_id_type& txid ) const; const transaction_receipt& get_transaction_receipt( const transaction_id_type& txid ) const; diff --git a/libraries/testing/tester.cpp b/libraries/testing/tester.cpp index 8befa1e5ad..c04ea7ccd4 100644 --- a/libraries/testing/tester.cpp +++ b/libraries/testing/tester.cpp @@ -950,6 +950,13 @@ namespace eosio { namespace testing { push_transaction( trx ); } + bool base_tester::is_code_cached( eosio::chain::account_name name ) const { + const auto& db = control->db(); + const account_metadata_object* receiver_account = &db.template get( name ); + if ( receiver_account->code_hash == digest_type() ) return false; + return control->get_wasm_interface().is_code_cached( receiver_account->code_hash, receiver_account->vm_type, receiver_account->vm_version ); + } + bool base_tester::chain_has_transaction( const transaction_id_type& txid ) const { return chain_transactions.count(txid) != 0; diff --git a/unittests/api_tests.cpp b/unittests/api_tests.cpp index 9e370306ea..7fa3cb2997 100644 --- a/unittests/api_tests.cpp +++ b/unittests/api_tests.cpp @@ -1264,14 +1264,14 @@ BOOST_FIXTURE_TEST_CASE(checktime_intrinsic, TESTER) { try { set_code( "testapi"_n, ss.str().c_str() ); produce_blocks(1); + BOOST_TEST( !is_code_cached("testapi"_n) ); + //initialize cache BOOST_CHECK_EXCEPTION( call_test( *this, test_api_action{}, 5000, 10, 10 ), deadline_exception, is_deadline_exception ); -// https://github.com/AntelopeIO/leap/issues/260 was created to track this TODO. -// Remove those comments after the issue is resolved. -// #warning TODO validate that the contract was successfully cached + BOOST_TEST( is_code_cached("testapi"_n) ); //it will always call BOOST_CHECK_EXCEPTION( call_test( *this, test_api_action{}, @@ -1303,14 +1303,14 @@ BOOST_FIXTURE_TEST_CASE(checktime_grow_memory, TESTER) { try { set_code( "testapi"_n, ss.str().c_str() ); produce_blocks(1); + BOOST_TEST( !is_code_cached("testapi"_n) ); + //initialize cache BOOST_CHECK_EXCEPTION( call_test( *this, test_api_action{}, 5000, 10, 10 ), deadline_exception, is_deadline_exception ); -// https://github.com/AntelopeIO/leap/issues/260 was created to track this TODO. -// Remove those comments after the issue is resolved. -//#warning TODO validate that the contract was successfully cached + BOOST_TEST( is_code_cached("testapi"_n) ); //it will always call BOOST_CHECK_EXCEPTION( call_test( *this, test_api_action{}, @@ -1325,14 +1325,14 @@ BOOST_FIXTURE_TEST_CASE(checktime_hashing_fail, TESTER) { try { set_code( "testapi"_n, contracts::test_api_wasm() ); produce_blocks(1); + BOOST_TEST( !is_code_cached("testapi"_n) ); + //hit deadline exception, but cache the contract BOOST_CHECK_EXCEPTION( call_test( *this, test_api_action{}, 5000, 3, 3 ), deadline_exception, is_deadline_exception ); -// https://github.com/AntelopeIO/leap/issues/260 was created to track this TODO. -// Remove those comments after the issue is resolved. -//#warning TODO validate that the contract was successfully cached + BOOST_TEST( is_code_cached("testapi"_n) ); //the contract should be cached, now we should get deadline_exception because of calls to checktime() from hashing function BOOST_CHECK_EXCEPTION( call_test( *this, test_api_action{},