From 856e03fec47963b7448b59737c1f2ce7b6d10c7a Mon Sep 17 00:00:00 2001 From: Terry Mancey Date: Tue, 7 Apr 2020 14:44:02 +0100 Subject: [PATCH] Brave Ads server retry logic should backoff exponentially with a ceiling --- vendor/bat-native-ads/BUILD.gn | 4 + .../src/bat/ads/internal/ad_conversions.cc | 64 ++--- .../src/bat/ads/internal/ad_conversions.h | 8 +- .../src/bat/ads/internal/ads_impl.cc | 170 ++----------- .../src/bat/ads/internal/ads_impl.h | 21 +- .../src/bat/ads/internal/ads_serve.cc | 124 ++++----- .../src/bat/ads/internal/ads_serve.h | 22 +- .../src/bat/ads/internal/bundle.cc | 19 +- .../src/bat/ads/internal/retry_timer.cc | 54 ++++ .../src/bat/ads/internal/retry_timer.h | 60 +++++ .../src/bat/ads/internal/static_values.h | 5 +- .../src/bat/ads/internal/timer.cc | 53 ++++ .../src/bat/ads/internal/timer.h | 51 ++++ vendor/bat-native-confirmations/BUILD.gn | 4 + .../include/bat/confirmations/confirmations.h | 6 - .../bat/confirmations/internal/ads_rewards.cc | 72 ++---- .../bat/confirmations/internal/ads_rewards.h | 11 +- .../internal/confirmations_impl.cc | 235 ++---------------- .../internal/confirmations_impl.h | 29 +-- .../confirmations/internal/payout_tokens.cc | 89 +++++-- .../confirmations/internal/payout_tokens.h | 22 +- .../confirmations/internal/refill_tokens.cc | 35 ++- .../confirmations/internal/refill_tokens.h | 7 +- .../bat/confirmations/internal/retry_timer.cc | 54 ++++ .../bat/confirmations/internal/retry_timer.h | 60 +++++ .../confirmations/internal/static_values.h | 10 +- .../src/bat/confirmations/internal/timer.cc | 53 ++++ .../src/bat/confirmations/internal/timer.h | 51 ++++ .../src/bat/ledger/internal/ledger_impl.cc | 4 - 29 files changed, 721 insertions(+), 676 deletions(-) create mode 100644 vendor/bat-native-ads/src/bat/ads/internal/retry_timer.cc create mode 100644 vendor/bat-native-ads/src/bat/ads/internal/retry_timer.h create mode 100644 vendor/bat-native-ads/src/bat/ads/internal/timer.cc create mode 100644 vendor/bat-native-ads/src/bat/ads/internal/timer.h create mode 100644 vendor/bat-native-confirmations/src/bat/confirmations/internal/retry_timer.cc create mode 100644 vendor/bat-native-confirmations/src/bat/confirmations/internal/retry_timer.h create mode 100644 vendor/bat-native-confirmations/src/bat/confirmations/internal/timer.cc create mode 100644 vendor/bat-native-confirmations/src/bat/confirmations/internal/timer.h diff --git a/vendor/bat-native-ads/BUILD.gn b/vendor/bat-native-ads/BUILD.gn index 88850f9eebe8..fc276cb0681c 100644 --- a/vendor/bat-native-ads/BUILD.gn +++ b/vendor/bat-native-ads/BUILD.gn @@ -205,6 +205,8 @@ source_set("ads") { "src/bat/ads/internal/ad_notifications.h", "src/bat/ads/internal/reports.cc", "src/bat/ads/internal/reports.h", + "src/bat/ads/internal/retry_timer.cc", + "src/bat/ads/internal/retry_timer.h", "src/bat/ads/internal/saved_ad.cc", "src/bat/ads/internal/saved_ad.h", "src/bat/ads/internal/search_provider_info.cc", @@ -228,6 +230,8 @@ source_set("ads") { "src/bat/ads/internal/static_values.h", "src/bat/ads/internal/time.cc", "src/bat/ads/internal/time.h", + "src/bat/ads/internal/timer.cc", + "src/bat/ads/internal/timer.h", "src/bat/ads/internal/uri_helper.cc", "src/bat/ads/internal/uri_helper.h", "src/bat/ads/internal/purchase_intent/funnel_site_info.cc", diff --git a/vendor/bat-native-ads/src/bat/ads/internal/ad_conversions.cc b/vendor/bat-native-ads/src/bat/ads/internal/ad_conversions.cc index 09bf5c71c8ff..567af2e7cc70 100644 --- a/vendor/bat-native-ads/src/bat/ads/internal/ad_conversions.cc +++ b/vendor/bat-native-ads/src/bat/ads/internal/ad_conversions.cc @@ -38,7 +38,6 @@ AdConversions::AdConversions( AdsClient* ads_client, Client* client) : is_initialized_(false), - timer_id_(0), ads_(ads), ads_client_(ads_client), client_(client) { @@ -47,9 +46,7 @@ AdConversions::AdConversions( DCHECK(client_); } -AdConversions::~AdConversions() { - StopTimer(); -} +AdConversions::~AdConversions() = default; void AdConversions::Initialize( InitializeCallback callback) { @@ -77,7 +74,7 @@ void AdConversions::Check( void AdConversions::StartTimerIfReady() { DCHECK(is_initialized_); - if (timer_id_ != 0) { + if (timer_.IsRunning()) { return; } @@ -90,25 +87,6 @@ void AdConversions::StartTimerIfReady() { StartTimer(ad_conversion); } -bool AdConversions::OnTimer( - const uint32_t timer_id) { - if (timer_id != timer_id_) { - return false; - } - - timer_id_ = 0; - - DCHECK(!queue_.empty()); - if (queue_.empty()) { - return true; - } - - AdConversionQueueItemInfo ad_conversion = queue_.front(); - ProcessQueueItem(ad_conversion); - - return true; -} - /////////////////////////////////////////////////////////////////////////////// void AdConversions::OnGetAdConversions( @@ -282,28 +260,31 @@ void AdConversions::ProcessQueueItem( StartTimerIfReady(); } +void AdConversions::ProcessQueue() { + if (queue_.empty()) { + return; + } + + AdConversionQueueItemInfo ad_conversion = queue_.front(); + ProcessQueueItem(ad_conversion); +} + void AdConversions::StartTimer( const AdConversionQueueItemInfo& info) { DCHECK(is_initialized_); - DCHECK_EQ(0UL, timer_id_); - - StopTimer(); + DCHECK(!timer_.IsRunning()); const uint64_t now = Time::NowInSeconds(); - uint64_t start_timer_in; + uint64_t delay; if (now < info.timestamp_in_seconds) { - start_timer_in = info.timestamp_in_seconds - now; + delay = info.timestamp_in_seconds - now; } else { - start_timer_in = brave_base::random::Geometric( - kExpiredAdConversionFrequency); + delay = brave_base::random::Geometric(kExpiredAdConversionFrequency); } - timer_id_ = ads_client_->SetTimer(start_timer_in); - if (timer_id_ == 0) { - BLOG(ERROR) << "Failed to start ad conversion timer"; - return; - } + timer_.Start(delay, base::BindOnce(&AdConversions::ProcessQueue, + base::Unretained(this))); BLOG(INFO) << "Started ad conversion timer for creative_instance_id " << info.creative_instance_id << " with creative set id " @@ -311,17 +292,6 @@ void AdConversions::StartTimer( << Time::FromDoubleT(info.timestamp_in_seconds); } -void AdConversions::StopTimer() { - if (timer_id_ == 0) { - return; - } - - BLOG(INFO) << "Stopped ad conversion timer"; - - ads_client_->KillTimer(timer_id_); - timer_id_ = 0; -} - void AdConversions::SaveState() { if (!is_initialized_) { return; diff --git a/vendor/bat-native-ads/src/bat/ads/internal/ad_conversions.h b/vendor/bat-native-ads/src/bat/ads/internal/ad_conversions.h index 01906ab52f7a..846425a63d60 100644 --- a/vendor/bat-native-ads/src/bat/ads/internal/ad_conversions.h +++ b/vendor/bat-native-ads/src/bat/ads/internal/ad_conversions.h @@ -13,6 +13,7 @@ #include "bat/ads/internal/ads_impl.h" #include "bat/ads/internal/client.h" #include "bat/ads/internal/ad_conversion_queue_item_info.h" +#include "bat/ads/internal/timer.h" #include "base/values.h" @@ -37,16 +38,13 @@ class AdConversions { void StartTimerIfReady(); - bool OnTimer( - const uint32_t timer_id); - private: bool is_initialized_; InitializeCallback callback_; AdConversionQueueItemList queue_; - uint32_t timer_id_; + Timer timer_; void OnGetAdConversions( const std::string& url, @@ -71,10 +69,10 @@ class AdConversions { const std::string& creative_instance_id); void ProcessQueueItem( const AdConversionQueueItemInfo& info); + void ProcessQueue(); void StartTimer( const AdConversionQueueItemInfo& info); - void StopTimer(); void SaveState(); void OnStateSaved( diff --git a/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.cc b/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.cc index ec7972e1157f..48d44df1f79a 100644 --- a/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.cc +++ b/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.cc @@ -81,12 +81,10 @@ namespace ads { AdsImpl::AdsImpl(AdsClient* ads_client) : is_foreground_(false), active_tab_id_(0), - collect_activity_timer_id_(0), - delivering_ad_notifications_timer_id_(0), next_easter_egg_timestamp_in_seconds_(0), client_(std::make_unique(this, ads_client)), bundle_(std::make_unique(this, ads_client)), - ads_serve_(std::make_unique(this, ads_client, bundle_.get())), + ads_serve_(std::make_unique(ads_client, bundle_.get())), frequency_capping_(std::make_unique(client_.get())), ad_conversions_(std::make_unique( this, ads_client, client_.get())), @@ -96,16 +94,11 @@ AdsImpl::AdsImpl(AdsClient* ads_client) kPurchaseIntentSignalDecayTimeWindow)), is_initialized_(false), is_confirmations_ready_(false), - sustained_ad_notification_interaction_timer_id_(0), ad_notifications_(std::make_unique(this, ads_client)), ads_client_(ads_client) { } -AdsImpl::~AdsImpl() { - StopCollectingActivity(); - StopDeliveringAdNotifications(); - StopSustainingAdNotificationInteraction(); -} +AdsImpl::~AdsImpl() = default; AdsClient* AdsImpl::get_ads_client() const { return ads_client_; @@ -212,12 +205,6 @@ void AdsImpl::InitializeStep5( } } - if (_is_debug) { - StartCollectingActivity(kDebugOneHourInSeconds); - } else { - StartCollectingActivity(base::Time::kSecondsPerHour); - } - ads_serve_->DownloadCatalog(); } @@ -350,7 +337,7 @@ void AdsImpl::OnBackground() { ads_client_->EventLog(report); if (IsMobile() && !ads_client_->CanShowBackgroundNotifications()) { - StopDeliveringAdNotifications(); + deliver_ad_notification_timer_.Stop(); } } @@ -662,8 +649,7 @@ void AdsImpl::OnPageLoaded( last_sustained_ad_notification_url_)) { last_sustained_ad_notification_url_ = url; - StartSustainingAdNotificationInteraction( - kSustainAdNotificationInteractionAfterSeconds); + StartSustainingAdNotificationInteraction(); } else { BLOG(INFO) << "Already sustaining ad notification interaction for " "visited URL"; @@ -1461,76 +1447,23 @@ bool AdsImpl::IsAllowedToServeAdNotifications() { return is_allowed; } -void AdsImpl::StartCollectingActivity( - const uint64_t start_timer_in) { - StopCollectingActivity(); - - collect_activity_timer_id_ = ads_client_->SetTimer(start_timer_in); - if (collect_activity_timer_id_ == 0) { - BLOG(ERROR) << - "Failed to start collecting activity due to an invalid timer"; - - return; - } - - BLOG(INFO) << "Start collecting activity in " << start_timer_in << " seconds"; -} - -void AdsImpl::CollectActivity() { - if (!IsInitialized()) { - BLOG(WARNING) << "CollectActivity failed as not initialized"; - return; - } - - BLOG(INFO) << "Collect activity"; - - ads_serve_->DownloadCatalog(); -} - -void AdsImpl::StopCollectingActivity() { - if (!IsCollectingActivity()) { - return; - } - - BLOG(INFO) << "Stopped collecting activity"; - - ads_client_->KillTimer(collect_activity_timer_id_); - collect_activity_timer_id_ = 0; -} - -bool AdsImpl::IsCollectingActivity() const { - if (collect_activity_timer_id_ == 0) { - return false; - } - - return true; -} - void AdsImpl::StartDeliveringAdNotifications() { - StopDeliveringAdNotifications(); - auto now_in_seconds = Time::NowInSeconds(); auto next_check_serve_ad_timestamp_in_seconds = client_->GetNextCheckServeAdNotificationTimestampInSeconds(); - uint64_t start_timer_in; + uint64_t delay; if (now_in_seconds >= next_check_serve_ad_timestamp_in_seconds) { // Browser was launched after the next check to serve an ad - start_timer_in = 1 * base::Time::kSecondsPerMinute; + delay = 1 * base::Time::kSecondsPerMinute; } else { - start_timer_in = next_check_serve_ad_timestamp_in_seconds - now_in_seconds; + delay = next_check_serve_ad_timestamp_in_seconds - now_in_seconds; } - delivering_ad_notifications_timer_id_ = ads_client_->SetTimer(start_timer_in); - if (delivering_ad_notifications_timer_id_ == 0) { - BLOG(ERROR) << "Failed to start delivering ad notifications due to an " - "invalid timer"; - - return; - } + const base::Time time = deliver_ad_notification_timer_.Start(delay, + base::BindOnce(&AdsImpl::DeliverAdNotification, base::Unretained(this))); - BLOG(INFO) << "Start delivering ad notifications in " << start_timer_in - << " seconds"; + BLOG(INFO) << "Deliver ad notification at " << time; } void AdsImpl::StartDeliveringAdNotificationsAfterSeconds( @@ -1546,25 +1479,6 @@ void AdsImpl::DeliverAdNotification() { MaybeServeAdNotification(true); } -void AdsImpl::StopDeliveringAdNotifications() { - if (!IsDeliveringAdNotifications()) { - return; - } - - BLOG(INFO) << "Stopped delivering ad notifications"; - - ads_client_->KillTimer(delivering_ad_notifications_timer_id_); - delivering_ad_notifications_timer_id_ = 0; -} - -bool AdsImpl::IsDeliveringAdNotifications() const { - if (delivering_ad_notifications_timer_id_ == 0) { - return false; - } - - return true; -} - bool AdsImpl::IsCatalogOlderThanOneDay() { auto catalog_last_updated_timestamp_in_seconds = bundle_->GetCatalogLastUpdatedTimestampInSeconds(); @@ -1580,10 +1494,6 @@ bool AdsImpl::IsCatalogOlderThanOneDay() { return false; } -void AdsImpl::BundleUpdated() { - ads_serve_->UpdateNextCatalogCheck(); -} - void AdsImpl::MaybeServeAdNotification( const bool should_serve) { auto ok = ads_client_->ShouldShowNotifications(); @@ -1631,21 +1541,14 @@ void AdsImpl::set_last_shown_ad_notification( last_shown_ad_notification_ = info; } -void AdsImpl::StartSustainingAdNotificationInteraction( - const uint64_t start_timer_in) { - StopSustainingAdNotificationInteraction(); - - sustained_ad_notification_interaction_timer_id_ = - ads_client_->SetTimer(start_timer_in); - if (sustained_ad_notification_interaction_timer_id_ == 0) { - BLOG(ERROR) << "Failed to start sustaining ad notification interaction due " - "to an invalid timer"; +void AdsImpl::StartSustainingAdNotificationInteraction() { + const uint64_t delay = kSustainAdNotificationInteractionAfterSeconds; - return; - } + const base::Time time = sustain_ad_notification_interaction_timer_.Start( + delay, base::BindOnce(&AdsImpl::SustainAdNotificationInteractionIfNeeded, + base::Unretained(this))); - BLOG(INFO) << "Start sustaining ad notification interaction in " - << start_timer_in << " seconds"; + BLOG(INFO) << "Sustain ad notification interaction at " << time; } void AdsImpl::SustainAdNotificationInteractionIfNeeded() { @@ -1664,27 +1567,6 @@ void AdsImpl::SustainAdNotificationInteractionIfNeeded() { ConfirmAd(last_shown_ad_notification_, ConfirmationType::kLanded); } -void AdsImpl::StopSustainingAdNotificationInteraction() { - if (!IsSustainingAdNotificationInteraction()) { - return; - } - - BLOG(INFO) << "Stopped sustaining ad notification interaction"; - - ads_client_->KillTimer(sustained_ad_notification_interaction_timer_id_); - sustained_ad_notification_interaction_timer_id_ = 0; - - last_sustained_ad_notification_url_ = ""; -} - -bool AdsImpl::IsSustainingAdNotificationInteraction() const { - if (sustained_ad_notification_interaction_timer_id_ == 0) { - return false; - } - - return true; -} - bool AdsImpl::IsStillViewingAdNotification() const { return helper::Uri::MatchesDomainOrHost(active_tab_url_, last_shown_ad_notification_.target_url); @@ -1729,25 +1611,7 @@ void AdsImpl::ConfirmAction( void AdsImpl::OnTimer( const uint32_t timer_id) { BLOG(INFO) << "OnTimer: " << std::endl - << " timer_id: " << std::to_string(timer_id) << std::endl - << " collect_activity_timer_id_: " - << std::to_string(collect_activity_timer_id_) << std::endl - << " delivering_ad_notifications_timer_id_: " - << std::to_string(delivering_ad_notifications_timer_id_) << std::endl - << " sustained_ad_notification_interaction_timer_id_: " - << std::to_string(sustained_ad_notification_interaction_timer_id_); - - if (timer_id == collect_activity_timer_id_) { - CollectActivity(); - } else if (timer_id == delivering_ad_notifications_timer_id_) { - DeliverAdNotification(); - } else if (timer_id == sustained_ad_notification_interaction_timer_id_) { - SustainAdNotificationInteractionIfNeeded(); - } else if (ad_conversions_->OnTimer(timer_id)) { - return; - } else { - BLOG(WARNING) << "Unexpected OnTimer: " << std::to_string(timer_id); - } + << " timer_id: " << timer_id; } void AdsImpl::AppendAdNotificationToHistory( diff --git a/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.h b/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.h index 82abcb0710fd..ea10630a375c 100644 --- a/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.h +++ b/vendor/bat-native-ads/src/bat/ads/internal/ads_impl.h @@ -24,6 +24,7 @@ #include "bat/ads/internal/ad_conversions.h" #include "bat/ads/internal/ad_notification_result_type.h" #include "bat/ads/internal/ad_notifications.h" +#include "bat/ads/internal/timer.h" #include "bat/usermodel/user_model.h" #include "bat/ads/internal/purchase_intent/purchase_intent_classifier.h" @@ -236,20 +237,11 @@ class AdsImpl : public Ads { const CreativeAdNotificationInfo& info); bool IsAllowedToServeAdNotifications(); - uint32_t collect_activity_timer_id_; - void StartCollectingActivity( - const uint64_t start_timer_in); - void CollectActivity(); - void StopCollectingActivity(); - bool IsCollectingActivity() const; - - uint32_t delivering_ad_notifications_timer_id_; + Timer deliver_ad_notification_timer_; void StartDeliveringAdNotifications(); void StartDeliveringAdNotificationsAfterSeconds( const uint64_t seconds); void DeliverAdNotification(); - void StopDeliveringAdNotifications(); - bool IsDeliveringAdNotifications() const; bool IsCatalogOlderThanOneDay(); #if defined(OS_ANDROID) @@ -257,8 +249,6 @@ class AdsImpl : public Ads { void RemoveAllAdNotificationsAfterUpdate(); #endif - void BundleUpdated(); - const AdNotificationInfo& get_last_shown_ad_notification() const; void set_last_shown_ad_notification( const AdNotificationInfo& info); @@ -302,13 +292,10 @@ class AdsImpl : public Ads { AdNotificationInfo last_shown_ad_notification_; CreativeAdNotificationInfo last_shown_creative_ad_notification_; - uint32_t sustained_ad_notification_interaction_timer_id_; + Timer sustain_ad_notification_interaction_timer_; std::string last_sustained_ad_notification_url_; - void StartSustainingAdNotificationInteraction( - const uint64_t start_timer_in); + void StartSustainingAdNotificationInteraction(); void SustainAdNotificationInteractionIfNeeded(); - void StopSustainingAdNotificationInteraction(); - bool IsSustainingAdNotificationInteraction() const; bool IsStillViewingAdNotification() const; std::unique_ptr ad_notifications_; diff --git a/vendor/bat-native-ads/src/bat/ads/internal/ads_serve.cc b/vendor/bat-native-ads/src/bat/ads/internal/ads_serve.cc index 8c8666e88811..43979c4d3495 100644 --- a/vendor/bat-native-ads/src/bat/ads/internal/ads_serve.cc +++ b/vendor/bat-native-ads/src/bat/ads/internal/ads_serve.cc @@ -11,7 +11,6 @@ #include "bat/ads/internal/logging.h" #include "base/time/time.h" -#include "brave_base/random.h" using std::placeholders::_1; using std::placeholders::_2; @@ -19,19 +18,53 @@ using std::placeholders::_3; namespace ads { -AdsServe::AdsServe(AdsImpl* ads, AdsClient* ads_client, Bundle* bundle) : - url_(""), - next_catalog_check_timestamp_in_seconds(0), - next_retry_start_timer_in_(0), - catalog_last_updated_(0), - ads_(ads), - ads_client_(ads_client), - bundle_(bundle) { +AdsServe::AdsServe( + AdsClient* ads_client, + Bundle* bundle) + : catalog_last_updated_(0), + ads_client_(ads_client), + bundle_(bundle) { BuildUrl(); } AdsServe::~AdsServe() = default; +void AdsServe::DownloadCatalog() { + if (retry_timer_.IsRunning()) { + return; + } + + BLOG(INFO) << "Download catalog"; + + auto callback = std::bind(&AdsServe::OnCatalogDownloaded, + this, url_, _1, _2, _3); + + ads_client_->URLRequest(url_, {}, "", "", URLRequestMethod::GET, callback); +} + +void AdsServe::DownloadCatalogAfterDelay() { + const uint64_t delay = _is_debug ? kDebugCatalogPing : + bundle_->GetCatalogPing(); + + const base::Time time = timer_.StartWithPrivacy(delay, + base::BindOnce(&AdsServe::DownloadCatalog, base::Unretained(this))); + + BLOG(INFO) << "Download catalog at " << time; +} + +uint64_t AdsServe::CatalogLastUpdated() const { + return catalog_last_updated_; +} + +void AdsServe::Reset() { + timer_.Stop(); + retry_timer_.Stop(); + + ResetCatalog(); +} + +////////////////////////////////////////////////////////////////////////////// + void AdsServe::BuildUrl() { switch (_environment) { case Environment::PRODUCTION: { @@ -53,13 +86,6 @@ void AdsServe::BuildUrl() { url_ += CATALOG_PATH; } -void AdsServe::DownloadCatalog() { - auto callback = std::bind(&AdsServe::OnCatalogDownloaded, - this, url_, _1, _2, _3); - - ads_client_->URLRequest(url_, {}, "", "", URLRequestMethod::GET, callback); -} - void AdsServe::OnCatalogDownloaded( const std::string& url, const int response_status_code, @@ -76,9 +102,7 @@ void AdsServe::OnCatalogDownloaded( should_retry = true; } } else if (response_status_code == 304) { - BLOG(INFO) << "Catalog is already up to dates"; - - UpdateNextCatalogCheck(); + BLOG(INFO) << "Catalog is up to date"; } else { std::string formatted_headers = ""; for (auto header = headers.begin(); header != headers.end(); ++header) { @@ -101,45 +125,12 @@ void AdsServe::OnCatalogDownloaded( RetryDownloadingCatalog(); return; } -} -uint64_t AdsServe::CatalogLastUpdated() const { - return catalog_last_updated_; -} - -void AdsServe::Reset() { - ads_->StopCollectingActivity(); - - next_retry_start_timer_in_ = 0; + retry_timer_.Stop(); - next_catalog_check_timestamp_in_seconds = 0; - - ResetCatalog(); + DownloadCatalogAfterDelay(); } -void AdsServe::UpdateNextCatalogCheck() { - next_retry_start_timer_in_ = 0; - - uint64_t ping; - if (_is_debug) { - ping = kDebugCatalogPing; - } else { - ping = bundle_->GetCatalogPing(); - } - - // Choose a geometrically distributed number of seconds so that from - // the server's perspective, at any given time, every client has the - // same distribution on when its next check will be, so knowing - // which client made the last one when reveals nothing about which - // client will make the next one. - auto rand_delay = brave_base::random::Geometric(ping); - next_catalog_check_timestamp_in_seconds = rand_delay; - - ads_->StartCollectingActivity(next_catalog_check_timestamp_in_seconds); -} - -////////////////////////////////////////////////////////////////////////////// - bool AdsServe::ProcessCatalog(const std::string& json) { // TODO(Terry Mancey): Refactor function to use callbacks @@ -157,8 +148,6 @@ bool AdsServe::ProcessCatalog(const std::string& json) { BLOG(WARNING) << "Catalog id " << catalog.GetId() << " matches current catalog id " << bundle_->GetCatalogId(); - UpdateNextCatalogCheck(); - return true; } @@ -181,8 +170,8 @@ bool AdsServe::ProcessCatalog(const std::string& json) { void AdsServe::OnCatalogSaved(const Result result) { if (result != SUCCESS) { - // If the catalog fails to save, we will retry the next time we collect - // activity + // If the catalog fails to save, we will retry the next time we download the + // catalog BLOG(ERROR) << "Failed to save catalog"; @@ -193,22 +182,11 @@ void AdsServe::OnCatalogSaved(const Result result) { } void AdsServe::RetryDownloadingCatalog() { - BLOG(INFO) << "Retry downloading catalog"; - - if (next_retry_start_timer_in_ == 0) { - if (ads_->IsMobile()) { - next_retry_start_timer_in_ = 2 * base::Time::kSecondsPerMinute; - } else { - next_retry_start_timer_in_ = base::Time::kSecondsPerMinute; - } - } else { - next_retry_start_timer_in_ *= 2; - } - - auto rand_delay = brave_base::random::Geometric(next_retry_start_timer_in_); - next_retry_start_timer_in_ = rand_delay; + const base::Time time = retry_timer_.StartWithBackoff( + kRetryDownloadingCatalogAfterSeconds, + base::BindOnce(&AdsServe::DownloadCatalog, base::Unretained(this))); - ads_->StartCollectingActivity(next_retry_start_timer_in_); + BLOG(INFO) << "Retry downloading catalog at " << time; } void AdsServe::ResetCatalog() { diff --git a/vendor/bat-native-ads/src/bat/ads/internal/ads_serve.h b/vendor/bat-native-ads/src/bat/ads/internal/ads_serve.h index 53c74074a880..a8197818f206 100644 --- a/vendor/bat-native-ads/src/bat/ads/internal/ads_serve.h +++ b/vendor/bat-native-ads/src/bat/ads/internal/ads_serve.h @@ -14,6 +14,8 @@ #include "bat/ads/ads_client.h" #include "bat/ads/internal/ads_impl.h" +#include "bat/ads/internal/timer.h" +#include "bat/ads/internal/retry_timer.h" namespace ads { @@ -23,15 +25,15 @@ class Bundle; class AdsServe { public: AdsServe( - AdsImpl* ads, AdsClient* ads_client, Bundle* bundle); ~AdsServe(); void DownloadCatalog(); + void DownloadCatalogAfterDelay(); + uint64_t CatalogLastUpdated() const; - void UpdateNextCatalogCheck(); void Reset(); @@ -39,24 +41,26 @@ class AdsServe { std::string url_; void BuildUrl(); - uint64_t next_catalog_check_timestamp_in_seconds; - + Timer timer_; void OnCatalogDownloaded( const std::string& url, const int response_status_code, const std::string& response, const std::map& headers); - bool ProcessCatalog(const std::string& json); - void OnCatalogSaved(const Result result); + bool ProcessCatalog( + const std::string& json); + void OnCatalogSaved( + const Result result); - uint64_t next_retry_start_timer_in_; + RetryTimer retry_timer_; void RetryDownloadingCatalog(); + uint64_t catalog_last_updated_; void ResetCatalog(); - void OnCatalogReset(const Result result); + void OnCatalogReset( + const Result result); - AdsImpl* ads_; // NOT OWNED AdsClient* ads_client_; // NOT OWNED Bundle* bundle_; // NOT OWNED }; diff --git a/vendor/bat-native-ads/src/bat/ads/internal/bundle.cc b/vendor/bat-native-ads/src/bat/ads/internal/bundle.cc index 094bca0f025c..bc41a4cd279e 100644 --- a/vendor/bat-native-ads/src/bat/ads/internal/bundle.cc +++ b/vendor/bat-native-ads/src/bat/ads/internal/bundle.cc @@ -45,10 +45,15 @@ bool Bundle::UpdateFromCatalog( return false; } + catalog_id_ = bundle_state->catalog_id; + catalog_version_ = bundle_state->catalog_version; + catalog_ping_ = bundle_state->catalog_ping; + catalog_last_updated_timestamp_in_seconds_ = + bundle_state->catalog_last_updated_timestamp_in_seconds; + auto callback = std::bind(&Bundle::OnStateSaved, - this, bundle_state->catalog_id, bundle_state->catalog_version, - bundle_state->catalog_ping, - bundle_state->catalog_last_updated_timestamp_in_seconds, _1); + this, catalog_id_, catalog_version_, catalog_ping_, + catalog_last_updated_timestamp_in_seconds_, _1); ads_client_->SaveBundleState(std::move(bundle_state), callback); BLOG(INFO) << "Generated bundle"; @@ -258,14 +263,6 @@ void Bundle::OnStateSaved( return; } - catalog_id_ = catalog_id; - catalog_version_ = catalog_version; - catalog_ping_ = catalog_ping; - catalog_last_updated_timestamp_in_seconds_ = - catalog_last_updated_timestamp_in_seconds; - - ads_->BundleUpdated(); - BLOG(INFO) << "Successfully saved bundle state"; } diff --git a/vendor/bat-native-ads/src/bat/ads/internal/retry_timer.cc b/vendor/bat-native-ads/src/bat/ads/internal/retry_timer.cc new file mode 100644 index 000000000000..5b1e3f11193a --- /dev/null +++ b/vendor/bat-native-ads/src/bat/ads/internal/retry_timer.cc @@ -0,0 +1,54 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "bat/ads/internal/retry_timer.h" + +namespace ads { + +RetryTimer::RetryTimer() = default; + +RetryTimer::~RetryTimer() = default; + +base::Time RetryTimer::Start( + const uint64_t delay, + base::OnceClosure user_task) { + timer_.Stop(); + + const base::Time time = timer_.StartWithPrivacy(delay, std::move(user_task)); + + return time; +} + +base::Time RetryTimer::StartWithBackoff( + const uint64_t delay, + base::OnceClosure user_task) { + uint64_t backoff_delay = delay; + + backoff_delay <<= backoff_count_++; + if (backoff_delay > max_backoff_delay_) { + backoff_delay = max_backoff_delay_; + } + + return Start(backoff_delay, std::move(user_task)); +} + +bool RetryTimer::IsRunning() const { + return timer_.IsRunning(); +} + +void RetryTimer::Stop() { + timer_.Stop(); + + backoff_count_ = 0; +} + +void RetryTimer::set_max_backoff_delay( + const uint64_t max_delay) { + max_backoff_delay_ = max_delay; +} + +} // namespace ads diff --git a/vendor/bat-native-ads/src/bat/ads/internal/retry_timer.h b/vendor/bat-native-ads/src/bat/ads/internal/retry_timer.h new file mode 100644 index 000000000000..95fedad7a537 --- /dev/null +++ b/vendor/bat-native-ads/src/bat/ads/internal/retry_timer.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BAT_ADS_INTERNAL_RETRY_TIMER_H_ +#define BAT_ADS_INTERNAL_RETRY_TIMER_H_ + +#include + +#include "bat/ads/internal/timer.h" + +#include "base/bind.h" +#include "base/time/time.h" + +namespace ads { + +class RetryTimer { + public: + RetryTimer(); + + ~RetryTimer(); + + // Start a timer to run at a geometrically distributed number of seconds + // |~delay| from now. If the timer is already running, it will be replaced to + // call the given |user_task|. Returns the time the delayed task will be fired + base::Time Start( + const uint64_t delay, + base::OnceClosure user_task); + + // Start a timer to run at a geometrically distributed number of seconds + // |~delay| from now backing off exponentially for each call. If the timer is + // already running, it will be replaced to call the given |user_task|. Returns + // the time the delayed task will be fired + base::Time StartWithBackoff( + const uint64_t delay, + base::OnceClosure user_task); + + // Returns true if the timer is running (i.e., not stopped) + bool IsRunning() const; + + // Call this method to stop the timer if running and to reset the exponential + // backoff delay + void Stop(); + + // Optionally call this method to set the maximum backoff delay to + // |max_delay|. Default maximum backoff delay is 1 hour + void set_max_backoff_delay( + const uint64_t max_delay); + + private: + Timer timer_; + + uint64_t backoff_count_ = 0; + uint64_t max_backoff_delay_ = base::Time::kSecondsPerHour; +}; + +} // namespace ads + +#endif // BAT_ADS_INTERNAL_RETRY_TIMER_H_ diff --git a/vendor/bat-native-ads/src/bat/ads/internal/static_values.h b/vendor/bat-native-ads/src/bat/ads/internal/static_values.h index d1194c53969f..23d8faf9888a 100644 --- a/vendor/bat-native-ads/src/bat/ads/internal/static_values.h +++ b/vendor/bat-native-ads/src/bat/ads/internal/static_values.h @@ -32,7 +32,7 @@ const uint64_t kMaximumEntriesInAdsShownHistory = 7 * (20 * 4); const uint64_t kMaximumEntriesPerSegmentInPurchaseIntentSignalHistory = 100; -const uint64_t kDebugOneHourInSeconds = 25; +const uint64_t kDebugOneHourInSeconds = 10 * base::Time::kSecondsPerMinute; const char kEasterEggUrl[] = "https://iab.com"; const uint64_t kNextEasterEggStartsInSeconds = 30; @@ -62,6 +62,9 @@ const uint16_t kPurchaseIntentMaxSegments = 3; const int kDoNotDisturbFromHour = 21; // 9pm const int kDoNotDisturbToHour = 6; // 6am +const uint64_t kRetryDownloadingCatalogAfterSeconds = + 1 * base::Time::kSecondsPerMinute; + const std::map> kSupportedRegionsSchemas = { // Append newly supported regions with a new schema version and update // |kSupportedRegionsSchemaVersionNumber| to match the new version diff --git a/vendor/bat-native-ads/src/bat/ads/internal/timer.cc b/vendor/bat-native-ads/src/bat/ads/internal/timer.cc new file mode 100644 index 000000000000..f2476c6507b6 --- /dev/null +++ b/vendor/bat-native-ads/src/bat/ads/internal/timer.cc @@ -0,0 +1,53 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "bat/ads/internal/timer.h" + +#include "brave_base/random.h" + +namespace ads { + +Timer::Timer() = default; + +Timer::~Timer() { + Stop(); +} + +base::Time Timer::Start( + const uint64_t delay, + base::OnceClosure user_task) { + Stop(); + + timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay), + std::move(user_task)); + + const base::Time time = + base::Time::Now() + base::TimeDelta::FromSeconds(delay); + + return time; +} + +base::Time Timer::StartWithPrivacy( + const uint64_t delay, + base::OnceClosure user_task) { + const uint64_t rand_delay = brave_base::random::Geometric(delay); + return Start(rand_delay, std::move(user_task)); +} + +bool Timer::IsRunning() const { + return timer_.IsRunning(); +} + +void Timer::Stop() { + if (!IsRunning()) { + return; + } + + timer_.Stop(); +} + +} // namespace ads diff --git a/vendor/bat-native-ads/src/bat/ads/internal/timer.h b/vendor/bat-native-ads/src/bat/ads/internal/timer.h new file mode 100644 index 000000000000..e7b812da5243 --- /dev/null +++ b/vendor/bat-native-ads/src/bat/ads/internal/timer.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BAT_ADS_INTERNAL_TIMER_H_ +#define BAT_ADS_INTERNAL_TIMER_H_ + +#include + +#include "base/bind.h" +#include "base/time/time.h" +#include "base/timer/timer.h" + +namespace ads { + +class Timer { + public: + Timer(); + + ~Timer(); + + // Start a timer to run at the given |delay| from now. If the timer is already + // running, it will be replaced to call the given |user_task|. Returns the + // time the delayed task will be fired + base::Time Start( + const uint64_t delay, + base::OnceClosure user_task); + + // Start a timer to run at a geometrically distributed number of seconds + // |~delay| from now for privacy-focused events. If the timer is already + // running, it will be replaced to call the given |user_task|. Returns the + // time the delayed task will be fired + base::Time StartWithPrivacy( + const uint64_t delay, + base::OnceClosure user_task); + + // Returns true if the timer is running (i.e., not stopped) + bool IsRunning() const; + + // Call this method to stop the timer. It is a no-op if the timer is not + // running + void Stop(); + + private: + base::OneShotTimer timer_; +}; + +} // namespace ads + +#endif // BAT_ADS_INTERNAL_TIMER_H_ diff --git a/vendor/bat-native-confirmations/BUILD.gn b/vendor/bat-native-confirmations/BUILD.gn index 19449991e272..7921929eb14f 100644 --- a/vendor/bat-native-confirmations/BUILD.gn +++ b/vendor/bat-native-confirmations/BUILD.gn @@ -88,12 +88,16 @@ source_set("bat-native-confirmations") { "src/bat/confirmations/internal/refill_tokens.h", "src/bat/confirmations/internal/request_signed_tokens_request.cc", "src/bat/confirmations/internal/request_signed_tokens_request.h", + "src/bat/confirmations/internal/retry_timer.cc", + "src/bat/confirmations/internal/retry_timer.h", "src/bat/confirmations/internal/security_helper.cc", "src/bat/confirmations/internal/security_helper.h", "src/bat/confirmations/internal/string_helper.cc", "src/bat/confirmations/internal/string_helper.h", "src/bat/confirmations/internal/time.cc", "src/bat/confirmations/internal/time.h", + "src/bat/confirmations/internal/timer.cc", + "src/bat/confirmations/internal/timer.h", "src/bat/confirmations/internal/token_info.cc", "src/bat/confirmations/internal/token_info.h", "src/bat/confirmations/internal/unblinded_tokens.cc", diff --git a/vendor/bat-native-confirmations/include/bat/confirmations/confirmations.h b/vendor/bat-native-confirmations/include/bat/confirmations/confirmations.h index 0917e05c0113..eec8262df4dc 100644 --- a/vendor/bat-native-confirmations/include/bat/confirmations/confirmations.h +++ b/vendor/bat-native-confirmations/include/bat/confirmations/confirmations.h @@ -89,12 +89,6 @@ class CONFIRMATIONS_EXPORT Confirmations { virtual void UpdateAdsRewards( const bool should_refresh) = 0; - // Should be called when the timer specified by |timer_id| should be - // triggered. Returns |true| if the timer was successfully triggered; - // otherwise, should return |false| - virtual bool OnTimer( - const uint32_t timer_id) = 0; - private: // Not copyable, not assignable Confirmations(const Confirmations&) = delete; diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/ads_rewards.cc b/vendor/bat-native-confirmations/src/bat/confirmations/internal/ads_rewards.cc index ebe8462d568f..d71a21b10711 100644 --- a/vendor/bat-native-confirmations/src/bat/confirmations/internal/ads_rewards.cc +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/ads_rewards.cc @@ -10,6 +10,7 @@ #include "bat/confirmations/internal/confirmations_impl.h" #include "bat/confirmations/internal/get_payment_balance_request.h" #include "bat/confirmations/internal/get_ad_grants_request.h" +#include "bat/confirmations/internal/static_values.h" #include "net/http/http_status_code.h" #include "brave_base/random.h" @@ -23,17 +24,13 @@ namespace confirmations { AdsRewards::AdsRewards( ConfirmationsImpl* confirmations, ConfirmationsClient* confirmations_client) : - next_retry_backoff_count_(0), - retry_timer_id_(0), payments_(std::make_unique(confirmations, confirmations_client)), ad_grants_(std::make_unique(confirmations, confirmations_client)), confirmations_(confirmations), confirmations_client_(confirmations_client) { } -AdsRewards::~AdsRewards() { - CancelRetry(); -} +AdsRewards::~AdsRewards() = default; void AdsRewards::Update( const WalletInfo& wallet_info, @@ -49,7 +46,9 @@ void AdsRewards::Update( return; } - CancelRetry(); + if (retry_timer_.IsRunning()) { + return; + } BLOG(INFO) << "Fetch ads rewards"; GetPaymentBalance(); @@ -94,20 +93,6 @@ bool AdsRewards::SetFromDictionary(base::DictionaryValue* dictionary) { return success; } -bool AdsRewards::OnTimer(const uint32_t timer_id) { - BLOG(INFO) << "OnTimer: " << std::endl - << " timer_id: " << std::to_string(timer_id) << std::endl - << " retry_timer_id_: " << std::to_string(retry_timer_id_) << std::endl; - - if (timer_id == retry_timer_id_) { - GetPaymentBalance(); - - return true; - } - - return false; -} - /////////////////////////////////////////////////////////////////////////////// void AdsRewards::GetPaymentBalance() { @@ -232,54 +217,27 @@ void AdsRewards::OnGetAdGrants( void AdsRewards::OnAdsRewards(const Result result) { if (result != SUCCESS) { BLOG(ERROR) << "Failed to retrieve ads rewards"; - Retry(); - return; - } - BLOG(INFO) << "Successfully retrieved ads rewards"; + const base::Time time = retry_timer_.StartWithBackoff( + kRetryAdsRewardsAfterSeconds, base::BindOnce(&AdsRewards::OnRetry, + base::Unretained(this))); - retry_timer_id_ = 0; - next_retry_backoff_count_ = 0; + BLOG(INFO) << "Retry getting ad grants at " << time; - Update(); -} - -void AdsRewards::Retry() { - // Overflow happens only if we have already backed off so many times our - // expected waiting time is longer than the lifetime of the universe - auto start_timer_in = 1 * base::Time::kSecondsPerMinute; - start_timer_in <<= next_retry_backoff_count_++; - - auto rand_delay = brave_base::random::Geometric(start_timer_in); - - confirmations_client_->SetTimer(rand_delay, &retry_timer_id_); - if (retry_timer_id_ == 0) { - BLOG(ERROR) << "Failed to retry due to an invalid timer"; return; } - BLOG(INFO) << "Start retrying in " << rand_delay << " seconds"; -} - -void AdsRewards::CancelRetry() { - if (!IsRetrying()) { - return; - } - - BLOG(INFO) << "Cancelled retry"; + BLOG(INFO) << "Successfully retrieved ads rewards"; - confirmations_client_->KillTimer(retry_timer_id_); - retry_timer_id_ = 0; + retry_timer_.Stop(); - next_retry_backoff_count_ = 0; + Update(); } -bool AdsRewards::IsRetrying() const { - if (retry_timer_id_ == 0) { - return false; - } +void AdsRewards::OnRetry() { + BLOG(INFO) << "Retrying"; - return true; + GetPaymentBalance(); } void AdsRewards::Update() { diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/ads_rewards.h b/vendor/bat-native-confirmations/src/bat/confirmations/internal/ads_rewards.h index 076b86ed2b9a..a662532b961d 100644 --- a/vendor/bat-native-confirmations/src/bat/confirmations/internal/ads_rewards.h +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/ads_rewards.h @@ -6,7 +6,6 @@ #ifndef BAT_CONFIRMATIONS_INTERNAL_ADS_REWARDS_H_ #define BAT_CONFIRMATIONS_INTERNAL_ADS_REWARDS_H_ -#include #include #include #include @@ -15,6 +14,7 @@ #include "bat/confirmations/wallet_info.h" #include "bat/confirmations/internal/payments.h" #include "bat/confirmations/internal/ad_grants.h" +#include "bat/confirmations/internal/retry_timer.h" #include "base/values.h" @@ -35,8 +35,6 @@ class AdsRewards { base::Value GetAsDictionary(); bool SetFromDictionary(base::DictionaryValue* dictionary); - bool OnTimer(const uint32_t timer_id); - private: WalletInfo wallet_info_; @@ -57,11 +55,8 @@ class AdsRewards { void OnAdsRewards( const Result result); - uint64_t next_retry_backoff_count_; - uint32_t retry_timer_id_; - void Retry(); - void CancelRetry(); - bool IsRetrying() const; + RetryTimer retry_timer_; + void OnRetry(); void Update(); double CalculateEstimatedPendingRewards() const; diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/confirmations_impl.cc b/vendor/bat-native-confirmations/src/bat/confirmations/internal/confirmations_impl.cc index 116bef93f036..d010db66c246 100644 --- a/vendor/bat-native-confirmations/src/bat/confirmations/internal/confirmations_impl.cc +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/confirmations_impl.cc @@ -31,30 +31,22 @@ namespace confirmations { ConfirmationsImpl::ConfirmationsImpl( ConfirmationsClient* confirmations_client) : is_initialized_(false), - retry_failed_confirmations_timer_id_(0), unblinded_tokens_(std::make_unique(this)), unblinded_payment_tokens_(std::make_unique(this)), estimated_pending_rewards_(0.0), next_payment_date_in_seconds_(0), ads_rewards_(std::make_unique(this, confirmations_client)), - retry_getting_signed_tokens_timer_id_(0), refill_tokens_(std::make_unique( this, confirmations_client, unblinded_tokens_.get())), redeem_token_(std::make_unique(this, confirmations_client, unblinded_tokens_.get(), unblinded_payment_tokens_.get())), - payout_redeemed_tokens_timer_id_(0), payout_tokens_(std::make_unique(this, confirmations_client, unblinded_payment_tokens_.get())), - next_token_redemption_date_in_seconds_(0), state_has_loaded_(false), confirmations_client_(confirmations_client) { } -ConfirmationsImpl::~ConfirmationsImpl() { - StopRetryingToGetRefillSignedTokens(); - StopRetryingFailedConfirmations(); - StopPayingOutRedeemedTokens(); -} +ConfirmationsImpl::~ConfirmationsImpl() = default; void ConfirmationsImpl::Initialize( OnInitializeCallback callback) { @@ -84,8 +76,7 @@ void ConfirmationsImpl::MaybeStart() { is_initialized_ = true; BLOG(INFO) << "Successfully initialized confirmations"; - auto start_timer_in = CalculateTokenRedemptionTimeInSeconds(); - StartPayingOutRedeemedTokens(start_timer_in); + payout_tokens_->PayoutAfterDelay(wallet_info_); RefillTokensIfNecessary(); @@ -110,8 +101,10 @@ std::string ConfirmationsImpl::ToJSON() const { dictionary.SetKey("catalog_issuers", base::Value(std::move(catalog_issuers))); // Next token redemption date + auto token_redemption_timestamp_in_seconds = + GetNextTokenRedemptionDateInSeconds(); dictionary.SetKey("next_token_redemption_date_in_seconds", base::Value( - std::to_string(next_token_redemption_date_in_seconds_))); + std::to_string(token_redemption_timestamp_in_seconds))); // Confirmations auto confirmations = GetConfirmationsAsDictionary(confirmations_); @@ -397,8 +390,8 @@ bool ConfirmationsImpl::ParseNextTokenRedemptionDateInSecondsFromJSON( auto next_token_redemption_date_in_seconds = std::stoull(next_token_redemption_date_in_seconds_value->GetString()); - next_token_redemption_date_in_seconds_ = - Time::MigrateTimestampToDoubleT(next_token_redemption_date_in_seconds); + payout_tokens_->set_token_redemption_timestamp_in_seconds( + Time::MigrateTimestampToDoubleT(next_token_redemption_date_in_seconds)); return true; } @@ -907,9 +900,7 @@ void ConfirmationsImpl::AppendConfirmationToQueue( << " creative instance id for " << std::string(confirmation_info.type) << " to the confirmations queue"; - if (!IsRetryingFailedConfirmations()) { - StartRetryingFailedConfirmations(); - } + StartRetryingFailedConfirmations(); } void ConfirmationsImpl::RemoveConfirmationFromQueue( @@ -1168,121 +1159,31 @@ void ConfirmationsImpl::ConfirmAction( confirmation_type); } -bool ConfirmationsImpl::OnTimer(const uint32_t timer_id) { - DCHECK(state_has_loaded_); - if (!state_has_loaded_) { - BLOG(ERROR) << - "Unable to trigger event as Confirmations state is not ready"; - return false; - } - - if (!is_initialized_) { - return false; - } - - BLOG(INFO) << "OnTimer:" << std::endl - << " timer_id: " - << timer_id << std::endl - << " retry_getting_signed_tokens_timer_id_: " - << retry_getting_signed_tokens_timer_id_ << std::endl - << " payout_redeemed_tokens_timer_id_: " - << payout_redeemed_tokens_timer_id_; - - if (timer_id == retry_getting_signed_tokens_timer_id_) { - RetryGettingRefillSignedTokens(); - return true; - } else if (timer_id == retry_failed_confirmations_timer_id_) { - RetryFailedConfirmations(); - return true; - } else if (timer_id == payout_redeemed_tokens_timer_id_) { - PayoutRedeemedTokens(); - return true; - } - - return ads_rewards_->OnTimer(timer_id); -} - void ConfirmationsImpl::RefillTokensIfNecessary() const { DCHECK(wallet_info_.IsValid()); refill_tokens_->Refill(wallet_info_, public_key_); } -uint64_t ConfirmationsImpl::CalculateTokenRedemptionTimeInSeconds() { - DCHECK(state_has_loaded_); - - if (next_token_redemption_date_in_seconds_ == 0) { - UpdateNextTokenRedemptionDate(); - } - - auto now_in_seconds = Time::NowInSeconds(); - - uint64_t start_timer_in; - if (now_in_seconds >= next_token_redemption_date_in_seconds_) { - // Browser was launched after the token redemption date - start_timer_in = 1 * base::Time::kSecondsPerMinute; - } else { - start_timer_in = next_token_redemption_date_in_seconds_ - now_in_seconds; - } - - auto rand_delay = brave_base::random::Geometric(start_timer_in); - start_timer_in = rand_delay; - - return start_timer_in; -} - -uint64_t ConfirmationsImpl::GetNextTokenRedemptionDateInSeconds() { - DCHECK(state_has_loaded_); - - return next_token_redemption_date_in_seconds_; -} - -void ConfirmationsImpl::UpdateNextTokenRedemptionDate() { - DCHECK(state_has_loaded_); - - next_token_redemption_date_in_seconds_ = Time::NowInSeconds(); - - if (!_is_debug) { - next_token_redemption_date_in_seconds_ += - kNextTokenRedemptionAfterSeconds; - } else { - next_token_redemption_date_in_seconds_ += - kDebugNextTokenRedemptionAfterSeconds; - } - - SaveState(); +uint64_t ConfirmationsImpl::GetNextTokenRedemptionDateInSeconds() const { + return payout_tokens_->get_token_redemption_timestamp_in_seconds(); } void ConfirmationsImpl::StartRetryingFailedConfirmations() { - auto start_timer_in = - brave_base::random::Geometric(kRetryFailedConfirmationsAfterSeconds); - - StartRetryingFailedConfirmations(start_timer_in); -} - -void ConfirmationsImpl::StartRetryingFailedConfirmations( - const uint64_t start_timer_in) { - StopRetryingFailedConfirmations(); - - confirmations_client_->SetTimer(start_timer_in, - &retry_failed_confirmations_timer_id_); - if (retry_failed_confirmations_timer_id_ == 0) { - BLOG(ERROR) << "Failed to start retrying failed confirmations " - << "due to an invalid timer"; - + if (failed_confirmations_timer_.IsRunning()) { return; } - BLOG(INFO) << "Start retrying failed confirmations in " << start_timer_in - << " seconds"; + const base::Time time = failed_confirmations_timer_.StartWithPrivacy( + kRetryFailedConfirmationsAfterSeconds, + base::BindOnce(&ConfirmationsImpl::RetryFailedConfirmations, + base::Unretained(this))); + + BLOG(INFO) << "Retry failed confirmations at " << time; } void ConfirmationsImpl::RetryFailedConfirmations() { - DCHECK(state_has_loaded_); - - StopRetryingFailedConfirmations(); - - if (confirmations_.size() == 0) { + if (confirmations_.empty()) { BLOG(INFO) << "No failed confirmations to retry"; return; } @@ -1295,104 +1196,4 @@ void ConfirmationsImpl::RetryFailedConfirmations() { StartRetryingFailedConfirmations(); } -void ConfirmationsImpl::StopRetryingFailedConfirmations() { - if (!IsRetryingFailedConfirmations()) { - return; - } - - BLOG(INFO) << "Stopped retrying failed confirmations"; - - confirmations_client_->KillTimer(retry_failed_confirmations_timer_id_); - retry_failed_confirmations_timer_id_ = 0; -} - -bool ConfirmationsImpl::IsRetryingFailedConfirmations() const { - if (retry_failed_confirmations_timer_id_ == 0) { - return false; - } - - return true; -} - -void ConfirmationsImpl::StartPayingOutRedeemedTokens( - const uint64_t start_timer_in) { - StopPayingOutRedeemedTokens(); - - confirmations_client_->SetTimer(start_timer_in, - &payout_redeemed_tokens_timer_id_); - if (payout_redeemed_tokens_timer_id_ == 0) { - BLOG(ERROR) - << "Failed to start paying out redeemed tokens due to an invalid timer"; - return; - } - - BLOG(INFO) << "Start paying out redeemed tokens in " << start_timer_in - << " seconds"; -} - -void ConfirmationsImpl::PayoutRedeemedTokens() const { - DCHECK(wallet_info_.IsValid()); - - payout_tokens_->Payout(wallet_info_); -} - -void ConfirmationsImpl::StopPayingOutRedeemedTokens() { - if (!IsPayingOutRedeemedTokens()) { - return; - } - - BLOG(INFO) << "Stopped paying out redeemed tokens"; - - confirmations_client_->KillTimer(payout_redeemed_tokens_timer_id_); - payout_redeemed_tokens_timer_id_ = 0; -} - -bool ConfirmationsImpl::IsPayingOutRedeemedTokens() const { - if (payout_redeemed_tokens_timer_id_ == 0) { - return false; - } - - return true; -} - -void ConfirmationsImpl::StartRetryingToGetRefillSignedTokens( - const uint64_t start_timer_in) { - StopRetryingToGetRefillSignedTokens(); - - confirmations_client_->SetTimer(start_timer_in, - &retry_getting_signed_tokens_timer_id_); - if (retry_getting_signed_tokens_timer_id_ == 0) { - BLOG(ERROR) - << "Failed to start getting signed tokens due to an invalid timer"; - - return; - } - - BLOG(INFO) << "Start getting signed tokens in " << start_timer_in - << " seconds"; -} - -void ConfirmationsImpl::RetryGettingRefillSignedTokens() const { - refill_tokens_->RetryGettingSignedTokens(); -} - -void ConfirmationsImpl::StopRetryingToGetRefillSignedTokens() { - if (!IsRetryingToGetRefillSignedTokens()) { - return; - } - - BLOG(INFO) << "Stopped getting signed tokens"; - - confirmations_client_->KillTimer(retry_getting_signed_tokens_timer_id_); - retry_getting_signed_tokens_timer_id_ = 0; -} - -bool ConfirmationsImpl::IsRetryingToGetRefillSignedTokens() const { - if (retry_getting_signed_tokens_timer_id_ == 0) { - return false; - } - - return true; -} - } // namespace confirmations diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/confirmations_impl.h b/vendor/bat-native-confirmations/src/bat/confirmations/internal/confirmations_impl.h index 4b5848f73dfc..eb3485dc1708 100644 --- a/vendor/bat-native-confirmations/src/bat/confirmations/internal/confirmations_impl.h +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/confirmations_impl.h @@ -74,13 +74,13 @@ class ConfirmationsImpl : public Confirmations { const double estimated_redemption_value, const ConfirmationType confirmation_type); - // Scheduled events - bool OnTimer(const uint32_t timer_id) override; - // Refill tokens void StartRetryingToGetRefillSignedTokens(const uint64_t start_timer_in); void RefillTokensIfNecessary() const; + // Payout tokens + uint64_t GetNextTokenRedemptionDateInSeconds() const; + // Redeem unblinded tokens void ConfirmAd( const AdInfo& info, @@ -90,12 +90,6 @@ class ConfirmationsImpl : public Confirmations { const std::string& creative_set_id, const ConfirmationType confirmation_type) override; - // Payout redeemed tokens - void UpdateNextTokenRedemptionDate(); - uint64_t CalculateTokenRedemptionTimeInSeconds(); - uint64_t GetNextTokenRedemptionDateInSeconds(); - void StartPayingOutRedeemedTokens(const uint64_t start_timer_in); - // State void SaveState(); @@ -113,12 +107,9 @@ class ConfirmationsImpl : public Confirmations { std::map catalog_issuers_; // Confirmations - uint32_t retry_failed_confirmations_timer_id_; + Timer failed_confirmations_timer_; void RemoveConfirmationFromQueue(const ConfirmationInfo& confirmation_info); - void StartRetryingFailedConfirmations(const uint64_t start_timer_in); - bool IsRetryingFailedConfirmations() const; void RetryFailedConfirmations(); - void StopRetryingFailedConfirmations(); ConfirmationList confirmations_; // Transaction history @@ -135,23 +126,11 @@ class ConfirmationsImpl : public Confirmations { uint64_t next_payment_date_in_seconds_; std::unique_ptr ads_rewards_; - // Refill tokens - uint32_t retry_getting_signed_tokens_timer_id_; - void RetryGettingRefillSignedTokens() const; - void StopRetryingToGetRefillSignedTokens(); - bool IsRetryingToGetRefillSignedTokens() const; std::unique_ptr refill_tokens_; - // Redeem unblinded tokens std::unique_ptr redeem_token_; - // Payout redeemed tokens - uint32_t payout_redeemed_tokens_timer_id_; - void PayoutRedeemedTokens() const; - void StopPayingOutRedeemedTokens(); - bool IsPayingOutRedeemedTokens() const; std::unique_ptr payout_tokens_; - uint64_t next_token_redemption_date_in_seconds_; // State void OnStateSaved(const Result result); diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/payout_tokens.cc b/vendor/bat-native-confirmations/src/bat/confirmations/internal/payout_tokens.cc index a779e3f2ce61..6beadc321e9e 100644 --- a/vendor/bat-native-confirmations/src/bat/confirmations/internal/payout_tokens.cc +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/payout_tokens.cc @@ -12,6 +12,7 @@ #include "brave_base/random.h" #include "net/http/http_status_code.h" +#include "base/time/time.h" using std::placeholders::_1; using std::placeholders::_2; @@ -22,24 +23,40 @@ namespace confirmations { PayoutTokens::PayoutTokens( ConfirmationsImpl* confirmations, ConfirmationsClient* confirmations_client, - UnblindedTokens* unblinded_payment_tokens) : - next_retry_backoff_count_(0), - confirmations_(confirmations), - confirmations_client_(confirmations_client), - unblinded_payment_tokens_(unblinded_payment_tokens) { + UnblindedTokens* unblinded_payment_tokens) + : confirmations_(confirmations), + confirmations_client_(confirmations_client), + unblinded_payment_tokens_(unblinded_payment_tokens) { } PayoutTokens::~PayoutTokens() = default; -void PayoutTokens::Payout(const WalletInfo& wallet_info) { +void PayoutTokens::PayoutAfterDelay( + const WalletInfo& wallet_info) { DCHECK(!wallet_info.payment_id.empty()); DCHECK(!wallet_info.private_key.empty()); - BLOG(INFO) << "Payout"; + if (retry_timer_.IsRunning()) { + return; + } wallet_info_ = WalletInfo(wallet_info); - RedeemPaymentTokens(); + const uint64_t delay = CalculatePayoutDelay(); + const base::Time time = timer_.Start(delay, + base::BindOnce(&PayoutTokens::RedeemPaymentTokens, + base::Unretained(this))); + + BLOG(INFO) << "Payout tokens at " << time; +} + +uint64_t PayoutTokens::get_token_redemption_timestamp_in_seconds() const { + return token_redemption_timestamp_in_seconds_; +} + +void PayoutTokens::set_token_redemption_timestamp_in_seconds( + const uint64_t timestamp_in_seconds) { + token_redemption_timestamp_in_seconds_ = timestamp_in_seconds; } /////////////////////////////////////////////////////////////////////////////// @@ -115,7 +132,12 @@ void PayoutTokens::OnPayout(const Result result) { if (result != SUCCESS) { BLOG(ERROR) << "Failed to payout tokens"; - RetryNextPayout(); + const base::Time time = retry_timer_.StartWithBackoff( + kRetryPayoutTokensAfterSeconds, base::BindOnce(&PayoutTokens::OnRetry, + base::Unretained(this))); + + BLOG(INFO) << "Retry paying out tokens at " << time; + return; } @@ -126,29 +148,52 @@ void PayoutTokens::OnPayout(const Result result) { confirmations_->UpdateAdsRewards(true); - next_retry_backoff_count_ = 0; + retry_timer_.Stop(); ScheduleNextPayout(); } -void PayoutTokens::ScheduleNextPayout() const { - confirmations_->UpdateNextTokenRedemptionDate(); +void PayoutTokens::ScheduleNextPayout() { + UpdateNextTokenRedemptionDate(); + PayoutAfterDelay(wallet_info_); +} + +void PayoutTokens::OnRetry() { + BLOG(INFO) << "Retrying"; - auto start_timer_in = confirmations_->CalculateTokenRedemptionTimeInSeconds(); - confirmations_->StartPayingOutRedeemedTokens(start_timer_in); + RedeemPaymentTokens(); } -void PayoutTokens::RetryNextPayout() { - BLOG(INFO) << "Retry next payout"; +uint64_t PayoutTokens::CalculatePayoutDelay() { + if (token_redemption_timestamp_in_seconds_ == 0) { + UpdateNextTokenRedemptionDate(); + } + + const uint64_t now_in_seconds = base::Time::Now().ToDoubleT(); - // Overflow happens only if we have already backed off so many times our - // expected waiting time is longer than the lifetime of the universe - auto start_timer_in = 1 * base::Time::kSecondsPerMinute; - start_timer_in <<= next_retry_backoff_count_++; + uint64_t delay; + if (now_in_seconds >= token_redemption_timestamp_in_seconds_) { + // Browser was launched after the token redemption date + delay = 1 * base::Time::kSecondsPerMinute; + } else { + delay = token_redemption_timestamp_in_seconds_ - now_in_seconds; + } + + const uint64_t rand_delay = brave_base::random::Geometric(delay); + return rand_delay; +} - auto rand_delay = brave_base::random::Geometric(start_timer_in); +void PayoutTokens::UpdateNextTokenRedemptionDate() { + uint64_t timestamp_in_seconds = base::Time::Now().ToDoubleT(); + + if (!_is_debug) { + timestamp_in_seconds += kNextTokenRedemptionAfterSeconds; + } else { + timestamp_in_seconds += kDebugNextTokenRedemptionAfterSeconds; + } - confirmations_->StartPayingOutRedeemedTokens(rand_delay); + token_redemption_timestamp_in_seconds_ = timestamp_in_seconds; + confirmations_->SaveState(); } } // namespace confirmations diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/payout_tokens.h b/vendor/bat-native-confirmations/src/bat/confirmations/internal/payout_tokens.h index 222c58a40412..adde5a375c0d 100644 --- a/vendor/bat-native-confirmations/src/bat/confirmations/internal/payout_tokens.h +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/payout_tokens.h @@ -12,6 +12,8 @@ #include "bat/confirmations/confirmations_client.h" #include "bat/confirmations/wallet_info.h" +#include "bat/confirmations/internal/retry_timer.h" +#include "bat/confirmations/internal/timer.h" namespace confirmations { @@ -27,11 +29,18 @@ class PayoutTokens { ~PayoutTokens(); - void Payout(const WalletInfo& wallet_info); + void PayoutAfterDelay( + const WalletInfo& wallet_info); + + uint64_t get_token_redemption_timestamp_in_seconds() const; + void set_token_redemption_timestamp_in_seconds( + const uint64_t timestamp_in_seconds); private: WalletInfo wallet_info_; + Timer timer_; + void RedeemPaymentTokens(); void OnRedeemPaymentTokens( const std::string& url, @@ -41,9 +50,14 @@ class PayoutTokens { void OnPayout(const Result result); - void ScheduleNextPayout() const; - uint64_t next_retry_backoff_count_; - void RetryNextPayout(); + void ScheduleNextPayout(); + uint64_t token_redemption_timestamp_in_seconds_ = 0; + + RetryTimer retry_timer_; + void OnRetry(); + + uint64_t CalculatePayoutDelay(); + void UpdateNextTokenRedemptionDate(); ConfirmationsImpl* confirmations_; // NOT OWNED ConfirmationsClient* confirmations_client_; // NOT OWNED diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/refill_tokens.cc b/vendor/bat-native-confirmations/src/bat/confirmations/internal/refill_tokens.cc index 3a11db2c3251..f36a8a4bbc40 100644 --- a/vendor/bat-native-confirmations/src/bat/confirmations/internal/refill_tokens.cc +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/refill_tokens.cc @@ -18,6 +18,7 @@ #include "base/logging.h" #include "base/json/json_reader.h" #include "net/http/http_status_code.h" +#include "brave_base/random.h" using std::placeholders::_1; using std::placeholders::_2; @@ -47,6 +48,10 @@ void RefillTokens::Refill( DCHECK(!wallet_info.private_key.empty()); DCHECK(!public_key.empty()); + if (retry_timer_.IsRunning()) { + return; + } + BLOG(INFO) << "Refill"; wallet_info_ = WalletInfo(wallet_info); @@ -58,17 +63,6 @@ void RefillTokens::Refill( RequestSignedTokens(); } -void RefillTokens::RetryGettingSignedTokens() { - BLOG(INFO) << "Retry getting signed tokens"; - - if (nonce_.empty()) { - RequestSignedTokens(); - return; - } - - GetSignedTokens(); -} - /////////////////////////////////////////////////////////////////////////////// void RefillTokens::RequestSignedTokens() { @@ -311,13 +305,18 @@ void RefillTokens::OnRefill( BLOG(ERROR) << "Failed to refill tokens"; if (should_retry) { - confirmations_->StartRetryingToGetRefillSignedTokens( - kRetryGettingRefillSignedTokensAfterSeconds); + const base::Time time = retry_timer_.StartWithBackoff( + kRetryRefillTokensAfterSeconds, base::BindOnce(&RefillTokens::OnRetry, + base::Unretained(this))); + + BLOG(INFO) << "Retry refilling tokens at " << time; } return; } + retry_timer_.Stop(); + blinded_tokens_.clear(); tokens_.clear(); confirmations_->SaveState(); @@ -325,6 +324,16 @@ void RefillTokens::OnRefill( BLOG(INFO) << "Successfully refilled tokens"; } +void RefillTokens::OnRetry() { + BLOG(INFO) << "Retrying"; + + if (nonce_.empty()) { + RequestSignedTokens(); + } else { + GetSignedTokens(); + } +} + bool RefillTokens::ShouldRefillTokens() const { if (unblinded_tokens_->Count() >= kMinimumUnblindedTokens) { return false; diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/refill_tokens.h b/vendor/bat-native-confirmations/src/bat/confirmations/internal/refill_tokens.h index 97d49889387e..9031987f5ba0 100644 --- a/vendor/bat-native-confirmations/src/bat/confirmations/internal/refill_tokens.h +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/refill_tokens.h @@ -6,12 +6,14 @@ #ifndef BAT_CONFIRMATIONS_INTERNAL_REFILL_TOKENS_H_ #define BAT_CONFIRMATIONS_INTERNAL_REFILL_TOKENS_H_ +#include #include #include #include #include "bat/confirmations/confirmations_client.h" #include "bat/confirmations/wallet_info.h" +#include "bat/confirmations/internal/retry_timer.h" #include "wrapper.hpp" @@ -34,8 +36,6 @@ class RefillTokens { void Refill(const WalletInfo& wallet_info, const std::string& public_key); - void RetryGettingSignedTokens(); - private: WalletInfo wallet_info_; @@ -64,6 +64,9 @@ class RefillTokens { const Result result, const bool should_retry = true); + RetryTimer retry_timer_; + void OnRetry(); + bool ShouldRefillTokens() const; int CalculateAmountOfTokensToRefill() const; diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/retry_timer.cc b/vendor/bat-native-confirmations/src/bat/confirmations/internal/retry_timer.cc new file mode 100644 index 000000000000..663b0e0260a1 --- /dev/null +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/retry_timer.cc @@ -0,0 +1,54 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "bat/confirmations/internal/retry_timer.h" + +namespace confirmations { + +RetryTimer::RetryTimer() = default; + +RetryTimer::~RetryTimer() = default; + +base::Time RetryTimer::Start( + const uint64_t delay, + base::OnceClosure user_task) { + timer_.Stop(); + + const base::Time time = timer_.StartWithPrivacy(delay, std::move(user_task)); + + return time; +} + +base::Time RetryTimer::StartWithBackoff( + const uint64_t delay, + base::OnceClosure user_task) { + uint64_t backoff_delay = delay; + + backoff_delay <<= backoff_count_++; + if (backoff_delay > max_backoff_delay_) { + backoff_delay = max_backoff_delay_; + } + + return Start(backoff_delay, std::move(user_task)); +} + +bool RetryTimer::IsRunning() const { + return timer_.IsRunning(); +} + +void RetryTimer::Stop() { + timer_.Stop(); + + backoff_count_ = 0; +} + +void RetryTimer::set_max_backoff_delay( + const uint64_t max_delay) { + max_backoff_delay_ = max_delay; +} + +} // namespace confirmations diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/retry_timer.h b/vendor/bat-native-confirmations/src/bat/confirmations/internal/retry_timer.h new file mode 100644 index 000000000000..f9642c3fcc00 --- /dev/null +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/retry_timer.h @@ -0,0 +1,60 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BAT_CONFIRMATIONS_INTERNAL_RETRY_TIMER_H_ +#define BAT_CONFIRMATIONS_INTERNAL_RETRY_TIMER_H_ + +#include + +#include "bat/confirmations/internal/timer.h" + +#include "base/bind.h" +#include "base/time/time.h" + +namespace confirmations { + +class RetryTimer { + public: + RetryTimer(); + + ~RetryTimer(); + + // Start a timer to run at a geometrically distributed number of seconds + // |~delay| from now. If the timer is already running, it will be replaced to + // call the given |user_task|. Returns the time the delayed task will be fired + base::Time Start( + const uint64_t delay, + base::OnceClosure user_task); + + // Start a timer to run at a geometrically distributed number of seconds + // |~delay| from now backing off exponentially for each call. If the timer is + // already running, it will be replaced to call the given |user_task|. Returns + // the time the delayed task will be fired + base::Time StartWithBackoff( + const uint64_t delay, + base::OnceClosure user_task); + + // Returns true if the timer is running (i.e., not stopped) + bool IsRunning() const; + + // Call this method to stop the timer if running and to reset the exponential + // backoff delay + void Stop(); + + // Optionally call this method to set the maximum backoff delay to + // |max_delay|. Default maximum backoff delay is 1 hour + void set_max_backoff_delay( + const uint64_t max_delay); + + private: + Timer timer_; + + uint64_t backoff_count_ = 0; + uint64_t max_backoff_delay_ = base::Time::kSecondsPerHour; +}; + +} // namespace confirmations + +#endif // BAT_CONFIRMATIONS_INTERNAL_RETRY_TIMER_H_ diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/static_values.h b/vendor/bat-native-confirmations/src/bat/confirmations/internal/static_values.h index 86c0e677a35c..020cb7df2dd1 100644 --- a/vendor/bat-native-confirmations/src/bat/confirmations/internal/static_values.h +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/static_values.h @@ -25,13 +25,19 @@ const int kNextPaymentDay = 5; const int kMinimumUnblindedTokens = 20; const int kMaximumUnblindedTokens = 50; -const uint64_t kRetryGettingRefillSignedTokensAfterSeconds = 15; - const uint64_t kNextTokenRedemptionAfterSeconds = 24 * base::Time::kSecondsPerHour; const uint64_t kDebugNextTokenRedemptionAfterSeconds = 25 * base::Time::kSecondsPerMinute; +const uint64_t kRetryRefillTokensAfterSeconds = 15; + +const uint64_t kRetryPayoutTokensAfterSeconds = + 1 * base::Time::kSecondsPerMinute; + +const uint64_t kRetryAdsRewardsAfterSeconds = + 1 * base::Time::kSecondsPerMinute; + const uint64_t kRetryFailedConfirmationsAfterSeconds = 5 * base::Time::kSecondsPerMinute; diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/timer.cc b/vendor/bat-native-confirmations/src/bat/confirmations/internal/timer.cc new file mode 100644 index 000000000000..8e0f27b5069a --- /dev/null +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/timer.cc @@ -0,0 +1,53 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include + +#include "bat/confirmations/internal/timer.h" + +#include "brave_base/random.h" + +namespace confirmations { + +Timer::Timer() = default; + +Timer::~Timer() { + Stop(); +} + +base::Time Timer::Start( + const uint64_t delay, + base::OnceClosure user_task) { + Stop(); + + timer_.Start(FROM_HERE, base::TimeDelta::FromSeconds(delay), + std::move(user_task)); + + const base::Time time = + base::Time::Now() + base::TimeDelta::FromSeconds(delay); + + return time; +} + +base::Time Timer::StartWithPrivacy( + const uint64_t delay, + base::OnceClosure user_task) { + const uint64_t rand_delay = brave_base::random::Geometric(delay); + return Start(rand_delay, std::move(user_task)); +} + +bool Timer::IsRunning() const { + return timer_.IsRunning(); +} + +void Timer::Stop() { + if (!IsRunning()) { + return; + } + + timer_.Stop(); +} + +} // namespace confirmations diff --git a/vendor/bat-native-confirmations/src/bat/confirmations/internal/timer.h b/vendor/bat-native-confirmations/src/bat/confirmations/internal/timer.h new file mode 100644 index 000000000000..148bf07a3deb --- /dev/null +++ b/vendor/bat-native-confirmations/src/bat/confirmations/internal/timer.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2020 The Brave Authors. All rights reserved. + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef BAT_CONFIRMATIONS_INTERNAL_TIMER_H_ +#define BAT_CONFIRMATIONS_INTERNAL_TIMER_H_ + +#include + +#include "base/bind.h" +#include "base/time/time.h" +#include "base/timer/timer.h" + +namespace confirmations { + +class Timer { + public: + Timer(); + + ~Timer(); + + // Start a timer to run at the given |delay| from now. If the timer is already + // running, it will be replaced to call the given |user_task|. Returns the + // time the delayed task will be fired + base::Time Start( + const uint64_t delay, + base::OnceClosure user_task); + + // Start a timer to run at a geometrically distributed number of seconds + // |~delay| from now for privacy-focused events. If the timer is already + // running, it will be replaced to call the given |user_task|. Returns the + // time the delayed task will be fired + base::Time StartWithPrivacy( + const uint64_t delay, + base::OnceClosure user_task); + + // Returns true if the timer is running (i.e., not stopped) + bool IsRunning() const; + + // Call this method to stop the timer. It is a no-op if the timer is not + // running + void Stop(); + + private: + base::OneShotTimer timer_; +}; + +} // namespace confirmations + +#endif // BAT_CONFIRMATIONS_INTERNAL_TIMER_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc index cc7bd3b7e82a..b35bf415b0e0 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.cc @@ -811,10 +811,6 @@ void LedgerImpl::OneTimeTip( } void LedgerImpl::OnTimer(uint32_t timer_id) { - if (bat_confirmations_->OnTimer(timer_id)) { - return; - } - bat_contribution_->OnTimer(timer_id); bat_publisher_->OnTimer(timer_id); bat_promotion_->OnTimer(timer_id);