Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tests for get_serialized_block_by_number #810

Merged
merged 2 commits into from
Sep 23, 2024
Merged
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
112 changes: 112 additions & 0 deletions unittests/block_log_get_block_tests.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#include <eosio/chain/block_log.hpp>
#include <eosio/testing/tester.hpp> // for fc_exception_message_contains

#include <fc/io/cfile.hpp>

#include <boost/test/unit_test.hpp>

using namespace eosio::chain;
using namespace eosio::testing;

struct block_log_get_block_fixture {
block_log_get_block_fixture() {
block_dir = dir.path();

log.emplace(block_dir);

log->reset(genesis_state(), std::make_shared<signed_block>());
BOOST_REQUIRE_EQUAL(log->first_block_num(), 1u);
BOOST_REQUIRE_EQUAL(log->head()->block_num(), 1u);

for(uint32_t i = 2; i < last_block_num + 1; ++i) {
auto p = std::make_shared<signed_block>();
p->previous._hash[0] = fc::endian_reverse_u32(i-1);
log->append(p, p->calculate_id());
}
BOOST_REQUIRE_EQUAL(log->head()->block_num(), last_block_num);
};

void test_read_serialized_block(const block_log& blog, uint32_t block_num) {
// read the serialized block
auto serialized_block = blog.read_serialized_block_by_num(block_num);

// the serialized block can be deserialized
BOOST_REQUIRE_NO_THROW(fc::raw::unpack<signed_block>(serialized_block));

// read the signed block by regular read_block_by_num
signed_block_ptr block = blog.read_block_by_num(block_num);
BOOST_REQUIRE(block);

// the serialized block should match the signed block's serialized form
BOOST_REQUIRE(serialized_block == fc::raw::pack(*block));
}

fc::temp_directory dir;
std::filesystem::path block_dir;
std::optional<block_log> log;
static constexpr uint32_t last_block_num = 50;
};

BOOST_AUTO_TEST_SUITE(block_log_get_block_tests)

BOOST_FIXTURE_TEST_CASE(basic_block_log, block_log_get_block_fixture) try {
// test reading a non-last-block
test_read_serialized_block(*log, last_block_num - 2);

// test reading last block
test_read_serialized_block(*log, last_block_num);
} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(splitted_block_log, block_log_get_block_fixture) try {
uint32_t stride = last_block_num / 2;
auto retained_dir = block_dir / "retained";

block_log::split_blocklog(block_dir, retained_dir, stride);

std::filesystem::remove(block_dir / "blocks.log");
std::filesystem::remove(block_dir / "blocks.index");

block_log blog(block_dir, partitioned_blocklog_config{ .retained_dir = retained_dir });

// test reading a block in the first partitioned log
test_read_serialized_block(blog, stride - 1);

// test reading a block in the second partitioned log
test_read_serialized_block(blog, stride + 1);
} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(nonexisting_block_num, block_log_get_block_fixture) try {
// read a non-existing block
auto serialized_block = log->read_serialized_block_by_num(last_block_num + 1);

// should return an empty vector of char
BOOST_REQUIRE(serialized_block.empty());
} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(corrupted_next_block_position, block_log_get_block_fixture) try {
// intentionally modify block position for next block (which is the last block)
uint64_t bad_pos = sizeof(uint64_t) * (last_block_num);
fc::datastream<fc::cfile> index_file;
index_file.set_file_path(block_dir / "blocks.index");
index_file.open(fc::cfile::update_rw_mode);
index_file.seek_end(-sizeof(uint64_t));
index_file.write((char*)&bad_pos, sizeof(bad_pos));
index_file.flush();
index_file.close();

BOOST_CHECK_EXCEPTION(log->read_serialized_block_by_num(last_block_num - 1),
block_log_exception,
fc_exception_message_contains("next block position"));
} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(corrupted_file_size, block_log_get_block_fixture) try {
// corrupt file size by truncating it
auto new_size = log->get_block_pos(last_block_num) + sizeof(uint64_t);
std::filesystem::resize_file(block_dir / "blocks.log", new_size);

BOOST_CHECK_EXCEPTION(log->read_serialized_block_by_num(last_block_num),
block_log_exception,
fc_exception_message_contains("block log file size"));
} FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_SUITE_END()