diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/blockchain_utilities/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/blocks/CMakeLists.txt | 12 | ||||
-rw-r--r-- | src/common/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/common/dns_utils.cpp | 7 | ||||
-rw-r--r-- | src/common/notify.cpp | 13 | ||||
-rw-r--r-- | src/common/password.cpp | 4 | ||||
-rw-r--r-- | src/common/password.h | 1 | ||||
-rw-r--r-- | src/common/spawn.cpp (renamed from src/common/exec.cpp) | 57 | ||||
-rw-r--r-- | src/common/spawn.h (renamed from src/common/exec.h) | 2 | ||||
-rw-r--r-- | src/cryptonote_core/blockchain.cpp | 4 | ||||
-rw-r--r-- | src/cryptonote_core/cryptonote_tx_utils.cpp | 2 | ||||
-rw-r--r-- | src/daemon/CMakeLists.txt | 2 | ||||
-rw-r--r-- | src/daemon/rpc_command_executor.cpp | 20 | ||||
-rw-r--r-- | src/simplewallet/simplewallet.cpp | 4 | ||||
-rw-r--r-- | src/version.cpp.in | 2 | ||||
-rw-r--r-- | src/wallet/api/wallet.cpp | 22 | ||||
-rw-r--r-- | src/wallet/api/wallet.h | 3 | ||||
-rw-r--r-- | src/wallet/api/wallet2_api.h | 5 | ||||
-rw-r--r-- | src/wallet/wallet2.cpp | 15 | ||||
-rw-r--r-- | src/wallet/wallet2.h | 2 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server.cpp | 25 | ||||
-rw-r--r-- | src/wallet/wallet_rpc_server_commands_defs.h | 4 |
22 files changed, 167 insertions, 45 deletions
diff --git a/src/blockchain_utilities/CMakeLists.txt b/src/blockchain_utilities/CMakeLists.txt index 37bca671f..ecd7b754c 100644 --- a/src/blockchain_utilities/CMakeLists.txt +++ b/src/blockchain_utilities/CMakeLists.txt @@ -32,6 +32,8 @@ if(PER_BLOCK_CHECKPOINT) 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() diff --git a/src/blocks/CMakeLists.txt b/src/blocks/CMakeLists.txt index cf3f0b354..ebb5408cc 100644 --- a/src/blocks/CMakeLists.txt +++ b/src/blocks/CMakeLists.txt @@ -30,9 +30,15 @@ if(APPLE) add_library(blocks STATIC blockexports.c) set_target_properties(blocks PROPERTIES LINKER_LANGUAGE C) 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) + 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() diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 9b83f149f..aed9bfee7 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -34,13 +34,13 @@ set(common_sources dns_utils.cpp download.cpp error.cpp - exec.cpp expect.cpp util.cpp i18n.cpp notify.cpp password.cpp perf_timer.cpp + spawn.cpp threadpool.cpp updates.cpp aligned.c) @@ -60,7 +60,6 @@ set(common_private_headers dns_utils.h download.h error.h - exec.h expect.h http_connection.h int-util.h @@ -74,6 +73,7 @@ set(common_private_headers i18n.h password.h perf_timer.h + spawn.h stack_trace.h threadpool.h updates.h diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp index 3f2bde620..f2b270981 100644 --- a/src/common/dns_utils.cpp +++ b/src/common/dns_utils.cpp @@ -46,10 +46,11 @@ namespace bf = boost::filesystem; static const char *DEFAULT_DNS_PUBLIC_ADDR[] = { "194.150.168.168", // CCC (Germany) - "81.3.27.54", // Lightning Wire Labs (Germany) - "31.3.135.232", // OpenNIC (Switzerland) "80.67.169.40", // FDN (France) - "209.58.179.186", // Cyberghost (Singapore) + "89.233.43.71", // http://censurfridns.dk (Denmark) + "109.69.8.51", // punCAT (Spain) + "77.109.148.137", // Xiala.net (Switzerland) + "193.58.251.251", // SkyDNS (Russia) }; static boost::mutex instance_lock; diff --git a/src/common/notify.cpp b/src/common/notify.cpp index b7869ad84..cadc68ea7 100644 --- a/src/common/notify.cpp +++ b/src/common/notify.cpp @@ -29,12 +29,17 @@ #include <boost/algorithm/string.hpp> #include "misc_log_ex.h" #include "file_io_utils.h" -#include "exec.h" +#include "spawn.h" #include "notify.h" namespace tools { +/* + TODO: + - Improve tokenization to handle paths containing whitespaces, quotes, etc. + - Windows unicode support (implies implementing unicode command line parsing code) +*/ Notify::Notify(const char *spec) { CHECK_AND_ASSERT_THROW_MES(spec, "Null spec"); @@ -51,11 +56,7 @@ int Notify::notify(const char *parameter) for (std::string &s: margs) boost::replace_all(s, "%s", parameter); - char **cargs = (char**)alloca(sizeof(char*) * (margs.size() + 1)); - for (size_t n = 0; n < margs.size(); ++n) - cargs[n] = (char*)margs[n].c_str(); - cargs[margs.size()] = NULL; - return tools::exec(filename.c_str(), cargs, false); + return tools::spawn(filename.c_str(), margs, false); } } diff --git a/src/common/password.cpp b/src/common/password.cpp index 5671c4a4e..b32bedae2 100644 --- a/src/common/password.cpp +++ b/src/common/password.cpp @@ -221,6 +221,10 @@ namespace tools : m_password(std::move(password)) { } + password_container::password_container(const epee::wipeable_string& password) noexcept + : m_password(password) + { + } password_container::~password_container() noexcept { diff --git a/src/common/password.h b/src/common/password.h index 529881e40..beb98283b 100644 --- a/src/common/password.h +++ b/src/common/password.h @@ -47,6 +47,7 @@ namespace tools //! `password` is used as password password_container(std::string&& password) noexcept; + password_container(const epee::wipeable_string& password) noexcept; //! \return A password from stdin TTY prompt or `std::cin` pipe. static boost::optional<password_container> prompt(bool verify, const char *mesage = "Password", bool hide_input = true); diff --git a/src/common/exec.cpp b/src/common/spawn.cpp index 41b8f1378..59f11675c 100644 --- a/src/common/exec.cpp +++ b/src/common/spawn.cpp @@ -29,16 +29,68 @@ #include <errno.h> #include <unistd.h> #include <sys/types.h> +#ifdef _WIN32 +#include <boost/algorithm/string/join.hpp> +#include <boost/scope_exit.hpp> +#include <windows.h> +#else #include <sys/wait.h> +#endif #include "misc_log_ex.h" -#include "exec.h" +#include "spawn.h" namespace tools { -int exec(const char *filename, char * const argv[], bool wait) +int spawn(const char *filename, const std::vector<std::string>& args, bool wait) { +#ifdef _WIN32 + std::string joined = boost::algorithm::join(args, " "); + char *commandLine = !joined.empty() ? &joined[0] : nullptr; + STARTUPINFOA si = {}; + si.cb = sizeof(si); + PROCESS_INFORMATION pi; + if (!CreateProcessA(filename, commandLine, nullptr, nullptr, false, 0, nullptr, nullptr, &si, &pi)) + { + MERROR("CreateProcess failed. Error code " << GetLastError()); + return -1; + } + + BOOST_SCOPE_EXIT(&pi) + { + CloseHandle(pi.hThread); + CloseHandle(pi.hProcess); + } + BOOST_SCOPE_EXIT_END + + if (!wait) + { + return 0; + } + + DWORD result = WaitForSingleObject(pi.hProcess, INFINITE); + if (result != WAIT_OBJECT_0) + { + MERROR("WaitForSingleObject failed. Result " << result << ", error code " << GetLastError()); + return -1; + } + + DWORD exitCode; + if (!GetExitCodeProcess(pi.hProcess, &exitCode)) + { + MERROR("GetExitCodeProcess failed. Error code " << GetLastError()); + return -1; + } + + MINFO("Child exited with " << exitCode); + return static_cast<int>(exitCode); +#else + char **argv = (char**)alloca(sizeof(char*) * (args.size() + 1)); + for (size_t n = 0; n < args.size(); ++n) + argv[n] = (char*)args[n].c_str(); + argv[args.size()] = NULL; + pid_t pid = fork(); if (pid < 0) { @@ -83,6 +135,7 @@ int exec(const char *filename, char * const argv[], bool wait) } MERROR("Secret passage found"); return -1; +#endif } } diff --git a/src/common/exec.h b/src/common/spawn.h index 4d2037798..c90a0f790 100644 --- a/src/common/exec.h +++ b/src/common/spawn.h @@ -31,6 +31,6 @@ namespace tools { -int exec(const char *filename, char * const argv[], bool wait); +int spawn(const char *filename, const std::vector<std::string>& args, bool wait); } diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index fb4dcef7c..eb869b795 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -138,8 +138,8 @@ static const struct { { 6, 971400, 0, 1501709789 }, { 7, 1057027, 0, 1512211236 }, - { 8, 1057058, 0, 1515967497 }, - { 9, 1057778, 0, 1515967498 }, + { 8, 1057058, 0, 1533211200 }, + { 9, 1057778, 0, 1533297600 }, }; static const uint64_t testnet_hard_fork_version_1_till = 624633; diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index fb2af9ceb..4bc33b56b 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -127,7 +127,7 @@ namespace cryptonote out_amounts[1] += out_amounts[0]; for (size_t n = 1; n < out_amounts.size(); ++n) out_amounts[n - 1] = out_amounts[n]; - out_amounts.resize(out_amounts.size() - 1); + out_amounts.pop_back(); } } else diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index b1c4b711d..f645836a4 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -32,6 +32,8 @@ if(PER_BLOCK_CHECKPOINT) 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() diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index 6b6c88907..6464d372f 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -442,7 +442,8 @@ bool t_rpc_command_executor::show_status() { } } - tools::success_msg_writer() << boost::format("Height: %llu/%llu (%.1f%%) on %s%s, %s, net hash %s, v%u%s, %s, %u(out)+%u(in) connections, uptime %ud %uh %um %us") + std::stringstream str; + str << boost::format("Height: %llu/%llu (%.1f%%) on %s%s, %s, net hash %s, v%u%s, %s, %u(out)+%u(in) connections") % (unsigned long long)ires.height % (unsigned long long)net_height % get_sync_percentage(ires) @@ -455,12 +456,21 @@ bool t_rpc_command_executor::show_status() { % (hfres.state == cryptonote::HardFork::Ready ? "up to date" : hfres.state == cryptonote::HardFork::UpdateNeeded ? "update needed" : "out of date, likely forked") % (unsigned)ires.outgoing_connections_count % (unsigned)ires.incoming_connections_count - % (unsigned int)floor(uptime / 60.0 / 60.0 / 24.0) - % (unsigned int)floor(fmod((uptime / 60.0 / 60.0), 24.0)) - % (unsigned int)floor(fmod((uptime / 60.0), 60.0)) - % (unsigned int)fmod(uptime, 60.0) ; + // restricted RPC does not disclose start time + if (ires.start_time) + { + str << boost::format(", uptime %ud %uh %um %us") + % (unsigned int)floor(uptime / 60.0 / 60.0 / 24.0) + % (unsigned int)floor(fmod((uptime / 60.0 / 60.0), 24.0)) + % (unsigned int)floor(fmod((uptime / 60.0), 60.0)) + % (unsigned int)fmod(uptime, 60.0) + ; + } + + tools::success_msg_writer() << str.str(); + return true; } diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 7c68de3f3..90f8535d7 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -3275,7 +3275,9 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm) { try { - m_wallet = tools::wallet2::make_from_json(vm, false, m_generate_from_json, password_prompter); + auto rc = tools::wallet2::make_from_json(vm, false, m_generate_from_json, password_prompter); + m_wallet = std::move(rc.first); + password = rc.second.password(); m_wallet_file = m_wallet->path(); } catch (const std::exception &e) diff --git a/src/version.cpp.in b/src/version.cpp.in index ff2405811..55075a064 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.0-master" +#define DEF_MONERO_VERSION "0.13.0.1-rc" #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 3d4e981ea..236928348 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -2146,6 +2146,28 @@ bool WalletImpl::blackballOutputs(const std::vector<std::string> &outputs, bool return true; } +bool WalletImpl::blackballOutput(const std::string &amount, const std::string &offset) +{ + uint64_t raw_amount, raw_offset; + if (!epee::string_tools::get_xtype_from_string(raw_amount, amount)) + { + setStatusError(tr("Failed to parse output amount")); + return false; + } + if (!epee::string_tools::get_xtype_from_string(raw_offset, offset)) + { + setStatusError(tr("Failed to parse output offset")); + return false; + } + bool ret = m_wallet->blackball_output(std::make_pair(raw_amount, raw_offset)); + if (!ret) + { + setStatusError(tr("Failed to blackball output")); + return false; + } + return true; +} + bool WalletImpl::unblackballOutput(const std::string &amount, const std::string &offset) { uint64_t raw_amount, raw_offset; diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 5963a7607..8e2af347d 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -182,7 +182,8 @@ public: virtual std::string getDefaultDataDir() const override; virtual bool lightWalletLogin(bool &isNewWallet) const override; virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) override; - virtual bool blackballOutputs(const std::vector<std::string> &pubkeys, bool add) override; + virtual bool blackballOutputs(const std::vector<std::string> &outputs, bool add) override; + virtual bool blackballOutput(const std::string &amount, const std::string &offset) override; virtual bool unblackballOutput(const std::string &amount, const std::string &offset) override; virtual bool getRing(const std::string &key_image, std::vector<uint64_t> &ring) const override; virtual bool getRings(const std::string &txid, std::vector<std::pair<std::string, std::vector<uint64_t>>> &rings) const override; diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index e0d491705..68ea26262 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -881,7 +881,10 @@ struct Wallet virtual bool rescanSpent() = 0; //! blackballs a set of outputs - virtual bool blackballOutputs(const std::vector<std::string> &pubkeys, bool add) = 0; + virtual bool blackballOutputs(const std::vector<std::string> &outputs, bool add) = 0; + + //! blackballs an output + virtual bool blackballOutput(const std::string &amount, const std::string &offset) = 0; //! unblackballs an output virtual bool unblackballOutput(const std::string &amount, const std::string &offset) = 0; diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 299b4afeb..e6ab10756 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -313,7 +313,7 @@ boost::optional<tools::password_container> get_password(const boost::program_opt return password_prompter(verify ? tr("Enter a new password for the wallet") : tr("Wallet password"), verify); } -std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, bool unattended, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) +std::pair<std::unique_ptr<tools::wallet2>, tools::password_container> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, bool unattended, const options& opts, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) { const bool testnet = command_line::get_arg(vm, opts.testnet); const bool stagenet = command_line::get_arg(vm, opts.stagenet); @@ -323,6 +323,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, false. Gcc will coerce this into unique_ptr(nullptr), but clang correctly fails. This large wrapper is for the use of that macro */ std::unique_ptr<tools::wallet2> wallet; + epee::wipeable_string password; const auto do_generate = [&]() -> bool { std::string buf; if (!epee::file_io_utils::load_file_to_string(json_file, buf)) { @@ -460,10 +461,12 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, if (!field_seed.empty()) { wallet->generate(field_filename, field_password, recovery_key, recover, false, create_address_file); + password = field_password; } else if (field_viewkey.empty() && !field_spendkey.empty()) { wallet->generate(field_filename, field_password, spendkey, recover, false, create_address_file); + password = field_password; } else { @@ -490,6 +493,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("Address must be specified in order to create watch-only wallet")); } wallet->generate(field_filename, field_password, address, viewkey, create_address_file); + password = field_password; } else { @@ -497,6 +501,7 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("failed to verify spend key secret key")); } wallet->generate(field_filename, field_password, address, spendkey, viewkey, create_address_file); + password = field_password; } } } @@ -509,9 +514,9 @@ std::unique_ptr<tools::wallet2> generate_from_json(const std::string& json_file, if (do_generate()) { - return wallet; + return {std::move(wallet), tools::password_container(password)}; } - return nullptr; + return {nullptr, tools::password_container{}}; } static void throw_on_rpc_response_error(const boost::optional<std::string> &status, const char *method) @@ -854,7 +859,7 @@ void wallet2::init_options(boost::program_options::options_description& desc_par command_line::add_arg(desc_params, opts.tx_notify); } -std::unique_ptr<wallet2> wallet2::make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) +std::pair<std::unique_ptr<wallet2>, tools::password_container> wallet2::make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function<boost::optional<tools::password_container>(const char *, bool)> &password_prompter) { const options opts{}; return generate_from_json(json_file, vm, unattended, opts, password_prompter); @@ -1339,7 +1344,6 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote // (that is, the prunable stuff may or may not be included) if (!miner_tx && !pool) process_unconfirmed(txid, tx, height); - std::vector<size_t> outs; std::unordered_map<cryptonote::subaddress_index, uint64_t> tx_money_got_in_outs; // per receiving subaddress index crypto::public_key tx_pub_key = null_pkey; bool notify = false; @@ -1362,6 +1366,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote uint64_t total_received_1 = 0; while (!tx.vout.empty()) { + std::vector<size_t> outs; // if tx.vout is not empty, we loop through all tx pubkeys tx_extra_pub_key pub_key_field; diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index 497dd486f..7857f36f1 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -177,7 +177,7 @@ namespace tools static void init_options(boost::program_options::options_description& desc_params); //! 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, bool unattended, const std::string& json_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter); + static std::pair<std::unique_ptr<wallet2>, password_container> make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function<boost::optional<password_container>(const char *, bool)> &password_prompter); //! Uses stdin and stdout. Returns a wallet2 and password for `wallet_file` if no errors. static std::pair<std::unique_ptr<wallet2>, password_container> diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index 5991e0cc2..2b5ef3157 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -2173,8 +2173,8 @@ namespace tools for (std::list<std::pair<crypto::hash, tools::wallet2::payment_details>>::const_iterator i = payments.begin(); i != payments.end(); ++i) { if (i->second.m_tx_hash == txid) { - fill_transfer_entry(res.transfer, i->second.m_tx_hash, i->first, i->second); - return true; + res.transfers.resize(res.transfers.size() + 1); + fill_transfer_entry(res.transfers.back(), i->second.m_tx_hash, i->first, i->second); } } @@ -2183,8 +2183,8 @@ namespace tools for (std::list<std::pair<crypto::hash, tools::wallet2::confirmed_transfer_details>>::const_iterator i = payments_out.begin(); i != payments_out.end(); ++i) { if (i->first == txid) { - fill_transfer_entry(res.transfer, i->first, i->second); - return true; + res.transfers.resize(res.transfers.size() + 1); + fill_transfer_entry(res.transfers.back(), i->first, i->second); } } @@ -2193,8 +2193,8 @@ namespace tools for (std::list<std::pair<crypto::hash, tools::wallet2::unconfirmed_transfer_details>>::const_iterator i = upayments.begin(); i != upayments.end(); ++i) { if (i->first == txid) { - fill_transfer_entry(res.transfer, i->first, i->second); - return true; + res.transfers.resize(res.transfers.size() + 1); + fill_transfer_entry(res.transfers.back(), i->first, i->second); } } @@ -2205,11 +2205,17 @@ namespace tools for (std::list<std::pair<crypto::hash, tools::wallet2::pool_payment_details>>::const_iterator i = pool_payments.begin(); i != pool_payments.end(); ++i) { if (i->second.m_pd.m_tx_hash == txid) { - fill_transfer_entry(res.transfer, i->first, i->second); - return true; + res.transfers.resize(res.transfers.size() + 1); + fill_transfer_entry(res.transfers.back(), i->first, i->second); } } + if (!res.transfers.empty()) + { + res.transfer = res.transfers.front(); // backward compat + return true; + } + er.code = WALLET_RPC_ERROR_CODE_WRONG_TXID; er.message = "Transaction not found."; return false; @@ -3352,7 +3358,8 @@ public: { try { - wal = tools::wallet2::make_from_json(vm, true, from_json, password_prompt); + auto rc = tools::wallet2::make_from_json(vm, true, from_json, password_prompt); + wal = std::move(rc.first); } catch (const std::exception &e) { diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 81ea22928..e46745339 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -47,7 +47,7 @@ // advance which version they will stop working with // Don't go over 32767 for any of these #define WALLET_RPC_VERSION_MAJOR 1 -#define WALLET_RPC_VERSION_MINOR 3 +#define WALLET_RPC_VERSION_MINOR 4 #define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR) namespace tools @@ -1399,9 +1399,11 @@ namespace wallet_rpc struct response { transfer_entry transfer; + std::list<transfer_entry> transfers; BEGIN_KV_SERIALIZE_MAP() KV_SERIALIZE(transfer); + KV_SERIALIZE(transfers); END_KV_SERIALIZE_MAP() }; }; |