1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-03-09 15:40:10 +00:00

Merge branch 'testnet' into block-generation

This commit is contained in:
SpyCheese 2024-02-01 19:29:25 +03:00
commit f4fd3ff3be
246 changed files with 7895 additions and 5430 deletions

View file

@ -23,6 +23,7 @@
#include "ton/ton-tl.hpp"
#include "ton/ton-io.hpp"
#include "common/delay.h"
namespace ton {
@ -62,16 +63,31 @@ void CellDbBase::execute_sync(std::function<void()> f) {
f();
}
CellDbIn::CellDbIn(td::actor::ActorId<RootDb> root_db, td::actor::ActorId<CellDb> parent, std::string path)
: root_db_(root_db), parent_(parent), path_(std::move(path)) {
CellDbIn::CellDbIn(td::actor::ActorId<RootDb> root_db, td::actor::ActorId<CellDb> parent, std::string path,
td::Ref<ValidatorManagerOptions> opts)
: root_db_(root_db), parent_(parent), path_(std::move(path)), opts_(opts) {
}
void CellDbIn::start_up() {
on_load_callback_ = [actor = std::make_shared<td::actor::ActorOwn<MigrationProxy>>(
td::actor::create_actor<MigrationProxy>("celldbmigration", actor_id(this))),
compress_depth = opts_->get_celldb_compress_depth()](const vm::CellLoader::LoadResult& res) {
if (res.cell_.is_null()) {
return;
}
bool expected_stored_boc = res.cell_->get_depth() == compress_depth && compress_depth != 0;
if (expected_stored_boc != res.stored_boc_) {
td::actor::send_closure(*actor, &CellDbIn::MigrationProxy::migrate_cell,
td::Bits256{res.cell_->get_hash().bits()});
}
};
CellDbBase::start_up();
cell_db_ = std::make_shared<td::RocksDb>(td::RocksDb::open(path_).move_as_ok());
boc_ = vm::DynamicBagOfCellsDb::create();
boc_->set_loader(std::make_unique<vm::CellLoader>(cell_db_->snapshot())).ensure();
boc_->set_celldb_compress_depth(opts_->get_celldb_compress_depth());
boc_->set_loader(std::make_unique<vm::CellLoader>(cell_db_->snapshot(), on_load_callback_)).ensure();
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
alarm_timestamp() = td::Timestamp::in(10.0);
@ -129,7 +145,7 @@ void CellDbIn::store_cell(BlockIdExt block_id, td::Ref<vm::Cell> cell, td::Promi
set_block(key_hash, std::move(D));
cell_db_->commit_write_batch().ensure();
boc_->set_loader(std::make_unique<vm::CellLoader>(cell_db_->snapshot())).ensure();
boc_->set_loader(std::make_unique<vm::CellLoader>(cell_db_->snapshot(), on_load_callback_)).ensure();
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
promise.set_result(boc_->load_cell(cell->get_hash().as_slice()));
@ -140,6 +156,16 @@ void CellDbIn::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>>
}
void CellDbIn::alarm() {
if (migrate_after_ && migrate_after_.is_in_past()) {
migrate_cells();
}
if (migration_stats_ && migration_stats_->end_at_.is_in_past()) {
LOG(INFO) << "CellDb migration, " << migration_stats_->start_.elapsed()
<< "s stats: batches=" << migration_stats_->batches_ << " migrated=" << migration_stats_->migrated_cells_
<< " checked=" << migration_stats_->checked_cells_ << " time=" << migration_stats_->total_time_
<< " queue_size=" << cells_to_migrate_.size();
migration_stats_ = {};
}
auto E = get_block(get_empty_key_hash()).move_as_ok();
auto N = get_block(E.next).move_as_ok();
if (N.is_empty()) {
@ -220,7 +246,7 @@ void CellDbIn::gc_cont2(BlockHandle handle) {
cell_db_->commit_write_batch().ensure();
alarm_timestamp() = td::Timestamp::now();
boc_->set_loader(std::make_unique<vm::CellLoader>(cell_db_->snapshot())).ensure();
boc_->set_loader(std::make_unique<vm::CellLoader>(cell_db_->snapshot(), on_load_callback_)).ensure();
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
DCHECK(get_block(key_hash).is_error());
@ -273,6 +299,66 @@ void CellDbIn::set_block(KeyHash key_hash, DbEntry e) {
cell_db_->set(td::as_slice(key), e.release()).ensure();
}
void CellDbIn::migrate_cell(td::Bits256 hash) {
cells_to_migrate_.insert(hash);
if (!migration_active_) {
migration_active_ = true;
migrate_after_ = td::Timestamp::in(10.0);
}
}
void CellDbIn::migrate_cells() {
migrate_after_ = td::Timestamp::never();
if (cells_to_migrate_.empty()) {
migration_active_ = false;
return;
}
td::Timer timer;
if (!migration_stats_) {
migration_stats_ = std::make_unique<MigrationStats>();
}
vm::CellStorer stor{*cell_db_};
auto loader = std::make_unique<vm::CellLoader>(cell_db_->snapshot());
boc_->set_loader(std::make_unique<vm::CellLoader>(*loader)).ensure();
cell_db_->begin_write_batch().ensure();
td::uint32 checked = 0, migrated = 0;
for (auto it = cells_to_migrate_.begin(); it != cells_to_migrate_.end() && checked < 128; ) {
++checked;
td::Bits256 hash = *it;
it = cells_to_migrate_.erase(it);
auto R = loader->load(hash.as_slice(), true, boc_->as_ext_cell_creator());
if (R.is_error()) {
continue;
}
if (R.ok().status == vm::CellLoader::LoadResult::NotFound) {
continue;
}
bool expected_stored_boc =
R.ok().cell_->get_depth() == opts_->get_celldb_compress_depth() && opts_->get_celldb_compress_depth() != 0;
if (expected_stored_boc != R.ok().stored_boc_) {
++migrated;
stor.set(R.ok().refcnt(), R.ok().cell_, expected_stored_boc).ensure();
}
}
cell_db_->commit_write_batch().ensure();
boc_->set_loader(std::make_unique<vm::CellLoader>(cell_db_->snapshot(), on_load_callback_)).ensure();
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
double time = timer.elapsed();
LOG(DEBUG) << "CellDb migration: migrated=" << migrated << " checked=" << checked << " time=" << time;
++migration_stats_->batches_;
migration_stats_->migrated_cells_ += migrated;
migration_stats_->checked_cells_ += checked;
migration_stats_->total_time_ += time;
if (cells_to_migrate_.empty()) {
migration_active_ = false;
} else {
delay_action([SelfId = actor_id(this)] { td::actor::send_closure(SelfId, &CellDbIn::migrate_cells); },
td::Timestamp::in(time * 2));
}
}
void CellDb::load_cell(RootHash hash, td::Promise<td::Ref<vm::DataCell>> promise) {
if (!started_) {
td::actor::send_closure(cell_db_, &CellDbIn::load_cell, hash, std::move(promise));
@ -300,7 +386,20 @@ void CellDb::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> p
void CellDb::start_up() {
CellDbBase::start_up();
boc_ = vm::DynamicBagOfCellsDb::create();
cell_db_ = td::actor::create_actor<CellDbIn>("celldbin", root_db_, actor_id(this), path_);
boc_->set_celldb_compress_depth(opts_->get_celldb_compress_depth());
cell_db_ = td::actor::create_actor<CellDbIn>("celldbin", root_db_, actor_id(this), path_, opts_);
on_load_callback_ = [actor = std::make_shared<td::actor::ActorOwn<CellDbIn::MigrationProxy>>(
td::actor::create_actor<CellDbIn::MigrationProxy>("celldbmigration", cell_db_.get())),
compress_depth = opts_->get_celldb_compress_depth()](const vm::CellLoader::LoadResult& res) {
if (res.cell_.is_null()) {
return;
}
bool expected_stored_boc = res.cell_->get_depth() == compress_depth && compress_depth != 0;
if (expected_stored_boc != res.stored_boc_) {
td::actor::send_closure(*actor, &CellDbIn::MigrationProxy::migrate_cell,
td::Bits256{res.cell_->get_hash().bits()});
}
};
}
CellDbIn::DbEntry::DbEntry(tl_object_ptr<ton_api::db_celldb_value> entry)

View file

@ -25,6 +25,7 @@
#include "ton/ton-types.h"
#include "interfaces/block-handle.h"
#include "auto/tl/ton_api.h"
#include "validator.h"
namespace ton {
@ -53,7 +54,10 @@ class CellDbIn : public CellDbBase {
void store_cell(BlockIdExt block_id, td::Ref<vm::Cell> cell, td::Promise<td::Ref<vm::DataCell>> promise);
void get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise);
CellDbIn(td::actor::ActorId<RootDb> root_db, td::actor::ActorId<CellDb> parent, std::string path);
void migrate_cell(td::Bits256 hash);
CellDbIn(td::actor::ActorId<RootDb> root_db, td::actor::ActorId<CellDb> parent, std::string path,
td::Ref<ValidatorManagerOptions> opts);
void start_up() override;
void alarm() override;
@ -89,13 +93,44 @@ class CellDbIn : public CellDbBase {
void gc_cont2(BlockHandle handle);
void skip_gc();
void migrate_cells();
td::actor::ActorId<RootDb> root_db_;
td::actor::ActorId<CellDb> parent_;
std::string path_;
td::Ref<ValidatorManagerOptions> opts_;
std::unique_ptr<vm::DynamicBagOfCellsDb> boc_;
std::shared_ptr<vm::KeyValue> cell_db_;
std::function<void(const vm::CellLoader::LoadResult&)> on_load_callback_;
std::set<td::Bits256> cells_to_migrate_;
td::Timestamp migrate_after_ = td::Timestamp::never();
bool migration_active_ = false;
struct MigrationStats {
td::Timer start_;
td::Timestamp end_at_ = td::Timestamp::in(60.0);
size_t batches_ = 0;
size_t migrated_cells_ = 0;
size_t checked_cells_ = 0;
double total_time_ = 0.0;
};
std::unique_ptr<MigrationStats> migration_stats_;
public:
class MigrationProxy : public td::actor::Actor {
public:
explicit MigrationProxy(td::actor::ActorId<CellDbIn> cell_db) : cell_db_(cell_db) {
}
void migrate_cell(td::Bits256 hash) {
td::actor::send_closure(cell_db_, &CellDbIn::migrate_cell, hash);
}
private:
td::actor::ActorId<CellDbIn> cell_db_;
};
};
class CellDb : public CellDbBase {
@ -104,11 +139,12 @@ class CellDb : public CellDbBase {
void store_cell(BlockIdExt block_id, td::Ref<vm::Cell> cell, td::Promise<td::Ref<vm::DataCell>> promise);
void update_snapshot(std::unique_ptr<td::KeyValueReader> snapshot) {
started_ = true;
boc_->set_loader(std::make_unique<vm::CellLoader>(std::move(snapshot))).ensure();
boc_->set_loader(std::make_unique<vm::CellLoader>(std::move(snapshot), on_load_callback_)).ensure();
}
void get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise);
CellDb(td::actor::ActorId<RootDb> root_db, std::string path) : root_db_(root_db), path_(path) {
CellDb(td::actor::ActorId<RootDb> root_db, std::string path, td::Ref<ValidatorManagerOptions> opts)
: root_db_(root_db), path_(path), opts_(opts) {
}
void start_up() override;
@ -116,11 +152,14 @@ class CellDb : public CellDbBase {
private:
td::actor::ActorId<RootDb> root_db_;
std::string path_;
td::Ref<ValidatorManagerOptions> opts_;
td::actor::ActorOwn<CellDbIn> cell_db_;
std::unique_ptr<vm::DynamicBagOfCellsDb> boc_;
bool started_ = false;
std::function<void(const vm::CellLoader::LoadResult&)> on_load_callback_;
};
} // namespace validator

View file

@ -397,7 +397,7 @@ void RootDb::get_hardforks(td::Promise<std::vector<BlockIdExt>> promise) {
}
void RootDb::start_up() {
cell_db_ = td::actor::create_actor<CellDb>("celldb", actor_id(this), root_path_ + "/celldb/");
cell_db_ = td::actor::create_actor<CellDb>("celldb", actor_id(this), root_path_ + "/celldb/", opts_);
state_db_ = td::actor::create_actor<StateDb>("statedb", actor_id(this), root_path_ + "/state/");
static_files_db_ = td::actor::create_actor<StaticFilesDb>("staticfilesdb", actor_id(this), root_path_ + "/static/");
archive_db_ = td::actor::create_actor<ArchiveManager>("archive", actor_id(this), root_path_);

View file

@ -26,6 +26,7 @@
#include "statedb.hpp"
#include "staticfilesdb.hpp"
#include "archive-manager.hpp"
#include "validator.h"
namespace ton {
@ -34,8 +35,9 @@ namespace validator {
class RootDb : public Db {
public:
enum class Flags : td::uint32 { f_started = 1, f_ready = 2, f_switched = 4, f_archived = 8 };
RootDb(td::actor::ActorId<ValidatorManager> validator_manager, std::string root_path)
: validator_manager_(validator_manager), root_path_(std::move(root_path)) {
RootDb(td::actor::ActorId<ValidatorManager> validator_manager, std::string root_path,
td::Ref<ValidatorManagerOptions> opts)
: validator_manager_(validator_manager), root_path_(std::move(root_path)), opts_(opts) {
}
void start_up() override;
@ -141,6 +143,7 @@ class RootDb : public Db {
td::actor::ActorId<ValidatorManager> validator_manager_;
std::string root_path_;
td::Ref<ValidatorManagerOptions> opts_;
td::actor::ActorOwn<CellDb> cell_db_;
td::actor::ActorOwn<StateDb> state_db_;