aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/blockchain_utilities/CMakeLists.txt2
-rw-r--r--src/blocks/CMakeLists.txt12
-rw-r--r--src/common/CMakeLists.txt4
-rw-r--r--src/common/dns_utils.cpp7
-rw-r--r--src/common/notify.cpp13
-rw-r--r--src/common/password.cpp4
-rw-r--r--src/common/password.h1
-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.cpp4
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp2
-rw-r--r--src/daemon/CMakeLists.txt2
-rw-r--r--src/daemon/rpc_command_executor.cpp20
-rw-r--r--src/simplewallet/simplewallet.cpp4
-rw-r--r--src/version.cpp.in2
-rw-r--r--src/wallet/api/wallet.cpp22
-rw-r--r--src/wallet/api/wallet.h3
-rw-r--r--src/wallet/api/wallet2_api.h5
-rw-r--r--src/wallet/wallet2.cpp15
-rw-r--r--src/wallet/wallet2.h2
-rw-r--r--src/wallet/wallet_rpc_server.cpp25
-rw-r--r--src/wallet/wallet_rpc_server_commands_defs.h4
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()
};
};