aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/crypto/slow-hash.c2
-rw-r--r--src/cryptonote_core/blockchain.cpp21
-rw-r--r--src/cryptonote_core/tx_pool.cpp88
-rw-r--r--src/wallet/api/wallet_manager.cpp5
-rw-r--r--src/wallet/api/wallet_manager.h2
-rw-r--r--src/wallet/wallet2.cpp25
-rw-r--r--src/wallet/wallet2.h4
7 files changed, 75 insertions, 72 deletions
diff --git a/src/crypto/slow-hash.c b/src/crypto/slow-hash.c
index 3a03e6cd4..38aeeee54 100644
--- a/src/crypto/slow-hash.c
+++ b/src/crypto/slow-hash.c
@@ -1109,7 +1109,7 @@ union cn_slow_hash_state
STATIC INLINE int check_aes_hw(void)
{
-#ifdef __APPLE___
+#ifdef __APPLE__
return 1;
#else
static int supported = -1;
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 33407bf95..34031fb7c 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -588,6 +588,7 @@ block Blockchain::pop_block_from_blockchain()
CHECK_AND_ASSERT_THROW_MES(m_db->height() > 1, "Cannot pop the genesis block");
+ const uint8_t previous_hf_version = get_current_hard_fork_version();
try
{
m_db->pop_block(popped_block, popped_txs);
@@ -650,6 +651,13 @@ block Blockchain::pop_block_from_blockchain()
m_tx_pool.on_blockchain_dec(top_block_height, top_block_hash);
invalidate_block_template_cache();
+ const uint8_t new_hf_version = get_current_hard_fork_version();
+ if (new_hf_version != previous_hf_version)
+ {
+ MINFO("Validating txpool for v" << (unsigned)new_hf_version);
+ m_tx_pool.validate(new_hf_version);
+ }
+
return popped_block;
}
//------------------------------------------------------------------
@@ -4392,6 +4400,19 @@ leave:
get_difficulty_for_next_block(); // just to cache it
invalidate_block_template_cache();
+ const uint8_t new_hf_version = get_current_hard_fork_version();
+ if (new_hf_version != hf_version)
+ {
+ // the genesis block is added before everything's setup, and the txpool is empty
+ // when we start from scratch, so we skip this
+ const bool is_genesis_block = new_height == 1;
+ if (!is_genesis_block)
+ {
+ MGINFO("Validating txpool for v" << (unsigned)new_hf_version);
+ m_tx_pool.validate(new_hf_version);
+ }
+ }
+
send_miner_notifications(id, already_generated_coins);
for (const auto& notifier: m_block_notifiers)
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index 84605d6f5..5629db3e6 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -1568,61 +1568,59 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
- size_t tx_weight_limit = get_transaction_weight_limit(version);
- std::unordered_set<crypto::hash> remove;
- m_txpool_weight = 0;
- m_blockchain.for_all_txpool_txes([this, &remove, tx_weight_limit](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref*) {
- m_txpool_weight += meta.weight;
- if (meta.weight > tx_weight_limit) {
- LOG_PRINT_L1("Transaction " << txid << " is too big (" << meta.weight << " bytes), removing it from pool");
- remove.insert(txid);
- }
- else if (m_blockchain.have_tx(txid)) {
- LOG_PRINT_L1("Transaction " << txid << " is in the blockchain, removing it from pool");
- remove.insert(txid);
- }
+ MINFO("Validating txpool contents for v" << (unsigned)version);
+
+ LockedTXN lock(m_blockchain.get_db());
+
+ struct tx_entry_t
+ {
+ crypto::hash txid;
+ txpool_tx_meta_t meta;
+ };
+
+ // get all txids
+ std::vector<tx_entry_t> txes;
+ m_blockchain.for_all_txpool_txes([this, &txes](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref*) {
+ if (!meta.pruned) // skip pruned txes
+ txes.push_back({txid, meta});
return true;
}, false, relay_category::all);
- size_t n_removed = 0;
- if (!remove.empty())
+ // take them all out and add them back in, some might fail
+ size_t added = 0;
+ for (auto &e: txes)
{
- LockedTXN lock(m_blockchain.get_db());
- for (const crypto::hash &txid: remove)
+ try
{
- try
- {
- cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(txid, relay_category::all);
- cryptonote::transaction tx;
- if (!parse_and_validate_tx_from_blob(txblob, tx)) // remove pruned ones on startup, they're meant to be temporary
- {
- MERROR("Failed to parse tx from txpool");
- continue;
- }
- // remove tx from db first
- m_blockchain.remove_txpool_tx(txid);
- m_txpool_weight -= get_transaction_weight(tx, txblob.size());
- remove_transaction_keyimages(tx, txid);
- auto sorted_it = find_tx_in_sorted_container(txid);
- if (sorted_it == m_txs_by_fee_and_receive_time.end())
- {
- LOG_PRINT_L1("Removing tx " << txid << " from tx pool, but it was not found in the sorted txs container!");
- }
- else
- {
- m_txs_by_fee_and_receive_time.erase(sorted_it);
- }
- ++n_removed;
- }
- catch (const std::exception &e)
+ size_t weight;
+ uint64_t fee;
+ cryptonote::transaction tx;
+ cryptonote::blobdata blob;
+ bool relayed, do_not_relay, double_spend_seen, pruned;
+ if (!take_tx(e.txid, tx, blob, weight, fee, relayed, do_not_relay, double_spend_seen, pruned))
+ MERROR("Failed to get tx " << e.txid << " from txpool for re-validation");
+
+ cryptonote::tx_verification_context tvc{};
+ relay_method tx_relay = e.meta.get_relay_method();
+ if (!add_tx(tx, e.txid, blob, e.meta.weight, tvc, tx_relay, relayed, version))
{
- MERROR("Failed to remove invalid tx from pool");
- // continue
+ MINFO("Failed to re-validate tx " << e.txid << " for v" << (unsigned)version << ", dropped");
+ continue;
}
+ m_blockchain.update_txpool_tx(e.txid, e.meta);
+ ++added;
+ }
+ catch (const std::exception &e)
+ {
+ MERROR("Failed to re-validate tx from pool");
+ continue;
}
- lock.commit();
}
+
+ lock.commit();
+
+ const size_t n_removed = txes.size() - added;
if (n_removed > 0)
++m_cookie;
return n_removed;
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index 417a27db5..f5d5e2168 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -49,6 +49,11 @@ namespace epee {
namespace Monero {
+WalletManagerImpl::WalletManagerImpl()
+{
+ tools::set_strict_default_file_permissions(true);
+}
+
Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::string &password,
const std::string &language, NetworkType nettype, uint64_t kdf_rounds)
{
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index cf3056a17..1e8cff877 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -95,7 +95,7 @@ public:
bool setProxy(const std::string &address) override;
private:
- WalletManagerImpl() {}
+ WalletManagerImpl();
friend struct WalletManagerFactory;
net::http::client m_http_client;
std::string m_errorString;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 04a9bc124..2a190add5 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -314,7 +314,6 @@ void do_prepare_file_names(const std::string& file_path, std::string& keys_file,
{
keys_file = file_path;
wallet_file = file_path;
- boost::system::error_code e;
if(string_tools::get_extension(keys_file) == "keys")
{//provided keys file name
wallet_file = string_tools::cut_off_extension(wallet_file);
@@ -1229,8 +1228,6 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
m_ring_history_saved(false),
m_ringdb(),
m_last_block_reward(0),
- m_encrypt_keys_after_refresh(boost::none),
- m_decrypt_keys_lockers(0),
m_unattended(unattended),
m_devices_registered(false),
m_device_last_key_image_sync(0),
@@ -1882,8 +1879,7 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
boost::optional<epee::wipeable_string> pwd = m_callback->on_get_password(pool ? "output found in pool" : "output received");
THROW_WALLET_EXCEPTION_IF(!pwd, error::password_needed, tr("Password is needed to compute key image for incoming monero"));
THROW_WALLET_EXCEPTION_IF(!verify_password(*pwd), error::password_needed, tr("Invalid password: password is needed to compute key image for incoming monero"));
- decrypt_keys(*pwd);
- m_encrypt_keys_after_refresh = *pwd;
+ m_encrypt_keys_after_refresh.reset(new wallet_keys_unlocker(*this, m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only, *pwd));
}
}
@@ -3015,11 +3011,7 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction,
MTRACE("update_pool_state start");
auto keys_reencryptor = epee::misc_utils::create_scope_leave_handler([&, this]() {
- if (m_encrypt_keys_after_refresh)
- {
- encrypt_keys(*m_encrypt_keys_after_refresh);
- m_encrypt_keys_after_refresh = boost::none;
- }
+ m_encrypt_keys_after_refresh.reset();
});
// get the pool state
@@ -3450,11 +3442,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
start_height = 0;
auto keys_reencryptor = epee::misc_utils::create_scope_leave_handler([&, this]() {
- if (m_encrypt_keys_after_refresh)
- {
- encrypt_keys(*m_encrypt_keys_after_refresh);
- m_encrypt_keys_after_refresh = boost::none;
- }
+ m_encrypt_keys_after_refresh.reset();
});
auto scope_exit_handler_hwdev = epee::misc_utils::create_scope_leave_handler([&](){hwdev.computing_key_images(false);});
@@ -4594,18 +4582,12 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip
void wallet2::encrypt_keys(const crypto::chacha_key &key)
{
- boost::lock_guard<boost::mutex> lock(m_decrypt_keys_lock);
- if (--m_decrypt_keys_lockers) // another lock left ?
- return;
m_account.encrypt_keys(key);
m_account.decrypt_viewkey(key);
}
void wallet2::decrypt_keys(const crypto::chacha_key &key)
{
- boost::lock_guard<boost::mutex> lock(m_decrypt_keys_lock);
- if (m_decrypt_keys_lockers++) // already unlocked ?
- return;
m_account.encrypt_viewkey(key);
m_account.decrypt_keys(key);
}
@@ -7090,7 +7072,6 @@ bool wallet2::load_tx(const std::string &signed_filename, std::vector<tools::wal
bool wallet2::parse_tx_from_str(const std::string &signed_tx_st, std::vector<tools::wallet2::pending_tx> &ptx, std::function<bool(const signed_tx_set &)> accept_func)
{
std::string s = signed_tx_st;
- boost::system::error_code errcode;
signed_tx_set signed_txs;
const size_t magiclen = strlen(SIGNED_TX_PREFIX) - 1;
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index facf9878d..7648becc8 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1798,9 +1798,7 @@ private:
crypto::secret_key m_original_view_secret_key;
crypto::chacha_key m_cache_key;
- boost::optional<epee::wipeable_string> m_encrypt_keys_after_refresh;
- boost::mutex m_decrypt_keys_lock;
- unsigned int m_decrypt_keys_lockers;
+ std::shared_ptr<wallet_keys_unlocker> m_encrypt_keys_after_refresh;
bool m_unattended;
bool m_devices_registered;