From b5756d7e6bf5aa8614123cfa9baa97fccffb49c3 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Tue, 12 Jul 2022 09:57:02 -0500 Subject: [PATCH 1/7] GH-599 backported contract deltas test --- unittests/state_history_tests.cpp | 83 ++++++++++++++++++++++++++++++- 1 file changed, 81 insertions(+), 2 deletions(-) diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 763e91e531..41d994db59 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -31,8 +31,8 @@ class table_deltas_tester : public tester { using tester::tester; using deltas_vector = vector; - pair find_table_delta(const std::string &name) { - v = eosio::state_history::create_deltas(control->db(), false);; + pair find_table_delta(const std::string &name, bool full_snapshot = false) { + v = eosio::state_history::create_deltas(control->db(), full_snapshot);; auto find_by_name = [&name](const auto& x) { return x.name == name; @@ -452,4 +452,83 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { BOOST_REQUIRE(it==v.end()); } + BOOST_AUTO_TEST_CASE(test_deltas_contract_several_rows){ + table_deltas_tester chain(setup_policy::none); + + chain.produce_block(); + + chain.create_account("tester"_n); + + chain.set_code("tester"_n, contracts::get_table_test_wasm()); + chain.set_abi("tester"_n, contracts::get_table_test_abi().data()); + + chain.produce_blocks(2); + + auto trace = chain.push_action("tester"_n, "addhashobj"_n, "tester"_n, mutable_variant_object()("hashinput", "hello")); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + trace = chain.push_action("tester"_n, "addhashobj"_n, "tester"_n, mutable_variant_object()("hashinput", "world")); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + trace = chain.push_action("tester"_n, "addhashobj"_n, "tester"_n, mutable_variant_object()("hashinput", "!")); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + trace = chain.push_action("tester"_n, "addnumobj"_n, "tester"_n, mutable_variant_object()("input", 2)); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + trace = chain.push_action("tester"_n, "addnumobj"_n, "tester"_n, mutable_variant_object()("input", 3)); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + trace = chain.push_action("tester"_n, "addnumobj"_n, "tester"_n, mutable_variant_object()("input", 4)); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + // Spot onto contract_row with full snapshot + auto result = chain.find_table_delta("contract_row", true); + BOOST_REQUIRE(result.first); + auto &it_contract_row = result.second; + BOOST_REQUIRE_EQUAL(it_contract_row->rows.obj.size(), 6); + auto contract_rows = chain.deserialize_data(it_contract_row); + + std::multiset expected_contract_row_table_names {"hashobjs", "hashobjs", "hashobjs", "numobjs", "numobjs", "numobjs"}; + std::multiset expected_contract_row_table_primary_keys {0, 1 ,2, 0, 1, 2}; + std::multiset result_contract_row_table_names; + std::multiset result_contract_row_table_primary_keys; + for(auto &contract_row : contract_rows) { + result_contract_row_table_names.insert(contract_row.table.to_string()); + result_contract_row_table_primary_keys.insert(contract_row.primary_key); + } + BOOST_REQUIRE(expected_contract_row_table_names == result_contract_row_table_names); + BOOST_REQUIRE(expected_contract_row_table_primary_keys == result_contract_row_table_primary_keys); + + chain.produce_block(); + + trace = chain.push_action("tester"_n, "erasenumobj"_n, "tester"_n, mutable_variant_object()("id", 1)); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + trace = chain.push_action("tester"_n, "erasenumobj"_n, "tester"_n, mutable_variant_object()("id", 0)); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); + + result = chain.find_table_delta("contract_row"); + BOOST_REQUIRE(result.first); + auto &it_contract_row_after_delete = result.second; + BOOST_REQUIRE_EQUAL(it_contract_row->rows.obj.size(), 2); + contract_rows = chain.deserialize_data(it_contract_row); + + for(int i=0; i < contract_rows.size(); i++) { + BOOST_REQUIRE_EQUAL(it_contract_row->rows.obj[i].first, 0); + BOOST_REQUIRE_EQUAL(contract_rows[i].table.to_string(), "numobjs"); + } + + result = chain.find_table_delta("contract_index_double"); + BOOST_REQUIRE(result.first); + auto &it_contract_index_double = result.second; + BOOST_REQUIRE_EQUAL(it_contract_index_double->rows.obj.size(), 2); + auto contract_index_double_elems = chain.deserialize_data(it_contract_index_double); + + for(int i=0; i < contract_index_double_elems.size(); i++) { + BOOST_REQUIRE_EQUAL(it_contract_index_double->rows.obj[i].first, 0); + BOOST_REQUIRE_EQUAL(contract_index_double_elems[i].table.to_string(), "numobjs.....2"); + } + } + BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From ee0dd02dd0f78f3e8c728831269fa918c74ace43 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Wed, 13 Jul 2022 09:21:34 -0500 Subject: [PATCH 2/7] GH-599 commented out portion of test dependent on missing test contract actions --- unittests/state_history_tests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 41d994db59..82b0986b89 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -501,7 +501,7 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { BOOST_REQUIRE(expected_contract_row_table_primary_keys == result_contract_row_table_primary_keys); chain.produce_block(); - +/* TODO erasenumobj does not exist in mandel trace = chain.push_action("tester"_n, "erasenumobj"_n, "tester"_n, mutable_variant_object()("id", 1)); BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); @@ -529,6 +529,7 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { BOOST_REQUIRE_EQUAL(it_contract_index_double->rows.obj[i].first, 0); BOOST_REQUIRE_EQUAL(contract_index_double_elems[i].table.to_string(), "numobjs.....2"); } + */ } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From 1a17c5c92808e7b4a47f77737a80f3cf5ac47002 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 15 Jul 2022 12:10:33 -0500 Subject: [PATCH 3/7] GH-599 added protocol feature activation for crypto primatives --- unittests/state_history_tests.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 82b0986b89..7bc58748f8 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -453,10 +453,16 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { } BOOST_AUTO_TEST_CASE(test_deltas_contract_several_rows){ - table_deltas_tester chain(setup_policy::none); + table_deltas_tester chain(setup_policy::preactivate_feature_and_new_bios ); chain.produce_block(); + const auto& pfm = chain.control->get_protocol_feature_manager(); + const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::crypto_primitives ); + BOOST_REQUIRE( d ); + + chain.preactivate_protocol_features( {*d} ); + chain.produce_block(); chain.create_account("tester"_n); chain.set_code("tester"_n, contracts::get_table_test_wasm()); @@ -501,7 +507,7 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { BOOST_REQUIRE(expected_contract_row_table_primary_keys == result_contract_row_table_primary_keys); chain.produce_block(); -/* TODO erasenumobj does not exist in mandel + trace = chain.push_action("tester"_n, "erasenumobj"_n, "tester"_n, mutable_variant_object()("id", 1)); BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace->receipt->status); @@ -529,7 +535,7 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { BOOST_REQUIRE_EQUAL(it_contract_index_double->rows.obj[i].first, 0); BOOST_REQUIRE_EQUAL(contract_index_double_elems[i].table.to_string(), "numobjs.....2"); } - */ + } BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file From a3f367938fc63b6d402c1368f658b616fd35a623 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 15 Jul 2022 12:45:56 -0500 Subject: [PATCH 4/7] GH-599 added missing methods on test contract --- .../get_table_test/get_table_test.cpp | 15 ++++++ .../get_table_test/get_table_test.hpp | 50 +++++++++++++++++++ 2 files changed, 65 insertions(+) diff --git a/unittests/test-contracts/get_table_test/get_table_test.cpp b/unittests/test-contracts/get_table_test/get_table_test.cpp index c35409f2ac..43f7bee412 100644 --- a/unittests/test-contracts/get_table_test/get_table_test.cpp +++ b/unittests/test-contracts/get_table_test/get_table_test.cpp @@ -15,6 +15,21 @@ void get_table_test::addnumobj(uint64_t input) { }); } +void get_table_test::modifynumobj(uint64_t id) { + numobjs numobjs_table( _self, _self.value ); + numobjs_table.modify(numobjs_table.get(id), _self, [&](auto& obj) { + obj.sec64++; + }); +} + +void get_table_test::erasenumobj(uint64_t id) { + numobjs numobjs_table( _self, _self.value ); + auto iterator = numobjs_table.find(id); + check(iterator != numobjs_table.end(), "Record does not exist."); + numobjs_table.erase(iterator); +} + + void get_table_test::addhashobj(std::string hashinput) { hashobjs hashobjs_table( _self, _self.value ); hashobjs_table.emplace(_self, [&]( auto& obj ) { diff --git a/unittests/test-contracts/get_table_test/get_table_test.hpp b/unittests/test-contracts/get_table_test/get_table_test.hpp index a777bfd63e..7a5cc7da02 100644 --- a/unittests/test-contracts/get_table_test/get_table_test.hpp +++ b/unittests/test-contracts/get_table_test/get_table_test.hpp @@ -7,6 +7,50 @@ #include #include + +namespace eosio { + namespace internal_use_do_not_use { + extern "C" { + __attribute__((eosio_wasm_import)) + int32_t alt_bn128_add( const char* op1_data, uint32_t op1_length, + const char* op2_data, uint32_t op2_length, + char* result , uint32_t result_length); + + __attribute__((eosio_wasm_import)) + int32_t alt_bn128_mul( const char* op1_data, uint32_t op1_length, + const char* op2_data, uint32_t op2_length, + char* result , uint32_t result_length); + + __attribute__((eosio_wasm_import)) + int32_t alt_bn128_pair( const char* op1_data, uint32_t op1_length); + + __attribute__((eosio_wasm_import)) + int32_t mod_exp(const char* base_data, uint32_t base_length, + const char* exp_data, uint32_t exp_length, + const char* mod_data, uint32_t mod_length, + char* result, uint32_t result_length); + + __attribute__((eosio_wasm_import)) + int32_t blake2_f( uint32_t rounds, + const char* state, uint32_t len_state, + const char* message, uint32_t len_message, + const char* t0_offset, uint32_t len_t0_offset, + const char* t1_offset, uint32_t len_t1_offset, + int32_t final, + char* result, uint32_t len_result); + + __attribute__((eosio_wasm_import)) + void sha3( const char* input_data, uint32_t input_length, + char* output_data, uint32_t output_length, int32_t keccak); + + __attribute__((eosio_wasm_import)) + int32_t k1_recover( const char* signature_data, uint32_t signature_length, + const char* digest_data, uint32_t digest_length, + char* output_data, uint32_t output_length); + } + } +} + using namespace eosio; class [[eosio::contract]] get_table_test : public eosio::contract { @@ -55,6 +99,12 @@ class [[eosio::contract]] get_table_test : public eosio::contract { [[eosio::action]] void addnumobj(uint64_t input); + [[eosio::action]] + void modifynumobj(uint64_t id); + + [[eosio::action]] + void erasenumobj(uint64_t id); + [[eosio::action]] void addhashobj(std::string hashinput); From 06a7a4f8987acb3cde625f0182bf77577683210b Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 15 Jul 2022 14:05:35 -0500 Subject: [PATCH 5/7] GH-599 added abi/wasm for get_table_test --- .../get_table_test/get_table_test.abi | 35 +++++++++++++++++- .../get_table_test/get_table_test.wasm | Bin 13428 -> 48478 bytes 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/unittests/test-contracts/get_table_test/get_table_test.abi b/unittests/test-contracts/get_table_test/get_table_test.abi index 1a7cdcc213..523a431842 100644 --- a/unittests/test-contracts/get_table_test/get_table_test.abi +++ b/unittests/test-contracts/get_table_test/get_table_test.abi @@ -1,6 +1,6 @@ { "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", - "version": "eosio::abi/1.1", + "version": "eosio::abi/1.2", "types": [], "structs": [ { @@ -23,6 +23,16 @@ } ] }, + { + "name": "erasenumobj", + "base": "", + "fields": [ + { + "name": "id", + "type": "uint64" + } + ] + }, { "name": "hashobj", "base": "", @@ -45,6 +55,16 @@ } ] }, + { + "name": "modifynumobj", + "base": "", + "fields": [ + { + "name": "id", + "type": "uint64" + } + ] + }, { "name": "numobj", "base": "", @@ -82,6 +102,16 @@ "name": "addnumobj", "type": "addnumobj", "ricardian_contract": "" + }, + { + "name": "erasenumobj", + "type": "erasenumobj", + "ricardian_contract": "" + }, + { + "name": "modifynumobj", + "type": "modifynumobj", + "ricardian_contract": "" } ], "tables": [ @@ -101,5 +131,6 @@ } ], "ricardian_clauses": [], - "variants": [] + "variants": [], + "action_results": [] } \ No newline at end of file diff --git a/unittests/test-contracts/get_table_test/get_table_test.wasm b/unittests/test-contracts/get_table_test/get_table_test.wasm index cc1b5399505b8370abfa52a7c264c2cbca1ba9e8..ef0bfa3dccf87c2e3ccc3910b71221088c27272d 100755 GIT binary patch literal 48478 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%0D?Wtd9(UP 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 From da5a23ba5eb27a9b21d374f8cfb88400578b56f7 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 15 Jul 2022 14:06:47 -0500 Subject: [PATCH 6/7] GH-599 added 2 abihash deltas to expected deltas --- unittests/state_history_tests.cpp | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 7bc58748f8..ace6102606 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -453,15 +453,8 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { } BOOST_AUTO_TEST_CASE(test_deltas_contract_several_rows){ - table_deltas_tester chain(setup_policy::preactivate_feature_and_new_bios ); + table_deltas_tester chain(setup_policy::full); - chain.produce_block(); - - const auto& pfm = chain.control->get_protocol_feature_manager(); - const auto& d = pfm.get_builtin_digest( builtin_protocol_feature_t::crypto_primitives ); - BOOST_REQUIRE( d ); - - chain.preactivate_protocol_features( {*d} ); chain.produce_block(); chain.create_account("tester"_n); @@ -492,14 +485,16 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { auto result = chain.find_table_delta("contract_row", true); BOOST_REQUIRE(result.first); auto &it_contract_row = result.second; - BOOST_REQUIRE_EQUAL(it_contract_row->rows.obj.size(), 6); + BOOST_REQUIRE_EQUAL(it_contract_row->rows.obj.size(), 8); auto contract_rows = chain.deserialize_data(it_contract_row); - std::multiset expected_contract_row_table_names {"hashobjs", "hashobjs", "hashobjs", "numobjs", "numobjs", "numobjs"}; - std::multiset expected_contract_row_table_primary_keys {0, 1 ,2, 0, 1, 2}; + std::multiset expected_contract_row_table_names {"abihash", "abihash", "hashobjs", "hashobjs", "hashobjs", "numobjs", "numobjs", "numobjs"}; + + std::multiset expected_contract_row_table_primary_keys {6138663577826885632,14605619288908759040, 0, 1 ,2, 0, 1, 2}; std::multiset result_contract_row_table_names; std::multiset result_contract_row_table_primary_keys; for(auto &contract_row : contract_rows) { + std::cerr << contract_row.table.to_string() << ":" << contract_row.primary_key << std::endl; result_contract_row_table_names.insert(contract_row.table.to_string()); result_contract_row_table_primary_keys.insert(contract_row.primary_key); } From 986d8356bc8e007a08838a7380dfdfcd7a85a932 Mon Sep 17 00:00:00 2001 From: Chris Gundlach Date: Fri, 15 Jul 2022 14:29:15 -0500 Subject: [PATCH 7/7] GH-599 took out debug messages --- unittests/state_history_tests.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index ace6102606..e3b0d28d7a 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -494,7 +494,6 @@ BOOST_AUTO_TEST_CASE(test_deltas_resources_history) { std::multiset result_contract_row_table_names; std::multiset result_contract_row_table_primary_keys; for(auto &contract_row : contract_rows) { - std::cerr << contract_row.table.to_string() << ":" << contract_row.primary_key << std::endl; result_contract_row_table_names.insert(contract_row.table.to_string()); result_contract_row_table_primary_keys.insert(contract_row.primary_key); }