Skip to content

Commit f9a5afd

Browse files
authored
Merge pull request #1767 from ton-blockchain/optimize-collate
Optimistic collation and other optimizations
2 parents 0326fc5 + badc4fd commit f9a5afd

40 files changed

+1250
-633
lines changed

tdutils/td/utils/Timer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ class PerfLog {
160160
};
161161
template <class T>
162162
double PerfLogAction::finish(const T &result) {
163+
if (!perf_log_) {
164+
return 0.0;
165+
}
163166
if (result.is_ok()) {
164167
return perf_log_->finish_action(i_, td::Status::OK());
165168
} else {

tl/generate/scheme/ton_api.tl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,7 @@ validatorSession.blockUpdate ts:long actions:(vector validatorSession.round.Mess
344344
validatorSession.candidate src:int256 round:int root_hash:int256 data:bytes collated_data:bytes = validatorSession.Candidate;
345345
validatorSession.compressedCandidate flags:# src:int256 round:int root_hash:int256 decompressed_size:int data:bytes = validatorSession.Candidate;
346346
validatorSession.compressedCandidateV2 flags:# src:int256 round:int root_hash:int256 data:bytes = validatorSession.Candidate;
347+
validatorSession.optimisticCandidateBroadcast flags:# prev_candidate_id:int256 data:bytes = validatorSession.OptimisticCandidateBroadcast;
347348

348349
validatorSession.config catchain_idle_timeout:double catchain_max_deps:int round_candidates:int next_candidate_delay:double round_attempt_duration:int
349350
max_round_attempts:int max_block_size:int max_collated_data_size:int = validatorSession.Config;
@@ -962,7 +963,7 @@ validatorStats.blockStats
962963
old_out_msg_queue_size:long new_out_msg_queue_size:long msg_queue_cleaned:int
963964
neighbors:(vector validatorStats.blockStats.neighborStats) = validatorStats.BlockStats;
964965
validatorStats.collateWorkTimeStats
965-
total:double queue_cleanup:double prelim_storage_stat:double trx_tvm:double trx_storage_stat:double
966+
total:double optimistic_apply:double queue_cleanup:double prelim_storage_stat:double trx_tvm:double trx_storage_stat:double
966967
trx_other:double final_storage_stat:double create_block:double create_collated_data:double create_block_candidate:double
967968
= validatorStats.CollateWorkTimeStats;
968969
validatorStats.storageStatCacheStats

tl/generate/scheme/ton_api.tlo

320 Bytes
Binary file not shown.

validator-session/validator-session.cpp

Lines changed: 160 additions & 40 deletions
Large diffs are not rendered by default.

validator-session/validator-session.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,9 @@ class ValidatorSession : public td::actor::Actor {
9393
ValidatorSessionFileHash file_hash,
9494
ValidatorSessionCollatedDataFileHash collated_data_file_hash,
9595
td::Promise<BlockCandidate> promise) = 0;
96+
virtual void generate_block_optimistic(BlockSourceInfo source_info, td::BufferSlice prev_block, RootHash prev_root_hash,
97+
FileHash prev_file_hash, td::Promise<GeneratedCandidate> promise) {
98+
}
9699
virtual ~Callback() = default;
97100
};
98101

validator-session/validator-session.hpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,13 +161,38 @@ class ValidatorSessionImpl : public ValidatorSession {
161161
bool catchain_started_ = false;
162162
bool allow_unsafe_self_blocks_resync_;
163163
bool compress_block_candidates_ = false;
164+
bool allow_optimistic_generation_ = false;
164165

165166
ValidatorSessionStats cur_stats_;
166167
bool stats_inited_ = false;
167168
std::map<std::pair<td::uint32, ValidatorSessionCandidateId>, std::vector<td::uint32>>
168169
stats_pending_approve_; // round, candidate_id -> approvers
169170
std::map<std::pair<td::uint32, ValidatorSessionCandidateId>, std::vector<td::uint32>>
170171
stats_pending_sign_; // round, candidate_id -> signers
172+
173+
struct SentCandidateStats {
174+
bool sent = false;
175+
double sent_at = -1.0;
176+
double serialize_time = -1.0;
177+
size_t serialized_size = 0;
178+
};
179+
std::map<ValidatorSessionCandidateId, SentCandidateStats> sent_candidates_;
180+
181+
struct BroadcastInfo {
182+
ValidatorSessionCandidateId candidate_id;
183+
double received_at = -1.0;
184+
double deserialize_time = -1.0;
185+
size_t serialized_size = 0;
186+
ValidatorSessionFileHash file_hash;
187+
ValidatorSessionCollatedDataFileHash collated_data_hash;
188+
};
189+
struct OptimisticBroadcast {
190+
tl_object_ptr<ton_api::validatorSession_candidate> candidate;
191+
ValidatorSessionCandidateId prev_candidate_id;
192+
BroadcastInfo broadcast_info;
193+
};
194+
std::map<std::pair<td::uint32, td::uint32>, OptimisticBroadcast> optimistic_broadcasts_; // round, src -> broadcast
195+
171196
void stats_init();
172197
void stats_add_round();
173198
ValidatorSessionStats::Producer *stats_get_candidate_stat(
@@ -176,6 +201,10 @@ class ValidatorSessionImpl : public ValidatorSession {
176201
ValidatorSessionStats::Producer *stats_get_candidate_stat_by_id(td::uint32 round,
177202
ValidatorSessionCandidateId candidate_id);
178203
void stats_process_action(td::uint32 node_id, ton_api::validatorSession_round_Message &action);
204+
void process_approve(td::uint32 node_id, td::uint32 round, ValidatorSessionCandidateId candidate_id);
205+
206+
void generated_optimistic_candidate(td::uint32 round, GeneratedCandidate candidate,
207+
ValidatorSessionCandidateId prev_candidate);
179208

180209
public:
181210
ValidatorSessionImpl(catchain::CatChainSessionId session_id, ValidatorSessionOptions opts, PublicKeyHash local_id,
@@ -205,6 +234,9 @@ class ValidatorSessionImpl : public ValidatorSession {
205234
bool ensure_candidate_unique(td::uint32 src_idx, td::uint32 round, ValidatorSessionCandidateId block_id);
206235
void process_broadcast(PublicKeyHash src, td::BufferSlice data, td::optional<ValidatorSessionCandidateId> expected_id,
207236
bool is_overlay_broadcast, bool is_startup);
237+
void process_received_block(td::uint32 block_round, PublicKeyHash src, td::uint32 src_idx,
238+
tl_object_ptr<ton_api::validatorSession_candidate> candidate, const BroadcastInfo &info,
239+
bool is_overlay_broadcast, bool is_startup);
208240
void process_message(PublicKeyHash src, td::BufferSlice data);
209241
void process_query(PublicKeyHash src, td::BufferSlice data, td::Promise<td::BufferSlice> promise);
210242

@@ -218,6 +250,9 @@ class ValidatorSessionImpl : public ValidatorSession {
218250
td::BufferSlice signature);
219251

220252
void generated_block(td::uint32 round, GeneratedCandidate c, double collation_time);
253+
SentCandidateStats &send_candidate_broadcast(
254+
td::uint32 round, const BlockCandidate &candidate,
255+
td::optional<ValidatorSessionCandidateId> optimistic_prev_candidate = {});
221256
void signed_block(td::uint32 round, ValidatorSessionCandidateId hash, td::BufferSlice signature);
222257

223258
void end_request(td::uint32 round, ValidatorSessionCandidateId block_id) {

validator/CMakeLists.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ set(VALIDATOR_HEADERS
6464
shard-block-retainer.hpp
6565

6666
collation-manager.hpp
67-
collator-node.hpp
67+
collator-node/collator-node.hpp
68+
collator-node/collator-node-session.hpp
6869
manager-disk.h
6970
manager-disk.hpp
7071
manager-init.h
@@ -81,7 +82,8 @@ set(VALIDATOR_SOURCE
8182
apply-block.cpp
8283
block-handle.cpp
8384
collation-manager.cpp
84-
collator-node.cpp
85+
collator-node/collator-node.cpp
86+
collator-node/collator-node-session.cpp
8587
get-next-key-blocks.cpp
8688
import-db-slice.cpp
8789
import-db-slice-local.cpp

validator/apply-block.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ void ApplyBlock::written_block_data() {
166166
});
167167

168168
td::actor::send_closure(manager_, &ValidatorManager::wait_block_state, handle_, apply_block_priority(), timeout_,
169-
std::move(P));
169+
true, std::move(P));
170170
}
171171
}
172172

validator/collation-manager.cpp

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717
#include "collation-manager.hpp"
1818

19-
#include "collator-node.hpp"
19+
#include "collator-node/collator-node.hpp"
2020
#include "fabric.h"
2121
#include "td/utils/Random.h"
2222

@@ -38,18 +38,43 @@ void CollationManager::collate_block(ShardIdFull shard, BlockIdExt min_mastercha
3838
td::Promise<GeneratedCandidate> promise, int proto_version) {
3939
if (shard.is_masterchain()) {
4040
run_collate_query(
41-
shard, min_masterchain_block_id, std::move(prev), creator, std::move(validator_set),
42-
opts_->get_collator_options(), manager_, td::Timestamp::in(10.0), promise.wrap([](BlockCandidate&& candidate) {
41+
CollateParams{.shard = shard,
42+
.min_masterchain_block_id = min_masterchain_block_id,
43+
.prev = std::move(prev),
44+
.creator = creator,
45+
.validator_set = std::move(validator_set),
46+
.collator_opts = opts_->get_collator_options()},
47+
manager_, td::Timestamp::in(10.0), std::move(cancellation_token), promise.wrap([](BlockCandidate&& candidate) {
4348
return GeneratedCandidate{.candidate = std::move(candidate), .is_cached = false, .self_collated = true};
44-
}),
45-
adnl::AdnlNodeIdShort::zero(), std::move(cancellation_token), 0);
49+
}));
4650
return;
4751
}
4852
collate_shard_block(shard, min_masterchain_block_id, std::move(prev), creator, priority, std::move(validator_set),
4953
max_answer_size, std::move(cancellation_token), std::move(promise), td::Timestamp::in(10.0),
5054
proto_version);
5155
}
5256

57+
void CollationManager::collate_next_block(ShardIdFull shard, BlockIdExt min_masterchain_block_id,
58+
BlockIdExt prev_block_id, td::BufferSlice prev_block,
59+
Ed25519_PublicKey creator, BlockCandidatePriority priority,
60+
td::Ref<ValidatorSet> validator_set, td::uint64 max_answer_size,
61+
td::CancellationToken cancellation_token,
62+
td::Promise<GeneratedCandidate> promise, int proto_version) {
63+
TRY_RESULT_PROMISE(promise, prev_block_data, create_block(prev_block_id, std::move(prev_block)));
64+
run_collate_query(
65+
CollateParams{.shard = shard,
66+
.min_masterchain_block_id = min_masterchain_block_id,
67+
.prev = {prev_block_id},
68+
.creator = creator,
69+
.validator_set = std::move(validator_set),
70+
.collator_opts = opts_->get_collator_options(),
71+
.optimistic_prev_block_ = std::move(prev_block_data)},
72+
manager_, td::Timestamp::in(10.0), std::move(cancellation_token), promise.wrap([](BlockCandidate&& candidate) {
73+
return GeneratedCandidate{.candidate = std::move(candidate), .is_cached = false, .self_collated = true};
74+
}));
75+
// TODO: request to collator node
76+
}
77+
5378
void CollationManager::collate_shard_block(ShardIdFull shard, BlockIdExt min_masterchain_block_id,
5479
std::vector<BlockIdExt> prev, Ed25519_PublicKey creator,
5580
BlockCandidatePriority priority, td::Ref<ValidatorSet> validator_set,
@@ -109,11 +134,15 @@ void CollationManager::collate_shard_block(ShardIdFull shard, BlockIdExt min_mas
109134

110135
if (selected_collator.is_zero() && s->self_collate) {
111136
run_collate_query(
112-
shard, min_masterchain_block_id, std::move(prev), creator, std::move(validator_set),
113-
opts_->get_collator_options(), manager_, td::Timestamp::in(10.0), promise.wrap([](BlockCandidate&& candidate) {
137+
CollateParams{.shard = shard,
138+
.min_masterchain_block_id = min_masterchain_block_id,
139+
.prev = std::move(prev),
140+
.creator = creator,
141+
.validator_set = std::move(validator_set),
142+
.collator_opts = opts_->get_collator_options()},
143+
manager_, td::Timestamp::in(10.0), std::move(cancellation_token), promise.wrap([](BlockCandidate&& candidate) {
114144
return GeneratedCandidate{.candidate = std::move(candidate), .is_cached = false, .self_collated = true};
115-
}),
116-
adnl::AdnlNodeIdShort::zero(), std::move(cancellation_token), 0);
145+
}));
117146
return;
118147
}
119148

validator/collation-manager.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ class CollationManager : public td::actor::Actor {
3939
td::uint64 max_answer_size, td::CancellationToken cancellation_token,
4040
td::Promise<GeneratedCandidate> promise, int proto_version);
4141

42+
void collate_next_block(ShardIdFull shard, BlockIdExt min_masterchain_block_id, BlockIdExt prev_block_id,
43+
td::BufferSlice prev_block, Ed25519_PublicKey creator, BlockCandidatePriority priority,
44+
td::Ref<ValidatorSet> validator_set, td::uint64 max_answer_size,
45+
td::CancellationToken cancellation_token, td::Promise<GeneratedCandidate> promise,
46+
int proto_version);
47+
4248
void update_options(td::Ref<ValidatorManagerOptions> opts);
4349

4450
void validator_group_started(ShardIdFull shard);

0 commit comments

Comments
 (0)