| 126 | } |
| 127 | |
| 128 | bool BerkeleyEnvironment::Open(bilingual_str& err) |
| 129 | { |
| 130 | if (fDbEnvInit) { |
| 131 | return true; |
| 132 | } |
| 133 | |
| 134 | fs::path pathIn = fs::PathFromString(strPath); |
| 135 | TryCreateDirectories(pathIn); |
| 136 | if (!LockDirectory(pathIn, ".walletlock")) { |
| 137 | LogPrintf("Cannot obtain a lock on wallet directory %s. Another instance may be using it.\n", strPath); |
| 138 | err = strprintf(_("Error initializing wallet database environment %s!"), fs::quoted(fs::PathToString(Directory()))); |
| 139 | return false; |
| 140 | } |
| 141 | |
| 142 | fs::path pathLogDir = pathIn / "database"; |
| 143 | TryCreateDirectories(pathLogDir); |
| 144 | fs::path pathErrorFile = pathIn / "db.log"; |
| 145 | LogPrintf("BerkeleyEnvironment::Open: LogDir=%s ErrorFile=%s\n", fs::PathToString(pathLogDir), fs::PathToString(pathErrorFile)); |
| 146 | |
| 147 | unsigned int nEnvFlags = 0; |
| 148 | if (gArgs.GetBoolArg("-privdb", DEFAULT_WALLET_PRIVDB)) |
| 149 | nEnvFlags |= DB_PRIVATE; |
| 150 | |
| 151 | dbenv->set_lg_dir(fs::PathToString(pathLogDir).c_str()); |
| 152 | dbenv->set_cachesize(0, 0x100000, 1); // 1 MiB should be enough for just the wallet |
| 153 | dbenv->set_lg_bsize(0x10000); |
| 154 | dbenv->set_lg_max(1048576); |
| 155 | dbenv->set_lk_max_locks(40000); |
| 156 | dbenv->set_lk_max_objects(40000); |
| 157 | dbenv->set_errfile(fsbridge::fopen(pathErrorFile, "a")); /// debug |
| 158 | dbenv->set_flags(DB_AUTO_COMMIT, 1); |
| 159 | dbenv->set_flags(DB_TXN_WRITE_NOSYNC, 1); |
| 160 | dbenv->log_set_config(DB_LOG_AUTO_REMOVE, 1); |
| 161 | int ret = dbenv->open(strPath.c_str(), |
| 162 | DB_CREATE | |
| 163 | DB_INIT_LOCK | |
| 164 | DB_INIT_LOG | |
| 165 | DB_INIT_MPOOL | |
| 166 | DB_INIT_TXN | |
| 167 | DB_THREAD | |
| 168 | DB_RECOVER | |
| 169 | nEnvFlags, |
| 170 | S_IRUSR | S_IWUSR); |
| 171 | if (ret != 0) { |
| 172 | LogPrintf("BerkeleyEnvironment::Open: Error %d opening database environment: %s\n", ret, DbEnv::strerror(ret)); |
| 173 | int ret2 = dbenv->close(0); |
| 174 | if (ret2 != 0) { |
| 175 | LogPrintf("BerkeleyEnvironment::Open: Error %d closing failed database environment: %s\n", ret2, DbEnv::strerror(ret2)); |
| 176 | } |
| 177 | Reset(); |
| 178 | err = strprintf(_("Error initializing wallet database environment %s!"), fs::quoted(fs::PathToString(Directory()))); |
| 179 | if (ret == DB_RUNRECOVERY) { |
| 180 | err += Untranslated(" ") + _("This error could occur if this wallet was not shutdown cleanly and was last loaded using a build with a newer version of Berkeley DB. If so, please use the software that last loaded this wallet"); |
| 181 | } |
| 182 | return false; |
| 183 | } |
| 184 | |
| 185 | fDbEnvInit = true; |