@@ -62,7 +62,7 @@ void CollatorNodeSession::start_up() {
6262 collated_data_deduplicator_ = std::make_shared<CollatedDataDeduplicator>();
6363 }
6464 if (can_generate_) {
65- generate_block (prev_, {}, {}, td::Timestamp::in (10.0 ), [](td::Result<BlockCandidate>) {});
65+ generate_block (prev_, {}, {}, {}, td::Timestamp::in (10.0 ), [](td::Result<BlockCandidate>) {});
6666 }
6767}
6868
@@ -72,6 +72,11 @@ void CollatorNodeSession::tear_down() {
7272 for (auto & [_, entry] : cache_) {
7373 entry->cancel (td::Status::Error (" validator session finished" ));
7474 }
75+ for (auto & [_, vec] : collated_data_merged_waiters_) {
76+ for (auto & [promise, _] : vec) {
77+ promise.set_error (td::Status::Error (" validator session finished" ));
78+ }
79+ }
7580}
7681
7782void CollatorNodeSession::new_shard_block_accepted (BlockIdExt block_id, bool can_generate) {
@@ -114,7 +119,7 @@ void CollatorNodeSession::new_shard_block_accepted(BlockIdExt block_id, bool can
114119 try_merge_collated_data (block_id);
115120
116121 if (can_generate_) {
117- generate_block (prev_, {}, {}, td::Timestamp::in (10.0 ), [](td::Result<BlockCandidate>) {});
122+ generate_block (prev_, {}, {}, {}, td::Timestamp::in (10.0 ), [](td::Result<BlockCandidate>) {});
118123 }
119124}
120125
@@ -143,7 +148,8 @@ void CollatorNodeSession::update_masterchain_config(td::Ref<MasterchainState> st
143148
144149void CollatorNodeSession::generate_block (std::vector<BlockIdExt> prev_blocks,
145150 td::optional<BlockCandidatePriority> o_priority,
146- td::Ref<BlockData> o_optimistic_prev_block, td::Timestamp timeout,
151+ td::Ref<BlockData> o_optimistic_prev_block,
152+ td::BufferSlice o_optimistic_prev_collated_data, td::Timestamp timeout,
147153 td::Promise<BlockCandidate> promise) {
148154 bool is_external = !o_priority;
149155 bool is_optimistic = o_optimistic_prev_block.not_null ();
@@ -242,6 +248,7 @@ void CollatorNodeSession::generate_block(std::vector<BlockIdExt> prev_blocks,
242248 .collator_node_id = local_id_,
243249 .skip_store_candidate = true ,
244250 .optimistic_prev_block = o_optimistic_prev_block,
251+ .optimistic_prev_collated_data = std::move (o_optimistic_prev_collated_data),
245252 .collated_data_deduplicator = collated_data_deduplicator_};
246253 auto token = cache_entry->cancellation_token_source .get_cancellation_token ();
247254 wait_collated_data_merged (
@@ -295,26 +302,33 @@ void CollatorNodeSession::process_request(adnl::AdnlNodeIdShort src, std::vector
295302 if (it == cache_.end () || it->second ->started ) {
296303 BlockIdExt prev_block = prev_blocks[0 ];
297304 td::actor::send_closure (
298- manager_, &ValidatorManager::get_candidate_data_by_block_id_from_db, prev_block,
299- [=, SelfId = actor_id (this ), promise = std::move (promise)](td::Result<td::BufferSlice> R) mutable {
305+ manager_, &ValidatorManager::get_block_candidate_by_block_id_from_db, prev_block,
306+ [=, SelfId = actor_id (this ), promise = std::move (promise)](td::Result<BlockCandidate> R) mutable {
307+ td::Result<std::pair<td::BufferSlice, td::BufferSlice>> res;
308+ if (R.is_error ()) {
309+ res = R.move_as_error ();
310+ } else {
311+ BlockCandidate c = R.move_as_ok ();
312+ res = std::make_pair (std::move (c.data ), std::move (c.collated_data ));
313+ }
300314 td::actor::send_closure (SelfId, &CollatorNodeSession::process_request_optimistic_cont, src, prev_block,
301- priority, timeout, std::move (promise), std::move (R ));
315+ priority, timeout, std::move (promise), std::move (res ));
302316 });
303317 return ;
304318 }
305319 }
306- generate_block (std::move (prev_blocks), priority, {}, timeout, std::move (promise));
320+ generate_block (std::move (prev_blocks), priority, {}, {}, timeout, std::move (promise));
307321}
308322
309- void CollatorNodeSession::process_request_optimistic_cont (adnl::AdnlNodeIdShort src, BlockIdExt prev_block_id,
310- BlockCandidatePriority priority, td::Timestamp timeout,
311- td::Promise<BlockCandidate> promise,
312- td::Result<td::BufferSlice> prev_block_data ) {
313- if ( prev_block_data. is_ok ()) {
314- TRY_RESULT_PROMISE_PREFIX (promise, prev_block, create_block (prev_block_id, prev_block_data. move_as_ok ( )),
323+ void CollatorNodeSession::process_request_optimistic_cont (
324+ adnl::AdnlNodeIdShort src, BlockIdExt prev_block_id, BlockCandidatePriority priority, td::Timestamp timeout,
325+ td::Promise<BlockCandidate> promise, td::Result<std::pair<td::BufferSlice, td::BufferSlice>> prev_candidate) {
326+ if (prev_candidate. is_ok () ) {
327+ auto [ prev_block_data, prev_collated_data] = prev_candidate. move_as_ok ();
328+ TRY_RESULT_PROMISE_PREFIX (promise, prev_block, create_block (prev_block_id, std::move (prev_block_data )),
315329 " invalid prev block data in db: " );
316330 LOG (INFO) << " got prev block from db for optimistic collation: " << prev_block_id.to_str ();
317- generate_block ({prev_block_id}, priority, prev_block, timeout, std::move (promise));
331+ generate_block ({prev_block_id}, priority, prev_block, std::move (prev_collated_data), timeout, std::move (promise));
318332 return ;
319333 }
320334 td::actor::send_closure (
@@ -324,7 +338,8 @@ void CollatorNodeSession::process_request_optimistic_cont(adnl::AdnlNodeIdShort
324338 timeout, std::move (promise), std::move (R));
325339 },
326340 timeout,
327- create_serialize_tl_object<ton_api::collatorNode_requestBlockCallback>(0 , create_tl_block_id (prev_block_id)),
341+ create_serialize_tl_object<ton_api::collatorNode_requestBlockCallback>(merge_collated_data_enabled_ ? 1 : 0 ,
342+ create_tl_block_id (prev_block_id)),
328343 max_candidate_size_);
329344}
330345
@@ -335,13 +350,29 @@ void CollatorNodeSession::process_request_optimistic_cont2(BlockIdExt prev_block
335350 " failed to download prev block data for optimistic collation: " );
336351 TRY_RESULT_PROMISE_PREFIX (promise, f, fetch_tl_object<ton_api::collatorNode_Candidate>(response, true ),
337352 " failed to download prev block data for optimistic collation: " );
338- TRY_RESULT_PROMISE_PREFIX (promise, candidate,
339- deserialize_candidate (std::move (f), max_candidate_size_),
353+ TRY_RESULT_PROMISE_PREFIX (promise, candidate, deserialize_candidate (std::move (f), max_candidate_size_),
340354 " failed to download prev block data for optimistic collation: " );
341355 TRY_RESULT_PROMISE_PREFIX (promise, prev_block, create_block (prev_block_id, std::move (candidate.data )),
342356 " invalid prev block data from validator: " );
357+ if (merge_collated_data_enabled_) {
358+ block::gen::Block::Record rec;
359+ block::gen::BlockInfo::Record info;
360+ if (!block::gen::unpack_cell (prev_block->root_cell (), rec) || !block::gen::unpack_cell (rec.info , info)) {
361+ promise.set_error (td::Status::Error (" failed to unpack prev block header" ));
362+ return ;
363+ }
364+ if (info.flags & 2 ) {
365+ FileHash stored_collated_data_hash;
366+ info.collated_data_hash ->prefetch_bits_to (stored_collated_data_hash);
367+ if (stored_collated_data_hash != candidate.collated_file_hash ) {
368+ promise.set_error (td::Status::Error (" collated data hash mismatch" ));
369+ return ;
370+ }
371+ }
372+ }
343373 LOG (INFO) << " got prev block from validator for optimistic collation: " << prev_block_id.to_str ();
344- generate_block ({prev_block_id}, priority, prev_block, timeout, std::move (promise));
374+ generate_block ({prev_block_id}, priority, prev_block, std::move (candidate.collated_data ), timeout,
375+ std::move (promise));
345376}
346377
347378void CollatorNodeSession::CacheEntry::cancel (td::Status reason) {
0 commit comments