aboutsummaryrefslogtreecommitdiff
path: root/src/cryptonote_core/cryptonote_core.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/cryptonote_core/cryptonote_core.cpp')
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp97
1 files changed, 97 insertions, 0 deletions
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 239ef5d84..fd509b603 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -35,6 +35,8 @@ using namespace epee;
#include "cryptonote_core.h"
#include "common/command_line.h"
#include "common/util.h"
+#include "common/updates.h"
+#include "common/download.h"
#include "warnings.h"
#include "crypto/crypto.h"
#include "cryptonote_config.h"
@@ -148,6 +150,7 @@ namespace cryptonote
command_line::add_arg(desc, command_line::arg_db_sync_mode);
command_line::add_arg(desc, command_line::arg_show_time_stats);
command_line::add_arg(desc, command_line::arg_block_sync_size);
+ command_line::add_arg(desc, command_line::arg_check_updates);
}
//-----------------------------------------------------------------------------------------------
bool core::handle_command_line(const boost::program_options::variables_map& vm)
@@ -242,6 +245,7 @@ namespace cryptonote
std::string db_sync_mode = command_line::get_arg(vm, command_line::arg_db_sync_mode);
bool fast_sync = command_line::get_arg(vm, command_line::arg_fast_block_sync) != 0;
uint64_t blocks_threads = command_line::get_arg(vm, command_line::arg_prep_blocks_threads);
+ std::string check_updates_string = command_line::get_arg(vm, command_line::arg_check_updates);
boost::filesystem::path folder(m_config_folder);
if (m_fakechain)
@@ -379,6 +383,20 @@ namespace cryptonote
// with respect to what blocks we already have
CHECK_AND_ASSERT_MES(update_checkpoints(), false, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints.");
+ // DNS versions checking
+ if (check_updates_string == "disabled")
+ check_updates_level = UPDATES_DISABLED;
+ else if (check_updates_string == "notify")
+ check_updates_level = UPDATES_NOTIFY;
+ else if (check_updates_string == "download")
+ check_updates_level = UPDATES_DOWNLOAD;
+ else if (check_updates_string == "update")
+ check_updates_level = UPDATES_UPDATE;
+ else {
+ MERROR("Invalid argument to --dns-versions-check: " << check_updates_string);
+ return false;
+ }
+
r = m_miner.init(vm, m_testnet);
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize miner instance");
@@ -599,6 +617,12 @@ namespace cryptonote
return false;
}
+ if (!check_tx_inputs_keyimages_domain(tx))
+ {
+ MERROR_VER("tx uses key image not in the valid domain");
+ return false;
+ }
+
if (tx.version >= 2)
{
const rct::rctSig &rv = tx.rct_signatures;
@@ -682,6 +706,18 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
+ bool core::check_tx_inputs_keyimages_domain(const transaction& tx) const
+ {
+ std::unordered_set<crypto::key_image> ki;
+ for(const auto& in: tx.vin)
+ {
+ CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, tokey_in, false);
+ if (!(rct::scalarmultKey(rct::ki2rct(tokey_in.k_image), rct::curveOrder()) == rct::identity()))
+ return false;
+ }
+ return true;
+ }
+ //-----------------------------------------------------------------------------------------------
bool core::add_new_tx(const transaction& tx, tx_verification_context& tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
{
crypto::hash tx_hash = get_transaction_hash(tx);
@@ -1000,6 +1036,7 @@ namespace cryptonote
m_fork_moaner.do_call(boost::bind(&core::check_fork_time, this));
m_txpool_auto_relayer.do_call(boost::bind(&core::relay_txpool_transactions, this));
+ m_check_updates_interval.do_call(boost::bind(&core::check_updates, this));
m_miner.on_idle();
m_mempool.on_idle();
return true;
@@ -1027,6 +1064,66 @@ namespace cryptonote
return true;
}
//-----------------------------------------------------------------------------------------------
+ bool core::check_updates()
+ {
+ static const char software[] = "monerod";
+ static const char subdir[] = "cli"; // because it can never be simple
+#ifdef BUILD_TAG
+ static const char buildtag[] = BOOST_PP_STRINGIZE(BUILD_TAG);
+#else
+ static const char buildtag[] = "source";
+#endif
+
+ if (check_updates_level == UPDATES_DISABLED)
+ return true;
+
+ std::string version, hash;
+ MDEBUG("Checking for a new " << software << " version for " << buildtag);
+ if (!tools::check_updates(software, buildtag, m_testnet, version, hash))
+ return false;
+
+ if (tools::vercmp(version.c_str(), MONERO_VERSION) <= 0)
+ return true;
+
+ std::string url = tools::get_update_url(software, subdir, buildtag, version);
+ MGINFO("Version " << version << " of " << software << " for " << buildtag << " is available: " << url << ", SHA256 hash " << hash);
+
+ if (check_updates_level == UPDATES_NOTIFY)
+ return true;
+
+ std::string filename;
+ const char *slash = strrchr(url.c_str(), '/');
+ if (slash)
+ filename = slash + 1;
+ else
+ filename = std::string(software) + "-update-" + version;
+ boost::filesystem::path path(epee::string_tools::get_current_module_folder());
+ path /= filename;
+ if (!tools::download(path.string(), url))
+ {
+ MERROR("Failed to download " << url);
+ return false;
+ }
+ crypto::hash file_hash;
+ if (!tools::sha256sum(path.string(), file_hash))
+ {
+ MERROR("Failed to hash " << path);
+ return false;
+ }
+ if (hash != epee::string_tools::pod_to_hex(file_hash))
+ {
+ MERROR("Download from " << url << " does not match the expected hash");
+ return false;
+ }
+ MGINFO("New version downloaded to " << path);
+
+ if (check_updates_level == UPDATES_DOWNLOAD)
+ return true;
+
+ MERROR("Download/update not implemented yet");
+ return true;
+ }
+ //-----------------------------------------------------------------------------------------------
void core::set_target_blockchain_height(uint64_t target_blockchain_height)
{
m_target_blockchain_height = target_blockchain_height;