-
Notifications
You must be signed in to change notification settings - Fork 38.7k
Closed
Description
src/bitcoind -daemon -regtest
src/bitcoin-cli -regtest stop
cp ~/.bitcoin/wallet/wallet.dat ~/.bitcoin/wallet/wallet2.dat
src/bitcoind -daemon -regtest
src/bitcoin-cli -regtest loadwallet wallet2.dat # The first time it would fail to load wallet
src/bitcoin-cli -regtest loadwallet wallet2.dat # The second time it would succeed to load wallet, but this would cause error because of duplicate fileid
It would flush wallet.dat and close Db* in mapDb['wallet.dat'].second, so mapDb['wallet.dat'].second would be nullptr. Then there is no available Db* to detect if the wallet fileid is duplicated.
I'm not sure if the issue is related to #14163, but I found this while debugging it.
Lines 32 to 53 in 920c090
| void CheckUniqueFileid(const BerkeleyEnvironment& env, const std::string& filename, Db& db) | |
| { | |
| if (env.IsMock()) return; | |
| u_int8_t fileid[DB_FILE_ID_LEN]; | |
| int ret = db.get_mpf()->get_fileid(fileid); | |
| if (ret != 0) { | |
| throw std::runtime_error(strprintf("BerkeleyBatch: Can't open database %s (get_fileid failed with %d)", filename, ret)); | |
| } | |
| for (const auto& item : env.mapDb) { | |
| u_int8_t item_fileid[DB_FILE_ID_LEN]; | |
| if (item.second && item.second->get_mpf()->get_fileid(item_fileid) == 0 && | |
| memcmp(fileid, item_fileid, sizeof(fileid)) == 0) { | |
| const char* item_filename = nullptr; | |
| item.second->get_dbname(&item_filename, nullptr); | |
| throw std::runtime_error(strprintf("BerkeleyBatch: Can't open database %s (duplicates fileid %s from %s)", filename, | |
| HexStr(std::begin(item_fileid), std::end(item_fileid)), | |
| item_filename ? item_filename : "(unknown database)")); | |
| } | |
| } | |
| } |