aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blockchain_utilities/CMakeLists.txt22
-rw-r--r--src/blockchain_utilities/blockchain_blackball.cpp57
-rw-r--r--src/blockchain_utilities/blockchain_import.cpp8
-rw-r--r--src/blocks/CMakeLists.txt35
-rw-r--r--src/blocks/blockexports.c87
-rw-r--r--src/blocks/blocks.cpp31
-rw-r--r--src/blocks/blocks.dat0
-rw-r--r--src/blocks/blocks.h14
-rw-r--r--src/common/expect.h4
-rw-r--r--src/common/password.cpp15
-rw-r--r--src/common/spawn.cpp3
-rw-r--r--src/common/threadpool.cpp10
-rw-r--r--src/common/util.cpp22
-rw-r--r--src/common/util.h2
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.cpp10
-rw-r--r--src/cryptonote_basic/cryptonote_format_utils.h1
-rw-r--r--src/cryptonote_basic/miner.cpp2
-rw-r--r--src/cryptonote_config.h1
-rw-r--r--src/cryptonote_core/CMakeLists.txt7
-rw-r--r--src/cryptonote_core/blockchain.cpp36
-rw-r--r--src/cryptonote_core/blockchain.h18
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp11
-rw-r--r--src/cryptonote_core/cryptonote_core.h3
-rw-r--r--src/cryptonote_core/tx_pool.cpp51
-rw-r--r--src/cryptonote_core/tx_pool.h13
-rw-r--r--src/daemon/CMakeLists.txt21
-rw-r--r--src/daemon/core.h8
-rw-r--r--src/daemon/daemon.cpp14
-rw-r--r--src/daemonizer/windows_daemonizer.inl1
-rw-r--r--src/debug_utilities/object_sizes.cpp1
-rw-r--r--src/device/CMakeLists.txt7
-rw-r--r--src/device/device.cpp25
-rw-r--r--src/device/device_io_hid.cpp56
-rw-r--r--src/device/device_io_hid.hpp20
-rw-r--r--src/device/device_ledger.cpp13
-rw-r--r--src/p2p/net_node.cpp1
-rw-r--r--src/p2p/net_node.inl6
-rw-r--r--src/rpc/core_rpc_server.cpp18
-rw-r--r--src/serialization/serialization.h23
-rw-r--r--src/simplewallet/simplewallet.cpp38
-rw-r--r--src/version.cpp.in2
-rw-r--r--src/wallet/api/wallet.cpp8
-rw-r--r--src/wallet/ringdb.cpp4
-rw-r--r--src/wallet/wallet2.cpp29
-rw-r--r--src/wallet/wallet_rpc_server.cpp3
-rw-r--r--src/wallet/wallet_rpc_server.h1
46 files changed, 486 insertions, 276 deletions
diff --git a/src/blockchain_utilities/CMakeLists.txt b/src/blockchain_utilities/CMakeLists.txt
index 873bf552c..24a750eb0 100644
--- a/src/blockchain_utilities/CMakeLists.txt
+++ b/src/blockchain_utilities/CMakeLists.txt
@@ -26,6 +26,20 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+set(blocksdat "")
+if(PER_BLOCK_CHECKPOINT)
+ if(APPLE AND DEPENDS)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} --target=x86_64-apple-darwin11 -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*)
+ elseif(APPLE AND NOT DEPENDS)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*)
+ elseif(LINUX_32)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat)
+ else()
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat)
+ endif()
+ set(blocksdat "blocksdat.o")
+endif()
+
set(blockchain_import_sources
blockchain_import.cpp
bootstrap_file.cpp
@@ -105,7 +119,8 @@ monero_private_headers(blockchain_depth
monero_add_executable(blockchain_import
${blockchain_import_sources}
- ${blockchain_import_private_headers})
+ ${blockchain_import_private_headers}
+ ${blocksdat})
target_link_libraries(blockchain_import
PRIVATE
@@ -117,8 +132,7 @@ target_link_libraries(blockchain_import
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
${CMAKE_THREAD_LIBS_INIT}
- ${EXTRA_LIBRARIES}
- ${Blocks})
+ ${EXTRA_LIBRARIES})
if(ARCH_WIDTH)
target_compile_definitions(blockchain_import
@@ -170,7 +184,7 @@ target_link_libraries(blockchain_blackball
set_property(TARGET blockchain_blackball
PROPERTY
- OUTPUT_NAME "monero-blockchain-blackball")
+ OUTPUT_NAME "monero-blockchain-mark-spent-outputs")
install(TARGETS blockchain_blackball DESTINATION bin)
diff --git a/src/blockchain_utilities/blockchain_blackball.cpp b/src/blockchain_utilities/blockchain_blackball.cpp
index 5eb2acc79..d2ce5cf76 100644
--- a/src/blockchain_utilities/blockchain_blackball.cpp
+++ b/src/blockchain_utilities/blockchain_blackball.cpp
@@ -226,7 +226,7 @@ static void init(std::string cache_filename)
bool tx_active = false;
int dbr;
- MINFO("Creating blackball cache in " << cache_filename);
+ MINFO("Creating spent output cache in " << cache_filename);
tools::create_directories_if_necessary(cache_filename);
@@ -536,12 +536,15 @@ static uint64_t get_num_spent_outputs()
return count;
}
-static void add_spent_output(MDB_cursor *cur, const output_data &od)
+static bool add_spent_output(MDB_cursor *cur, const output_data &od)
{
MDB_val k = {sizeof(od.amount), (void*)&od.amount};
MDB_val v = {sizeof(od.offset), (void*)&od.offset};
- int dbr = mdb_cursor_put(cur, &k, &v, 0);
- CHECK_AND_ASSERT_THROW_MES(!dbr || dbr == MDB_KEYEXIST, "Failed to add spent output: " + std::string(mdb_strerror(dbr)));
+ int dbr = mdb_cursor_put(cur, &k, &v, MDB_NODUPDATA);
+ if (dbr == MDB_KEYEXIST)
+ return false;
+ CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to add spent output: " + std::string(mdb_strerror(dbr)));
+ return true;
}
static bool is_output_spent(MDB_cursor *cur, const output_data &od)
@@ -1016,7 +1019,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_blackball_db_dir = {
- "blackball-db-dir", "Specify blackball database directory",
+ "spent-output-db-dir", "Specify spent output database directory",
get_default_db_path(),
};
const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""};
@@ -1073,7 +1076,7 @@ int main(int argc, char* argv[])
return 1;
}
- mlog_configure(mlog_get_default_log_path("monero-blockchain-blackball.log"), true);
+ mlog_configure(mlog_get_default_log_path("monero-blockchain-find-spent-outputs.log"), true);
if (!command_line::is_arg_defaulted(vm, arg_log_level))
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
else
@@ -1111,10 +1114,10 @@ int main(int argc, char* argv[])
return 1;
}
- const std::string cache_dir = (output_file_path / "blackball-cache").string();
+ const std::string cache_dir = (output_file_path / "spent-outputs-cache").string();
init(cache_dir);
- LOG_PRINT_L0("Scanning for blackballable outputs...");
+ LOG_PRINT_L0("Scanning for spent outputs...");
size_t done = 0;
@@ -1153,8 +1156,8 @@ int main(int argc, char* argv[])
if (!is_output_spent(cur, output_data(output.first, output.second)))
{
blackballs.push_back(output);
- add_spent_output(cur, output_data(output.first, output.second));
- inc_stat(txn, output.first ? "pre-rct-extra" : "rct-ring-extra");
+ if (add_spent_output(cur, output_data(output.first, output.second)))
+ inc_stat(txn, output.first ? "pre-rct-extra" : "rct-ring-extra");
}
}
if (!blackballs.empty())
@@ -1212,12 +1215,12 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, absolute[0]);
if (opt_verbose)
{
- MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in a 1-ring");
+ MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in a 1-ring");
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
}
blackballs.push_back(output);
- add_spent_output(cur, output_data(txin.amount, absolute[0]));
- inc_stat(txn, txin.amount ? "pre-rct-ring-size-1" : "rct-ring-size-1");
+ if (add_spent_output(cur, output_data(txin.amount, absolute[0])))
+ inc_stat(txn, txin.amount ? "pre-rct-ring-size-1" : "rct-ring-size-1");
}
else if (n == 0 && instances == new_ring.size())
{
@@ -1226,12 +1229,12 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, absolute[o]);
if (opt_verbose)
{
- MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in " << new_ring.size() << " identical " << new_ring.size() << "-rings");
+ MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in " << new_ring.size() << " identical " << new_ring.size() << "-rings");
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
}
blackballs.push_back(output);
- add_spent_output(cur, output_data(txin.amount, absolute[o]));
- inc_stat(txn, txin.amount ? "pre-rct-duplicate-rings" : "rct-duplicate-rings");
+ if (add_spent_output(cur, output_data(txin.amount, absolute[o])))
+ inc_stat(txn, txin.amount ? "pre-rct-duplicate-rings" : "rct-duplicate-rings");
}
}
else if (n == 0 && opt_check_subsets && get_ring_subset_instances(txn, txin.amount, new_ring) >= new_ring.size())
@@ -1241,12 +1244,12 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, absolute[o]);
if (opt_verbose)
{
- MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in " << new_ring.size() << " subsets of " << new_ring.size() << "-rings");
+ MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in " << new_ring.size() << " subsets of " << new_ring.size() << "-rings");
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
}
blackballs.push_back(output);
- add_spent_output(cur, output_data(txin.amount, absolute[o]));
- inc_stat(txn, txin.amount ? "pre-rct-subset-rings" : "rct-subset-rings");
+ if (add_spent_output(cur, output_data(txin.amount, absolute[o])))
+ inc_stat(txn, txin.amount ? "pre-rct-subset-rings" : "rct-subset-rings");
}
}
else if (n > 0 && get_relative_ring(txn, txin.k_image, relative_ring))
@@ -1277,12 +1280,12 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, common[0]);
if (opt_verbose)
{
- MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in rings with a single common element");
+ MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in rings with a single common element");
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
}
blackballs.push_back(output);
- add_spent_output(cur, output_data(txin.amount, common[0]));
- inc_stat(txn, txin.amount ? "pre-rct-key-image-attack" : "rct-key-image-attack");
+ if (add_spent_output(cur, output_data(txin.amount, common[0])))
+ inc_stat(txn, txin.amount ? "pre-rct-key-image-attack" : "rct-key-image-attack");
}
else
{
@@ -1389,13 +1392,13 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(od.amount, last_unknown);
if (opt_verbose)
{
- MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in a " <<
+ MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in a " <<
absolute.size() << "-ring where all other outputs are known to be spent");
}
blackballs.push_back(output);
- add_spent_output(cur, output_data(od.amount, last_unknown));
+ if (add_spent_output(cur, output_data(od.amount, last_unknown)))
+ inc_stat(txn, od.amount ? "pre-rct-chain-reaction" : "rct-chain-reaction");
work_spent.push_back(output_data(od.amount, last_unknown));
- inc_stat(txn, od.amount ? "pre-rct-chain-reaction" : "rct-chain-reaction");
}
}
@@ -1417,7 +1420,7 @@ int main(int argc, char* argv[])
skip_secondary_passes:
uint64_t diff = get_num_spent_outputs() - start_blackballed_outputs;
- LOG_PRINT_L0(std::to_string(diff) << " new outputs blackballed, " << get_num_spent_outputs() << " total outputs blackballed");
+ LOG_PRINT_L0(std::to_string(diff) << " new outputs marked as spent, " << get_num_spent_outputs() << " total outputs marked as spent");
MDB_txn *txn;
dbr = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
@@ -1457,7 +1460,7 @@ skip_secondary_passes:
mdb_txn_abort(txn);
}
- LOG_PRINT_L0("Blockchain blackball data exported OK");
+ LOG_PRINT_L0("Blockchain spent output data exported OK");
close_db(env0, txn0, cur0, dbi0);
close();
return 0;
diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp
index 134969dc4..9ec768d26 100644
--- a/src/blockchain_utilities/blockchain_import.cpp
+++ b/src/blockchain_utilities/blockchain_import.cpp
@@ -37,7 +37,6 @@
#include "misc_log_ex.h"
#include "bootstrap_file.h"
#include "bootstrap_serialization.h"
-#include "blocks/blocks.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "serialization/binary_utils.h" // dump_binary(), parse_binary()
#include "serialization/json_utils.h" // dump_json()
@@ -759,12 +758,7 @@ int main(int argc, char* argv[])
{
core.disable_dns_checkpoints(true);
-#if defined(PER_BLOCK_CHECKPOINT)
- GetCheckpointsCallback get_checkpoints = blocks::GetCheckpointsData;
-#else
- GetCheckpointsCallback get_checkpoints = nullptr;
-#endif
- if (!core.init(vm, nullptr, nullptr, get_checkpoints))
+ if (!core.init(vm, NULL))
{
std::cerr << "Failed to initialize core" << ENDL;
return 1;
diff --git a/src/blocks/CMakeLists.txt b/src/blocks/CMakeLists.txt
index bedda3b88..ebb5408cc 100644
--- a/src/blocks/CMakeLists.txt
+++ b/src/blocks/CMakeLists.txt
@@ -26,23 +26,20 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-set(GENERATED_SOURCES "")
+if(APPLE)
+ add_library(blocks STATIC blockexports.c)
+ set_target_properties(blocks PROPERTIES LINKER_LANGUAGE C)
+else()
+ if(LINUX_32)
+ add_custom_command(OUTPUT blocks.o MAIN_DEPENDENCY blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocks.o blocks.dat)
+ add_custom_command(OUTPUT testnet_blocks.o MAIN_DEPENDENCY testnet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/testnet_blocks.o testnet_blocks.dat)
+ add_custom_command(OUTPUT stagenet_blocks.o MAIN_DEPENDENCY stagenet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/stagenet_blocks.o stagenet_blocks.dat)
+ else()
+ add_custom_command(OUTPUT blocks.o MAIN_DEPENDENCY blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocks.o blocks.dat)
+ add_custom_command(OUTPUT testnet_blocks.o MAIN_DEPENDENCY testnet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/testnet_blocks.o testnet_blocks.dat)
+ add_custom_command(OUTPUT stagenet_blocks.o MAIN_DEPENDENCY stagenet_blocks.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/stagenet_blocks.o stagenet_blocks.dat)
+ endif()
+ add_library(blocks STATIC blocks.o testnet_blocks.o stagenet_blocks.o blockexports.c)
+ set_target_properties(blocks PROPERTIES LINKER_LANGUAGE C)
+endif()
-foreach(BLOB_NAME checkpoints testnet_blocks stagenet_blocks)
- set(OUTPUT_C_SOURCE "generated_${BLOB_NAME}.c")
- list(APPEND GENERATED_SOURCES ${OUTPUT_C_SOURCE})
- set(INPUT_DAT_FILE "${BLOB_NAME}.dat")
- add_custom_command(
- OUTPUT ${OUTPUT_C_SOURCE}
- MAIN_DEPENDENCY ${INPUT_DAT_FILE}
- COMMAND
- cd ${CMAKE_CURRENT_BINARY_DIR} &&
- echo "'#include\t<stddef.h>'" > ${OUTPUT_C_SOURCE} &&
- echo -n "'const\tunsigned\tchar\t${BLOB_NAME}[]={'" >> ${OUTPUT_C_SOURCE} &&
- od -v -An -w1 -tu1 ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE} | sed -e "':a;N;$$!ba;s/\\n/,/g'" >> ${OUTPUT_C_SOURCE} &&
- echo "'};'" >> ${OUTPUT_C_SOURCE} &&
- echo "'const\tsize_t\t${BLOB_NAME}_len\t=\tsizeof(${BLOB_NAME});'" >> ${OUTPUT_C_SOURCE}
- )
-endforeach()
-
-add_library(blocks STATIC blocks.cpp ${GENERATED_SOURCES})
diff --git a/src/blocks/blockexports.c b/src/blocks/blockexports.c
new file mode 100644
index 000000000..0154b0413
--- /dev/null
+++ b/src/blocks/blockexports.c
@@ -0,0 +1,87 @@
+#include <stddef.h>
+
+#if defined(__APPLE__)
+#include <mach-o/getsect.h>
+#ifdef BUILD_SHARED_LIBS
+#if !defined(__LP64__)
+const struct mach_header _mh_execute_header;
+#else
+const struct mach_header_64 _mh_execute_header;
+#endif
+#else
+#if !defined(__LP64__)
+extern const struct mach_header _mh_execute_header;
+#else
+extern const struct mach_header_64 _mh_execute_header;
+#endif
+#endif
+
+const unsigned char *get_blocks_dat_start(int testnet, int stagenet)
+{
+ size_t size;
+ if (testnet)
+ return getsectiondata(&_mh_execute_header, "__DATA", "__testnet_blocks_dat", &size);
+ else if (stagenet)
+ return getsectiondata(&_mh_execute_header, "__DATA", "__stagenet_blocks_dat", &size);
+ else
+ return getsectiondata(&_mh_execute_header, "__DATA", "__blocks_dat", &size);
+}
+
+size_t get_blocks_dat_size(int testnet, int stagenet)
+{
+ size_t size;
+ if (testnet)
+ getsectiondata(&_mh_execute_header, "__DATA", "__testnet_blocks_dat", &size);
+ else if (stagenet)
+ getsectiondata(&_mh_execute_header, "__DATA", "__stagenet_blocks_dat", &size);
+ else
+ getsectiondata(&_mh_execute_header, "__DATA", "__blocks_dat", &size);
+ return size;
+}
+
+#else
+
+#if defined(_WIN32) && !defined(_WIN64)
+#define _binary_blocks_start binary_blocks_dat_start
+#define _binary_blocks_end binary_blocks_dat_end
+#define _binary_testnet_blocks_start binary_testnet_blocks_dat_start
+#define _binary_testnet_blocks_end binary_testnet_blocks_dat_end
+#define _binary_stagenet_blocks_start binary_stagenet_blocks_dat_start
+#define _binary_stagenet_blocks_end binary_stagenet_blocks_dat_end
+#else
+#define _binary_blocks_start _binary_blocks_dat_start
+#define _binary_blocks_end _binary_blocks_dat_end
+#define _binary_testnet_blocks_start _binary_testnet_blocks_dat_start
+#define _binary_testnet_blocks_end _binary_testnet_blocks_dat_end
+#define _binary_stagenet_blocks_start _binary_stagenet_blocks_dat_start
+#define _binary_stagenet_blocks_end _binary_stagenet_blocks_dat_end
+#endif
+
+extern const unsigned char _binary_blocks_start[];
+extern const unsigned char _binary_blocks_end[];
+extern const unsigned char _binary_testnet_blocks_start[];
+extern const unsigned char _binary_testnet_blocks_end[];
+extern const unsigned char _binary_stagenet_blocks_start[];
+extern const unsigned char _binary_stagenet_blocks_end[];
+
+const unsigned char *get_blocks_dat_start(int testnet, int stagenet)
+{
+ if (testnet)
+ return _binary_testnet_blocks_start;
+ else if (stagenet)
+ return _binary_stagenet_blocks_start;
+ else
+ return _binary_blocks_start;
+}
+
+size_t get_blocks_dat_size(int testnet, int stagenet)
+{
+ if (testnet)
+ return (size_t) (_binary_testnet_blocks_end - _binary_testnet_blocks_start);
+ else if (stagenet)
+ return (size_t) (_binary_stagenet_blocks_end - _binary_stagenet_blocks_start);
+ else
+ return (size_t) (_binary_blocks_end - _binary_blocks_start);
+}
+
+#endif
diff --git a/src/blocks/blocks.cpp b/src/blocks/blocks.cpp
deleted file mode 100644
index 0661f8448..000000000
--- a/src/blocks/blocks.cpp
+++ /dev/null
@@ -1,31 +0,0 @@
-#include "blocks.h"
-
-#include <unordered_map>
-
-extern const unsigned char checkpoints[];
-extern const size_t checkpoints_len;
-extern const unsigned char stagenet_blocks[];
-extern const size_t stagenet_blocks_len;
-extern const unsigned char testnet_blocks[];
-extern const size_t testnet_blocks_len;
-
-namespace blocks
-{
-
- const std::unordered_map<cryptonote::network_type, const epee::span<const unsigned char>, std::hash<size_t>> CheckpointsByNetwork = {
- {cryptonote::network_type::MAINNET, {checkpoints, checkpoints_len}},
- {cryptonote::network_type::STAGENET, {stagenet_blocks, stagenet_blocks_len}},
- {cryptonote::network_type::TESTNET, {testnet_blocks, testnet_blocks_len}}
- };
-
- const epee::span<const unsigned char> GetCheckpointsData(cryptonote::network_type network)
- {
- const auto it = CheckpointsByNetwork.find(network);
- if (it != CheckpointsByNetwork.end())
- {
- return it->second;
- }
- return nullptr;
- }
-
-}
diff --git a/src/blocks/blocks.dat b/src/blocks/blocks.dat
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/src/blocks/blocks.dat
diff --git a/src/blocks/blocks.h b/src/blocks/blocks.h
index 14e391319..ec683f47e 100644
--- a/src/blocks/blocks.h
+++ b/src/blocks/blocks.h
@@ -1,12 +1,16 @@
#ifndef SRC_BLOCKS_BLOCKS_H_
#define SRC_BLOCKS_BLOCKS_H_
-#include "cryptonote_config.h"
-#include "span.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
-namespace blocks
-{
- const epee::span<const unsigned char> GetCheckpointsData(cryptonote::network_type network);
+const unsigned char *get_blocks_dat_start(int testnet, int stagenet);
+size_t get_blocks_dat_size(int testnet, int stagenet);
+
+#ifdef __cplusplus
}
+#endif
+
#endif /* SRC_BLOCKS_BLOCKS_H_ */
diff --git a/src/common/expect.h b/src/common/expect.h
index 326242502..72e4060a7 100644
--- a/src/common/expect.h
+++ b/src/common/expect.h
@@ -350,7 +350,9 @@ public:
using error_type = std::error_code;
//! Create a successful object.
- expect() = default;
+ expect() noexcept
+ : code_()
+ {}
expect(std::error_code const& code) noexcept
: code_(code)
diff --git a/src/common/password.cpp b/src/common/password.cpp
index a8d5141dc..b3c51128f 100644
--- a/src/common/password.cpp
+++ b/src/common/password.cpp
@@ -60,7 +60,7 @@ namespace
DWORD mode_old;
::GetConsoleMode(h_cin, &mode_old);
- DWORD mode_new = mode_old & ~((hide_input ? ENABLE_ECHO_INPUT : 0) | ENABLE_LINE_INPUT);
+ DWORD mode_new = mode_old & ~(hide_input ? ENABLE_ECHO_INPUT : 0);
::SetConsoleMode(h_cin, mode_new);
bool r = true;
@@ -78,7 +78,11 @@ namespace
{
break;
}
- else if (ucs2_ch == L'\n' || ucs2_ch == L'\r')
+ else if (ucs2_ch == L'\r')
+ {
+ continue;
+ }
+ else if (ucs2_ch == L'\n')
{
std::cout << std::endl;
break;
@@ -158,6 +162,13 @@ namespace
if (!aPass.empty())
{
aPass.pop_back();
+ if (!hide_input)
+ std::cout << "\b\b\b \b\b\b" << std::flush;
+ }
+ else
+ {
+ if (!hide_input)
+ std::cout << "\b\b \b\b" << std::flush;
}
}
else
diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp
index 59f11675c..0a2ce8387 100644
--- a/src/common/spawn.cpp
+++ b/src/common/spawn.cpp
@@ -38,6 +38,7 @@
#endif
#include "misc_log_ex.h"
+#include "util.h"
#include "spawn.h"
namespace tools
@@ -101,6 +102,8 @@ int spawn(const char *filename, const std::vector<std::string>& args, bool wait)
// child
if (pid == 0)
{
+ tools::closefrom(3);
+ close(0);
char *envp[] = {NULL};
execve(filename, argv, envp);
MERROR("Failed to execve: " << strerror(errno));
diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp
index 5ea04a353..37825e31d 100644
--- a/src/common/threadpool.cpp
+++ b/src/common/threadpool.cpp
@@ -51,11 +51,19 @@ threadpool::threadpool(unsigned int max_threads) : running(true), active(0) {
}
threadpool::~threadpool() {
+ try
{
const boost::unique_lock<boost::mutex> lock(mutex);
running = false;
has_work.notify_all();
}
+ catch (...)
+ {
+ // if the lock throws, we're just do it without a lock and hope,
+ // since the alternative is terminate
+ running = false;
+ has_work.notify_all();
+ }
for (size_t i = 0; i<threads.size(); i++) {
try { threads[i].join(); }
catch (...) { /* ignore */ }
@@ -91,11 +99,13 @@ unsigned int threadpool::get_max_concurrency() const {
threadpool::waiter::~waiter()
{
+ try
{
boost::unique_lock<boost::mutex> lock(mt);
if (num)
MERROR("wait should have been called before waiter dtor - waiting now");
}
+ catch (...) { /* ignore */ }
try
{
wait(NULL);
diff --git a/src/common/util.cpp b/src/common/util.cpp
index 2a1d49af0..f91230528 100644
--- a/src/common/util.cpp
+++ b/src/common/util.cpp
@@ -28,6 +28,7 @@
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
+#include <unistd.h>
#include <cstdio>
#ifdef __GLIBC__
@@ -233,7 +234,7 @@ namespace tools
MERROR("Failed to open " << filename << ": " << std::error_code(GetLastError(), std::system_category()));
}
#else
- m_fd = open(filename.c_str(), O_RDONLY | O_CREAT, 0666);
+ m_fd = open(filename.c_str(), O_RDONLY | O_CREAT | O_CLOEXEC, 0666);
if (m_fd != -1)
{
if (flock(m_fd, LOCK_EX | LOCK_NB) == -1)
@@ -967,4 +968,23 @@ std::string get_nix_version_display_string()
}
#endif
+ void closefrom(int fd)
+ {
+#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
+ ::closefrom(fd);
+#else
+#if defined __GLIBC__
+ const int sc_open_max = sysconf(_SC_OPEN_MAX);
+ const int MAX_FDS = std::min(65536, sc_open_max);
+#else
+ const int MAX_FDS = 65536;
+#endif
+ while (fd < MAX_FDS)
+ {
+ close(fd);
+ ++fd;
+ }
+#endif
+ }
+
}
diff --git a/src/common/util.h b/src/common/util.h
index ce773bd38..e793a42b5 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -238,4 +238,6 @@ namespace tools
#ifdef _WIN32
std::string input_line_win();
#endif
+
+ void closefrom(int fd);
}
diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp
index 5fcfa33f6..9e9c12605 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.cpp
+++ b/src/cryptonote_basic/cryptonote_format_utils.cpp
@@ -199,6 +199,16 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------
+ bool parse_and_validate_tx_prefix_from_blob(const blobdata& tx_blob, transaction_prefix& tx)
+ {
+ std::stringstream ss;
+ ss << tx_blob;
+ binary_archive<false> ba(ss);
+ bool r = ::serialization::serialize_noeof(ba, tx);
+ CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction prefix from blob");
+ return true;
+ }
+ //---------------------------------------------------------------
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash)
{
std::stringstream ss;
diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h
index bf71eb591..725c75f4e 100644
--- a/src/cryptonote_basic/cryptonote_format_utils.h
+++ b/src/cryptonote_basic/cryptonote_format_utils.h
@@ -48,6 +48,7 @@ namespace cryptonote
//---------------------------------------------------------------
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h);
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx);
+ bool parse_and_validate_tx_prefix_from_blob(const blobdata& tx_blob, transaction_prefix& tx);
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash);
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx);
bool parse_and_validate_tx_base_from_blob(const blobdata& tx_blob, transaction& tx);
diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp
index 2bd43de94..d0b03593e 100644
--- a/src/cryptonote_basic/miner.cpp
+++ b/src/cryptonote_basic/miner.cpp
@@ -201,7 +201,7 @@ namespace cryptonote
float hr = static_cast<float>(total_hr)/static_cast<float>(m_last_hash_rates.size());
const auto flags = std::cout.flags();
const auto precision = std::cout.precision();
- std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << flags << precision << ENDL;
+ std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << std::setiosflags(flags) << std::setprecision(precision) << ENDL;
}
}
m_last_hr_merge_time = misc_utils::get_tick_count();
diff --git a/src/cryptonote_config.h b/src/cryptonote_config.h
index c62eeb738..a6858ce7c 100644
--- a/src/cryptonote_config.h
+++ b/src/cryptonote_config.h
@@ -30,7 +30,6 @@
#pragma once
-#include <stdexcept>
#include <string>
#include <boost/uuid/uuid.hpp>
diff --git a/src/cryptonote_core/CMakeLists.txt b/src/cryptonote_core/CMakeLists.txt
index 231489fdb..72844db66 100644
--- a/src/cryptonote_core/CMakeLists.txt
+++ b/src/cryptonote_core/CMakeLists.txt
@@ -41,6 +41,12 @@ set(cryptonote_core_private_headers
tx_pool.h
cryptonote_tx_utils.h)
+if(PER_BLOCK_CHECKPOINT)
+ set(Blocks "blocks")
+else()
+ set(Blocks "")
+endif()
+
monero_private_headers(cryptonote_core
${cryptonote_core_private_headers})
monero_add_library(cryptonote_core
@@ -63,4 +69,5 @@ target_link_libraries(cryptonote_core
${Boost_SYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
PRIVATE
+ ${Blocks}
${EXTRA_LIBRARIES})
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 6c6e024e4..1ec2366e4 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -53,6 +53,9 @@
#include "ringct/rctSigs.h"
#include "common/perf_timer.h"
#include "common/notify.h"
+#if defined(PER_BLOCK_CHECKPOINT)
+#include "blocks/blocks.h"
+#endif
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "blockchain"
@@ -338,9 +341,12 @@ uint64_t Blockchain::get_current_blockchain_height() const
//------------------------------------------------------------------
//FIXME: possibly move this into the constructor, to avoid accidentally
// dereferencing a null BlockchainDB pointer
-bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline, const cryptonote::test_options *test_options, difficulty_type fixed_difficulty, const GetCheckpointsCallback get_checkpoints/* = nullptr*/)
+bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline, const cryptonote::test_options *test_options, difficulty_type fixed_difficulty)
{
LOG_PRINT_L3("Blockchain::" << __func__);
+
+ CHECK_AND_ASSERT_MES(nettype != FAKECHAIN || test_options, false, "fake chain network type used without options");
+
CRITICAL_REGION_LOCAL(m_tx_pool);
CRITICAL_REGION_LOCAL1(m_blockchain_lock);
@@ -436,7 +442,7 @@ bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline
#if defined(PER_BLOCK_CHECKPOINT)
if (m_nettype != FAKECHAIN)
- load_compiled_in_block_hashes(get_checkpoints);
+ load_compiled_in_block_hashes();
#endif
MINFO("Blockchain initialized. last block: " << m_db->height() - 1 << ", " << epee::misc_utils::get_time_interval_string(timestamp_diff) << " time ago, current difficulty: " << get_difficulty_for_next_block());
@@ -2361,7 +2367,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
const bool bulletproof = rct::is_rct_bulletproof(tx.rct_signatures.type);
if (bulletproof || !tx.rct_signatures.p.bulletproofs.empty())
{
- MERROR("Bulletproofs are not allowed before v8");
+ MERROR_VER("Bulletproofs are not allowed before v8");
tvc.m_invalid_output = true;
return false;
}
@@ -2374,7 +2380,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
const bool borromean = rct::is_rct_borromean(tx.rct_signatures.type);
if (borromean)
{
- MERROR("Borromean range proofs are not allowed after v8");
+ MERROR_VER("Borromean range proofs are not allowed after v8");
tvc.m_invalid_output = true;
return false;
}
@@ -4401,21 +4407,19 @@ void Blockchain::cancel()
#if defined(PER_BLOCK_CHECKPOINT)
static const char expected_block_hashes_hash[] = "954cb2bbfa2fe6f74b2cdd22a1a4c767aea249ad47ad4f7c9445f0f03260f511";
-void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback get_checkpoints)
+void Blockchain::load_compiled_in_block_hashes()
{
- if (get_checkpoints == nullptr || !m_fast_sync)
+ const bool testnet = m_nettype == TESTNET;
+ const bool stagenet = m_nettype == STAGENET;
+ if (m_fast_sync && get_blocks_dat_start(testnet, stagenet) != nullptr && get_blocks_dat_size(testnet, stagenet) > 0)
{
- return;
- }
- const epee::span<const unsigned char> checkpoints = get_checkpoints(m_nettype);
- if (!checkpoints.empty())
- {
- MINFO("Loading precomputed blocks (" << checkpoints.size() << " bytes)");
+ MINFO("Loading precomputed blocks (" << get_blocks_dat_size(testnet, stagenet) << " bytes)");
+
if (m_nettype == MAINNET)
{
// first check hash
crypto::hash hash;
- if (!tools::sha256sum(checkpoints.data(), checkpoints.size(), hash))
+ if (!tools::sha256sum(get_blocks_dat_start(testnet, stagenet), get_blocks_dat_size(testnet, stagenet), hash))
{
MERROR("Failed to hash precomputed blocks data");
return;
@@ -4435,9 +4439,9 @@ void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback get_
}
}
- if (checkpoints.size() > 4)
+ if (get_blocks_dat_size(testnet, stagenet) > 4)
{
- const unsigned char *p = checkpoints.data();
+ const unsigned char *p = get_blocks_dat_start(testnet, stagenet);
const uint32_t nblocks = *p | ((*(p+1))<<8) | ((*(p+2))<<16) | ((*(p+3))<<24);
if (nblocks > (std::numeric_limits<uint32_t>::max() - 4) / sizeof(hash))
{
@@ -4445,7 +4449,7 @@ void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback get_
return;
}
const size_t size_needed = 4 + nblocks * sizeof(crypto::hash);
- if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP && checkpoints.size() >= size_needed)
+ if(nblocks > 0 && nblocks > (m_db->height() + HASH_OF_HASHES_STEP - 1) / HASH_OF_HASHES_STEP && get_blocks_dat_size(testnet, stagenet) >= size_needed)
{
p += sizeof(uint32_t);
m_blocks_hash_of_hashes.reserve(nblocks);
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index 9b67765b5..ab66fac8b 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -38,11 +38,9 @@
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <atomic>
-#include <functional>
#include <unordered_map>
#include <unordered_set>
-#include "span.h"
#include "syncobj.h"
#include "string_tools.h"
#include "cryptonote_basic/cryptonote_basic.h"
@@ -75,15 +73,6 @@ namespace cryptonote
db_nosync //!< Leave syncing up to the backing db (safest, but slowest because of disk I/O)
};
- /**
- * @brief Callback routine that returns checkpoints data for specific network type
- *
- * @param network network type
- *
- * @return checkpoints data, empty span if there ain't any checkpoints for specific network type
- */
- typedef std::function<const epee::span<const unsigned char>(cryptonote::network_type network)> GetCheckpointsCallback;
-
/************************************************************************/
/* */
/************************************************************************/
@@ -128,11 +117,10 @@ namespace cryptonote
* @param offline true if running offline, else false
* @param test_options test parameters
* @param fixed_difficulty fixed difficulty for testing purposes; 0 means disabled
- * @param get_checkpoints if set, will be called to get checkpoints data
*
* @return true on success, false if any initialization steps fail
*/
- bool init(BlockchainDB* db, const network_type nettype = MAINNET, bool offline = false, const cryptonote::test_options *test_options = NULL, difficulty_type fixed_difficulty = 0, const GetCheckpointsCallback get_checkpoints = nullptr);
+ bool init(BlockchainDB* db, const network_type nettype = MAINNET, bool offline = false, const cryptonote::test_options *test_options = NULL, difficulty_type fixed_difficulty = 0);
/**
* @brief Initialize the Blockchain state
@@ -1381,10 +1369,8 @@ namespace cryptonote
* A (possibly empty) set of block hashes can be compiled into the
* monero daemon binary. This function loads those hashes into
* a useful state.
- *
- * @param get_checkpoints if set, will be called to get checkpoints data
*/
- void load_compiled_in_block_hashes(const GetCheckpointsCallback get_checkpoints);
+ void load_compiled_in_block_hashes();
/**
* @brief expands v2 transaction data from blockchain
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 3882a14ae..2fec6b613 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -389,7 +389,7 @@ namespace cryptonote
return m_blockchain_storage.get_alternative_blocks_count();
}
//-----------------------------------------------------------------------------------------------
- bool core::init(const boost::program_options::variables_map& vm, const char *config_subdir, const cryptonote::test_options *test_options, const GetCheckpointsCallback get_checkpoints/* = nullptr */)
+ bool core::init(const boost::program_options::variables_map& vm, const char *config_subdir, const cryptonote::test_options *test_options)
{
start_time = std::time(nullptr);
@@ -567,7 +567,7 @@ namespace cryptonote
regtest_hard_forks
};
const difficulty_type fixed_difficulty = command_line::get_arg(vm, arg_fixed_difficulty);
- r = m_blockchain_storage.init(db.release(), m_nettype, m_offline, regtest ? &regtest_test_options : test_options, fixed_difficulty, get_checkpoints);
+ r = m_blockchain_storage.init(db.release(), m_nettype, m_offline, regtest ? &regtest_test_options : test_options, fixed_difficulty);
r = m_mempool.init(max_txpool_weight);
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool");
@@ -856,16 +856,19 @@ namespace cryptonote
}
waiter.wait(&tpool);
it = tx_blobs.begin();
+ std::vector<bool> already_have(tx_blobs.size(), false);
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
if (!results[i].res)
continue;
if(m_mempool.have_tx(results[i].hash))
{
LOG_PRINT_L2("tx " << results[i].hash << "already have transaction in tx_pool");
+ already_have[i] = true;
}
else if(m_blockchain_storage.have_tx(results[i].hash))
{
LOG_PRINT_L2("tx " << results[i].hash << " already have transaction in blockchain");
+ already_have[i] = true;
}
else
{
@@ -887,7 +890,7 @@ namespace cryptonote
std::vector<tx_verification_batch_info> tx_info;
tx_info.reserve(tx_blobs.size());
for (size_t i = 0; i < tx_blobs.size(); i++) {
- if (!results[i].res)
+ if (!results[i].res || already_have[i])
continue;
tx_info.push_back({&results[i].tx, results[i].hash, tvc[i], results[i].res});
}
@@ -897,6 +900,8 @@ namespace cryptonote
bool ok = true;
it = tx_blobs.begin();
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
+ if (already_have[i])
+ continue;
if (!results[i].res)
{
ok = false;
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index 882568330..58fe5b7b5 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -244,11 +244,10 @@ namespace cryptonote
* @param vm command line parameters
* @param config_subdir subdirectory for config storage
* @param test_options configuration options for testing
- * @param get_checkpoints if set, will be called to get checkpoints data, must return checkpoints data pointer and size or nullptr if there ain't any checkpoints for specific network type
*
* @return false if one of the init steps fails, otherwise true
*/
- bool init(const boost::program_options::variables_map& vm, const char *config_subdir = NULL, const test_options *test_options = NULL, const GetCheckpointsCallback get_checkpoints = nullptr);
+ bool init(const boost::program_options::variables_map& vm, const char *config_subdir = NULL, const test_options *test_options = NULL);
/**
* @copydoc Blockchain::reset_and_set_genesis_block
diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp
index c31a2073b..553a22298 100644
--- a/src/cryptonote_core/tx_pool.cpp
+++ b/src/cryptonote_core/tx_pool.cpp
@@ -250,7 +250,7 @@ namespace cryptonote
CRITICAL_REGION_LOCAL1(m_blockchain);
LockedTXN lock(m_blockchain);
m_blockchain.add_txpool_tx(tx, meta);
- if (!insert_key_images(tx, kept_by_block))
+ if (!insert_key_images(tx, id, kept_by_block))
return false;
m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)tx_weight, receive_time), id);
}
@@ -290,9 +290,10 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL1(m_blockchain);
LockedTXN lock(m_blockchain);
- m_blockchain.remove_txpool_tx(get_transaction_hash(tx));
+ const crypto::hash txid = get_transaction_hash(tx);
+ m_blockchain.remove_txpool_tx(txid);
m_blockchain.add_txpool_tx(tx, meta);
- if (!insert_key_images(tx, kept_by_block))
+ if (!insert_key_images(tx, txid, kept_by_block))
return false;
m_txs_by_fee_and_receive_time.emplace(std::pair<double, std::time_t>(fee / (double)tx_weight, receive_time), id);
}
@@ -371,8 +372,8 @@ namespace cryptonote
continue;
}
cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(txid);
- cryptonote::transaction tx;
- if (!parse_and_validate_tx_from_blob(txblob, tx))
+ cryptonote::transaction_prefix tx;
+ if (!parse_and_validate_tx_prefix_from_blob(txblob, tx))
{
MERROR("Failed to parse tx from txpool");
return;
@@ -381,7 +382,7 @@ namespace cryptonote
MINFO("Pruning tx " << txid << " from txpool: weight: " << it->first.second << ", fee/byte: " << it->first.first);
m_blockchain.remove_txpool_tx(txid);
m_txpool_weight -= it->first.second;
- remove_transaction_keyimages(tx);
+ remove_transaction_keyimages(tx, txid);
MINFO("Pruned tx " << txid << " from txpool: weight: " << it->first.second << ", fee/byte: " << it->first.first);
m_txs_by_fee_and_receive_time.erase(it--);
changed = true;
@@ -398,11 +399,10 @@ namespace cryptonote
MINFO("Pool weight after pruning is larger than limit: " << m_txpool_weight << "/" << bytes);
}
//---------------------------------------------------------------------------------
- bool tx_memory_pool::insert_key_images(const transaction &tx, bool kept_by_block)
+ bool tx_memory_pool::insert_key_images(const transaction_prefix &tx, const crypto::hash &id, bool kept_by_block)
{
for(const auto& in: tx.vin)
{
- const crypto::hash id = get_transaction_hash(tx);
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, txin, false);
std::unordered_set<crypto::hash>& kei_image_set = m_spent_key_images[txin.k_image];
CHECK_AND_ASSERT_MES(kept_by_block || kei_image_set.size() == 0, false, "internal error: kept_by_block=" << kept_by_block
@@ -418,19 +418,17 @@ namespace cryptonote
//FIXME: Can return early before removal of all of the key images.
// At the least, need to make sure that a false return here
// is treated properly. Should probably not return early, however.
- bool tx_memory_pool::remove_transaction_keyimages(const transaction& tx)
+ bool tx_memory_pool::remove_transaction_keyimages(const transaction_prefix& tx, const crypto::hash &actual_hash)
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
// ND: Speedup
- // 1. Move transaction hash calcuation outside of loop. ._.
- crypto::hash actual_hash = get_transaction_hash(tx);
for(const txin_v& vi: tx.vin)
{
CHECKED_GET_SPECIFIC_VARIANT(vi, const txin_to_key, txin, false);
auto it = m_spent_key_images.find(txin.k_image);
CHECK_AND_ASSERT_MES(it != m_spent_key_images.end(), false, "failed to find transaction input in key images. img=" << txin.k_image << ENDL
- << "transaction id = " << get_transaction_hash(tx));
+ << "transaction id = " << actual_hash);
std::unordered_set<crypto::hash>& key_image_set = it->second;
CHECK_AND_ASSERT_MES(key_image_set.size(), false, "empty key_image set, img=" << txin.k_image << ENDL
<< "transaction id = " << actual_hash);
@@ -483,7 +481,7 @@ namespace cryptonote
// remove first, in case this throws, so key images aren't removed
m_blockchain.remove_txpool_tx(id);
m_txpool_weight -= tx_weight;
- remove_transaction_keyimages(tx);
+ remove_transaction_keyimages(tx, id);
}
catch (const std::exception &e)
{
@@ -515,7 +513,7 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
- std::unordered_set<crypto::hash> remove;
+ std::list<std::pair<crypto::hash, uint64_t>> remove;
m_blockchain.for_all_txpool_txes([this, &remove](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata*) {
uint64_t tx_age = time(nullptr) - meta.receive_time;
@@ -533,7 +531,7 @@ namespace cryptonote
m_txs_by_fee_and_receive_time.erase(sorted_it);
}
m_timed_out_transactions.insert(txid);
- remove.insert(txid);
+ remove.push_back(std::make_pair(txid, meta.weight));
}
return true;
}, false);
@@ -541,13 +539,14 @@ namespace cryptonote
if (!remove.empty())
{
LockedTXN lock(m_blockchain);
- for (const crypto::hash &txid: remove)
+ for (const std::pair<crypto::hash, uint64_t> &entry: remove)
{
+ const crypto::hash &txid = entry.first;
try
{
cryptonote::blobdata bd = m_blockchain.get_txpool_tx_blob(txid);
- cryptonote::transaction tx;
- if (!parse_and_validate_tx_from_blob(bd, tx))
+ cryptonote::transaction_prefix tx;
+ if (!parse_and_validate_tx_prefix_from_blob(bd, tx))
{
MERROR("Failed to parse tx from txpool");
// continue
@@ -556,8 +555,8 @@ namespace cryptonote
{
// remove first, so we only remove key images if the tx removal succeeds
m_blockchain.remove_txpool_tx(txid);
- m_txpool_weight -= get_transaction_weight(tx, bd.size());
- remove_transaction_keyimages(tx);
+ m_txpool_weight -= entry.second;
+ remove_transaction_keyimages(tx, txid);
}
}
catch (const std::exception &e)
@@ -1041,7 +1040,7 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------------------------
- bool tx_memory_pool::have_key_images(const std::unordered_set<crypto::key_image>& k_images, const transaction& tx)
+ bool tx_memory_pool::have_key_images(const std::unordered_set<crypto::key_image>& k_images, const transaction_prefix& tx)
{
for(size_t i = 0; i!= tx.vin.size(); i++)
{
@@ -1052,7 +1051,7 @@ namespace cryptonote
return false;
}
//---------------------------------------------------------------------------------
- bool tx_memory_pool::append_key_images(std::unordered_set<crypto::key_image>& k_images, const transaction& tx)
+ bool tx_memory_pool::append_key_images(std::unordered_set<crypto::key_image>& k_images, const transaction_prefix& tx)
{
for(size_t i = 0; i!= tx.vin.size(); i++)
{
@@ -1301,7 +1300,7 @@ namespace cryptonote
// remove tx from db first
m_blockchain.remove_txpool_tx(txid);
m_txpool_weight -= get_transaction_weight(tx, txblob.size());
- remove_transaction_keyimages(tx);
+ 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())
{
@@ -1344,14 +1343,14 @@ namespace cryptonote
bool r = m_blockchain.for_all_txpool_txes([this, &remove, kept](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd) {
if (!!kept != !!meta.kept_by_block)
return true;
- cryptonote::transaction tx;
- if (!parse_and_validate_tx_from_blob(*bd, tx))
+ cryptonote::transaction_prefix tx;
+ if (!parse_and_validate_tx_prefix_from_blob(*bd, tx))
{
MWARNING("Failed to parse tx from txpool, removing");
remove.push_back(txid);
return true;
}
- if (!insert_key_images(tx, meta.kept_by_block))
+ if (!insert_key_images(tx, txid, meta.kept_by_block))
{
MFATAL("Failed to insert key images from txpool tx");
return false;
diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h
index 892cadc69..7a0cc23bf 100644
--- a/src/cryptonote_core/tx_pool.h
+++ b/src/cryptonote_core/tx_pool.h
@@ -434,7 +434,7 @@ namespace cryptonote
*
* @return true on success, false on error
*/
- bool insert_key_images(const transaction &tx, bool kept_by_block);
+ bool insert_key_images(const transaction_prefix &tx, const crypto::hash &txid, bool kept_by_block);
/**
* @brief remove old transactions from the pool
@@ -478,10 +478,11 @@ namespace cryptonote
* a transaction from the pool.
*
* @param tx the transaction
+ * @param txid the transaction's hash
*
* @return false if any key images to be removed cannot be found, otherwise true
*/
- bool remove_transaction_keyimages(const transaction& tx);
+ bool remove_transaction_keyimages(const transaction_prefix& tx, const crypto::hash &txid);
/**
* @brief check if any of a transaction's spent key images are present in a given set
@@ -491,7 +492,7 @@ namespace cryptonote
*
* @return true if any key images present in the set, otherwise false
*/
- static bool have_key_images(const std::unordered_set<crypto::key_image>& kic, const transaction& tx);
+ static bool have_key_images(const std::unordered_set<crypto::key_image>& kic, const transaction_prefix& tx);
/**
* @brief append the key images from a transaction to the given set
@@ -501,7 +502,7 @@ namespace cryptonote
*
* @return false if any append fails, otherwise true
*/
- static bool append_key_images(std::unordered_set<crypto::key_image>& kic, const transaction& tx);
+ static bool append_key_images(std::unordered_set<crypto::key_image>& kic, const transaction_prefix& tx);
/**
* @brief check if a transaction is a valid candidate for inclusion in a block
@@ -509,11 +510,11 @@ namespace cryptonote
* @param txd the transaction to check (and info about it)
* @param txid the txid of the transaction to check
* @param txblob the transaction blob to check
- * @param tx the parsed transaction, if successful
+ * @param tx the parsed transaction prefix, if successful
*
* @return true if the transaction is good to go, otherwise false
*/
- bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const;
+ bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction&tx) const;
/**
* @brief mark all transactions double spending the one passed
diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt
index 117790455..f645836a4 100644
--- a/src/daemon/CMakeLists.txt
+++ b/src/daemon/CMakeLists.txt
@@ -26,6 +26,20 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+set(blocksdat "")
+if(PER_BLOCK_CHECKPOINT)
+ if(APPLE AND DEPENDS)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} --target=x86_64-apple-darwin11 -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*)
+ elseif(APPLE AND NOT DEPENDS)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && touch stub.c && ${CMAKE_C_COMPILER} -o stub.o -c stub.c COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -sectcreate __DATA __blocks_dat ../blocks/checkpoints.dat -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o stub.o && rm -f stub.*)
+ elseif(LINUX_32)
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} -m elf_i386 ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat)
+ else()
+ add_custom_command(OUTPUT blocksdat.o MAIN_DEPENDENCY ../blocks/checkpoints.dat COMMAND cd ${CMAKE_CURRENT_SOURCE_DIR} && cp ../blocks/checkpoints.dat blocks.dat && ${CMAKE_LINKER} ${LD_RAW_FLAGS} -r -b binary -o ${CMAKE_CURRENT_BINARY_DIR}/blocksdat.o blocks.dat && rm -f blocks.dat)
+ endif()
+ set(blocksdat "blocksdat.o")
+endif()
+
set(daemon_sources
command_parser_executor.cpp
command_server.cpp
@@ -67,7 +81,9 @@ monero_private_headers(daemon
monero_add_executable(daemon
${daemon_sources}
${daemon_headers}
- ${daemon_private_headers})
+ ${daemon_private_headers}
+ ${blocksdat}
+)
target_link_libraries(daemon
PRIVATE
rpc
@@ -90,8 +106,7 @@ target_link_libraries(daemon
${CMAKE_THREAD_LIBS_INIT}
${ZMQ_LIB}
${GNU_READLINE_LIBRARY}
- ${EXTRA_LIBRARIES}
- ${Blocks})
+ ${EXTRA_LIBRARIES})
set_property(TARGET daemon
PROPERTY
OUTPUT_NAME "monerod")
diff --git a/src/daemon/core.h b/src/daemon/core.h
index eda8894a6..475f418d6 100644
--- a/src/daemon/core.h
+++ b/src/daemon/core.h
@@ -28,7 +28,6 @@
#pragma once
-#include "blocks/blocks.h"
#include "cryptonote_core/cryptonote_core.h"
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
#include "misc_log_ex.h"
@@ -86,12 +85,7 @@ public:
//initialize core here
MGINFO("Initializing core...");
std::string config_subdir = get_config_subdir();
-#if defined(PER_BLOCK_CHECKPOINT)
- cryptonote::GetCheckpointsCallback get_checkpoints = blocks::GetCheckpointsData;
-#else
- cryptonote::GetCheckpointsCallback get_checkpoints = nullptr;
-#endif
- if (!m_core.init(m_vm_HACK, config_subdir.empty() ? NULL : config_subdir.c_str(), nullptr, get_checkpoints))
+ if (!m_core.init(m_vm_HACK, config_subdir.empty() ? NULL : config_subdir.c_str()))
{
return false;
}
diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp
index ea24e32eb..49d6d49cf 100644
--- a/src/daemon/daemon.cpp
+++ b/src/daemon/daemon.cpp
@@ -136,7 +136,19 @@ bool t_daemon::run(bool interactive)
{
throw std::runtime_error{"Can't run stopped daemon"};
}
- tools::signal_handler::install(std::bind(&daemonize::t_daemon::stop_p2p, this));
+
+ std::atomic<bool> stop(false), shutdown(false);
+ boost::thread stop_thread = boost::thread([&stop, &shutdown, this] {
+ while (!stop)
+ epee::misc_utils::sleep_no_w(100);
+ if (shutdown)
+ this->stop_p2p();
+ });
+ epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){
+ stop = true;
+ stop_thread.join();
+ });
+ tools::signal_handler::install([&stop, &shutdown](int){ stop = shutdown = true; });
try
{
diff --git a/src/daemonizer/windows_daemonizer.inl b/src/daemonizer/windows_daemonizer.inl
index 8077f29fb..7e61e3603 100644
--- a/src/daemonizer/windows_daemonizer.inl
+++ b/src/daemonizer/windows_daemonizer.inl
@@ -31,6 +31,7 @@
#include "common/util.h"
#include "daemonizer/windows_service.h"
#include "daemonizer/windows_service_runner.h"
+#include "cryptonote_core/cryptonote_core.h"
#include <shlobj.h>
#include <boost/filesystem/operations.hpp>
diff --git a/src/debug_utilities/object_sizes.cpp b/src/debug_utilities/object_sizes.cpp
index ab8839636..2281d0734 100644
--- a/src/debug_utilities/object_sizes.cpp
+++ b/src/debug_utilities/object_sizes.cpp
@@ -29,6 +29,7 @@
#include <map>
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/tx_extra.h"
+#include "cryptonote_core/cryptonote_core.h"
#include "cryptonote_core/blockchain.h"
#include "p2p/p2p_protocol_defs.h"
#include "net/connection_basic.hpp"
diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt
index 727134f75..8f446f42a 100644
--- a/src/device/CMakeLists.txt
+++ b/src/device/CMakeLists.txt
@@ -58,6 +58,12 @@ endif()
set(device_private_headers)
+if(PER_BLOCK_CHECKPOINT)
+ set(Blocks "blocks")
+else()
+ set(Blocks "")
+endif()
+
monero_private_headers(device
${device_private_headers})
@@ -73,4 +79,5 @@ target_link_libraries(device
ringct_basic
${OPENSSL_CRYPTO_LIBRARIES}
PRIVATE
+ ${Blocks}
${EXTRA_LIBRARIES})
diff --git a/src/device/device.cpp b/src/device/device.cpp
index 50041baef..d5e3031ff 100644
--- a/src/device/device.cpp
+++ b/src/device/device.cpp
@@ -41,13 +41,26 @@ namespace hw {
/* SETUP */
/* ======================================================================= */
- static std::unique_ptr<device_registry> registry;
+ static device_registry *get_device_registry(bool clear = false){
+ static device_registry *registry = new device_registry();
+ if (clear)
+ {
+ delete registry;
+ registry = NULL;
+ }
+ return registry;
+ }
+
+ static void clear_device_registry(){
+ get_device_registry(true);
+ }
device_registry::device_registry(){
hw::core::register_all(registry);
#ifdef WITH_DEVICE_LEDGER
hw::ledger::register_all(registry);
#endif
+ atexit(clear_device_registry);
}
bool device_registry::register_device(const std::string & device_name, device * hw_device){
@@ -80,18 +93,12 @@ namespace hw {
}
device& get_device(const std::string & device_descriptor) {
- if (!registry){
- registry.reset(new device_registry());
- }
-
+ device_registry *registry = get_device_registry();
return registry->get_device(device_descriptor);
}
bool register_device(const std::string & device_name, device * hw_device){
- if (!registry){
- registry.reset(new device_registry());
- }
-
+ device_registry *registry = get_device_registry();
return registry->register_device(device_name, hw_device);
}
diff --git a/src/device/device_io_hid.cpp b/src/device/device_io_hid.cpp
index 562aca8b8..666255cb3 100644
--- a/src/device/device_io_hid.cpp
+++ b/src/device/device_io_hid.cpp
@@ -13,6 +13,7 @@
//
#if defined(HAVE_HIDAPI)
+#include <boost/scope_exit.hpp>
#include "log.hpp"
#include "device_io_hid.hpp"
@@ -69,11 +70,47 @@ namespace hw {
void device_io_hid::connect(void *params) {
hid_conn_params *p = (struct hid_conn_params*)params;
- this->connect(p->vid, p->pid, p->interface_number, p->usage_page, p->interface_OR_page);
+ this->connect(p->vid, p->pid, p->interface_number, p->usage_page);
}
- void device_io_hid::connect(unsigned int vid, unsigned int pid, unsigned int interface_number, unsigned int usage_page, bool interface_OR_page ) {
- hid_device_info *hwdev_info, *hwdev_info_list;
+ hid_device_info *device_io_hid::find_device(hid_device_info *devices_list, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page) {
+ bool select_any = !interface_number && !usage_page;
+
+ MDEBUG( "Looking for " <<
+ (select_any ? "any HID Device" : "HID Device with") <<
+ (interface_number ? (" interface_number " + std::to_string(interface_number.value())) : "") <<
+ ((interface_number && usage_page) ? " or" : "") <<
+ (usage_page ? (" usage_page " + std::to_string(usage_page.value())) : ""));
+
+ hid_device_info *result = nullptr;
+ for (; devices_list != nullptr; devices_list = devices_list->next) {
+ BOOST_SCOPE_EXIT(&devices_list, &result) {
+ MDEBUG( (result == devices_list ? "SELECTED" : "SKIPPED ") <<
+ " HID Device" <<
+ " path " << safe_hid_path(devices_list) <<
+ " interface_number " << devices_list->interface_number <<
+ " usage_page " << devices_list->usage_page);
+ }
+ BOOST_SCOPE_EXIT_END
+
+ if (result != nullptr) {
+ continue;
+ }
+
+ if (select_any) {
+ result = devices_list;
+ } else if (interface_number && devices_list->interface_number == interface_number.value()) {
+ result = devices_list;
+ } else if (usage_page && devices_list->usage_page == usage_page.value()) {
+ result = devices_list;
+ }
+ }
+
+ return result;
+ }
+
+ void device_io_hid::connect(unsigned int vid, unsigned int pid, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page) {
+ hid_device_info *hwdev_info_list;
hid_device *hwdev;
this->disconnect();
@@ -81,17 +118,8 @@ namespace hw {
hwdev_info_list = hid_enumerate(vid, pid);
ASSERT_X(hwdev_info_list, "Unable to enumerate device "+std::to_string(vid)+":"+std::to_string(vid)+ ": "+ safe_hid_error(this->usb_device));
hwdev = NULL;
- hwdev_info = hwdev_info_list;
- while (hwdev_info) {
- if ((interface_OR_page && ((usage_page == 0xffa0) || (interface_number == 0))) ||
- ((usage_page == 0xffa0) && (interface_number == 0)) ) {
- MDEBUG("HID Device found: " << safe_hid_path(hwdev_info));
- hwdev = hid_open_path(hwdev_info->path);
- break;
- } else {
- MDEBUG("HID Device discard: " << safe_hid_path(hwdev_info) << "("+std::to_string(hwdev_info->usage_page) << "," << std::to_string(hwdev_info->interface_number) << ")");
- }
- hwdev_info = hwdev_info->next;
+ if (hid_device_info *device = find_device(hwdev_info_list, interface_number, usage_page)) {
+ hwdev = hid_open_path(device->path);
}
hid_free_enumeration(hwdev_info_list);
ASSERT_X(hwdev, "Unable to open device "+std::to_string(pid)+":"+std::to_string(vid));
diff --git a/src/device/device_io_hid.hpp b/src/device/device_io_hid.hpp
index 560208c77..bb0f0a814 100644
--- a/src/device/device_io_hid.hpp
+++ b/src/device/device_io_hid.hpp
@@ -29,6 +29,7 @@
#if defined(HAVE_HIDAPI)
+#include <boost/optional/optional.hpp>
#include <hidapi/hidapi.h>
#include "device_io.hpp"
@@ -52,9 +53,8 @@ namespace hw {
struct hid_conn_params {
unsigned int vid;
unsigned int pid;
- unsigned int interface_number;
- unsigned int usage_page;
- bool interface_OR_page ;
+ int interface_number;
+ unsigned short usage_page;
};
@@ -82,17 +82,15 @@ namespace hw {
unsigned int wrapCommand(const unsigned char *command, size_t command_len, unsigned char *out, size_t out_len);
unsigned int unwrapReponse(const unsigned char *data, size_t data_len, unsigned char *out, size_t out_len);
+ hid_device_info *find_device(hid_device_info *devices_list, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page);
public:
bool hid_verbose = false;
- const unsigned int OR_SELECT = 1;
- const unsigned int AND_SELECT = 2;
-
- const unsigned char DEFAULT_CHANNEL = 0x0001;
- const unsigned char DEFAULT_TAG = 0x01;
- const unsigned int DEFAULT_PACKET_SIZE = 64;
- const unsigned int DEFAULT_TIMEOUT = 120000;
+ static const unsigned short DEFAULT_CHANNEL = 0x0001;
+ static const unsigned char DEFAULT_TAG = 0x01;
+ static const unsigned int DEFAULT_PACKET_SIZE = 64;
+ static const unsigned int DEFAULT_TIMEOUT = 120000;
device_io_hid(unsigned short channel, unsigned char tag, unsigned int packet_zize, unsigned int timeout);
device_io_hid();
@@ -100,7 +98,7 @@ namespace hw {
void init();
void connect(void *params);
- void connect(unsigned int vid, unsigned int pid, unsigned int interface_number, unsigned int usage_page, bool interface_OR_page );
+ void connect(unsigned int vid, unsigned int pid, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page);
bool connected() const;
int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len);
void disconnect();
diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp
index 456eda739..d879ee95a 100644
--- a/src/device/device_ledger.cpp
+++ b/src/device/device_ledger.cpp
@@ -48,21 +48,12 @@ namespace hw {
/* ===================================================================== */
/* === Debug ==== */
/* ===================================================================== */
- #ifdef WIN32
- static char *pcsc_stringify_error(LONG rv) {
- static __thread char out[20];
- sprintf_s(out, sizeof(out), "0x%08lX", rv);
-
- return out;
- }
- #endif
void set_apdu_verbose(bool verbose) {
apdu_verbose = verbose;
}
#define TRACKD MTRACE("hw")
- #define ASSERT_RV(rv) CHECK_AND_ASSERT_THROW_MES((rv)==SCARD_S_SUCCESS, "Fail SCard API : (" << (rv) << ") "<< pcsc_stringify_error(rv)<<" Device="<<this->id<<", hCard="<<hCard<<", hContext="<<hContext);
#define ASSERT_SW(sw,ok,msk) CHECK_AND_ASSERT_THROW_MES(((sw)&(mask))==(ok), "Wrong Device Status : SW=" << std::hex << (sw) << " (EXPECT=" << std::hex << (ok) << ", MASK=" << std::hex << (mask) << ")") ;
#define ASSERT_T0(exp) CHECK_AND_ASSERT_THROW_MES(exp, "Protocol assert failure: "#exp ) ;
#define ASSERT_X(exp,msg) CHECK_AND_ASSERT_THROW_MES(exp, msg);
@@ -185,7 +176,7 @@ namespace hw {
#define INS_GET_RESPONSE 0xc0
- device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 10000) {
+ device_ledger::device_ledger(): hw_device(0x0101, 0x05, 64, 120000) {
this->id = device_id++;
this->reset_buffer();
this->mode = NONE;
@@ -349,7 +340,7 @@ namespace hw {
bool device_ledger::connect(void) {
this->disconnect();
- hw_device.connect(0x2c97,0x0001, 0, 0xffa0, hw_device.OR_SELECT);
+ hw_device.connect(0x2c97, 0x0001, 0, 0xffa0);
this->reset();
#ifdef DEBUG_HWDEVICE
cryptonote::account_public_address pubkey;
diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp
index c9ca63f43..e9d2061e8 100644
--- a/src/p2p/net_node.cpp
+++ b/src/p2p/net_node.cpp
@@ -29,6 +29,7 @@
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include "common/command_line.h"
+#include "cryptonote_core/cryptonote_core.h"
#include "net_node.h"
namespace nodetool
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index 74924e4f4..9390626a8 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -937,7 +937,7 @@ namespace nodetool
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()),
epee::string_tools::num_to_string_fast(ipv4.port()),
m_config.m_net_config.connection_timeout,
- con, m_bind_ip.empty() ? "0.0.0.0" : m_bind_ip);
+ con);
if(!res)
{
@@ -1002,7 +1002,7 @@ namespace nodetool
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()),
epee::string_tools::num_to_string_fast(ipv4.port()),
m_config.m_net_config.connection_timeout,
- con, m_bind_ip.empty() ? "0.0.0.0" : m_bind_ip);
+ con);
if (!res) {
bool is_priority = is_priority_node(na);
@@ -1617,7 +1617,7 @@ namespace nodetool
return false;
}
return true;
- }, m_bind_ip.empty() ? "0.0.0.0" : m_bind_ip);
+ });
if(!r)
{
LOG_WARNING_CC(context, "Failed to call connect_async, network error.");
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index be511a2d2..55ee66a79 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -924,6 +924,8 @@ namespace cryptonote
return r;
m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, !request_has_rpc_origin || !m_restricted);
+ for (tx_info& txi : res.transactions)
+ txi.tx_blob = epee::string_tools::buff_to_hex_nodelimer(txi.tx_blob);
res.status = CORE_RPC_STATUS_OK;
return true;
}
@@ -1090,7 +1092,7 @@ namespace cryptonote
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Internal error: failed to create block template";
- LOG_ERROR("Failed to tx pub key in coinbase extra");
+ LOG_ERROR("Failed to get tx pub key in coinbase extra");
return false;
}
res.reserved_offset = slow_memmem((void*)block_blob.data(), block_blob.size(), &tx_pub_key, sizeof(tx_pub_key));
@@ -2118,6 +2120,8 @@ namespace cryptonote
try
{
+ // 0 is placeholder for the whole chain
+ const uint64_t req_to_height = req.to_height ? req.to_height : (m_core.get_current_blockchain_height() - 1);
for (uint64_t amount: req.amounts)
{
static struct D
@@ -2130,7 +2134,7 @@ namespace cryptonote
} d;
boost::unique_lock<boost::mutex> lock(d.mutex);
- if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req.to_height)
+ if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req_to_height)
{
res.distributions.push_back({amount, d.cached_start_height, req.binary, d.cached_distribution, d.cached_base});
if (!req.cumulative)
@@ -2145,23 +2149,23 @@ namespace cryptonote
std::vector<uint64_t> distribution;
uint64_t start_height, base;
- if (!m_core.get_output_distribution(amount, req.from_height, req.to_height, start_height, distribution, base))
+ if (!m_core.get_output_distribution(amount, req.from_height, req_to_height, start_height, distribution, base))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Failed to get rct distribution";
return false;
}
- if (req.to_height > 0 && req.to_height >= req.from_height)
+ if (req_to_height > 0 && req_to_height >= req.from_height)
{
uint64_t offset = std::max(req.from_height, start_height);
- if (offset <= req.to_height && req.to_height - offset + 1 < distribution.size())
- distribution.resize(req.to_height - offset + 1);
+ if (offset <= req_to_height && req_to_height - offset + 1 < distribution.size())
+ distribution.resize(req_to_height - offset + 1);
}
if (amount == 0)
{
d.cached_from = req.from_height;
- d.cached_to = req.to_height;
+ d.cached_to = req_to_height;
d.cached_distribution = distribution;
d.cached_start_height = start_height;
d.cached_base = base;
diff --git a/src/serialization/serialization.h b/src/serialization/serialization.h
index 5fc382a1e..2050e88e2 100644
--- a/src/serialization/serialization.h
+++ b/src/serialization/serialization.h
@@ -318,7 +318,7 @@ namespace serialization {
* \brief self explanatory
*/
template<class Stream>
- bool do_check_stream_state(Stream& s, boost::mpl::bool_<true>)
+ bool do_check_stream_state(Stream& s, boost::mpl::bool_<true>, bool noeof)
{
return s.good();
}
@@ -329,13 +329,13 @@ namespace serialization {
* \detailed Also checks to make sure that the stream is not at EOF
*/
template<class Stream>
- bool do_check_stream_state(Stream& s, boost::mpl::bool_<false>)
+ bool do_check_stream_state(Stream& s, boost::mpl::bool_<false>, bool noeof)
{
bool result = false;
if (s.good())
{
std::ios_base::iostate state = s.rdstate();
- result = EOF == s.peek();
+ result = noeof || EOF == s.peek();
s.clear(state);
}
return result;
@@ -347,9 +347,9 @@ namespace serialization {
* \brief calls detail::do_check_stream_state for ar
*/
template<class Archive>
- bool check_stream_state(Archive& ar)
+ bool check_stream_state(Archive& ar, bool noeof = false)
{
- return detail::do_check_stream_state(ar.stream(), typename Archive::is_saving());
+ return detail::do_check_stream_state(ar.stream(), typename Archive::is_saving(), noeof);
}
/*! \fn serialize
@@ -360,6 +360,17 @@ namespace serialization {
inline bool serialize(Archive &ar, T &v)
{
bool r = do_serialize(ar, v);
- return r && check_stream_state(ar);
+ return r && check_stream_state(ar, false);
+ }
+
+ /*! \fn serialize
+ *
+ * \brief serializes \a v into \a ar
+ */
+ template <class Archive, class T>
+ inline bool serialize_noeof(Archive &ar, T &v)
+ {
+ bool r = do_serialize(ar, v);
+ return r && check_stream_state(ar, true);
}
}
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index 4ec7e3eb4..18b596662 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -1640,7 +1640,7 @@ bool simple_wallet::blackball(const std::vector<std::string> &args)
uint64_t amount = std::numeric_limits<uint64_t>::max(), offset, num_offsets;
if (args.size() == 0)
{
- fail_msg_writer() << tr("usage: blackball <amount>/<offset> | <filename> [add]");
+ fail_msg_writer() << tr("usage: mark_output_spent <amount>/<offset> | <filename> [add]");
return true;
}
@@ -1718,7 +1718,7 @@ bool simple_wallet::blackball(const std::vector<std::string> &args)
}
catch (const std::exception &e)
{
- fail_msg_writer() << tr("Failed to blackball output: ") << e.what();
+ fail_msg_writer() << tr("Failed to mark output spent: ") << e.what();
}
return true;
@@ -1729,7 +1729,7 @@ bool simple_wallet::unblackball(const std::vector<std::string> &args)
std::pair<uint64_t, uint64_t> output;
if (args.size() != 1)
{
- fail_msg_writer() << tr("usage: unblackball <amount>/<offset>");
+ fail_msg_writer() << tr("usage: mark_output_unspent <amount>/<offset>");
return true;
}
@@ -1745,7 +1745,7 @@ bool simple_wallet::unblackball(const std::vector<std::string> &args)
}
catch (const std::exception &e)
{
- fail_msg_writer() << tr("Failed to unblackball output: ") << e.what();
+ fail_msg_writer() << tr("Failed to mark output unspent: ") << e.what();
}
return true;
@@ -1756,7 +1756,7 @@ bool simple_wallet::blackballed(const std::vector<std::string> &args)
std::pair<uint64_t, uint64_t> output;
if (args.size() != 1)
{
- fail_msg_writer() << tr("usage: blackballed <amount>/<offset>");
+ fail_msg_writer() << tr("usage: is_output_spent <amount>/<offset>");
return true;
}
@@ -1769,13 +1769,13 @@ bool simple_wallet::blackballed(const std::vector<std::string> &args)
try
{
if (m_wallet->is_output_blackballed(output))
- message_writer() << tr("Blackballed: ") << output.first << "/" << output.second;
+ message_writer() << tr("Spent: ") << output.first << "/" << output.second;
else
- message_writer() << tr("not blackballed: ") << output.first << "/" << output.second;
+ message_writer() << tr("Not spent: ") << output.first << "/" << output.second;
}
catch (const std::exception &e)
{
- fail_msg_writer() << tr("Failed to unblackball output: ") << e.what();
+ fail_msg_writer() << tr("Failed to check whether output is spent: ") << e.what();
}
return true;
@@ -2403,7 +2403,7 @@ simple_wallet::simple_wallet()
"store-tx-info <1|0>\n "
" Whether to store outgoing tx info (destination address, payment ID, tx secret key) for future reference.\n "
"default-ring-size <n>\n "
- " Set the default ring size (default and minimum is 5).\n "
+ " Set the default ring size (obsolete).\n "
"auto-refresh <1|0>\n "
" Whether to automatically synchronize new blocks from the daemon.\n "
"refresh-type <full|optimize-coinbase|no-coinbase|default>\n "
@@ -2599,18 +2599,18 @@ simple_wallet::simple_wallet()
boost::bind(&simple_wallet::save_known_rings, this, _1),
tr("save_known_rings"),
tr("Save known rings to the shared rings database"));
- m_cmd_binder.set_handler("blackball",
+ m_cmd_binder.set_handler("mark_output_spent",
boost::bind(&simple_wallet::blackball, this, _1),
- tr("blackball <amount>/<offset> | <filename> [add]"),
- tr("Blackball output(s) so they never get selected as fake outputs in a ring"));
- m_cmd_binder.set_handler("unblackball",
+ tr("mark_output_spent <amount>/<offset> | <filename> [add]"),
+ tr("Mark output(s) as spent so they never get selected as fake outputs in a ring"));
+ m_cmd_binder.set_handler("mark_output_unspent",
boost::bind(&simple_wallet::unblackball, this, _1),
- tr("unblackball <amount>/<offset>"),
- tr("Unblackballs an output so it may get selected as a fake output in a ring"));
- m_cmd_binder.set_handler("blackballed",
+ tr("mark_output_unspent <amount>/<offset>"),
+ tr("Marks an output as unspent so it may get selected as a fake output in a ring"));
+ m_cmd_binder.set_handler("is_output_spent",
boost::bind(&simple_wallet::blackballed, this, _1),
- tr("blackballed <amount>/<offset>"),
- tr("Checks whether an output is blackballed"));
+ tr("is_output_spent <amount>/<offset>"),
+ tr("Checks whether an output is marked as spent"));
m_cmd_binder.set_handler("version",
boost::bind(&simple_wallet::version, this, _1),
tr("version"),
@@ -3032,7 +3032,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
return false;
}
crypto::secret_key viewkey;
- if (viewkey_string.hex_to_pod(unwrap(unwrap(viewkey))))
+ if (!viewkey_string.hex_to_pod(unwrap(unwrap(viewkey))))
{
fail_msg_writer() << tr("failed to parse view key secret key");
return false;
diff --git a/src/version.cpp.in b/src/version.cpp.in
index 55075a064..ff2405811 100644
--- a/src/version.cpp.in
+++ b/src/version.cpp.in
@@ -1,5 +1,5 @@
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
-#define DEF_MONERO_VERSION "0.13.0.1-rc"
+#define DEF_MONERO_VERSION "0.13.0.0-master"
#define DEF_MONERO_RELEASE_NAME "Beryllium Bullet"
#define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index de1bfdae1..1b4370c36 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -776,7 +776,7 @@ bool WalletImpl::setPassword(const std::string &password)
{
clearStatus();
try {
- m_wallet->rewrite(m_wallet->get_wallet_file(), password);
+ m_wallet->change_password(m_wallet->get_wallet_file(), m_password, password);
m_password = password;
} catch (const std::exception &e) {
setStatusError(e.what());
@@ -2161,7 +2161,7 @@ bool WalletImpl::blackballOutputs(const std::vector<std::string> &outputs, bool
bool ret = m_wallet->set_blackballed_outputs(raw_outputs, add);
if (!ret)
{
- setStatusError(tr("Failed to set blackballed outputs"));
+ setStatusError(tr("Failed to mark outputs as spent"));
return false;
}
return true;
@@ -2183,7 +2183,7 @@ bool WalletImpl::blackballOutput(const std::string &amount, const std::string &o
bool ret = m_wallet->blackball_output(std::make_pair(raw_amount, raw_offset));
if (!ret)
{
- setStatusError(tr("Failed to blackball output"));
+ setStatusError(tr("Failed to mark output as spent"));
return false;
}
return true;
@@ -2205,7 +2205,7 @@ bool WalletImpl::unblackballOutput(const std::string &amount, const std::string
bool ret = m_wallet->unblackball_output(std::make_pair(raw_amount, raw_offset));
if (!ret)
{
- setStatusError(tr("Failed to unblackball output"));
+ setStatusError(tr("Failed to mark output as unspent"));
return false;
}
return true;
diff --git a/src/wallet/ringdb.cpp b/src/wallet/ringdb.cpp
index e5995e7fb..f562d6c06 100644
--- a/src/wallet/ringdb.cpp
+++ b/src/wallet/ringdb.cpp
@@ -412,13 +412,13 @@ bool ringdb::blackball_worker(const std::vector<std::pair<uint64_t, uint64_t>> &
switch (op)
{
case BLACKBALL_BLACKBALL:
- MDEBUG("Blackballing output " << output.first << "/" << output.second);
+ MDEBUG("Marking output " << output.first << "/" << output.second << " as spent");
dbr = mdb_cursor_put(cursor, &key, &data, MDB_APPENDDUP);
if (dbr == MDB_KEYEXIST)
dbr = 0;
break;
case BLACKBALL_UNBLACKBALL:
- MDEBUG("Unblackballing output " << output.first << "/" << output.second);
+ MDEBUG("Marking output " << output.first << "/" << output.second << " as unspent");
dbr = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH);
if (dbr == 0)
dbr = mdb_cursor_del(cursor, 0);
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 7871fe99c..6b3a8533e 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -37,6 +37,8 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/join.hpp>
+#include <boost/range/adaptor/transformed.hpp>
#include "include_base_utils.h"
using namespace epee;
@@ -3611,6 +3613,7 @@ bool wallet2::query_device(hw::device::device_type& device_type, const std::stri
if (json.Parse(account_data.c_str()).HasParseError() || !json.IsObject())
crypto::chacha8(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
+ device_type = hw::device::device_type::SOFTWARE;
// The contents should be JSON if the wallet follows the new format.
if (json.Parse(account_data.c_str()).HasParseError())
{
@@ -5563,10 +5566,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector<wallet2::pendin
rct::RangeProofType range_proof_type = rct::RangeProofBorromean;
if (sd.use_bulletproofs)
{
- range_proof_type = rct::RangeProofBulletproof;
- for (const rct::Bulletproof &proof: ptx.tx.rct_signatures.p.bulletproofs)
- if (proof.V.size() > 1)
- range_proof_type = rct::RangeProofPaddedBulletproof;
+ range_proof_type = rct::RangeProofPaddedBulletproof;
}
crypto::secret_key tx_key;
std::vector<crypto::secret_key> additional_tx_keys;
@@ -6968,6 +6968,8 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
LOG_PRINT_L1("Selecting real output: " << td.m_global_output_index << " for " << print_money(amount));
}
+ std::unordered_map<const char*, std::set<uint64_t>> picks;
+
// while we still need more mixins
uint64_t num_usable_outs = num_outs;
bool allow_blackballed = false;
@@ -6982,7 +6984,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
// outputs, we still need to reach the minimum ring size)
if (allow_blackballed)
break;
- MINFO("Not enough non blackballed outputs, we'll allow blackballed ones");
+ MINFO("Not enough output not marked as spent, we'll allow outputs marked as spent");
allow_blackballed = true;
num_usable_outs = num_outs;
}
@@ -7066,11 +7068,15 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
}
seen_indices.emplace(i);
- LOG_PRINT_L2("picking " << i << " as " << type);
+ picks[type].insert(i);
req.outputs.push_back({amount, i});
++num_found;
}
+ for (const auto &pick: picks)
+ MDEBUG("picking " << pick.first << " outputs: " <<
+ boost::join(pick.second | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " "));
+
// if we had enough unusable outputs, we might fall off here and still
// have too few outputs, so we stuff with one to keep counts good, and
// we'll error out later
@@ -7086,8 +7092,15 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
[](const get_outputs_out &a, const get_outputs_out &b) { return a.index < b.index; });
}
- for (auto i: req.outputs)
- LOG_PRINT_L1("asking for output " << i.index << " for " << print_money(i.amount));
+ if (ELPP->vRegistry()->allowed(el::Level::Debug, MONERO_DEFAULT_LOG_CATEGORY))
+ {
+ std::map<uint64_t, std::set<uint64_t>> outs;
+ for (const auto &i: req.outputs)
+ outs[i.amount].insert(i.index);
+ for (const auto &o: outs)
+ MDEBUG("asking for outputs with amount " << print_money(o.first) << ": " <<
+ boost::join(o.second | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " "));
+ }
// get the keys for those
m_daemon_rpc_mutex.lock();
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index e0b631aaf..1b63d65b6 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -2822,8 +2822,7 @@ namespace tools
{
try
{
- m_wallet->rewrite(m_wallet->get_wallet_file(), req.new_password);
- m_wallet->store();
+ m_wallet->change_password(m_wallet->get_wallet_file(), req.old_password, req.new_password);
LOG_PRINT_L0("Wallet password changed.");
}
catch (const std::exception& e)
diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h
index ab896aa3b..35ea11902 100644
--- a/src/wallet/wallet_rpc_server.h
+++ b/src/wallet/wallet_rpc_server.h
@@ -35,6 +35,7 @@
#include <string>
#include "common/util.h"
#include "net/http_server_impl_base.h"
+#include "math_helper.h"
#include "wallet_rpc_server_commands_defs.h"
#include "wallet2.h"