@@ -111,6 +111,66 @@ struct MergeOperatorAddCellRefcnt : public rocksdb::MergeOperator {
111
111
}
112
112
};
113
113
114
+ void CellDbIn::validate_meta () {
115
+ LOG (INFO) << " Validating metadata\n " ;
116
+ size_t max_meta_keys_loaded = opts_->get_celldb_in_memory () ? std::numeric_limits<std::size_t >::max () : 10000 ;
117
+ auto meta = boc_->meta_get_all (max_meta_keys_loaded).move_as_ok ();
118
+ bool partial_check = meta.size () == max_meta_keys_loaded;
119
+ if (partial_check) {
120
+ LOG (ERROR) << " Too much metadata in the database, do only partial check" ;
121
+ }
122
+ size_t missing_roots = 0 ;
123
+ size_t unknown_roots = 0 ;
124
+ std::set<vm::CellHash> root_hashes;
125
+ for (auto [k, v] : meta) {
126
+ if (k == " desczero" ) {
127
+ continue ;
128
+ }
129
+ auto obj = fetch_tl_object<ton_api::db_celldb_value>(td::BufferSlice{v}, true );
130
+ obj.ensure ();
131
+ auto entry = DbEntry{obj.move_as_ok ()};
132
+ root_hashes.insert (vm::CellHash::from_slice (entry.root_hash .as_slice ()));
133
+ auto cell = boc_->load_cell (entry.root_hash .as_slice ());
134
+ missing_roots += cell.is_error ();
135
+ LOG_IF (ERROR, cell.is_error ()) << " Cannot load root from meta: " << entry.block_id .to_str () << " " << cell.error ();
136
+ }
137
+
138
+ // load_known_roots is only supported by InMemory database, so it is ok to check all known roots here
139
+ auto known_roots = boc_->load_known_roots ().move_as_ok ();
140
+ for (auto & root : known_roots) {
141
+ block::gen::ShardStateUnsplit::Record info;
142
+ block::gen::OutMsgQueueInfo::Record qinfo;
143
+ block::ShardId shard;
144
+ if (!(tlb::unpack_cell (root, info) && shard.deserialize (info.shard_id .write ()) &&
145
+ tlb::unpack_cell (info.out_msg_queue_info , qinfo))) {
146
+ LOG (FATAL) << " cannot create ShardDescr from a root in celldb" ;
147
+ }
148
+ if (!partial_check && !root_hashes.contains (root->get_hash ())) {
149
+ unknown_roots++;
150
+ LOG (ERROR) << " Unknown root" << ShardIdFull (shard).to_str () << " :" << info.seq_no ;
151
+ constexpr bool delete_unknown_roots = false ;
152
+ if (delete_unknown_roots) {
153
+ vm::CellStorer stor{*cell_db_};
154
+ cell_db_->begin_write_batch ().ensure ();
155
+ boc_->dec (root);
156
+ boc_->commit (stor).ensure ();
157
+ cell_db_->commit_write_batch ().ensure ();
158
+ if (!opts_->get_celldb_in_memory ()) {
159
+ boc_->set_loader (std::make_unique<vm::CellLoader>(cell_db_->snapshot (), on_load_callback_)).ensure ();
160
+ }
161
+ LOG (ERROR) << " Unknown root" << ShardIdFull (shard).to_str () << " :" << info.seq_no << " REMOVED" ;
162
+ }
163
+ }
164
+ }
165
+
166
+ LOG_IF (ERROR, missing_roots != 0 ) << " Missing root hashes: " << missing_roots;
167
+ LOG_IF (ERROR, unknown_roots != 0 ) << " Unknown roots: " << unknown_roots;
168
+
169
+ LOG_IF (FATAL, missing_roots != 0 ) << " Missing root hashes: " << missing_roots;
170
+ LOG_IF (FATAL, unknown_roots != 0 ) << " Unknown roots: " << unknown_roots;
171
+ LOG (INFO) << " Validating metadata: OK\n " ;
172
+ }
173
+
114
174
void CellDbIn::start_up () {
115
175
on_load_callback_ = [actor = std::make_shared<td::actor::ActorOwn<MigrationProxy>>(
116
176
td::actor::create_actor<MigrationProxy>(" celldbmigration" , actor_id (this ))),
@@ -141,11 +201,11 @@ void CellDbIn::start_up() {
141
201
std::optional<vm::DynamicBagOfCellsDb::CreateV2Options> boc_v2_options;
142
202
143
203
if (opts_->get_celldb_v2 ()) {
144
- boc_v2_options =
145
- vm::DynamicBagOfCellsDb::CreateV2Options{ .extra_threads = std::clamp (std::thread::hardware_concurrency () / 2 , 1u , 8u ),
146
- .executor = {},
147
- .cache_ttl_max = 2000 ,
148
- .cache_size_max = 1000000 };
204
+ boc_v2_options = vm::DynamicBagOfCellsDb::CreateV2Options{
205
+ .extra_threads = std::clamp (std::thread::hardware_concurrency () / 2 , 1u , 8u ),
206
+ .executor = {},
207
+ .cache_ttl_max = 2000 ,
208
+ .cache_size_max = 1000000 };
149
209
size_t min_rocksdb_cache = std::max (size_t {1 } << 30 , boc_v2_options->cache_size_max * 5000 );
150
210
if (!o_celldb_cache_size || o_celldb_cache_size.value () < min_rocksdb_cache) {
151
211
LOG (WARNING) << " Increase CellDb block cache size to " << td::format::as_size (min_rocksdb_cache) << " from "
@@ -208,54 +268,7 @@ void CellDbIn::start_up() {
208
268
boc_->set_loader (std::make_unique<vm::CellLoader>(cell_db_->snapshot (), on_load_callback_)).ensure ();
209
269
}
210
270
211
- auto meta = boc_->meta_get_all ().move_as_ok ();
212
- size_t missing_roots = 0 ;
213
- size_t unknown_roots = 0 ;
214
- std::set<vm::CellHash> root_hashes;
215
- for (auto [k, v] : meta) {
216
- if (k == " desczero" ) {
217
- continue ;
218
- }
219
- auto obj = fetch_tl_object<ton_api::db_celldb_value>(td::BufferSlice{v}, true );
220
- obj.ensure ();
221
- auto entry = DbEntry{obj.move_as_ok ()};
222
- root_hashes.insert (vm::CellHash::from_slice (entry.root_hash .as_slice ()));
223
- auto cell = boc_->load_cell (entry.root_hash .as_slice ());
224
- missing_roots += cell.is_error ();
225
- LOG_IF (ERROR, cell.is_error ()) << " Cannot load root from meta: " << entry.block_id .to_str () << " " << cell.error ();
226
- }
227
- auto known_roots = boc_->load_known_roots ().move_as_ok ();
228
- for (auto & root : known_roots) {
229
- block::gen::ShardStateUnsplit::Record info;
230
- block::gen::OutMsgQueueInfo::Record qinfo;
231
- block::ShardId shard;
232
- if (!(tlb::unpack_cell (root, info) && shard.deserialize (info.shard_id .write ()) &&
233
- tlb::unpack_cell (info.out_msg_queue_info , qinfo))) {
234
- LOG (FATAL) << " cannot create ShardDescr from a root in celldb" ;
235
- }
236
- if (!root_hashes.contains (root->get_hash ())) {
237
- unknown_roots++;
238
- LOG (ERROR) << " Unknown root" << ShardIdFull (shard).to_str () << " :" << info.seq_no ;
239
- constexpr bool delete_unknown_roots = false ;
240
- if (delete_unknown_roots) {
241
- vm::CellStorer stor{*cell_db_};
242
- cell_db_->begin_write_batch ().ensure ();
243
- boc_->dec (root);
244
- boc_->commit (stor).ensure ();
245
- cell_db_->commit_write_batch ().ensure ();
246
- if (!opts_->get_celldb_in_memory ()) {
247
- boc_->set_loader (std::make_unique<vm::CellLoader>(cell_db_->snapshot (), on_load_callback_)).ensure ();
248
- }
249
- LOG (ERROR) << " Unknown root" << ShardIdFull (shard).to_str () << " :" << info.seq_no << " REMOVED" ;
250
- }
251
- }
252
- }
253
-
254
- LOG_IF (ERROR, missing_roots != 1 ) << " Missing root hashes: " << missing_roots;
255
- LOG_IF (ERROR, unknown_roots != 0 ) << " Unknown roots: " << unknown_roots;
256
-
257
- LOG_IF (FATAL, missing_roots > 1 ) << " Missing root hashes: " << missing_roots;
258
- LOG_IF (FATAL, unknown_roots != 0 ) << " Unknown roots: " << unknown_roots;
271
+ validate_meta ();
259
272
260
273
alarm_timestamp () = td::Timestamp::in (10.0 );
261
274
@@ -267,6 +280,9 @@ void CellDbIn::start_up() {
267
280
set_block (empty, std::move (e));
268
281
boc_->commit (stor);
269
282
cell_db_->commit_write_batch ().ensure ();
283
+ if (!opts_->get_celldb_in_memory ()) {
284
+ boc_->set_loader (std::make_unique<vm::CellLoader>(cell_db_->snapshot (), on_load_callback_)).ensure ();
285
+ }
270
286
}
271
287
272
288
if (opts_->get_celldb_v2 () || opts_->get_celldb_in_memory ()) {
0 commit comments