aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blockchain_db/blockchain_db.h10
-rw-r--r--src/blockchain_utilities/blockchain_export.cpp15
-rw-r--r--src/blockchain_utilities/blockchain_import.cpp13
-rw-r--r--src/common/download.cpp182
-rw-r--r--src/common/download.h10
-rw-r--r--src/cryptonote_basic/CMakeLists.txt2
-rw-r--r--src/cryptonote_basic/hardfork.cpp (renamed from src/cryptonote_core/hardfork.cpp)0
-rw-r--r--src/cryptonote_basic/hardfork.h (renamed from src/cryptonote_core/hardfork.h)0
-rw-r--r--src/cryptonote_core/CMakeLists.txt2
-rw-r--r--src/cryptonote_core/blockchain.cpp2
-rw-r--r--src/cryptonote_core/blockchain.h2
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp69
-rw-r--r--src/cryptonote_core/cryptonote_core.h5
-rw-r--r--src/daemon/rpc_command_executor.cpp2
-rw-r--r--src/rpc/core_rpc_server.cpp4
-rw-r--r--src/simplewallet/simplewallet.cpp7
-rw-r--r--src/wallet/wallet2.cpp4
-rw-r--r--src/wallet/wallet2.h2
18 files changed, 262 insertions, 69 deletions
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h
index 674b844c1..f5710550b 100644
--- a/src/blockchain_db/blockchain_db.h
+++ b/src/blockchain_db/blockchain_db.h
@@ -37,7 +37,7 @@
#include "cryptonote_protocol/blobdatatype.h"
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/difficulty.h"
-#include "cryptonote_core/hardfork.h"
+#include "cryptonote_basic/hardfork.h"
/** \file
* Cryptonote Blockchain Database Interface
@@ -768,7 +768,7 @@ public:
*
* @return the block requested
*/
- block get_block(const crypto::hash& h) const;
+ virtual block get_block(const crypto::hash& h) const;
/**
* @brief gets the height of the block with a given hash
@@ -821,7 +821,7 @@ public:
*
* @return the block
*/
- block get_block_from_height(const uint64_t& height) const;
+ virtual block get_block_from_height(const uint64_t& height) const;
/**
* @brief fetch a block's timestamp
@@ -1041,7 +1041,7 @@ public:
*
* @return the transaction with the given hash
*/
- transaction get_tx(const crypto::hash& h) const;
+ virtual transaction get_tx(const crypto::hash& h) const;
/**
* @brief fetches the transaction with the given hash
@@ -1052,7 +1052,7 @@ public:
*
* @return true iff the transaction was found
*/
- bool get_tx(const crypto::hash& h, transaction &tx) const;
+ virtual bool get_tx(const crypto::hash& h, transaction &tx) const;
/**
* @brief fetches the transaction blob with the given hash
diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp
index 269710ee1..f145bc107 100644
--- a/src/blockchain_utilities/blockchain_export.cpp
+++ b/src/blockchain_utilities/blockchain_export.cpp
@@ -57,6 +57,8 @@ std::string join_set_strings(const std::unordered_set<std::string>& db_types_all
int main(int argc, char* argv[])
{
+ TRY_ENTRY();
+
epee::string_tools::set_module_name_and_folder(argv[0]);
std::string default_db_type = "lmdb";
@@ -80,7 +82,7 @@ int main(int argc, char* argv[])
po::options_description desc_cmd_only("Command line options");
po::options_description desc_cmd_sett("Command line options and settings options");
const command_line::arg_descriptor<std::string> arg_output_file = {"output-file", "Specify output file", "", true};
- const command_line::arg_descriptor<uint32_t> arg_log_level = {"log-level", "", log_level};
+ const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""};
const command_line::arg_descriptor<uint64_t> arg_block_stop = {"block-stop", "Stop at block number", block_stop};
const command_line::arg_descriptor<bool> arg_testnet_on = {
"testnet"
@@ -124,11 +126,13 @@ int main(int argc, char* argv[])
return 1;
}
- log_level = command_line::get_arg(vm, arg_log_level);
+ mlog_configure(mlog_get_default_log_path("monero-blockchain-export.log"), true);
+ if (!vm["log-level"].defaulted())
+ mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
+ else
+ mlog_set_log(std::string(std::to_string(log_level) + ",bcutil:INFO").c_str());
block_stop = command_line::get_arg(vm, arg_block_stop);
- mlog_configure(mlog_get_default_log_path("monero-blockchain-export.log"), true);
- mlog_set_log(std::string(std::to_string(log_level) + ",bcutil:INFO").c_str());
LOG_PRINT_L0("Starting...");
bool opt_testnet = command_line::get_arg(vm, arg_testnet_on);
@@ -226,4 +230,7 @@ int main(int argc, char* argv[])
}
CHECK_AND_ASSERT_MES(r, false, "Failed to export blockchain raw data");
LOG_PRINT_L0("Blockchain raw data exported OK");
+ return 0;
+
+ CATCH_ENTRY("Export error", 1);
}
diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp
index 83fd6fb20..b2c217ca1 100644
--- a/src/blockchain_utilities/blockchain_import.cpp
+++ b/src/blockchain_utilities/blockchain_import.cpp
@@ -596,6 +596,8 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path,
int main(int argc, char* argv[])
{
+ TRY_ENTRY();
+
epee::string_tools::set_module_name_and_folder(argv[0]);
std::string default_db_type = "lmdb";
@@ -622,7 +624,7 @@ int main(int argc, char* argv[])
po::options_description desc_cmd_only("Command line options");
po::options_description desc_cmd_sett("Command line options and settings options");
const command_line::arg_descriptor<std::string> arg_input_file = {"input-file", "Specify input file", "", true};
- const command_line::arg_descriptor<uint32_t> arg_log_level = {"log-level", "", log_level};
+ const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""};
const command_line::arg_descriptor<uint64_t> arg_block_stop = {"block-stop", "Stop at block number", block_stop};
const command_line::arg_descriptor<uint64_t> arg_batch_size = {"batch-size", "", db_batch_size};
const command_line::arg_descriptor<uint64_t> arg_pop_blocks = {"pop-blocks", "Remove blocks from end of blockchain", num_blocks};
@@ -682,7 +684,6 @@ int main(int argc, char* argv[])
if (! r)
return 1;
- log_level = command_line::get_arg(vm, arg_log_level);
opt_verify = command_line::get_arg(vm, arg_verify);
opt_batch = command_line::get_arg(vm, arg_batch);
opt_resume = command_line::get_arg(vm, arg_resume);
@@ -725,7 +726,11 @@ int main(int argc, char* argv[])
db_arg_str = command_line::get_arg(vm, arg_database);
mlog_configure(mlog_get_default_log_path("monero-blockchain-import.log"), true);
- mlog_set_log(std::string(std::to_string(log_level) + ",bcutil:INFO").c_str());
+ if (!vm["log-level"].defaulted())
+ mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
+ else
+ mlog_set_log(std::string(std::to_string(log_level) + ",bcutil:INFO").c_str());
+
MINFO("Starting...");
boost::filesystem::path fs_import_file_path;
@@ -852,4 +857,6 @@ int main(int argc, char* argv[])
// calls delete on its BlockchainDB derived class' object, which closes its
// files.
return 0;
+
+ CATCH_ENTRY("Import error", 1);
}
diff --git a/src/common/download.cpp b/src/common/download.cpp
index c5ee797d0..28aac5a59 100644
--- a/src/common/download.cpp
+++ b/src/common/download.cpp
@@ -27,6 +27,7 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
+#include <atomic>
#include <boost/filesystem.hpp>
#include <boost/asio.hpp>
#include <boost/thread/thread.hpp>
@@ -40,27 +41,82 @@
namespace tools
{
- static bool download_thread(const std::string &path, const std::string &url)
+ struct download_thread_control
{
+ const std::string path;
+ const std::string uri;
+ std::function<void(const std::string&, const std::string&, bool)> result_cb;
+ std::function<bool(const std::string&, const std::string&, size_t, ssize_t)> progress_cb;
+ bool stop;
+ bool stopped;
+ bool success;
+ boost::thread thread;
+ boost::mutex mutex;
+
+ download_thread_control(const std::string &path, const std::string &uri, std::function<void(const std::string&, const std::string&, bool)> result_cb, std::function<bool(const std::string&, const std::string&, size_t, ssize_t)> progress_cb):
+ path(path), uri(uri), result_cb(result_cb), progress_cb(progress_cb), stop(false), stopped(false), success(false) {}
+ ~download_thread_control() { if (thread.joinable()) thread.detach(); }
+ };
+
+ static void download_thread(download_async_handle control)
+ {
+ static std::atomic<unsigned int> thread_id(0);
+
+ MLOG_SET_THREAD_NAME("DL" + std::to_string(thread_id++));
+
+ struct stopped_setter
+ {
+ stopped_setter(const download_async_handle &control): control(control) {}
+ ~stopped_setter() { control->stopped = true; }
+ download_async_handle control;
+ } stopped_setter(control);
+
try
{
- MINFO("Downloading " << url << " to " << path);
+ boost::unique_lock<boost::mutex> lock(control->mutex);
+ MINFO("Downloading " << control->uri << " to " << control->path);
std::ofstream f;
- f.open(path, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
+ f.open(control->path, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
if (!f.good()) {
- MERROR("Failed to open file " << path);
- return false;
+ MERROR("Failed to open file " << control->path);
+ control->result_cb(control->path, control->uri, control->success);
+ return;
}
class download_client: public epee::net_utils::http::http_simple_client
{
public:
- download_client(std::ofstream &f): f(f) {}
+ download_client(download_async_handle control, std::ofstream &f):
+ control(control), f(f), content_length(-1), total(0) {}
virtual ~download_client() { f.close(); }
+ virtual bool on_header(const epee::net_utils::http::http_response_info &headers)
+ {
+ ssize_t length;
+ if (epee::string_tools::get_xtype_from_string(length, headers.m_header_info.m_content_length) && length >= 0)
+ {
+ MINFO("Content-Length: " << length);
+ content_length = length;
+ boost::filesystem::path path(control->path);
+ boost::filesystem::space_info si = boost::filesystem::space(path);
+ if (si.available < (size_t)content_length)
+ {
+ const uint64_t avail = (si.available + 1023) / 1024, needed = (content_length + 1023) / 1024;
+ MERROR("Not enough space to download " << needed << " kB to " << path << " (" << avail << " kB available)");
+ return false;
+ }
+ }
+ return true;
+ }
virtual bool handle_target_data(std::string &piece_of_transfer)
{
try
{
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ if (control->stop)
+ return false;
f << piece_of_transfer;
+ total += piece_of_transfer.size();
+ if (control->progress_cb && !control->progress_cb(control->path, control->uri, total, content_length))
+ return false;
return f.good();
}
catch (const std::exception &e)
@@ -70,69 +126,145 @@ namespace tools
}
}
private:
+ download_async_handle control;
std::ofstream &f;
- } client(f);
+ ssize_t content_length;
+ size_t total;
+ } client(control, f);
epee::net_utils::http::url_content u_c;
- if (!epee::net_utils::parse_url(url, u_c))
+ if (!epee::net_utils::parse_url(control->uri, u_c))
{
- MWARNING("Failed to parse URL " << url);
- return false;
+ MERROR("Failed to parse URL " << control->uri);
+ control->result_cb(control->path, control->uri, control->success);
+ return;
}
if (u_c.host.empty())
{
- MWARNING("Failed to determine address from URL " << url);
- return false;
+ MERROR("Failed to determine address from URL " << control->uri);
+ control->result_cb(control->path, control->uri, control->success);
+ return;
}
+
+ lock.unlock();
+
uint16_t port = u_c.port ? u_c.port : 80;
MDEBUG("Connecting to " << u_c.host << ":" << port);
client.set_server(u_c.host, std::to_string(port), boost::none);
if (!client.connect(std::chrono::seconds(30)))
{
- MERROR("Failed to connect to " << url);
- return false;
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ MERROR("Failed to connect to " << control->uri);
+ control->result_cb(control->path, control->uri, control->success);
+ return;
}
MDEBUG("GETting " << u_c.uri);
const epee::net_utils::http::http_response_info *info = NULL;
if (!client.invoke_get(u_c.uri, std::chrono::seconds(30), "", &info))
{
- MERROR("Failed to connect to " << url);
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ MERROR("Failed to connect to " << control->uri);
client.disconnect();
- return false;
+ control->result_cb(control->path, control->uri, control->success);
+ return;
+ }
+ if (control->stop)
+ {
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ MDEBUG("Download cancelled");
+ client.disconnect();
+ control->result_cb(control->path, control->uri, control->success);
+ return;
}
if (!info)
{
- MERROR("Failed invoking GET command to " << url << ", no status info returned");
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ MERROR("Failed invoking GET command to " << control->uri << ", no status info returned");
client.disconnect();
- return false;
+ control->result_cb(control->path, control->uri, control->success);
+ return;
}
MDEBUG("response code: " << info->m_response_code);
+ MDEBUG("response length: " << info->m_header_info.m_content_length);
MDEBUG("response comment: " << info->m_response_comment);
MDEBUG("response body: " << info->m_body);
for (const auto &f: info->m_additional_fields)
MDEBUG("additional field: " << f.first << ": " << f.second);
if (info->m_response_code != 200)
{
+ boost::lock_guard<boost::mutex> lock(control->mutex);
MERROR("Status code " << info->m_response_code);
client.disconnect();
- return false;
+ control->result_cb(control->path, control->uri, control->success);
+ return;
}
client.disconnect();
f.close();
MDEBUG("Download complete");
- return true;
+ lock.lock();
+ control->success = true;
+ control->result_cb(control->path, control->uri, control->success);
+ return;
}
catch (const std::exception &e)
{
MERROR("Exception in download thread: " << e.what());
- return false;
+ // fall through and call result_cb not from the catch block to avoid another exception
}
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ control->result_cb(control->path, control->uri, control->success);
}
- bool download(const std::string &path, const std::string &url)
+ bool download(const std::string &path, const std::string &url, std::function<bool(const std::string&, const std::string&, size_t, ssize_t)> cb)
{
- bool success;
- std::unique_ptr<boost::thread> thread(new boost::thread([&](){ success = download_thread(path, url); }));
- thread->join();
+ bool success = false;
+ download_async_handle handle = download_async(path, url, [&success](const std::string&, const std::string&, bool result) {success = result;}, cb);
+ download_wait(handle);
return success;
}
+
+ download_async_handle download_async(const std::string &path, const std::string &url, std::function<void(const std::string&, const std::string&, bool)> result, std::function<bool(const std::string&, const std::string&, size_t, ssize_t)> progress)
+ {
+ download_async_handle control = std::make_shared<download_thread_control>(path, url, result, progress);
+ control->thread = boost::thread([control](){ download_thread(control); });
+ return control;
+ }
+
+ bool download_finished(const download_async_handle &control)
+ {
+ CHECK_AND_ASSERT_MES(control != 0, false, "NULL async download handle");
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ return control->stopped;
+ }
+
+ bool download_error(const download_async_handle &control)
+ {
+ CHECK_AND_ASSERT_MES(control != 0, false, "NULL async download handle");
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ return !control->success;
+ }
+
+ bool download_wait(const download_async_handle &control)
+ {
+ CHECK_AND_ASSERT_MES(control != 0, false, "NULL async download handle");
+ {
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ if (control->stopped)
+ return true;
+ }
+ control->thread.join();
+ return true;
+ }
+
+ bool download_cancel(const download_async_handle &control)
+ {
+ CHECK_AND_ASSERT_MES(control != 0, false, "NULL async download handle");
+ {
+ boost::lock_guard<boost::mutex> lock(control->mutex);
+ if (control->stopped)
+ return true;
+ control->stop = true;
+ }
+ control->thread.join();
+ return true;
+ }
}
diff --git a/src/common/download.h b/src/common/download.h
index ab7644689..917cb2278 100644
--- a/src/common/download.h
+++ b/src/common/download.h
@@ -32,5 +32,13 @@
namespace tools
{
- bool download(const std::string &path, const std::string &url);
+ struct download_thread_control;
+ typedef std::shared_ptr<download_thread_control> download_async_handle;
+
+ bool download(const std::string &path, const std::string &url, std::function<bool(const std::string&, const std::string&, size_t, ssize_t)> progress = NULL);
+ download_async_handle download_async(const std::string &path, const std::string &url, std::function<void(const std::string&, const std::string&, bool)> result, std::function<bool(const std::string&, const std::string&, size_t, ssize_t)> progress = NULL);
+ bool download_error(const download_async_handle &h);
+ bool download_finished(const download_async_handle &h);
+ bool download_wait(const download_async_handle &h);
+ bool download_cancel(const download_async_handle &h);
}
diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt
index db478c690..2b8ad365a 100644
--- a/src/cryptonote_basic/CMakeLists.txt
+++ b/src/cryptonote_basic/CMakeLists.txt
@@ -32,6 +32,7 @@ set(cryptonote_basic_sources
cryptonote_basic_impl.cpp
cryptonote_format_utils.cpp
difficulty.cpp
+ hardfork.cpp
miner.cpp)
set(cryptonote_basic_headers)
@@ -47,6 +48,7 @@ set(cryptonote_basic_private_headers
cryptonote_format_utils.h
cryptonote_stat_info.h
difficulty.h
+ hardfork.h
miner.h
tx_extra.h
verification_context.h)
diff --git a/src/cryptonote_core/hardfork.cpp b/src/cryptonote_basic/hardfork.cpp
index 546af2076..546af2076 100644
--- a/src/cryptonote_core/hardfork.cpp
+++ b/src/cryptonote_basic/hardfork.cpp
diff --git a/src/cryptonote_core/hardfork.h b/src/cryptonote_basic/hardfork.h
index 6c6fbcb84..6c6fbcb84 100644
--- a/src/cryptonote_core/hardfork.h
+++ b/src/cryptonote_basic/hardfork.h
diff --git a/src/cryptonote_core/CMakeLists.txt b/src/cryptonote_core/CMakeLists.txt
index 8a72dd259..5944ddcd1 100644
--- a/src/cryptonote_core/CMakeLists.txt
+++ b/src/cryptonote_core/CMakeLists.txt
@@ -30,7 +30,6 @@ set(cryptonote_core_sources
blockchain.cpp
cryptonote_core.cpp
tx_pool.cpp
- hardfork.cpp
cryptonote_tx_utils.cpp)
set(cryptonote_core_headers)
@@ -38,7 +37,6 @@ set(cryptonote_core_headers)
set(cryptonote_core_private_headers
blockchain_storage_boost_serialization.h
blockchain.h
- hardfork.h
cryptonote_core.h
tx_pool.h
cryptonote_tx_utils.h)
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index f49050918..0713274a6 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -4016,7 +4016,7 @@ void Blockchain::cancel()
static const char expected_block_hashes_hash[] = "23d8a8c73de7b2383c72a016d9a6034e69d62dd48077d1c414e064ceab6daa94";
void Blockchain::load_compiled_in_block_hashes()
{
- if (m_fast_sync && get_blocks_dat_start(m_testnet) != nullptr)
+ if (m_fast_sync && get_blocks_dat_start(m_testnet) != nullptr && get_blocks_dat_size(m_testnet) > 0)
{
MINFO("Loading precomputed blocks (" << get_blocks_dat_size(m_testnet) << " bytes)");
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 6e4ba5e2a..2c7420e18 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -51,7 +51,7 @@
#include "cryptonote_basic/verification_context.h"
#include "crypto/hash.h"
#include "cryptonote_basic/checkpoints.h"
-#include "cryptonote_core/hardfork.h"
+#include "cryptonote_basic/hardfork.h"
#include "blockchain_db/blockchain_db.h"
namespace cryptonote
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index cfe3b5441..9c5fae4ef 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -75,7 +75,8 @@ namespace cryptonote
m_target_blockchain_height(0),
m_checkpoints_path(""),
m_last_dns_checkpoints_update(0),
- m_last_json_checkpoints_update(0)
+ m_last_json_checkpoints_update(0),
+ m_update_download(0)
{
set_cryptonote_protocol(pprotocol);
}
@@ -134,6 +135,15 @@ namespace cryptonote
void core::stop()
{
m_blockchain_storage.cancel();
+
+ tools::download_async_handle handle;
+ {
+ boost::lock_guard<boost::mutex> lock(m_update_mutex);
+ handle = m_update_download;
+ m_update_download = 0;
+ }
+ if (handle)
+ tools::download_cancel(handle);
}
//-----------------------------------------------------------------------------------
void core::init_options(boost::program_options::options_description& desc)
@@ -1118,7 +1128,7 @@ namespace cryptonote
return true;
std::string url = tools::get_update_url(software, subdir, buildtag, version, true);
- MGINFO("Version " << version << " of " << software << " for " << buildtag << " is available: " << url << ", SHA256 hash " << hash);
+ MCLOG_CYAN(el::Level::Info, "global", "Version " << version << " of " << software << " for " << buildtag << " is available: " << url << ", SHA256 hash " << hash);
if (check_updates_level == UPDATES_NOTIFY)
return true;
@@ -1133,32 +1143,55 @@ namespace cryptonote
boost::filesystem::path path(epee::string_tools::get_current_module_folder());
path /= filename;
+ boost::unique_lock<boost::mutex> lock(m_update_mutex);
+
+ if (m_update_download != 0)
+ {
+ MCDEBUG("updates", "Already downloading update");
+ return true;
+ }
+
crypto::hash file_hash;
if (!tools::sha256sum(path.string(), file_hash) || (hash != epee::string_tools::pod_to_hex(file_hash)))
{
MCDEBUG("updates", "We don't have that file already, downloading");
- if (!tools::download(path.string(), url))
- {
- MCERROR("updates", "Failed to download " << url);
- return false;
- }
- if (!tools::sha256sum(path.string(), file_hash))
- {
- MCERROR("updates", "Failed to hash " << path);
- return false;
- }
- if (hash != epee::string_tools::pod_to_hex(file_hash))
- {
- MCERROR("updates", "Download from " << url << " does not match the expected hash");
- return false;
- }
- MGINFO("New version downloaded to " << path);
+ m_last_update_length = 0;
+ m_update_download = tools::download_async(path.string(), url, [this, hash](const std::string &path, const std::string &uri, bool success) {
+ if (success)
+ {
+ crypto::hash file_hash;
+ if (!tools::sha256sum(path, file_hash))
+ {
+ MCERROR("updates", "Failed to hash " << path);
+ }
+ if (hash != epee::string_tools::pod_to_hex(file_hash))
+ {
+ MCERROR("updates", "Download from " << uri << " does not match the expected hash");
+ }
+ MCLOG_CYAN(el::Level::Info, "updates", "New version downloaded to " << path);
+ }
+ else
+ {
+ MCERROR("updates", "Failed to download " << uri);
+ }
+ boost::unique_lock<boost::mutex> lock(m_update_mutex);
+ m_update_download = 0;
+ }, [this](const std::string &path, const std::string &uri, size_t length, ssize_t content_length) {
+ if (length >= m_last_update_length + 1024 * 1024 * 10)
+ {
+ m_last_update_length = length;
+ MCDEBUG("updates", "Downloaded " << length << "/" << (content_length ? std::to_string(content_length) : "unknown"));
+ }
+ return true;
+ });
}
else
{
MCDEBUG("updates", "We already have " << path << " with expected hash");
}
+ lock.unlock();
+
if (check_updates_level == UPDATES_DOWNLOAD)
return true;
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index 7323bef29..02d58691d 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -39,6 +39,7 @@
#include "p2p/net_node_common.h"
#include "cryptonote_protocol/cryptonote_protocol_handler_common.h"
#include "storages/portable_storage_template_helper.h"
+#include "common/download.h"
#include "tx_pool.h"
#include "blockchain.h"
#include "cryptonote_basic/miner.h"
@@ -844,6 +845,10 @@ namespace cryptonote
UPDATES_DOWNLOAD,
UPDATES_UPDATE,
} check_updates_level;
+
+ tools::download_async_handle m_update_download;
+ size_t m_last_update_length;
+ boost::mutex m_update_mutex;
};
}
diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp
index 80109c791..e9f95ae6b 100644
--- a/src/daemon/rpc_command_executor.cpp
+++ b/src/daemon/rpc_command_executor.cpp
@@ -34,7 +34,7 @@
#include "daemon/rpc_command_executor.h"
#include "rpc/core_rpc_server_commands_defs.h"
#include "cryptonote_core/cryptonote_core.h"
-#include "cryptonote_core/hardfork.h"
+#include "cryptonote_basic/hardfork.h"
#include <boost/format.hpp>
#include <ctime>
#include <string>
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index b114f77ae..9f7e8aa38 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -1491,8 +1491,8 @@ namespace cryptonote
bool core_rpc_server::on_update(const COMMAND_RPC_UPDATE::request& req, COMMAND_RPC_UPDATE::response& res)
{
static const char software[] = "monero";
-#ifdef BUILDTAG
- static const char buildtag[] = BOOST_PP_STRINGIZE(BUILDTAG);
+#ifdef BUILD_TAG
+ static const char buildtag[] = BOOST_PP_STRINGIZE(BUILD_TAG);
#else
static const char buildtag[] = "source";
#endif
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 4b5a36c83..727103fa8 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -380,9 +380,9 @@ bool simple_wallet::change_password(const std::vector<std::string> &args)
return false;
}
- // prompts for a new password, this is not a new wallet so pass in false.
- const auto pwd_container = tools::wallet2::password_prompt(false);
-
+ // prompts for a new password, pass true to verify the password
+ const auto pwd_container = tools::wallet2::password_prompt(true);
+
try
{
m_wallet->rewrite(m_wallet_file, pwd_container->password());
@@ -676,6 +676,7 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("export_outputs", boost::bind(&simple_wallet::export_outputs, this, _1), tr("Export a set of outputs owned by this wallet"));
m_cmd_binder.set_handler("import_outputs", boost::bind(&simple_wallet::import_outputs, this, _1), tr("Import set of outputs owned by this wallet"));
m_cmd_binder.set_handler("show_transfer", boost::bind(&simple_wallet::show_transfer, this, _1), tr("Show information about a transfer to/from this address"));
+ m_cmd_binder.set_handler("password", boost::bind(&simple_wallet::change_password, this, _1), tr("Change wallet password"));
m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), tr("Show this help"));
}
//----------------------------------------------------------------------------------------------------
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index bc182e04b..7ae2ce074 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -452,10 +452,10 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
command_line::add_arg(desc_params, opts.restricted);
}
-boost::optional<password_container> wallet2::password_prompt(const bool is_new_wallet)
+boost::optional<password_container> wallet2::password_prompt(const bool new_password)
{
auto pwd_container = tools::password_container::prompt(
- is_new_wallet, (is_new_wallet ? tr("Enter a password for your new wallet") : tr("Wallet password"))
+ new_password, (new_password ? tr("Enter new wallet password") : tr("Wallet password"))
);
if (!pwd_container)
{
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index a074bfc37..ddc237f1b 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -114,7 +114,7 @@ namespace tools
static void init_options(boost::program_options::options_description& desc_params);
//! \return Password retrieved from prompt. Logs error on failure.
- static boost::optional<password_container> password_prompt(const bool is_new_wallet);
+ static boost::optional<password_container> password_prompt(const bool new_password);
//! Uses stdin and stdout. Returns a wallet2 if no errors.
static std::unique_ptr<wallet2> make_from_json(const boost::program_options::variables_map& vm, const std::string& json_file);