@@ -137,53 +137,61 @@ void CollationManager::collate_shard_block(ShardIdFull shard, BlockIdExt min_mas
137137
138138 adnl::AdnlNodeIdShort selected_collator = adnl::AdnlNodeIdShort::zero ();
139139 size_t selected_idx = 0 ;
140- auto check_collator = [&](const adnl::AdnlNodeIdShort& id) -> bool {
141- auto & collator = collators_[id];
142- if (!collator.alive ) {
143- return false ;
144- }
145- if (is_optimistic && collator.version < CollatorNode::VERSION_OPTIMISTIC_COLLATE) {
146- return false ;
147- }
148- return true ;
149- };
150- switch (s->select_mode ) {
151- case CollatorsList::mode_random: {
152- int cnt = 0 ;
153- for (size_t i = 0 ; i < s->collators .size (); ++i) {
154- adnl::AdnlNodeIdShort collator = s->collators [i];
155- if (check_collator (collator)) {
156- ++cnt;
157- if (td::Random::fast (1 , cnt) == 1 ) {
140+ for (int allow_banned = 0 ; allow_banned < 2 ; ++allow_banned) {
141+ auto check_collator = [&](const adnl::AdnlNodeIdShort& id) -> bool {
142+ auto & collator = collators_[id];
143+ if (!collator.alive ) {
144+ return false ;
145+ }
146+ if (collator.banned_until && !allow_banned) {
147+ return false ;
148+ }
149+ if (is_optimistic && collator.version < CollatorNode::VERSION_OPTIMISTIC_COLLATE) {
150+ return false ;
151+ }
152+ return true ;
153+ };
154+ switch (s->select_mode ) {
155+ case CollatorsList::mode_random: {
156+ int cnt = 0 ;
157+ for (size_t i = 0 ; i < s->collators .size (); ++i) {
158+ adnl::AdnlNodeIdShort collator = s->collators [i];
159+ if (check_collator (collator)) {
160+ ++cnt;
161+ if (td::Random::fast (1 , cnt) == 1 ) {
162+ selected_collator = collator;
163+ selected_idx = i;
164+ }
165+ }
166+ }
167+ break ;
168+ }
169+ case CollatorsList::mode_ordered: {
170+ for (size_t i = 0 ; i < s->collators .size (); ++i) {
171+ adnl::AdnlNodeIdShort collator = s->collators [i];
172+ if (check_collator (collator)) {
158173 selected_collator = collator;
159174 selected_idx = i;
175+ break ;
160176 }
161177 }
178+ break ;
162179 }
163- break ;
164- }
165- case CollatorsList::mode_ordered: {
166- for (size_t i = 0 ; i < s->collators .size (); ++i) {
167- adnl::AdnlNodeIdShort collator = s->collators [i];
168- if (check_collator (collator)) {
169- selected_collator = collator;
170- selected_idx = i;
171- break ;
180+ case CollatorsList::mode_round_robin: {
181+ size_t iters = 0 ;
182+ for (size_t i = s->cur_idx ; iters < s->collators .size (); (++i) %= s->collators .size (), ++iters) {
183+ adnl::AdnlNodeIdShort& collator = s->collators [i];
184+ if (check_collator (collator)) {
185+ selected_collator = collator;
186+ selected_idx = i;
187+ s->cur_idx = (i + 1 ) % s->collators .size ();
188+ break ;
189+ }
172190 }
191+ break ;
173192 }
174- break ;
175193 }
176- case CollatorsList::mode_round_robin: {
177- size_t iters = 0 ;
178- for (size_t i = s->cur_idx ; iters < s->collators .size (); (++i) %= s->collators .size (), ++iters) {
179- adnl::AdnlNodeIdShort& collator = s->collators [i];
180- if (check_collator (collator)) {
181- selected_collator = collator;
182- selected_idx = i;
183- s->cur_idx = (i + 1 ) % s->collators .size ();
184- break ;
185- }
186- }
194+ if (!selected_collator.is_zero () || s->self_collate ) {
187195 break ;
188196 }
189197 }
@@ -372,11 +380,21 @@ void CollationManager::get_stats(
372380 }
373381 obj->last_ping_ago_ = collator.last_ping_at ? td::Time::now () - collator.last_ping_at .at () : -1.0 ;
374382 obj->last_ping_status_ = collator.last_ping_status .is_ok () ? " OK" : collator.last_ping_status .message ().str ();
383+ obj->banned_for_ = collator.banned_until ? collator.banned_until .in () : -1.0 ;
375384 stats->collators_ .push_back (std::move (obj));
376385 }
377386 promise.set_value (std::move (stats));
378387}
379388
389+ void CollationManager::ban_collator (adnl::AdnlNodeIdShort collator_id, std::string reason) {
390+ auto it = collators_.find (collator_id);
391+ if (it == collators_.end ()) {
392+ return ;
393+ }
394+ alarm_timestamp ().relax (it->second .banned_until = td::Timestamp::in (BAN_DURATION));
395+ LOG (ERROR) << " Ban collator " << collator_id << " for " << BAN_DURATION << " s: " << reason;
396+ }
397+
380398void CollationManager::update_collators_list (const CollatorsList& collators_list) {
381399 shards_.clear ();
382400 for (auto & [_, collator] : collators_) {
@@ -427,6 +445,14 @@ CollationManager::ShardInfo* CollationManager::select_shard_info(ShardIdFull sha
427445void CollationManager::alarm () {
428446 alarm_timestamp () = td::Timestamp::never ();
429447 for (auto & [id, collator] : collators_) {
448+ if (collator.banned_until ) {
449+ if (collator.banned_until .is_in_past ()) {
450+ collator.banned_until = {};
451+ LOG (ERROR) << " Unban collator " << id;
452+ } else {
453+ alarm_timestamp ().relax (collator.banned_until );
454+ }
455+ }
430456 if (collator.active_cnt == 0 || collator.sent_ping ) {
431457 continue ;
432458 }
0 commit comments