@@ -503,37 +503,44 @@ td::Status OverlayImpl::check_date(td::uint32 date) {
503
503
return td::Status::OK ();
504
504
}
505
505
506
- BroadcastCheckResult OverlayImpl::check_source_eligible (const PublicKeyHash & source, const Certificate * cert,
506
+ BroadcastCheckResult OverlayImpl::check_source_eligible (const PublicKeyHash& source, const Certificate* cert,
507
507
td::uint32 size, bool is_fec) {
508
508
if (size == 0 ) {
509
509
return BroadcastCheckResult::Forbidden;
510
510
}
511
-
512
511
auto r = rules_.check_rules (source, size, is_fec);
513
512
if (!cert || r == BroadcastCheckResult::Allowed) {
514
513
return r;
515
514
}
515
+ td::Bits256 cert_hash = get_tl_object_sha_bits256 (cert->tl ());
516
+ auto cached_cert = checked_certificates_cache_.find (source);
517
+ bool cached = cached_cert != checked_certificates_cache_.end () && cached_cert->second ->cert_hash == cert_hash;
516
518
517
- auto r2 = cert->check (source, overlay_id_, static_cast <td::int32>(td::Clocks::system ()), size, is_fec);
519
+ auto r2 = cert->check (source, overlay_id_, static_cast <td::int32>(td::Clocks::system ()), size, is_fec,
520
+ /* skip_check_signature = */ cached);
521
+ if (r2 != BroadcastCheckResult::Forbidden) {
522
+ if (cached_cert == checked_certificates_cache_.end ()) {
523
+ cached_cert = checked_certificates_cache_.emplace (
524
+ source, std::make_unique<CachedCertificate>(source, cert_hash)).first ;
525
+ } else {
526
+ cached_cert->second ->cert_hash = cert_hash;
527
+ cached_cert->second ->remove ();
528
+ }
529
+ checked_certificates_cache_lru_.put (cached_cert->second .get ());
530
+ while (checked_certificates_cache_.size () > max_checked_certificates_cache_size_) {
531
+ auto to_remove = (CachedCertificate*)checked_certificates_cache_lru_.get ();
532
+ CHECK (to_remove);
533
+ to_remove->remove ();
534
+ checked_certificates_cache_.erase (to_remove->source );
535
+ }
536
+ }
518
537
r2 = broadcast_check_result_min (r2, rules_.check_rules (cert->issuer_hash (), size, is_fec));
519
538
return broadcast_check_result_max (r, r2);
520
539
}
521
540
522
- BroadcastCheckResult OverlayImpl::check_source_eligible (PublicKey source, const Certificate * cert, td::uint32 size,
541
+ BroadcastCheckResult OverlayImpl::check_source_eligible (PublicKey source, const Certificate* cert, td::uint32 size,
523
542
bool is_fec) {
524
- if (size == 0 ) {
525
- return BroadcastCheckResult::Forbidden;
526
- }
527
- auto short_id = source.compute_short_id ();
528
-
529
- auto r = rules_.check_rules (short_id, size, is_fec);
530
- if (!cert || r == BroadcastCheckResult::Allowed) {
531
- return r;
532
- }
533
-
534
- auto r2 = cert->check (short_id, overlay_id_, static_cast <td::int32>(td::Clocks::system ()), size, is_fec);
535
- r2 = broadcast_check_result_min (r2, rules_.check_rules (cert->issuer_hash (), size, is_fec));
536
- return broadcast_check_result_max (r, r2);
543
+ return check_source_eligible (source.compute_short_id (), cert, size, is_fec);
537
544
}
538
545
539
546
td::Status OverlayImpl::check_delivered (BroadcastHash hash) {
0 commit comments