27 std::string dump_filename =
args.GetArg(
"-dumpfile",
"");
28 if (dump_filename.empty()) {
29 error =
_(
"No dump file provided. To use dump, -dumpfile=<filename> must be provided.");
33 fs::path path = fs::PathFromString(dump_filename);
34 path = fs::absolute(path);
35 if (fs::exists(path)) {
36 error =
strprintf(
_(
"File %s already exists. If you are sure this is what you want, move it out of the way first."), fs::PathToString(path));
39 std::ofstream dump_file;
40 dump_file.open(path.std_path());
41 if (dump_file.fail()) {
42 error =
strprintf(
_(
"Unable to open %s for writing"), fs::PathToString(path));
48 std::unique_ptr<DatabaseBatch> batch = db.
MakeBatch();
51 std::unique_ptr<DatabaseCursor> cursor = batch->GetNewCursor();
53 error =
_(
"Error: Couldn't create cursor into database");
59 dump_file.write(line.data(), line.size());
60 hasher << std::span{line};
63 std::string format = db.
Format();
66 if (format ==
"bdb_ro") {
69 line =
strprintf(
"%s,%s\n",
"format", format);
70 dump_file.write(line.data(), line.size());
71 hasher << std::span{line};
84 error =
_(
"Error reading next record from wallet database");
88 std::string key_str =
HexStr(ss_key);
89 std::string value_str =
HexStr(ss_value);
90 line =
strprintf(
"%s,%s\n", key_str, value_str);
91 dump_file.write(line.data(), line.size());
92 hasher << std::span{line};
125 tfm::format(std::cerr,
"Wallet name cannot be empty\n");
130 std::string dump_filename =
args.GetArg(
"-dumpfile",
"");
131 if (dump_filename.empty()) {
132 error =
_(
"No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided.");
136 fs::path dump_path = fs::PathFromString(dump_filename);
137 dump_path = fs::absolute(dump_path);
138 if (!fs::exists(dump_path)) {
139 error =
strprintf(
_(
"Dump file %s does not exist."), fs::PathToString(dump_path));
142 std::ifstream dump_file{dump_path.std_path()};
149 std::string magic_key;
150 std::getline(dump_file, magic_key,
',');
151 std::string version_value;
152 std::getline(dump_file, version_value,
'\n');
154 error =
strprintf(
_(
"Error: Dumpfile identifier record is incorrect. Got \"%s\", expected \"%s\"."), magic_key,
DUMP_MAGIC);
161 error =
strprintf(
_(
"Error: Unable to parse version %u as a uint32_t"), version_value);
166 error =
strprintf(
_(
"Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version %s"), version_value);
170 std::string magic_hasher_line =
strprintf(
"%s,%s\n", magic_key, version_value);
171 hasher << std::span{magic_hasher_line};
174 std::string format_key;
175 std::getline(dump_file, format_key,
',');
176 std::string format_value;
177 std::getline(dump_file, format_value,
'\n');
178 if (format_key !=
"format") {
179 error =
strprintf(
_(
"Error: Dumpfile format record is incorrect. Got \"%s\", expected \"format\"."), format_key);
187 if (format_value !=
"sqlite") {
188 error =
strprintf(
_(
"Error: Dumpfile specifies an unsupported database format (%s). Only sqlite database dumps are supported"), format_value);
191 std::string format_hasher_line =
strprintf(
"%s,%s\n", format_key, format_value);
192 hasher << std::span{format_hasher_line};
199 std::unique_ptr<WalletDatabase> database =
MakeDatabase(wallet_path, options, status, error);
200 if (!database)
return false;
208 std::unique_ptr<DatabaseBatch> batch = db.
MakeBatch();
212 while (dump_file.good()) {
214 std::getline(dump_file, key,
',');
216 std::getline(dump_file, value,
'\n');
218 if (key ==
"checksum") {
219 std::vector<unsigned char> parsed_checksum =
ParseHex(value);
220 if (parsed_checksum.size() != checksum.
size()) {
221 error =
Untranslated(
"Error: Checksum is not the correct size");
225 std::copy(parsed_checksum.begin(), parsed_checksum.end(), checksum.
begin());
229 std::string line =
strprintf(
"%s,%s\n", key, value);
230 hasher << std::span{line};
232 if (key.empty() || value.empty()) {
237 error =
strprintf(
_(
"Error: Got key that was not hex: %s"), key);
242 error =
strprintf(
_(
"Error: Got value that was not hex: %s"), value);
247 std::vector<unsigned char>
k =
ParseHex(key);
248 std::vector<unsigned char> v =
ParseHex(value);
249 if (!batch->Write(std::span{k}, std::span{v})) {
250 error =
strprintf(
_(
"Error: Unable to write record to new wallet"));
259 error =
_(
"Error: Missing checksum");
261 }
else if (checksum != comp_checksum) {
262 error =
strprintf(
_(
"Error: Dumpfile checksum does not match. Computed %s, expected %s"),
HexStr(comp_checksum),
HexStr(checksum));
278 std::vector<fs::path> paths_to_remove =
wallet->GetDatabase().Files();
279 if (!
name.empty()) paths_to_remove.push_back(wallet_path);
285 for (
const auto& p : paths_to_remove) {