aboutsummaryrefslogtreecommitdiff
path: root/src/wallet
diff options
context:
space:
mode:
authormoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-08-12 21:41:44 +0000
committermoneromooo-monero <moneromooo-monero@users.noreply.github.com>2018-09-09 12:01:43 +0000
commit50cb370d5babcef5caa9f90981c475ca5fe3f887 (patch)
tree5cc4ffccd3e16ffed4ce3eab797d948ddba7d10f /src/wallet
parentMerge pull request #4290 (diff)
downloadmonero-50cb370d5babcef5caa9f90981c475ca5fe3f887.tar.xz
ringdb: allow blackballing many outputs at once
It cuts down on txn commits, and speeds up blackballing substantially
Diffstat (limited to 'src/wallet')
-rw-r--r--src/wallet/ringdb.cpp95
-rw-r--r--src/wallet/ringdb.h3
-rw-r--r--src/wallet/wallet2.cpp3
3 files changed, 60 insertions, 41 deletions
diff --git a/src/wallet/ringdb.cpp b/src/wallet/ringdb.cpp
index 3f2634c8b..bf5478f5e 100644
--- a/src/wallet/ringdb.cpp
+++ b/src/wallet/ringdb.cpp
@@ -146,7 +146,7 @@ static int resize_env(MDB_env *env, const char *db_path, size_t needed)
MDB_stat mst;
int ret;
- needed = std::max(needed, (size_t)(2ul * 1024 * 1024)); // at least 2 MB
+ needed = std::max(needed, (size_t)(100ul * 1024 * 1024)); // at least 100 MB
ret = mdb_env_info(env, &mei);
if (ret)
@@ -374,7 +374,7 @@ bool ringdb::set_ring(const crypto::chacha_key &chacha_key, const crypto::key_im
return true;
}
-bool ringdb::blackball_worker(const crypto::public_key &output, int op)
+bool ringdb::blackball_worker(const std::vector<crypto::public_key> &outputs, int op)
{
MDB_txn *txn;
MDB_cursor *cursor;
@@ -382,7 +382,9 @@ bool ringdb::blackball_worker(const crypto::public_key &output, int op)
bool tx_active = false;
bool ret = true;
- dbr = resize_env(env, filename.c_str(), 32 * 2); // a pubkey, and some slack
+ THROW_WALLET_EXCEPTION_IF(outputs.size() > 1 && op == BLACKBALL_QUERY, tools::error::wallet_internal_error, "Blackball query only makes sense for a single output");
+
+ dbr = resize_env(env, filename.c_str(), 32 * 2 * outputs.size()); // a pubkey, and some slack
THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size: " + std::string(mdb_strerror(dbr)));
dbr = mdb_txn_begin(env, NULL, 0, &txn);
THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr)));
@@ -391,40 +393,49 @@ bool ringdb::blackball_worker(const crypto::public_key &output, int op)
MDB_val key = zerokeyval;
MDB_val data;
- data.mv_data = (void*)&output;
- data.mv_size = sizeof(output);
- switch (op)
+ for (const crypto::public_key &output: outputs)
+ {
+ data.mv_data = (void*)&output;
+ data.mv_size = sizeof(output);
+
+ switch (op)
+ {
+ case BLACKBALL_BLACKBALL:
+ MDEBUG("Blackballing output " << output);
+ dbr = mdb_put(txn, dbi_blackballs, &key, &data, MDB_NODUPDATA);
+ if (dbr == MDB_KEYEXIST)
+ dbr = 0;
+ break;
+ case BLACKBALL_UNBLACKBALL:
+ MDEBUG("Unblackballing output " << output);
+ dbr = mdb_del(txn, dbi_blackballs, &key, &data);
+ if (dbr == MDB_NOTFOUND)
+ dbr = 0;
+ break;
+ case BLACKBALL_QUERY:
+ dbr = mdb_cursor_open(txn, dbi_blackballs, &cursor);
+ THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create cursor for blackballs table: " + std::string(mdb_strerror(dbr)));
+ dbr = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH);
+ THROW_WALLET_EXCEPTION_IF(dbr && dbr != MDB_NOTFOUND, tools::error::wallet_internal_error, "Failed to lookup in blackballs table: " + std::string(mdb_strerror(dbr)));
+ ret = dbr != MDB_NOTFOUND;
+ if (dbr == MDB_NOTFOUND)
+ dbr = 0;
+ mdb_cursor_close(cursor);
+ break;
+ case BLACKBALL_CLEAR:
+ break;
+ default:
+ THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, "Invalid blackball op");
+ }
+ THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to query blackballs table: " + std::string(mdb_strerror(dbr)));
+ }
+
+ if (op == BLACKBALL_CLEAR)
{
- case BLACKBALL_BLACKBALL:
- MDEBUG("Blackballing output " << output);
- dbr = mdb_put(txn, dbi_blackballs, &key, &data, MDB_NODUPDATA);
- if (dbr == MDB_KEYEXIST)
- dbr = 0;
- break;
- case BLACKBALL_UNBLACKBALL:
- MDEBUG("Unblackballing output " << output);
- dbr = mdb_del(txn, dbi_blackballs, &key, &data);
- if (dbr == MDB_NOTFOUND)
- dbr = 0;
- break;
- case BLACKBALL_QUERY:
- dbr = mdb_cursor_open(txn, dbi_blackballs, &cursor);
- THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create cursor for blackballs table: " + std::string(mdb_strerror(dbr)));
- dbr = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH);
- THROW_WALLET_EXCEPTION_IF(dbr && dbr != MDB_NOTFOUND, tools::error::wallet_internal_error, "Failed to lookup in blackballs table: " + std::string(mdb_strerror(dbr)));
- ret = dbr != MDB_NOTFOUND;
- if (dbr == MDB_NOTFOUND)
- dbr = 0;
- mdb_cursor_close(cursor);
- break;
- case BLACKBALL_CLEAR:
- dbr = mdb_drop(txn, dbi_blackballs, 0);
- break;
- default:
- THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, "Invalid blackball op");
+ dbr = mdb_drop(txn, dbi_blackballs, 0);
+ THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to clear blackballs table: " + std::string(mdb_strerror(dbr)));
}
- THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to query blackballs table: " + std::string(mdb_strerror(dbr)));
dbr = mdb_txn_commit(txn);
THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to commit txn blackballing output to database: " + std::string(mdb_strerror(dbr)));
@@ -432,24 +443,32 @@ bool ringdb::blackball_worker(const crypto::public_key &output, int op)
return ret;
}
+bool ringdb::blackball(const std::vector<crypto::public_key> &outputs)
+{
+ return blackball_worker(outputs, BLACKBALL_BLACKBALL);
+}
+
bool ringdb::blackball(const crypto::public_key &output)
{
- return blackball_worker(output, BLACKBALL_BLACKBALL);
+ std::vector<crypto::public_key> outputs(1, output);
+ return blackball_worker(outputs, BLACKBALL_BLACKBALL);
}
bool ringdb::unblackball(const crypto::public_key &output)
{
- return blackball_worker(output, BLACKBALL_UNBLACKBALL);
+ std::vector<crypto::public_key> outputs(1, output);
+ return blackball_worker(outputs, BLACKBALL_UNBLACKBALL);
}
bool ringdb::blackballed(const crypto::public_key &output)
{
- return blackball_worker(output, BLACKBALL_QUERY);
+ std::vector<crypto::public_key> outputs(1, output);
+ return blackball_worker(outputs, BLACKBALL_QUERY);
}
bool ringdb::clear_blackballs()
{
- return blackball_worker(crypto::public_key(), BLACKBALL_CLEAR);
+ return blackball_worker(std::vector<crypto::public_key>(), BLACKBALL_CLEAR);
}
}
diff --git a/src/wallet/ringdb.h b/src/wallet/ringdb.h
index 6b4bce124..4a78f61f8 100644
--- a/src/wallet/ringdb.h
+++ b/src/wallet/ringdb.h
@@ -50,12 +50,13 @@ namespace tools
bool set_ring(const crypto::chacha_key &chacha_key, const crypto::key_image &key_image, const std::vector<uint64_t> &outs, bool relative);
bool blackball(const crypto::public_key &output);
+ bool blackball(const std::vector<crypto::public_key> &outputs);
bool unblackball(const crypto::public_key &output);
bool blackballed(const crypto::public_key &output);
bool clear_blackballs();
private:
- bool blackball_worker(const crypto::public_key &output, int op);
+ bool blackball_worker(const std::vector<crypto::public_key> &outputs, int op);
private:
std::string filename;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index a2e36706e..ffd7131cd 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -6238,8 +6238,7 @@ bool wallet2::set_blackballed_outputs(const std::vector<crypto::public_key> &out
bool ret = true;
if (!add)
ret &= m_ringdb->clear_blackballs();
- for (const auto &output: outputs)
- ret &= m_ringdb->blackball(output);
+ ret &= m_ringdb->blackball(outputs);
return ret;
}
catch (const std::exception &e) { return false; }