LevelDB.cpp 7.31 KB
Newer Older
kladkogex's avatar
kladkogex committed
1
/*
2
    Copyright (C) 2019-Present SKALE Labs
kladkogex's avatar
kladkogex committed
3

4
    This file is part of sgxwallet.
kladkogex's avatar
kladkogex committed
5

6
    sgxwallet is free software: you can redistribute it and/or modify
kladkogex's avatar
kladkogex committed
7 8 9 10
    it under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

11
    sgxwallet is distributed in the hope that it will be useful,
kladkogex's avatar
kladkogex committed
12 13 14 15 16
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
17
    along with sgxwallet.  If not, see <https://www.gnu.org/licenses/>.
kladkogex's avatar
kladkogex committed
18 19 20 21 22 23 24 25 26 27

    @file LevelDB.cpp
    @author Stan Kladko
    @date 2019
*/


#include <stdexcept>
#include <memory>
#include <string>
28
#include <iostream>
kladkogex's avatar
kladkogex committed
29 30 31 32


#include "leveldb/db.h"

kladkogex's avatar
kladkogex committed
33
#include "sgxwallet_common.h"
34
#include "SGXException.h"
kladkogex's avatar
kladkogex committed
35 36
#include "LevelDB.h"

37 38
#include "ServerInit.h"

39
#include "spdlog/spdlog.h"
40 41
#include "common.h"

42

kladkogex's avatar
kladkogex committed
43 44 45
using namespace leveldb;


46

kladkogex's avatar
kladkogex committed
47 48 49 50
static WriteOptions writeOptions;
static ReadOptions readOptions;


51

kladkogex's avatar
kladkogex committed
52

53
std::shared_ptr<string> LevelDB::readString(const string &_key) {
kladkogex's avatar
kladkogex committed
54

kladkogex's avatar
kladkogex committed
55 56
    std::lock_guard<std::recursive_mutex> lock(mutex);

57
    auto result = std::make_shared<string>();
kladkogex's avatar
kladkogex committed
58 59

    if (db == nullptr) {
60
        throw SGXException(NULL_DATABASE, "Null db");
kladkogex's avatar
kladkogex committed
61 62 63 64
    }

    auto status = db->Get(readOptions, _key, &*result);

65

66
      spdlog::debug("key to read from db: {}",_key );
67
      //std::cerr << "key to read from db: " << _key << std::endl;
68

69

kladkogex's avatar
kladkogex committed
70 71 72 73 74 75 76 77
    throwExceptionOnError(status);

    if (status.IsNotFound())
        return nullptr;

    return result;
}

78
void LevelDB::writeString(const string &_key, const string &_value) {
kladkogex's avatar
kladkogex committed
79

kladkogex's avatar
kladkogex committed
80 81
    std::lock_guard<std::recursive_mutex> lock(mutex);

kladkogex's avatar
kladkogex committed
82 83 84
    auto status = db->Put(writeOptions, Slice(_key), Slice(_value));

    throwExceptionOnError(status);
85

86

87
        spdlog::debug("written key: {}",_key );
88
       // std::cerr << "written key " << _key  << std::endl;
89

kladkogex's avatar
kladkogex committed
90 91
}

92

93
void LevelDB::deleteDHDKGKey (const string &_key) {
94 95 96

    std::lock_guard<std::recursive_mutex> lock(mutex);

97
    string full_key = "DKG_DH_KEY_" + _key;
98 99 100 101 102

    auto status = db->Delete(writeOptions, Slice(_key));

    throwExceptionOnError(status);

103
      spdlog::debug("key deleted: {}",full_key );
104
      //std::cerr << "key deleted " << full_key << std::endl;
105

106 107
}

108
void LevelDB::deleteTempNEK(const string &_key){
109 110 111

    std::lock_guard<std::recursive_mutex> lock(mutex);

112
    string prefix = _key.substr(0,8);
113 114 115 116 117 118 119 120 121 122 123
    if (prefix != "tmp_NEK:") {
      return;
    }

    auto status = db->Delete(writeOptions, Slice(_key));

    throwExceptionOnError(status);

    std::cerr << "key deleted " << _key << std::endl;
}

124
void LevelDB::deleteKey(const string &_key){
125 126 127 128 129 130 131

    std::lock_guard<std::recursive_mutex> lock(mutex);

    auto status = db->Delete(writeOptions, Slice(_key));

    throwExceptionOnError(status);

132
      spdlog::debug("key deleted: {}",_key );
133
      // std::cerr << "key deleted " << _key << std::endl;
134

135 136
}

137

138

kladkogex's avatar
kladkogex committed
139 140 141
void LevelDB::writeByteArray(const char *_key, size_t _keyLen, const char *value,
                             size_t _valueLen) {

kladkogex's avatar
kladkogex committed
142 143
    std::lock_guard<std::recursive_mutex> lock(mutex);

kladkogex's avatar
kladkogex committed
144 145 146 147 148 149
    auto status = db->Put(writeOptions, Slice(_key, _keyLen), Slice(value, _valueLen));

    throwExceptionOnError(status);
}


150
void LevelDB::writeByteArray(string &_key, const char *value,
kladkogex's avatar
kladkogex committed
151 152
                             size_t _valueLen) {

kladkogex's avatar
kladkogex committed
153 154
    std::lock_guard<std::recursive_mutex> lock(mutex);

kladkogex's avatar
kladkogex committed
155 156 157 158 159 160
    auto status = db->Put(writeOptions, Slice(_key), Slice(value, _valueLen));

    throwExceptionOnError(status);
}

void LevelDB::throwExceptionOnError(Status _status) {
161

kladkogex's avatar
kladkogex committed
162 163
    if (_status.IsNotFound())
        return;
kladkogex's avatar
kladkogex committed
164

kladkogex's avatar
kladkogex committed
165
    if (!_status.ok()) {
166
        throw SGXException(COULD_NOT_ACCESS_DATABASE, ("Could not access database database:" + _status.ToString()).c_str());
kladkogex's avatar
kladkogex committed
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
    }

}

uint64_t LevelDB::visitKeys(LevelDB::KeyVisitor *_visitor, uint64_t _maxKeysToVisit) {

    uint64_t readCounter = 0;

    leveldb::Iterator *it = db->NewIterator(readOptions);
    for (it->SeekToFirst(); it->Valid(); it->Next()) {
        _visitor->visitDBKey(it->key().data());
        readCounter++;
        if (readCounter >= _maxKeysToVisit) {
            break;
        }
    }

    delete it;

    return readCounter;
}

189
std::vector<string> LevelDB::writeKeysToVector1(uint64_t _maxKeysToVisit){
190
  uint64_t readCounter = 0;
191
  std::vector<string> keys;
192 193 194

  leveldb::Iterator *it = db->NewIterator(readOptions);
  for (it->SeekToFirst(); it->Valid(); it->Next()) {
195
    string cur_key(it->key().data(), it->key().size());
196 197 198 199 200 201 202 203 204 205 206 207 208
    keys.push_back(cur_key);
   // keys.push_back(it->key().data());
    readCounter++;
    if (readCounter >= _maxKeysToVisit) {
      break;
    }
  }

  delete it;

  return keys;
}

209
void LevelDB::writeDataUnique(const string & Name, const string &value) {
210 211 212 213

  auto key = Name;

  if (readString(Name) != nullptr) {
214
    spdlog::debug("name {}",Name, " already exists");
215
     // std::cerr << "name " << Name << " already exists" << std::endl;
216
    throw SGXException(KEY_SHARE_ALREADY_EXISTS, "Data with this name already exists");
217 218 219
  }

  writeString(key, value);
220

221
      spdlog::debug("{}",Name, " is written to db");
222

223 224 225
}


226
LevelDB::LevelDB(string &filename) {
kladkogex's avatar
kladkogex committed
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244


    leveldb::Options options;
    options.create_if_missing = true;

    if (!leveldb::DB::Open(options, filename, (leveldb::DB **) &db).ok()) {
        throw std::runtime_error("Unable to open levelDB database");
    }

    if (db == nullptr) {
        throw std::runtime_error("Null levelDB object");
    }

}

LevelDB::~LevelDB() {
}

245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263
const std::shared_ptr<LevelDB> &LevelDB::getLevelDb() {
    CHECK_STATE(levelDb)
    return levelDb;
}

const std::shared_ptr<LevelDB> &LevelDB::getCsrDb() {
    CHECK_STATE(csrDb)
    return csrDb;
}

const std::shared_ptr<LevelDB> &LevelDB::getCsrStatusDb() {
    CHECK_STATE(csrStatusDb)
    return csrStatusDb;
}


std::shared_ptr<LevelDB> LevelDB::levelDb = nullptr;

std::shared_ptr<LevelDB> LevelDB::csrDb = nullptr;
kladkogex's avatar
kladkogex committed
264

265
std::shared_ptr<LevelDB> LevelDB::csrStatusDb = nullptr;
kladkogex's avatar
kladkogex committed
266

kladko's avatar
kladko committed
267
string LevelDB::sgx_data_folder;
268 269 270

bool LevelDB::isInited = false;

kladko's avatar
kladko committed
271
void LevelDB::initDataFolderAndDBs() {
272

273 274 275 276 277
    CHECK_STATE(!isInited)
    isInited = true;

    spdlog::info("Initing wallet database ... ");

278

kladko's avatar
kladko committed
279
    char cwd[PATH_MAX];
280 281


kladko's avatar
kladko committed
282
    if (getcwd(cwd, sizeof(cwd)) == NULL) {
283
        spdlog::error("could not get current workin directory");
kladko's avatar
kladko committed
284 285 286 287 288 289 290
        exit(-1);
    }

    sgx_data_folder = string(cwd) + "/" + SGXDATA_FOLDER;

    struct stat info;
    if (stat(sgx_data_folder.c_str(), &info) !=0 ){
291 292 293 294
        spdlog::info("sgx_data folder does not exist. Creating ...");

        if (system(("mkdir " + sgx_data_folder).c_str()) == 0){
            spdlog::info("Successfully created sgx_data folder");
kladko's avatar
kladko committed
295 296
        }
        else{
297
            spdlog::error("Couldnt create creating sgx_data folder");
kladko's avatar
kladko committed
298 299 300 301
            exit(-1);
        }
    }

302 303 304

    spdlog::info("Opening wallet databases");

kladko's avatar
kladko committed
305
    auto dbName = sgx_data_folder +  WALLETDB_NAME;
306 307
    levelDb = make_shared<LevelDB>(dbName);

kladko's avatar
kladko committed
308
    auto csr_dbname = sgx_data_folder + "CSR_DB";
309 310
    csrDb = make_shared<LevelDB>(csr_dbname);

kladko's avatar
kladko committed
311
    auto csr_status_dbname = sgx_data_folder + "CSR_STATUS_DB";
312 313
    csrStatusDb = make_shared<LevelDB>(csr_status_dbname);

314 315
    spdlog::info("Successfully opened databases");

316
}
kladko's avatar
kladko committed
317 318 319 320

const string &LevelDB::getSgxDataFolder() {
    return sgx_data_folder;
}