Make sure database has a unique fileid within the environment. If it doesn't, throw an error. BDB caches do not work properly when more than one open database has the same fileid (values written to one database may show up in reads to other databases). BerkeleyDB generates unique fileids by default (https://docs.oracle.com/cd/E17275_01/html/programmer_reference/program_copy.html), so bitcoin shou
| 29 | //! so bitcoin should never create different databases with the same fileid, but |
| 30 | //! this error can be triggered if users manually copy database files. |
| 31 | void CheckUniqueFileid(const BerkeleyEnvironment& env, const std::string& filename, Db& db, WalletDatabaseFileId& fileid) |
| 32 | { |
| 33 | if (env.IsMock()) return; |
| 34 | |
| 35 | int ret = db.get_mpf()->get_fileid(fileid.value); |
| 36 | if (ret != 0) { |
| 37 | throw std::runtime_error(strprintf("BerkeleyDatabase: Can't open database %s (get_fileid failed with %d)", filename, ret)); |
| 38 | } |
| 39 | |
| 40 | for (const auto& item : env.m_fileids) { |
| 41 | if (fileid == item.second && &fileid != &item.second) { |
| 42 | throw std::runtime_error(strprintf("BerkeleyDatabase: Can't open database %s (duplicates fileid %s from %s)", filename, |
| 43 | HexStr(item.second.value), item.first)); |
| 44 | } |
| 45 | } |
| 46 | } |
| 47 | |
| 48 | RecursiveMutex cs_db; |
| 49 | std::map<std::string, std::weak_ptr<BerkeleyEnvironment>> g_dbenvs GUARDED_BY(cs_db); //!< Map from directory name to db environment. |