Skip to content

Commit

Permalink
Update config without node
Browse files Browse the repository at this point in the history
  • Loading branch information
spylogsster committed May 24, 2021
1 parent eac7986 commit 8dee132
Show file tree
Hide file tree
Showing 12 changed files with 237 additions and 22 deletions.
5 changes: 2 additions & 3 deletions components/ipfs/brave_ipfs_client_updater.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
#include "base/task/thread_pool.h"
#include "base/task_runner.h"
#include "base/task_runner_util.h"
#include "brave/components/ipfs/ipfs_utils.h"
#include "components/component_updater/component_updater_service.h"
#include "third_party/re2/src/re2/re2.h"

namespace ipfs {

Expand Down Expand Up @@ -57,8 +57,7 @@ base::FilePath InitExecutablePath(const base::FilePath& install_dir) {
for (base::FilePath current = traversal.Next(); !current.empty();
current = traversal.Next()) {
base::FileEnumerator::FileInfo file_info = traversal.GetInfo();
if (!RE2::FullMatch(file_info.GetName().MaybeAsASCII(),
"go-ipfs_v\\d+\\.\\d+\\.\\d+\\_\\w+-amd64"))
if (!ipfs::IsValidNodeFilename(file_info.GetName().MaybeAsASCII()))
continue;
executable_path = current;
break;
Expand Down
1 change: 1 addition & 0 deletions components/ipfs/ipfs_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ IpfsService::IpfsService(content::BrowserContext* context,
if (ipfs_client_updater_) {
ipfs_client_updater_->AddObserver(this);
OnExecutableReady(ipfs_client_updater_->GetExecutablePath());
RegisterIpfsClientUpdater();
}
ipns_keys_manager_ =
std::make_unique<IpnsKeysManager>(context_, server_endpoint_);
Expand Down
11 changes: 11 additions & 0 deletions components/ipfs/ipfs_utils.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "content/public/browser/browser_context.h"
#include "extensions/common/url_pattern.h"
#include "net/base/url_util.h"
#include "third_party/re2/src/re2/re2.h"
#include "url/gurl.h"

namespace {
Expand All @@ -32,6 +33,12 @@ GURL AppendLocalPort(const std::string& port) {
return gateway.ReplaceComponents(replacements);
}

// RegEx to validate the node name:
// go-ipfs_v0.9.0-rc1_windows-amd64 - valid
// go-ipfs_v0.9.0_windows-amd64 - valid
constexpr char kExecutableRegEx[] =
"go-ipfs_v(\\d+\\.\\d+\\.\\d+)(-rc\\d+)?\\_\\w+-amd64";

// Valid CID multibase prefix, "code" character
// from https://github.com/multiformats/multibase/blob/master/multibase.csv
const char kCIDv1Codes[] = "079fFvVtTbBcChkKzZmMuU";
Expand Down Expand Up @@ -331,4 +338,8 @@ bool ParsePeerConnectionString(const std::string& value,
return valid;
}

bool IsValidNodeFilename(const std::string& filename) {
return RE2::FullMatch(filename, kExecutableRegEx);
}

} // namespace ipfs
1 change: 1 addition & 0 deletions components/ipfs/ipfs_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ bool TranslateIPFSURI(const GURL& url,
const GURL& gateway_url,
bool use_subdomain);
bool IsIpfsMenuEnabled(content::BrowserContext* browser_context);
bool IsValidNodeFilename(const std::string& filename);

bool ParsePeerConnectionString(const std::string& value,
std::string* id,
Expand Down
18 changes: 18 additions & 0 deletions components/ipfs/ipfs_utils_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -596,3 +596,21 @@ TEST_F(IpfsUtilsUnitTest, ParsePeerConnectionStringTest) {
value, "12D3KooWBdmLJjhpgJ9KZgLM3f894ff9xyBfPvPjFNn7MKJpyrC2",
"/ip4/46.21.210.45/udp/14406/quic"));
}

TEST_F(IpfsUtilsUnitTest, ValidateNodeFilename) {
ASSERT_TRUE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0-rc1_windows-amd64"));
ASSERT_TRUE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0-rc21_windows-amd64"));
ASSERT_TRUE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0_windows-amd64"));

ASSERT_TRUE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0-rc1_darwin-amd64"));
ASSERT_TRUE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0-rc21_darwin-amd64"));
ASSERT_TRUE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0_darwin-amd64"));

ASSERT_TRUE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0-rc1_linux-amd64"));
ASSERT_TRUE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0-rc21_linux-amd64"));
ASSERT_TRUE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0_linux-amd64"));

ASSERT_FALSE(ipfs::IsValidNodeFilename(""));
ASSERT_FALSE(ipfs::IsValidNodeFilename("ipfs.exe"));
ASSERT_FALSE(ipfs::IsValidNodeFilename("go-ipfs_v0.9.0_linux"));
}
6 changes: 5 additions & 1 deletion components/services/ipfs/BUILD.gn
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
source_set("ipfs") {
sources = [ "ipfs_service_impl.h" ]
sources = [
"ipfs_service_impl.h",
"ipfs_service_utils.cc",
"ipfs_service_utils.h",
]
if (!is_android) {
sources += [ "ipfs_service_impl.cc" ]
} else {
Expand Down
43 changes: 25 additions & 18 deletions components/services/ipfs/ipfs_service_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/process/launch.h"
#include "brave/components/services/ipfs/ipfs_service_utils.h"

namespace {

Expand Down Expand Up @@ -105,22 +106,36 @@ void IpfsServiceImpl::Launch(mojom::IpfsConfigPtr config,
if (!base::PathExists(config_path)) {
// run ipfs init to gen config
if (!LaunchProcessAndExit(config->binary_path, {"init"}, options)) {
std::move(callback).Run(false, -1);
if (callback)
std::move(callback).Run(false, -1);
return;
}
}
std::string data;
if (!base::ReadFileToString(config_path, &data)) {
VLOG(1) << "Unable to read the ipfs config:" << config_path;
if (callback)
std::move(callback).Run(false, -1);
return;
}

std::string updated_config;
if (!ipfs::UpdateConfigJSON(data, config.get(), &updated_config)) {
VLOG(1) << "Unable to update the ipfs config:" << config_path;
if (callback)
std::move(callback).Run(false, -1);
return;
}
if (!base::WriteFile(config_path, updated_config)) {
VLOG(1) << "Unable to write the ipfs config:" << config_path;
if (callback)
std::move(callback).Run(false, -1);
return;
}

std::initializer_list<std::initializer_list<std::string>> config_args = {
{"shutdown"}, // Cleanup left-over daemon process.
{"config", "Addresses.API", "/ip4/127.0.0.1/tcp/" + config->api_port},
{"config", "Addresses.Gateway",
"/ip4/127.0.0.1/tcp/" + config->gateway_port},
{"config", "--json", "Addresses.Swarm",
"[\"/ip4/0.0.0.0/tcp/" + config->swarm_port + "\", \"/ip6/::/tcp/" +
config->swarm_port + "\"]"},
{"config", "Datastore.GCPeriod", "1h"},
{"config", "--json", "Swarm.ConnMgr.LowWater", "50"},
{"config", "--json", "Swarm.ConnMgr.HighWater", "300"}};
};

for (auto args : config_args) {
if (!LaunchProcessAndExit(config->binary_path, args, options)) {
Expand All @@ -129,14 +144,6 @@ void IpfsServiceImpl::Launch(mojom::IpfsConfigPtr config,
}
}

// Configure storage
if (!LaunchProcessAndExit(
config->binary_path,
{"config", "Datastore.StorageMax", config->storage_max}, options)) {
std::move(callback).Run(false, -1);
return;
}

child_monitor_ = std::make_unique<brave::ChildProcessMonitor>();

// Launch IPFS daemon.
Expand Down
58 changes: 58 additions & 0 deletions components/services/ipfs/ipfs_service_utils.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/* Copyright (c) 2021 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 <memory>
#include <utility>

#include "base/json/json_reader.h"
#include "base/json/json_writer.h"

#include "brave/components/services/ipfs/ipfs_service_utils.h"

#include "brave/components/services/ipfs/public/mojom/ipfs_service.mojom.h"

namespace ipfs {

// Updates the ipfs node config to meet current preferences
bool UpdateConfigJSON(const std::string& source,
const ipfs::mojom::IpfsConfig* config,
std::string* result) {
base::JSONReader::ValueWithError value_with_error =
base::JSONReader::ReadAndReturnValueWithError(
source, base::JSONParserOptions::JSON_PARSE_RFC);
base::Optional<base::Value>& records_v = value_with_error.value;
if (!records_v) {
VLOG(1) << "Could not parse JSON, JSON is: " << source;
return false;
}
base::DictionaryValue* dict = nullptr;
if (!records_v->GetAsDictionary(&dict)) {
VLOG(1) << "Could not parse JSON, JSON is: " << source;
return false;
}
dict->Set("Addresses.API", std::make_unique<base::Value>(
"/ip4/127.0.0.1/tcp/" + config->api_port));
dict->Set("Addresses.Gateway",
std::make_unique<base::Value>("/ip4/127.0.0.1/tcp/" +
config->gateway_port));
dict->Set("Datastore.GCPeriod", std::make_unique<base::Value>("1h"));
dict->Set("Swarm.ConnMgr.LowWater", std::make_unique<base::Value>(50));
dict->Set("Swarm.ConnMgr.HighWater", std::make_unique<base::Value>(300));
dict->Set("Datastore.StorageMax",
std::make_unique<base::Value>(config->storage_max));
std::unique_ptr<base::ListValue> list = std::make_unique<base::ListValue>();
list->Append(base::Value("/ip4/0.0.0.0/tcp/" + config->swarm_port));
list->Append(base::Value("/ip6/::/tcp/" + config->swarm_port));
dict->Set("Addresses.Swarm", std::move(list));
std::string json_string;
if (!base::JSONWriter::Write(records_v.value(), &json_string) ||
json_string.empty()) {
return false;
}
*result = json_string;
return true;
}

} // namespace ipfs
24 changes: 24 additions & 0 deletions components/services/ipfs/ipfs_service_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/* Copyright (c) 2021 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 BRAVE_COMPONENTS_SERVICES_IPFS_IPFS_SERVICE_UTILS_H_
#define BRAVE_COMPONENTS_SERVICES_IPFS_IPFS_SERVICE_UTILS_H_

#include <string>

namespace ipfs {

namespace mojom {
class IpfsConfig;
}

// Updates the ipfs node config to meet current preferences
bool UpdateConfigJSON(const std::string& source,
const ipfs::mojom::IpfsConfig* config,
std::string* result);

} // namespace ipfs

#endif // BRAVE_COMPONENTS_SERVICES_IPFS_IPFS_SERVICE_UTILS_H_
68 changes: 68 additions & 0 deletions components/services/ipfs/ipfs_service_utils_unittest.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
/* Copyright (c) 2021 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 <memory>

#include "base/json/json_reader.h"
#include "base/json/json_writer.h"

#include "brave/components/services/ipfs/ipfs_service_utils.h"

#include "brave/components/services/ipfs/public/mojom/ipfs_service.mojom.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace ipfs {

typedef testing::Test IPFSServiceUtils;

TEST_F(IPFSServiceUtils, UpdateConfigJSONTest) {
std::string json = R"({})";
std::string updated;
auto config = ipfs::mojom::IpfsConfig::New(
base::FilePath(), base::FilePath(), base::FilePath(), "GatewayPort",
"APIPort", "SwarmPort", "StorageSize");

std::string expect =
"{\"Addresses\":{\"API\":\"/ip4/127.0.0.1/tcp/APIPort\","
"\"Gateway\":\"/ip4/127.0.0.1/tcp/GatewayPort\",\"Swarm\":"
"[\"/ip4/0.0.0.0/tcp/SwarmPort\",\"/ip6/::/tcp/SwarmPort\""
"]},\"Datastore\":{\"GCPeriod\":\"1h\",\"StorageMax\":"
"\"StorageSize\"},\"Swarm\":{\"ConnMgr\":{\"HighWater\""
":300,\"LowWater\":50}}}";
ASSERT_TRUE(UpdateConfigJSON(json, config.get(), &updated));
EXPECT_EQ(updated, expect);
updated.clear();
json = R"({
"Addresses":{
"API":"/ip4/127.0.0.1/tcp/111",
"Gateway":"/ip4/127.0.0.1/tcp/111",
"Swarm":[
"/ip4/0.0.0.0/tcp/222",
"/ip6/::/tcp/222",
"/ip6/::/udp/666"
]
},
"Datastore":{
"GCPeriod":"6h",
"StorageMax":"9GB"
},
"Swarm":{
"ConnMgr":{
"HighWater":0,
"LowWater":0
}
}
})";
ASSERT_TRUE(UpdateConfigJSON(json, config.get(), &updated));
EXPECT_EQ(updated, expect);
updated.clear();
ASSERT_FALSE(UpdateConfigJSON("{", config.get(), &updated));
EXPECT_EQ(updated, "");
updated.clear();
ASSERT_FALSE(UpdateConfigJSON("[]", config.get(), &updated));
EXPECT_EQ(updated, "");
}

} // namespace ipfs
23 changes: 23 additions & 0 deletions components/services/ipfs/test/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright (c) 2021 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/. */

import("//brave/build/config.gni")
import("//brave/components/ipfs/buildflags/buildflags.gni")
import("//testing/test.gni")

source_set("ipfs_service_unit_tests") {
testonly = true
if (ipfs_enabled) {
sources =
[ "//brave/components/services/ipfs/ipfs_service_utils_unittest.cc" ]

deps = [
"//base/test:test_support",
"//brave/components/services/ipfs",
"//brave/components/services/ipfs/public/mojom",
"//testing/gtest",
]
} # if (ipfs_enabled)
} # source_set("ipfs_service_unit_tests")
1 change: 1 addition & 0 deletions test/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ test("brave_unit_tests") {
"//brave/components/ntp_widget_utils/browser",
"//brave/components/p3a",
"//brave/components/permissions:unit_tests",
"//brave/components/services/ipfs/test:ipfs_service_unit_tests",
"//brave/components/sidebar:unit_tests",
"//brave/components/tor:tor_unit_tests",
"//brave/components/tor/buildflags",
Expand Down

0 comments on commit 8dee132

Please sign in to comment.