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

Merge master #824

Merged
merged 3 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
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
43 changes: 35 additions & 8 deletions crypto/vm/db/CellStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,25 @@ namespace vm {
namespace {
class RefcntCellStorer {
public:
RefcntCellStorer(td::int32 refcnt, const DataCell &cell) : refcnt_(refcnt), cell_(cell) {
RefcntCellStorer(td::int32 refcnt, const td::Ref<DataCell> &cell, bool as_boc)
: refcnt_(refcnt), cell_(cell), as_boc_(as_boc) {
}

template <class StorerT>
void store(StorerT &storer) const {
using td::store;
if (as_boc_) {
td::int32 tag = -1;
store(tag, storer);
store(refcnt_, storer);
td::BufferSlice data = vm::std_boc_serialize(cell_).move_as_ok();
storer.store_slice(data);
return;
}
store(refcnt_, storer);
store(cell_, storer);
for (unsigned i = 0; i < cell_.size_refs(); i++) {
auto cell = cell_.get_ref(i);
store(*cell_, storer);
for (unsigned i = 0; i < cell_->size_refs(); i++) {
auto cell = cell_->get_ref(i);
auto level_mask = cell->get_level_mask();
auto level = level_mask.get_level();
td::uint8 x = static_cast<td::uint8>(level_mask.get_mask());
Expand All @@ -60,7 +69,8 @@ class RefcntCellStorer {

private:
td::int32 refcnt_;
const DataCell &cell_;
td::Ref<DataCell> cell_;
bool as_boc_;
};

class RefcntCellParser {
Expand All @@ -69,18 +79,30 @@ class RefcntCellParser {
}
td::int32 refcnt;
Ref<DataCell> cell;
bool stored_boc_;

template <class ParserT>
void parse(ParserT &parser, ExtCellCreator &ext_cell_creator) {
using ::td::parse;
parse(refcnt, parser);
stored_boc_ = false;
if (refcnt == -1) {
stored_boc_ = true;
parse(refcnt, parser);
}
if (!need_data_) {
return;
}
auto status = [&]() -> td::Status {
TRY_STATUS(parser.get_status());
auto size = parser.get_left_len();
td::Slice data = parser.template fetch_string_raw<td::Slice>(size);
if (stored_boc_) {
TRY_RESULT(boc, vm::std_boc_deserialize(data));
TRY_RESULT(loaded_cell, boc->load_cell());
cell = std::move(loaded_cell.data_cell);
return td::Status::OK();
}
CellSerializationInfo info;
auto cell_data = data;
TRY_STATUS(info.init(cell_data, 0 /*ref_byte_size*/));
Expand Down Expand Up @@ -122,7 +144,8 @@ class RefcntCellParser {
};
} // namespace

CellLoader::CellLoader(std::shared_ptr<KeyValueReader> reader) : reader_(std::move(reader)) {
CellLoader::CellLoader(std::shared_ptr<KeyValueReader> reader, std::function<void(const LoadResult &)> on_load_callback)
: reader_(std::move(reader)), on_load_callback_(std::move(on_load_callback)) {
CHECK(reader_);
}

Expand All @@ -145,7 +168,11 @@ td::Result<CellLoader::LoadResult> CellLoader::load(td::Slice hash, bool need_da

res.refcnt_ = refcnt_cell.refcnt;
res.cell_ = std::move(refcnt_cell.cell);
res.stored_boc_ = refcnt_cell.stored_boc_;
//CHECK(res.cell_->get_hash() == hash);
if (on_load_callback_) {
on_load_callback_(res);
}

return res;
}
Expand All @@ -157,7 +184,7 @@ td::Status CellStorer::erase(td::Slice hash) {
return kv_.erase(hash);
}

td::Status CellStorer::set(td::int32 refcnt, const DataCell &cell) {
return kv_.set(cell.get_hash().as_slice(), td::serialize(RefcntCellStorer(refcnt, cell)));
td::Status CellStorer::set(td::int32 refcnt, const td::Ref<DataCell> &cell, bool as_boc) {
return kv_.set(cell->get_hash().as_slice(), td::serialize(RefcntCellStorer(refcnt, cell, as_boc)));
}
} // namespace vm
6 changes: 4 additions & 2 deletions crypto/vm/db/CellStorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,19 +45,21 @@ class CellLoader {

Ref<DataCell> cell_;
td::int32 refcnt_{0};
bool stored_boc_{false};
};
CellLoader(std::shared_ptr<KeyValueReader> reader);
CellLoader(std::shared_ptr<KeyValueReader> reader, std::function<void(const LoadResult &)> on_load_callback = {});
td::Result<LoadResult> load(td::Slice hash, bool need_data, ExtCellCreator &ext_cell_creator);

private:
std::shared_ptr<KeyValueReader> reader_;
std::function<void(const LoadResult &)> on_load_callback_;
};

class CellStorer {
public:
CellStorer(KeyValue &kv);
td::Status erase(td::Slice hash);
td::Status set(td::int32 refcnt, const DataCell &cell);
td::Status set(td::int32 refcnt, const td::Ref<DataCell> &cell, bool as_boc);

private:
KeyValue &kv_;
Expand Down
12 changes: 11 additions & 1 deletion crypto/vm/db/DynamicBagOfCellsDb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,13 +210,22 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
return td::Status::OK();
}

void set_celldb_compress_depth(td::uint32 value) override {
celldb_compress_depth_ = value;
}

vm::ExtCellCreator& as_ext_cell_creator() override {
return *this;
}

private:
std::unique_ptr<CellLoader> loader_;
std::vector<Ref<Cell>> to_inc_;
std::vector<Ref<Cell>> to_dec_;
CellHashTable<CellInfo> hash_table_;
std::vector<CellInfo *> visited_;
Stats stats_diff_;
td::uint32 celldb_compress_depth_{0};

static td::NamedThreadSafeCounter::CounterRef get_thread_safe_counter() {
static auto res = td::NamedThreadSafeCounter::get_default().get_counter("DynamicBagOfCellsDb");
Expand Down Expand Up @@ -443,7 +452,8 @@ class DynamicBagOfCellsDbImpl : public DynamicBagOfCellsDb, private ExtCellCreat
guard.dismiss();
} else {
auto loaded_cell = info.cell->load_cell().move_as_ok();
storer.set(info.db_refcnt, *loaded_cell.data_cell);
storer.set(info.db_refcnt, loaded_cell.data_cell,
loaded_cell.data_cell->get_depth() == celldb_compress_depth_ && celldb_compress_depth_ != 0);
info.in_db = true;
}
}
Expand Down
3 changes: 3 additions & 0 deletions crypto/vm/db/DynamicBagOfCellsDb.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class DynamicBagOfCellsDb {
// restart with new loader will also reset stats_diff
virtual td::Status set_loader(std::unique_ptr<CellLoader> loader) = 0;

virtual void set_celldb_compress_depth(td::uint32 value) = 0;
virtual vm::ExtCellCreator& as_ext_cell_creator() = 0;

static std::unique_ptr<DynamicBagOfCellsDb> create();

class AsyncExecutor {
Expand Down
20 changes: 12 additions & 8 deletions crypto/vm/dict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "vm/cellslice.h"
#include "vm/stack.hpp"
#include "common/bitstring.h"
#include "td/utils/Random.h"

#include "td/utils/bits.h"

Expand Down Expand Up @@ -2007,7 +2008,7 @@ bool DictionaryFixed::combine_with(DictionaryFixed& dict2) {

bool DictionaryFixed::dict_check_for_each(Ref<Cell> dict, td::BitPtr key_buffer, int n, int total_key_len,
const DictionaryFixed::foreach_func_t& foreach_func,
bool invert_first) const {
bool invert_first, bool shuffle) const {
if (dict.is_null()) {
return true;
}
Expand All @@ -2026,26 +2027,29 @@ bool DictionaryFixed::dict_check_for_each(Ref<Cell> dict, td::BitPtr key_buffer,
key_buffer += l + 1;
if (l) {
invert_first = false;
} else if (invert_first) {
}
bool invert = shuffle ? td::Random::fast(0, 1) == 1: invert_first;
if (invert) {
std::swap(c1, c2);
}
key_buffer[-1] = invert_first;
key_buffer[-1] = invert;
// recursive check_foreach applied to both children
if (!dict_check_for_each(std::move(c1), key_buffer, n - l - 1, total_key_len, foreach_func)) {
if (!dict_check_for_each(std::move(c1), key_buffer, n - l - 1, total_key_len, foreach_func, false, shuffle)) {
return false;
}
key_buffer[-1] = !invert_first;
return dict_check_for_each(std::move(c2), key_buffer, n - l - 1, total_key_len, foreach_func);
key_buffer[-1] = !invert;
return dict_check_for_each(std::move(c2), key_buffer, n - l - 1, total_key_len, foreach_func, false, shuffle);
}

bool DictionaryFixed::check_for_each(const foreach_func_t& foreach_func, bool invert_first) {
bool DictionaryFixed::check_for_each(const foreach_func_t& foreach_func, bool invert_first, bool shuffle) {
force_validate();
if (is_empty()) {
return true;
}
int key_len = get_key_bits();
unsigned char key_buffer[max_key_bytes];
return dict_check_for_each(get_root_cell(), td::BitPtr{key_buffer}, key_len, key_len, foreach_func, invert_first);
return dict_check_for_each(get_root_cell(), td::BitPtr{key_buffer}, key_len, key_len, foreach_func, invert_first,
shuffle);
}

static inline bool set_bit(td::BitPtr ptr, bool value = true) {
Expand Down
4 changes: 2 additions & 2 deletions crypto/vm/dict.h
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ class DictionaryFixed : public DictionaryBase {
int get_common_prefix(td::BitPtr buffer, unsigned buffer_len);
bool cut_prefix_subdict(td::ConstBitPtr prefix, int prefix_len, bool remove_prefix = false);
Ref<vm::Cell> extract_prefix_subdict_root(td::ConstBitPtr prefix, int prefix_len, bool remove_prefix = false);
bool check_for_each(const foreach_func_t& foreach_func, bool invert_first = false);
bool check_for_each(const foreach_func_t& foreach_func, bool invert_first = false, bool shuffle = false);
int filter(filter_func_t check);
bool combine_with(DictionaryFixed& dict2, const combine_func_t& combine_func, int mode = 0);
bool combine_with(DictionaryFixed& dict2, const simple_combine_func_t& simple_combine_func, int mode = 0);
Expand Down Expand Up @@ -292,7 +292,7 @@ class DictionaryFixed : public DictionaryBase {
std::pair<Ref<Cell>, bool> extract_prefix_subdict_internal(Ref<Cell> dict, td::ConstBitPtr prefix, int prefix_len,
bool remove_prefix = false) const;
bool dict_check_for_each(Ref<Cell> dict, td::BitPtr key_buffer, int n, int total_key_len,
const foreach_func_t& foreach_func, bool invert_first = false) const;
const foreach_func_t& foreach_func, bool invert_first = false, bool shuffle = false) const;
std::pair<Ref<Cell>, int> dict_filter(Ref<Cell> dict, td::BitPtr key, int n, const filter_func_t& check_leaf,
int& skip_rest) const;
Ref<Cell> dict_combine_with(Ref<Cell> dict1, Ref<Cell> dict2, td::BitPtr key_buffer, int n, int total_key_len,
Expand Down
6 changes: 6 additions & 0 deletions tdutils/td/utils/Time.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ class Timestamp {
}

friend bool operator==(Timestamp a, Timestamp b);
friend Timestamp &operator+=(Timestamp &a, double b);

private:
double at_{0};
Expand All @@ -122,6 +123,11 @@ inline bool operator<(const Timestamp &a, const Timestamp &b) {
return a.at() < b.at();
}

inline Timestamp &operator+=(Timestamp &a, double b) {
a.at_ += b;
return a;
}

template <class StorerT>
void store(const Timestamp &timestamp, StorerT &storer) {
storer.store_binary(timestamp.at() - Time::now() + Clocks::system());
Expand Down
6 changes: 6 additions & 0 deletions validator-engine/validator-engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1363,6 +1363,7 @@ td::Status ValidatorEngine::load_global_config() {
if (!session_logs_file_.empty()) {
validator_options_.write().set_session_logs_file(session_logs_file_);
}
validator_options_.write().set_celldb_compress_depth(celldb_compress_depth_);

std::vector<ton::BlockIdExt> h;
for (auto &x : conf.validator_->hardforks_) {
Expand Down Expand Up @@ -3761,6 +3762,11 @@ int main(int argc, char *argv[]) {
acts.push_back([&x, at]() { td::actor::send_closure(x, &ValidatorEngine::schedule_shutdown, (double)at); });
return td::Status::OK();
});
p.add_checked_option('\0', "celldb-compress-depth", "(default: 0)", [&](td::Slice arg) {
TRY_RESULT(value, td::to_integer_safe<td::uint32>(arg));
acts.push_back([&x, value]() { td::actor::send_closure(x, &ValidatorEngine::set_celldb_compress_depth, value); });
return td::Status::OK();
});
auto S = p.run(argc, argv);
if (S.is_error()) {
LOG(ERROR) << "failed to parse options: " << S.move_as_error();
Expand Down
4 changes: 4 additions & 0 deletions validator-engine/validator-engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ class ValidatorEngine : public td::actor::Actor {
double sync_ttl_ = 0;
double archive_ttl_ = 0;
double key_proof_ttl_ = 0;
td::uint32 celldb_compress_depth_ = 0;
bool read_config_ = false;
bool started_keyring_ = false;
bool started_ = false;
Expand Down Expand Up @@ -257,6 +258,9 @@ class ValidatorEngine : public td::actor::Actor {
keys_[key.compute_short_id()] = key;
}
void schedule_shutdown(double at);
void set_celldb_compress_depth(td::uint32 value) {
celldb_compress_depth_ = value;
}
void start_up() override;
ValidatorEngine() {
}
Expand Down
Loading