Skip to content

Commit 39d5519

Browse files
committed
Save intermediate split state parts in DB
This way, we don't need to keep full shard state at any point during deserialization.
1 parent d3cec64 commit 39d5519

File tree

11 files changed

+57
-5
lines changed

11 files changed

+57
-5
lines changed

validator/db/rootdb.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,11 @@ void RootDb::get_block_state(ConstBlockHandle handle, td::Promise<td::Ref<ShardS
281281
}
282282
}
283283

284+
void RootDb::store_block_state_part(BlockId effective_block, td::Ref<vm::Cell> cell,
285+
td::Promise<td::Ref<vm::DataCell>> promise) {
286+
td::actor::send_closure(cell_db_, &CellDb::store_cell, BlockIdExt{effective_block}, cell, std::move(promise));
287+
}
288+
284289
void RootDb::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) {
285290
td::actor::send_closure(cell_db_, &CellDb::get_cell_db_reader, std::move(promise));
286291
}

validator/db/rootdb.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ class RootDb : public Db {
6363
void store_block_state(BlockHandle handle, td::Ref<ShardState> state,
6464
td::Promise<td::Ref<ShardState>> promise) override;
6565
void get_block_state(ConstBlockHandle handle, td::Promise<td::Ref<ShardState>> promise) override;
66+
void store_block_state_part(BlockId effective_block, td::Ref<vm::Cell> cell,
67+
td::Promise<td::Ref<vm::DataCell>> promise) override;
6668
void get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) override;
6769

6870
void store_block_handle(BlockHandle handle, td::Promise<td::Unit> promise) override;

validator/downloaders/download-state.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ void DownloadShardState::downloaded_split_state_header(td::BufferSlice data) {
337337

338338
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
339339
R.ensure();
340-
td::actor::send_closure(SelfId, &DownloadShardState::written_split_state_file);
340+
td::actor::send_closure(SelfId, &DownloadShardState::download_next_part_or_finish);
341341
});
342342
td::actor::send_closure(manager_, &ValidatorManager::store_persistent_state_file, block_id_, masterchain_block_id_,
343343
SplitPersistentStateType{}, std::move(data), std::move(P));
@@ -347,13 +347,13 @@ namespace {
347347

348348
void retry_part_download(td::actor::ActorId<DownloadShardState> SelfId, td::Status error) {
349349
LOG(WARNING) << "failed to download state part : " << error;
350-
delay_action([=]() { td::actor::send_closure(SelfId, &DownloadShardState::written_split_state_file); },
350+
delay_action([=]() { td::actor::send_closure(SelfId, &DownloadShardState::download_next_part_or_finish); },
351351
td::Timestamp::in(1.0));
352352
}
353353

354354
} // namespace
355355

356-
void DownloadShardState::written_split_state_file() {
356+
void DownloadShardState::download_next_part_or_finish() {
357357
if (stored_parts_.size() == parts_.size()) {
358358
auto state_root = deserializer_->merge(stored_parts_);
359359
auto maybe_state = create_shard_state(block_id_, state_root);
@@ -411,7 +411,7 @@ void DownloadShardState::downloaded_state_part(td::BufferSlice data) {
411411

412412
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Unit> R) {
413413
R.ensure();
414-
td::actor::send_closure(SelfId, &DownloadShardState::written_split_state_file);
414+
td::actor::send_closure(SelfId, &DownloadShardState::written_state_part_file);
415415
});
416416
td::actor::send_closure(manager_, &ValidatorManager::store_persistent_state_file, block_id_, masterchain_block_id_,
417417
SplitAccountStateType{parts_[idx].effective_shard}, std::move(data), std::move(P));
@@ -421,6 +421,26 @@ void DownloadShardState::downloaded_state_part(td::BufferSlice data) {
421421
<< " out of " << parts_.size() << ")");
422422
}
423423

424+
void DownloadShardState::written_state_part_file() {
425+
size_t idx = stored_parts_.size() - 1;
426+
427+
auto P = td::PromiseCreator::lambda([SelfId = actor_id(this)](td::Result<td::Ref<vm::DataCell>> R) {
428+
R.ensure();
429+
td::actor::send_closure(SelfId, &DownloadShardState::saved_state_part_into_celldb, R.move_as_ok());
430+
});
431+
td::actor::send_closure(manager_, &ValidatorManager::store_block_state_part,
432+
BlockId{block_id_.shard_full().workchain, parts_[idx].effective_shard, block_id_.seqno()},
433+
stored_parts_.back(), std::move(P));
434+
LOG(INFO) << "saving to celldb state part " << idx + 1 << " out of " << parts_.size();
435+
status_.set_status(PSTRING() << block_id_.id.to_str() << " : saving state part to celldb (part " << idx + 1
436+
<< " out of " << parts_.size() << ")");
437+
}
438+
439+
void DownloadShardState::saved_state_part_into_celldb(td::Ref<vm::DataCell> cell) {
440+
stored_parts_.back() = cell;
441+
download_next_part_or_finish();
442+
}
443+
424444
void DownloadShardState::written_shard_state_file() {
425445
status_.set_status(PSTRING() << block_id_.id.to_str() << " : storing state to celldb");
426446
LOG(WARNING) << "written shard state file " << block_id_.to_str();

validator/downloaders/download-state.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,10 @@ class DownloadShardState : public td::actor::Actor {
5454
void checked_shard_state();
5555

5656
void downloaded_split_state_header(td::BufferSlice data);
57-
void written_split_state_file();
57+
void download_next_part_or_finish();
5858
void downloaded_state_part(td::BufferSlice data);
59+
void written_state_part_file();
60+
void saved_state_part_into_celldb(td::Ref<vm::DataCell> cell);
5961

6062
void written_shard_state_file();
6163
void written_shard_state(td::Ref<ShardState> state);

validator/interfaces/db.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ class Db : public td::actor::Actor {
5252
virtual void store_block_state(BlockHandle handle, td::Ref<ShardState> state,
5353
td::Promise<td::Ref<ShardState>> promise) = 0;
5454
virtual void get_block_state(ConstBlockHandle handle, td::Promise<td::Ref<ShardState>> promise) = 0;
55+
virtual void store_block_state_part(BlockId effective_block, td::Ref<vm::Cell> cell,
56+
td::Promise<td::Ref<vm::DataCell>> promise) = 0;
5557
virtual void get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) = 0;
5658

5759
virtual void store_persistent_state_file(BlockIdExt block_id, BlockIdExt masterchain_block_id,

validator/interfaces/validator-manager.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ class ValidatorManager : public ValidatorManagerInterface {
7070
}
7171
virtual void set_block_state(BlockHandle handle, td::Ref<ShardState> state,
7272
td::Promise<td::Ref<ShardState>> promise) = 0;
73+
virtual void store_block_state_part(BlockId effective_block, td::Ref<vm::Cell> cell,
74+
td::Promise<td::Ref<vm::DataCell>> promise) = 0;
7375
virtual void get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) = 0;
7476
virtual void store_persistent_state_file(BlockIdExt block_id, BlockIdExt masterchain_block_id,
7577
PersistentStateType type, td::BufferSlice state,

validator/manager-disk.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,11 @@ void ValidatorManagerImpl::set_block_state(BlockHandle handle, td::Ref<ShardStat
688688
td::actor::send_closure(db_, &Db::store_block_state, handle, state, std::move(promise));
689689
}
690690

691+
void ValidatorManagerImpl::store_block_state_part(BlockId effective_block, td::Ref<vm::Cell> cell,
692+
td::Promise<td::Ref<vm::DataCell>> promise) {
693+
td::actor::send_closure(db_, &Db::store_block_state_part, effective_block, cell, std::move(promise));
694+
}
695+
691696
void ValidatorManagerImpl::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) {
692697
td::actor::send_closure(db_, &Db::get_cell_db_reader, std::move(promise));
693698
}

validator/manager-disk.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ class ValidatorManagerImpl : public ValidatorManager {
150150

151151
void set_block_state(BlockHandle handle, td::Ref<ShardState> state,
152152
td::Promise<td::Ref<ShardState>> promise) override;
153+
void store_block_state_part(BlockId effective_block, td::Ref<vm::Cell> cell,
154+
td::Promise<td::Ref<vm::DataCell>> promise) override;
153155
void get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) override;
154156
void store_persistent_state_file(BlockIdExt block_id, BlockIdExt masterchain_block_id, PersistentStateType type,
155157
td::BufferSlice state, td::Promise<td::Unit> promise) override;

validator/manager-hardfork.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,11 @@ class ValidatorManagerImpl : public ValidatorManager {
176176
td::Promise<td::Ref<ShardState>> promise) override {
177177
UNREACHABLE();
178178
}
179+
void store_block_state_part(BlockId effective_block, td::Ref<vm::Cell> cell,
180+
td::Promise<td::Ref<vm::DataCell>> promise) override {
181+
UNREACHABLE();
182+
}
183+
179184
void get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) override;
180185
void store_persistent_state_file(BlockIdExt block_id, BlockIdExt masterchain_block_id, PersistentStateType type,
181186
td::BufferSlice state, td::Promise<td::Unit> promise) override {

validator/manager.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,11 @@ void ValidatorManagerImpl::set_block_state(BlockHandle handle, td::Ref<ShardStat
12331233
td::actor::send_closure(db_, &Db::store_block_state, handle, state, std::move(P));
12341234
}
12351235

1236+
void ValidatorManagerImpl::store_block_state_part(BlockId effective_block, td::Ref<vm::Cell> cell,
1237+
td::Promise<td::Ref<vm::DataCell>> promise) {
1238+
td::actor::send_closure(db_, &Db::store_block_state_part, effective_block, cell, std::move(promise));
1239+
}
1240+
12361241
void ValidatorManagerImpl::get_cell_db_reader(td::Promise<std::shared_ptr<vm::CellDbReader>> promise) {
12371242
td::actor::send_closure(db_, &Db::get_cell_db_reader, std::move(promise));
12381243
}

0 commit comments

Comments
 (0)