Store creator hash prefixes in a separate lookup file (#27731)
[Rewards] Store creator hash prefixes in a separate lookup file
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
#include "brave/components/brave_rewards/content/service_sandbox_type.h"
|
||||
#include "brave/components/brave_rewards/core/buildflags/buildflags.h"
|
||||
#include "brave/components/brave_rewards/core/engine/global_constants.h"
|
||||
#include "brave/components/brave_rewards/core/engine/hash_prefix_store.h"
|
||||
#include "brave/components/brave_rewards/core/engine/parameters/rewards_parameters_provider.h"
|
||||
#include "brave/components/brave_rewards/core/engine/rewards_database.h"
|
||||
#include "brave/components/brave_rewards/core/features.h"
|
||||
@@ -235,12 +236,14 @@ void DeferCallback(base::Location location, Callback callback, Args&&... args) {
|
||||
|
||||
// read comment about file pathes at src\base\files\file_path.h
|
||||
#if BUILDFLAG(IS_WIN)
|
||||
const base::FilePath::StringType kCreatorPrefixStore(L"RewardsCreators.db");
|
||||
const base::FilePath::StringType kDiagnosticLogPath(L"Rewards.log");
|
||||
const base::FilePath::StringType kLegacy_state(L"ledger_state");
|
||||
const base::FilePath::StringType kPublisher_state(L"publisher_state");
|
||||
const base::FilePath::StringType kPublisher_info_db(L"publisher_info_db");
|
||||
const base::FilePath::StringType kPublishers_list(L"publishers_list");
|
||||
#else
|
||||
const base::FilePath::StringType kCreatorPrefixStore("RewardsCreators.db");
|
||||
const base::FilePath::StringType kDiagnosticLogPath("Rewards.log");
|
||||
const base::FilePath::StringType kLegacy_state("ledger_state");
|
||||
const base::FilePath::StringType kPublisher_state("publisher_state");
|
||||
@@ -272,6 +275,7 @@ RewardsServiceImpl::RewardsServiceImpl(
|
||||
publisher_state_path_(profile_path.Append(kPublisher_state)),
|
||||
publisher_info_db_path_(profile_path.Append(kPublisher_info_db)),
|
||||
publisher_list_path_(profile_path.Append(kPublishers_list)),
|
||||
creator_prefix_store_path_(profile_path.Append(kCreatorPrefixStore)),
|
||||
diagnostic_log_(new DiagnosticLog(profile_path.Append(kDiagnosticLogPath),
|
||||
kDiagnosticLogMaxFileSize,
|
||||
kDiagnosticLogKeepNumLines)),
|
||||
@@ -386,6 +390,9 @@ void RewardsServiceImpl::StartEngineProcessIfNecessary() {
|
||||
rewards_database_ = base::SequenceBound<internal::RewardsDatabase>(
|
||||
file_task_runner_, publisher_info_db_path_);
|
||||
|
||||
creator_prefix_store_ = base::SequenceBound<internal::HashPrefixStore>(
|
||||
file_task_runner_, creator_prefix_store_path_);
|
||||
|
||||
BLOG(1, "Starting engine process");
|
||||
|
||||
if (!engine_factory_.is_bound()) {
|
||||
@@ -1066,10 +1073,8 @@ void RewardsServiceImpl::OnDiagnosticLogDeletedForCompleteReset(
|
||||
bool success) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
const std::vector<base::FilePath> paths = {
|
||||
legacy_state_path_,
|
||||
publisher_state_path_,
|
||||
publisher_info_db_path_,
|
||||
publisher_list_path_,
|
||||
legacy_state_path_, publisher_state_path_, publisher_info_db_path_,
|
||||
publisher_list_path_, creator_prefix_store_path_,
|
||||
};
|
||||
file_task_runner_->PostTaskAndReplyWithResult(
|
||||
FROM_HERE, base::BindOnce(&DeleteFilesOnFileTaskRunner, paths),
|
||||
@@ -1092,6 +1097,7 @@ void RewardsServiceImpl::Reset() {
|
||||
engine_factory_.reset();
|
||||
ready_ = std::make_unique<base::OneShotEvent>();
|
||||
rewards_database_.Reset();
|
||||
creator_prefix_store_.Reset();
|
||||
BLOG(1, "Successfully reset rewards service");
|
||||
}
|
||||
|
||||
@@ -2103,6 +2109,22 @@ void RewardsServiceImpl::OnRunDBTransaction(
|
||||
std::move(callback).Run(std::move(response));
|
||||
}
|
||||
|
||||
void RewardsServiceImpl::UpdateCreatorPrefixStore(
|
||||
mojom::HashPrefixDataPtr prefix_data,
|
||||
UpdateCreatorPrefixStoreCallback callback) {
|
||||
creator_prefix_store_.AsyncCall(&internal::HashPrefixStore::UpdatePrefixes)
|
||||
.WithArgs(std::move(prefix_data->prefixes), prefix_data->prefix_size)
|
||||
.Then(std::move(callback));
|
||||
}
|
||||
|
||||
void RewardsServiceImpl::CreatorPrefixStoreContains(
|
||||
const std::string& value,
|
||||
CreatorPrefixStoreContainsCallback callback) {
|
||||
creator_prefix_store_.AsyncCall(&internal::HashPrefixStore::ContainsPrefix)
|
||||
.WithArgs(value)
|
||||
.Then(std::move(callback));
|
||||
}
|
||||
|
||||
void RewardsServiceImpl::ForTestingSetTestResponseCallback(
|
||||
const GetTestResponseCallback& callback) {
|
||||
test_response_callback_ = callback;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "brave/components/brave_rewards/content/diagnostic_log.h"
|
||||
#include "brave/components/brave_rewards/content/rewards_p3a.h"
|
||||
#include "brave/components/brave_rewards/content/rewards_service.h"
|
||||
#include "brave/components/brave_rewards/core/mojom/rewards_database.mojom.h"
|
||||
#include "brave/components/brave_rewards/core/mojom/rewards_engine.mojom.h"
|
||||
#include "brave/components/brave_rewards/core/rewards_flags.h"
|
||||
#include "brave/components/brave_wallet/browser/brave_wallet_service.h"
|
||||
@@ -60,6 +61,7 @@ namespace brave_rewards {
|
||||
class RewardsFlagBrowserTest;
|
||||
|
||||
namespace internal {
|
||||
class HashPrefixStore;
|
||||
class RewardsDatabase;
|
||||
} // namespace internal
|
||||
|
||||
@@ -429,6 +431,14 @@ class RewardsServiceImpl final : public RewardsService,
|
||||
void RunDBTransaction(mojom::DBTransactionPtr transaction,
|
||||
RunDBTransactionCallback callback) override;
|
||||
|
||||
void UpdateCreatorPrefixStore(
|
||||
mojom::HashPrefixDataPtr prefix_data,
|
||||
UpdateCreatorPrefixStoreCallback callback) override;
|
||||
|
||||
void CreatorPrefixStoreContains(
|
||||
const std::string& value,
|
||||
CreatorPrefixStoreContainsCallback callback) override;
|
||||
|
||||
void ClearAllNotifications() override;
|
||||
|
||||
void ExternalWalletConnected() override;
|
||||
@@ -502,9 +512,11 @@ class RewardsServiceImpl final : public RewardsService,
|
||||
const base::FilePath publisher_state_path_;
|
||||
const base::FilePath publisher_info_db_path_;
|
||||
const base::FilePath publisher_list_path_;
|
||||
const base::FilePath creator_prefix_store_path_;
|
||||
|
||||
std::unique_ptr<DiagnosticLog> diagnostic_log_;
|
||||
base::SequenceBound<internal::RewardsDatabase> rewards_database_;
|
||||
base::SequenceBound<internal::HashPrefixStore> creator_prefix_store_;
|
||||
std::unique_ptr<RewardsNotificationServiceImpl> notification_service_;
|
||||
std::unique_ptr<RewardsServiceObserver> extension_observer_;
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ static_library("core") {
|
||||
"//base",
|
||||
"//brave/components/l10n/common",
|
||||
"//components/prefs",
|
||||
"//mojo/public/mojom/base",
|
||||
"//net",
|
||||
"//url",
|
||||
]
|
||||
|
||||
@@ -146,8 +146,6 @@ static_library("engine") {
|
||||
"database/database_migration.h",
|
||||
"database/database_publisher_info.cc",
|
||||
"database/database_publisher_info.h",
|
||||
"database/database_publisher_prefix_list.cc",
|
||||
"database/database_publisher_prefix_list.h",
|
||||
"database/database_recurring_tip.cc",
|
||||
"database/database_recurring_tip.h",
|
||||
"database/database_server_publisher_banner.cc",
|
||||
@@ -203,6 +201,7 @@ static_library("engine") {
|
||||
"database/migration/migration_v39.h",
|
||||
"database/migration/migration_v4.h",
|
||||
"database/migration/migration_v40.h",
|
||||
"database/migration/migration_v41.h",
|
||||
"database/migration/migration_v5.h",
|
||||
"database/migration/migration_v6.h",
|
||||
"database/migration/migration_v7.h",
|
||||
@@ -299,6 +298,9 @@ static_library("engine") {
|
||||
"endpoints/zebpay/post_oauth_zebpay.h",
|
||||
"gemini/gemini.cc",
|
||||
"gemini/gemini.h",
|
||||
"hash_prefix_iterator.h",
|
||||
"hash_prefix_store.cc",
|
||||
"hash_prefix_store.h",
|
||||
"initialization_manager.cc",
|
||||
"initialization_manager.h",
|
||||
"legacy/bat_state.cc",
|
||||
@@ -329,7 +331,6 @@ static_library("engine") {
|
||||
"publisher/media/media.h",
|
||||
"publisher/media/youtube.cc",
|
||||
"publisher/media/youtube.h",
|
||||
"publisher/prefix_iterator.h",
|
||||
"publisher/prefix_list_reader.cc",
|
||||
"publisher/prefix_list_reader.h",
|
||||
"publisher/prefix_util.cc",
|
||||
@@ -365,6 +366,8 @@ static_library("engine") {
|
||||
"state/state_migration_v13.h",
|
||||
"state/state_migration_v14.cc",
|
||||
"state/state_migration_v14.h",
|
||||
"state/state_migration_v15.cc",
|
||||
"state/state_migration_v15.h",
|
||||
"state/state_migration_v2.cc",
|
||||
"state/state_migration_v2.h",
|
||||
"state/state_migration_v3.cc",
|
||||
|
||||
@@ -26,7 +26,6 @@ Database::Database(RewardsEngine& engine)
|
||||
external_transactions_(engine),
|
||||
media_publisher_info_(engine),
|
||||
publisher_info_(engine),
|
||||
publisher_prefix_list_(engine),
|
||||
recurring_tip_(engine),
|
||||
server_publisher_info_(engine),
|
||||
sku_order_(engine),
|
||||
@@ -358,17 +357,6 @@ void Database::RemoveRecurringTip(const std::string& publisher_key,
|
||||
/**
|
||||
* SERVER PUBLISHER INFO
|
||||
*/
|
||||
void Database::SearchPublisherPrefixList(
|
||||
const std::string& publisher_prefix,
|
||||
SearchPublisherPrefixListCallback callback) {
|
||||
publisher_prefix_list_.Search(publisher_prefix, std::move(callback));
|
||||
}
|
||||
|
||||
void Database::ResetPublisherPrefixList(publisher::PrefixListReader reader,
|
||||
ResultCallback callback) {
|
||||
publisher_prefix_list_.Reset(std::move(reader), std::move(callback));
|
||||
}
|
||||
|
||||
void Database::InsertServerPublisherInfo(
|
||||
const mojom::ServerPublisherInfo& server_info,
|
||||
ResultCallback callback) {
|
||||
|
||||
@@ -26,13 +26,11 @@
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_initialize.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_media_publisher_info.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_publisher_info.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_publisher_prefix_list.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_recurring_tip.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_server_publisher_info.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_sku_order.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_sku_transaction.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_unblinded_token.h"
|
||||
#include "brave/components/brave_rewards/core/engine/publisher/prefix_list_reader.h"
|
||||
#include "brave/components/brave_rewards/core/engine/rewards_callbacks.h"
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
@@ -232,12 +230,6 @@ class Database {
|
||||
/**
|
||||
* SERVER PUBLISHER INFO
|
||||
*/
|
||||
void SearchPublisherPrefixList(const std::string& publisher_key,
|
||||
SearchPublisherPrefixListCallback callback);
|
||||
|
||||
void ResetPublisherPrefixList(publisher::PrefixListReader reader,
|
||||
ResultCallback callback);
|
||||
|
||||
void InsertServerPublisherInfo(const mojom::ServerPublisherInfo& server_info,
|
||||
ResultCallback callback);
|
||||
|
||||
@@ -317,7 +309,6 @@ class Database {
|
||||
DatabaseExternalTransactions external_transactions_;
|
||||
DatabaseMediaPublisherInfo media_publisher_info_;
|
||||
DatabasePublisherInfo publisher_info_;
|
||||
DatabasePublisherPrefixList publisher_prefix_list_;
|
||||
DatabaseRecurringTip recurring_tip_;
|
||||
DatabaseServerPublisherInfo server_publisher_info_;
|
||||
DatabaseSKUOrder sku_order_;
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "brave/components/brave_rewards/core/engine/database/migration/migration_v39.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/migration/migration_v4.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/migration/migration_v40.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/migration/migration_v41.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/migration/migration_v5.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/migration/migration_v6.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/migration/migration_v7.h"
|
||||
@@ -140,7 +141,8 @@ void DatabaseMigration::Start(uint32_t table_version, ResultCallback callback) {
|
||||
migration::v37,
|
||||
migration::v38,
|
||||
migration::v39,
|
||||
migration::v40};
|
||||
migration::v40,
|
||||
migration::v41};
|
||||
|
||||
DCHECK_LE(target_version, mappings.size());
|
||||
|
||||
|
||||
@@ -829,4 +829,11 @@ TEST_F(RewardsDatabaseMigrationTest, Migration_40) {
|
||||
EXPECT_FALSE(GetDB()->DoesTableExist("processed_publisher"));
|
||||
}
|
||||
|
||||
TEST_F(RewardsDatabaseMigrationTest, Migration_41) {
|
||||
DatabaseMigration::SetTargetVersionForTesting(41);
|
||||
InitializeDatabaseAtVersion(39);
|
||||
InitializeEngine();
|
||||
EXPECT_FALSE(GetDB()->DoesTableExist("publisher_prefix_list"));
|
||||
}
|
||||
|
||||
} // namespace brave_rewards::internal
|
||||
|
||||
@@ -1,168 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_publisher_prefix_list.h"
|
||||
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/strings/stringprintf.h"
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_util.h"
|
||||
#include "brave/components/brave_rewards/core/engine/publisher/prefix_util.h"
|
||||
#include "brave/components/brave_rewards/core/engine/rewards_engine.h"
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr char kTableName[] = "publisher_prefix_list";
|
||||
|
||||
constexpr size_t kHashPrefixSize = 4;
|
||||
constexpr size_t kMaxInsertRecords = 100'000;
|
||||
|
||||
std::tuple<publisher::PrefixIterator, std::string, size_t> GetPrefixInsertList(
|
||||
publisher::PrefixIterator begin,
|
||||
publisher::PrefixIterator end) {
|
||||
DCHECK(begin != end);
|
||||
size_t count = 0;
|
||||
std::string values;
|
||||
publisher::PrefixIterator iter = begin;
|
||||
for (iter = begin; iter != end && count < kMaxInsertRecords;
|
||||
++count, ++iter) {
|
||||
auto prefix = *iter;
|
||||
DCHECK(prefix.size() >= kHashPrefixSize);
|
||||
std::string hex = base::HexEncode(prefix.data(), kHashPrefixSize);
|
||||
values.append(base::StringPrintf("(x'%s'),", hex.c_str()));
|
||||
}
|
||||
// Remove last comma
|
||||
if (!values.empty()) {
|
||||
values.pop_back();
|
||||
}
|
||||
return {iter, std::move(values), count};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace database {
|
||||
|
||||
DatabasePublisherPrefixList::DatabasePublisherPrefixList(RewardsEngine& engine)
|
||||
: DatabaseTable(engine) {}
|
||||
|
||||
DatabasePublisherPrefixList::~DatabasePublisherPrefixList() = default;
|
||||
|
||||
void DatabasePublisherPrefixList::Search(
|
||||
const std::string& publisher_key,
|
||||
SearchPublisherPrefixListCallback callback) {
|
||||
std::string hex =
|
||||
publisher::GetHashPrefixInHex(publisher_key, kHashPrefixSize);
|
||||
|
||||
auto command = mojom::DBCommand::New();
|
||||
command->type = mojom::DBCommand::Type::READ;
|
||||
command->command = base::StringPrintf(
|
||||
"SELECT EXISTS(SELECT hash_prefix FROM %s WHERE hash_prefix = x'%s')",
|
||||
kTableName, hex.c_str());
|
||||
|
||||
command->record_bindings = {mojom::DBCommand::RecordBindingType::BOOL_TYPE};
|
||||
|
||||
auto transaction = mojom::DBTransaction::New();
|
||||
transaction->commands.push_back(std::move(command));
|
||||
|
||||
engine_->client()->RunDBTransaction(
|
||||
std::move(transaction),
|
||||
base::BindOnce(&DatabasePublisherPrefixList::OnSearch,
|
||||
base::Unretained(this), std::move(callback)));
|
||||
}
|
||||
|
||||
void DatabasePublisherPrefixList::OnSearch(
|
||||
SearchPublisherPrefixListCallback callback,
|
||||
mojom::DBCommandResponsePtr response) {
|
||||
if (!response || !response->result ||
|
||||
response->status != mojom::DBCommandResponse::Status::RESPONSE_OK ||
|
||||
response->result->get_records().empty()) {
|
||||
engine_->LogError(FROM_HERE)
|
||||
<< "Unexpected database result while searching publisher prefix list";
|
||||
std::move(callback).Run(false);
|
||||
return;
|
||||
}
|
||||
|
||||
std::move(callback).Run(
|
||||
GetBoolColumn(response->result->get_records()[0].get(), 0));
|
||||
}
|
||||
|
||||
void DatabasePublisherPrefixList::Reset(publisher::PrefixListReader reader,
|
||||
ResultCallback callback) {
|
||||
if (reader_) {
|
||||
engine_->Log(FROM_HERE) << "Publisher prefix list batch insert in progress";
|
||||
std::move(callback).Run(mojom::Result::FAILED);
|
||||
return;
|
||||
}
|
||||
if (reader.empty()) {
|
||||
engine_->LogError(FROM_HERE)
|
||||
<< "Cannot reset with an empty publisher prefix list";
|
||||
std::move(callback).Run(mojom::Result::FAILED);
|
||||
return;
|
||||
}
|
||||
reader_ = std::move(reader);
|
||||
InsertNext(reader_->begin(), std::move(callback));
|
||||
}
|
||||
|
||||
void DatabasePublisherPrefixList::InsertNext(publisher::PrefixIterator begin,
|
||||
ResultCallback callback) {
|
||||
DCHECK(reader_ && begin != reader_->end());
|
||||
|
||||
auto transaction = mojom::DBTransaction::New();
|
||||
|
||||
if (begin == reader_->begin()) {
|
||||
engine_->Log(FROM_HERE) << "Clearing publisher prefixes table";
|
||||
auto command = mojom::DBCommand::New();
|
||||
command->type = mojom::DBCommand::Type::RUN;
|
||||
command->command = base::StringPrintf("DELETE FROM %s", kTableName);
|
||||
transaction->commands.push_back(std::move(command));
|
||||
}
|
||||
|
||||
auto insert_tuple = GetPrefixInsertList(begin, reader_->end());
|
||||
|
||||
engine_->Log(FROM_HERE) << "Inserting " << std::get<size_t>(insert_tuple)
|
||||
<< " records into publisher prefix table";
|
||||
|
||||
auto command = mojom::DBCommand::New();
|
||||
command->type = mojom::DBCommand::Type::RUN;
|
||||
command->command = base::StringPrintf(
|
||||
"INSERT OR REPLACE INTO %s (hash_prefix) VALUES %s", kTableName,
|
||||
std::get<std::string>(insert_tuple).data());
|
||||
|
||||
transaction->commands.push_back(std::move(command));
|
||||
|
||||
engine_->client()->RunDBTransaction(
|
||||
std::move(transaction),
|
||||
base::BindOnce(&DatabasePublisherPrefixList::OnInsertNext,
|
||||
base::Unretained(this), std::move(callback),
|
||||
std::get<publisher::PrefixIterator>(insert_tuple)));
|
||||
}
|
||||
|
||||
void DatabasePublisherPrefixList::OnInsertNext(
|
||||
ResultCallback callback,
|
||||
publisher::PrefixIterator iter,
|
||||
mojom::DBCommandResponsePtr response) {
|
||||
if (!response ||
|
||||
response->status != mojom::DBCommandResponse::Status::RESPONSE_OK) {
|
||||
reader_ = std::nullopt;
|
||||
std::move(callback).Run(mojom::Result::FAILED);
|
||||
return;
|
||||
}
|
||||
|
||||
if (iter == reader_->end()) {
|
||||
reader_ = std::nullopt;
|
||||
std::move(callback).Run(mojom::Result::OK);
|
||||
return;
|
||||
}
|
||||
|
||||
InsertNext(iter, std::move(callback));
|
||||
}
|
||||
|
||||
} // namespace database
|
||||
} // namespace brave_rewards::internal
|
||||
@@ -1,46 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_DATABASE_DATABASE_PUBLISHER_PREFIX_LIST_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_DATABASE_DATABASE_PUBLISHER_PREFIX_LIST_H_
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_table.h"
|
||||
#include "brave/components/brave_rewards/core/engine/publisher/prefix_list_reader.h"
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
namespace database {
|
||||
|
||||
using SearchPublisherPrefixListCallback = base::OnceCallback<void(bool)>;
|
||||
|
||||
class DatabasePublisherPrefixList : public DatabaseTable {
|
||||
public:
|
||||
explicit DatabasePublisherPrefixList(RewardsEngine& engine);
|
||||
~DatabasePublisherPrefixList() override;
|
||||
|
||||
void Reset(publisher::PrefixListReader reader, ResultCallback callback);
|
||||
|
||||
void Search(const std::string& publisher_key,
|
||||
SearchPublisherPrefixListCallback callback);
|
||||
|
||||
private:
|
||||
void InsertNext(publisher::PrefixIterator begin, ResultCallback callback);
|
||||
|
||||
void OnSearch(SearchPublisherPrefixListCallback callback,
|
||||
mojom::DBCommandResponsePtr response);
|
||||
|
||||
void OnInsertNext(ResultCallback callback,
|
||||
publisher::PrefixIterator iter,
|
||||
mojom::DBCommandResponsePtr response);
|
||||
|
||||
std::optional<publisher::PrefixListReader> reader_;
|
||||
};
|
||||
|
||||
} // namespace database
|
||||
} // namespace brave_rewards::internal
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_DATABASE_DATABASE_PUBLISHER_PREFIX_LIST_H_
|
||||
-104
@@ -1,104 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "brave/components/brave_rewards/core/engine/database/database_publisher_prefix_list.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "base/numerics/byte_conversions.h"
|
||||
#include "brave/components/brave_rewards/core/engine/publisher/protos/publisher_prefix_list.pb.h"
|
||||
#include "brave/components/brave_rewards/core/engine/test/rewards_engine_test.h"
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
|
||||
namespace {
|
||||
|
||||
class Client : public TestRewardsEngineClient {
|
||||
public:
|
||||
void RunDBTransaction(mojom::DBTransactionPtr transaction,
|
||||
RunDBTransactionCallback callback) override {
|
||||
transactions_.push_back(transaction->Clone());
|
||||
auto response = mojom::DBCommandResponse::New();
|
||||
response->status = mojom::DBCommandResponse::Status::RESPONSE_OK;
|
||||
std::move(callback).Run(std::move(response));
|
||||
}
|
||||
|
||||
std::vector<mojom::DBTransactionPtr>& transactions() { return transactions_; }
|
||||
|
||||
private:
|
||||
std::vector<mojom::DBTransactionPtr> transactions_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
class RewardsDatabasePublisherPrefixListTest : public RewardsEngineTest {
|
||||
protected:
|
||||
RewardsDatabasePublisherPrefixListTest()
|
||||
: RewardsEngineTest(std::make_unique<Client>()) {}
|
||||
|
||||
Client& client() { return static_cast<Client&>(RewardsEngineTest::client()); }
|
||||
|
||||
publisher::PrefixListReader CreateReader(uint32_t prefix_count) {
|
||||
publisher::PrefixListReader reader;
|
||||
if (prefix_count == 0) {
|
||||
return reader;
|
||||
}
|
||||
|
||||
std::string prefixes;
|
||||
prefixes.resize(prefix_count * 4);
|
||||
for (uint32_t i = 0; i < prefix_count; ++i) {
|
||||
base::as_writable_byte_span(prefixes).subspan(i * 4).first<4>().copy_from(
|
||||
base::numerics::U32ToBigEndian(i));
|
||||
}
|
||||
|
||||
publishers_pb::PublisherPrefixList message;
|
||||
message.set_prefix_size(4);
|
||||
message.set_compression_type(
|
||||
publishers_pb::PublisherPrefixList::NO_COMPRESSION);
|
||||
message.set_uncompressed_size(prefixes.size());
|
||||
message.set_prefixes(std::move(prefixes));
|
||||
|
||||
std::string out;
|
||||
message.SerializeToString(&out);
|
||||
reader.Parse(out);
|
||||
return reader;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(RewardsDatabasePublisherPrefixListTest, Reset) {
|
||||
database::DatabasePublisherPrefixList prefix_list(engine());
|
||||
WaitFor<mojom::Result>([&](auto callback) {
|
||||
prefix_list.Reset(CreateReader(100'001), std::move(callback));
|
||||
});
|
||||
|
||||
auto& transactions = client().transactions();
|
||||
ASSERT_EQ(transactions.size(), 2ul);
|
||||
|
||||
{
|
||||
auto& transaction = transactions[0];
|
||||
EXPECT_TRUE(transaction);
|
||||
EXPECT_EQ(transaction->commands.size(), 2u);
|
||||
EXPECT_EQ(transaction->commands[0]->command,
|
||||
"DELETE FROM publisher_prefix_list");
|
||||
EXPECT_TRUE(transaction->commands[1]->command.starts_with(
|
||||
"INSERT OR REPLACE INTO publisher_prefix_list (hash_prefix) "
|
||||
"VALUES (x'00000000'),(x'00000001'),(x'00000002'),"));
|
||||
}
|
||||
|
||||
{
|
||||
auto& transaction = transactions[1];
|
||||
EXPECT_TRUE(transaction);
|
||||
EXPECT_EQ(transaction->commands.size(), 1u);
|
||||
EXPECT_EQ(transaction->commands[0]->command,
|
||||
"INSERT OR REPLACE INTO publisher_prefix_list (hash_prefix) "
|
||||
"VALUES (x'000186A0')");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace brave_rewards::internal
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int kCurrentVersionNumber = 40;
|
||||
constexpr int kCurrentVersionNumber = 41;
|
||||
constexpr int kCompatibleVersionNumber = 1;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
/* Copyright (c) 2025 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_DATABASE_MIGRATION_MIGRATION_V41_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_DATABASE_MIGRATION_MIGRATION_V41_H_
|
||||
|
||||
namespace brave_rewards::internal::database::migration {
|
||||
|
||||
// Migration 41 removes the publisher prefix list table after storage was moved
|
||||
// to a separate file.
|
||||
inline constexpr char v41[] = R"sql(
|
||||
DROP TABLE IF EXISTS publisher_prefix_list;
|
||||
)sql";
|
||||
|
||||
} // namespace brave_rewards::internal::database::migration
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_DATABASE_MIGRATION_MIGRATION_V41_H_
|
||||
@@ -0,0 +1,115 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_HASH_PREFIX_ITERATOR_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_HASH_PREFIX_ITERATOR_H_
|
||||
|
||||
#include <iterator>
|
||||
#include <string_view>
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
|
||||
// A random-access iterator over prefixes stored in an uncompressed prefix list,
|
||||
// suitable for binary search.
|
||||
class HashPrefixIterator {
|
||||
public:
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
using value_type = std::string_view;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using pointer = value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
|
||||
HashPrefixIterator(std::string_view data, size_t index, size_t size)
|
||||
: data_(data), index_(index), size_(size) {}
|
||||
|
||||
HashPrefixIterator(const HashPrefixIterator& rhs)
|
||||
: data_(rhs.data_), index_(rhs.index_), size_(rhs.size_) {}
|
||||
|
||||
std::string_view operator*() const { return PrefixAt(index_); }
|
||||
|
||||
std::string_view operator[](const int& rhs) const {
|
||||
return PrefixAt(index_ + rhs);
|
||||
}
|
||||
|
||||
HashPrefixIterator& operator=(const HashPrefixIterator& rhs) {
|
||||
index_ = rhs.index_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HashPrefixIterator& operator+=(const int& rhs) {
|
||||
index_ += rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HashPrefixIterator& operator-=(const int& rhs) {
|
||||
index_ -= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HashPrefixIterator& operator++() {
|
||||
index_++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HashPrefixIterator& operator--() {
|
||||
index_--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
HashPrefixIterator operator+(const HashPrefixIterator& rhs) const {
|
||||
return HashPrefixIterator(data_, index_ + rhs.index_, size_);
|
||||
}
|
||||
|
||||
difference_type operator-(const HashPrefixIterator& rhs) const {
|
||||
return index_ - rhs.index_;
|
||||
}
|
||||
|
||||
HashPrefixIterator operator+(const int& rhs) const {
|
||||
return HashPrefixIterator(data_, index_ + rhs, size_);
|
||||
}
|
||||
|
||||
HashPrefixIterator operator-(const int& rhs) const {
|
||||
return HashPrefixIterator(data_, index_ - rhs, size_);
|
||||
}
|
||||
|
||||
bool operator==(const HashPrefixIterator& rhs) const {
|
||||
return index_ == rhs.index_;
|
||||
}
|
||||
|
||||
bool operator!=(const HashPrefixIterator& rhs) const {
|
||||
return index_ != rhs.index_;
|
||||
}
|
||||
|
||||
bool operator>(const HashPrefixIterator& rhs) const {
|
||||
return index_ > rhs.index_;
|
||||
}
|
||||
|
||||
bool operator<(const HashPrefixIterator& rhs) const {
|
||||
return index_ < rhs.index_;
|
||||
}
|
||||
|
||||
bool operator>=(const HashPrefixIterator& rhs) const {
|
||||
return index_ >= rhs.index_;
|
||||
}
|
||||
|
||||
bool operator<=(const HashPrefixIterator& rhs) const {
|
||||
return index_ <= rhs.index_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string_view PrefixAt(size_t index) const {
|
||||
return data_.substr(index_ * size_, size_);
|
||||
}
|
||||
|
||||
const std::string_view data_;
|
||||
size_t index_;
|
||||
const size_t size_;
|
||||
};
|
||||
|
||||
} // namespace brave_rewards::internal
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_HASH_PREFIX_ITERATOR_H_
|
||||
@@ -0,0 +1,192 @@
|
||||
/* Copyright (c) 2025 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "brave/components/brave_rewards/core/engine/hash_prefix_store.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <utility>
|
||||
|
||||
#include "base/containers/span.h"
|
||||
#include "base/containers/span_reader.h"
|
||||
#include "base/files/file.h"
|
||||
#include "base/memory/raw_span.h"
|
||||
#include "base/numerics/byte_conversions.h"
|
||||
#include "brave/components/brave_rewards/core/engine/hash_prefix_iterator.h"
|
||||
#include "crypto/sha2.h"
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr uint32_t kFileVersion = 1;
|
||||
constexpr uint32_t kMinPrefixSize = 4;
|
||||
constexpr uint32_t kMaxPrefixSize = 32;
|
||||
|
||||
struct FileParts {
|
||||
uint32_t version = 0;
|
||||
uint32_t prefix_size = 0;
|
||||
uint64_t prefix_count = 0;
|
||||
base::raw_span<const uint8_t> prefixes;
|
||||
};
|
||||
|
||||
bool IsValidPrefixSize(size_t prefix_size) {
|
||||
return prefix_size >= kMinPrefixSize && prefix_size <= kMaxPrefixSize;
|
||||
}
|
||||
|
||||
std::optional<size_t> GetPrefixCount(size_t byte_length, size_t prefix_size) {
|
||||
if (prefix_size == 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (byte_length % prefix_size != 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return byte_length / prefix_size;
|
||||
}
|
||||
|
||||
bool IsValidFile(const FileParts& parts) {
|
||||
if (parts.version != kFileVersion) {
|
||||
return false;
|
||||
}
|
||||
if (!IsValidPrefixSize(parts.prefix_size)) {
|
||||
return false;
|
||||
}
|
||||
auto count = GetPrefixCount(parts.prefixes.size(), parts.prefix_size);
|
||||
if (!count || count.value() != parts.prefix_count) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::optional<FileParts> ParseFile(base::span<const uint8_t> bytes) {
|
||||
FileParts parts;
|
||||
base::SpanReader reader(bytes);
|
||||
if (!reader.ReadU32LittleEndian(parts.version)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!reader.ReadU32LittleEndian(parts.prefix_size)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (!reader.ReadU64LittleEndian(parts.prefix_count)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
parts.prefixes = reader.remaining_span();
|
||||
if (!IsValidFile(parts)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
HashPrefixStore::HashPrefixStore(base::FilePath path)
|
||||
: file_path_(std::move(path)) {
|
||||
DETACH_FROM_SEQUENCE(sequence_checker_);
|
||||
}
|
||||
|
||||
HashPrefixStore::~HashPrefixStore() = default;
|
||||
|
||||
bool HashPrefixStore::Open() {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
||||
if (mapped_file_) {
|
||||
DCHECK(mapped_file_->IsValid());
|
||||
return true;
|
||||
}
|
||||
|
||||
open_called_ = true;
|
||||
|
||||
auto mapped_file = std::make_unique<base::MemoryMappedFile>();
|
||||
if (!mapped_file->Initialize(file_path_)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto parts = ParseFile(mapped_file->bytes());
|
||||
if (!parts) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mapped_file_ = std::move(mapped_file);
|
||||
prefixes_ = base::as_string_view(parts->prefixes);
|
||||
prefix_size_ = parts->prefix_size;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HashPrefixStore::Close() {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
prefixes_ = {};
|
||||
prefix_size_ = 0;
|
||||
open_called_ = false;
|
||||
mapped_file_.reset();
|
||||
}
|
||||
|
||||
bool HashPrefixStore::UpdatePrefixes(const std::string& prefixes,
|
||||
size_t prefix_size) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
|
||||
Close();
|
||||
|
||||
if (!IsValidPrefixSize(prefix_size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto prefix_count = GetPrefixCount(prefixes.length(), prefix_size);
|
||||
if (!prefix_count) {
|
||||
return false;
|
||||
}
|
||||
|
||||
base::File file;
|
||||
file.Initialize(file_path_,
|
||||
base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
|
||||
if (!file.IsValid()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto encoded_version = base::U32ToLittleEndian(kFileVersion);
|
||||
if (!file.WriteAtCurrentPosAndCheck(base::as_byte_span(encoded_version))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto encoded_size =
|
||||
base::U32ToLittleEndian(base::checked_cast<uint32_t>(prefix_size));
|
||||
if (!file.WriteAtCurrentPosAndCheck(base::as_byte_span(encoded_size))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto encoded_count = base::U64ToLittleEndian(
|
||||
base::checked_cast<uint64_t>(prefix_count.value()));
|
||||
if (!file.WriteAtCurrentPosAndCheck(base::as_byte_span(encoded_count))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!file.WriteAtCurrentPosAndCheck(base::as_byte_span(prefixes))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
file.Close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool HashPrefixStore::ContainsPrefix(const std::string& value) {
|
||||
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
|
||||
if (!open_called_) {
|
||||
Open();
|
||||
}
|
||||
|
||||
if (prefix_size_ == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string hash = crypto::SHA256HashString(value);
|
||||
hash.resize(prefix_size_);
|
||||
|
||||
size_t prefix_count = prefixes_.length() / prefix_size_;
|
||||
|
||||
return std::binary_search(
|
||||
HashPrefixIterator(prefixes_, 0, prefix_size_),
|
||||
HashPrefixIterator(prefixes_, prefix_count, prefix_size_), hash);
|
||||
}
|
||||
|
||||
} // namespace brave_rewards::internal
|
||||
@@ -0,0 +1,54 @@
|
||||
/* Copyright (c) 2025 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_HASH_PREFIX_STORE_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_HASH_PREFIX_STORE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/files/memory_mapped_file.h"
|
||||
#include "base/sequence_checker.h"
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
|
||||
// Responsible for storage and retrieval of a sorted hash prefix list. The
|
||||
// operations of this class will block the current thread on IO.
|
||||
class HashPrefixStore {
|
||||
public:
|
||||
explicit HashPrefixStore(base::FilePath path);
|
||||
~HashPrefixStore();
|
||||
|
||||
HashPrefixStore(const HashPrefixStore&) = delete;
|
||||
HashPrefixStore& operator=(const HashPrefixStore&) = delete;
|
||||
|
||||
// Opens the hash prefix file, if not already open.
|
||||
bool Open();
|
||||
|
||||
// Closes the hash prefix file, if open.
|
||||
void Close();
|
||||
|
||||
// Updates the hash prefix file.
|
||||
bool UpdatePrefixes(const std::string& prefixes, size_t prefix_size);
|
||||
|
||||
// Returns a value indicating if the specified value exists in the prefix
|
||||
// list. Opens the file if not already open.
|
||||
bool ContainsPrefix(const std::string& value);
|
||||
|
||||
private:
|
||||
const base::FilePath file_path_;
|
||||
std::unique_ptr<base::MemoryMappedFile> mapped_file_;
|
||||
std::string_view prefixes_;
|
||||
size_t prefix_size_ = 0;
|
||||
bool open_called_ = false;
|
||||
|
||||
SEQUENCE_CHECKER(sequence_checker_);
|
||||
};
|
||||
|
||||
} // namespace brave_rewards::internal
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_HASH_PREFIX_STORE_H_
|
||||
@@ -0,0 +1,179 @@
|
||||
/* Copyright (c) 2025 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "brave/components/brave_rewards/core/engine/hash_prefix_store.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "base/containers/span_writer.h"
|
||||
#include "base/files/file_util.h"
|
||||
#include "base/files/scoped_temp_dir.h"
|
||||
#include "base/numerics/byte_conversions.h"
|
||||
#include "base/task/sequenced_task_runner.h"
|
||||
#include "base/test/task_environment.h"
|
||||
#include "crypto/sha2.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
|
||||
class RewardsHashPrefixStoreTest : public testing::Test {
|
||||
public:
|
||||
void SetUp() override {
|
||||
Test::SetUp();
|
||||
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
|
||||
store_path_ = temp_dir_.GetPath().AppendASCII("prefixes.store");
|
||||
}
|
||||
|
||||
std::array<uint8_t, 16u> MakeFileHeader(uint32_t version,
|
||||
uint32_t prefix_size,
|
||||
uint64_t prefix_count) {
|
||||
std::array<uint8_t, 16u> header;
|
||||
base::SpanWriter writer(base::as_writable_byte_span(header));
|
||||
auto encoded_version = base::U32ToLittleEndian(version);
|
||||
writer.Write(base::as_byte_span(encoded_version));
|
||||
auto encoded_size = base::U32ToLittleEndian(prefix_size);
|
||||
writer.Write(base::as_byte_span(encoded_size));
|
||||
auto encoded_count = base::U64ToLittleEndian(prefix_count);
|
||||
writer.Write(base::as_byte_span(encoded_count));
|
||||
return header;
|
||||
}
|
||||
|
||||
std::string MakePrefixString(size_t prefix_size,
|
||||
std::vector<std::string_view> values) {
|
||||
std::vector<std::string> hash_values;
|
||||
for (auto& value : values) {
|
||||
std::string hash = crypto::SHA256HashString(value);
|
||||
hash.resize(prefix_size);
|
||||
hash_values.push_back(std::move(hash));
|
||||
}
|
||||
|
||||
std::sort(hash_values.begin(), hash_values.end());
|
||||
|
||||
std::string data;
|
||||
data.reserve(hash_values.size() * prefix_size);
|
||||
for (auto& value : hash_values) {
|
||||
data += value;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
protected:
|
||||
base::ScopedTempDir temp_dir_;
|
||||
base::FilePath store_path_;
|
||||
base::test::TaskEnvironment task_environment_;
|
||||
};
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, FileDoesNotExist) {
|
||||
HashPrefixStore store(store_path_);
|
||||
EXPECT_FALSE(store.Open());
|
||||
EXPECT_FALSE(store.ContainsPrefix("test-value"));
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, EmptyFile) {
|
||||
base::WriteFile(store_path_, "");
|
||||
HashPrefixStore store(store_path_);
|
||||
EXPECT_FALSE(store.Open());
|
||||
EXPECT_FALSE(store.ContainsPrefix("test-value"));
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, InvalidFileHeader) {
|
||||
base::WriteFile(store_path_, "--------");
|
||||
HashPrefixStore store(store_path_);
|
||||
EXPECT_FALSE(store.Open());
|
||||
EXPECT_FALSE(store.ContainsPrefix("test-value"));
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, InvalidFileVersion) {
|
||||
auto header = MakeFileHeader(2, 4, 0);
|
||||
base::WriteFile(store_path_, base::as_byte_span(header));
|
||||
HashPrefixStore store(store_path_);
|
||||
EXPECT_FALSE(store.Open());
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, InvalidPrefixSize) {
|
||||
auto header = MakeFileHeader(1, 1024, 0);
|
||||
base::WriteFile(store_path_, base::as_byte_span(header));
|
||||
HashPrefixStore store(store_path_);
|
||||
EXPECT_FALSE(store.Open());
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, InvalidPrefixCount) {
|
||||
auto header = MakeFileHeader(1, 4, 1);
|
||||
auto content = std::string(base::as_string_view(header)) + "?";
|
||||
base::WriteFile(store_path_, content);
|
||||
HashPrefixStore store(store_path_);
|
||||
EXPECT_FALSE(store.Open());
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, WrongPrefixCount) {
|
||||
auto header = MakeFileHeader(1, 4, 0);
|
||||
auto content = std::string(base::as_string_view(header)) + "????";
|
||||
base::WriteFile(store_path_, content);
|
||||
HashPrefixStore store(store_path_);
|
||||
EXPECT_FALSE(store.Open());
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, InvalidDataLength) {
|
||||
auto header = MakeFileHeader(1, 4, 0);
|
||||
auto content = std::string(base::as_string_view(header)) + "?";
|
||||
base::WriteFile(store_path_, content);
|
||||
HashPrefixStore store(store_path_);
|
||||
EXPECT_FALSE(store.Open());
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, ZeroPrefixes) {
|
||||
auto header = MakeFileHeader(1, 4, 0);
|
||||
base::WriteFile(store_path_, base::as_byte_span(header));
|
||||
HashPrefixStore store(store_path_);
|
||||
EXPECT_TRUE(store.Open());
|
||||
EXPECT_FALSE(store.ContainsPrefix("test-value"));
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, WithPrefixes) {
|
||||
HashPrefixStore store(store_path_);
|
||||
|
||||
size_t prefix_size = 4;
|
||||
|
||||
std::string data = MakePrefixString(
|
||||
prefix_size, {"test-value-1", "test-value-2", "test-value-3",
|
||||
"test-value-4", "test-value-5", "test-value-6",
|
||||
"test-value-7", "test-value-8", "test-value-9"});
|
||||
|
||||
bool updated = store.UpdatePrefixes(data, prefix_size);
|
||||
|
||||
EXPECT_TRUE(updated);
|
||||
EXPECT_TRUE(store.ContainsPrefix("test-value-4"));
|
||||
EXPECT_TRUE(store.ContainsPrefix("test-value-1"));
|
||||
EXPECT_TRUE(store.ContainsPrefix("test-value-9"));
|
||||
EXPECT_FALSE(store.ContainsPrefix("test-value-0"));
|
||||
|
||||
data = MakePrefixString(prefix_size, {"test-value-10"});
|
||||
updated = store.UpdatePrefixes(data, prefix_size);
|
||||
|
||||
EXPECT_TRUE(updated);
|
||||
EXPECT_TRUE(store.ContainsPrefix("test-value-10"));
|
||||
EXPECT_FALSE(store.ContainsPrefix("test-value-1"));
|
||||
}
|
||||
|
||||
TEST_F(RewardsHashPrefixStoreTest, UpdateEmpty) {
|
||||
HashPrefixStore store(store_path_);
|
||||
|
||||
size_t prefix_size = 8;
|
||||
bool updated = store.UpdatePrefixes("", prefix_size);
|
||||
EXPECT_TRUE(updated);
|
||||
EXPECT_FALSE(store.ContainsPrefix("test-value-1"));
|
||||
|
||||
std::string data = MakePrefixString(prefix_size, {"test-value-1"});
|
||||
updated = store.UpdatePrefixes(data, prefix_size);
|
||||
EXPECT_TRUE(updated);
|
||||
EXPECT_TRUE(store.ContainsPrefix("test-value-1"));
|
||||
}
|
||||
|
||||
} // namespace brave_rewards::internal
|
||||
@@ -1,123 +0,0 @@
|
||||
/* 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifdef UNSAFE_BUFFERS_BUILD
|
||||
// TODO(https://github.com/brave/brave-browser/issues/41661): Remove this and
|
||||
// convert code to safer constructs.
|
||||
#pragma allow_unsafe_buffers
|
||||
#endif
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_PUBLISHER_PREFIX_ITERATOR_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_PUBLISHER_PREFIX_ITERATOR_H_
|
||||
|
||||
#include <iterator>
|
||||
#include <string_view>
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
namespace publisher {
|
||||
|
||||
// A random-access iterator over prefixes stored in an
|
||||
// uncompressed prefix list, suitable for binary search
|
||||
class PrefixIterator {
|
||||
public:
|
||||
using iterator_category = std::random_access_iterator_tag;
|
||||
using value_type = std::string_view;
|
||||
using difference_type = std::ptrdiff_t;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using pointer = value_type*;
|
||||
using const_pointer = const value_type*;
|
||||
|
||||
PrefixIterator(const char* data, size_t index, size_t size)
|
||||
: data_(data), index_(index), size_(size) {}
|
||||
|
||||
PrefixIterator(const PrefixIterator& rhs)
|
||||
: data_(rhs.data_), index_(rhs.index_), size_(rhs.size_) {}
|
||||
|
||||
std::string_view operator*() const {
|
||||
size_t offset = index_ * size_;
|
||||
return std::string_view(data_ + offset, size_);
|
||||
}
|
||||
|
||||
std::string_view operator[](const int& rhs) const {
|
||||
size_t offset = (index_ + rhs) * size_;
|
||||
return std::string_view(data_ + offset, size_);
|
||||
}
|
||||
|
||||
PrefixIterator& operator=(const PrefixIterator& rhs) {
|
||||
index_ = rhs.index_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PrefixIterator& operator+=(const int& rhs) {
|
||||
index_ += rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PrefixIterator& operator-=(const int& rhs) {
|
||||
index_ -= rhs;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PrefixIterator& operator++() {
|
||||
index_++;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PrefixIterator& operator--() {
|
||||
index_--;
|
||||
return *this;
|
||||
}
|
||||
|
||||
PrefixIterator operator+(const PrefixIterator& rhs) const {
|
||||
return PrefixIterator(data_, index_ + rhs.index_, size_);
|
||||
}
|
||||
|
||||
difference_type operator-(const PrefixIterator& rhs) const {
|
||||
return index_ - rhs.index_;
|
||||
}
|
||||
|
||||
PrefixIterator operator+(const int& rhs) const {
|
||||
return PrefixIterator(data_, index_ + rhs, size_);
|
||||
}
|
||||
|
||||
PrefixIterator operator-(const int& rhs) const {
|
||||
return PrefixIterator(data_, index_ - rhs, size_);
|
||||
}
|
||||
|
||||
bool operator==(const PrefixIterator& rhs) const {
|
||||
return index_ == rhs.index_;
|
||||
}
|
||||
|
||||
bool operator!=(const PrefixIterator& rhs) const {
|
||||
return index_ != rhs.index_;
|
||||
}
|
||||
|
||||
bool operator>(const PrefixIterator& rhs) const {
|
||||
return index_ > rhs.index_;
|
||||
}
|
||||
|
||||
bool operator<(const PrefixIterator& rhs) const {
|
||||
return index_ < rhs.index_;
|
||||
}
|
||||
|
||||
bool operator>=(const PrefixIterator& rhs) const {
|
||||
return index_ >= rhs.index_;
|
||||
}
|
||||
|
||||
bool operator<=(const PrefixIterator& rhs) const {
|
||||
return index_ <= rhs.index_;
|
||||
}
|
||||
|
||||
private:
|
||||
const char* data_;
|
||||
size_t index_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
} // namespace publisher
|
||||
} // namespace brave_rewards::internal
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_PUBLISHER_PREFIX_ITERATOR_H_
|
||||
@@ -73,7 +73,7 @@ PrefixListReader::ParseError PrefixListReader::Parse(
|
||||
prefix_size_ = prefix_size;
|
||||
|
||||
// Perform a quick sanity check that the first few prefixes are in order.
|
||||
PrefixIterator iter = this->begin();
|
||||
HashPrefixIterator iter = this->begin();
|
||||
if (iter != this->end()) {
|
||||
for (size_t i = 0; i < 5; ++i) {
|
||||
auto next = iter + 1;
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "brave/components/brave_rewards/core/engine/publisher/prefix_iterator.h"
|
||||
#include "brave/components/brave_rewards/core/engine/hash_prefix_iterator.h"
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
namespace publisher {
|
||||
@@ -42,15 +42,21 @@ class PrefixListReader {
|
||||
ParseError Parse(const std::string& contents);
|
||||
|
||||
// Returns an iterator pointing to the first prefix in the list
|
||||
PrefixIterator begin() const {
|
||||
return PrefixIterator(prefixes_.data(), 0, prefix_size_);
|
||||
HashPrefixIterator begin() const {
|
||||
return HashPrefixIterator(prefixes_, 0, prefix_size_);
|
||||
}
|
||||
|
||||
// Returns an iterator pointing to the past-the-end element in the list
|
||||
PrefixIterator end() const {
|
||||
return PrefixIterator(prefixes_.data(), size(), prefix_size_);
|
||||
HashPrefixIterator end() const {
|
||||
return HashPrefixIterator(prefixes_, size(), prefix_size_);
|
||||
}
|
||||
|
||||
// Returns the hash prefix size.
|
||||
size_t prefix_size() const { return prefix_size_; }
|
||||
|
||||
// Returns the entire raw prefix list.
|
||||
const std::string& prefixes() const { return prefixes_; }
|
||||
|
||||
// Returns the number of prefixes in the list
|
||||
size_t size() const { return prefixes_.size() / prefix_size_; }
|
||||
|
||||
|
||||
@@ -145,7 +145,7 @@ void Publisher::SaveVisit(const std::string& publisher_key,
|
||||
weak_factory_.GetWeakPtr(), publisher_key, visit_data,
|
||||
duration, first_visit, window_id, std::move(callback));
|
||||
|
||||
engine_->database()->SearchPublisherPrefixList(
|
||||
engine_->client()->CreatorPrefixStoreContains(
|
||||
publisher_key, base::BindOnce(&Publisher::OnSearchPrefixListForSaveVisit,
|
||||
weak_factory_.GetWeakPtr(), publisher_key,
|
||||
std::move(on_server_info)));
|
||||
@@ -682,7 +682,7 @@ void Publisher::OnServerPublisherInfoLoaded(
|
||||
// If we don't have a record in the database for this publisher, search the
|
||||
// prefix list. If the prefix list indicates that the publisher is likely
|
||||
// registered, then fetch the publisher data.
|
||||
engine_->database()->SearchPublisherPrefixList(
|
||||
engine_->client()->CreatorPrefixStoreContains(
|
||||
publisher_key,
|
||||
base::BindOnce(&Publisher::OnSearchPrefixListForGetServerPublisherInfo,
|
||||
weak_factory_.GetWeakPtr(), publisher_key,
|
||||
|
||||
@@ -90,14 +90,18 @@ void PublisherPrefixListUpdater::OnFetchCompleted(mojom::Result result,
|
||||
|
||||
retry_count_ = 0;
|
||||
|
||||
engine_->Log(FROM_HERE) << "Resetting publisher prefix list table";
|
||||
engine_->database()->ResetPublisherPrefixList(
|
||||
std::move(reader),
|
||||
auto prefix_data = mojom::HashPrefixData::New();
|
||||
prefix_data->prefixes = reader.prefixes();
|
||||
prefix_data->prefix_size = reader.prefix_size();
|
||||
|
||||
engine_->Log(FROM_HERE) << "Resetting publisher prefix list store";
|
||||
engine_->client()->UpdateCreatorPrefixStore(
|
||||
std::move(prefix_data),
|
||||
base::BindOnce(&PublisherPrefixListUpdater::OnPrefixListInserted,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
}
|
||||
|
||||
void PublisherPrefixListUpdater::OnPrefixListInserted(mojom::Result result) {
|
||||
void PublisherPrefixListUpdater::OnPrefixListInserted(bool success) {
|
||||
// At this point we have received a valid response from the server
|
||||
// and we've attempted to insert it into the database. Store the last
|
||||
// successful fetch time for calculation of next refresh interval.
|
||||
@@ -109,9 +113,8 @@ void PublisherPrefixListUpdater::OnPrefixListInserted(mojom::Result result) {
|
||||
StartFetchTimer(FROM_HERE, GetAutoUpdateDelay());
|
||||
}
|
||||
|
||||
if (result != mojom::Result::OK) {
|
||||
engine_->LogError(FROM_HERE)
|
||||
<< "Error updating publisher prefix list table: " << result;
|
||||
if (!success) {
|
||||
engine_->LogError(FROM_HERE) << "Error updating publisher prefix list";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ class PublisherPrefixListUpdater {
|
||||
|
||||
void OnFetchTimerElapsed();
|
||||
void OnFetchCompleted(mojom::Result result, std::string body);
|
||||
void OnPrefixListInserted(mojom::Result result);
|
||||
void OnPrefixListInserted(bool success);
|
||||
|
||||
base::TimeDelta GetAutoUpdateDelay();
|
||||
base::TimeDelta GetRetryAfterFailureDelay();
|
||||
|
||||
@@ -90,7 +90,7 @@ void RefreshNext(std::unique_ptr<RefreshTaskInfo> task_info) {
|
||||
|
||||
// Look for publisher key in hash index.
|
||||
auto& key = task_info->current->first;
|
||||
task_info->engine->database()->SearchPublisherPrefixList(
|
||||
task_info->engine->client()->CreatorPrefixStoreContains(
|
||||
key, base::BindOnce(on_prefix_searched, std::move(task_info)));
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr int kCurrentVersionNumber = 14;
|
||||
constexpr int kCurrentVersionNumber = 15;
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -31,7 +31,8 @@ StateMigration::StateMigration(RewardsEngine& engine)
|
||||
v11_(engine),
|
||||
v12_(engine),
|
||||
v13_(engine),
|
||||
v14_(engine) {}
|
||||
v14_(engine),
|
||||
v15_(engine) {}
|
||||
|
||||
StateMigration::~StateMigration() = default;
|
||||
|
||||
@@ -129,6 +130,10 @@ void StateMigration::Migrate(ResultCallback callback) {
|
||||
v14_.Migrate(std::move(migrate_callback));
|
||||
return;
|
||||
}
|
||||
case 15: {
|
||||
v15_.Migrate(std::move(migrate_callback));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
engine_->LogError(FROM_HERE)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
#include "brave/components/brave_rewards/core/engine/state/state_migration_v12.h"
|
||||
#include "brave/components/brave_rewards/core/engine/state/state_migration_v13.h"
|
||||
#include "brave/components/brave_rewards/core/engine/state/state_migration_v14.h"
|
||||
#include "brave/components/brave_rewards/core/engine/state/state_migration_v15.h"
|
||||
#include "brave/components/brave_rewards/core/engine/state/state_migration_v2.h"
|
||||
#include "brave/components/brave_rewards/core/engine/state/state_migration_v3.h"
|
||||
#include "brave/components/brave_rewards/core/engine/state/state_migration_v4.h"
|
||||
@@ -57,6 +58,7 @@ class StateMigration {
|
||||
StateMigrationV12 v12_;
|
||||
StateMigrationV13 v13_;
|
||||
StateMigrationV14 v14_;
|
||||
StateMigrationV15 v15_;
|
||||
};
|
||||
|
||||
} // namespace state
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/* Copyright (c) 2025 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "brave/components/brave_rewards/core/engine/state/state_migration_v15.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "brave/components/brave_rewards/core/engine/rewards_engine.h"
|
||||
#include "brave/components/brave_rewards/core/engine/state/state_keys.h"
|
||||
|
||||
namespace brave_rewards::internal::state {
|
||||
|
||||
StateMigrationV15::StateMigrationV15(RewardsEngine& engine) : engine_(engine) {}
|
||||
|
||||
StateMigrationV15::~StateMigrationV15() = default;
|
||||
|
||||
void StateMigrationV15::Migrate(ResultCallback callback) {
|
||||
engine_->SetState<uint64_t>(kServerPublisherListStamp, 0);
|
||||
std::move(callback).Run(mojom::Result::OK);
|
||||
}
|
||||
|
||||
} // namespace brave_rewards::internal::state
|
||||
@@ -0,0 +1,33 @@
|
||||
/* Copyright (c) 2025 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 https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_STATE_STATE_MIGRATION_V15_H_
|
||||
#define BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_STATE_STATE_MIGRATION_V15_H_
|
||||
|
||||
#include "base/memory/raw_ref.h"
|
||||
#include "brave/components/brave_rewards/core/engine/rewards_callbacks.h"
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
class RewardsEngine;
|
||||
|
||||
namespace state {
|
||||
|
||||
// Migration 15 resets the `kServerPublisherListStamp` pref in order to trigger
|
||||
// a download of the creator hash prefix list.
|
||||
class StateMigrationV15 {
|
||||
public:
|
||||
explicit StateMigrationV15(RewardsEngine& engine);
|
||||
~StateMigrationV15();
|
||||
|
||||
void Migrate(ResultCallback);
|
||||
|
||||
private:
|
||||
const raw_ref<RewardsEngine> engine_;
|
||||
};
|
||||
|
||||
} // namespace state
|
||||
} // namespace brave_rewards::internal
|
||||
|
||||
#endif // BRAVE_COMPONENTS_BRAVE_REWARDS_CORE_ENGINE_STATE_STATE_MIGRATION_V15_H_
|
||||
@@ -16,7 +16,6 @@ source_set("test") {
|
||||
"//brave/components/brave_rewards/core/engine/database/database_migration_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/database/database_mock.cc",
|
||||
"//brave/components/brave_rewards/core/engine/database/database_mock.h",
|
||||
"//brave/components/brave_rewards/core/engine/database/database_publisher_prefix_list_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/database/database_util_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/endpoint/bitflyer/get_balance/get_balance_bitflyer_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/endpoint/bitflyer/post_oauth/post_oauth_bitflyer_unittest.cc",
|
||||
@@ -47,6 +46,7 @@ source_set("test") {
|
||||
"//brave/components/brave_rewards/core/engine/endpoints/uphold/post_oauth_uphold_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/endpoints/zebpay/get_balance_zebpay_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/endpoints/zebpay/post_oauth_zebpay_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/hash_prefix_store_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/legacy/bat_util_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/legacy/client_state_unittest.cc",
|
||||
"//brave/components/brave_rewards/core/engine/legacy/publisher_settings_state_unittest.cc",
|
||||
|
||||
@@ -28,7 +28,6 @@ index|sqlite_autoindex_media_publisher_info_1|media_publisher_info|
|
||||
index|sqlite_autoindex_meta_1|meta|
|
||||
index|sqlite_autoindex_promotion_1|promotion|
|
||||
index|sqlite_autoindex_publisher_info_1|publisher_info|
|
||||
index|sqlite_autoindex_publisher_prefix_list_1|publisher_prefix_list|
|
||||
index|sqlite_autoindex_recurring_donation_1|recurring_donation|
|
||||
index|sqlite_autoindex_server_publisher_banner_1|server_publisher_banner|
|
||||
index|sqlite_autoindex_server_publisher_info_1|server_publisher_info|
|
||||
@@ -52,7 +51,6 @@ table|media_publisher_info|media_publisher_info|CREATE TABLE media_publisher_inf
|
||||
table|meta|meta|CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR)
|
||||
table|promotion|promotion|CREATE TABLE promotion ( promotion_id TEXT NOT NULL, version INTEGER NOT NULL, type INTEGER NOT NULL, public_keys TEXT NOT NULL, suggestions INTEGER NOT NULL DEFAULT 0, approximate_value DOUBLE NOT NULL DEFAULT 0, status INTEGER NOT NULL DEFAULT 0, expires_at TIMESTAMP NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, claimed_at TIMESTAMP, claim_id TEXT, legacy BOOLEAN DEFAULT 0 NOT NULL, claimable_until INTEGER, PRIMARY KEY (promotion_id) )
|
||||
table|publisher_info|publisher_info|CREATE TABLE publisher_info ( publisher_id LONGVARCHAR PRIMARY KEY NOT NULL UNIQUE, excluded INTEGER DEFAULT 0 NOT NULL, name TEXT NOT NULL, favIcon TEXT NOT NULL, url TEXT NOT NULL, provider TEXT NOT NULL )
|
||||
table|publisher_prefix_list|publisher_prefix_list|CREATE TABLE publisher_prefix_list (hash_prefix BLOB PRIMARY KEY NOT NULL)
|
||||
table|recurring_donation|recurring_donation|CREATE TABLE recurring_donation ( publisher_id LONGVARCHAR NOT NULL PRIMARY KEY UNIQUE, amount DOUBLE DEFAULT 0 NOT NULL, added_date INTEGER DEFAULT 0 NOT NULL , next_contribution_at TIMESTAMP)
|
||||
table|server_publisher_banner|server_publisher_banner|CREATE TABLE server_publisher_banner ( publisher_key LONGVARCHAR PRIMARY KEY NOT NULL UNIQUE, title TEXT, description TEXT, background TEXT, logo TEXT , web3_url TEXT)
|
||||
table|server_publisher_info|server_publisher_info|CREATE TABLE server_publisher_info ( publisher_key LONGVARCHAR PRIMARY KEY NOT NULL, status INTEGER DEFAULT 0 NOT NULL, address TEXT NOT NULL, updated_at TIMESTAMP NOT NULL )
|
||||
|
||||
@@ -328,6 +328,18 @@ void TestRewardsEngineClient::RunDBTransaction(
|
||||
std::move(callback).Run(std::move(response));
|
||||
}
|
||||
|
||||
void TestRewardsEngineClient::UpdateCreatorPrefixStore(
|
||||
mojom::HashPrefixDataPtr prefix_data,
|
||||
UpdateCreatorPrefixStoreCallback callback) {
|
||||
std::move(callback).Run(false);
|
||||
}
|
||||
|
||||
void TestRewardsEngineClient::CreatorPrefixStoreContains(
|
||||
const std::string& value,
|
||||
CreatorPrefixStoreContainsCallback callback) {
|
||||
std::move(callback).Run(false);
|
||||
}
|
||||
|
||||
void TestRewardsEngineClient::Log(const std::string& file,
|
||||
int32_t line,
|
||||
int32_t verbose_level,
|
||||
|
||||
@@ -173,6 +173,14 @@ class TestRewardsEngineClient : public mojom::RewardsEngineClient {
|
||||
void RunDBTransaction(mojom::DBTransactionPtr transaction,
|
||||
RunDBTransactionCallback callback) override;
|
||||
|
||||
void UpdateCreatorPrefixStore(
|
||||
mojom::HashPrefixDataPtr prefix_data,
|
||||
UpdateCreatorPrefixStoreCallback callback) override;
|
||||
|
||||
void CreatorPrefixStoreContains(
|
||||
const std::string& value,
|
||||
CreatorPrefixStoreContainsCallback callback) override;
|
||||
|
||||
void Log(const std::string& file,
|
||||
int32_t line,
|
||||
int32_t verbose_level,
|
||||
|
||||
@@ -71,3 +71,12 @@ struct DBCommandResponse {
|
||||
DBCommandResult? result;
|
||||
Status status;
|
||||
};
|
||||
|
||||
interface RewardsDatabase {
|
||||
RunDBTransaction(DBTransaction transaction) => (DBCommandResponse response);
|
||||
};
|
||||
|
||||
struct HashPrefixData {
|
||||
string prefixes;
|
||||
uint32 prefix_size;
|
||||
};
|
||||
|
||||
@@ -207,6 +207,10 @@ interface RewardsEngineClient {
|
||||
|
||||
RunDBTransaction(DBTransaction transaction) => (DBCommandResponse response);
|
||||
|
||||
UpdateCreatorPrefixStore(HashPrefixData prefix_data) => (bool success);
|
||||
|
||||
CreatorPrefixStoreContains(string value) => (bool contains_prefix);
|
||||
|
||||
Log(string file, int32 line, int32 verbose_level, string message);
|
||||
|
||||
ClearAllNotifications();
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "base/values.h"
|
||||
#include "brave/build/ios/mojom/cpp_transformations.h"
|
||||
#include "brave/components/brave_rewards/core/engine/global_constants.h"
|
||||
#include "brave/components/brave_rewards/core/engine/hash_prefix_store.h"
|
||||
#include "brave/components/brave_rewards/core/engine/rewards_database.h"
|
||||
#include "brave/components/brave_rewards/core/engine/rewards_engine.h"
|
||||
#include "brave/components/brave_rewards/core/rewards_flags.h"
|
||||
@@ -42,6 +43,8 @@
|
||||
#error "This file requires ARC support."
|
||||
#endif
|
||||
|
||||
using brave_rewards::internal::HashPrefixStore;
|
||||
|
||||
namespace brave_rewards::internal {
|
||||
|
||||
template <typename T>
|
||||
@@ -104,6 +107,7 @@ static NSString* const kTransferFeesPrefKey = @"transfer_fees";
|
||||
brave_rewards::internal::task_deleter<RewardsClientIOS>>
|
||||
_rewardsClient;
|
||||
base::SequenceBound<brave_rewards::internal::RewardsDatabase> rewardsDatabase;
|
||||
base::SequenceBound<HashPrefixStore> _creatorPrefixStore;
|
||||
scoped_refptr<base::SequencedTaskRunner> databaseQueue;
|
||||
scoped_refptr<base::SequencedTaskRunner> _engineTaskRunner;
|
||||
}
|
||||
@@ -172,6 +176,10 @@ static NSString* const kTransferFeesPrefKey = @"transfer_fees";
|
||||
base::SequenceBound<brave_rewards::internal::RewardsDatabase>(
|
||||
databaseQueue, base::FilePath(dbPath));
|
||||
|
||||
_creatorPrefixStore = base::SequenceBound<HashPrefixStore>(
|
||||
databaseQueue,
|
||||
base::FilePath(base::SysNSStringToUTF8([self creatorPrefixStorePath])));
|
||||
|
||||
_engineTaskRunner->PostTask(
|
||||
FROM_HERE, base::BindOnce(^{
|
||||
self->_rewardsClient =
|
||||
@@ -266,6 +274,11 @@ static NSString* const kTransferFeesPrefKey = @"transfer_fees";
|
||||
return [self.storagePath stringByAppendingPathComponent:@"Rewards.db"];
|
||||
}
|
||||
|
||||
- (NSString*)creatorPrefixStorePath {
|
||||
return
|
||||
[self.storagePath stringByAppendingPathComponent:@"RewardsCreators.db"];
|
||||
}
|
||||
|
||||
- (void)resetRewardsDatabase {
|
||||
const auto dbPath = [self rewardsDatabasePath];
|
||||
[NSFileManager.defaultManager removeItemAtPath:dbPath error:nil];
|
||||
@@ -275,6 +288,11 @@ static NSString* const kTransferFeesPrefKey = @"transfer_fees";
|
||||
rewardsDatabase =
|
||||
base::SequenceBound<brave_rewards::internal::RewardsDatabase>(
|
||||
databaseQueue, base::FilePath(base::SysNSStringToUTF8(dbPath)));
|
||||
|
||||
const auto prefixPath = [self creatorPrefixStorePath];
|
||||
[NSFileManager.defaultManager removeItemAtPath:prefixPath error:nil];
|
||||
_creatorPrefixStore = base::SequenceBound<HashPrefixStore>(
|
||||
databaseQueue, base::FilePath(base::SysNSStringToUTF8(prefixPath)));
|
||||
}
|
||||
|
||||
- (NSString*)randomStatePath {
|
||||
@@ -1024,6 +1042,25 @@ static NSString* const kTransferFeesPrefKey = @"transfer_fees";
|
||||
std::move(callback)));
|
||||
}
|
||||
|
||||
- (void)updateCreatorPrefixStore:
|
||||
(brave_rewards::mojom::HashPrefixDataPtr)prefix_data
|
||||
callback:
|
||||
(brave_rewards::mojom::RewardsEngineClient::
|
||||
UpdateCreatorPrefixStoreCallback)callback {
|
||||
_creatorPrefixStore.AsyncCall(&HashPrefixStore::UpdatePrefixes)
|
||||
.WithArgs(std::move(prefix_data->prefixes), prefix_data->prefix_size)
|
||||
.Then(std::move(callback));
|
||||
}
|
||||
|
||||
- (void)creatorPrefixStoreContains:(const std::string&)value
|
||||
callback:
|
||||
(brave_rewards::mojom::RewardsEngineClient::
|
||||
CreatorPrefixStoreContainsCallback)callback {
|
||||
_creatorPrefixStore.AsyncCall(&HashPrefixStore::ContainsPrefix)
|
||||
.WithArgs(value)
|
||||
.Then(std::move(callback));
|
||||
}
|
||||
|
||||
- (void)walletDisconnected:(const std::string&)wallet_type {
|
||||
// Not used on iOS
|
||||
}
|
||||
|
||||
@@ -139,6 +139,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
- (void)runDbTransaction:(brave_rewards::mojom::DBTransactionPtr)transaction
|
||||
callback:(brave_rewards::mojom::RewardsEngineClient::
|
||||
RunDBTransactionCallback)callback;
|
||||
- (void)updateCreatorPrefixStore:
|
||||
(brave_rewards::mojom::HashPrefixDataPtr)prefix_data
|
||||
callback:(brave_rewards::mojom::RewardsEngineClient::
|
||||
UpdateCreatorPrefixStoreCallback)callback;
|
||||
- (void)creatorPrefixStoreContains:(const std::string&)value
|
||||
callback:
|
||||
(brave_rewards::mojom::RewardsEngineClient::
|
||||
CreatorPrefixStoreContainsCallback)callback;
|
||||
- (void)log:(const std::string&)file
|
||||
line:(int32_t)line
|
||||
verboseLevel:(int32_t)verboseLevel
|
||||
|
||||
@@ -106,6 +106,12 @@ class RewardsClientIOS : public brave_rewards::mojom::RewardsEngineClient {
|
||||
void ReconcileStampReset() override;
|
||||
void RunDBTransaction(brave_rewards::mojom::DBTransactionPtr transaction,
|
||||
RunDBTransactionCallback callback) override;
|
||||
void UpdateCreatorPrefixStore(
|
||||
brave_rewards::mojom::HashPrefixDataPtr prefix_data,
|
||||
UpdateCreatorPrefixStoreCallback callback) override;
|
||||
void CreatorPrefixStoreContains(
|
||||
const std::string& value,
|
||||
CreatorPrefixStoreContainsCallback callback) override;
|
||||
void ClearAllNotifications() override;
|
||||
void ExternalWalletConnected() override;
|
||||
void ExternalWalletLoggedOut() override;
|
||||
|
||||
@@ -180,6 +180,17 @@ void RewardsClientIOS::RunDBTransaction(
|
||||
[bridge_ runDbTransaction:std::move(transaction)
|
||||
callback:std::move(callback)];
|
||||
}
|
||||
void RewardsClientIOS::UpdateCreatorPrefixStore(
|
||||
brave_rewards::mojom::HashPrefixDataPtr prefix_data,
|
||||
UpdateCreatorPrefixStoreCallback callback) {
|
||||
[bridge_ updateCreatorPrefixStore:std::move(prefix_data)
|
||||
callback:std::move(callback)];
|
||||
}
|
||||
void RewardsClientIOS::CreatorPrefixStoreContains(
|
||||
const std::string& value,
|
||||
CreatorPrefixStoreContainsCallback callback) {
|
||||
[bridge_ creatorPrefixStoreContains:value callback:std::move(callback)];
|
||||
}
|
||||
void RewardsClientIOS::ClearAllNotifications() {
|
||||
[bridge_ clearAllNotifications];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user