X Tutup
Skip to content

Commit 5aaeb6c

Browse files
committed
MOVEONLY: Move IsBDBFile, IsSQLiteFile, and ListWalletDir
This commit does not change to any code and behavior. It it is easily reviewed with the --color-moved=dimmed_zebra git diff option. Motivation for this change is to: - Consolidate redundant functions IsBDBFile /ExistsBerkeleyDatabase / SplitWalletPath, and IsSQLiteFile / ExistsSQLiteDatabase in the next commits - Detect SQLite wallets consistently regardless whether bitcoin is built with SQLite support in the next commits - Avoid attempting to open SQLite databases with the BDB library when bitcoin is built without SQLite support in the next commits
1 parent 751ffaa commit 5aaeb6c

File tree

7 files changed

+121
-118
lines changed

7 files changed

+121
-118
lines changed

src/wallet/bdb.cpp

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -839,28 +839,3 @@ std::unique_ptr<BerkeleyDatabase> MakeBerkeleyDatabase(const fs::path& path, con
839839
status = DatabaseStatus::SUCCESS;
840840
return db;
841841
}
842-
843-
bool IsBDBFile(const fs::path& path)
844-
{
845-
if (!fs::exists(path)) return false;
846-
847-
// A Berkeley DB Btree file has at least 4K.
848-
// This check also prevents opening lock files.
849-
boost::system::error_code ec;
850-
auto size = fs::file_size(path, ec);
851-
if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), path.string());
852-
if (size < 4096) return false;
853-
854-
fsbridge::ifstream file(path, std::ios::binary);
855-
if (!file.is_open()) return false;
856-
857-
file.seekg(12, std::ios::beg); // Magic bytes start at offset 12
858-
uint32_t data = 0;
859-
file.read((char*) &data, sizeof(data)); // Read 4 bytes of file to compare against magic
860-
861-
// Berkeley DB Btree magic bytes, from:
862-
// https://github.com/file/file/blob/5824af38469ec1ca9ac3ffd251e7afe9dc11e227/magic/Magdir/database#L74-L75
863-
// - big endian systems - 00 05 31 62
864-
// - little endian systems - 62 31 05 00
865-
return data == 0x00053162 || data == 0x62310500;
866-
}

src/wallet/bdb.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,6 @@ class BerkeleyEnvironment
8686
/** Get BerkeleyEnvironment and database filename given a wallet path. */
8787
std::shared_ptr<BerkeleyEnvironment> GetWalletEnv(const fs::path& wallet_path, std::string& database_filename);
8888

89-
/** Check format of database file */
90-
bool IsBDBFile(const fs::path& path);
91-
9289
class BerkeleyBatch;
9390

9491
/** An instance of this class represents one database.

src/wallet/db.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,70 @@
33
// Distributed under the MIT software license, see the accompanying
44
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

6+
#include <chainparams.h>
67
#include <fs.h>
8+
#include <logging.h>
79
#include <wallet/db.h>
810

911
#include <string>
1012

13+
fs::path GetWalletDir();
14+
15+
#ifdef USE_BDB
16+
bool ExistsBerkeleyDatabase(const fs::path& path);
17+
#else
18+
# define ExistsBerkeleyDatabase(path) (false)
19+
#endif
20+
#ifdef USE_SQLITE
21+
bool ExistsSQLiteDatabase(const fs::path& path);
22+
#else
23+
# define ExistsSQLiteDatabase(path) (false)
24+
#endif
25+
26+
std::vector<fs::path> ListWalletDir()
27+
{
28+
const fs::path wallet_dir = GetWalletDir();
29+
const size_t offset = wallet_dir.string().size() + 1;
30+
std::vector<fs::path> paths;
31+
boost::system::error_code ec;
32+
33+
for (auto it = fs::recursive_directory_iterator(wallet_dir, ec); it != fs::recursive_directory_iterator(); it.increment(ec)) {
34+
if (ec) {
35+
LogPrintf("%s: %s %s\n", __func__, ec.message(), it->path().string());
36+
continue;
37+
}
38+
39+
try {
40+
// Get wallet path relative to walletdir by removing walletdir from the wallet path.
41+
// This can be replaced by boost::filesystem::lexically_relative once boost is bumped to 1.60.
42+
const fs::path path = it->path().string().substr(offset);
43+
44+
if (it->status().type() == fs::directory_file &&
45+
(ExistsBerkeleyDatabase(it->path()) || ExistsSQLiteDatabase(it->path()))) {
46+
// Found a directory which contains wallet.dat btree file, add it as a wallet.
47+
paths.emplace_back(path);
48+
} else if (it.level() == 0 && it->symlink_status().type() == fs::regular_file && ExistsBerkeleyDatabase(it->path())) {
49+
if (it->path().filename() == "wallet.dat") {
50+
// Found top-level wallet.dat btree file, add top level directory ""
51+
// as a wallet.
52+
paths.emplace_back();
53+
} else {
54+
// Found top-level btree file not called wallet.dat. Current bitcoin
55+
// software will never create these files but will allow them to be
56+
// opened in a shared database environment for backwards compatibility.
57+
// Add it to the list of available wallets.
58+
paths.emplace_back(path);
59+
}
60+
}
61+
} catch (const std::exception& e) {
62+
LogPrintf("%s: Error scanning %s: %s\n", __func__, it->path().string(), e.what());
63+
it.no_push();
64+
}
65+
}
66+
67+
return paths;
68+
}
69+
1170
void SplitWalletPath(const fs::path& wallet_path, fs::path& env_directory, std::string& database_filename)
1271
{
1372
if (fs::is_regular_file(wallet_path)) {
@@ -23,3 +82,62 @@ void SplitWalletPath(const fs::path& wallet_path, fs::path& env_directory, std::
2382
database_filename = "wallet.dat";
2483
}
2584
}
85+
86+
bool IsBDBFile(const fs::path& path)
87+
{
88+
if (!fs::exists(path)) return false;
89+
90+
// A Berkeley DB Btree file has at least 4K.
91+
// This check also prevents opening lock files.
92+
boost::system::error_code ec;
93+
auto size = fs::file_size(path, ec);
94+
if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), path.string());
95+
if (size < 4096) return false;
96+
97+
fsbridge::ifstream file(path, std::ios::binary);
98+
if (!file.is_open()) return false;
99+
100+
file.seekg(12, std::ios::beg); // Magic bytes start at offset 12
101+
uint32_t data = 0;
102+
file.read((char*) &data, sizeof(data)); // Read 4 bytes of file to compare against magic
103+
104+
// Berkeley DB Btree magic bytes, from:
105+
// https://github.com/file/file/blob/5824af38469ec1ca9ac3ffd251e7afe9dc11e227/magic/Magdir/database#L74-L75
106+
// - big endian systems - 00 05 31 62
107+
// - little endian systems - 62 31 05 00
108+
return data == 0x00053162 || data == 0x62310500;
109+
}
110+
111+
bool IsSQLiteFile(const fs::path& path)
112+
{
113+
if (!fs::exists(path)) return false;
114+
115+
// A SQLite Database file is at least 512 bytes.
116+
boost::system::error_code ec;
117+
auto size = fs::file_size(path, ec);
118+
if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), path.string());
119+
if (size < 512) return false;
120+
121+
fsbridge::ifstream file(path, std::ios::binary);
122+
if (!file.is_open()) return false;
123+
124+
// Magic is at beginning and is 16 bytes long
125+
char magic[16];
126+
file.read(magic, 16);
127+
128+
// Application id is at offset 68 and 4 bytes long
129+
file.seekg(68, std::ios::beg);
130+
char app_id[4];
131+
file.read(app_id, 4);
132+
133+
file.close();
134+
135+
// Check the magic, see https://sqlite.org/fileformat2.html
136+
std::string magic_str(magic, 16);
137+
if (magic_str != std::string("SQLite format 3", 16)) {
138+
return false;
139+
}
140+
141+
// Check the application id matches our network magic
142+
return memcmp(Params().MessageStart(), app_id, 4) == 0;
143+
}

src/wallet/db.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,4 +225,7 @@ enum class DatabaseStatus {
225225

226226
std::unique_ptr<WalletDatabase> MakeDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
227227

228+
bool IsBDBFile(const fs::path& path);
229+
bool IsSQLiteFile(const fs::path& path);
230+
228231
#endif // BITCOIN_WALLET_DB_H

src/wallet/sqlite.cpp

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -596,37 +596,3 @@ std::string SQLiteDatabaseVersion()
596596
{
597597
return std::string(sqlite3_libversion());
598598
}
599-
600-
bool IsSQLiteFile(const fs::path& path)
601-
{
602-
if (!fs::exists(path)) return false;
603-
604-
// A SQLite Database file is at least 512 bytes.
605-
boost::system::error_code ec;
606-
auto size = fs::file_size(path, ec);
607-
if (ec) LogPrintf("%s: %s %s\n", __func__, ec.message(), path.string());
608-
if (size < 512) return false;
609-
610-
fsbridge::ifstream file(path, std::ios::binary);
611-
if (!file.is_open()) return false;
612-
613-
// Magic is at beginning and is 16 bytes long
614-
char magic[16];
615-
file.read(magic, 16);
616-
617-
// Application id is at offset 68 and 4 bytes long
618-
file.seekg(68, std::ios::beg);
619-
char app_id[4];
620-
file.read(app_id, 4);
621-
622-
file.close();
623-
624-
// Check the magic, see https://sqlite.org/fileformat2.html
625-
std::string magic_str(magic, 16);
626-
if (magic_str != std::string("SQLite format 3", 16)) {
627-
return false;
628-
}
629-
630-
// Check the application id matches our network magic
631-
return memcmp(Params().MessageStart(), app_id, 4) == 0;
632-
}

src/wallet/sqlite.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,5 @@ bool ExistsSQLiteDatabase(const fs::path& path);
117117
std::unique_ptr<SQLiteDatabase> MakeSQLiteDatabase(const fs::path& path, const DatabaseOptions& options, DatabaseStatus& status, bilingual_str& error);
118118

119119
std::string SQLiteDatabaseVersion();
120-
bool IsSQLiteFile(const fs::path& path);
121120

122121
#endif // BITCOIN_WALLET_SQLITE_H

src/wallet/walletutil.cpp

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,6 @@
77
#include <logging.h>
88
#include <util/system.h>
99

10-
#ifdef USE_BDB
11-
bool ExistsBerkeleyDatabase(const fs::path& path);
12-
#else
13-
# define ExistsBerkeleyDatabase(path) (false)
14-
#endif
15-
#ifdef USE_SQLITE
16-
bool ExistsSQLiteDatabase(const fs::path& path);
17-
#else
18-
# define ExistsSQLiteDatabase(path) (false)
19-
#endif
20-
2110
fs::path GetWalletDir()
2211
{
2312
fs::path path;
@@ -40,50 +29,6 @@ fs::path GetWalletDir()
4029
return path;
4130
}
4231

43-
std::vector<fs::path> ListWalletDir()
44-
{
45-
const fs::path wallet_dir = GetWalletDir();
46-
const size_t offset = wallet_dir.string().size() + 1;
47-
std::vector<fs::path> paths;
48-
boost::system::error_code ec;
49-
50-
for (auto it = fs::recursive_directory_iterator(wallet_dir, ec); it != fs::recursive_directory_iterator(); it.increment(ec)) {
51-
if (ec) {
52-
LogPrintf("%s: %s %s\n", __func__, ec.message(), it->path().string());
53-
continue;
54-
}
55-
56-
try {
57-
// Get wallet path relative to walletdir by removing walletdir from the wallet path.
58-
// This can be replaced by boost::filesystem::lexically_relative once boost is bumped to 1.60.
59-
const fs::path path = it->path().string().substr(offset);
60-
61-
if (it->status().type() == fs::directory_file &&
62-
(ExistsBerkeleyDatabase(it->path()) || ExistsSQLiteDatabase(it->path()))) {
63-
// Found a directory which contains wallet.dat btree file, add it as a wallet.
64-
paths.emplace_back(path);
65-
} else if (it.level() == 0 && it->symlink_status().type() == fs::regular_file && ExistsBerkeleyDatabase(it->path())) {
66-
if (it->path().filename() == "wallet.dat") {
67-
// Found top-level wallet.dat btree file, add top level directory ""
68-
// as a wallet.
69-
paths.emplace_back();
70-
} else {
71-
// Found top-level btree file not called wallet.dat. Current bitcoin
72-
// software will never create these files but will allow them to be
73-
// opened in a shared database environment for backwards compatibility.
74-
// Add it to the list of available wallets.
75-
paths.emplace_back(path);
76-
}
77-
}
78-
} catch (const std::exception& e) {
79-
LogPrintf("%s: Error scanning %s: %s\n", __func__, it->path().string(), e.what());
80-
it.no_push();
81-
}
82-
}
83-
84-
return paths;
85-
}
86-
8732
bool IsFeatureSupported(int wallet_version, int feature_version)
8833
{
8934
return wallet_version >= feature_version;

0 commit comments

Comments
 (0)
X Tutup