@@ -4073,15 +4073,14 @@ std::optional<MigrationData> CWallet::GetDescriptorsForLegacy(bilingual_str& err
4073
4073
return res;
4074
4074
}
4075
4075
4076
- bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error )
4076
+ util::Result<void> CWallet::ApplyMigrationData(MigrationData& data)
4077
4077
{
4078
4078
AssertLockHeld(cs_wallet);
4079
4079
4080
4080
LegacyDataSPKM* legacy_spkm = GetLegacyDataSPKM();
4081
4081
if (!Assume(legacy_spkm)) {
4082
4082
// This shouldn't happen
4083
- error = Untranslated(STR_INTERNAL_BUG("Error: Legacy wallet data missing"));
4084
- return false;
4083
+ return util::Error{Untranslated(STR_INTERNAL_BUG("Error: Legacy wallet data missing"))};
4085
4084
}
4086
4085
4087
4086
// Get all invalid or non-watched scripts that will not be migrated
@@ -4095,16 +4094,15 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4095
4094
4096
4095
for (auto& desc_spkm : data.desc_spkms) {
4097
4096
if (m_spk_managers.count(desc_spkm->GetID()) > 0) {
4098
- error = _("Error: Duplicate descriptors created during migration. Your wallet may be corrupted.");
4099
- return false;
4097
+ return util::Error{_("Error: Duplicate descriptors created during migration. Your wallet may be corrupted.")};
4100
4098
}
4101
4099
uint256 id = desc_spkm->GetID();
4102
4100
AddScriptPubKeyMan(id, std::move(desc_spkm));
4103
4101
}
4104
4102
4105
4103
// Remove the LegacyScriptPubKeyMan from disk
4106
4104
if (!legacy_spkm->DeleteRecords()) {
4107
- return false ;
4105
+ return util::Error{_("Error: cannot remove legacy wallet records")} ;
4108
4106
}
4109
4107
4110
4108
// Remove the LegacyScriptPubKeyMan from memory
@@ -4127,8 +4125,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4127
4125
// Get best block locator so that we can copy it to the watchonly and solvables
4128
4126
CBlockLocator best_block_locator;
4129
4127
if (!WalletBatch(GetDatabase()).ReadBestBlock(best_block_locator)) {
4130
- error = _("Error: Unable to read wallet's best block locator record");
4131
- return false;
4128
+ return util::Error{_("Error: Unable to read wallet's best block locator record")};
4132
4129
}
4133
4130
4134
4131
// Check if the transactions in the wallet are still ours. Either they belong here, or they belong in the watchonly wallet.
@@ -4143,15 +4140,13 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4143
4140
watchonly_batch->WriteOrderPosNext(data.watchonly_wallet->nOrderPosNext);
4144
4141
// Write the best block locator to avoid rescanning on reload
4145
4142
if (!watchonly_batch->WriteBestBlock(best_block_locator)) {
4146
- error = _("Error: Unable to write watchonly wallet best block locator record");
4147
- return false;
4143
+ return util::Error{_("Error: Unable to write watchonly wallet best block locator record")};
4148
4144
}
4149
4145
}
4150
4146
if (data.solvable_wallet) {
4151
4147
// Write the best block locator to avoid rescanning on reload
4152
4148
if (!WalletBatch(data.solvable_wallet->GetDatabase()).WriteBestBlock(best_block_locator)) {
4153
- error = _("Error: Unable to write solvable wallet best block locator record");
4154
- return false;
4149
+ return util::Error{_("Error: Unable to write solvable wallet best block locator record")};
4155
4150
}
4156
4151
}
4157
4152
for (const auto& [_pos, wtx] : wtxOrdered) {
@@ -4170,8 +4165,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4170
4165
ins_wtx.CopyFrom(to_copy_wtx);
4171
4166
return true;
4172
4167
})) {
4173
- error = strprintf(_("Error: Could not add watchonly tx %s to watchonly wallet"), wtx->GetHash().GetHex());
4174
- return false;
4168
+ return util::Error{strprintf(_("Error: Could not add watchonly tx %s to watchonly wallet"), wtx->GetHash().GetHex())};
4175
4169
}
4176
4170
watchonly_batch->WriteTx(data.watchonly_wallet->mapWallet.at(hash));
4177
4171
// Mark as to remove from the migrated wallet only if it does not also belong to it
@@ -4183,16 +4177,14 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4183
4177
}
4184
4178
if (!is_mine) {
4185
4179
// Both not ours and not in the watchonly wallet
4186
- error = strprintf(_("Error: Transaction %s in wallet cannot be identified to belong to migrated wallets"), wtx->GetHash().GetHex());
4187
- return false;
4180
+ return util::Error{strprintf(_("Error: Transaction %s in wallet cannot be identified to belong to migrated wallets"), wtx->GetHash().GetHex())};
4188
4181
}
4189
4182
}
4190
4183
watchonly_batch.reset(); // Flush
4191
4184
// Do the removes
4192
4185
if (txids_to_delete.size() > 0) {
4193
4186
if (auto res = RemoveTxs(txids_to_delete); !res) {
4194
- error = _("Error: Could not delete watchonly transactions. ") + util::ErrorString(res);
4195
- return false;
4187
+ return util::Error{_("Error: Could not delete watchonly transactions. ") + util::ErrorString(res)};
4196
4188
}
4197
4189
}
4198
4190
@@ -4203,8 +4195,7 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4203
4195
4204
4196
std::unique_ptr<WalletBatch> batch = std::make_unique<WalletBatch>(ext_wallet->GetDatabase());
4205
4197
if (!batch->TxnBegin()) {
4206
- error = strprintf(_("Error: database transaction cannot be executed for wallet %s"), ext_wallet->GetName());
4207
- return false;
4198
+ return util::Error{strprintf(_("Error: database transaction cannot be executed for wallet %s"), ext_wallet->GetName())};
4208
4199
}
4209
4200
wallets_vec.emplace_back(ext_wallet, std::move(batch));
4210
4201
}
@@ -4254,16 +4245,14 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4254
4245
continue;
4255
4246
}
4256
4247
4257
- error = _("Error: Address book data in wallet cannot be identified to belong to migrated wallets");
4258
- return false;
4248
+ return util::Error{_("Error: Address book data in wallet cannot be identified to belong to migrated wallets")};
4259
4249
}
4260
4250
}
4261
4251
4262
4252
// Persist external wallets address book entries
4263
4253
for (auto& [wallet, batch] : wallets_vec) {
4264
4254
if (!batch->TxnCommit()) {
4265
- error = strprintf(_("Error: address book copy failed for wallet %s"), wallet->GetName());
4266
- return false;
4255
+ return util::Error{strprintf(_("Error: address book copy failed for wallet %s"), wallet->GetName())};
4267
4256
}
4268
4257
}
4269
4258
@@ -4273,16 +4262,15 @@ bool CWallet::ApplyMigrationData(MigrationData& data, bilingual_str& error)
4273
4262
if (dests_to_delete.size() > 0) {
4274
4263
for (const auto& dest : dests_to_delete) {
4275
4264
if (!DelAddressBookWithDB(local_wallet_batch, dest)) {
4276
- error = _("Error: Unable to remove watchonly address book data");
4277
- return false;
4265
+ return util::Error{_("Error: Unable to remove watchonly address book data")};
4278
4266
}
4279
4267
}
4280
4268
}
4281
4269
local_wallet_batch.TxnCommit();
4282
4270
4283
4271
WalletLogPrintf("Wallet migration complete.\n");
4284
4272
4285
- return true;
4273
+ return {}; // all good
4286
4274
}
4287
4275
4288
4276
bool CWallet::CanGrindR() const
@@ -4393,7 +4381,8 @@ bool DoMigration(CWallet& wallet, WalletContext& context, bilingual_str& error,
4393
4381
}
4394
4382
4395
4383
// Add the descriptors to wallet, remove LegacyScriptPubKeyMan, and cleanup txs and address book data
4396
- if (!wallet.ApplyMigrationData(*data, error)) {
4384
+ if (auto res_migration = wallet.ApplyMigrationData(*data); !res_migration) {
4385
+ error = util::ErrorString(res_migration);
4397
4386
return false;
4398
4387
}
4399
4388
return true;
0 commit comments