Skip to content

Commit

Permalink
Merge pull request #13824 from /issues/23516
Browse files Browse the repository at this point in the history
Brave Ads failed confirmations should not backoff if payment tokens are not created or not ready
  • Loading branch information
tmancey authored Jun 16, 2022
2 parents 4767500 + 2ef8902 commit 8a1c0e9
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,8 @@ void Confirmations::OnDidRedeemUnblindedToken(
->get_unblinded_payment_tokens()
->TokenExists(unblinded_payment_token)) {
BLOG(1, "Unblinded payment token is a duplicate");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false,
/* should_backoff */ false);
return;
}

Expand Down Expand Up @@ -312,7 +313,8 @@ void Confirmations::OnDidRedeemUnblindedToken(

void Confirmations::OnFailedToRedeemUnblindedToken(
const ConfirmationInfo& confirmation,
const bool should_retry) {
const bool should_retry,
const bool should_backoff) {
BLOG(1, "Failed to redeem unblinded token for "
<< confirmation.ad_type << " with confirmation id "
<< confirmation.id << ", transaction id "
Expand All @@ -332,6 +334,10 @@ void Confirmations::OnFailedToRedeemUnblindedToken(
delegate_->OnFailedToConfirm(confirmation);
}

if (!should_backoff) {
StopRetrying();
}

ProcessRetryQueue();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,8 @@ class Confirmations final : public RedeemUnblindedTokenDelegate {
const privacy::UnblindedPaymentTokenInfo&
unblinded_payment_token) override;
void OnFailedToRedeemUnblindedToken(const ConfirmationInfo& confirmation,
const bool should_retry) override;
const bool should_retry,
const bool should_backoff) override;

raw_ptr<ConfirmationsDelegate> delegate_ = nullptr;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@ void RedeemUnblindedToken::Redeem(const ConfirmationInfo& confirmation) {

if (ShouldRewardUser() && !HasIssuers()) {
BLOG(1, "Failed to redeem unblinded token due to missing issuers");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

Expand Down Expand Up @@ -100,7 +101,8 @@ void RedeemUnblindedToken::OnCreateConfirmation(
return;
} else if (url_response.status_code == net::kHttpUpgradeRequired) {
BLOG(1, "Failed to create confirmation as a browser upgrade is required");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false,
/* should_backoff */ false);
return;
}

Expand Down Expand Up @@ -143,29 +145,35 @@ void RedeemUnblindedToken::OnFetchPaymentToken(
ConfirmationInfo new_confirmation = confirmation;
new_confirmation.was_created = false;

OnFailedToRedeemUnblindedToken(new_confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(new_confirmation, /* should_retry */ true,
/* should_backoff */ false);
return;
} else if (url_response.status_code == net::HTTP_BAD_REQUEST) {
BLOG(1, "Credential is invalid");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false,
/* should_backoff */ false);
return;
} else if (url_response.status_code == net::HTTP_ACCEPTED) {
BLOG(1, "Payment token is not ready");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ false);
return;
} else if (url_response.status_code == net::kHttpUpgradeRequired) {
BLOG(1, "Failed to fetch payment token as a browser upgrade is required");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false,
/* should_backoff */ false);
return;
} else if (url_response.status_code != net::HTTP_OK) {
BLOG(1, "Failed to fetch payment token");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

if (!VerifyConfirmation(confirmation)) {
BLOG(1, "Failed to verify confirmation");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false,
/* should_backoff */ false);
return;
}

Expand All @@ -174,23 +182,26 @@ void RedeemUnblindedToken::OnFetchPaymentToken(
base::JSONReader::Read(url_response.body);
if (!dictionary || !dictionary->is_dict()) {
BLOG(3, "Failed to parse response: " << url_response.body);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

// Get id
const std::string* id = dictionary->FindStringKey("id");
if (!id) {
BLOG(0, "Response is missing id");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

// Validate id
if (*id != confirmation.id) {
BLOG(0, "Response id " << *id << " does not match confirmation id "
<< confirmation.id);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ false,
/* should_backoff */ false);
return;
}

Expand All @@ -199,7 +210,8 @@ void RedeemUnblindedToken::OnFetchPaymentToken(
dictionary->FindDictKey("paymentToken");
if (!payment_token_dictionary) {
BLOG(1, "Response is missing paymentToken");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

Expand All @@ -208,7 +220,8 @@ void RedeemUnblindedToken::OnFetchPaymentToken(
payment_token_dictionary->FindStringKey("publicKey");
if (!public_key_base64) {
BLOG(0, "Response is missing publicKey in paymentToken dictionary");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

Expand All @@ -217,15 +230,17 @@ void RedeemUnblindedToken::OnFetchPaymentToken(
if (!public_key.has_value()) {
BLOG(0, "Invalid public key");
NOTREACHED();
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

if (!PublicKeyExistsForIssuerType(IssuerType::kPayments,
*public_key_base64)) {
BLOG(0, "Response public key " << *public_key_base64 << " does not exist "
<< "in payments issuer public keys");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

Expand All @@ -234,15 +249,17 @@ void RedeemUnblindedToken::OnFetchPaymentToken(
payment_token_dictionary->FindStringKey("batchProof");
if (!batch_dleq_proof_base64) {
BLOG(0, "Response is missing batchProof");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}
privacy::cbr::BatchDLEQProof batch_dleq_proof =
privacy::cbr::BatchDLEQProof(*batch_dleq_proof_base64);
if (!batch_dleq_proof.has_value()) {
BLOG(0, "Invalid batch DLEQ proof");
NOTREACHED();
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

Expand All @@ -251,13 +268,15 @@ void RedeemUnblindedToken::OnFetchPaymentToken(
payment_token_dictionary->FindListKey("signedTokens");
if (!signed_tokens_list) {
BLOG(0, "Response is missing signedTokens");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

if (signed_tokens_list->GetList().size() != 1) {
BLOG(0, "Response has too many signedTokens");
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}

Expand Down Expand Up @@ -291,7 +310,8 @@ void RedeemUnblindedToken::OnFetchPaymentToken(
BLOG(1, " Batch proof: " << *batch_dleq_proof_base64);
BLOG(1, " Public key: " << *public_key_base64);

OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true);
OnFailedToRedeemUnblindedToken(confirmation, /* should_retry */ true,
/* should_backoff */ true);
return;
}
const std::vector<privacy::cbr::UnblindedToken>&
Expand Down Expand Up @@ -339,12 +359,14 @@ void RedeemUnblindedToken::OnDidRedeemUnblindedToken(

void RedeemUnblindedToken::OnFailedToRedeemUnblindedToken(
const ConfirmationInfo& confirmation,
const bool should_retry) {
const bool should_retry,
const bool should_backoff) {
if (!delegate_) {
return;
}

delegate_->OnFailedToRedeemUnblindedToken(confirmation, should_retry);
delegate_->OnFailedToRedeemUnblindedToken(confirmation, should_retry,
should_backoff);
}

} // namespace ads
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ class RedeemUnblindedToken final {
const ConfirmationInfo& confirmation,
const privacy::UnblindedPaymentTokenInfo& unblinded_payment_token);
void OnFailedToRedeemUnblindedToken(const ConfirmationInfo& confirmation,
const bool should_retry);
const bool should_retry,
const bool should_backoff);

raw_ptr<RedeemUnblindedTokenDelegate> delegate_ = nullptr;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ class RedeemUnblindedTokenDelegate {
const privacy::UnblindedPaymentTokenInfo& unblinded_payment_token) {}

// Invoked to tell the delegate unblinded token redemption failed for the
// corresponding |confirmation| and whether we should retry
// corresponding |confirmation| and whether we should retry and backoff for
// subsequent failures
virtual void OnFailedToRedeemUnblindedToken(
const ConfirmationInfo& confirmation,
const bool should_retry) {}
const bool should_retry,
const bool should_backoff) {}
};

} // namespace ads
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ class RedeemUnblindedTokenDelegateMock : public RedeemUnblindedTokenDelegate {

MOCK_METHOD(void,
OnFailedToRedeemUnblindedToken,
(const ConfirmationInfo& confirmation, const bool should_retry));
(const ConfirmationInfo& confirmation,
const bool should_retry,
const bool should_backoff));
};

} // namespace ads
Expand Down
Loading

0 comments on commit 8a1c0e9

Please sign in to comment.