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 2023-03-28 16:52:33 +03:00
commit d082ac36b0
261 changed files with 24449 additions and 1791 deletions

View file

@ -749,6 +749,9 @@ ArchiveManager::FileDescription *ArchiveManager::get_file_desc_by_seqno(AccountI
return get_file_desc_by_seqno(ShardIdFull{masterchainId}, seqno, key_block);
}
for (auto it = f.rbegin(); it != f.rend(); it++) {
if (it->second.deleted) {
continue;
}
bool found = false;
for (int i = 0; i < 60; i++) {
auto shard = shard_prefix(account, i);
@ -773,6 +776,9 @@ ArchiveManager::FileDescription *ArchiveManager::get_file_desc_by_unix_time(Acco
return get_file_desc_by_unix_time(ShardIdFull{masterchainId}, ts, key_block);
}
for (auto it = f.rbegin(); it != f.rend(); it++) {
if (it->second.deleted) {
continue;
}
bool found = false;
for (int i = 0; i < 60; i++) {
auto shard = shard_prefix(account, i);
@ -797,6 +803,9 @@ ArchiveManager::FileDescription *ArchiveManager::get_file_desc_by_lt(AccountIdPr
return get_file_desc_by_lt(ShardIdFull{masterchainId}, lt, key_block);
}
for (auto it = f.rbegin(); it != f.rend(); it++) {
if (it->second.deleted) {
continue;
}
bool found = false;
for (int i = 0; i < 60; i++) {
auto shard = shard_prefix(account, i);
@ -818,11 +827,13 @@ ArchiveManager::FileDescription *ArchiveManager::get_next_file_desc(FileDescript
auto &m = get_file_map(f->id);
auto it = m.find(f->id);
CHECK(it != m.end());
it++;
if (it == m.end()) {
return nullptr;
} else {
return &it->second;
while (true) {
it++;
if (it == m.end()) {
return nullptr;
} else if (!it->second.deleted) {
return &it->second;
}
}
}
@ -895,7 +906,7 @@ void ArchiveManager::start_up() {
td::WalkPath::run(db_root_ + "/archive/states/", [&](td::CSlice fname, td::WalkPath::Type t) -> void {
if (t == td::WalkPath::Type::NotDir) {
LOG(ERROR) << "checking file " << fname;
auto pos = fname.rfind('/');
auto pos = fname.rfind(TD_DIR_SLASH);
if (pos != td::Slice::npos) {
fname.remove_prefix(pos + 1);
}
@ -1159,13 +1170,17 @@ void ArchiveManager::truncate(BlockSeqno masterchain_seqno, ConstBlockHandle han
auto it = key_files_.begin();
while (it != key_files_.end()) {
if (it->first.id <= masterchain_seqno) {
td::actor::send_closure(it->second.file_actor_id(), &ArchiveSlice::truncate, masterchain_seqno, handle,
ig.get_promise());
if (!it->second.deleted) {
td::actor::send_closure(it->second.file_actor_id(), &ArchiveSlice::truncate, masterchain_seqno, handle,
ig.get_promise());
}
it++;
} else {
auto it2 = it;
it++;
td::actor::send_closure(it2->second.file_actor_id(), &ArchiveSlice::destroy, ig.get_promise());
if (!it2->second.deleted) {
td::actor::send_closure(it2->second.file_actor_id(), &ArchiveSlice::destroy, ig.get_promise());
}
it2->second.file.release();
index_
->erase(create_serialize_tl_object<ton_api::db_files_package_key>(it2->second.id.id, it2->second.id.key,
@ -1180,13 +1195,17 @@ void ArchiveManager::truncate(BlockSeqno masterchain_seqno, ConstBlockHandle han
auto it = files_.begin();
while (it != files_.end()) {
if (it->first.id <= masterchain_seqno) {
td::actor::send_closure(it->second.file_actor_id(), &ArchiveSlice::truncate, masterchain_seqno, handle,
ig.get_promise());
if (!it->second.deleted) {
td::actor::send_closure(it->second.file_actor_id(), &ArchiveSlice::truncate, masterchain_seqno, handle,
ig.get_promise());
}
it++;
} else {
auto it2 = it;
it++;
td::actor::send_closure(it2->second.file_actor_id(), &ArchiveSlice::destroy, ig.get_promise());
if (!it2->second.deleted) {
td::actor::send_closure(it2->second.file_actor_id(), &ArchiveSlice::destroy, ig.get_promise());
}
it2->second.file.release();
index_
->erase(create_serialize_tl_object<ton_api::db_files_package_key>(it2->second.id.id, it2->second.id.key,

View file

@ -33,11 +33,11 @@ class CellDbAsyncExecutor : public vm::DynamicBagOfCellsDb::AsyncExecutor {
explicit CellDbAsyncExecutor(td::actor::ActorId<CellDbBase> cell_db) : cell_db_(std::move(cell_db)) {
}
void execute_async(std::function<void()> f) {
void execute_async(std::function<void()> f) override {
class Runner : public td::actor::Actor {
public:
explicit Runner(std::function<void()> f) : f_(std::move(f)) {}
void start_up() {
void start_up() override {
f_();
stop();
}
@ -47,7 +47,7 @@ class CellDbAsyncExecutor : public vm::DynamicBagOfCellsDb::AsyncExecutor {
td::actor::create_actor<Runner>("executeasync", std::move(f)).release();
}
void execute_sync(std::function<void()> f) {
void execute_sync(std::function<void()> f) override {
td::actor::send_closure(cell_db_, &CellDbBase::execute_sync, std::move(f));
}
private:
@ -83,23 +83,45 @@ void CellDbIn::start_up() {
set_block(empty, std::move(e));
cell_db_->commit_write_batch().ensure();
}
last_gc_ = empty;
}
void CellDbIn::load_cell(RootHash hash, td::Promise<td::Ref<vm::DataCell>> promise) {
boc_->load_cell_async(hash.as_slice(), async_executor, std::move(promise));
enqueue([this, hash, promise = std::move(promise)](td::Result<td::Unit> R) mutable {
if (R.is_error()) {
return;
}
promise.set_result(boc_->load_cell(hash.as_slice()));
release_db();
});
}
void CellDbIn::store_cell(BlockIdExt block_id, td::Ref<vm::Cell> cell, td::Promise<td::Ref<vm::DataCell>> promise) {
td::PerfWarningTimer{"storecell", 0.1};
auto key_hash = get_key_hash(block_id);
auto R = get_block(key_hash);
// duplicate
if (R.is_ok()) {
promise.set_result(boc_->load_cell(cell->get_hash().as_slice()));
return;
}
enqueue([this, block_id, cell = std::move(cell), promise = std::move(promise)](td::Result<td::Unit> R0) mutable {
if (R0.is_error()) {
return;
}
promise = promise.wrap([timer = td::PerfWarningTimer{"storecell", 0.1}](td::Ref<vm::DataCell> &&r) { return r; });
auto key_hash = get_key_hash(block_id);
auto R = get_block(key_hash);
// duplicate
if (R.is_ok()) {
promise.set_result(boc_->load_cell(cell->get_hash().as_slice()));
release_db();
return;
}
boc_->inc(cell);
boc_->prepare_commit_async(
async_executor, [=, SelfId = actor_id(this), promise = std::move(promise)](td::Result<td::Unit> R) mutable {
R.ensure();
td::actor::send_closure(SelfId, &CellDbIn::store_cell_cont, block_id, cell, std::move(promise));
});
});
}
void CellDbIn::store_cell_cont(BlockIdExt block_id, td::Ref<vm::Cell> cell,
td::Promise<td::Ref<vm::DataCell>> promise) {
auto key_hash = get_key_hash(block_id);
auto empty = get_empty_key_hash();
auto ER = get_block(empty);
ER.ensure();
@ -120,9 +142,7 @@ void CellDbIn::store_cell(BlockIdExt block_id, td::Ref<vm::Cell> cell, td::Promi
P.prev = key_hash;
}
boc_->inc(cell);
boc_->prepare_commit().ensure();
vm::CellStorer stor{*cell_db_.get()};
vm::CellStorer stor{*cell_db_};
cell_db_->begin_write_batch().ensure();
boc_->commit(stor).ensure();
set_block(empty, std::move(E));
@ -134,24 +154,29 @@ void CellDbIn::store_cell(BlockIdExt block_id, td::Ref<vm::Cell> cell, td::Promi
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
promise.set_result(boc_->load_cell(cell->get_hash().as_slice()));
release_db();
}
void CellDbIn::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) {
promise.set_result(boc_->get_cell_db_reader());
enqueue([this, promise = std::move(promise)](td::Result<td::Unit> R) mutable {
if (R.is_error()) {
return;
}
promise.set_result(boc_->get_cell_db_reader());
release_db();
});
}
void CellDbIn::alarm() {
auto R = get_block(last_gc_);
R.ensure();
auto N = R.move_as_ok();
auto E = get_block(get_empty_key_hash()).move_as_ok();
auto N = get_block(E.next).move_as_ok();
if (N.is_empty()) {
last_gc_ = N.next;
alarm_timestamp() = td::Timestamp::in(0.1);
return;
}
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<bool> R) {
auto block_id = N.block_id;
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this), block_id](td::Result<bool> R) {
if (R.is_error()) {
td::actor::send_closure(SelfId, &CellDbIn::skip_gc);
} else {
@ -159,24 +184,19 @@ void CellDbIn::alarm() {
if (!value) {
td::actor::send_closure(SelfId, &CellDbIn::skip_gc);
} else {
td::actor::send_closure(SelfId, &CellDbIn::gc);
td::actor::send_closure(SelfId, &CellDbIn::gc, block_id);
}
}
});
td::actor::send_closure(root_db_, &RootDb::allow_state_gc, N.block_id, std::move(P));
td::actor::send_closure(root_db_, &RootDb::allow_state_gc, block_id, std::move(P));
}
void CellDbIn::gc() {
auto R = get_block(last_gc_);
R.ensure();
auto N = R.move_as_ok();
void CellDbIn::gc(BlockIdExt block_id) {
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<BlockHandle> R) {
R.ensure();
td::actor::send_closure(SelfId, &CellDbIn::gc_cont, R.move_as_ok());
});
td::actor::send_closure(root_db_, &RootDb::get_block_handle_external, N.block_id, false, std::move(P));
td::actor::send_closure(root_db_, &RootDb::get_block_handle_external, block_id, false, std::move(P));
}
void CellDbIn::gc_cont(BlockHandle handle) {
@ -194,12 +214,30 @@ void CellDbIn::gc_cont(BlockHandle handle) {
}
void CellDbIn::gc_cont2(BlockHandle handle) {
td::PerfWarningTimer{"gccell", 0.1};
enqueue([this, handle = std::move(handle)](td::Result<td::Unit> R) mutable {
if (R.is_error()) {
return;
}
td::Promise<td::Unit> promise = [timer = td::PerfWarningTimer{"gccell", 0.1}](td::Result<td::Unit>) {};
auto FR = get_block(get_key_hash(handle->id()));
FR.ensure();
auto F = FR.move_as_ok();
auto cell = boc_->load_cell(F.root_hash.as_slice()).move_as_ok();
auto FR = get_block(last_gc_);
boc_->dec(cell);
boc_->prepare_commit_async(async_executor, [SelfId = actor_id(this), promise = std::move(promise),
block_id = handle->id()](td::Result<td::Unit> R) mutable {
R.ensure();
td::actor::send_closure(SelfId, &CellDbIn::gc_cont3, block_id, std::move(promise));
});
});
}
void CellDbIn::gc_cont3(BlockIdExt block_id, td::Promise<td::Unit> promise) {
auto key_hash = get_key_hash(block_id);
auto FR = get_block(key_hash);
FR.ensure();
auto F = FR.move_as_ok();
auto PR = get_block(F.prev);
PR.ensure();
auto P = PR.move_as_ok();
@ -214,14 +252,10 @@ void CellDbIn::gc_cont2(BlockHandle handle) {
N.next = N.prev;
}
auto cell = boc_->load_cell(F.root_hash.as_slice()).move_as_ok();
boc_->dec(cell);
boc_->prepare_commit().ensure();
vm::CellStorer stor{*cell_db_.get()};
vm::CellStorer stor{*cell_db_};
cell_db_->begin_write_batch().ensure();
boc_->commit(stor).ensure();
cell_db_->erase(get_key(last_gc_)).ensure();
cell_db_->erase(get_key(key_hash)).ensure();
set_block(F.prev, std::move(P));
set_block(F.next, std::move(N));
cell_db_->commit_write_batch().ensure();
@ -230,16 +264,33 @@ void CellDbIn::gc_cont2(BlockHandle handle) {
boc_->set_loader(std::make_unique<vm::CellLoader>(cell_db_->snapshot())).ensure();
td::actor::send_closure(parent_, &CellDb::update_snapshot, cell_db_->snapshot());
DCHECK(get_block(last_gc_).is_error());
last_gc_ = F.next;
DCHECK(get_block(key_hash).is_error());
promise.set_result(td::Unit());
release_db();
}
void CellDbIn::enqueue(td::Promise<td::Unit> promise) {
db_queue_.push(std::move(promise));
process_event();
}
void CellDbIn::release_db() {
db_busy_ = false;
process_event();
}
void CellDbIn::process_event() {
if (db_busy_ || db_queue_.empty()) {
return;
}
db_busy_ = true;
auto promise = std::move(db_queue_.front());
db_queue_.pop();
promise.set_result(td::Unit());
}
void CellDbIn::skip_gc() {
auto FR = get_block(last_gc_);
FR.ensure();
auto F = FR.move_as_ok();
last_gc_ = F.next;
alarm_timestamp() = td::Timestamp::in(0.01);
alarm_timestamp() = td::Timestamp::in(1.0);
}
std::string CellDbIn::get_key(KeyHash key_hash) {
@ -296,7 +347,7 @@ void CellDb::load_cell(RootHash hash, td::Promise<td::Ref<vm::DataCell>> promise
} else {
promise.set_result(R.move_as_ok());
}
});
});
boc_->load_cell_async(hash.as_slice(), async_executor, std::move(P));
}
}

View file

@ -25,6 +25,7 @@
#include "ton/ton-types.h"
#include "interfaces/block-handle.h"
#include "auto/tl/ton_api.h"
#include <queue>
namespace ton {
@ -84,11 +85,14 @@ class CellDbIn : public CellDbBase {
static BlockIdExt get_empty_key();
KeyHash get_empty_key_hash();
void gc();
void gc(BlockIdExt block_id);
void gc_cont(BlockHandle handle);
void gc_cont2(BlockHandle handle);
void gc_cont3(BlockIdExt block_id, td::Promise<td::Unit> promise);
void skip_gc();
void store_cell_cont(BlockIdExt block_id, td::Ref<vm::Cell> cell, td::Promise<td::Ref<vm::DataCell>> promise);
td::actor::ActorId<RootDb> root_db_;
td::actor::ActorId<CellDb> parent_;
@ -97,7 +101,12 @@ class CellDbIn : public CellDbBase {
std::unique_ptr<vm::DynamicBagOfCellsDb> boc_;
std::shared_ptr<vm::KeyValue> cell_db_;
KeyHash last_gc_;
std::queue<td::Promise<td::Unit>> db_queue_;
bool db_busy_ = false;
void enqueue(td::Promise<td::Unit> promise);
void release_db();
void process_event();
};
class CellDb : public CellDbBase {