aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml22
-rw-r--r--.gitmodules4
-rw-r--r--CMakeLists.txt6
-rw-r--r--README.md6
-rw-r--r--contrib/depends/packages/expat.mk6
-rw-r--r--contrib/depends/packages/ldns.mk6
-rw-r--r--contrib/depends/packages/packages.mk2
-rw-r--r--contrib/depends/packages/unbound.mk8
-rw-r--r--contrib/depends/toolchain.cmake.in3
-rw-r--r--contrib/epee/include/net/http_protocol_handler.inl2
-rw-r--r--contrib/epee/include/stats.inl3
-rw-r--r--contrib/epee/src/http_base.cpp2
-rw-r--r--contrib/epee/src/net_parse_helpers.cpp2
-rw-r--r--contrib/epee/src/parserse_base_utils.cpp10
-rw-r--r--external/CMakeLists.txt20
-rw-r--r--external/easylogging++/easylogging++.h1
m---------external/unbound0
-rw-r--r--src/common/CMakeLists.txt2
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp6
-rw-r--r--src/cryptonote_core/cryptonote_core.h3
-rw-r--r--src/daemon/command_line_args.h10
-rw-r--r--src/daemon/core.h10
-rw-r--r--src/daemon/main.cpp2
-rw-r--r--src/daemon/p2p.h3
-rw-r--r--src/daemon/rpc.h2
-rw-r--r--src/device/device.hpp1
-rw-r--r--src/net/socks.h7
-rw-r--r--src/p2p/net_node.cpp8
-rw-r--r--src/p2p/net_node.h4
-rw-r--r--src/p2p/net_node.inl19
-rw-r--r--src/ringct/multiexp.cc2
-rw-r--r--src/rpc/core_rpc_server.cpp6
-rw-r--r--src/rpc/core_rpc_server.h4
-rw-r--r--src/wallet/wallet2.cpp73
-rw-r--r--src/wallet/wallet_args.cpp4
-rw-r--r--src/wallet/wallet_args.h1
-rw-r--r--src/wallet/wallet_rpc_server.cpp11
-rw-r--r--tests/core_tests/transaction_tests.cpp1
-rw-r--r--tests/unit_tests/logging.cpp7
-rw-r--r--tests/unit_tests/node_server.cpp3
40 files changed, 190 insertions, 102 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 7c28a71ce..c3c552dd8 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -27,8 +27,8 @@ jobs:
- uses: actions/cache@v2
with:
path: /Users/runner/Library/Caches/ccache
- key: ccache-macos-build-${{ github.sha }}
- restore-keys: ccache-macos-build-
+ key: ccache-${{ runner.os }}-build-${{ github.sha }}
+ restore-keys: ccache-${{ runner.os }}-build-
- name: install dependencies
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi zmq libpgm miniupnpc ldns expat libunwind-headers protobuf ccache
- name: build
@@ -52,12 +52,12 @@ jobs:
- uses: actions/cache@v2
with:
path: C:\Users\runneradmin\.ccache
- key: ccache-windows-build-${{ github.sha }}
- restore-keys: ccache-windows-build-
+ key: ccache-${{ runner.os }}-build-${{ github.sha }}
+ restore-keys: ccache-${{ runner.os }}-build-
- uses: eine/setup-msys2@v2
with:
update: true
- install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-ccache mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb git
+ install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-ccache mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb mingw-w64-x86_64-unbound git
- name: build
run: |
ccache --max-size=150M
@@ -81,8 +81,8 @@ jobs:
- uses: actions/cache@v2
with:
path: ~/.ccache
- key: ccache-ubuntu-build-${{ matrix.os }}-${{ github.sha }}
- restore-keys: ccache-ubuntu-build-${{ matrix.os }}
+ key: ccache-${{ runner.os }}-build-${{ matrix.os }}-${{ github.sha }}
+ restore-keys: ccache-${{ runner.os }}-build-${{ matrix.os }}
- name: remove bundled boost
run: ${{env.REMOVE_BUNDLED_BOOST}}
- name: set apt conf
@@ -106,8 +106,8 @@ jobs:
- uses: actions/cache@v2
with:
path: ~/.ccache
- key: ccache-ubuntu-libwallet-${{ github.sha }}
- restore-keys: ccache-ubuntu-libwallet-
+ key: ccache-${{ runner.os }}-libwallet-${{ github.sha }}
+ restore-keys: ccache-${{ runner.os }}-libwallet-
- name: remove bundled boost
run: ${{env.REMOVE_BUNDLED_BOOST}}
- name: set apt conf
@@ -136,8 +136,8 @@ jobs:
uses: actions/cache@v2
with:
path: ~/.ccache
- key: ccache-ubuntu-build-ubuntu-latest-${{ github.sha }}
- restore-keys: ccache-ubuntu-build-ubuntu-latest
+ key: ccache-${{ runner.os }}-build-ubuntu-latest-${{ github.sha }}
+ restore-keys: ccache-${{ runner.os }}-build-ubuntu-latest
- name: remove bundled boost
run: ${{env.REMOVE_BUNDLED_BOOST}}
- name: set apt conf
diff --git a/.gitmodules b/.gitmodules
index 3cf831bcd..721cce3b4 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,7 +1,3 @@
-[submodule "external/unbound"]
- path = external/unbound
- url = https://github.com/monero-project/unbound
- branch = monero
[submodule "external/miniupnp"]
path = external/miniupnp
url = https://github.com/miniupnp/miniupnp
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f8af45f4b..1b9ba570d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -106,6 +106,8 @@ function (die msg)
endfunction ()
function (add_c_flag_if_supported flag var)
+ # Prepending the flag with -Werror will only add the flag,
+ # if it doesn't result in generation of a warning of using a flag unknown to the compiler.
set(TMP "-Werror ${flag}")
string(REGEX REPLACE "[- ]" "_" supported ${TMP}_c)
check_c_compiler_flag(${TMP} ${supported})
@@ -345,7 +347,6 @@ if(NOT MANUAL_SUBMODULES)
message(STATUS "Checking submodules")
check_submodule(external/miniupnp)
- check_submodule(external/unbound)
check_submodule(external/rapidjson)
check_submodule(external/trezor-common)
check_submodule(external/randomx)
@@ -672,8 +673,7 @@ include_directories("${CMAKE_CURRENT_BINARY_DIR}/translations")
add_subdirectory(external)
# Final setup for libunbound
-include_directories(${UNBOUND_INCLUDE})
-link_directories(${UNBOUND_LIBRARY_DIRS})
+include_directories(${UNBOUND_INCLUDE_DIR})
# Final setup for easylogging++
include_directories(${EASYLOGGING_INCLUDE})
diff --git a/README.md b/README.md
index aa86e7c1e..feb2f641d 100644
--- a/README.md
+++ b/README.md
@@ -202,7 +202,7 @@ Install all dependencies at once on macOS with the provided Brewfile:
``` brew update && brew bundle --file=contrib/brew/Brewfile ```
FreeBSD 12.1 one-liner required to build dependencies:
-```pkg install git gmake cmake pkgconf boost-libs libzmq4 libsodium```
+```pkg install git gmake cmake pkgconf boost-libs libzmq4 libsodium unbound```
### Cloning the repository
@@ -399,13 +399,13 @@ application.
To build for 64-bit Windows:
```bash
- pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi
+ pacman -S mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-unbound
```
To build for 32-bit Windows:
```bash
- pacman -S mingw-w64-i686-toolchain make mingw-w64-i686-cmake mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-zeromq mingw-w64-i686-libsodium mingw-w64-i686-hidapi
+ pacman -S mingw-w64-i686-toolchain make mingw-w64-i686-cmake mingw-w64-i686-boost mingw-w64-i686-openssl mingw-w64-i686-zeromq mingw-w64-i686-libsodium mingw-w64-i686-hidapi mingw-w64-i686-unbound
```
* Open the MingW shell via `MinGW-w64-Win64 Shell` shortcut on 64-bit Windows
diff --git a/contrib/depends/packages/expat.mk b/contrib/depends/packages/expat.mk
index d73a5e307..1e1b9dbb8 100644
--- a/contrib/depends/packages/expat.mk
+++ b/contrib/depends/packages/expat.mk
@@ -1,8 +1,8 @@
package=expat
-$(package)_version=2.2.4
-$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_4
+$(package)_version=2.4.1
+$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_4_1
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
-$(package)_sha256_hash=03ad85db965f8ab2d27328abcf0bc5571af6ec0a414874b2066ee3fdd372019e
+$(package)_sha256_hash=2f9b6a580b94577b150a7d5617ad4643a4301a6616ff459307df3e225bcfbf40
define $(package)_set_vars
$(package)_config_opts=--enable-static
diff --git a/contrib/depends/packages/ldns.mk b/contrib/depends/packages/ldns.mk
index 6fbcc3466..90c63e821 100644
--- a/contrib/depends/packages/ldns.mk
+++ b/contrib/depends/packages/ldns.mk
@@ -1,8 +1,8 @@
package=ldns
-$(package)_version=1.6.17
-$(package)_download_path=https://www.nlnetlabs.nl/downloads/ldns/
+$(package)_version=1.7.1
+$(package)_download_path=https://www.nlnetlabs.nl/downloads/$(package)/
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=8b88e059452118e8949a2752a55ce59bc71fa5bc414103e17f5b6b06f9bcc8cd
+$(package)_sha256_hash=8ac84c16bdca60e710eea75782356f3ac3b55680d40e1530d7cea474ac208229
$(package)_dependencies=openssl
define $(package)_set_vars
diff --git a/contrib/depends/packages/packages.mk b/contrib/depends/packages/packages.mk
index 95b23a37e..56ce425bb 100644
--- a/contrib/depends/packages/packages.mk
+++ b/contrib/depends/packages/packages.mk
@@ -1,4 +1,4 @@
-packages:=boost openssl zeromq libiconv
+packages:=boost openssl zeromq libiconv expat ldns unbound
native_packages := native_ccache
diff --git a/contrib/depends/packages/unbound.mk b/contrib/depends/packages/unbound.mk
index 733a7f232..2d870d63f 100644
--- a/contrib/depends/packages/unbound.mk
+++ b/contrib/depends/packages/unbound.mk
@@ -1,12 +1,12 @@
package=unbound
-$(package)_version=1.6.8
-$(package)_download_path=https://www.unbound.net/downloads/
+$(package)_version=1.13.2
+$(package)_download_path=https://www.nlnetlabs.nl/downloads/$(package)/
$(package)_file_name=$(package)-$($(package)_version).tar.gz
-$(package)_sha256_hash=e3b428e33f56a45417107448418865fe08d58e0e7fea199b855515f60884dd49
+$(package)_sha256_hash=0a13b547f3b92a026b5ebd0423f54c991e5718037fd9f72445817f6a040e1a83
$(package)_dependencies=openssl expat ldns
define $(package)_set_vars
- $(package)_config_opts=--disable-shared --enable-static --without-pyunbound --prefix=$(host_prefix) --with-libexpat=$(host_prefix) --with-ssl=$(host_prefix) --with-libevent=no --without-pythonmodule --disable-flto --with-pthreads
+ $(package)_config_opts=--disable-shared --enable-static --without-pyunbound --prefix=$(host_prefix) --with-libexpat=$(host_prefix) --with-ssl=$(host_prefix) --with-libevent=no --without-pythonmodule --disable-flto --with-pthreads --with-libunbound-only
$(package)_config_opts_linux=--with-pic
$(package)_config_opts_w64=--enable-static-exe --sysconfdir=/etc --prefix=$(host_prefix) --target=$(host_prefix)
$(package)_build_opts_mingw32=LDFLAGS="$($(package)_ldflags) -lpthread"
diff --git a/contrib/depends/toolchain.cmake.in b/contrib/depends/toolchain.cmake.in
index 383b88f31..a87b9c058 100644
--- a/contrib/depends/toolchain.cmake.in
+++ b/contrib/depends/toolchain.cmake.in
@@ -24,6 +24,9 @@ SET(Readline_INCLUDE_DIR @prefix@/include)
SET(Readline_LIBRARY @prefix@/lib/libreadline.a)
SET(Terminfo_LIBRARY @prefix@/lib/libtinfo.a)
+SET(UNBOUND_INCLUDE_DIR @prefix@/include)
+SET(UNBOUND_LIBRARIES @prefix@/lib/libunbound.a)
+
SET(LRELEASE_PATH @prefix@/native/bin CACHE FILEPATH "path to lrelease" FORCE)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
diff --git a/contrib/epee/include/net/http_protocol_handler.inl b/contrib/epee/include/net/http_protocol_handler.inl
index 19bdf4ff0..0f4a28c99 100644
--- a/contrib/epee/include/net/http_protocol_handler.inl
+++ b/contrib/epee/include/net/http_protocol_handler.inl
@@ -668,7 +668,7 @@ namespace net_utils
// Cross-origin resource sharing
if(m_query_info.m_header_info.m_origin.size())
{
- if (std::binary_search(m_config.m_access_control_origins.begin(), m_config.m_access_control_origins.end(), m_query_info.m_header_info.m_origin))
+ if (std::binary_search(m_config.m_access_control_origins.begin(), m_config.m_access_control_origins.end(), "*") || std::binary_search(m_config.m_access_control_origins.begin(), m_config.m_access_control_origins.end(), m_query_info.m_header_info.m_origin))
{
buf += "Access-Control-Allow-Origin: ";
buf += m_query_info.m_header_info.m_origin;
diff --git a/contrib/epee/include/stats.inl b/contrib/epee/include/stats.inl
index 5a5cd0b93..70c127be7 100644
--- a/contrib/epee/include/stats.inl
+++ b/contrib/epee/include/stats.inl
@@ -1,6 +1,7 @@
#include <math.h>
#include <limits>
#include <algorithm>
+#include "misc_language.h"
#include "stats.h"
enum
@@ -86,7 +87,7 @@ Tpod Stats<T, Tpod>::get_median() const
}
else
{
- median = (sorted[(sorted.size() - 1) / 2] + sorted[sorted.size() / 2]) / 2;
+ median = epee::misc_utils::get_mid(sorted[(sorted.size() - 1) / 2], sorted[sorted.size() / 2]);
}
set_cached(bit_median);
}
diff --git a/contrib/epee/src/http_base.cpp b/contrib/epee/src/http_base.cpp
index 647dfb899..f6d7568c5 100644
--- a/contrib/epee/src/http_base.cpp
+++ b/contrib/epee/src/http_base.cpp
@@ -44,7 +44,7 @@ namespace http
std::string get_value_from_fields_list(const std::string& param_name, const net_utils::http::fields_list& fields)
{
fields_list::const_iterator it = fields.begin();
- for(; it != fields.end(); it++)
+ for(; it != fields.end(); ++it)
if(!string_tools::compare_no_case(param_name, it->first))
break;
diff --git a/contrib/epee/src/net_parse_helpers.cpp b/contrib/epee/src/net_parse_helpers.cpp
index de7843b67..2697bdac4 100644
--- a/contrib/epee/src/net_parse_helpers.cpp
+++ b/contrib/epee/src/net_parse_helpers.cpp
@@ -48,7 +48,7 @@ namespace net_utils
state st = st_param_name;
std::string::const_iterator start_it = query.begin();
std::pair<std::string, std::string> e;
- for(std::string::const_iterator it = query.begin(); it != query.end(); it++)
+ for(std::string::const_iterator it = query.begin(); it != query.end(); ++it)
{
switch(st)
{
diff --git a/contrib/epee/src/parserse_base_utils.cpp b/contrib/epee/src/parserse_base_utils.cpp
index 112e9c5e4..e96c2dede 100644
--- a/contrib/epee/src/parserse_base_utils.cpp
+++ b/contrib/epee/src/parserse_base_utils.cpp
@@ -102,7 +102,7 @@ namespace misc_utils
++fi;
val.assign(it, fi);
it = fi;
- for(;it != buf_end;it++)
+ for(;it != buf_end;++it)
{
if(escape_mode/*prev_ch == '\\'*/)
{
@@ -197,7 +197,7 @@ namespace misc_utils
++chars;
++it;
}
- for(;it != buf_end;it++)
+ for(;it != buf_end;++it)
{
const uint8_t flags = lut[(uint8_t)*it];
if (flags & 16)
@@ -224,7 +224,7 @@ namespace misc_utils
{
val.clear();
- for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
+ for(std::string::const_iterator it = star_end_string;it != buf_end;++it)
{
if (!(lut[(uint8_t)*it] & 4))
{
@@ -243,7 +243,7 @@ namespace misc_utils
{
val.clear();
- for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
+ for(std::string::const_iterator it = star_end_string;it != buf_end;++it)
{
if(!isalnum(*it) && *it != '-' && *it != '_')
{
@@ -262,7 +262,7 @@ namespace misc_utils
{
word_end = star_end_string;
- for(std::string::const_iterator it = star_end_string;it != buf_end;it++)
+ for(std::string::const_iterator it = star_end_string;it != buf_end;++it)
{
if(isspace(*it))
{
diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt
index 7ae4ba750..5b7f69a56 100644
--- a/external/CMakeLists.txt
+++ b/external/CMakeLists.txt
@@ -55,26 +55,12 @@ set(UPNP_LIBRARIES "libminiupnpc-static" PARENT_SCOPE)
find_package(Unbound)
-if(NOT UNBOUND_INCLUDE_DIR OR STATIC)
- # NOTE: If STATIC is true, CMAKE_FIND_LIBRARY_SUFFIXES has been reordered.
- # unbound has config tests which used OpenSSL libraries, so -ldl may need to
- # be set in this case.
- # The unbound CMakeLists.txt can set it, since it's also needed for the
- # static OpenSSL libraries set up there after with target_link_libraries.
- add_subdirectory(unbound)
-
- set(UNBOUND_STATIC true PARENT_SCOPE)
- set(UNBOUND_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/unbound/libunbound" PARENT_SCOPE)
- set(UNBOUND_LIBRARY "unbound" PARENT_SCOPE)
- set(UNBOUND_LIBRARY_DIRS "${LIBEVENT2_LIBDIR}" PARENT_SCOPE)
+if(NOT UNBOUND_INCLUDE_DIR)
+ die("Could not find libunbound")
else()
message(STATUS "Found libunbound include (unbound.h) in ${UNBOUND_INCLUDE_DIR}")
if(UNBOUND_LIBRARIES)
- message(STATUS "Found libunbound shared library")
- set(UNBOUND_STATIC false PARENT_SCOPE)
- set(UNBOUND_INCLUDE ${UNBOUND_INCLUDE_DIR} PARENT_SCOPE)
- set(UNBOUND_LIBRARY ${UNBOUND_LIBRARIES} PARENT_SCOPE)
- set(UNBOUND_LIBRARY_DIRS "" PARENT_SCOPE)
+ message(STATUS "Found libunbound library")
else()
die("Found libunbound includes, but could not find libunbound library. Please make sure you have installed libunbound or libunbound-dev or the equivalent")
endif()
diff --git a/external/easylogging++/easylogging++.h b/external/easylogging++/easylogging++.h
index c4a88339f..b983a796c 100644
--- a/external/easylogging++/easylogging++.h
+++ b/external/easylogging++/easylogging++.h
@@ -2026,6 +2026,7 @@ class TypedConfigurations : public base::threading::ThreadSafe {
ELPP_INTERNAL_ERROR("Unable to get configuration [" << confName << "] for level ["
<< LevelHelper::convertToString(level) << "]"
<< std::endl << "Please ensure you have properly configured logger.", false);
+ throw; // The exception has to be rethrown, to abort a branch leading to UB.
}
}
return it->second;
diff --git a/external/unbound b/external/unbound
deleted file mode 160000
-Subproject 0f6c0579d66b65f86066e30e7876105ba2775ef
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 8e427b6b8..99d9bd8bf 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -99,7 +99,7 @@ monero_add_library(common
target_link_libraries(common
PUBLIC
cncrypto
- ${UNBOUND_LIBRARY}
+ ${UNBOUND_LIBRARIES}
${LIBUNWIND_LIBRARIES}
${Boost_DATE_TIME_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index 3b7ccb157..4c6536318 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -388,6 +388,7 @@ namespace cryptonote
m_fluffy_blocks_enabled = !get_arg(vm, arg_no_fluffy_blocks);
m_offline = get_arg(vm, arg_offline);
m_disable_dns_checkpoints = get_arg(vm, arg_disable_dns_checkpoints);
+
if (!command_line::is_arg_defaulted(vm, arg_fluffy_blocks))
MWARNING(arg_fluffy_blocks.name << " is obsolete, it is now default");
@@ -460,7 +461,7 @@ namespace cryptonote
return m_blockchain_storage.get_alternative_blocks_count();
}
//-----------------------------------------------------------------------------------------------
- bool core::init(const boost::program_options::variables_map& vm, const cryptonote::test_options *test_options, const GetCheckpointsCallback& get_checkpoints/* = nullptr */)
+ bool core::init(const boost::program_options::variables_map& vm, const cryptonote::test_options *test_options, const GetCheckpointsCallback& get_checkpoints/* = nullptr */, bool allow_dns)
{
start_time = std::time(nullptr);
@@ -471,6 +472,7 @@ namespace cryptonote
}
bool r = handle_command_line(vm);
CHECK_AND_ASSERT_MES(r, false, "Failed to handle command line");
+ m_disable_dns_checkpoints |= not allow_dns;
std::string db_sync_mode = command_line::get_arg(vm, cryptonote::arg_db_sync_mode);
bool db_salvage = command_line::get_arg(vm, cryptonote::arg_db_salvage) != 0;
@@ -697,7 +699,7 @@ namespace cryptonote
CHECK_AND_ASSERT_MES(update_checkpoints(skip_dns_checkpoints), false, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints.");
// DNS versions checking
- if (check_updates_string == "disabled")
+ if (check_updates_string == "disabled" || not allow_dns)
check_updates_level = UPDATES_DISABLED;
else if (check_updates_string == "notify")
check_updates_level = UPDATES_NOTIFY;
diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h
index dd813733f..d2bffdaee 100644
--- a/src/cryptonote_core/cryptonote_core.h
+++ b/src/cryptonote_core/cryptonote_core.h
@@ -283,10 +283,11 @@ namespace cryptonote
* @param vm command line parameters
* @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
+ * @param allow_dns whether or not to allow DNS requests
*
* @return false if one of the init steps fails, otherwise true
*/
- bool init(const boost::program_options::variables_map& vm, const test_options *test_options = NULL, const GetCheckpointsCallback& get_checkpoints = nullptr);
+ bool init(const boost::program_options::variables_map& vm, const test_options *test_options = NULL, const GetCheckpointsCallback& get_checkpoints = nullptr, bool allow_dns = true);
/**
* @copydoc Blockchain::reset_and_set_genesis_block
diff --git a/src/daemon/command_line_args.h b/src/daemon/command_line_args.h
index 6c3e163e6..a988fe25f 100644
--- a/src/daemon/command_line_args.h
+++ b/src/daemon/command_line_args.h
@@ -96,6 +96,16 @@ namespace daemon_args
, 0
};
+ const command_line::arg_descriptor<std::string> arg_proxy = {
+ "proxy",
+ "Network communication through proxy: <socks-ip:port> i.e. \"127.0.0.1:9050\"",
+ "",
+ };
+ const command_line::arg_descriptor<bool> arg_proxy_allow_dns_leaks = {
+ "proxy-allow-dns-leaks",
+ "Allow DNS leaks outside of proxy",
+ false,
+ };
const command_line::arg_descriptor<bool> arg_public_node = {
"public-node"
, "Allow other users to use the node as a remote (restricted RPC mode, view-only commands) and advertise it over P2P"
diff --git a/src/daemon/core.h b/src/daemon/core.h
index 804d7474d..0811cf420 100644
--- a/src/daemon/core.h
+++ b/src/daemon/core.h
@@ -32,6 +32,7 @@
#include "cryptonote_core/cryptonote_core.h"
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
#include "misc_log_ex.h"
+#include "daemon/command_line_args.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "daemon"
@@ -66,7 +67,14 @@ public:
#else
const cryptonote::GetCheckpointsCallback& get_checkpoints = nullptr;
#endif
- if (!m_core.init(m_vm_HACK, nullptr, get_checkpoints))
+
+ if (command_line::is_arg_defaulted(vm, daemon_args::arg_proxy) && command_line::get_arg(vm, daemon_args::arg_proxy_allow_dns_leaks)) {
+ MLOG_RED(el::Level::Warning, "--" << daemon_args::arg_proxy_allow_dns_leaks.name << " is enabled, but --"
+ << daemon_args::arg_proxy.name << " is not specified.");
+ }
+
+ const bool allow_dns = command_line::is_arg_defaulted(vm, daemon_args::arg_proxy) || command_line::get_arg(vm, daemon_args::arg_proxy_allow_dns_leaks);
+ if (!m_core.init(m_vm_HACK, nullptr, get_checkpoints, allow_dns))
{
throw std::runtime_error("Failed to initialize core");
}
diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp
index d413906df..70aec5538 100644
--- a/src/daemon/main.cpp
+++ b/src/daemon/main.cpp
@@ -152,6 +152,8 @@ int main(int argc, char const * argv[])
command_line::add_arg(core_settings, daemon_args::arg_max_log_file_size);
command_line::add_arg(core_settings, daemon_args::arg_max_log_files);
command_line::add_arg(core_settings, daemon_args::arg_max_concurrency);
+ command_line::add_arg(core_settings, daemon_args::arg_proxy);
+ command_line::add_arg(core_settings, daemon_args::arg_proxy_allow_dns_leaks);
command_line::add_arg(core_settings, daemon_args::arg_public_node);
command_line::add_arg(core_settings, daemon_args::arg_zmq_rpc_bind_ip);
command_line::add_arg(core_settings, daemon_args::arg_zmq_rpc_bind_port);
diff --git a/src/daemon/p2p.h b/src/daemon/p2p.h
index f68efccc2..38862c017 100644
--- a/src/daemon/p2p.h
+++ b/src/daemon/p2p.h
@@ -33,6 +33,7 @@
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
#include "p2p/net_node.h"
#include "daemon/protocol.h"
+#include "daemon/command_line_args.h"
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "daemon"
@@ -61,7 +62,7 @@ public:
{
//initialize objects
MGINFO("Initializing p2p server...");
- if (!m_server.init(vm))
+ if (!m_server.init(vm, command_line::get_arg(vm, daemon_args::arg_proxy), command_line::get_arg(vm, daemon_args::arg_proxy_allow_dns_leaks)))
{
throw std::runtime_error("Failed to initialize p2p server.");
}
diff --git a/src/daemon/rpc.h b/src/daemon/rpc.h
index af48bcc45..bff7dc449 100644
--- a/src/daemon/rpc.h
+++ b/src/daemon/rpc.h
@@ -62,7 +62,7 @@ public:
{
MGINFO("Initializing " << m_description << " RPC server...");
- if (!m_server.init(vm, restricted, port, allow_rpc_payment))
+ if (!m_server.init(vm, restricted, port, allow_rpc_payment, command_line::get_arg(vm, daemon_args::arg_proxy)))
{
throw std::runtime_error("Failed to initialize " + m_description + " RPC server.");
}
diff --git a/src/device/device.hpp b/src/device/device.hpp
index 582eb2242..6005e157d 100644
--- a/src/device/device.hpp
+++ b/src/device/device.hpp
@@ -91,7 +91,6 @@ namespace hw {
public:
device(): mode(NONE) {}
- device(const device &hwdev) {}
virtual ~device() {}
explicit virtual operator bool() const = 0;
diff --git a/src/net/socks.h b/src/net/socks.h
index 739c972ab..506b53195 100644
--- a/src/net/socks.h
+++ b/src/net/socks.h
@@ -201,6 +201,13 @@ namespace socks
std::shared_ptr<client> self_;
void operator()(boost::system::error_code error = boost::system::error_code{});
};
+
+ //! Calls `async_close` on `self` at destruction. NOP if `nullptr`.
+ struct close_on_exit
+ {
+ std::shared_ptr<client> self;
+ ~close_on_exit() { async_close{std::move(self)}(); }
+ };
};
template<typename Handler>
diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp
index 84cc1581e..d9050200a 100644
--- a/src/p2p/net_node.cpp
+++ b/src/p2p/net_node.cpp
@@ -94,6 +94,9 @@ namespace
case net::i2p_address::get_type_id():
set = client->set_connect_command(remote.as<net::i2p_address>());
break;
+ case epee::net_utils::ipv4_network_address::get_type_id():
+ set = client->set_connect_command(remote.as<epee::net_utils::ipv4_network_address>());
+ break;
default:
MERROR("Unsupported network address in socks_connect");
return false;
@@ -339,6 +342,7 @@ namespace nodetool
}
};
+ net::socks::client::close_on_exit close_client{};
boost::unique_future<client_result> socks_result{};
{
boost::promise<client_result> socks_promise{};
@@ -347,6 +351,7 @@ namespace nodetool
auto client = net::socks::make_connect_client(
boost::asio::ip::tcp::socket{service}, net::socks::version::v4a, notify{std::move(socks_promise)}
);
+ close_client.self = client;
if (!start_socks(std::move(client), proxy, remote))
return boost::none;
}
@@ -368,7 +373,10 @@ namespace nodetool
{
auto result = socks_result.get();
if (!result.first)
+ {
+ close_client.self.reset();
return {std::move(result.second)};
+ }
MERROR("Failed to make socks connection to " << remote.str() << " (via " << proxy << "): " << result.first.message());
}
diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h
index f2888674b..9e64121be 100644
--- a/src/p2p/net_node.h
+++ b/src/p2p/net_node.h
@@ -259,6 +259,7 @@ namespace nodetool
m_offline(false),
is_closing(false),
m_network_id(),
+ m_enable_dns_seed_nodes(true),
max_connections(1)
{}
virtual ~node_server();
@@ -267,7 +268,7 @@ namespace nodetool
bool run();
network_zone& add_zone(epee::net_utils::zone zone);
- bool init(const boost::program_options::variables_map& vm);
+ bool init(const boost::program_options::variables_map& vm, const std::string& proxy = {}, bool proxy_dns_leaks_allowed = {});
bool deinit();
bool send_stop_signal();
uint32_t get_this_peer_port(){return m_listening_port;}
@@ -516,6 +517,7 @@ namespace nodetool
epee::net_utils::ssl_support_t m_ssl_support;
+ bool m_enable_dns_seed_nodes;
bool m_enable_dns_blocklist;
uint32_t max_connections;
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index cfeac3d37..ac65a57c1 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -741,6 +741,12 @@ namespace nodetool
{
return get_ip_seed_nodes();
}
+ if (!m_enable_dns_seed_nodes)
+ {
+ // TODO: a domain can be set through socks, so that the remote side does the lookup for the DNS seed nodes.
+ m_fallback_seed_nodes_added.test_and_set();
+ return get_ip_seed_nodes();
+ }
std::set<std::string> full_addrs;
@@ -880,10 +886,21 @@ namespace nodetool
}
//-----------------------------------------------------------------------------------
template<class t_payload_net_handler>
- bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm)
+ bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm, const std::string& proxy, bool proxy_dns_leaks_allowed)
{
bool res = handle_command_line(vm);
CHECK_AND_ASSERT_MES(res, false, "Failed to handle command line");
+ if (proxy.size())
+ {
+ const auto endpoint = net::get_tcp_endpoint(proxy);
+ CHECK_AND_ASSERT_MES(endpoint, false, "Failed to parse proxy: " << proxy << " - " << endpoint.error());
+ network_zone& public_zone = m_network_zones[epee::net_utils::zone::public_];
+ public_zone.m_connect = &socks_connect;
+ public_zone.m_proxy_address = *endpoint;
+ public_zone.m_can_pingback = false;
+ m_enable_dns_seed_nodes &= proxy_dns_leaks_allowed;
+ m_enable_dns_blocklist &= proxy_dns_leaks_allowed;
+ }
if (m_nettype == cryptonote::TESTNET)
{
diff --git a/src/ringct/multiexp.cc b/src/ringct/multiexp.cc
index 620f7d0dd..784c90a4e 100644
--- a/src/ringct/multiexp.cc
+++ b/src/ringct/multiexp.cc
@@ -449,7 +449,6 @@ rct::key straus(const std::vector<MultiexpData> &data, const std::shared_ptr<str
STEP = STEP ? STEP : 192;
MULTIEXP_PERF(PERF_TIMER_START_UNIT(setup, 1000000));
- static constexpr unsigned int mask = (1<<STRAUS_C)-1;
std::shared_ptr<straus_cached_data> local_cache = cache == NULL ? straus_init_cache(data) : cache;
ge_cached cached;
ge_p1p1 p1;
@@ -483,6 +482,7 @@ rct::key straus(const std::vector<MultiexpData> &data, const std::shared_ptr<str
memcpy(bytes33, data[j].scalar.bytes, 32);
bytes33[32] = 0;
bytes = bytes33;
+ static constexpr unsigned int mask = (1<<STRAUS_C)-1;
for (size_t i = 0; i < 256; ++i)
digits[j*256+i] = ((bytes[i>>3] | (bytes[(i>>3)+1]<<8)) >> (i&7)) & mask;
#else
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index cd0cdad92..942bfce0a 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -242,11 +242,11 @@ namespace cryptonote
auto get_nodes = [this]() {
return get_public_nodes(credits_per_hash_threshold);
};
- m_bootstrap_daemon.reset(new bootstrap_daemon(std::move(get_nodes), rpc_payment_enabled, proxy));
+ m_bootstrap_daemon.reset(new bootstrap_daemon(std::move(get_nodes), rpc_payment_enabled, m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy));
}
else
{
- m_bootstrap_daemon.reset(new bootstrap_daemon(address, credentials, rpc_payment_enabled, proxy));
+ m_bootstrap_daemon.reset(new bootstrap_daemon(address, credentials, rpc_payment_enabled, m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy));
}
m_should_use_bootstrap_daemon = m_bootstrap_daemon.get() != nullptr;
@@ -264,8 +264,10 @@ namespace cryptonote
, const bool restricted
, const std::string& port
, bool allow_rpc_payment
+ , const std::string& proxy
)
{
+ m_bootstrap_daemon_proxy = proxy;
m_restricted = restricted;
m_net_server.set_threads_prefix("RPC");
m_net_server.set_connection_filter(&m_p2p);
diff --git a/src/rpc/core_rpc_server.h b/src/rpc/core_rpc_server.h
index 9bc783299..84b14383a 100644
--- a/src/rpc/core_rpc_server.h
+++ b/src/rpc/core_rpc_server.h
@@ -91,7 +91,8 @@ namespace cryptonote
const boost::program_options::variables_map& vm,
const bool restricted,
const std::string& port,
- bool allow_rpc_payment
+ bool allow_rpc_payment,
+ const std::string& proxy = {}
);
network_type nettype() const { return m_core.get_nettype(); }
@@ -291,6 +292,7 @@ private:
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_p2p;
boost::shared_mutex m_bootstrap_daemon_mutex;
std::unique_ptr<bootstrap_daemon> m_bootstrap_daemon;
+ std::string m_bootstrap_daemon_proxy;
bool m_should_use_bootstrap_daemon;
std::chrono::system_clock::time_point m_bootstrap_height_check_time;
bool m_was_bootstrap_ever_used;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 6e8d585dc..5a4cafc32 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -49,6 +49,7 @@ using namespace epee;
#include "cryptonote_core/tx_sanity_check.h"
#include "wallet_rpc_helpers.h"
#include "wallet2.h"
+#include "wallet_args.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "net/parse.h"
#include "rpc/core_rpc_server_commands_defs.h"
@@ -276,7 +277,7 @@ struct options {
const command_line::arg_descriptor<bool> trusted_daemon = {"trusted-daemon", tools::wallet2::tr("Enable commands which rely on a trusted daemon"), false};
const command_line::arg_descriptor<bool> untrusted_daemon = {"untrusted-daemon", tools::wallet2::tr("Disable commands which rely on a trusted daemon"), false};
const command_line::arg_descriptor<std::string> password = {"password", tools::wallet2::tr("Wallet password (escape/quote as needed)"), "", true};
- const command_line::arg_descriptor<std::string> password_file = {"password-file", tools::wallet2::tr("Wallet password file"), "", true};
+ const command_line::arg_descriptor<std::string> password_file = wallet_args::arg_password_file();
const command_line::arg_descriptor<int> daemon_port = {"daemon-port", tools::wallet2::tr("Use daemon instance at port <arg> instead of 18081"), 0};
const command_line::arg_descriptor<std::string> daemon_login = {"daemon-login", tools::wallet2::tr("Specify username[:password] for daemon RPC client"), "", true};
const command_line::arg_descriptor<std::string> daemon_ssl = {"daemon-ssl", tools::wallet2::tr("Enable SSL on daemon RPC connections: enabled|disabled|autodetect"), "autodetect"};
@@ -532,7 +533,7 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
boost::optional<tools::password_container> get_password(const boost::program_options::variables_map& vm, const options& opts, const std::function<boost::optional<tools::password_container>(const char*, bool)> &password_prompter, const bool verify)
{
- if (command_line::has_arg(vm, opts.password) && command_line::has_arg(vm, opts.password_file))
+ if (command_line::has_arg(vm, opts.password) && !command_line::is_arg_defaulted(vm, opts.password_file))
{
THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, tools::wallet2::tr("can't specify more than one of --password and --password-file"));
}
@@ -542,10 +543,11 @@ boost::optional<tools::password_container> get_password(const boost::program_opt
return tools::password_container{command_line::get_arg(vm, opts.password)};
}
- if (command_line::has_arg(vm, opts.password_file))
+ if (!command_line::is_arg_defaulted(vm, opts.password_file))
{
std::string password;
- bool r = epee::file_io_utils::load_file_to_string(command_line::get_arg(vm, opts.password_file),
+ const auto password_file = command_line::get_arg(vm, opts.password_file);
+ bool r = epee::file_io_utils::load_file_to_string(password_file,
password);
THROW_WALLET_EXCEPTION_IF(!r, tools::error::wallet_internal_error, tools::wallet2::tr("the password file specified could not be read"));
@@ -1938,7 +1940,7 @@ void wallet2::cache_tx_data(const cryptonote::transaction& tx, const crypto::has
const bool is_miner = tx.vin.size() == 1 && tx.vin[0].type() == typeid(cryptonote::txin_gen);
if (!is_miner || m_refresh_type != RefreshType::RefreshNoCoinbase)
{
- const size_t rec_size = is_miner && m_refresh_type == RefreshType::RefreshOptimizeCoinbase ? 1 : tx.vout.size();
+ const size_t rec_size = (is_miner && m_refresh_type == RefreshType::RefreshOptimizeCoinbase && tx.version < 2) ? 1 : tx.vout.size();
if (!tx.vout.empty())
{
// if tx.vout is not empty, we loop through all tx pubkeys
@@ -2087,7 +2089,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
{
// assume coinbase isn't for us
}
- else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase)
+ else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase && tx.version < 2)
{
check_acc_out_precomp_once(tx.vout[0], derivation, additional_derivations, 0, is_out_data_ptr, tx_scan_info[0], output_found[0]);
THROW_WALLET_EXCEPTION_IF(tx_scan_info[0].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
@@ -2858,8 +2860,9 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
if (m_refresh_type != RefreshType::RefreshNoCoinbase)
{
THROW_WALLET_EXCEPTION_IF(txidx >= tx_cache_data.size(), error::wallet_internal_error, "txidx out of range");
- const size_t n_vouts = m_refresh_type == RefreshType::RefreshOptimizeCoinbase ? 1 : parsed_blocks[i].block.miner_tx.vout.size();
- tpool.submit(&waiter, [&, i, n_vouts, txidx](){ geniod(parsed_blocks[i].block.miner_tx, n_vouts, txidx); }, true);
+ const cryptonote::transaction& tx = parsed_blocks[i].block.miner_tx;
+ const size_t n_vouts = (m_refresh_type == RefreshType::RefreshOptimizeCoinbase && tx.version < 2) ? 1 : tx.vout.size();
+ tpool.submit(&waiter, [&, n_vouts, txidx](){ geniod(tx, n_vouts, txidx); }, true);
}
++txidx;
for (size_t j = 0; j < parsed_blocks[i].txes.size(); ++j)
@@ -10260,6 +10263,38 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
const size_t num_outputs = get_num_outputs(tx.dsts, m_transfers, tx.selected_transfers);
needed_fee = estimate_fee(use_per_byte_fee, use_rct ,tx.selected_transfers.size(), fake_outs_count, num_outputs, extra.size(), bulletproof, clsag, base_fee, fee_multiplier, fee_quantization_mask);
+ auto try_carving_from_partial_payment = [&](uint64_t needed_fee, uint64_t available_for_fee)
+ {
+ // The check against original_output_index is to ensure the last entry in tx.dsts is really
+ // a partial payment. Otherwise multiple requested outputs to the same address could
+ // fool this logic into thinking there is a partial payment.
+ if (needed_fee > available_for_fee && !dsts.empty() && dsts[0].amount > 0 && tx.dsts.size() > original_output_index)
+ {
+ // we don't have enough for the fee, but we've only partially paid the current address,
+ // so we can take the fee from the paid amount, since we'll have to make another tx anyway
+ LOG_PRINT_L2("Attempting to carve tx fee " << print_money(needed_fee) << " from partial payment (first pass)");
+ std::vector<cryptonote::tx_destination_entry>::iterator i;
+ i = std::find_if(tx.dsts.begin(), tx.dsts.end(),
+ [&](const cryptonote::tx_destination_entry &d) { return !memcmp (&d.addr, &dsts[0].addr, sizeof(dsts[0].addr)); });
+ THROW_WALLET_EXCEPTION_IF(i == tx.dsts.end(), error::wallet_internal_error, "paid address not found in outputs");
+ if (i->amount > needed_fee)
+ {
+ uint64_t new_paid_amount = i->amount /*+ test_ptx.fee*/ - needed_fee;
+ LOG_PRINT_L2("Adjusting amount paid to " << get_account_address_as_str(m_nettype, i->is_subaddress, i->addr) << " from " <<
+ print_money(i->amount) << " to " << print_money(new_paid_amount) << " to accommodate " <<
+ print_money(needed_fee) << " fee");
+ dsts[0].amount += i->amount - new_paid_amount;
+ i->amount = new_paid_amount;
+ test_ptx.fee = needed_fee;
+ available_for_fee = needed_fee;
+ }
+ }
+ return available_for_fee;
+ };
+
+ // Try to carve the estimated fee from the partial payment (if there is one)
+ available_for_fee = try_carving_from_partial_payment(needed_fee, available_for_fee);
+
uint64_t inputs = 0, outputs = needed_fee;
for (size_t idx: tx.selected_transfers) inputs += m_transfers[idx].amount();
for (const auto &o: tx.dsts) outputs += o.amount;
@@ -10285,26 +10320,8 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
LOG_PRINT_L2("Made a " << get_weight_string(test_ptx.tx, txBlob.size()) << " tx, with " << print_money(available_for_fee) << " available for fee (" <<
print_money(needed_fee) << " needed)");
- if (needed_fee > available_for_fee && !dsts.empty() && dsts[0].amount > 0)
- {
- // we don't have enough for the fee, but we've only partially paid the current address,
- // so we can take the fee from the paid amount, since we'll have to make another tx anyway
- std::vector<cryptonote::tx_destination_entry>::iterator i;
- i = std::find_if(tx.dsts.begin(), tx.dsts.end(),
- [&](const cryptonote::tx_destination_entry &d) { return !memcmp (&d.addr, &dsts[0].addr, sizeof(dsts[0].addr)); });
- THROW_WALLET_EXCEPTION_IF(i == tx.dsts.end(), error::wallet_internal_error, "paid address not found in outputs");
- if (i->amount > needed_fee)
- {
- uint64_t new_paid_amount = i->amount /*+ test_ptx.fee*/ - needed_fee;
- LOG_PRINT_L2("Adjusting amount paid to " << get_account_address_as_str(m_nettype, i->is_subaddress, i->addr) << " from " <<
- print_money(i->amount) << " to " << print_money(new_paid_amount) << " to accommodate " <<
- print_money(needed_fee) << " fee");
- dsts[0].amount += i->amount - new_paid_amount;
- i->amount = new_paid_amount;
- test_ptx.fee = needed_fee;
- available_for_fee = needed_fee;
- }
- }
+ // Try to carve the fee from the partial payment again after updating from estimate to actual
+ available_for_fee = try_carving_from_partial_payment(needed_fee, available_for_fee);
if (needed_fee > available_for_fee)
{
diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp
index 55058bf4e..066e98e52 100644
--- a/src/wallet/wallet_args.cpp
+++ b/src/wallet/wallet_args.cpp
@@ -80,6 +80,10 @@ namespace wallet_args
{
return {"rpc-client-secret-key", wallet_args::tr("Set RPC client secret key for RPC payments"), ""};
}
+ command_line::arg_descriptor<std::string> arg_password_file()
+ {
+ return {"password-file", wallet_args::tr("Wallet password file"), ""};
+ }
const char* tr(const char* str)
{
diff --git a/src/wallet/wallet_args.h b/src/wallet/wallet_args.h
index 4af1b58fe..21e5f187c 100644
--- a/src/wallet/wallet_args.h
+++ b/src/wallet/wallet_args.h
@@ -37,6 +37,7 @@ namespace wallet_args
command_line::arg_descriptor<std::string> arg_generate_from_json();
command_line::arg_descriptor<std::string> arg_wallet_file();
command_line::arg_descriptor<std::string> arg_rpc_client_secret_key();
+ command_line::arg_descriptor<std::string> arg_password_file();
const char* tr(const char* str);
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index e1a06886b..4655e24cd 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -41,6 +41,7 @@ using namespace epee;
#include "wallet/wallet_args.h"
#include "common/command_line.h"
#include "common/i18n.h"
+#include "common/scoped_message_writer.h"
#include "cryptonote_config.h"
#include "cryptonote_basic/cryptonote_format_utils.h"
#include "cryptonote_basic/account.h"
@@ -4525,10 +4526,12 @@ public:
const auto arg_wallet_file = wallet_args::arg_wallet_file();
const auto arg_from_json = wallet_args::arg_generate_from_json();
const auto arg_rpc_client_secret_key = wallet_args::arg_rpc_client_secret_key();
+ const auto arg_password_file = wallet_args::arg_password_file();
const auto wallet_file = command_line::get_arg(vm, arg_wallet_file);
const auto from_json = command_line::get_arg(vm, arg_from_json);
const auto wallet_dir = command_line::get_arg(vm, arg_wallet_dir);
+ const auto password_file = command_line::get_arg(vm, arg_password_file);
const auto prompt_for_password = command_line::get_arg(vm, arg_prompt_for_password);
const auto password_prompt = prompt_for_password ? password_prompter : nullptr;
@@ -4538,6 +4541,12 @@ public:
return false;
}
+ if(!wallet_dir.empty() && !password_file.empty())
+ {
+ LOG_ERROR(tools::wallet_rpc_server::tr("--password-file is not allowed in combination with --wallet-dir"));
+ return false;
+ }
+
if (!wallet_dir.empty())
{
wal = NULL;
@@ -4716,7 +4725,7 @@ int main(int argc, char** argv) {
tools::wallet_rpc_server::tr("This is the RPC monero wallet. It needs to connect to a monero\ndaemon to work correctly."),
desc_params,
po::positional_options_description(),
- [](const std::string &s, bool emphasis){ epee::set_console_color(emphasis ? epee::console_color_white : epee::console_color_default, true); std::cout << s << std::endl; if (emphasis) epee::reset_console_color(); },
+ [](const std::string &s, bool emphasis){ tools::scoped_message_writer(emphasis ? epee::console_color_white : epee::console_color_default, true) << s; },
"monero-wallet-rpc.log",
true
);
diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp
index d19bdd1f9..efd294336 100644
--- a/tests/core_tests/transaction_tests.cpp
+++ b/tests/core_tests/transaction_tests.cpp
@@ -72,7 +72,6 @@ bool test_transaction_generation_and_ring_signature()
construct_miner_tx(0, 0, 0, 0, 0, miner_acc6.get_keys().m_account_address, tx_mine_6);
//fill inputs entry
- typedef tx_source_entry::output_entry tx_output_entry;
std::vector<tx_source_entry> sources;
sources.resize(sources.size()+1);
tx_source_entry& src = sources.back();
diff --git a/tests/unit_tests/logging.cpp b/tests/unit_tests/logging.cpp
index f11b17412..b3ffb9aa6 100644
--- a/tests/unit_tests/logging.cpp
+++ b/tests/unit_tests/logging.cpp
@@ -208,3 +208,10 @@ TEST(logging, operator_equals_segfault)
el::Logger log2("id2", nullptr);
log2 = log1;
}
+
+TEST(logging, empty_configurations_throws)
+{
+ el::Logger log1("id1", nullptr);
+ const el::Configurations cfg;
+ EXPECT_ANY_THROW(log1.configure(cfg));
+}
diff --git a/tests/unit_tests/node_server.cpp b/tests/unit_tests/node_server.cpp
index cab600b3d..cc7790c1a 100644
--- a/tests/unit_tests/node_server.cpp
+++ b/tests/unit_tests/node_server.cpp
@@ -303,6 +303,9 @@ TEST(node_server, bind_same_p2p_port)
Relevant part about REUSEADDR from man:
https://www.man7.org/linux/man-pages/man7/ip.7.html
+
+ For Mac OSX, set the following alias, before running the test, or else it will fail:
+ sudo ifconfig lo0 alias 127.0.0.2
*/
vm.find(nodetool::arg_p2p_bind_ip.name)->second = boost::program_options::variable_value(std::string("127.0.0.2"), false);
vm.find(nodetool::arg_p2p_bind_port.name)->second = boost::program_options::variable_value(std::string(port), false);