diff --git a/components/brave_rewards/browser/rewards_service.cc b/components/brave_rewards/browser/rewards_service.cc index 20688550edc1..1bec71a908c4 100644 --- a/components/brave_rewards/browser/rewards_service.cc +++ b/components/brave_rewards/browser/rewards_service.cc @@ -66,6 +66,7 @@ void RewardsService::RegisterProfilePrefs(PrefRegistrySimple* registry) { #endif registry->RegisterUint64Pref(prefs::kStatePromotionLastFetchStamp, 0ull); registry->RegisterBooleanPref(prefs::kStatePromotionCorruptedMigrated, false); + registry->RegisterBooleanPref(prefs::kStateAnonTransferChecked, false); } } // namespace brave_rewards diff --git a/components/brave_rewards/common/pref_names.cc b/components/brave_rewards/common/pref_names.cc index 49a92955583d..24241ce5dc80 100644 --- a/components/brave_rewards/common/pref_names.cc +++ b/components/brave_rewards/common/pref_names.cc @@ -34,5 +34,6 @@ const char kStatePromotionLastFetchStamp[] = "brave.rewards.promotion_last_fetch_stamp"; const char kStatePromotionCorruptedMigrated[] = "brave.rewards.promotion_corrupted_migrated"; +const char kStateAnonTransferChecked[] = "brave.rewards.anon_transfer_checked"; } // namespace prefs } // namespace brave_rewards diff --git a/components/brave_rewards/common/pref_names.h b/components/brave_rewards/common/pref_names.h index dcdf373254e1..06f50160ce76 100644 --- a/components/brave_rewards/common/pref_names.h +++ b/components/brave_rewards/common/pref_names.h @@ -27,6 +27,7 @@ extern const char kStateServerPublisherListStamp[]; extern const char kStateUpholdAnonAddress[]; extern const char kStatePromotionLastFetchStamp[]; extern const char kStatePromotionCorruptedMigrated[]; +extern const char kStateAnonTransferChecked[]; extern const char kUseRewardsStagingServer[]; } // namespace prefs diff --git a/test/BUILD.gn b/test/BUILD.gn index 1435581340b6..228c91e3fae0 100644 --- a/test/BUILD.gn +++ b/test/BUILD.gn @@ -299,6 +299,7 @@ test("brave_unit_tests") { "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_activity_info_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded_unittest.cc", + "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/phase_two_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/helper_unittest.cc", "//brave/vendor/bat-native-ledger/src/bat/ledger/internal/media/reddit_unittest.cc", diff --git a/vendor/bat-native-ledger/BUILD.gn b/vendor/bat-native-ledger/BUILD.gn index 4b97595fd60d..06e60d4b95d9 100644 --- a/vendor/bat-native-ledger/BUILD.gn +++ b/vendor/bat-native-ledger/BUILD.gn @@ -183,6 +183,8 @@ source_set("ledger") { "src/bat/ledger/internal/media/youtube.cc", "src/bat/ledger/internal/promotion/promotion.cc", "src/bat/ledger/internal/promotion/promotion.h", + "src/bat/ledger/internal/promotion/promotion_transfer.cc", + "src/bat/ledger/internal/promotion/promotion_transfer.h", "src/bat/ledger/internal/promotion/promotion_util.cc", "src/bat/ledger/internal/promotion/promotion_util.h", "src/bat/ledger/internal/properties/ballot_properties.cc", diff --git a/vendor/bat-native-ledger/include/bat/ledger/ledger_client.h b/vendor/bat-native-ledger/include/bat/ledger/ledger_client.h index a908fa9f8b5b..5999aa7e49e0 100644 --- a/vendor/bat-native-ledger/include/bat/ledger/ledger_client.h +++ b/vendor/bat-native-ledger/include/bat/ledger/ledger_client.h @@ -65,7 +65,7 @@ using ResultCallback = std::function; using GetFirstContributionQueueCallback = std::function; using GetPromotionCallback = std::function; -using GetAllUnblindedTokensCallback = std::function; +using GetUnblindedTokenListCallback = std::function; using GetAllPromotionsCallback = std::function; using GetTransactionReportCallback = diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded.cc index 3206ef766c19..d39130431541 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded.cc @@ -11,20 +11,15 @@ #include "bat/ledger/internal/bat_util.h" #include "bat/ledger/internal/ledger_impl.h" #include "bat/ledger/internal/contribution/contribution_unblinded.h" +#include "bat/ledger/internal/contribution/contribution_util.h" #include "bat/ledger/internal/request/promotion_requests.h" #include "brave_base/random.h" #include "net/http/http_status_code.h" -#include "wrapper.hpp" // NOLINT - using std::placeholders::_1; using std::placeholders::_2; using std::placeholders::_3; -using challenge_bypass_ristretto::UnblindedToken; -using challenge_bypass_ristretto::VerificationKey; -using challenge_bypass_ristretto::VerificationSignature; - namespace { std::string ConvertTypeToString(const ledger::RewardsType type) { @@ -46,35 +41,6 @@ std::string ConvertTypeToString(const ledger::RewardsType type) { } } -void GenerateSuggestionMock( - const ledger::UnblindedToken& token, - const std::string& suggestion_encoded, - base::Value* result) { - result->SetStringKey("t", token.token_value); - result->SetStringKey("publicKey", token.public_key); - result->SetStringKey("signature", token.token_value); -} - -void GenerateSuggestion( - const ledger::UnblindedToken& token, - const std::string& suggestion_encoded, - base::Value* result) { - UnblindedToken unblinded = UnblindedToken::decode_base64(token.token_value); - VerificationKey verification_key = unblinded.derive_verification_key(); - VerificationSignature signature = verification_key.sign(suggestion_encoded); - const std::string pre_image = unblinded.preimage().encode_base64(); - - if (challenge_bypass_ristretto::exception_occurred()) { - challenge_bypass_ristretto::TokenException e = - challenge_bypass_ristretto::get_last_exception(); - return; - } - - result->SetStringKey("t", pre_image); - result->SetStringKey("publicKey", token.public_key); - result->SetStringKey("signature", signature.encode_base64()); -} - bool HasTokenExpired(const ledger::UnblindedToken& token) { const uint64_t now = static_cast(base::Time::Now().ToDoubleT()); @@ -95,13 +61,27 @@ std::string GenerateTokenPayload( base::Base64Encode(suggestion_json, &suggestion_encoded); base::Value credentials(base::Value::Type::LIST); - for (auto & item : list) { + for (auto& item : list) { base::Value token(base::Value::Type::DICTIONARY); + bool success; if (ledger::is_testing) { - GenerateSuggestionMock(item, suggestion_encoded, &token); + success = braveledger_contribution::GenerateSuggestionMock( + item.token_value, + item.public_key, + suggestion_encoded, + &token); } else { - GenerateSuggestion(item, suggestion_encoded, &token); + success = braveledger_contribution::GenerateSuggestion( + item.token_value, + item.public_key, + suggestion_encoded, + &token); } + + if (!success) { + continue; + } + credentials.GetList().push_back(std::move(token)); } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded_unittest.cc index 9c04c0bc28a8..dfa767948ce5 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded_unittest.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_unblinded_unittest.cc @@ -66,7 +66,7 @@ TEST_F(UnblindedTest, NotEnoughFunds) { ON_CALL(*mock_ledger_impl_, GetAllUnblindedTokens(_)) .WillByDefault( - Invoke([](ledger::GetAllUnblindedTokensCallback callback) { + Invoke([](ledger::GetUnblindedTokenListCallback callback) { ledger::UnblindedTokenList list; auto info = ledger::UnblindedToken::New(); @@ -92,7 +92,7 @@ TEST_F(UnblindedTest, PromotionExpiredDeleteToken) { ON_CALL(*mock_ledger_impl_, GetAllUnblindedTokens(_)) .WillByDefault( - Invoke([](ledger::GetAllUnblindedTokensCallback callback) { + Invoke([](ledger::GetUnblindedTokenListCallback callback) { ledger::UnblindedTokenList list; auto info = ledger::UnblindedToken::New(); @@ -123,7 +123,7 @@ TEST_F(UnblindedTest, PromotionExpiredDeleteTokensNotEnoughFunds) { ON_CALL(*mock_ledger_impl_, GetAllUnblindedTokens(_)) .WillByDefault( - Invoke([](ledger::GetAllUnblindedTokensCallback callback) { + Invoke([](ledger::GetUnblindedTokenListCallback callback) { ledger::UnblindedTokenList list; auto info = ledger::UnblindedToken::New(); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util.cc index 6834acbeaac8..aed6ff10aa7d 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util.cc @@ -7,6 +7,12 @@ #include "bat/ledger/internal/contribution/contribution_util.h" +#include "wrapper.hpp" // NOLINT + +using challenge_bypass_ristretto::UnblindedToken; +using challenge_bypass_ristretto::VerificationKey; +using challenge_bypass_ristretto::VerificationSignature; + namespace braveledger_contribution { ledger::ReconcileDirections @@ -49,4 +55,41 @@ ledger::ReportType GetReportTypeFromRewardsType( } } +bool GenerateSuggestion( + const std::string& token_value, + const std::string& public_key, + const std::string& suggestion_encoded, + base::Value* result) { + if (token_value.empty() || public_key.empty() || suggestion_encoded.empty()) { + return false; + } + + UnblindedToken unblinded = UnblindedToken::decode_base64(token_value); + VerificationKey verification_key = unblinded.derive_verification_key(); + VerificationSignature signature = verification_key.sign(suggestion_encoded); + const std::string pre_image = unblinded.preimage().encode_base64(); + + if (challenge_bypass_ristretto::exception_occurred()) { + challenge_bypass_ristretto::TokenException e = + challenge_bypass_ristretto::get_last_exception(); + return false; + } + + result->SetStringKey("t", pre_image); + result->SetStringKey("publicKey", public_key); + result->SetStringKey("signature", signature.encode_base64()); + return true; +} + +bool GenerateSuggestionMock( + const std::string& token_value, + const std::string& public_key, + const std::string& suggestion_encoded, + base::Value* result) { + result->SetStringKey("t", token_value); + result->SetStringKey("publicKey", public_key); + result->SetStringKey("signature", token_value); + return true; +} + } // namespace braveledger_contribution diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util.h b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util.h index f11bd220dc05..a51220096e2f 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util.h @@ -9,6 +9,7 @@ #include #include +#include "base/values.h" #include "bat/ledger/mojom_structs.h" #include "bat/ledger/internal/properties/reconcile_direction_properties.h" @@ -20,6 +21,18 @@ FromContributionQueuePublishersToReconcileDirections( ledger::ReportType GetReportTypeFromRewardsType(const ledger::RewardsType type); +bool GenerateSuggestion( + const std::string& token_value, + const std::string& public_key, + const std::string& suggestion_encoded, + base::Value* result); + +bool GenerateSuggestionMock( + const std::string& token_value, + const std::string& public_key, + const std::string& suggestion_encoded, + base::Value* result); + } // namespace braveledger_contribution #endif // BRAVELEDGER_CONTRIBUTION_CONTRIBUTION_UTIL_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util_unittest.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util_unittest.cc new file mode 100644 index 000000000000..02f331adc919 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/contribution/contribution_util_unittest.cc @@ -0,0 +1,61 @@ +/* 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 "base/values.h" +#include "bat/ledger/internal/contribution/contribution_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +// npm run test -- brave_unit_tests --filter=ContributionUtilTest.* + +namespace braveledger_contribution { + +class ContributionUtilTest : public testing::Test {}; + +TEST_F(ContributionUtilTest, GenerateSuggestionEmptyToken) { + base::Value token(base::Value::Type::DICTIONARY); + bool success = GenerateSuggestion( + "", + "rqQ1Tz26C4mv33ld7xpcLhuX1sWaD+s7VMnuX6cokT4=", + "some id", + &token); + ASSERT_FALSE(success); +} + +TEST_F(ContributionUtilTest, GenerateSuggestionEmptyPublicKey) { + base::Value token(base::Value::Type::DICTIONARY); + bool success = GenerateSuggestion( + "Twsi4QeUNcOOW/IFnYcGLHgLsfVco0oPZ+cl3YeZMQgb4NB8E29Ts+2/pQA54VksqGpg/DtmPRBV4FlQ1VXbKmiwO9BI7jDXSN33CCb+rSBe1PCG1LtigUOfzaIVF3c5", // NOLINT + "", + "some id", + &token); + ASSERT_FALSE(success); +} + +TEST_F(ContributionUtilTest, GenerateSuggestionEmptyPayload) { + base::Value token(base::Value::Type::DICTIONARY); + bool success = GenerateSuggestion( + "Twsi4QeUNcOOW/IFnYcGLHgLsfVco0oPZ+cl3YeZMQgb4NB8E29Ts+2/pQA54VksqGpg/DtmPRBV4FlQ1VXbKmiwO9BI7jDXSN33CCb+rSBe1PCG1LtigUOfzaIVF3c5", // NOLINT + "rqQ1Tz26C4mv33ld7xpcLhuX1sWaD+s7VMnuX6cokT4=", + "", + &token); + ASSERT_FALSE(success); +} + +TEST_F(ContributionUtilTest, GenerateSuggestionGenerated) { + const std::string public_key = + "rqQ1Tz26C4mv33ld7xpcLhuX1sWaD+s7VMnuX6cokT4="; + base::Value token(base::Value::Type::DICTIONARY); + bool success = GenerateSuggestion( + "Twsi4QeUNcOOW/IFnYcGLHgLsfVco0oPZ+cl3YeZMQgb4NB8E29Ts+2/pQA54VksqGpg/DtmPRBV4FlQ1VXbKmiwO9BI7jDXSN33CCb+rSBe1PCG1LtigUOfzaIVF3c5", // NOLINT + public_key, + "some id", + &token); + ASSERT_TRUE(success); + ASSERT_EQ(*token.FindStringKey("t"), "Twsi4QeUNcOOW/IFnYcGLHgLsfVco0oPZ+cl3YeZMQgb4NB8E29Ts+2/pQA54VksqGpg/DtmPRBV4FlQ1VXbKg=="); // NOLINT + ASSERT_EQ(*token.FindStringKey("publicKey"), public_key); + ASSERT_EQ(*token.FindStringKey("signature"), "qnQvRh1dWoc/YKAGVYgP4PljOoK10T8ryMqLGY6RFc3Gig8mZCzmuGH5IQtVtCZ0x42/pOFKfX3rUpzIL4wPUw=="); // NOLINT +} + +} // namespace braveledger_contribution diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/database/database.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/database/database.cc index 562b253f31df..ec0b66b61a5a 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/database/database.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/database/database.cc @@ -329,7 +329,7 @@ void Database::SaveUnblindedTokenList( } void Database::GetAllUnblindedTokens( - ledger::GetAllUnblindedTokensCallback callback) { + ledger::GetUnblindedTokenListCallback callback) { unblinded_token_->GetAllRecords(callback); } @@ -345,4 +345,10 @@ void Database::DeleteUnblindedTokensForPromotion( unblinded_token_->DeleteRecordsForPromotion(promotion_id, callback); } +void Database::GetUnblindedTokensByPromotionType( + const std::vector& promotion_types, + ledger::GetUnblindedTokenListCallback callback) { + unblinded_token_->GetRecordsByPromotionType(promotion_types, callback); +} + } // namespace braveledger_database diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/database/database.h b/vendor/bat-native-ledger/src/bat/ledger/internal/database/database.h index 5a7051c75131..78a9155e1a88 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/database/database.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/database/database.h @@ -226,7 +226,7 @@ class Database { ledger::ResultCallback callback); void GetAllUnblindedTokens( - ledger::GetAllUnblindedTokensCallback callback); + ledger::GetUnblindedTokenListCallback callback); void DeleteUnblindedTokens( const std::vector& ids, @@ -236,6 +236,10 @@ class Database { const std::string& promotion_id, ledger::ResultCallback callback); + void GetUnblindedTokensByPromotionType( + const std::vector& promotion_types, + ledger::GetUnblindedTokenListCallback callback); + private: std::unique_ptr initialize_; std::unique_ptr activity_info_; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_unblinded_token.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_unblinded_token.cc index 49e29eb38d96..2c707283447d 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_unblinded_token.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_unblinded_token.cc @@ -245,7 +245,7 @@ void DatabaseUnblindedToken::InsertOrUpdateList( } void DatabaseUnblindedToken::GetAllRecords( - ledger::GetAllUnblindedTokensCallback callback) { + ledger::GetUnblindedTokenListCallback callback) { auto transaction = ledger::DBTransaction::New(); const std::string query = base::StringPrintf( @@ -281,7 +281,7 @@ void DatabaseUnblindedToken::GetAllRecords( void DatabaseUnblindedToken::OnGetAllRecords( ledger::DBCommandResponsePtr response, - ledger::GetAllUnblindedTokensCallback callback) { + ledger::GetUnblindedTokenListCallback callback) { if (!response || response->status != ledger::DBCommandResponse::Status::RESPONSE_OK) { callback({}); @@ -365,4 +365,69 @@ void DatabaseUnblindedToken::DeleteRecordsForPromotion( ledger_->RunDBTransaction(std::move(transaction), transaction_callback); } +void DatabaseUnblindedToken::GetRecordsByPromotionType( + const std::vector& promotion_types, + ledger::GetUnblindedTokenListCallback callback) { + DCHECK(!promotion_types.empty()); + auto transaction = ledger::DBTransaction::New(); + std::vector in_case; + + for (const auto& type : promotion_types) { + in_case.push_back(std::to_string(static_cast(type))); + } + + const std::string query = base::StringPrintf( + "SELECT u.token_id, u.token_value, u.public_key, u.value FROM %s as u " + "INNER JOIN promotion as p ON p.promotion_id = u.promotion_id " + "WHERE p.type IN (%s)", + table_name_, + base::JoinString(in_case, ",").c_str()); + + auto command = ledger::DBCommand::New(); + command->type = ledger::DBCommand::Type::READ; + command->command = query; + + command->record_bindings = { + ledger::DBCommand::RecordBindingType::INT64_TYPE, + ledger::DBCommand::RecordBindingType::STRING_TYPE, + ledger::DBCommand::RecordBindingType::STRING_TYPE, + ledger::DBCommand::RecordBindingType::DOUBLE_TYPE + }; + + transaction->commands.push_back(std::move(command)); + + auto transaction_callback = + std::bind(&DatabaseUnblindedToken::OnGetRecordsByPromotionType, + this, + _1, + callback); + + ledger_->RunDBTransaction(std::move(transaction), transaction_callback); +} + +void DatabaseUnblindedToken::OnGetRecordsByPromotionType( + ledger::DBCommandResponsePtr response, + ledger::GetUnblindedTokenListCallback callback) { + if (!response + || response->status != ledger::DBCommandResponse::Status::RESPONSE_OK) { + callback({}); + return; + } + + ledger::UnblindedTokenList list; + for (auto const& record : response->result->get_records()) { + auto info = ledger::UnblindedToken::New(); + auto* record_pointer = record.get(); + + info->id = GetInt64Column(record_pointer, 0); + info->token_value = GetStringColumn(record_pointer, 1); + info->public_key = GetStringColumn(record_pointer, 2); + info->value = GetDoubleColumn(record_pointer, 3); + + list.push_back(std::move(info)); + } + + callback(std::move(list)); +} + } // namespace braveledger_database diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_unblinded_token.h b/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_unblinded_token.h index 1ea11e66c592..5bada264c9ff 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_unblinded_token.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/database/database_unblinded_token.h @@ -24,7 +24,7 @@ class DatabaseUnblindedToken: public DatabaseTable { ledger::UnblindedTokenList list, ledger::ResultCallback callback); - void GetAllRecords(ledger::GetAllUnblindedTokensCallback callback); + void GetAllRecords(ledger::GetUnblindedTokenListCallback callback); void DeleteRecordList( const std::vector& ids, @@ -34,6 +34,10 @@ class DatabaseUnblindedToken: public DatabaseTable { const std::string& promotion_id, ledger::ResultCallback callback); + void GetRecordsByPromotionType( + const std::vector& promotion_types, + ledger::GetUnblindedTokenListCallback callback); + private: bool CreateTableV10(ledger::DBTransaction* transaction); @@ -51,7 +55,11 @@ class DatabaseUnblindedToken: public DatabaseTable { void OnGetAllRecords( ledger::DBCommandResponsePtr response, - ledger::GetAllUnblindedTokensCallback callback); + ledger::GetUnblindedTokenListCallback callback); + + void OnGetRecordsByPromotionType( + ledger::DBCommandResponsePtr response, + ledger::GetUnblindedTokenListCallback callback); }; } // namespace braveledger_database 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 46f4736c10f8..c2c2e8abea34 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 @@ -1379,8 +1379,8 @@ void LedgerImpl::DisconnectWallet( void LedgerImpl::TransferAnonToExternalWallet( ledger::ExternalWalletPtr wallet, - const bool allow_zero_balance, - ledger::TransferAnonToExternalWalletCallback callback) { + ledger::TransferAnonToExternalWalletCallback callback, + const bool allow_zero_balance) { bat_wallet_->TransferAnonToExternalWallet( std::move(wallet), allow_zero_balance, @@ -1574,7 +1574,7 @@ void LedgerImpl::SaveUnblindedTokenList( } void LedgerImpl::GetAllUnblindedTokens( - ledger::GetAllUnblindedTokensCallback callback) { + ledger::GetUnblindedTokenListCallback callback) { bat_database_->GetAllUnblindedTokens(callback); } @@ -1677,4 +1677,16 @@ void LedgerImpl::GetAllMonthlyReportIds( bat_report_->GetAllMonthlyIds(callback); } +void LedgerImpl::TransferTokens( + ledger::ExternalWalletPtr wallet, + ledger::ResultCallback callback) { + bat_promotion_->TransferTokens(std::move(wallet), callback); +} + +void LedgerImpl::GetUnblindedTokensByPromotionType( + const std::vector& promotion_types, + ledger::GetUnblindedTokenListCallback callback) { + bat_database_->GetUnblindedTokensByPromotionType(promotion_types, callback); +} + } // namespace bat_ledger diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h index 963a5006ef34..71dd12c8f2fc 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl.h @@ -519,8 +519,8 @@ class LedgerImpl : public ledger::Ledger, void TransferAnonToExternalWallet( ledger::ExternalWalletPtr wallet, - const bool allow_zero_balance, - ledger::TransferAnonToExternalWalletCallback callback); + ledger::TransferAnonToExternalWalletCallback callback, + const bool allow_zero_balance = false); void ShowNotification( const std::string& type, @@ -626,7 +626,7 @@ class LedgerImpl : public ledger::Ledger, ledger::ResultCallback callback); virtual void GetAllUnblindedTokens( - ledger::GetAllUnblindedTokensCallback callback); + ledger::GetUnblindedTokenListCallback callback); virtual void DeleteUnblindedTokens( const std::vector& id_list, @@ -687,6 +687,14 @@ class LedgerImpl : public ledger::Ledger, void GetAllMonthlyReportIds( ledger::GetAllMonthlyReportIdsCallback callback) override; + void TransferTokens( + ledger::ExternalWalletPtr wallet, + ledger::ResultCallback callback); + + void GetUnblindedTokensByPromotionType( + const std::vector& promotion_types, + ledger::GetUnblindedTokenListCallback callback); + private: void InitializeConfirmations( const bool execute_create_script, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl_mock.h b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl_mock.h index e1e302468bbd..bc758fdeb13c 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl_mock.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/ledger_impl_mock.h @@ -481,8 +481,8 @@ class MockLedgerImpl : public LedgerImpl { MOCK_METHOD3(TransferAnonToExternalWallet, void(ledger::ExternalWalletPtr, - const bool, - ledger::TransferAnonToExternalWalletCallback)); + ledger::TransferAnonToExternalWalletCallback, + const bool)); MOCK_METHOD3(ShowNotification, void(const std::string&, @@ -580,7 +580,7 @@ class MockLedgerImpl : public LedgerImpl { ledger::UnblindedTokenList, ledger::ResultCallback)); MOCK_METHOD1(GetAllUnblindedTokens, - void(ledger::GetAllUnblindedTokensCallback)); + void(ledger::GetUnblindedTokenListCallback)); MOCK_METHOD2(DeleteUnblindedTokens, void(const std::vector&, ledger::ResultCallback)); diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion.cc index 0f5a7917ced6..f89c474224c3 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion.cc @@ -25,6 +25,7 @@ #include "bat/ledger/internal/common/security_helper.h" #include "bat/ledger/internal/common/time_util.h" #include "bat/ledger/internal/promotion/promotion_util.h" +#include "bat/ledger/internal/promotion/promotion_transfer.h" #include "brave_base/random.h" #include "net/http/http_status_code.h" @@ -80,6 +81,7 @@ void HandleExpiredPromotions( Promotion::Promotion(bat_ledger::LedgerImpl* ledger) : attestation_(std::make_unique (ledger)), + transfer_(std::make_unique(ledger)), ledger_(ledger) { } @@ -910,4 +912,10 @@ void Promotion::PromotionListDeleted(const ledger::Result result) { ledger_->SetBooleanState(ledger::kStatePromotionCorruptedMigrated, true); } +void Promotion::TransferTokens( + ledger::ExternalWalletPtr wallet, + ledger::ResultCallback callback) { + transfer_->Start(std::move(wallet), callback); +} + } // namespace braveledger_promotion diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion.h b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion.h index 89d6b4184e7b..5caf960a4c2e 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion.h @@ -21,6 +21,8 @@ class LedgerImpl; namespace braveledger_promotion { +class PromotionTransfer; + class Promotion { public: explicit Promotion(bat_ledger::LedgerImpl* ledger); @@ -47,6 +49,10 @@ class Promotion { ledger::PromotionPtr promotion, ledger::ResultCallback callback); + void TransferTokens( + ledger::ExternalWalletPtr wallet, + ledger::ResultCallback callback); + private: void OnFetch( const int response_status_code, @@ -152,6 +158,7 @@ class Promotion { void PromotionListDeleted(const ledger::Result result); std::unique_ptr attestation_; + std::unique_ptr transfer_; bat_ledger::LedgerImpl* ledger_; // NOT OWNED uint32_t last_check_timer_id_; uint32_t retry_timer_id_; diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_transfer.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_transfer.cc new file mode 100644 index 000000000000..5177d9145d21 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_transfer.cc @@ -0,0 +1,174 @@ +/* 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 "base/json/json_writer.h" +#include "base/values.h" +#include "bat/ledger/internal/contribution/contribution_util.h" +#include "bat/ledger/internal/ledger_impl.h" +#include "bat/ledger/internal/promotion/promotion_transfer.h" +#include "bat/ledger/internal/promotion/promotion_util.h" +#include "bat/ledger/internal/request/promotion_requests.h" +#include "bat/ledger/internal/request/request_util.h" +#include "bat/ledger/internal/state_keys.h" +#include "net/http/http_status_code.h" + +using std::placeholders::_1; +using std::placeholders::_2; +using std::placeholders::_3; + +namespace braveledger_promotion { + +PromotionTransfer::PromotionTransfer(bat_ledger::LedgerImpl* ledger) : + ledger_(ledger) { + DCHECK(ledger_); +} + +PromotionTransfer::~PromotionTransfer() = default; + +void PromotionTransfer::Start( + ledger::ExternalWalletPtr wallet, + ledger::ResultCallback callback) { + // we only need to call old anon api once + if (ledger_->GetBooleanState(ledger::kStateAnonTransferChecked)) { + GetEligibleTokens(callback); + return; + } + + if (!wallet) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << "Wallet is empty"; + callback(ledger::Result::LEDGER_ERROR); + return; + } + + auto transfer_callback = std::bind(&PromotionTransfer::OnAnonExternalWallet, + this, + _1, + callback); + + ledger_->TransferAnonToExternalWallet( + std::move(wallet), + transfer_callback, + true); +} + +void PromotionTransfer::OnAnonExternalWallet( + const ledger::Result result, + ledger::ResultCallback callback) { + if (result != ledger::Result::LEDGER_OK) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) << "Initial transfer failed"; + callback(ledger::Result::LEDGER_ERROR); + return; + } + + ledger_->SetBooleanState(ledger::kStateAnonTransferChecked, true); + GetEligibleTokens(callback); +} + +void PromotionTransfer::GetEligibleTokens(ledger::ResultCallback callback) { + auto tokens_callback = std::bind(&PromotionTransfer::SendTokens, + this, + _1, + callback); + + ledger_->GetUnblindedTokensByPromotionType( + GetEligiblePromotions(), + tokens_callback); +} + +void PromotionTransfer::SendTokens( + ledger::UnblindedTokenList list, + ledger::ResultCallback callback) { + if (list.empty()) { + callback(ledger::Result::LEDGER_OK); + return; + } + + base::Value credentials(base::Value::Type::LIST); + std::vector tokens_ids; + + for (auto& item : list) { + if (!item) { + continue; + } + + base::Value token(base::Value::Type::DICTIONARY); + bool success = false; + if (ledger::is_testing) { + success = braveledger_contribution::GenerateSuggestionMock( + item->token_value, + item->public_key, + ledger_->GetPaymentId(), + &token); + } else { + success = braveledger_contribution::GenerateSuggestion( + item->token_value, + item->public_key, + ledger_->GetPaymentId(), + &token); + } + + if (!success) { + BLOG(ledger_, ledger::LogLevel::LOG_ERROR) + << "Token was not generated successfully. Token: " + << item->token_value; + continue; + } + + credentials.GetList().push_back(std::move(token)); + tokens_ids.push_back(std::to_string(item->id)); + } + + base::Value body(base::Value::Type::DICTIONARY); + body.SetStringKey("paymentId", ledger_->GetPaymentId()); + body.SetKey("credentials", std::move(credentials)); + + std::string json; + base::JSONWriter::Write(body, &json); + + const std::string url = braveledger_request_util::GetTransferTokens(); + + auto url_callback = std::bind(&PromotionTransfer::DeleteTokens, + this, + _1, + _2, + _3, + tokens_ids, + std::move(callback)); + + ledger::WalletInfoProperties wallet_info = ledger_->GetWalletInfo(); + const auto headers = braveledger_request_util::BuildSignHeaders( + "post /v1/suggestions/claim", + json, + ledger_->GetPaymentId(), + wallet_info.key_info_seed); + + ledger_->LoadURL( + url, + headers, + json, + "application/json; charset=utf-8", + ledger::UrlMethod::POST, + url_callback); +} + +void PromotionTransfer::DeleteTokens( + const int response_status_code, + const std::string& response, + const std::map& headers, + const std::vector& sent_ids, + ledger::ResultCallback callback) { + ledger_->LogResponse(__func__, response_status_code, response, headers); + + if (response_status_code != net::HTTP_OK) { + callback(ledger::Result::LEDGER_ERROR); + return; + } + + ledger_->DeleteUnblindedTokens(sent_ids, callback); +} + +} // namespace braveledger_promotion diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_transfer.h b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_transfer.h new file mode 100644 index 000000000000..00b9c70e50a8 --- /dev/null +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_transfer.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 BRAVELEDGER_PROMOTION_TRANSFER_H_ +#define BRAVELEDGER_PROMOTION_TRANSFER_H_ + +#include +#include +#include + +#include "bat/ledger/ledger.h" + +namespace bat_ledger { +class LedgerImpl; +} + +namespace braveledger_promotion { + +class PromotionTransfer { + public: + explicit PromotionTransfer(bat_ledger::LedgerImpl* ledger); + ~PromotionTransfer(); + + void Start(ledger::ExternalWalletPtr wallet, ledger::ResultCallback callback); + + private: + void OnAnonExternalWallet( + const ledger::Result result, + ledger::ResultCallback callback); + + void GetEligibleTokens(ledger::ResultCallback callback); + + void SendTokens( + ledger::UnblindedTokenList list, + ledger::ResultCallback callback); + + void DeleteTokens( + const int response_status_code, + const std::string& response, + const std::map& headers, + const std::vector& sent_ids, + ledger::ResultCallback callback); + + bat_ledger::LedgerImpl* ledger_; // NOT OWNED +}; + +} // namespace braveledger_promotion + +#endif // BRAVELEDGER_PROMOTION_TRANSFER_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_util.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_util.cc index baddbce39290..063274b7c35f 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_util.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_util.cc @@ -387,4 +387,10 @@ bool VerifyPublicKey(const ledger::PromotionPtr promotion) { return false; } +std::vector GetEligiblePromotions() { + return { + ledger::PromotionType::ADS + }; +} + } // namespace braveledger_promotion diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_util.h b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_util.h index 3581a552f084..33e4f8f80c86 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_util.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/promotion/promotion_util.h @@ -49,6 +49,8 @@ bool UnBlindTokensMock( bool VerifyPublicKey(const ledger::PromotionPtr promotion); +std::vector GetEligiblePromotions(); + } // namespace braveledger_promotion #endif // BRAVELEDGER_PROMOTION_PROMOTION_UTIL_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/request/promotion_requests.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/request/promotion_requests.cc index 28f2328fcae1..06e184d7deb5 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/request/promotion_requests.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/request/promotion_requests.cc @@ -55,4 +55,8 @@ std::string ReportClobberedClaimsUrl() { ServerTypes::kPromotion); } +std::string GetTransferTokens() { + return BuildUrl("/suggestions/claim", PREFIX_V1, ServerTypes::kPromotion); +} + } // namespace braveledger_request_util diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/request/promotion_requests.h b/vendor/bat-native-ledger/src/bat/ledger/internal/request/promotion_requests.h index 2c04f0c87452..d60ab4e80234 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/request/promotion_requests.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/request/promotion_requests.h @@ -24,6 +24,8 @@ std::string GetReedemSuggestionsUrl(); std::string ReportClobberedClaimsUrl(); +std::string GetTransferTokens(); + } // namespace braveledger_request_util #endif // BRAVELEDGER_COMMON_PROMOTION_REQUESTS_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/state_keys.h b/vendor/bat-native-ledger/src/bat/ledger/internal/state_keys.h index dd773bf940af..c833c60e4c24 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/state_keys.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/state_keys.h @@ -14,6 +14,7 @@ namespace ledger { const char kStatePromotionLastFetchStamp[] = "promotion_last_fetch_stamp"; const char kStatePromotionCorruptedMigrated[] = "promotion_corrupted_migrated"; + const char kStateAnonTransferChecked[] = "anon_transfer_checked"; } // namespace ledger #endif // BRAVELEDGER_STATE_KEYS_H_ diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold.cc index aa3298487b35..ffb2a02037df 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold.cc @@ -203,7 +203,6 @@ void Uphold::WalletAuthorization( void Uphold::TransferAnonToExternalWallet( ledger::ExternalWalletPtr wallet, - const bool allow_zero_balance, ledger::ExternalWalletCallback callback) { auto transfer_callback = std::bind( &Uphold::OnTransferAnonToExternalWalletCallback, @@ -213,10 +212,7 @@ void Uphold::TransferAnonToExternalWallet( _1); // transfer funds from anon wallet to uphold - ledger_->TransferAnonToExternalWallet( - std::move(wallet), - allow_zero_balance, - transfer_callback); + ledger_->TransferAnonToExternalWallet(std::move(wallet), transfer_callback); } void Uphold::GenerateExternalWallet( @@ -236,7 +232,8 @@ void Uphold::OnTransferAnonToExternalWalletCallback( const ledger::ExternalWallet& wallet, ledger::Result result) { auto wallet_ptr = ledger::ExternalWallet::New(wallet); - if (result == ledger::Result::LEDGER_OK) { + if (result == ledger::Result::LEDGER_OK || + result == ledger::Result::ALREADY_EXISTS) { wallet_ptr->transferred = true; } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold.h b/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold.h index 51f1dba9aebf..9e999cad6f22 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold.h @@ -68,7 +68,6 @@ class Uphold { void TransferAnonToExternalWallet( ledger::ExternalWalletPtr wallet, - const bool allow_zero_balance, ledger::ExternalWalletCallback callback); void GenerateExternalWallet( diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_wallet.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_wallet.cc index c606fb9e23c3..d9d73e282098 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_wallet.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_wallet.cc @@ -96,33 +96,16 @@ void UpholdWallet::OnGenerate( wallet_ptr->user_name = user.name; - bool allow_zero_balance = false; - if (user.status != UserStatus::OK) { wallet_ptr->status = ledger::WalletStatus::PENDING; } - const auto current_status = wallet_ptr->status; wallet_ptr = SetStatus(user, std::move(wallet_ptr)); - if (current_status == ledger::WalletStatus::CONNECTED && - wallet_ptr->status == ledger::WalletStatus::VERIFIED) { - allow_zero_balance = true; - } - - // if we don't have anon address we need to force claim so that server - // can save it - const std::string anon_address = - ledger_->GetStringState(ledger::kStateUpholdAnonAddress); - if (anon_address.empty()) { - allow_zero_balance = true; - } - if (wallet_ptr->address.empty()) { auto card_callback = std::bind( &UpholdWallet::OnCreateCard, this, - allow_zero_balance, *wallet_ptr, callback, _1, @@ -132,10 +115,8 @@ void UpholdWallet::OnGenerate( } if (user.verified) { - uphold_->TransferAnonToExternalWallet( - std::move(wallet_ptr), - allow_zero_balance, - callback); + ledger_->TransferTokens(wallet_ptr->Clone(), [](const ledger::Result){}); + uphold_->TransferAnonToExternalWallet(std::move(wallet_ptr), callback); return; } @@ -144,7 +125,6 @@ void UpholdWallet::OnGenerate( } void UpholdWallet::OnCreateCard( - const bool allow_zero_balance, const ledger::ExternalWallet& wallet, ledger::ExternalWalletCallback callback, const ledger::Result result, @@ -159,10 +139,8 @@ void UpholdWallet::OnCreateCard( wallet_ptr = GenerateLinks(std::move(wallet_ptr)); if (wallet_ptr->status == ledger::WalletStatus::VERIFIED) { - uphold_->TransferAnonToExternalWallet( - std::move(wallet_ptr), - allow_zero_balance, - callback); + ledger_->TransferTokens(wallet_ptr->Clone(), [](const ledger::Result){}); + uphold_->TransferAnonToExternalWallet(std::move(wallet_ptr), callback); return; } diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_wallet.h b/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_wallet.h index 54c167d9de38..dd79f25a09dd 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_wallet.h +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_wallet.h @@ -36,7 +36,6 @@ class UpholdWallet { ledger::ExternalWalletCallback callback); void OnCreateCard( - const bool allow_zero_balance, const ledger::ExternalWallet& wallet, ledger::ExternalWalletCallback callback, const ledger::Result result, diff --git a/vendor/bat-native-ledger/src/bat/ledger/internal/wallet/wallet.cc b/vendor/bat-native-ledger/src/bat/ledger/internal/wallet/wallet.cc index 45f2a31cb2c9..0e71976b7c90 100644 --- a/vendor/bat-native-ledger/src/bat/ledger/internal/wallet/wallet.cc +++ b/vendor/bat-native-ledger/src/bat/ledger/internal/wallet/wallet.cc @@ -268,11 +268,14 @@ void Wallet::OnTransferAnonToExternalWallet( ledger::TransferAnonToExternalWalletCallback callback) { ledger_->LogResponse(__func__, response_status_code, response, headers); - if (response_status_code == net::HTTP_OK || - response_status_code == net::HTTP_CONFLICT) { + if (response_status_code == net::HTTP_OK) { callback(ledger::Result::LEDGER_OK); return; } + if (response_status_code == net::HTTP_CONFLICT) { + callback(ledger::Result::ALREADY_EXISTS); + return; + } callback(ledger::Result::LEDGER_ERROR); } @@ -281,7 +284,6 @@ void Wallet::TransferAnonToExternalWallet( ledger::ExternalWalletPtr wallet, const bool allow_zero_balance, ledger::TransferAnonToExternalWalletCallback callback) { - FetchBalance(std::bind(&Wallet::OnTransferAnonToExternalWalletBalance, this, _1,