Electroneum
Loading...
Searching...
No Matches
ringdb.cpp
Go to the documentation of this file.
1// Copyright (c) 2018, The Monero Project
2//
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without modification, are
6// permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this list of
9// conditions and the following disclaimer.
10//
11// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12// of conditions and the following disclaimer in the documentation and/or other
13// materials provided with the distribution.
14//
15// 3. Neither the name of the copyright holder nor the names of its contributors may be
16// used to endorse or promote products derived from this software without specific
17// prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29#include <lmdb.h>
30#include <boost/algorithm/string.hpp>
31#include <boost/range/adaptor/transformed.hpp>
32#include <boost/filesystem.hpp>
33#include "common/util.h"
34#include "misc_log_ex.h"
35#include "misc_language.h"
36#include "wallet_errors.h"
37#include "ringdb.h"
38
39#undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
40#define ELECTRONEUM_DEFAULT_LOG_CATEGORY "wallet.ringdb"
41
42static const char zerokey[8] = {0};
43static const MDB_val zerokeyval = { sizeof(zerokey), (void *)zerokey };
44
45static int compare_hash32(const MDB_val *a, const MDB_val *b)
46{
47 for (int n = 7; n >= 0; n--)
48 {
49 uint32_t va, vb;
50 memcpy(&va, (const uint32_t*) a->mv_data + n, sizeof(va));
51 memcpy(&vb, (const uint32_t*) b->mv_data + n, sizeof(vb));
52 if (va == vb)
53 continue;
54 return va < vb ? -1 : 1;
55 }
56
57 return 0;
58}
59
60static int compare_uint64(const MDB_val *a, const MDB_val *b)
61{
62 uint64_t va, vb;
63 memcpy(&va, a->mv_data, sizeof(va));
64 memcpy(&vb, b->mv_data, sizeof(vb));
65 return va < vb ? -1 : va > vb;
66}
67
68static std::string compress_ring(const std::vector<uint64_t> &ring)
69{
70 std::string s;
71 for (uint64_t out: ring)
72 s += tools::get_varint_data(out);
73 return s;
74}
75
76static std::vector<uint64_t> decompress_ring(const std::string &s)
77{
78 std::vector<uint64_t> ring;
79 int read = 0;
80 for (std::string::const_iterator i = s.begin(); i != s.cend(); std::advance(i, read))
81 {
83 std::string tmp(i, s.cend());
84 read = tools::read_varint(tmp.begin(), tmp.end(), out);
85 THROW_WALLET_EXCEPTION_IF(read <= 0 || read > 256, tools::error::wallet_internal_error, "Internal error decompressing ring");
86 ring.push_back(out);
87 }
88 return ring;
89}
90
91std::string get_rings_filename(boost::filesystem::path filename)
92{
93 if (!boost::filesystem::is_directory(filename))
94 filename.remove_filename();
95 return filename.string();
96}
97
98static crypto::chacha_iv make_iv(const crypto::key_image &key_image, const crypto::chacha_key &key)
99{
100 static const char salt[] = "ringdsb";
101
102 uint8_t buffer[sizeof(key_image) + sizeof(key) + sizeof(salt)];
103 memcpy(buffer, &key_image, sizeof(key_image));
104 memcpy(buffer + sizeof(key_image), &key, sizeof(key));
105 memcpy(buffer + sizeof(key_image) + sizeof(key), salt, sizeof(salt));
107 crypto::cn_fast_hash(buffer, sizeof(buffer), hash.data);
108 static_assert(sizeof(hash) >= CHACHA_IV_SIZE, "Incompatible hash and chacha IV sizes");
109 crypto::chacha_iv iv;
110 memcpy(&iv, &hash, CHACHA_IV_SIZE);
111 return iv;
112}
113
114static std::string encrypt(const std::string &plaintext, const crypto::key_image &key_image, const crypto::chacha_key &key)
115{
116 const crypto::chacha_iv iv = make_iv(key_image, key);
117 std::string ciphertext;
118 ciphertext.resize(plaintext.size() + sizeof(iv));
119 crypto::chacha20(plaintext.data(), plaintext.size(), key, iv, &ciphertext[sizeof(iv)]);
120 memcpy(&ciphertext[0], &iv, sizeof(iv));
121 return ciphertext;
122}
123
124static std::string encrypt(const crypto::key_image &key_image, const crypto::chacha_key &key)
125{
126 return encrypt(std::string((const char*)&key_image, sizeof(key_image)), key_image, key);
127}
128
129static std::string decrypt(const std::string &ciphertext, const crypto::key_image &key_image, const crypto::chacha_key &key)
130{
131 const crypto::chacha_iv iv = make_iv(key_image, key);
132 std::string plaintext;
133 THROW_WALLET_EXCEPTION_IF(ciphertext.size() < sizeof(iv), tools::error::wallet_internal_error, "Bad ciphertext text");
134 plaintext.resize(ciphertext.size() - sizeof(iv));
135 crypto::chacha20(ciphertext.data() + sizeof(iv), ciphertext.size() - sizeof(iv), key, iv, &plaintext[0]);
136 return plaintext;
137}
138
139static void store_relative_ring(MDB_txn *txn, MDB_dbi &dbi, const crypto::key_image &key_image, const std::vector<uint64_t> &relative_ring, const crypto::chacha_key &chacha_key)
140{
141 MDB_val key, data;
142 std::string key_ciphertext = encrypt(key_image, chacha_key);
143 key.mv_data = (void*)key_ciphertext.data();
144 key.mv_size = key_ciphertext.size();
145 std::string compressed_ring = compress_ring(relative_ring);
146 std::string data_ciphertext = encrypt(compressed_ring, key_image, chacha_key);
147 data.mv_size = data_ciphertext.size();
148 data.mv_data = (void*)data_ciphertext.c_str();
149 int dbr = mdb_put(txn, dbi, &key, &data, 0);
150 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set ring for key image in LMDB table: " + std::string(mdb_strerror(dbr)));
151}
152
153static int resize_env(MDB_env *env, const char *db_path, size_t needed)
154{
155 MDB_envinfo mei;
156 MDB_stat mst;
157 int ret;
158
159 needed = std::max(needed, (size_t)(100ul * 1024 * 1024)); // at least 100 MB
160
161 ret = mdb_env_info(env, &mei);
162 if (ret)
163 return ret;
164 ret = mdb_env_stat(env, &mst);
165 if (ret)
166 return ret;
167 uint64_t size_used = mst.ms_psize * mei.me_last_pgno;
168 uint64_t mapsize = mei.me_mapsize;
169 if (size_used + needed > mei.me_mapsize)
170 {
171 try
172 {
173 boost::filesystem::path path(db_path);
174 boost::filesystem::space_info si = boost::filesystem::space(path);
175 if(si.available < needed)
176 {
177 MERROR("!! WARNING: Insufficient free space to extend database !!: " << (si.available >> 20L) << " MB available");
178 return ENOSPC;
179 }
180 }
181 catch(...)
182 {
183 // print something but proceed.
184 MWARNING("Unable to query free disk space.");
185 }
186
187 mapsize += needed;
188 }
189 return mdb_env_set_mapsize(env, mapsize);
190}
191
192static size_t get_ring_data_size(size_t n_entries)
193{
194 return n_entries * (32 + 1024); // highball 1kB for the ring data to make sure
195}
196
198
199namespace tools
200{
201
202ringdb::ringdb(std::string filename, const std::string &genesis):
203 filename(filename),
204 env(NULL)
205{
206 MDB_txn *txn;
207 bool tx_active = false;
208 int dbr;
209
211
212 dbr = mdb_env_create(&env);
213 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LDMB environment: " + std::string(mdb_strerror(dbr)));
214 dbr = mdb_env_set_maxdbs(env, 2);
215 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set max env dbs: " + std::string(mdb_strerror(dbr)));
216 const std::string actual_filename = get_rings_filename(filename);
217 dbr = mdb_env_open(env, actual_filename.c_str(), 0, 0664);
218 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to open rings database file '"
219 + actual_filename + "': " + std::string(mdb_strerror(dbr)));
220
221 dbr = mdb_txn_begin(env, NULL, 0, &txn);
222 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
224 tx_active = true;
225
226 dbr = mdb_dbi_open(txn, ("rings-" + genesis).c_str(), MDB_CREATE, &dbi_rings);
227 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr)));
228 mdb_set_compare(txn, dbi_rings, compare_hash32);
229
230 dbr = mdb_dbi_open(txn, ("blackballs2-" + genesis).c_str(), MDB_CREATE | MDB_INTEGERKEY | MDB_DUPSORT | MDB_DUPFIXED, &dbi_blackballs);
231 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to open LMDB dbi: " + std::string(mdb_strerror(dbr)));
232 mdb_set_dupsort(txn, dbi_blackballs, compare_uint64);
233
234 dbr = mdb_txn_commit(txn);
235 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to commit txn creating/opening database: " + std::string(mdb_strerror(dbr)));
236 tx_active = false;
237}
238
240{
241 close();
242}
243
245{
246 if (env)
247 {
248 mdb_dbi_close(env, dbi_rings);
249 mdb_dbi_close(env, dbi_blackballs);
250 mdb_env_close(env);
251 env = NULL;
252 }
253}
254
255bool ringdb::add_rings(const crypto::chacha_key &chacha_key, const cryptonote::transaction_prefix &tx)
256{
257 MDB_txn *txn;
258 int dbr;
259 bool tx_active = false;
260
261 dbr = resize_env(env, filename.c_str(), get_ring_data_size(tx.vin.size()));
262 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size");
263 dbr = mdb_txn_begin(env, NULL, 0, &txn);
264 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
266 tx_active = true;
267
268 for (const auto &in: tx.vin)
269 {
270 if (in.type() != typeid(cryptonote::txin_to_key))
271 continue;
272 const auto &txin = boost::get<cryptonote::txin_to_key>(in);
273 const uint32_t ring_size = txin.key_offsets.size();
274 if (ring_size == 1)
275 continue;
276
277 store_relative_ring(txn, dbi_rings, txin.k_image, txin.key_offsets, chacha_key);
278 }
279
280 dbr = mdb_txn_commit(txn);
281 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to commit txn adding ring to database: " + std::string(mdb_strerror(dbr)));
282 tx_active = false;
283 return true;
284}
285
286bool ringdb::remove_rings(const crypto::chacha_key &chacha_key, const std::vector<crypto::key_image> &key_images)
287{
288 MDB_txn *txn;
289 int dbr;
290 bool tx_active = false;
291
292 dbr = resize_env(env, filename.c_str(), 0);
293 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size");
294 dbr = mdb_txn_begin(env, NULL, 0, &txn);
295 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
297 tx_active = true;
298
299 for (const crypto::key_image &key_image: key_images)
300 {
301 MDB_val key, data;
302 std::string key_ciphertext = encrypt(key_image, chacha_key);
303 key.mv_data = (void*)key_ciphertext.data();
304 key.mv_size = key_ciphertext.size();
305
306 dbr = mdb_get(txn, dbi_rings, &key, &data);
307 THROW_WALLET_EXCEPTION_IF(dbr && dbr != MDB_NOTFOUND, tools::error::wallet_internal_error, "Failed to look for key image in LMDB table: " + std::string(mdb_strerror(dbr)));
308 if (dbr == MDB_NOTFOUND)
309 continue;
310 THROW_WALLET_EXCEPTION_IF(data.mv_size <= 0, tools::error::wallet_internal_error, "Invalid ring data size");
311
312 MDEBUG("Removing ring data for key image " << key_image);
313 dbr = mdb_del(txn, dbi_rings, &key, NULL);
314 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to remove ring to database: " + std::string(mdb_strerror(dbr)));
315 }
316
317 dbr = mdb_txn_commit(txn);
318 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to commit txn removing ring to database: " + std::string(mdb_strerror(dbr)));
319 tx_active = false;
320 return true;
321}
322
323bool ringdb::remove_rings(const crypto::chacha_key &chacha_key, const cryptonote::transaction_prefix &tx)
324{
325 std::vector<crypto::key_image> key_images;
326 key_images.reserve(tx.vin.size());
327 for (const auto &in: tx.vin)
328 {
329 if (in.type() != typeid(cryptonote::txin_to_key))
330 continue;
331 const auto &txin = boost::get<cryptonote::txin_to_key>(in);
332 const uint32_t ring_size = txin.key_offsets.size();
333 if (ring_size == 1)
334 continue;
335 key_images.push_back(txin.k_image);
336 }
337 return remove_rings(chacha_key, key_images);
338}
339
340bool ringdb::get_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, std::vector<uint64_t> &outs)
341{
342 MDB_txn *txn;
343 int dbr;
344 bool tx_active = false;
345
346 dbr = resize_env(env, filename.c_str(), 0);
347 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size: " + std::string(mdb_strerror(dbr)));
348 dbr = mdb_txn_begin(env, NULL, 0, &txn);
349 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
351 tx_active = true;
352
353 MDB_val key, data;
354 std::string key_ciphertext = encrypt(key_image, chacha_key);
355 key.mv_data = (void*)key_ciphertext.data();
356 key.mv_size = key_ciphertext.size();
357 dbr = mdb_get(txn, dbi_rings, &key, &data);
358 THROW_WALLET_EXCEPTION_IF(dbr && dbr != MDB_NOTFOUND, tools::error::wallet_internal_error, "Failed to look for key image in LMDB table: " + std::string(mdb_strerror(dbr)));
359 if (dbr == MDB_NOTFOUND)
360 return false;
361 THROW_WALLET_EXCEPTION_IF(data.mv_size <= 0, tools::error::wallet_internal_error, "Invalid ring data size");
362
363 std::string data_plaintext = decrypt(std::string((const char*)data.mv_data, data.mv_size), key_image, chacha_key);
364 outs = decompress_ring(data_plaintext);
365 MDEBUG("Found ring for key image " << key_image << ":");
366 MDEBUG("Relative: " << boost::join(outs | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " "));
368 MDEBUG("Absolute: " << boost::join(outs | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " "));
369
370 dbr = mdb_txn_commit(txn);
371 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to commit txn getting ring from database: " + std::string(mdb_strerror(dbr)));
372 tx_active = false;
373 return true;
374}
375
376bool ringdb::set_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative)
377{
378 MDB_txn *txn;
379 int dbr;
380 bool tx_active = false;
381
382 dbr = resize_env(env, filename.c_str(), outs.size() * 64);
383 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size: " + std::string(mdb_strerror(dbr)));
384 dbr = mdb_txn_begin(env, NULL, 0, &txn);
385 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
387 tx_active = true;
388
389 store_relative_ring(txn, dbi_rings, key_image, relative ? outs : cryptonote::absolute_output_offsets_to_relative(outs), chacha_key);
390
391 dbr = mdb_txn_commit(txn);
392 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to commit txn setting ring to database: " + std::string(mdb_strerror(dbr)));
393 tx_active = false;
394 return true;
395}
396
397bool ringdb::blackball_worker(const std::vector<std::pair<uint64_t, uint64_t>> &outputs, int op)
398{
399 MDB_txn *txn;
400 MDB_cursor *cursor;
401 int dbr;
402 bool tx_active = false;
403 bool ret = true;
404
405 THROW_WALLET_EXCEPTION_IF(outputs.size() > 1 && op == BLACKBALL_QUERY, tools::error::wallet_internal_error, "Blackball query only makes sense for a single output");
406
407 dbr = resize_env(env, filename.c_str(), 32 * 2 * outputs.size()); // a pubkey, and some slack
408 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size: " + std::string(mdb_strerror(dbr)));
409 dbr = mdb_txn_begin(env, NULL, 0, &txn);
410 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
412 tx_active = true;
413
414 dbr = mdb_cursor_open(txn, dbi_blackballs, &cursor);
415 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create cursor for blackballs table: " + std::string(mdb_strerror(dbr)));
416
417 MDB_val key, data;
418 for (const std::pair<uint64_t, uint64_t> &output: outputs)
419 {
420 key.mv_data = (void*)&output.first;
421 key.mv_size = sizeof(output.first);
422 data.mv_data = (void*)&output.second;
423 data.mv_size = sizeof(output.second);
424
425 switch (op)
426 {
428 MDEBUG("Marking output " << output.first << "/" << output.second << " as spent");
429 dbr = mdb_cursor_put(cursor, &key, &data, MDB_APPENDDUP);
430 if (dbr == MDB_KEYEXIST)
431 dbr = 0;
432 break;
434 MDEBUG("Marking output " << output.first << "/" << output.second << " as unspent");
435 dbr = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH);
436 if (dbr == 0)
437 dbr = mdb_cursor_del(cursor, 0);
438 break;
439 case BLACKBALL_QUERY:
440 dbr = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH);
441 THROW_WALLET_EXCEPTION_IF(dbr && dbr != MDB_NOTFOUND, tools::error::wallet_internal_error, "Failed to lookup in blackballs table: " + std::string(mdb_strerror(dbr)));
442 ret = dbr != MDB_NOTFOUND;
443 if (dbr == MDB_NOTFOUND)
444 dbr = 0;
445 break;
446 case BLACKBALL_CLEAR:
447 break;
448 default:
450 }
451 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to query blackballs table: " + std::string(mdb_strerror(dbr)));
452 }
453
454 mdb_cursor_close(cursor);
455
456 if (op == BLACKBALL_CLEAR)
457 {
458 dbr = mdb_drop(txn, dbi_blackballs, 0);
459 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to clear blackballs table: " + std::string(mdb_strerror(dbr)));
460 }
461
462 dbr = mdb_txn_commit(txn);
463 THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to commit txn blackballing output to database: " + std::string(mdb_strerror(dbr)));
464 tx_active = false;
465 return ret;
466}
467
468bool ringdb::blackball(const std::vector<std::pair<uint64_t, uint64_t>> &outputs)
469{
470 return blackball_worker(outputs, BLACKBALL_BLACKBALL);
471}
472
473bool ringdb::blackball(const std::pair<uint64_t, uint64_t> &output)
474{
475 std::vector<std::pair<uint64_t, uint64_t>> outputs(1, output);
476 return blackball_worker(outputs, BLACKBALL_BLACKBALL);
477}
478
479bool ringdb::unblackball(const std::pair<uint64_t, uint64_t> &output)
480{
481 std::vector<std::pair<uint64_t, uint64_t>> outputs(1, output);
482 return blackball_worker(outputs, BLACKBALL_UNBLACKBALL);
483}
484
485bool ringdb::blackballed(const std::pair<uint64_t, uint64_t> &output)
486{
487 std::vector<std::pair<uint64_t, uint64_t>> outputs(1, output);
488 return blackball_worker(outputs, BLACKBALL_QUERY);
489}
490
492{
493 return blackball_worker(std::vector<std::pair<uint64_t, uint64_t>>(), BLACKBALL_CLEAR);
494}
495
496}
int compare_uint64(const MDB_val *a, const MDB_val *b)
#define CHACHA_IV_SIZE
Definition chacha.h:37
bool remove_rings(const crypto::chacha_key &chacha_key, const std::vector< crypto::key_image > &key_images)
Definition ringdb.cpp:286
void close()
Definition ringdb.cpp:244
bool clear_blackballs()
Definition ringdb.cpp:491
bool set_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, const std::vector< uint64_t > &outs, bool relative)
Definition ringdb.cpp:376
bool add_rings(const crypto::chacha_key &chacha_key, const cryptonote::transaction_prefix &tx)
Definition ringdb.cpp:255
bool unblackball(const std::pair< uint64_t, uint64_t > &output)
Definition ringdb.cpp:479
bool blackball(const std::pair< uint64_t, uint64_t > &output)
Definition ringdb.cpp:473
bool blackballed(const std::pair< uint64_t, uint64_t > &output)
Definition ringdb.cpp:485
bool get_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, std::vector< uint64_t > &outs)
Definition ringdb.cpp:340
ringdb(std::string filename, const std::string &genesis)
Definition ringdb.cpp:202
void * memcpy(void *a, const void *b, size_t c)
#define MDB_KEYEXIST
Definition lmdb.h:437
#define MDB_NOTFOUND
Definition lmdb.h:439
int mdb_env_info(MDB_env *env, MDB_envinfo *stat)
Return information about the LMDB environment.
int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, unsigned int flags)
Store by cursor.
int mdb_cursor_del(MDB_cursor *cursor, unsigned int flags)
Delete current key/data pair.
int mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode)
Open an environment handle.
void mdb_env_close(MDB_env *env)
Close the environment and release the memory map.
int mdb_cursor_get(MDB_cursor *cursor, MDB_val *key, MDB_val *data, MDB_cursor_op op)
Retrieve by cursor.
int mdb_env_set_mapsize(MDB_env *env, mdb_size_t size)
Set the size of the memory map to use for this environment.
int mdb_put(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned int flags)
Store items into a database.
void mdb_dbi_close(MDB_env *env, MDB_dbi dbi)
Close a database handle. Normally unnecessary. Use with care:
int mdb_set_compare(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Set a custom key comparison function for a database.
void mdb_txn_abort(MDB_txn *txn)
Abandon all the operations of the transaction instead of saving them.
int mdb_txn_commit(MDB_txn *txn)
Commit all the operations of a transaction into the database.
int mdb_get(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data)
Get items from a database.
char * mdb_strerror(int err)
Return a string describing a given error code.
int mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **cursor)
Create a cursor handle.
int mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs)
Set the maximum number of named databases for the environment.
int mdb_env_create(MDB_env **env)
Create an LMDB environment handle.
int mdb_del(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data)
Delete items from a database.
int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
Empty or delete+close a database.
int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *dbi)
Open a database in the environment.
int mdb_set_dupsort(MDB_txn *txn, MDB_dbi dbi, MDB_cmp_func *cmp)
Set a custom data comparison function for a MDB_DUPSORT database.
void mdb_cursor_close(MDB_cursor *cursor)
Close a cursor handle.
int mdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB_txn **txn)
Create a transaction for use with the environment.
int mdb_env_stat(MDB_env *env, MDB_stat *stat)
Return statistics about the LMDB environment.
@ MDB_GET_BOTH
Definition lmdb.h:402
#define MDB_INTEGERKEY
Definition lmdb.h:349
#define MDB_DUPFIXED
Definition lmdb.h:351
#define MDB_DUPSORT
Definition lmdb.h:345
#define MDB_CREATE
Definition lmdb.h:357
#define MDB_APPENDDUP
Definition lmdb.h:379
mdb_size_t me_mapsize
Definition lmdb.h:503
mdb_size_t me_last_pgno
Definition lmdb.h:504
unsigned int ms_psize
Definition lmdb.h:491
void * mv_data
Definition lmdb.h:288
size_t mv_size
Definition lmdb.h:287
struct MDB_env MDB_env
Opaque structure for a database environment.
Definition lmdb.h:260
struct MDB_txn MDB_txn
Opaque structure for a transaction handle.
Definition lmdb.h:267
unsigned int MDB_dbi
A handle for an individual database in the DB environment.
Definition lmdb.h:270
struct MDB_cursor MDB_cursor
Opaque structure for navigating through a database.
Definition lmdb.h:273
const char * key
Lightning memory-mapped database library.
#define MERROR(x)
Definition misc_log_ex.h:73
#define MWARNING(x)
Definition misc_log_ex.h:74
#define MDEBUG(x)
Definition misc_log_ex.h:76
void cn_fast_hash(const void *data, size_t length, char *hash)
POD_CLASS key_image
Definition crypto.h:105
POD_CLASS hash
Definition hash.h:50
std::vector< uint64_t > absolute_output_offsets_to_relative(const std::vector< uint64_t > &off)
std::vector< uint64_t > relative_output_offsets_to_absolute(const std::vector< uint64_t > &off)
boost::shared_ptr< call_befor_die_base > auto_scope_leave_caller
auto_scope_leave_caller create_scope_leave_handler(t_scope_leave_handler f)
Various Tools.
Definition tools.cpp:31
std::enable_if< std::is_integral< T >::value &&std::is_unsigned< T >::value &&0<=bits &&bits<=std::numeric_limits< T >::digits, int >::type read_varint(InputIt &&first, InputIt &&last, T &write)
reads in the varint that is pointed to by InputIt into write
Definition varint.h:95
std::string get_varint_data(const T &v)
Returns the string that represents the varint.
Definition varint.h:85
bool create_directories_if_necessary(const std::string &path)
creates directories for a path
Definition util.cpp:625
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1124
@ BLACKBALL_CLEAR
Definition ringdb.cpp:197
@ BLACKBALL_QUERY
Definition ringdb.cpp:197
@ BLACKBALL_UNBLACKBALL
Definition ringdb.cpp:197
@ BLACKBALL_BLACKBALL
Definition ringdb.cpp:197
std::string get_rings_filename(boost::filesystem::path filename)
Definition ringdb.cpp:91
unsigned int uint32_t
Definition stdint.h:126
unsigned char uint8_t
Definition stdint.h:124
unsigned __int64 uint64_t
Definition stdint.h:136
Information about the environment.
Definition lmdb.h:501
Statistics for a database in the environment.
Definition lmdb.h:490
Generic structure used for passing keys and data in and out of the database.
Definition lmdb.h:286
#define THROW_WALLET_EXCEPTION_IF(cond, err_type,...)
#define THROW_WALLET_EXCEPTION(err_type,...)