Skip to content

Commit

Permalink
Move Zcash protobuf parsing to separate process (#21627)
Browse files Browse the repository at this point in the history
* Move Zcash protobuf parsing to separate process
Introduces BraveWalletUtilsService that is able to provide ZCashDecoder
to convert protobufs to mojo structs and pass them to the mai.
Resolves brave/brave-browser#34561
  • Loading branch information
cypt4 authored Jan 29, 2024
1 parent 224c58b commit 5b8ea34
Show file tree
Hide file tree
Showing 44 changed files with 975 additions and 184 deletions.
4 changes: 4 additions & 0 deletions app/brave_generated_resources.grd
Original file line number Diff line number Diff line change
Expand Up @@ -898,6 +898,10 @@ Or change later at <ph name="SETTINGS_EXTENIONS_LINK">$2<ex>brave://settings/ext
<message name="IDS_BRAVE_IPFS_ALWAYS_START_INFOBAR_NO" desc="Ignore proposition">
Cancel
</message>
<!-- Brave Wallet -->
<message name="IDS_UTILITY_PROCESS_WALLET_UTILS_NAME" desc="The utility process running wallet utils">
Brave Wallet Utility Service
</message>

<!-- Brave Wayback Machine -->
<message name="IDS_BRAVE_WAYBACK_MACHINE_INFOBAR_PAGE_MISSING_TEXT" desc="The label for sorry message when page is not available on infobar">
Expand Down
9 changes: 4 additions & 5 deletions components/brave_wallet/browser/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,6 @@ static_library("browser") {
":pref_names",
":transaction",
":utils",
":zcash_proto",
"//base",
"//brave/components/brave_component_updater/browser",
"//brave/components/brave_stats/browser",
Expand All @@ -267,6 +266,10 @@ static_library("browser") {
"//brave/components/json/rs:rust_lib",
"//brave/components/p3a_utils",
"//brave/components/resources:strings_grit",
"//brave/components/services/brave_wallet/public/cpp",
"//brave/components/services/brave_wallet/public/cpp/utils",
"//brave/components/services/brave_wallet/public/mojom",
"//brave/components/services/brave_wallet/public/proto:zcash_proto",
"//brave/third_party/argon2",
"//components/component_updater",
"//components/content_settings/core/browser",
Expand Down Expand Up @@ -490,10 +493,6 @@ generated_types("generated_swap_responses") {
]
}

proto_library("zcash_proto") {
sources = [ "zcash/protos/zcash_grpc_data.proto" ]
}

config("sardine_config") {
defines = [
"SARDINE_CLIENT_ID=\"$sardine_client_id\"",
Expand Down
2 changes: 2 additions & 0 deletions components/brave_wallet/browser/test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ source_set("brave_wallet_unit_tests") {
"//brave/components/ipfs",
"//brave/components/json/rs:rust_lib",
"//brave/components/resources:strings_grit",
"//brave/components/services/brave_wallet/public/cpp/utils",
"//brave/components/services/brave_wallet/public/mojom",
"//components/component_updater:test_support",
"//components/permissions",
"//components/prefs",
Expand Down
10 changes: 5 additions & 5 deletions components/brave_wallet/browser/zcash/zcash_block_tracker.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ std::optional<uint32_t> ZCashBlockTracker::GetLatestHeight(

void ZCashBlockTracker::OnGetLatestBlockForHeight(
const std::string& chain_id,
base::expected<zcash::BlockID, std::string> latest_block) {
if (!latest_block.has_value()) {
base::expected<mojom::BlockIDPtr, std::string> latest_block) {
if (!latest_block.has_value() || !latest_block.value()) {
return;
}
auto cur_latest_height = GetLatestHeight(chain_id);
if (cur_latest_height &&
cur_latest_height.value() == latest_block->height()) {
cur_latest_height.value() == (*latest_block)->height) {
return;
}
latest_height_map_[chain_id] = latest_block->height();
latest_height_map_[chain_id] = (*latest_block)->height;
for (auto& observer : observers_) {
observer.OnLatestHeightUpdated(chain_id, latest_block->height());
observer.OnLatestHeightUpdated(chain_id, (*latest_block)->height);
}
}

Expand Down
4 changes: 2 additions & 2 deletions components/brave_wallet/browser/zcash/zcash_block_tracker.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
#include "base/time/time.h"
#include "base/types/expected.h"
#include "brave/components/brave_wallet/browser/block_tracker.h"
#include "brave/components/brave_wallet/browser/zcash/protos/zcash_grpc_data.pb.h"
#include "brave/components/services/brave_wallet/public/mojom/zcash_decoder.mojom.h"

namespace brave_wallet {

Expand Down Expand Up @@ -44,7 +44,7 @@ class ZCashBlockTracker : public BlockTracker {
void GetBlockHeight(const std::string& chain_id);
void OnGetLatestBlockForHeight(
const std::string& chain_id,
base::expected<zcash::BlockID, std::string> latest_height);
base::expected<mojom::BlockIDPtr, std::string> latest_height);

// <chain_id, block_height>
std::map<std::string, uint32_t> latest_height_map_;
Expand Down
29 changes: 0 additions & 29 deletions components/brave_wallet/browser/zcash/zcash_grpc_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,6 @@ constexpr size_t kGrpcHeaderSize = 5;
constexpr char kNoCompression = 0;
} // namespace

std::string GetPrefixedProtobuf(const std::string& serialized_proto) {
std::string result(kGrpcHeaderSize, 0);
result[0] = kNoCompression;
base::WriteBigEndian<uint32_t>(&result[1], serialized_proto.size());
result.append(serialized_proto);
return result;
}

// Resolves serialized protobuf from length-prefixed string
std::optional<std::string> ResolveSerializedMessage(
const std::string& grpc_response_body) {
if (grpc_response_body.size() < kGrpcHeaderSize) {
return std::nullopt;
}
if (grpc_response_body[0] != kNoCompression) {
// Compression is not supported yet
return std::nullopt;
}
uint32_t size = 0;
base::ReadBigEndian(
reinterpret_cast<const uint8_t*>(&(grpc_response_body[1])), &size);

if (grpc_response_body.size() != size + kGrpcHeaderSize) {
return std::nullopt;
}

return grpc_response_body.substr(kGrpcHeaderSize);
}

GRrpcMessageStreamHandler::GRrpcMessageStreamHandler() = default;
GRrpcMessageStreamHandler::~GRrpcMessageStreamHandler() = default;

Expand Down
10 changes: 0 additions & 10 deletions components/brave_wallet/browser/zcash/zcash_grpc_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,13 @@
#ifndef BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_ZCASH_ZCASH_GRPC_UTILS_H_
#define BRAVE_COMPONENTS_BRAVE_WALLET_BROWSER_ZCASH_ZCASH_GRPC_UTILS_H_

#include <optional>
#include <string>
#include <string_view>

#include "services/network/public/cpp/simple_url_loader_stream_consumer.h"

namespace brave_wallet {

// Resolves serialized protobuf from length-prefixed string
std::optional<std::string> ResolveSerializedMessage(
const std::string& grpc_response_body);

// Prefixes provided serialized protobuf with compression byte and 4 bytes of
// message size. See
// https://github.com/grpc/grpc/blob/master/doc/PROTOCOL-HTTP2.md
std::string GetPrefixedProtobuf(const std::string& serialized_proto);

// Handles a stream of GRPC objects
class GRrpcMessageStreamHandler
: public network::SimpleURLLoaderStreamConsumer {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "base/functional/callback.h"
#include "base/strings/strcat.h"
#include "base/test/bind.h"
#include "brave/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace brave_wallet {
Expand Down
113 changes: 45 additions & 68 deletions components/brave_wallet/browser/zcash/zcash_rpc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
#include "base/functional/bind.h"
#include "brave/components/brave_wallet/browser/brave_wallet_utils.h"
#include "brave/components/brave_wallet/common/brave_wallet.mojom.h"
#include "brave/components/services/brave_wallet/public/cpp/brave_wallet_utils_service.h"
#include "brave/components/services/brave_wallet/public/cpp/utils/protobuf_utils.h"
#include "brave/components/services/brave_wallet/public/proto/zcash_grpc_data.pb.h"
#include "components/grit/brave_components_strings.h"
#include "net/base/load_flags.h"
#include "net/http/http_request_headers.h"
Expand Down Expand Up @@ -319,10 +322,9 @@ void ZCashRpc::GetTransaction(const std::string& chain_id,
5000);
}

void ZCashRpc::OnGetUtxosResponse(
ZCashRpc::GetUtxoListCallback callback,
UrlLoadersList::iterator it,
const std::unique_ptr<std::string> response_body) {
void ZCashRpc::OnGetUtxosResponse(ZCashRpc::GetUtxoListCallback callback,
UrlLoadersList::iterator it,
std::unique_ptr<std::string> response_body) {
auto current_loader = std::move(*it);
url_loaders_list_.erase(it);
if (current_loader->NetError()) {
Expand All @@ -337,35 +339,32 @@ void ZCashRpc::OnGetUtxosResponse(
return;
}

auto message = ResolveSerializedMessage(*response_body);
if (!message) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)));
return;
}
GetDecoder()->ParseGetAddressUtxos(
*response_body,
base::BindOnce(
&ZCashRpc::OnParseResult<mojom::GetAddressUtxosResponsePtr>,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

zcash::GetAddressUtxosResponse response;
if (!response.ParseFromString(message.value())) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)));
template <typename T>
void ZCashRpc::OnParseResult(
base::OnceCallback<void(base::expected<T, std::string>)> callback,
T value) {
if (value) {
std::move(callback).Run(std::move(value));
return;
}

std::vector<zcash::ZCashUtxo> result;
for (const auto& item : response.addressutxos()) {
result.push_back(item);
}

std::move(callback).Run(result);
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)));
}

void ZCashRpc::OnGetLatestBlockResponse(
ZCashRpc::GetLatestBlockCallback callback,
UrlLoadersList::iterator it,
const std::unique_ptr<std::string> response_body) {
std::unique_ptr<std::string> response_body) {
auto current_loader = std::move(*it);
url_loaders_list_.erase(it);
zcash::BlockID response;
if (current_loader->NetError()) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)));
Expand All @@ -378,29 +377,18 @@ void ZCashRpc::OnGetLatestBlockResponse(
return;
}

auto message = ResolveSerializedMessage(*response_body);
if (!message) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)));
return;
}

if (!response.ParseFromString(message.value())) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)));
return;
}

std::move(callback).Run(response);
GetDecoder()->ParseBlockID(
*response_body,
base::BindOnce(&ZCashRpc::OnParseResult<mojom::BlockIDPtr>,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

void ZCashRpc::OnGetTransactionResponse(
ZCashRpc::GetTransactionCallback callback,
UrlLoadersList::iterator it,
const std::unique_ptr<std::string> response_body) {
std::unique_ptr<std::string> response_body) {
auto current_loader = std::move(*it);
url_loaders_list_.erase(it);
zcash::RawTransaction response;
if (current_loader->NetError()) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)));
Expand All @@ -413,20 +401,10 @@ void ZCashRpc::OnGetTransactionResponse(
return;
}

auto message = ResolveSerializedMessage(*response_body);
if (!message) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)));
return;
}

if (!response.ParseFromString(message.value())) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)));
return;
}

std::move(callback).Run(response);
GetDecoder()->ParseRawTransaction(
*response_body,
base::BindOnce(&ZCashRpc::OnParseResult<mojom::RawTransactionPtr>,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

void ZCashRpc::SendTransaction(const std::string& chain_id,
Expand Down Expand Up @@ -488,10 +466,9 @@ void ZCashRpc::IsKnownAddress(const std::string& chain_id,
void ZCashRpc::OnSendTransactionResponse(
ZCashRpc::SendTransactionCallback callback,
UrlLoadersList::iterator it,
const std::unique_ptr<std::string> response_body) {
std::unique_ptr<std::string> response_body) {
auto current_loader = std::move(*it);
url_loaders_list_.erase(it);
zcash::SendResponse response;
if (current_loader->NetError()) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_INTERNAL_ERROR)));
Expand All @@ -504,20 +481,10 @@ void ZCashRpc::OnSendTransactionResponse(
return;
}

auto message = ResolveSerializedMessage(*response_body);
if (!message) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)));
return;
}

if (!response.ParseFromString(message.value())) {
std::move(callback).Run(
base::unexpected(l10n_util::GetStringUTF8(IDS_WALLET_PARSING_ERROR)));
return;
}

std::move(callback).Run(response);
GetDecoder()->ParseSendResponse(
*response_body,
base::BindOnce(&ZCashRpc::OnParseResult<mojom::SendResponsePtr>,
weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
}

void ZCashRpc::OnGetAddressTxResponse(
Expand All @@ -540,4 +507,14 @@ void ZCashRpc::OnGetAddressTxResponse(
std::move(callback).Run(result.value());
}

mojo::AssociatedRemote<mojom::ZCashDecoder>& ZCashRpc::GetDecoder() {
if (zcash_decoder_.is_bound()) {
return zcash_decoder_;
}
BraveWalletUtilsService::GetInstance()->CreateZCashDecoder(
zcash_decoder_.BindNewEndpointAndPassReceiver());
zcash_decoder_.reset_on_disconnect();
return zcash_decoder_;
}

} // namespace brave_wallet
Loading

0 comments on commit 5b8ea34

Please sign in to comment.