Skip to content

Commit ac47b18

Browse files
Feature/fs repository (#46)
Signed-off-by: Alexey-N-Chernyshov <[email protected]>
1 parent bb58f12 commit ac47b18

21 files changed

+471
-29
lines changed

core/storage/ipfs/CMakeLists.txt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,17 @@
22
# Copyright Soramitsu Co., Ltd. All Rights Reserved.
33
# SPDX-License-Identifier: Apache-2.0
44
#
5+
add_library(ipfs_datastore_in_memory
6+
impl/in_memory_datastore.cpp
7+
impl/ipfs_datastore_error.cpp
8+
)
9+
target_link_libraries(ipfs_datastore_in_memory
10+
p2p::p2p_cid
11+
buffer
12+
)
513

614
add_library(ipfs_datastore_leveldb
715
impl/datastore_leveldb.cpp
8-
impl/in_memory_datastore.cpp
916
impl/ipfs_datastore_error.cpp
1017
)
1118
target_link_libraries(ipfs_datastore_leveldb

core/storage/repository/CMakeLists.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,16 @@ add_library(repository
88
target_link_libraries(repository
99
outcome
1010
)
11+
12+
add_library(filesystem_repository
13+
impl/filesystem_repository.cpp
14+
)
15+
target_link_libraries(filesystem_repository
16+
Boost::filesystem
17+
config
18+
fslock
19+
ipfs_datastore_leveldb
20+
keystore
21+
outcome
22+
repository
23+
)
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#include "storage/repository/impl/filesystem_repository.hpp"
7+
8+
#include <utility>
9+
10+
#include "boost/filesystem.hpp"
11+
#include "crypto/bls_provider/impl/bls_provider_impl.hpp"
12+
#include "libp2p/crypto/secp256k1_provider/secp256k1_provider_impl.hpp"
13+
#include "primitives/address/impl/address_verifier_impl.hpp"
14+
#include "storage/ipfs/impl/datastore_leveldb.hpp"
15+
#include "storage/keystore/impl/filesystem/filesystem_keystore.hpp"
16+
#include "storage/repository/repository_error.hpp"
17+
18+
using fc::crypto::bls::impl::BlsProviderImpl;
19+
using fc::primitives::address::AddressVerifierImpl;
20+
using fc::storage::ipfs::LeveldbDatastore;
21+
using fc::storage::keystore::FileSystemKeyStore;
22+
using fc::storage::repository::FileSystemRepository;
23+
using fc::storage::repository::Repository;
24+
using fc::storage::repository::RepositoryError;
25+
using libp2p::crypto::secp256k1::Secp256k1ProviderImpl;
26+
using Version = fc::storage::repository::Repository::Version;
27+
28+
FileSystemRepository::FileSystemRepository(
29+
std::shared_ptr<IpfsDatastore> ipld_store,
30+
std::shared_ptr<KeyStore> keystore,
31+
std::shared_ptr<Config> config,
32+
std::string repository_path,
33+
std::unique_ptr<fslock::Locker> fs_locker)
34+
: Repository{std::move(ipld_store), std::move(keystore), std::move(config)},
35+
repository_path_{std::move(repository_path)},
36+
fs_locker_{std::move(fs_locker)} {}
37+
38+
fc::outcome::result<std::shared_ptr<Repository>> FileSystemRepository::create(
39+
const Path &repo_path,
40+
const std::string &api_address,
41+
const leveldb::Options &leveldb_options) {
42+
// check version if version file exists
43+
auto version_filename =
44+
repo_path + fc::storage::filestore::DELIMITER + kVersionFilename;
45+
if (boost::filesystem::exists(version_filename)) {
46+
boost::filesystem::ifstream version_is(version_filename);
47+
std::string version_line;
48+
std::getline(version_is, version_line);
49+
// returns version number or 0 in case of failure
50+
Version version = atoi(version_line.c_str());
51+
if (version != kFileSystemRepositoryVersion)
52+
return RepositoryError::WRONG_VERSION;
53+
} else {
54+
logger_->debug("Version file does not exist \"" + repo_path
55+
+ fc::storage::filestore::DELIMITER + version_filename
56+
+ "\". Will be created.");
57+
}
58+
59+
// try lock
60+
auto lock_filename =
61+
repo_path + fc::storage::filestore::DELIMITER + kRepositoryLock;
62+
std::unique_ptr<fslock::Locker> fs_locker =
63+
std::make_unique<fslock::Locker>();
64+
OUTCOME_TRY(fs_locker->lock(lock_filename));
65+
66+
// load config if exists
67+
auto config_filename =
68+
repo_path + fc::storage::filestore::DELIMITER + kConfigFilename;
69+
auto config = std::make_shared<Config>();
70+
if (boost::filesystem::exists(config_filename)) {
71+
OUTCOME_TRY(config->load(config_filename));
72+
}
73+
74+
// write api address
75+
auto api_filename =
76+
repo_path + fc::storage::filestore::DELIMITER + kApiFilename;
77+
boost::filesystem::ofstream api_os(api_filename);
78+
if (!api_os.is_open()) return RepositoryError::OPEN_FILE_ERROR;
79+
api_os << api_address << std::endl;
80+
api_os.close();
81+
82+
// write version
83+
boost::filesystem::ofstream version_os(version_filename);
84+
if (!version_os.is_open()) return RepositoryError::OPEN_FILE_ERROR;
85+
version_os << kFileSystemRepositoryVersion << std::endl;
86+
version_os.close();
87+
88+
// create datastore
89+
auto datastore_path =
90+
repo_path + fc::storage::filestore::DELIMITER + kDatastore;
91+
OUTCOME_TRY(ipfs_datastore,
92+
LeveldbDatastore::create(datastore_path, leveldb_options));
93+
94+
// create keystore
95+
auto keystore_path =
96+
repo_path + fc::storage::filestore::DELIMITER + kKeysDirectory;
97+
boost::filesystem::create_directory(keystore_path);
98+
auto keystore = std::make_shared<FileSystemKeyStore>(
99+
keystore_path,
100+
std::make_shared<BlsProviderImpl>(),
101+
std::make_shared<Secp256k1ProviderImpl>(),
102+
std::make_shared<AddressVerifierImpl>());
103+
104+
return std::make_shared<FileSystemRepository>(
105+
ipfs_datastore, keystore, config, repo_path, std::move(fs_locker));
106+
}
107+
108+
fc::outcome::result<Version> FileSystemRepository::getVersion() const {
109+
return kFileSystemRepositoryVersion;
110+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* Copyright Soramitsu Co., Ltd. All Rights Reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
#ifndef FILECOIN_CORE_STORAGE_IMPL_FILESYSTEM_REPOSITORY_HPP
7+
#define FILECOIN_CORE_STORAGE_IMPL_FILESYSTEM_REPOSITORY_HPP
8+
9+
#include <iostream>
10+
11+
#include "fslock/fslock.hpp"
12+
#include "storage/filestore/path.hpp"
13+
#include "storage/leveldb/leveldb.hpp"
14+
#include "storage/repository/repository.hpp"
15+
16+
namespace fc::storage::repository {
17+
18+
using filestore::Path;
19+
using Version = Repository::Version;
20+
21+
/**
22+
* @brief FileSystem implementation of Repository.
23+
*
24+
* Directory structure of Filesystem Repository is:
25+
* .ipfs/
26+
* ├── api <--- running daemon api addr
27+
* ├── blocks/ <--- objects stored directly on disk
28+
* │ └── aa <--- prefix namespacing like git
29+
* │ └── aa <--- N tiers
30+
* ├── config <--- config file (json or toml)
31+
* ├── hooks/ <--- hook scripts (not implemented yet)
32+
* ├── keys/ <--- cryptographic keys
33+
* │ ├── id.pri <--- identity private key
34+
* │ └── id.pub <--- identity public key
35+
* ├── datastore/ <--- datastore
36+
* ├── logs/ <--- 1 or more files (log rotate)
37+
* │ └── events.log <--- can be tailed
38+
* ├── repo.lock <--- mutex for repo
39+
* └── version <--- version file
40+
*
41+
*/
42+
class FileSystemRepository : public Repository {
43+
public:
44+
inline static const std::string kApiFilename = "api";
45+
inline static const std::string kConfigFilename = "config.json";
46+
inline static const std::string kKeysDirectory = "keys";
47+
inline static const std::string kDatastore = "datastore";
48+
inline static const std::string kRepositoryLock = "repo.lock";
49+
inline static const std::string kVersionFilename = "version";
50+
inline static const Version kFileSystemRepositoryVersion = 1;
51+
52+
FileSystemRepository(std::shared_ptr<IpfsDatastore> ipld_store,
53+
std::shared_ptr<KeyStore> keystore,
54+
std::shared_ptr<Config> config,
55+
std::string repository_path,
56+
std::unique_ptr<fslock::Locker> fs_locker);
57+
58+
static outcome::result<std::shared_ptr<Repository>> create(
59+
const Path &repo_path,
60+
const std::string &api_address,
61+
const leveldb::Options &leveldb_options);
62+
63+
outcome::result<Version> getVersion() const override;
64+
65+
private:
66+
Path repository_path_;
67+
std::unique_ptr<fslock::Locker> fs_locker_;
68+
inline static common::Logger logger_ = common::createLogger("repository");
69+
};
70+
71+
} // namespace fc::storage::repository
72+
73+
#endif // FILECOIN_CORE_STORAGE_IMPL_FILESYSTEM_REPOSITORY_HPP

core/storage/repository/impl/repository_error.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ OUTCOME_CPP_DEFINE_CATEGORY(fc::storage::repository, RepositoryError, e) {
1111
switch (e) {
1212
case RepositoryError::WRONG_VERSION:
1313
return "RepositoryError: wrong version";
14+
case RepositoryError::OPEN_FILE_ERROR:
15+
return "RepositoryError: cannot open file";
1416
case RepositoryError::UNKNOWN:
1517
break;
1618
}

core/storage/repository/repository_error.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ namespace fc::storage::repository {
1515
*/
1616
enum class RepositoryError {
1717
WRONG_VERSION = 1,
18+
OPEN_FILE_ERROR,
1819

1920
UNKNOWN
2021
};

test/core/fslock/fslock_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ using fc::storage::filestore::Path;
1818

1919
class FSLockTest : public test::BaseFS_Test {
2020
public:
21-
FSLockTest() : test::BaseFS_Test("/tmp/fc_filesystem_lock_file_test/") {}
21+
FSLockTest() : test::BaseFS_Test("fc_filesystem_lock_file_test") {}
2222

2323
/** Path to lock file */
2424
Path lock_file_path;

test/core/storage/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ add_subdirectory(hamt)
77
add_subdirectory(keystore)
88
add_subdirectory(ipfs)
99
add_subdirectory(leveldb)
10+
add_subdirectory(repository)

test/core/storage/config/config_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ using fc::storage::config::ConfigError;
1414

1515
class ConfigImplTest : public test::BaseFS_Test {
1616
public:
17-
ConfigImplTest() : test::BaseFS_Test("/tmp/fc_config_test/") {}
17+
ConfigImplTest() : test::BaseFS_Test("fc_config_test") {}
1818

1919
/**
2020
* Create a test directory with an empty file.

test/core/storage/filestore/filesystem/filesystem_file_test.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ using fc::storage::filestore::Path;
1818

1919
class FileSystemFileTest : public test::BaseFS_Test {
2020
public:
21-
FileSystemFileTest() : test::BaseFS_Test("/tmp/fc_filesystem_file_test/") {}
21+
FileSystemFileTest() : test::BaseFS_Test("fc_filesystem_file_test") {}
2222

2323
/** Path to empty file */
2424
Path empty_file_path;

0 commit comments

Comments
 (0)