rpc: lock access to the rpc payment object

This commit is contained in:
moneromooo-monero 2020-05-19 18:20:32 +00:00
parent 77a008f714
commit 7ebb351c2d
No known key found for this signature in database
GPG key ID: 686F07454D6CEFC3
2 changed files with 12 additions and 0 deletions

View file

@ -92,6 +92,7 @@ namespace cryptonote
uint64_t rpc_payment::balance(const crypto::public_key &client, int64_t delta) uint64_t rpc_payment::balance(const crypto::public_key &client, int64_t delta)
{ {
boost::lock_guard<boost::mutex> lock(mutex);
client_info &info = m_client_info[client]; // creates if not found client_info &info = m_client_info[client]; // creates if not found
uint64_t credits = info.credits; uint64_t credits = info.credits;
if (delta > 0 && credits > std::numeric_limits<uint64_t>::max() - delta) if (delta > 0 && credits > std::numeric_limits<uint64_t>::max() - delta)
@ -107,6 +108,7 @@ namespace cryptonote
bool rpc_payment::pay(const crypto::public_key &client, uint64_t ts, uint64_t payment, const std::string &rpc, bool same_ts, uint64_t &credits) bool rpc_payment::pay(const crypto::public_key &client, uint64_t ts, uint64_t payment, const std::string &rpc, bool same_ts, uint64_t &credits)
{ {
boost::lock_guard<boost::mutex> lock(mutex);
client_info &info = m_client_info[client]; // creates if not found client_info &info = m_client_info[client]; // creates if not found
if (ts < info.last_request_timestamp || (ts == info.last_request_timestamp && !same_ts)) if (ts < info.last_request_timestamp || (ts == info.last_request_timestamp && !same_ts))
{ {
@ -130,6 +132,7 @@ namespace cryptonote
bool rpc_payment::get_info(const crypto::public_key &client, const std::function<bool(const cryptonote::blobdata&, cryptonote::block&, uint64_t &seed_height, crypto::hash &seed_hash)> &get_block_template, cryptonote::blobdata &hashing_blob, uint64_t &seed_height, crypto::hash &seed_hash, const crypto::hash &top, uint64_t &diff, uint64_t &credits_per_hash_found, uint64_t &credits, uint32_t &cookie) bool rpc_payment::get_info(const crypto::public_key &client, const std::function<bool(const cryptonote::blobdata&, cryptonote::block&, uint64_t &seed_height, crypto::hash &seed_hash)> &get_block_template, cryptonote::blobdata &hashing_blob, uint64_t &seed_height, crypto::hash &seed_hash, const crypto::hash &top, uint64_t &diff, uint64_t &credits_per_hash_found, uint64_t &credits, uint32_t &cookie)
{ {
boost::lock_guard<boost::mutex> lock(mutex);
client_info &info = m_client_info[client]; // creates if not found client_info &info = m_client_info[client]; // creates if not found
const uint64_t now = time(NULL); const uint64_t now = time(NULL);
bool need_template = top != info.top || now >= info.block_template_update_time + STALE_THRESHOLD; bool need_template = top != info.top || now >= info.block_template_update_time + STALE_THRESHOLD;
@ -180,6 +183,7 @@ namespace cryptonote
bool rpc_payment::submit_nonce(const crypto::public_key &client, uint32_t nonce, const crypto::hash &top, int64_t &error_code, std::string &error_message, uint64_t &credits, crypto::hash &hash, cryptonote::block &block, uint32_t cookie, bool &stale) bool rpc_payment::submit_nonce(const crypto::public_key &client, uint32_t nonce, const crypto::hash &top, int64_t &error_code, std::string &error_message, uint64_t &credits, crypto::hash &hash, cryptonote::block &block, uint32_t cookie, bool &stale)
{ {
boost::lock_guard<boost::mutex> lock(mutex);
client_info &info = m_client_info[client]; // creates if not found client_info &info = m_client_info[client]; // creates if not found
if (cookie != info.cookie && cookie != info.cookie - 1) if (cookie != info.cookie && cookie != info.cookie - 1)
{ {
@ -272,6 +276,7 @@ namespace cryptonote
bool rpc_payment::foreach(const std::function<bool(const crypto::public_key &client, const client_info &info)> &f) const bool rpc_payment::foreach(const std::function<bool(const crypto::public_key &client, const client_info &info)> &f) const
{ {
boost::lock_guard<boost::mutex> lock(mutex);
for (std::unordered_map<crypto::public_key, client_info>::const_iterator i = m_client_info.begin(); i != m_client_info.end(); ++i) for (std::unordered_map<crypto::public_key, client_info>::const_iterator i = m_client_info.begin(); i != m_client_info.end(); ++i)
{ {
if (!f(i->first, i->second)) if (!f(i->first, i->second))
@ -283,6 +288,7 @@ namespace cryptonote
bool rpc_payment::load(std::string directory) bool rpc_payment::load(std::string directory)
{ {
TRY_ENTRY(); TRY_ENTRY();
boost::lock_guard<boost::mutex> lock(mutex);
m_directory = std::move(directory); m_directory = std::move(directory);
std::string state_file_path = directory + "/" + RPC_PAYMENTS_DATA_FILENAME; std::string state_file_path = directory + "/" + RPC_PAYMENTS_DATA_FILENAME;
MINFO("loading rpc payments data from " << state_file_path); MINFO("loading rpc payments data from " << state_file_path);
@ -313,6 +319,7 @@ namespace cryptonote
bool rpc_payment::store(const std::string &directory_) const bool rpc_payment::store(const std::string &directory_) const
{ {
TRY_ENTRY(); TRY_ENTRY();
boost::lock_guard<boost::mutex> lock(mutex);
const std::string &directory = directory_.empty() ? m_directory : directory_; const std::string &directory = directory_.empty() ? m_directory : directory_;
MDEBUG("storing rpc payments data to " << directory); MDEBUG("storing rpc payments data to " << directory);
if (!tools::create_directories_if_necessary(directory)) if (!tools::create_directories_if_necessary(directory))
@ -345,6 +352,7 @@ namespace cryptonote
unsigned int rpc_payment::flush_by_age(time_t seconds) unsigned int rpc_payment::flush_by_age(time_t seconds)
{ {
boost::lock_guard<boost::mutex> lock(mutex);
unsigned int count = 0; unsigned int count = 0;
const time_t now = time(NULL); const time_t now = time(NULL);
time_t seconds0 = seconds; time_t seconds0 = seconds;
@ -372,6 +380,7 @@ namespace cryptonote
uint64_t rpc_payment::get_hashes(unsigned int seconds) const uint64_t rpc_payment::get_hashes(unsigned int seconds) const
{ {
boost::lock_guard<boost::mutex> lock(mutex);
const uint64_t now = time(NULL); const uint64_t now = time(NULL);
uint64_t hashes = 0; uint64_t hashes = 0;
for (std::map<uint64_t, uint64_t>::const_reverse_iterator i = m_hashrate.crbegin(); i != m_hashrate.crend(); ++i) for (std::map<uint64_t, uint64_t>::const_reverse_iterator i = m_hashrate.crbegin(); i != m_hashrate.crend(); ++i)
@ -385,6 +394,7 @@ namespace cryptonote
void rpc_payment::prune_hashrate(unsigned int seconds) void rpc_payment::prune_hashrate(unsigned int seconds)
{ {
boost::lock_guard<boost::mutex> lock(mutex);
const uint64_t now = time(NULL); const uint64_t now = time(NULL);
std::map<uint64_t, uint64_t>::iterator i; std::map<uint64_t, uint64_t>::iterator i;
for (i = m_hashrate.begin(); i != m_hashrate.end(); ++i) for (i = m_hashrate.begin(); i != m_hashrate.end(); ++i)

View file

@ -31,6 +31,7 @@
#include <string> #include <string>
#include <unordered_set> #include <unordered_set>
#include <unordered_map> #include <unordered_map>
#include <boost/thread/mutex.hpp>
#include <boost/serialization/version.hpp> #include <boost/serialization/version.hpp>
#include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/blobdatatype.h"
#include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_basic.h"
@ -139,6 +140,7 @@ namespace cryptonote
uint64_t m_nonces_stale; uint64_t m_nonces_stale;
uint64_t m_nonces_bad; uint64_t m_nonces_bad;
uint64_t m_nonces_dupe; uint64_t m_nonces_dupe;
mutable boost::mutex mutex;
}; };
} }