From a2b4e6dd69ba600fe4a46642b1916f5bfd670854 Mon Sep 17 00:00:00 2001 From: Huang-Ming Huang Date: Mon, 21 Dec 2020 11:54:37 -0600 Subject: [PATCH 1/3] fix ship trace log back compatibility --- libraries/chain/block_log.cpp | 8 +- .../chain/include/eosio/chain/log_catalog.hpp | 6 +- .../include/eosio/state_history/log.hpp | 16 ++- libraries/state_history/log.cpp | 31 +++-- .../state_history_plugin.cpp | 2 +- unittests/state_history_tests.cpp | 107 ++++++++++++------ 6 files changed, 111 insertions(+), 59 deletions(-) diff --git a/libraries/chain/block_log.cpp b/libraries/chain/block_log.cpp index d025153d095..b91a1ee62bf 100644 --- a/libraries/chain/block_log.cpp +++ b/libraries/chain/block_log.cpp @@ -320,12 +320,12 @@ namespace eosio { namespace chain { return fc::endian_reverse_u32(prev_block_num) + 1; } - fc::datastream ro_stream_at(uint64_t pos) { - return fc::datastream(file.const_data() + pos, file.size() - pos); + std::pair,uint32_t> ro_stream_at(uint64_t pos) { + return std::make_pair(fc::datastream(file.const_data() + pos, file.size() - pos), version()); } - fc::datastream rw_stream_at(uint64_t pos) { - return fc::datastream(file.data() + pos, file.size() - pos); + std::pair,uint32_t> rw_stream_at(uint64_t pos) { + return std::make_pair(fc::datastream(file.data() + pos, file.size() - pos), version()); } /** diff --git a/libraries/chain/include/eosio/chain/log_catalog.hpp b/libraries/chain/include/eosio/chain/log_catalog.hpp index 6b78f3e5cff..48f17cd156e 100644 --- a/libraries/chain/include/eosio/chain/log_catalog.hpp +++ b/libraries/chain/include/eosio/chain/log_catalog.hpp @@ -162,7 +162,7 @@ struct log_catalog { std::pair, uint32_t> ro_stream_for_block(uint32_t block_num) { auto pos = get_block_position(block_num, mapmode::readonly); if (pos) { - return std::make_pair(log_data.ro_stream_at(*pos), log_data.version()); + return log_data.ro_stream_at(*pos); } return {fc::datastream(nullptr, 0), static_cast(0)}; } @@ -170,7 +170,7 @@ struct log_catalog { std::pair, uint32_t> rw_stream_for_block(uint32_t block_num) { auto pos = get_block_position(block_num, mapmode::readwrite); if (pos) { - return std::make_pair(log_data.rw_stream_at(*pos), log_data.version()); + return log_data.rw_stream_at(*pos); } return {fc::datastream(nullptr, 0), static_cast(0)}; } @@ -272,4 +272,4 @@ struct log_catalog { }; } // namespace chain -} // namespace eosio \ No newline at end of file +} // namespace eosio diff --git a/libraries/state_history/include/eosio/state_history/log.hpp b/libraries/state_history/include/eosio/state_history/log.hpp index ae5e4fef52d..595628da155 100644 --- a/libraries/state_history/include/eosio/state_history/log.hpp +++ b/libraries/state_history/include/eosio/state_history/log.hpp @@ -80,13 +80,17 @@ class state_history_log_data : public chain::log_data_base ro_stream_at(uint64_t pos) const { - return fc::datastream(file.const_data() + pos + sizeof(state_history_log_header), - payload_size_at(pos)); + std::pair, uint32_t> ro_stream_at(uint64_t pos) const { + uint32_t ver = get_ship_version(chain::read_buffer(file.const_data() + pos)); + return std::make_pair( + fc::datastream(file.const_data() + pos + sizeof(state_history_log_header), payload_size_at(pos)), + ver); } - fc::datastream rw_stream_at(uint64_t pos) const { - return fc::datastream(file.data() + pos + sizeof(state_history_log_header), payload_size_at(pos)); + std::pair, uint32_t> rw_stream_at(uint64_t pos) const { + uint32_t ver = get_ship_version(chain::read_buffer(file.const_data() + pos)); + return std::make_pair( + fc::datastream(file.data() + pos + sizeof(state_history_log_header), payload_size_at(pos)), ver); } uint32_t block_num_at(uint64_t position) const { @@ -197,7 +201,7 @@ class state_history_traces_log : public state_history_log { cache.add_transaction(trace, transaction); } - std::vector get_traces(block_num_type block_num); + chain::bytes get_log_entry(block_num_type block_num); void block_start(uint32_t block_num) { cache.clear(); } diff --git a/libraries/state_history/log.cpp b/libraries/state_history/log.cpp index 78cefc8b3dc..c49c7593c96 100644 --- a/libraries/state_history/log.cpp +++ b/libraries/state_history/log.cpp @@ -292,28 +292,39 @@ void state_history_log::split_log() { state_history_traces_log::state_history_traces_log(const state_history_config& config) : state_history_log("trace_history", config) {} -std::vector state_history_traces_log::get_traces(block_num_type block_num) { +chain::bytes state_history_traces_log::get_log_entry(block_num_type block_num) { - auto [ds, _] = catalog.ro_stream_for_block(block_num); + auto get_traces_bin = [](auto& ds, uint32_t version) { + if (version == 0) { + return state_history::zlib_decompress(ds); + } + else { + std::vector traces; + state_history::trace_converter::unpack(ds, traces); + return fc::raw::pack(traces); + } + }; + + auto [ds, version] = catalog.ro_stream_for_block(block_num); if (ds.remaining()) { - std::vector traces; - state_history::trace_converter::unpack(ds, traces); - return traces; + return get_traces_bin(ds, version); } if (block_num < begin_block() || block_num >= end_block()) return {}; state_history_log_header header; get_entry_header(block_num, header); - std::vector traces; - state_history::trace_converter::unpack(read_log, traces); - return traces; + return get_traces_bin(read_log, get_ship_version(header.magic)); } + void state_history_traces_log::prune_transactions(state_history_log::block_num_type block_num, std::vector& ids) { - auto [ds, _] = catalog.rw_stream_for_block(block_num); + auto [ds, version] = catalog.rw_stream_for_block(block_num); + if (ds.remaining()) { + EOS_ASSERT(version > 0, chain::state_history_exception, + "The trace log version 0 does not support transaction pruning."); state_history::trace_converter::prune_traces(ds, ds.remaining(), ids); return; } @@ -322,6 +333,8 @@ void state_history_traces_log::prune_transactions(state_history_log::block_num_t return; state_history_log_header header; get_entry_header(block_num, header); + EOS_ASSERT(get_ship_version(header.magic) > 0, chain::state_history_exception, + "The trace log version 0 does not support transaction pruning."); write_log.seek(read_log.tellp()); state_history::trace_converter::prune_traces(write_log, header.payload_size, ids); write_log.flush(); diff --git a/plugins/state_history_plugin/state_history_plugin.cpp b/plugins/state_history_plugin/state_history_plugin.cpp index e957c973ac9..a510e9da94a 100644 --- a/plugins/state_history_plugin/state_history_plugin.cpp +++ b/plugins/state_history_plugin/state_history_plugin.cpp @@ -224,7 +224,7 @@ struct state_history_plugin_impl : std::enable_shared_from_thisfetch_block) result.block = plugin->get_block(current_request->start_block_num); if (current_request->fetch_traces && plugin->trace_log) { - result.traces = plugin->trace_log->get_traces(current_request->start_block_num); + result.traces = plugin->trace_log->get_log_entry(current_request->start_block_num); } if (current_request->fetch_deltas && plugin->chain_state_log) { result.deltas = plugin->chain_state_log->get_log_entry(current_request->start_block_num); diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 7cb83364a30..8010170411b 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -1,6 +1,6 @@ -#include #include #include +#include #include #include #include @@ -10,11 +10,8 @@ #include "test_cfd_transaction.hpp" #include -#pragma push_macro("N") -#undef N -#include #include -#pragma pop_macro("N") +#include using namespace eosio::chain; using namespace eosio::testing; @@ -24,11 +21,13 @@ using prunable_data_type = eosio::chain::packed_transaction::prunable_data_type; namespace bio = boost::iostreams; extern const char* const state_history_plugin_abi; -prunable_data_type::prunable_data_t get_prunable_data_from_traces(std::vector& traces, - const transaction_id_type& id) { - auto cfd_trace_itr = std::find_if(traces.begin(), traces.end(), [id](const eosio::state_history::transaction_trace& v) { - return std::get(v).id == id; - }); +prunable_data_type::prunable_data_t +get_prunable_data_from_traces(std::vector& traces, + const transaction_id_type& id) { + auto cfd_trace_itr = + std::find_if(traces.begin(), traces.end(), [id](const eosio::state_history::transaction_trace& v) { + return std::get(v).id == id; + }); // make sure the trace with cfd can be found BOOST_REQUIRE(cfd_trace_itr != traces.end()); @@ -39,14 +38,45 @@ prunable_data_type::prunable_data_t get_prunable_data_from_traces(std::vector(*trace_v0.partial).prunable_data->prunable_data; } +bool operator==(const eosio::checksum256& lhs, const transaction_id_type& rhs) { + return memcmp(lhs.extract_as_byte_array().data(), rhs.data(), rhs.data_size()) == 0; +} + +auto get_prunable_data_from_traces(std::vector& traces, + const transaction_id_type& id) { + auto cfd_trace_itr = + std::find_if(traces.begin(), traces.end(), [id](const eosio::ship_protocol::transaction_trace& v) { + return std::get(v).id == id; + }); + + // make sure the trace with cfd can be found + BOOST_REQUIRE(cfd_trace_itr != traces.end()); + BOOST_REQUIRE(std::holds_alternative(*cfd_trace_itr)); + auto trace_v0 = std::get(*cfd_trace_itr); + BOOST_REQUIRE(trace_v0.partial); + BOOST_REQUIRE(std::holds_alternative(*trace_v0.partial)); + return std::get(*trace_v0.partial).prunable_data->prunable_data; +} + prunable_data_type::prunable_data_t get_prunable_data_from_traces_bin(const std::vector& entry, const transaction_id_type& id) { - fc::datastream strm(entry.data(), entry.size()); + fc::datastream strm(entry.data(), entry.size()); std::vector traces; eosio::state_history::trace_converter::unpack(strm, traces); return get_prunable_data_from_traces(traces, id); } +std::vector get_traces(eosio::state_history_traces_log& log, + block_num_type block_num) { + auto entry = log.get_log_entry(block_num); + std::vector traces; + if (entry.size()) { + eosio::input_stream traces_bin{entry.data(), entry.data() + entry.size()}; + BOOST_REQUIRE_NO_THROW(from_bin(traces, traces_bin)); + } + return traces; +} + struct state_history_abi_serializer { tester& chain; abi_serializer sr; @@ -132,10 +162,11 @@ BOOST_AUTO_TEST_CASE(test_trace_log) { auto cfd_trace = push_test_cfd_transaction(chain); chain.produce_blocks(1); - auto traces = log.get_traces(cfd_trace->block_num); + auto traces = get_traces(log, cfd_trace->block_num); BOOST_REQUIRE(traces.size()); - BOOST_REQUIRE(!std::holds_alternative(get_prunable_data_from_traces(traces, cfd_trace->id))); + BOOST_REQUIRE(!std::holds_alternative( + get_prunable_data_from_traces(traces, cfd_trace->id))); std::vector ids{cfd_trace->id}; log.prune_transactions(cfd_trace->block_num, ids); @@ -144,10 +175,11 @@ BOOST_AUTO_TEST_CASE(test_trace_log) { // we assume the nodeos has to be stopped while running, it can only be read // correctly with restart eosio::state_history_traces_log new_log({ .log_dir = state_history_dir.path }); - auto pruned_traces = new_log.get_traces(cfd_trace->block_num); + auto pruned_traces = get_traces(new_log, cfd_trace->block_num); BOOST_REQUIRE(pruned_traces.size()); - BOOST_CHECK(std::holds_alternative(get_prunable_data_from_traces(pruned_traces, cfd_trace->id))); + BOOST_CHECK(std::holds_alternative( + get_prunable_data_from_traces(pruned_traces, cfd_trace->id))); } BOOST_AUTO_TEST_CASE(test_chain_state_log) { @@ -258,11 +290,11 @@ BOOST_AUTO_TEST_CASE(test_splitted_log) { BOOST_CHECK(bfs::exists( retained_dir / "chain_state_history-121-140.log" )); BOOST_CHECK(bfs::exists( retained_dir / "chain_state_history-121-140.index" )); - BOOST_CHECK(chain.traces_log.get_traces(10).empty()); - BOOST_CHECK(chain.traces_log.get_traces(100).size()); - BOOST_CHECK(chain.traces_log.get_traces(140).size()); - BOOST_CHECK(chain.traces_log.get_traces(150).size()); - BOOST_CHECK(chain.traces_log.get_traces(160).empty()); + BOOST_CHECK(get_traces(chain.traces_log, 10).empty()); + BOOST_CHECK(get_traces(chain.traces_log, 100).size()); + BOOST_CHECK(get_traces(chain.traces_log, 140).size()); + BOOST_CHECK(get_traces(chain.traces_log, 150).size()); + BOOST_CHECK(get_traces(chain.traces_log, 160).empty()); BOOST_CHECK(chain.chain_state_log.get_log_entry(10).empty()); BOOST_CHECK(chain.chain_state_log.get_log_entry(100).size()); @@ -270,10 +302,11 @@ BOOST_AUTO_TEST_CASE(test_splitted_log) { BOOST_CHECK(chain.chain_state_log.get_log_entry(150).size()); BOOST_CHECK(chain.chain_state_log.get_log_entry(160).empty()); - auto traces = chain.traces_log.get_traces(cfd_trace->block_num); + auto traces = get_traces(chain.traces_log, cfd_trace->block_num); BOOST_REQUIRE(traces.size()); - BOOST_REQUIRE(!std::holds_alternative(get_prunable_data_from_traces(traces, cfd_trace->id))); + BOOST_REQUIRE(!std::holds_alternative( + get_prunable_data_from_traces(traces, cfd_trace->id))); std::vector ids{cfd_trace->id}; chain.traces_log.prune_transactions(cfd_trace->block_num, ids); @@ -282,10 +315,11 @@ BOOST_AUTO_TEST_CASE(test_splitted_log) { // we assume the nodeos has to be stopped while running, it can only be read // correctly with restart eosio::state_history_traces_log new_log(config); - auto pruned_traces = new_log.get_traces(cfd_trace->block_num); + auto pruned_traces = get_traces(new_log, cfd_trace->block_num); BOOST_REQUIRE(pruned_traces.size()); - BOOST_CHECK(std::holds_alternative(get_prunable_data_from_traces(pruned_traces, cfd_trace->id))); + BOOST_CHECK(std::holds_alternative( + get_prunable_data_from_traces(pruned_traces, cfd_trace->id))); } void push_blocks( tester& from, tester& to ) { @@ -335,10 +369,10 @@ bool test_fork(uint32_t stride, uint32_t max_retained_files) { auto fb = chain2.control->fetch_block_by_number( start ); chain1.push_block( fb ); } - auto traces = chain1.traces_log.get_traces(b->block_num()); + auto traces = get_traces(chain1.traces_log, b->block_num()); bool trace_found = std::find_if(traces.begin(), traces.end(), [create_account_trace_id](const auto& v) { - return std::get(v).id == create_account_trace_id; + return std::get(v).id == create_account_trace_id; }) != traces.end(); return trace_found; @@ -390,7 +424,7 @@ BOOST_AUTO_TEST_CASE(test_corrupted_log_recovery) { state_history_tester new_chain(config); new_chain.produce_blocks(50); - BOOST_CHECK(new_chain.traces_log.get_traces(10).size()); + BOOST_CHECK(get_traces(new_chain.traces_log, 10).size()); BOOST_CHECK(new_chain.chain_state_log.get_log_entry(10).size()); } @@ -510,25 +544,26 @@ BOOST_AUTO_TEST_CASE(test_traces_present) BOOST_CHECK(onblock_test_executed); - auto traces = log.get_traces(tr_ptr->block_num); + auto traces = get_traces(log, tr_ptr->block_num); BOOST_REQUIRE_EQUAL(traces.size(), 1); - auto trace_itr = std::find_if(traces.begin(), traces.end(), [tr_ptr](const eosio::state_history::transaction_trace& v) { - return std::get(v).id == tr_ptr->id; - }); + auto trace_itr = + std::find_if(traces.begin(), traces.end(), [tr_ptr](const eosio::ship_protocol::transaction_trace& v) { + return std::get(v).id == tr_ptr->id; + }); BOOST_REQUIRE(trace_itr != traces.end()); - auto &action_traces = std::get(*trace_itr).action_traces; + auto& action_traces = std::get(*trace_itr).action_traces; - auto new_account_action_itr = std::find_if(action_traces.begin(), action_traces.end(), [](const eosio::state_history::action_trace& v) { - return std::get(v).act.name == "newaccount"_n.to_uint64_t(); - }); + auto new_account_action_itr = + std::find_if(action_traces.begin(), action_traces.end(), [](const eosio::ship_protocol::action_trace& v) { + return std::get(v).act.name.value == "newaccount"_n.to_uint64_t(); + }); BOOST_REQUIRE(new_account_action_itr != action_traces.end()); } - class table_deltas_tester : public tester { public: using tester::tester; From 36f179b231f84b62276c879baec0212d90c8f4ac Mon Sep 17 00:00:00 2001 From: Victor Camacho Date: Tue, 22 Dec 2020 11:33:41 -0500 Subject: [PATCH 2/3] add unit test for testing versions of trace_history logs --- unittests/CMakeLists.txt | 3 +++ unittests/state-history-data/CMakeLists.txt | 2 ++ .../trace-log-v0/CMakeLists.txt | 2 ++ .../trace-log-v0/trace_history.index | Bin 0 -> 80 bytes .../trace-log-v0/trace_history.log | Bin 0 -> 2644 bytes .../trace-log-v1/CMakeLists.txt | 2 ++ .../trace-log-v1/trace_history.index | Bin 0 -> 128 bytes .../trace-log-v1/trace_history.log | Bin 0 -> 643041 bytes unittests/state_history_tests.cpp | 14 ++++++++++++++ unittests/utilities.hpp.in | 9 +++++++++ 10 files changed, 32 insertions(+) create mode 100644 unittests/state-history-data/CMakeLists.txt create mode 100644 unittests/state-history-data/trace-log-v0/CMakeLists.txt create mode 100644 unittests/state-history-data/trace-log-v0/trace_history.index create mode 100644 unittests/state-history-data/trace-log-v0/trace_history.log create mode 100644 unittests/state-history-data/trace-log-v1/CMakeLists.txt create mode 100644 unittests/state-history-data/trace-log-v1/trace_history.index create mode 100644 unittests/state-history-data/trace-log-v1/trace_history.log create mode 100644 unittests/utilities.hpp.in diff --git a/unittests/CMakeLists.txt b/unittests/CMakeLists.txt index 88c67577694..a5e0d1fa6aa 100644 --- a/unittests/CMakeLists.txt +++ b/unittests/CMakeLists.txt @@ -32,6 +32,9 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/contracts.hpp.in ${CMAKE_CURRENT_BINA add_subdirectory(snapshots) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/snapshots.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/include/snapshots.hpp ESCAPE_QUOTES) +add_subdirectory(state-history-data) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/utilities.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/include/utilities.hpp ESCAPE_QUOTES) + add_custom_command( OUTPUT protocol_feature_digest_tests.cpp COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/gen_protocol_feature_digest_tests.py ${CMAKE_CURRENT_SOURCE_DIR}/../libraries/chain/protocol_feature_manager.cpp > protocol_feature_digest_tests.cpp diff --git a/unittests/state-history-data/CMakeLists.txt b/unittests/state-history-data/CMakeLists.txt new file mode 100644 index 00000000000..9d1b970e287 --- /dev/null +++ b/unittests/state-history-data/CMakeLists.txt @@ -0,0 +1,2 @@ +add_subdirectory(trace-log-v0) +add_subdirectory(trace-log-v1) \ No newline at end of file diff --git a/unittests/state-history-data/trace-log-v0/CMakeLists.txt b/unittests/state-history-data/trace-log-v0/CMakeLists.txt new file mode 100644 index 00000000000..25a384937d0 --- /dev/null +++ b/unittests/state-history-data/trace-log-v0/CMakeLists.txt @@ -0,0 +1,2 @@ +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/trace_history.index ${CMAKE_CURRENT_BINARY_DIR}/trace_history.index COPYONLY ) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/trace_history.log ${CMAKE_CURRENT_BINARY_DIR}/trace_history.log COPYONLY ) \ No newline at end of file diff --git a/unittests/state-history-data/trace-log-v0/trace_history.index b/unittests/state-history-data/trace-log-v0/trace_history.index new file mode 100644 index 0000000000000000000000000000000000000000..4d7eda8534af8e51d3dfab05aaaf146a97b24f69 GIT binary patch literal 80 pcmZQzfPhy}`YR)p!3?2!SRk|{D}+{IgU|--5ZampLVIvRXaJb)0|x*A literal 0 HcmV?d00001 diff --git a/unittests/state-history-data/trace-log-v0/trace_history.log b/unittests/state-history-data/trace-log-v0/trace_history.log new file mode 100644 index 0000000000000000000000000000000000000000..1d8fba5775e90da4882c1e8750c8b6637521cd85 GIT binary patch literal 2644 zcmZvddohL}rk8*_`?_nXo=o&4VCeBSSWUVnUEkMq0$0L)_ouVdb?rp#P6sxK%H%g%cu<(M zMJ23EkB|tO0+3v=16#ZU7blMA98k$OZY(GGWVP8y`Ia~F)UEI1-N3~{K1vI*ze1r@ zzB7Rr3ryqmKo;C(Ex;Hw>eF5`&h5=xq>pLLelHTT z!Zu&5YG?0iVDH)2)pXb6xCwijRgy;SU0xf9hHIdlqzHycge*qbvkJYbjwmW<7VGIGo2cSZAv*vg@JOE#K~ey zyj|>X6w;_;!}yO(6!@kqFQ~sUY`?!yumebE18xK9_25RM@jQ$ztLnpAVCL(!210!M z-oH`2!fN*_`Spz!3Y1?ftR6UQesVQnxuSjy4%MpE2YFDR3845mz3%YxydO%@nH)}D zrxb)MS&+^wTFtMfC=^1vs5Pm?*w^%M89eok7(rUmLQv6G)dHl5DLBiExN1nB{^OB2cvec<9`9Te^*>+BcB_ahSI_n(P@r$w-P{l?0~QgGsY6j zA1r>M;J6cDb65fRG}A_oR$%o$GTl2yL-N$)lsXuIzvRo#cqjAS)<4+$%>2yQR-Yx8%`Y_G`C2qQzQ-Lfza9IfM&g)vPg5GpN6NxzK+U5C8stvn~y0< z`)1tKoRZNBq!3Q<7SbM_UATV%Umds4&AEN{p-pC${#G3OB183MrH^NTtUKitdGz77 zEZmq55kQ5|kp>b{fE%F}?*MGOSa5QcbwI!guKlL5bmM;#twV~F^pto(zM&HfiG;45 z@lQJ}QW+Pm^WDdWGkl)ZBv(j{s~+Ab8s%`YCSH65_|i4|n!~qa=l@Azb0B zZc=`Eo#7}P1KsFzVxao0UzPLPrn|wJ{nJ24s2$W@RNg{Rep?sv|3??AKXvipW^Yy* zdVPR5+S#t-2{zUdGCR7Qx zwt8)EjO{bnQba;=l;xqnJ;F73%h%vr*_+E|-Ckx%HQ6C~v-xmh%Lz#4D8-P`+N&A* zXIz}2VgyG7r%<*$>Q&)13M15Mxzyg6xN0>$Ac%Z_h>p77`=W|GRF!qO*W@xstOUu( zY~m?c3Ro26iLik5GEm~N9^I(V7v#d}Q+^<2dmN7@Sxp{CGBWjP`BFE`lPywGCC060 zV@Pg2d2nBC$cnAyfI5pc-*?;3LDb*6N%|M@GIqZyd{rS?CrpMnJk zzR=7*9wmy26UB;P9*K5Yyx@Wq9}S4$2EBO~i`UmbX1?LGlJ&}Ul345X`VwGZ~R8FbbG-&m^t|M z6~4CS>0PoQw%%UYpeM>0q31*Jca0lT__a#l83Zp>>uS$%@THh%JaRl_07xk6y?nGu zWOnkR5oS@v{)T*ibra)Q z*1O-5xk29A5Fs^T>B+iJU}Gyc<7!WBxtxU%GcN8VC#IyQcMcBBa(HXN$#%3wq)$+3 z^^~z_Wk)GA?BDe6pDlu9#>IY=_?SoJ0bW48u<0G}o?R&R%1f;1^2fuEI+p5K6lnMQ`15_w1>E`&psVbgoxYb(CqE^( zUBOXLzi!_FIygfqH~j`Rr$hrRJ>^n;{|we<1uvH;Nj zR`)cycEJF8S2W+m%0&|-6iAPV?fwus$16fJ%_IxpP;TDe9!d3^ab0Jd<)?*Bi2L@v z#jgdn<+I&4hoe{D#vI8MDttY?M|Urq$~!KU!(5Am{{S+FBIsWhA&j_A7pz&Bi6H0B z=<@^{h*W((r~5p`D`p~!Iuga~k#FaA_lW<`9#PK&rNh#hD^x2v<~wvef9o+}CC2rS z3VBk&cln!05!Qeexbd?573R53*=DC9@#}eaL4uXSYdTS5*6vWL9U=EIiERf4>*m|( TuOa6jZ~?%Emg*O{f3f%<&)~Hh literal 0 HcmV?d00001 diff --git a/unittests/state-history-data/trace-log-v1/CMakeLists.txt b/unittests/state-history-data/trace-log-v1/CMakeLists.txt new file mode 100644 index 00000000000..25a384937d0 --- /dev/null +++ b/unittests/state-history-data/trace-log-v1/CMakeLists.txt @@ -0,0 +1,2 @@ +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/trace_history.index ${CMAKE_CURRENT_BINARY_DIR}/trace_history.index COPYONLY ) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/trace_history.log ${CMAKE_CURRENT_BINARY_DIR}/trace_history.log COPYONLY ) \ No newline at end of file diff --git a/unittests/state-history-data/trace-log-v1/trace_history.index b/unittests/state-history-data/trace-log-v1/trace_history.index new file mode 100644 index 0000000000000000000000000000000000000000..35406cc3403e8bb09f78a8b5bb4601aa63a152a4 GIT binary patch literal 128 zcmcC+vKC0IK5>u>b%7 literal 0 HcmV?d00001 diff --git a/unittests/state-history-data/trace-log-v1/trace_history.log b/unittests/state-history-data/trace-log-v1/trace_history.log new file mode 100644 index 0000000000000000000000000000000000000000..8204d83365fd2c397dc82e4e76af67aba3a530ed GIT binary patch literal 643041 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 literal 0 HcmV?d00001 diff --git a/unittests/state_history_tests.cpp b/unittests/state_history_tests.cpp index 8010170411b..cbce759dab2 100644 --- a/unittests/state_history_tests.cpp +++ b/unittests/state_history_tests.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include #include @@ -182,6 +183,19 @@ BOOST_AUTO_TEST_CASE(test_trace_log) { get_prunable_data_from_traces(pruned_traces, cfd_trace->id))); } +BOOST_AUTO_TEST_CASE(test_trace_log_versions) { + namespace bfs = boost::filesystem; + + for(std::string version : {"v0", "v1"}) { + tester chain; + eosio::state_history_traces_log log({ .log_dir = state_history_data_base_path() + "/trace-log-"+ version }); + + for(int i = 2; i <= 11; i++) { + auto traces = get_traces(log, i); + } + } +} + BOOST_AUTO_TEST_CASE(test_chain_state_log) { namespace bfs = boost::filesystem; diff --git a/unittests/utilities.hpp.in b/unittests/utilities.hpp.in new file mode 100644 index 00000000000..ff71a5ffbd1 --- /dev/null +++ b/unittests/utilities.hpp.in @@ -0,0 +1,9 @@ +#pragma once + +namespace eosio { + namespace testing { + std::string state_history_data_base_path() { + return "${CMAKE_BINARY_DIR}/unittests/state-history-data"; + } + } +} From e4bc8326ac1bf2d66fa84fcf99349179f2bc40c5 Mon Sep 17 00:00:00 2001 From: Victor Camacho Date: Tue, 22 Dec 2020 14:51:08 -0500 Subject: [PATCH 3/3] fix ship test data for trace_history log v1 --- .../trace-log-v1/trace_history.index | Bin 128 -> 128 bytes .../trace-log-v1/trace_history.log | Bin 643041 -> 19013 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/unittests/state-history-data/trace-log-v1/trace_history.index b/unittests/state-history-data/trace-log-v1/trace_history.index index 35406cc3403e8bb09f78a8b5bb4601aa63a152a4..f9a40fb098de9f94db5373b5a623b19cc0d6a9ec 100644 GIT binary patch literal 128 zcmZQzfB<1e2<^cHq3f6-^kxvKC0IK5>u>b%7 diff --git a/unittests/state-history-data/trace-log-v1/trace_history.log b/unittests/state-history-data/trace-log-v1/trace_history.log index 8204d83365fd2c397dc82e4e76af67aba3a530ed..e60d20f3d754d970a9a635044c8ad9bfef4f6148 100644 GIT binary patch literal 19013 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 literal 643041 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