Skip to content

Commit

Permalink
comment tweaks, logging tweaks, and minor renames
Browse files Browse the repository at this point in the history
  • Loading branch information
spoonincode committed Jun 11, 2024
1 parent 63dcefc commit 4681ad2
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 16 deletions.
2 changes: 1 addition & 1 deletion libraries/libfc/include/fc/io/random_access_file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ struct random_access_file_context {
do {
r = ftruncate(fd, static_cast<off_t>(size));
} while(r == -1 && errno == EINTR);
FC_ASSERT(r == 0, "ftruncate failure on file ${fn}: ${e}", ("fn", display_path)("e", strerror(errno)));
FC_ASSERT(r == 0, "failed to resize file ${fn} to ${sz} bytes: ${e}", ("fn", display_path)("sz", size)("e", strerror(errno)));
}

void punch_hole(size_t begin, size_t end) {
Expand Down
33 changes: 22 additions & 11 deletions libraries/state_history/include/eosio/state_history/log.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class state_history_log {
fc::random_access_file index;
uint32_t _begin_block = 0; //always tracks the first block available even after pruning
uint32_t _index_begin_block = 0; //the first block of the file; even after pruning. it's what index 0 in the index file points to
uint32_t _end_block = 0;
uint32_t _end_block = 0; //one-past-the-last block of the file
chain::block_id_type last_block_id;

inline static const unsigned packed_header_size = fc::raw::pack_size(log_header());
Expand All @@ -133,8 +133,8 @@ class state_history_log {
prune_config->prune_threshold = ~(prune_config->prune_threshold-1);
}

open_log();
open_index();
check_log_on_init();
check_index_on_init();

//check for conversions to/from pruned log, as long as log contains something
if(!empty()) {
Expand Down Expand Up @@ -293,7 +293,7 @@ class state_history_log {
return;

const uint32_t prune_to_num = _end_block - prune_config->prune_blocks;
///TODO: we need to cap this to the lowest position there are any active entries reading from
///TODO: we should cap this to the lowest position there are any active entries reading from, see https://github.com/AntelopeIO/spring/pull/237
uint64_t prune_to_pos = get_pos(prune_to_num);
log.punch_hole(fc::raw::pack_size(log_header()), prune_to_pos);

Expand All @@ -304,11 +304,12 @@ class state_history_log {
bool discover_and_check_last_block_ok(bool is_pruned) {
try {
//fetch the last block header from the log solely using the log (i.e. not the index: so don't use get_pos()). This is a sanity check.
log_header last_header = log.unpack_from<decltype(last_header)>(log.unpack_from<uint64_t>(log.size() - sizeof(uint64_t) - (is_pruned ? sizeof(uint32_t) : 0)));
const uint64_t last_header_pos = log.unpack_from<std::decay_t<decltype(last_header_pos)>>(log.size() - sizeof(uint64_t) - (is_pruned ? sizeof(uint32_t) : 0));
log_header last_header = log.unpack_from<decltype(last_header)>(last_header_pos);
FC_ASSERT(is_ship(last_header.magic) && is_ship_supported_version(last_header.magic), "Unexpected header magic on last block");
_end_block = chain::block_header::num_from_id(last_header.block_id) + 1;
last_block_id = last_header.block_id;
FC_ASSERT(_begin_block < _end_block, "Block numbers from head and tail of log are not expected");
FC_ASSERT(_begin_block < _end_block, "Block number ${hbn} from head and block number ${tbn} from tail of log are not expected", ("hbn", _begin_block)("tbn", _end_block-1));
}
catch(const std::bad_alloc&) {
throw;
Expand Down Expand Up @@ -347,11 +348,11 @@ class state_history_log {
ilog("${num_found} blocks found, log pos = ${pos}", ("num_found", num_found)("pos", pos));
}
}
ilog("recovery of ${fn} complete, ${b} blocks found in ${bytes} bytes", ("fn", log.display_path())("b", num_found)("bytes", pos));
log.resize(pos);
}

// only called from constructor
void open_log() {
void check_log_on_init() {
if(log.size() == 0)
return;

Expand All @@ -378,8 +379,7 @@ class state_history_log {
} EOS_RETHROW_EXCEPTIONS(chain::plugin_exception, "${name} is corrupted and cannot be repaired", ("name", log.display_path()));
}

// only called from constructor
void open_index() {
void check_index_on_init() {
const uint64_t expected_index_size = (_end_block - _index_begin_block) * sizeof(uint64_t);
if(index.size() == expected_index_size)
return;
Expand Down Expand Up @@ -413,13 +413,24 @@ class state_history_log {
ilog("${r} blocks remaining, log pos = ${pos}", ("r", chain::block_header::num_from_id(header.block_id) - _begin_block)("pos", logpos));
} while(chain::block_header::num_from_id(header.block_id) != _begin_block);
}

ilog("${name} regeneration complete", ("name", index.display_path()));
}

uint64_t get_pos(uint32_t block_num) {
return index.unpack_from<uint64_t>((block_num - _index_begin_block) * sizeof(uint64_t));
}


/*
* A pruned log will have a gap where data has been erased (via "poking holes"). for example,
* _index_begin_block=1, _begin_block=5, _end_block=9
* index: 1|2|3|4|5|6|7|8
* log: Hxxxxxx|5|6|7|8 (H is the just the header)
* Pruning will collapse the gap resulting in a non-pruned log and index:

This comment has been minimized.

Copy link
@linh2931

linh2931 Jun 11, 2024

Member

Should Pruning be Vacuuming?

This comment has been minimized.

Copy link
@spoonincode

spoonincode Jun 11, 2024

Author Member

yes fair enough I think that's more consistent terminology

This comment has been minimized.

Copy link
@spoonincode

spoonincode Jun 11, 2024

Author Member

tweaked the wording in 477e1bf

* _index_begin_block=5, _begin_block=5, _end_block=9
* index: 5|6|7|8
* log: 5|6|7|8
*/
void vacuum() {
//a completely empty log should have nothing on disk; don't touch anything
if(empty())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class log_catalog {
std::visit(chain::overloaded {
[this](const std::monostate&) {
open_head_log();
}, //nothing needed
},
[this](const state_history::prune_config& prune) {
open_head_log(prune);
},
Expand Down Expand Up @@ -99,7 +99,7 @@ class log_catalog {
}

if(retained_log_files.size() > 1)
for(decltype(retained_log_files)::iterator it = retained_log_files.begin(); it != std::prev(retained_log_files.end()); ++it)
for(catalog_t::iterator it = retained_log_files.begin(); it != std::prev(retained_log_files.end()); ++it)
EOS_ASSERT(it->end_block_num == std::next(it)->begin_block_num, chain::plugin_exception,
"retained log file ${sf}.log has block range ${sb}-${se} but ${ef}.log has range ${eb}-${ee} which results in a hole",
("sf", it->path_and_basename.native())("sb", it->begin_block_num)("se", it->end_block_num-1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace eosio::state_history {

struct prune_config {
uint32_t prune_blocks; //number of blocks to prune to when doing a prune
uint32_t prune_blocks; //when pruning, the number of most recent blocks to remain available in the log
size_t prune_threshold = 4*1024*1024; //(approximately) how many bytes need to be added before a prune is performed
std::optional<size_t> vacuum_on_close; //when set, a vacuum is performed on dtor if log contains less than this many bytes
};
Expand Down
2 changes: 1 addition & 1 deletion tests/ship_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ struct ship_log_fixture {
}
};

//historically can only punch holes on filesystem block boundaries. not true any longer, but let's make sure the entries we add are larger than that anyways
//can only punch holes on filesystem block boundaries. let's make sure the entries we add are larger than that
static size_t larger_than_tmpfile_blocksize() {
fc::temp_cfile tf;
auto& cf = tf.file();
Expand Down

0 comments on commit 4681ad2

Please sign in to comment.