aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/FindBacktrace.cmake90
-rw-r--r--contrib/gitian/gitian-linux.yml2
-rw-r--r--contrib/gitian/gitian-win.yml2
-rw-r--r--external/db_drivers/liblmdb/mdb.c2
-rw-r--r--external/easylogging++/CMakeLists.txt4
-rw-r--r--src/common/combinator.h1
-rw-r--r--src/common/dns_utils.cpp7
-rw-r--r--src/crypto/crypto.h27
-rw-r--r--src/cryptonote_basic/difficulty.cpp15
-rw-r--r--src/cryptonote_basic/difficulty.h3
-rw-r--r--src/device/device.hpp1
-rw-r--r--src/device_trezor/device_trezor_base.cpp13
-rw-r--r--src/device_trezor/device_trezor_base.hpp2
-rw-r--r--src/device_trezor/trezor/transport.cpp64
-rw-r--r--src/device_trezor/trezor/transport.hpp10
-rw-r--r--src/p2p/net_node.inl4
-rw-r--r--src/p2p/net_peerlist.h2
-rw-r--r--src/rpc/core_rpc_server.cpp3
-rw-r--r--src/simplewallet/simplewallet.cpp3
-rw-r--r--src/wallet/api/wallet.cpp12
-rw-r--r--src/wallet/api/wallet2_api.h27
-rw-r--r--src/wallet/api/wallet_manager.cpp15
-rw-r--r--src/wallet/api/wallet_manager.h5
-rw-r--r--src/wallet/wallet2.cpp47
-rw-r--r--src/wallet/wallet2.h5
-rw-r--r--tests/core_tests/wallet_tools.cpp2
-rw-r--r--tests/difficulty/difficulty.cpp5
-rwxr-xr-xtests/functional_tests/blockchain.py14
-rw-r--r--tests/hash-target.cpp3
-rw-r--r--tests/hash/main.cpp4
-rw-r--r--tests/libwallet_api_tests/main.cpp3
-rw-r--r--tests/trezor/daemon.cpp8
-rw-r--r--tests/trezor/trezor_tests.cpp87
-rw-r--r--tests/trezor/trezor_tests.h2
34 files changed, 403 insertions, 91 deletions
diff --git a/cmake/FindBacktrace.cmake b/cmake/FindBacktrace.cmake
new file mode 100644
index 000000000..89bbad07c
--- /dev/null
+++ b/cmake/FindBacktrace.cmake
@@ -0,0 +1,90 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#.rst:
+# FindBacktrace
+# -------------
+#
+# Find provider for backtrace(3).
+#
+# Checks if OS supports backtrace(3) via either libc or custom library.
+# This module defines the following variables:
+#
+# ``Backtrace_HEADER``
+# The header file needed for backtrace(3). Cached.
+# Could be forcibly set by user.
+# ``Backtrace_INCLUDE_DIRS``
+# The include directories needed to use backtrace(3) header.
+# ``Backtrace_LIBRARIES``
+# The libraries (linker flags) needed to use backtrace(3), if any.
+# ``Backtrace_FOUND``
+# Is set if and only if backtrace(3) support detected.
+#
+# The following cache variables are also available to set or use:
+#
+# ``Backtrace_LIBRARY``
+# The external library providing backtrace, if any.
+# ``Backtrace_INCLUDE_DIR``
+# The directory holding the backtrace(3) header.
+#
+# Typical usage is to generate of header file using configure_file() with the
+# contents like the following::
+#
+# #cmakedefine01 Backtrace_FOUND
+# #if Backtrace_FOUND
+# # include <${Backtrace_HEADER}>
+# #endif
+#
+# And then reference that generated header file in actual source.
+
+include(CMakePushCheckState)
+include(CheckSymbolExists)
+include(FindPackageHandleStandardArgs)
+
+# List of variables to be provided to find_package_handle_standard_args()
+set(_Backtrace_STD_ARGS Backtrace_INCLUDE_DIR)
+
+if(Backtrace_HEADER)
+ set(_Backtrace_HEADER_TRY "${Backtrace_HEADER}")
+else(Backtrace_HEADER)
+ set(_Backtrace_HEADER_TRY "execinfo.h")
+endif(Backtrace_HEADER)
+
+find_path(Backtrace_INCLUDE_DIR "${_Backtrace_HEADER_TRY}")
+set(Backtrace_INCLUDE_DIRS ${Backtrace_INCLUDE_DIR})
+
+if (NOT DEFINED Backtrace_LIBRARY)
+ # First, check if we already have backtrace(), e.g., in libc
+ cmake_push_check_state(RESET)
+ set(CMAKE_REQUIRED_INCLUDES ${Backtrace_INCLUDE_DIRS})
+ set(CMAKE_REQUIRED_QUIET ${Backtrace_FIND_QUIETLY})
+ check_symbol_exists("backtrace" "${_Backtrace_HEADER_TRY}" _Backtrace_SYM_FOUND)
+ cmake_pop_check_state()
+endif()
+
+if(_Backtrace_SYM_FOUND)
+ # Avoid repeating the message() call below each time CMake is run.
+ if(NOT Backtrace_FIND_QUIETLY AND NOT DEFINED Backtrace_LIBRARY)
+ message(STATUS "backtrace facility detected in default set of libraries")
+ endif()
+ set(Backtrace_LIBRARY "" CACHE FILEPATH "Library providing backtrace(3), empty for default set of libraries")
+else()
+ # Check for external library, for non-glibc systems
+ if(Backtrace_INCLUDE_DIR)
+ # OpenBSD has libbacktrace renamed to libexecinfo
+ find_library(Backtrace_LIBRARY "execinfo")
+ elseif() # respect user wishes
+ set(_Backtrace_HEADER_TRY "backtrace.h")
+ find_path(Backtrace_INCLUDE_DIR ${_Backtrace_HEADER_TRY})
+ find_library(Backtrace_LIBRARY "backtrace")
+ endif()
+
+ # Prepend list with library path as it's more common practice
+ set(_Backtrace_STD_ARGS Backtrace_LIBRARY ${_Backtrace_STD_ARGS})
+endif()
+
+set(Backtrace_LIBRARIES ${Backtrace_LIBRARY})
+set(Backtrace_HEADER "${_Backtrace_HEADER_TRY}" CACHE STRING "Header providing backtrace(3) facility")
+
+find_package_handle_standard_args(Backtrace FOUND_VAR Backtrace_FOUND REQUIRED_VARS ${_Backtrace_STD_ARGS})
+mark_as_advanced(Backtrace_HEADER Backtrace_INCLUDE_DIR Backtrace_LIBRARY)
diff --git a/contrib/gitian/gitian-linux.yml b/contrib/gitian/gitian-linux.yml
index 3bb25c314..67f174fec 100644
--- a/contrib/gitian/gitian-linux.yml
+++ b/contrib/gitian/gitian-linux.yml
@@ -137,7 +137,7 @@ script: |
if [ -d "$EXTRA_INCLUDES" ]; then
export HOST_ID_SALT="$EXTRA_INCLUDES"
fi
- make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" -j 4 V=1
+ make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" V=1
unset HOST_ID_SALT
done
diff --git a/contrib/gitian/gitian-win.yml b/contrib/gitian/gitian-win.yml
index fef5567f9..1eb558300 100644
--- a/contrib/gitian/gitian-win.yml
+++ b/contrib/gitian/gitian-win.yml
@@ -108,7 +108,7 @@ script: |
if [ -d "$EXTRA_INCLUDES" ]; then
export HOST_ID_SALT="$EXTRA_INCLUDES"
fi
- make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" -j 4 V=1
+ make ${MAKEOPTS} -C ${BASEPREFIX} HOST="${i}" V=1
unset HOST_ID_SALT
done
diff --git a/external/db_drivers/liblmdb/mdb.c b/external/db_drivers/liblmdb/mdb.c
index 8e67d5981..ba1315401 100644
--- a/external/db_drivers/liblmdb/mdb.c
+++ b/external/db_drivers/liblmdb/mdb.c
@@ -1742,6 +1742,8 @@ mdb_strerror(int err)
NULL, err, 0, ptr, MSGSIZE, (va_list *)buf+MSGSIZE);
return ptr;
#else
+ if (err < 0)
+ return "Invalid error code";
return strerror(err);
#endif
}
diff --git a/external/easylogging++/CMakeLists.txt b/external/easylogging++/CMakeLists.txt
index 8287024c2..35fb86552 100644
--- a/external/easylogging++/CMakeLists.txt
+++ b/external/easylogging++/CMakeLists.txt
@@ -33,6 +33,7 @@ project(easylogging CXX)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
find_package(Threads)
+find_package(Backtrace)
add_library(easylogging
easylogging++.cc)
@@ -41,7 +42,8 @@ include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
target_link_libraries(easylogging
PRIVATE
- ${CMAKE_THREAD_LIBS_INIT})
+ ${CMAKE_THREAD_LIBS_INIT}
+ ${Backtrace_LIBRARIES})
# GUI/libwallet install target
if (BUILD_GUI_DEPS)
diff --git a/src/common/combinator.h b/src/common/combinator.h
index 72c6800d5..ba851bd81 100644
--- a/src/common/combinator.h
+++ b/src/common/combinator.h
@@ -32,6 +32,7 @@
#include <iostream>
#include <vector>
+#include <stdexcept>
namespace tools {
diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp
index 1a1155c7c..5e03bf897 100644
--- a/src/common/dns_utils.cpp
+++ b/src/common/dns_utils.cpp
@@ -33,7 +33,7 @@
#include <stdlib.h>
#include "include_base_utils.h"
#include "common/threadpool.h"
-#include <random>
+#include "crypto/crypto.h"
#include <boost/thread/mutex.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/optional.hpp>
@@ -517,10 +517,7 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std
std::vector<std::vector<std::string> > records;
records.resize(dns_urls.size());
- std::random_device rd;
- std::mt19937 gen(rd());
- std::uniform_int_distribution<int> dis(0, dns_urls.size() - 1);
- size_t first_index = dis(gen);
+ size_t first_index = crypto::rand_idx(dns_urls.size());
// send all requests in parallel
std::deque<bool> avail(dns_urls.size(), false), valid(dns_urls.size(), false);
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index 22b182ab0..bac456f60 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -35,6 +35,7 @@
#include <boost/optional.hpp>
#include <type_traits>
#include <vector>
+#include <random>
#include "common/pod-class.h"
#include "memwipe.h"
@@ -162,6 +163,32 @@ namespace crypto {
return res;
}
+ /* UniformRandomBitGenerator using crypto::rand<uint64_t>()
+ */
+ struct random_device
+ {
+ typedef uint64_t result_type;
+ static constexpr result_type min() { return 0; }
+ static constexpr result_type max() { return result_type(-1); }
+ result_type operator()() const { return crypto::rand<result_type>(); }
+ };
+
+ /* Generate a random value between range_min and range_max
+ */
+ template<typename T>
+ typename std::enable_if<std::is_integral<T>::value, T>::type rand_range(T range_min, T range_max) {
+ crypto::random_device rd;
+ std::uniform_int_distribution<T> dis(range_min, range_max);
+ return dis(rd);
+ }
+
+ /* Generate a random index between 0 and sz-1
+ */
+ template<typename T>
+ typename std::enable_if<std::is_unsigned<T>::value, T>::type rand_idx(T sz) {
+ return crypto::rand_range<T>(0, sz-1);
+ }
+
/* Generate a new key pair
*/
inline secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false) {
diff --git a/src/cryptonote_basic/difficulty.cpp b/src/cryptonote_basic/difficulty.cpp
index 5162e53e6..859173aa5 100644
--- a/src/cryptonote_basic/difficulty.cpp
+++ b/src/cryptonote_basic/difficulty.cpp
@@ -239,4 +239,19 @@ namespace cryptonote {
return res.convert_to<difficulty_type>();
}
+ std::string hex(difficulty_type v)
+ {
+ static const char chars[] = "0123456789abcdef";
+ std::string s;
+ while (v > 0)
+ {
+ s.push_back(chars[(v & 0xf).convert_to<unsigned>()]);
+ v >>= 4;
+ }
+ if (s.empty())
+ s += "0";
+ std::reverse(s.begin(), s.end());
+ return "0x" + s;
+ }
+
}
diff --git a/src/cryptonote_basic/difficulty.h b/src/cryptonote_basic/difficulty.h
index f7a9376fb..02ed89e5a 100644
--- a/src/cryptonote_basic/difficulty.h
+++ b/src/cryptonote_basic/difficulty.h
@@ -32,6 +32,7 @@
#include <cstdint>
#include <vector>
+#include <string>
#include <boost/multiprecision/cpp_int.hpp>
#include "crypto/hash.h"
@@ -58,4 +59,6 @@ namespace cryptonote
bool check_hash_128(const crypto::hash &hash, difficulty_type difficulty);
bool check_hash(const crypto::hash &hash, difficulty_type difficulty);
difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
+
+ std::string hex(difficulty_type v);
}
diff --git a/src/device/device.hpp b/src/device/device.hpp
index 2e485b1d6..866e2c676 100644
--- a/src/device/device.hpp
+++ b/src/device/device.hpp
@@ -76,6 +76,7 @@ namespace hw {
class i_device_callback {
public:
virtual void on_button_request(uint64_t code=0) {}
+ virtual void on_button_pressed() {}
virtual boost::optional<epee::wipeable_string> on_pin_request() { return boost::none; }
virtual boost::optional<epee::wipeable_string> on_passphrase_request(bool on_device) { return boost::none; }
virtual void on_progress(const device_progress& event) {}
diff --git a/src/device_trezor/device_trezor_base.cpp b/src/device_trezor/device_trezor_base.cpp
index f3d15c5e2..58abde1d1 100644
--- a/src/device_trezor/device_trezor_base.cpp
+++ b/src/device_trezor/device_trezor_base.cpp
@@ -43,7 +43,7 @@ namespace trezor {
const uint32_t device_trezor_base::DEFAULT_BIP44_PATH[] = {0x8000002c, 0x80000080};
- device_trezor_base::device_trezor_base(): m_callback(nullptr) {
+ device_trezor_base::device_trezor_base(): m_callback(nullptr), m_last_msg_type(messages::MessageType_Success) {
#ifdef WITH_TREZOR_DEBUGGING
m_debug = false;
#endif
@@ -275,6 +275,12 @@ namespace trezor {
// Later if needed this generic message handler can be replaced by a pointer to
// a protocol message handler which by default points to the device class which implements
// the default handler.
+
+ if (m_last_msg_type == messages::MessageType_ButtonRequest){
+ on_button_pressed();
+ }
+ m_last_msg_type = input.m_type;
+
switch(input.m_type){
case messages::MessageType_ButtonRequest:
on_button_request(input, dynamic_cast<const messages::common::ButtonRequest*>(input.m_msg.get()));
@@ -413,6 +419,11 @@ namespace trezor {
resp = read_raw();
}
+ void device_trezor_base::on_button_pressed()
+ {
+ TREZOR_CALLBACK(on_button_pressed);
+ }
+
void device_trezor_base::on_pin_request(GenericMessage & resp, const messages::common::PinMatrixRequest * msg)
{
MDEBUG("on_pin_request");
diff --git a/src/device_trezor/device_trezor_base.hpp b/src/device_trezor/device_trezor_base.hpp
index 8c3c14b29..c106d2099 100644
--- a/src/device_trezor/device_trezor_base.hpp
+++ b/src/device_trezor/device_trezor_base.hpp
@@ -98,6 +98,7 @@ namespace trezor {
std::shared_ptr<messages::management::Features> m_features; // features from the last device reset
boost::optional<epee::wipeable_string> m_pin;
boost::optional<epee::wipeable_string> m_passphrase;
+ messages::MessageType m_last_msg_type;
cryptonote::network_type network_type;
@@ -311,6 +312,7 @@ namespace trezor {
// Protocol callbacks
void on_button_request(GenericMessage & resp, const messages::common::ButtonRequest * msg);
+ void on_button_pressed();
void on_pin_request(GenericMessage & resp, const messages::common::PinMatrixRequest * msg);
void on_passphrase_request(GenericMessage & resp, const messages::common::PassphraseRequest * msg);
void on_passphrase_state_request(GenericMessage & resp, const messages::common::PassphraseStateRequest * msg);
diff --git a/src/device_trezor/trezor/transport.cpp b/src/device_trezor/trezor/transport.cpp
index 991ba3395..dd9b0b52f 100644
--- a/src/device_trezor/trezor/transport.cpp
+++ b/src/device_trezor/trezor/transport.cpp
@@ -223,6 +223,11 @@ namespace trezor{
msg = msg_wrap;
}
+ static void assert_port_number(uint32_t port)
+ {
+ CHECK_AND_ASSERT_THROW_MES(port >= 1024 && port < 65535, "Invalid port number: " << port);
+ }
+
Transport::Transport(): m_open_counter(0) {
}
@@ -263,6 +268,29 @@ namespace trezor{
const char * BridgeTransport::PATH_PREFIX = "bridge:";
+ BridgeTransport::BridgeTransport(
+ boost::optional<std::string> device_path,
+ boost::optional<std::string> bridge_host):
+ m_device_path(device_path),
+ m_bridge_host(bridge_host ? bridge_host.get() : DEFAULT_BRIDGE),
+ m_response(boost::none),
+ m_session(boost::none),
+ m_device_info(boost::none)
+ {
+ const char *env_bridge_port = nullptr;
+ if (!bridge_host && (env_bridge_port = getenv("TREZOR_BRIDGE_PORT")) != nullptr)
+ {
+ uint16_t bridge_port;
+ CHECK_AND_ASSERT_THROW_MES(epee::string_tools::get_xtype_from_string(bridge_port, env_bridge_port), "Invalid bridge port: " << env_bridge_port);
+ assert_port_number(bridge_port);
+
+ m_bridge_host = std::string("127.0.0.1:") + boost::lexical_cast<std::string>(env_bridge_port);
+ MDEBUG("Bridge host: " << m_bridge_host);
+ }
+
+ m_http_client.set_server(m_bridge_host, boost::none, epee::net_utils::ssl_support_t::e_ssl_support_disabled);
+ }
+
std::string BridgeTransport::get_path() const {
if (!m_device_path){
return "";
@@ -401,28 +429,40 @@ namespace trezor{
const char * UdpTransport::DEFAULT_HOST = "127.0.0.1";
const int UdpTransport::DEFAULT_PORT = 21324;
+ static void parse_udp_path(std::string &host, int &port, std::string path)
+ {
+ if (boost::starts_with(path, UdpTransport::PATH_PREFIX))
+ {
+ path = path.substr(strlen(UdpTransport::PATH_PREFIX));
+ }
+
+ auto delim = path.find(':');
+ if (delim == std::string::npos) {
+ host = path;
+ } else {
+ host = path.substr(0, delim);
+ port = std::stoi(path.substr(delim + 1));
+ }
+ }
+
UdpTransport::UdpTransport(boost::optional<std::string> device_path,
boost::optional<std::shared_ptr<Protocol>> proto) :
m_io_service(), m_deadline(m_io_service)
{
+ m_device_host = DEFAULT_HOST;
m_device_port = DEFAULT_PORT;
+ const char *env_trezor_path = nullptr;
+
if (device_path) {
- const std::string device_str = device_path.get();
- auto delim = device_str.find(':');
- if (delim == std::string::npos) {
- m_device_host = device_str;
- } else {
- m_device_host = device_str.substr(0, delim);
- m_device_port = std::stoi(device_str.substr(delim + 1));
- }
+ parse_udp_path(m_device_host, m_device_port, device_path.get());
+ } else if ((env_trezor_path = getenv("TREZOR_PATH")) != nullptr && boost::starts_with(env_trezor_path, UdpTransport::PATH_PREFIX)){
+ parse_udp_path(m_device_host, m_device_port, std::string(env_trezor_path));
+ MDEBUG("Applied TREZOR_PATH: " << m_device_host << ":" << m_device_port);
} else {
m_device_host = DEFAULT_HOST;
}
- if (m_device_port <= 1024 || m_device_port > 65535){
- throw std::invalid_argument("Port number invalid");
- }
-
+ assert_port_number((uint32_t)m_device_port);
if (m_device_host != "localhost" && m_device_host != DEFAULT_HOST){
throw std::invalid_argument("Local endpoint allowed only");
}
diff --git a/src/device_trezor/trezor/transport.hpp b/src/device_trezor/trezor/transport.hpp
index 2945b3184..cde862547 100644
--- a/src/device_trezor/trezor/transport.hpp
+++ b/src/device_trezor/trezor/transport.hpp
@@ -163,15 +163,7 @@ namespace trezor {
public:
BridgeTransport(
boost::optional<std::string> device_path = boost::none,
- boost::optional<std::string> bridge_host = boost::none):
- m_device_path(device_path),
- m_bridge_host(bridge_host ? bridge_host.get() : DEFAULT_BRIDGE),
- m_response(boost::none),
- m_session(boost::none),
- m_device_info(boost::none)
- {
- m_http_client.set_server(m_bridge_host, boost::none, epee::net_utils::ssl_support_t::e_ssl_support_disabled);
- }
+ boost::optional<std::string> bridge_host = boost::none);
virtual ~BridgeTransport() = default;
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index f0aef384f..7d13b3216 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -1259,7 +1259,7 @@ namespace nodetool
}
}
else
- random_index = crypto::rand<size_t>() % filtered.size();
+ random_index = crypto::rand_idx(filtered.size());
CHECK_AND_ASSERT_MES(random_index < filtered.size(), false, "random_index < filtered.size() failed!!");
random_index = filtered[random_index];
@@ -1313,7 +1313,7 @@ namespace nodetool
return true;
size_t try_count = 0;
- size_t current_index = crypto::rand<size_t>()%m_seed_nodes.size();
+ size_t current_index = crypto::rand_idx(m_seed_nodes.size());
const net_server& server = m_network_zones.at(epee::net_utils::zone::public_).m_net_server;
while(true)
{
diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h
index ebe0268d8..52814af94 100644
--- a/src/p2p/net_peerlist.h
+++ b/src/p2p/net_peerlist.h
@@ -398,7 +398,7 @@ namespace nodetool
return false;
}
- size_t random_index = crypto::rand<size_t>() % m_peers_gray.size();
+ size_t random_index = crypto::rand_idx(m_peers_gray.size());
peers_indexed::index<by_time>::type& by_time_index = m_peers_gray.get<by_time>();
pe = *epee::misc_utils::move_it_backward(--by_time_index.end(), random_index);
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index 71bfcc950..39a8b4745 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -74,7 +74,7 @@ namespace
void store_difficulty(cryptonote::difficulty_type difficulty, uint64_t &sdiff, std::string &swdiff, uint64_t &stop64)
{
sdiff = (difficulty << 64 >> 64).convert_to<uint64_t>();
- swdiff = difficulty.convert_to<std::string>();
+ swdiff = cryptonote::hex(difficulty);
stop64 = (difficulty >> 64).convert_to<uint64_t>();
}
}
@@ -204,6 +204,7 @@ namespace cryptonote
crypto::hash hash;
m_core.get_blockchain_top(res.height, hash);
+ ++res.height; // block height to chain height
res.hash = string_tools::pod_to_hex(hash);
res.status = CORE_RPC_STATUS_OK;
return true;
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index db5ed32f7..2e134931f 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -5065,8 +5065,7 @@ bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bo
LOCK_IDLE_SCOPE();
crypto::hash transfer_hash_pre{};
- uint64_t height_pre, height_post;
-
+ uint64_t height_pre = 0, height_post;
if (reset != ResetNone)
{
if (reset == ResetSoftKeepKI)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index c1303c225..032b873d6 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -249,6 +249,13 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback
}
}
+ virtual void on_device_button_pressed()
+ {
+ if (m_listener) {
+ m_listener->onDeviceButtonPressed();
+ }
+ }
+
virtual boost::optional<epee::wipeable_string> on_device_pin_request()
{
if (m_listener) {
@@ -449,6 +456,11 @@ WalletImpl::~WalletImpl()
close(false); // do not store wallet as part of the closing activities
// Stop refresh thread
stopRefresh();
+
+ if (m_wallet2Callback->getListener()) {
+ m_wallet2Callback->getListener()->onSetWallet(nullptr);
+ }
+
LOG_PRINT_L1(__FUNCTION__ << " finished");
}
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index ee1d6ae79..0af3b1867 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -37,6 +37,7 @@
#include <set>
#include <ctime>
#include <iostream>
+#include <stdexcept>
// Public interface for libwallet library
namespace Monero {
@@ -337,6 +338,7 @@ protected:
bool m_indeterminate;
};
+struct Wallet;
struct WalletListener
{
virtual ~WalletListener() = 0;
@@ -381,7 +383,12 @@ struct WalletListener
/**
* @brief called by device if the action is required
*/
- virtual void onDeviceButtonRequest(uint64_t code) {}
+ virtual void onDeviceButtonRequest(uint64_t code) { (void)code; }
+
+ /**
+ * @brief called by device if the button was pressed
+ */
+ virtual void onDeviceButtonPressed() { }
/**
* @brief called by device when PIN is needed
@@ -401,7 +408,12 @@ struct WalletListener
/**
* @brief Signalizes device operation progress
*/
- virtual void onDeviceProgress(const DeviceProgress & event) {};
+ virtual void onDeviceProgress(const DeviceProgress & event) { (void)event; };
+
+ /**
+ * @brief If the listener is created before the wallet this enables to set created wallet object
+ */
+ virtual void onSetWallet(Wallet * wallet) { (void)wallet; };
};
@@ -440,8 +452,8 @@ struct Wallet
//! returns both error and error string atomically. suggested to use in instead of status() and errorString()
virtual void statusWithErrorString(int& status, std::string& errorString) const = 0;
virtual bool setPassword(const std::string &password) = 0;
- virtual bool setDevicePin(const std::string &password) { return false; };
- virtual bool setDevicePassphrase(const std::string &password) { return false; };
+ virtual bool setDevicePin(const std::string &pin) { (void)pin; return false; };
+ virtual bool setDevicePassphrase(const std::string &passphrase) { (void)passphrase; return false; };
virtual std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const = 0;
std::string mainAddress() const { return address(0, 0); }
virtual std::string path() const = 0;
@@ -1020,9 +1032,10 @@ struct WalletManager
* \param password Password of wallet file
* \param nettype Network type
* \param kdf_rounds Number of rounds for key derivation function
+ * \param listener Wallet listener to set to the wallet after creation
* \return Wallet instance (Wallet::status() needs to be called to check if opened successfully)
*/
- virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1) = 0;
+ virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) = 0;
Wallet * openWallet(const std::string &path, const std::string &password, bool testnet = false) // deprecated
{
return openWallet(path, password, testnet ? TESTNET : MAINNET);
@@ -1134,6 +1147,7 @@ struct WalletManager
* \param restoreHeight restore from start height (0 sets to current height)
* \param subaddressLookahead Size of subaddress lookahead (empty sets to some default low value)
* \param kdf_rounds Number of rounds for key derivation function
+ * \param listener Wallet listener to set to the wallet after creation
* \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully)
*/
virtual Wallet * createWalletFromDevice(const std::string &path,
@@ -1142,7 +1156,8 @@ struct WalletManager
const std::string &deviceName,
uint64_t restoreHeight = 0,
const std::string &subaddressLookahead = "",
- uint64_t kdf_rounds = 1) = 0;
+ uint64_t kdf_rounds = 1,
+ WalletListener * listener = nullptr) = 0;
/*!
* \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted
diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp
index f584e88ac..ef2ed2015 100644
--- a/src/wallet/api/wallet_manager.cpp
+++ b/src/wallet/api/wallet_manager.cpp
@@ -57,9 +57,14 @@ Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::stri
return wallet;
}
-Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds)
+Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds, WalletListener * listener)
{
WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds);
+ wallet->setListener(listener);
+ if (listener){
+ listener->onSetWallet(wallet);
+ }
+
wallet->open(path, password);
//Refresh addressBook
wallet->addressBook()->refresh();
@@ -122,9 +127,15 @@ Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path,
const std::string &deviceName,
uint64_t restoreHeight,
const std::string &subaddressLookahead,
- uint64_t kdf_rounds)
+ uint64_t kdf_rounds,
+ WalletListener * listener)
{
WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds);
+ wallet->setListener(listener);
+ if (listener){
+ listener->onSetWallet(wallet);
+ }
+
if(restoreHeight > 0){
wallet->setRefreshFromBlockHeight(restoreHeight);
} else {
diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h
index 0c83d794f..235f96e17 100644
--- a/src/wallet/api/wallet_manager.h
+++ b/src/wallet/api/wallet_manager.h
@@ -40,7 +40,7 @@ class WalletManagerImpl : public WalletManager
public:
Wallet * createWallet(const std::string &path, const std::string &password,
const std::string &language, NetworkType nettype, uint64_t kdf_rounds = 1) override;
- Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1) override;
+ Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) override;
virtual Wallet * recoveryWallet(const std::string &path,
const std::string &password,
const std::string &mnemonic,
@@ -72,7 +72,8 @@ public:
const std::string &deviceName,
uint64_t restoreHeight = 0,
const std::string &subaddressLookahead = "",
- uint64_t kdf_rounds = 1) override;
+ uint64_t kdf_rounds = 1,
+ WalletListener * listener = nullptr) override;
virtual bool closeWallet(Wallet *wallet, bool store = true) override;
bool walletExists(const std::string &path) override;
bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index dfcc61426..b288994a5 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -265,6 +265,7 @@ struct options {
const command_line::arg_descriptor<std::string> hw_device = {"hw-device", tools::wallet2::tr("HW device to use"), ""};
const command_line::arg_descriptor<std::string> hw_device_derivation_path = {"hw-device-deriv-path", tools::wallet2::tr("HW device wallet derivation path (e.g., SLIP-10)"), ""};
const command_line::arg_descriptor<std::string> tx_notify = { "tx-notify" , "Run a program for each new incoming transaction, '%s' will be replaced by the transaction hash" , "" };
+ const command_line::arg_descriptor<bool> no_dns = {"no-dns", tools::wallet2::tr("Do not use DNS"), false};
};
void do_prepare_file_names(const std::string& file_path, std::string& keys_file, std::string& wallet_file, std::string &mms_file)
@@ -452,6 +453,9 @@ std::unique_ptr<tools::wallet2> make_basic(const boost::program_options::variabl
wallet->device_name(device_name);
wallet->device_derivation_path(device_derivation_path);
+ if (command_line::get_arg(vm, opts.no_dns))
+ wallet->enable_dns(false);
+
try
{
if (!command_line::is_arg_defaulted(vm, opts.tx_notify))
@@ -992,6 +996,12 @@ void wallet_device_callback::on_button_request(uint64_t code)
wallet->on_device_button_request(code);
}
+void wallet_device_callback::on_button_pressed()
+{
+ if (wallet)
+ wallet->on_device_button_pressed();
+}
+
boost::optional<epee::wipeable_string> wallet_device_callback::on_pin_request()
{
if (wallet)
@@ -1072,7 +1082,8 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended):
m_encrypt_keys_after_refresh(boost::none),
m_unattended(unattended),
m_devices_registered(false),
- m_device_last_key_image_sync(0)
+ m_device_last_key_image_sync(0),
+ m_use_dns(true)
{
}
@@ -1127,6 +1138,7 @@ void wallet2::init_options(boost::program_options::options_description& desc_par
command_line::add_arg(desc_params, opts.hw_device);
command_line::add_arg(desc_params, opts.hw_device_derivation_path);
command_line::add_arg(desc_params, opts.tx_notify);
+ command_line::add_arg(desc_params, opts.no_dns);
}
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)
@@ -5773,7 +5785,7 @@ namespace
{
CHECK_AND_ASSERT_MES(!vec.empty(), T(), "Vector must be non-empty");
- size_t idx = crypto::rand<size_t>() % vec.size();
+ size_t idx = crypto::rand_idx(vec.size());
return pop_index (vec, idx);
}
@@ -5876,7 +5888,7 @@ size_t wallet2::pop_best_value_from(const transfer_container &transfers, std::ve
}
else
{
- idx = crypto::rand<size_t>() % candidates.size();
+ idx = crypto::rand_idx(candidates.size());
}
return pop_index (unused_indices, candidates[idx]);
}
@@ -7565,7 +7577,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
if (n_rct == 0)
return rct_offsets[block_offset] ? rct_offsets[block_offset] - 1 : 0;
MDEBUG("Picking 1/" << n_rct << " in " << (last_block_offset - first_block_offset + 1) << " blocks centered around " << block_offset + rct_start_height);
- return first_rct + crypto::rand<uint64_t>() % n_rct;
+ return first_rct + crypto::rand_idx(n_rct);
};
size_t num_selected_transfers = 0;
@@ -9621,14 +9633,16 @@ bool wallet2::sanity_check(const std::vector<wallet2::pending_tx> &ptx_vector, s
change -= r.second.first;
MDEBUG("Adding " << cryptonote::print_money(change) << " expected change");
+ // for all txes that have actual change, check change is coming back to the sending wallet
for (const pending_tx &ptx: ptx_vector)
- THROW_WALLET_EXCEPTION_IF(ptx.change_dts.addr != ptx_vector[0].change_dts.addr, error::wallet_internal_error,
- "Change goes to several different addresses");
- const auto it = m_subaddresses.find(ptx_vector[0].change_dts.addr.m_spend_public_key);
- THROW_WALLET_EXCEPTION_IF(change > 0 && it == m_subaddresses.end(), error::wallet_internal_error, "Change address is not ours");
-
- required[ptx_vector[0].change_dts.addr].first += change;
- required[ptx_vector[0].change_dts.addr].second = ptx_vector[0].change_dts.is_subaddress;
+ {
+ if (ptx.change_dts.amount == 0)
+ continue;
+ THROW_WALLET_EXCEPTION_IF(m_subaddresses.find(ptx.change_dts.addr.m_spend_public_key) == m_subaddresses.end(),
+ error::wallet_internal_error, "Change address is not ours");
+ required[ptx.change_dts.addr].first += ptx.change_dts.amount;
+ required[ptx.change_dts.addr].second = ptx.change_dts.is_subaddress;
+ }
for (const auto &r: required)
{
@@ -9694,7 +9708,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_all(uint64_t below
if (unused_transfer_dust_indices_per_subaddr.count(0) == 1 && unused_transfer_dust_indices_per_subaddr.size() > 1)
unused_transfer_dust_indices_per_subaddr.erase(0);
auto i = unused_transfer_dust_indices_per_subaddr.begin();
- std::advance(i, crypto::rand<size_t>() % unused_transfer_dust_indices_per_subaddr.size());
+ std::advance(i, crypto::rand_idx(unused_transfer_dust_indices_per_subaddr.size()));
unused_transfers_indices = i->second.first;
unused_dust_indices = i->second.second;
LOG_PRINT_L2("Spending from subaddress index " << i->first);
@@ -12865,8 +12879,7 @@ uint64_t wallet2::get_segregation_fork_height() const
if (m_segregation_height > 0)
return m_segregation_height;
- static const bool use_dns = true;
- if (use_dns)
+ if (m_use_dns)
{
// All four MoneroPulse domains have DNSSEC on and valid
static const std::vector<std::string> dns_urls = {
@@ -12946,6 +12959,12 @@ void wallet2::on_device_button_request(uint64_t code)
m_callback->on_device_button_request(code);
}
//----------------------------------------------------------------------------------------------------
+void wallet2::on_device_button_pressed()
+{
+ if (nullptr != m_callback)
+ m_callback->on_device_button_pressed();
+}
+//----------------------------------------------------------------------------------------------------
boost::optional<epee::wipeable_string> wallet2::on_device_pin_request()
{
if (nullptr != m_callback)
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index c8ac7d429..39380c9df 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -105,6 +105,7 @@ namespace tools
virtual void on_lw_money_spent(uint64_t height, const crypto::hash &txid, uint64_t amount) {}
// Device callbacks
virtual void on_device_button_request(uint64_t code) {}
+ virtual void on_device_button_pressed() {}
virtual boost::optional<epee::wipeable_string> on_device_pin_request() { return boost::none; }
virtual boost::optional<epee::wipeable_string> on_device_passphrase_request(bool on_device) { return boost::none; }
virtual void on_device_progress(const hw::device_progress& event) {};
@@ -118,6 +119,7 @@ namespace tools
public:
wallet_device_callback(wallet2 * wallet): wallet(wallet) {};
void on_button_request(uint64_t code=0) override;
+ void on_button_pressed() override;
boost::optional<epee::wipeable_string> on_pin_request() override;
boost::optional<epee::wipeable_string> on_passphrase_request(bool on_device) override;
void on_progress(const hw::device_progress& event) override;
@@ -1288,6 +1290,7 @@ namespace tools
void hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const;
uint64_t hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const;
void finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash);
+ void enable_dns(bool enable) { m_use_dns = enable; }
private:
/*!
@@ -1378,6 +1381,7 @@ namespace tools
wallet_device_callback * get_device_callback();
void on_device_button_request(uint64_t code);
+ void on_device_button_pressed();
boost::optional<epee::wipeable_string> on_device_pin_request();
boost::optional<epee::wipeable_string> on_device_passphrase_request(bool on_device);
void on_device_progress(const hw::device_progress& event);
@@ -1469,6 +1473,7 @@ namespace tools
std::string m_device_name;
std::string m_device_derivation_path;
uint64_t m_device_last_key_image_sync;
+ bool m_use_dns;
// Aux transaction data from device
std::unordered_map<crypto::hash, std::string> m_tx_device;
diff --git a/tests/core_tests/wallet_tools.cpp b/tests/core_tests/wallet_tools.cpp
index 616774d18..d9cee34c1 100644
--- a/tests/core_tests/wallet_tools.cpp
+++ b/tests/core_tests/wallet_tools.cpp
@@ -135,7 +135,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
}
}
- MINFO("Selected " << i << " from tx: " << dump_keys(td.m_txid.data)
+ MDEBUG("Selected " << i << " from tx: " << dump_keys(td.m_txid.data)
<< " ki: " << dump_keys(td.m_key_image.data)
<< " amnt: " << td.amount()
<< " rct: " << td.is_rct()
diff --git a/tests/difficulty/difficulty.cpp b/tests/difficulty/difficulty.cpp
index 9985b8710..11ce0bd73 100644
--- a/tests/difficulty/difficulty.cpp
+++ b/tests/difficulty/difficulty.cpp
@@ -36,6 +36,7 @@
#include <algorithm>
#include <stdexcept>
+#include "misc_log_ex.h"
#include "cryptonote_config.h"
#include "cryptonote_basic/difficulty.h"
@@ -82,6 +83,8 @@ static int test_wide_difficulty(const char *filename)
}
int main(int argc, char *argv[]) {
+ TRY_ENTRY();
+
if (argc < 2) {
cerr << "Wrong arguments" << endl;
return 1;
@@ -136,4 +139,6 @@ int main(int argc, char *argv[]) {
data.clear(fstream::badbit);
}
return 0;
+
+ CATCH_ENTRY_L0("main", 1);
}
diff --git a/tests/functional_tests/blockchain.py b/tests/functional_tests/blockchain.py
index 3957200d8..56164600d 100755
--- a/tests/functional_tests/blockchain.py
+++ b/tests/functional_tests/blockchain.py
@@ -61,8 +61,8 @@ class BlockchainTest():
prev_block = res_info.top_block_hash
res_height = daemon.get_height()
assert res_height.height == height
- assert int(res_info.wide_cumulative_difficulty) == (res_info.cumulative_difficulty_top64 << 64) + res_info.cumulative_difficulty
- cumulative_difficulty = int(res_info.wide_cumulative_difficulty)
+ assert int(res_info.wide_cumulative_difficulty, 16) == (res_info.cumulative_difficulty_top64 << 64) + res_info.cumulative_difficulty
+ cumulative_difficulty = int(res_info.wide_cumulative_difficulty, 16)
# we should not see a block at height
ok = False
@@ -91,11 +91,11 @@ class BlockchainTest():
assert block_header.orphan_status == False
assert block_header.depth == blocks - n - 1
assert block_header.prev_hash == prev_block, prev_block
- assert int(block_header.wide_difficulty) == (block_header.difficulty_top64 << 64) + block_header.difficulty
- assert int(block_header.wide_cumulative_difficulty) == (block_header.cumulative_difficulty_top64 << 64) + block_header.cumulative_difficulty
+ assert int(block_header.wide_difficulty, 16) == (block_header.difficulty_top64 << 64) + block_header.difficulty
+ assert int(block_header.wide_cumulative_difficulty, 16) == (block_header.cumulative_difficulty_top64 << 64) + block_header.cumulative_difficulty
assert block_header.reward >= 600000000000 # tail emission
- cumulative_difficulty += int(block_header.wide_difficulty)
- assert cumulative_difficulty == int(block_header.wide_cumulative_difficulty)
+ cumulative_difficulty += int(block_header.wide_difficulty, 16)
+ assert cumulative_difficulty == int(block_header.wide_cumulative_difficulty, 16)
assert block_header.block_size > 0
assert block_header.block_weight >= block_header.block_size
assert block_header.long_term_weight > 0
@@ -123,7 +123,7 @@ class BlockchainTest():
assert res_getblocktemplate.expected_reward >= 600000000000
assert len(res_getblocktemplate.blocktemplate_blob) > 0
assert len(res_getblocktemplate.blockhashing_blob) > 0
- assert int(res_getblocktemplate.wide_difficulty) == (res_getblocktemplate.difficulty_top64 << 64) + res_getblocktemplate.difficulty
+ assert int(res_getblocktemplate.wide_difficulty, 16) == (res_getblocktemplate.difficulty_top64 << 64) + res_getblocktemplate.difficulty
# diff etc should be the same
assert res_getblocktemplate.prev_hash == res_info.top_block_hash
diff --git a/tests/hash-target.cpp b/tests/hash-target.cpp
index 12acc5a67..1e988c302 100644
--- a/tests/hash-target.cpp
+++ b/tests/hash-target.cpp
@@ -32,6 +32,7 @@
#include <cstdlib>
#include <cstring>
#include <limits>
+#include "misc_log_ex.h"
#include "crypto/hash.h"
#include "cryptonote_basic/difficulty.h"
@@ -39,6 +40,7 @@ using namespace std;
using cryptonote::check_hash;
int main(int argc, char *argv[]) {
+ TRY_ENTRY();
crypto::hash h;
for (cryptonote::difficulty_type diff = 1;; diff += 1 + (diff >> 8)) {
for (uint16_t b = 0; b < 256; b++) {
@@ -83,4 +85,5 @@ int main(int argc, char *argv[]) {
}
}
return 0;
+ CATCH_ENTRY_L0("main", 1);
}
diff --git a/tests/hash/main.cpp b/tests/hash/main.cpp
index adf1bd9c4..d62098a60 100644
--- a/tests/hash/main.cpp
+++ b/tests/hash/main.cpp
@@ -35,6 +35,7 @@
#include <string>
#include <cfenv>
+#include "misc_log_ex.h"
#include "warnings.h"
#include "crypto/hash.h"
#include "crypto/variant2_int_sqrt.h"
@@ -89,6 +90,8 @@ int test_variant2_int_sqrt();
int test_variant2_int_sqrt_ref();
int main(int argc, char *argv[]) {
+ TRY_ENTRY();
+
hash_f *f;
hash_func *hf;
fstream input;
@@ -183,6 +186,7 @@ int main(int argc, char *argv[]) {
}
}
return error ? 1 : 0;
+ CATCH_ENTRY_L0("main", 1);
}
#if defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64))
diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp
index 02faae50d..c34da04b7 100644
--- a/tests/libwallet_api_tests/main.cpp
+++ b/tests/libwallet_api_tests/main.cpp
@@ -1139,6 +1139,8 @@ TEST_F(WalletManagerMainnetTest, RecoverAndRefreshWalletMainNetAsync)
int main(int argc, char** argv)
{
+ TRY_ENTRY();
+
tools::on_startup();
// we can override default values for "TESTNET_DAEMON_ADDRESS" and "WALLETS_ROOT_DIR"
@@ -1173,4 +1175,5 @@ int main(int argc, char** argv)
::testing::InitGoogleTest(&argc, argv);
Monero::WalletManagerFactory::setLogLevel(Monero::WalletManagerFactory::LogLevel_Max);
return RUN_ALL_TESTS();
+ CATCH_ENTRY_L0("main", 1);
}
diff --git a/tests/trezor/daemon.cpp b/tests/trezor/daemon.cpp
index 5e987793a..41af93f3f 100644
--- a/tests/trezor/daemon.cpp
+++ b/tests/trezor/daemon.cpp
@@ -101,6 +101,9 @@ void mock_daemon::load_params(boost::program_options::variables_map const & vm)
mock_daemon::~mock_daemon()
{
+ if(m_http_client.is_connected())
+ m_http_client.disconnect();
+
if (!m_terminated)
{
try
@@ -134,11 +137,14 @@ void mock_daemon::init()
if(m_http_client.is_connected())
m_http_client.disconnect();
- CHECK_AND_ASSERT_THROW_MES(m_http_client.set_server(rpc_addr(), boost::none), "RPC client init fail");
+ CHECK_AND_ASSERT_THROW_MES(m_http_client.set_server(rpc_addr(), boost::none, epee::net_utils::ssl_support_t::e_ssl_support_disabled), "RPC client init fail");
}
void mock_daemon::deinit()
{
+ if(m_http_client.is_connected())
+ m_http_client.disconnect();
+
try
{
m_rpc_server.deinit();
diff --git a/tests/trezor/trezor_tests.cpp b/tests/trezor/trezor_tests.cpp
index 8d5540328..31c2471ec 100644
--- a/tests/trezor/trezor_tests.cpp
+++ b/tests/trezor/trezor_tests.cpp
@@ -60,13 +60,14 @@ namespace
#define HW_TREZOR_NAME "Trezor"
#define TREZOR_ACCOUNT_ORDERING &m_miner_account, &m_alice_account, &m_bob_account, &m_eve_account
-#define TREZOR_COMMON_TEST_CASE(genclass, CORE, BASE) \
+#define TREZOR_COMMON_TEST_CASE(genclass, CORE, BASE) do { \
rollback_chain(CORE, BASE.head_block()); \
{ \
genclass ctest; \
BASE.fork(ctest); \
GENERATE_AND_PLAY_INSTANCE(genclass, ctest, *(CORE)); \
- }
+ } \
+} while(0)
#define TREZOR_SETUP_CHAIN(NAME) do { \
++tests_count; \
@@ -83,6 +84,11 @@ static device_trezor_test *ensure_trezor_test_device();
static void rollback_chain(cryptonote::core * core, const cryptonote::block & head);
static void setup_chain(cryptonote::core * core, gen_trezor_base & trezor_base, std::string chain_path, bool fix_chain, const po::variables_map & vm_core);
+static long get_env_long(const char * flag_name, boost::optional<long> def = boost::none){
+ const char *env_data = getenv(flag_name);
+ return env_data ? atol(env_data) : (def ? def.get() : 0);
+}
+
int main(int argc, char* argv[])
{
TRY_ENTRY();
@@ -127,12 +133,13 @@ int main(int argc, char* argv[])
const bool heavy_tests = command_line::get_arg(vm, arg_heavy_tests);
const bool fix_chain = command_line::get_arg(vm, arg_fix_chain);
- hw::register_device(HW_TREZOR_NAME, ensure_trezor_test_device());
- // hw::trezor::register_all(); // We use our shim instead.
+ hw::register_device(HW_TREZOR_NAME, ensure_trezor_test_device()); // shim device for call tracking
// Bootstrapping common chain & accounts
- const uint8_t initial_hf = 9;
- const uint8_t max_hf = 10;
+ const uint8_t initial_hf = (uint8_t)get_env_long("TEST_MIN_HF", 11);
+ const uint8_t max_hf = (uint8_t)get_env_long("TEST_MAX_HF", 11);
+ MINFO("Test versions " << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")");
+ MINFO("Testing hardforks [" << (int)initial_hf << ", " << (int)max_hf << "]");
cryptonote::core core_obj(nullptr);
cryptonote::core * const core = &core_obj;
@@ -150,16 +157,20 @@ int main(int argc, char* argv[])
mock_daemon::default_options(vm_core);
// Transaction tests
- for(uint8_t hf=initial_hf; hf <= max_hf; ++hf)
+ for(uint8_t hf=initial_hf; hf <= max_hf + 1; ++hf)
{
- MDEBUG("Transaction tests for HF " << (int)hf);
- if (hf > initial_hf)
+ if (hf > initial_hf || hf > max_hf)
{
daemon->stop_and_deinit();
daemon = nullptr;
trezor_base.daemon(nullptr);
+ if (hf > max_hf)
+ {
+ break;
+ }
}
+ MDEBUG("Transaction tests for HF " << (int)hf);
trezor_base.set_hard_fork(hf);
TREZOR_SETUP_CHAIN(std::string("HF") + std::to_string((int)hf));
@@ -196,7 +207,6 @@ int main(int argc, char* argv[])
TREZOR_COMMON_TEST_CASE(gen_trezor_many_utxo, core, trezor_base);
}
- daemon->stop();
core->deinit();
el::Level level = (failed_tests.empty() ? el::Level::Info : el::Level::Error);
MLOG(level, "\nREPORT:");
@@ -225,6 +235,7 @@ static void rollback_chain(cryptonote::core * core, const cryptonote::block & he
crypto::hash head_hash = get_block_hash(head), cur_hash{};
uint64_t height = get_block_height(head), cur_height=0;
+ MDEBUG("Rollbacking to " << height << " to hash " << head_hash);
do {
core->get_blockchain_top(cur_height, cur_hash);
@@ -593,7 +604,7 @@ gen_trezor_base::gen_trezor_base(){
gen_trezor_base::gen_trezor_base(const gen_trezor_base &other):
m_generator(other.m_generator), m_bt(other.m_bt), m_miner_account(other.m_miner_account),
m_bob_account(other.m_bob_account), m_alice_account(other.m_alice_account), m_eve_account(other.m_eve_account),
- m_hard_forks(other.m_hard_forks), m_trezor(other.m_trezor), m_rct_config(other.m_rct_config),
+ m_hard_forks(other.m_hard_forks), m_trezor(other.m_trezor), m_rct_config(other.m_rct_config), m_top_hard_fork(other.m_top_hard_fork),
m_heavy_tests(other.m_heavy_tests), m_test_get_tx_key(other.m_test_get_tx_key), m_live_refresh_enabled(other.m_live_refresh_enabled),
m_network_type(other.m_network_type), m_daemon(other.m_daemon)
{
@@ -625,6 +636,7 @@ void gen_trezor_base::fork(gen_trezor_base & other)
other.m_events = m_events;
other.m_head = m_head;
other.m_hard_forks = m_hard_forks;
+ other.m_top_hard_fork = m_top_hard_fork;
other.m_trezor_path = m_trezor_path;
other.m_heavy_tests = m_heavy_tests;
other.m_rct_config = m_rct_config;
@@ -806,8 +818,6 @@ bool gen_trezor_base::generate(std::vector<test_event_entry>& events)
// RCT transactions, wallets have to be used
wallet_tools::process_transactions(m_wl_alice.get(), events, blk_5r, m_bt);
wallet_tools::process_transactions(m_wl_bob.get(), events, blk_5r, m_bt);
- MDEBUG("Available funds on Alice: " << get_available_funds(m_wl_alice.get()));
- MDEBUG("Available funds on Bob: " << get_available_funds(m_wl_bob.get()));
// Send Alice -> Bob, manually constructed. Simple TX test, precondition.
cryptonote::transaction tx_1;
@@ -827,7 +837,12 @@ bool gen_trezor_base::generate(std::vector<test_event_entry>& events)
CHECK_AND_ASSERT_THROW_MES(resx, "tx_1 semantics failed");
CHECK_AND_ASSERT_THROW_MES(resy, "tx_1 non-semantics failed");
- REWIND_BLOCKS_HF(events, blk_6r, blk_6, m_miner_account, CUR_HF);
+ REWIND_BLOCKS_N_HF(events, blk_6r, blk_6, m_miner_account, 10, CUR_HF);
+ wallet_tools::process_transactions(m_wl_alice.get(), events, blk_6, m_bt);
+ wallet_tools::process_transactions(m_wl_bob.get(), events, blk_6, m_bt);
+ MDEBUG("Available funds on Alice: " << get_available_funds(m_wl_alice.get()));
+ MDEBUG("Available funds on Bob: " << get_available_funds(m_wl_bob.get()));
+
m_head = blk_6r;
m_events = events;
return true;
@@ -889,15 +904,44 @@ void gen_trezor_base::load(std::vector<test_event_entry>& events)
MDEBUG("Available funds on Bob: " << get_available_funds(m_wl_bob.get()));
}
+void gen_trezor_base::rewind_blocks(std::vector<test_event_entry>& events, size_t rewind_n, uint8_t hf)
+{
+ auto & generator = m_generator; // macro shortcut
+ REWIND_BLOCKS_N_HF(events, blk_new, m_head, m_miner_account, rewind_n, hf);
+ m_head = blk_new;
+ m_events = events;
+ MDEBUG("Blocks rewound: " << rewind_n << ", #blocks: " << num_blocks(events) << ", #events: " << events.size());
+
+ wallet_tools::process_transactions(m_wl_alice.get(), events, m_head, m_bt);
+ wallet_tools::process_transactions(m_wl_bob.get(), events, m_head, m_bt);
+}
+
void gen_trezor_base::fix_hf(std::vector<test_event_entry>& events)
{
// If current test requires higher hard-fork, move it up
const auto current_hf = m_hard_forks.back().first;
- if (m_rct_config.bp_version == 2 && current_hf < 10){
+
+ if (current_hf > m_top_hard_fork)
+ {
+ throw std::runtime_error("Generated chain hardfork is higher than desired maximum");
+ }
+
+ if (m_rct_config.bp_version == 2 && m_top_hard_fork < 10)
+ {
+ throw std::runtime_error("Desired maximum is too low for BPv2");
+ }
+
+ if (current_hf < m_top_hard_fork)
+ {
auto hardfork_height = num_blocks(events);
- ADD_HARDFORK(m_hard_forks, 10, hardfork_height);
+ ADD_HARDFORK(m_hard_forks, m_top_hard_fork, hardfork_height);
add_top_hfork(events, m_hard_forks);
- MDEBUG("Hardfork height: " << hardfork_height);
+ MDEBUG("Hardfork added at height: " << hardfork_height << ", from " << (int)current_hf << " to " << (int)m_top_hard_fork);
+
+ if (current_hf < 10)
+ { // buffer blocks, add 10 to apply v10 rules
+ rewind_blocks(events, 10, m_top_hard_fork);
+ }
}
}
@@ -934,10 +978,9 @@ void gen_trezor_base::add_transactions_to_events(
{
// If current test requires higher hard-fork, move it up
const auto current_hf = m_hard_forks.back().first;
- const uint8_t tx_hf = m_rct_config.bp_version == 2 ? 10 : 9;
- if (tx_hf > current_hf){
- throw std::runtime_error("Too late for HF change");
- }
+ const uint8_t tx_hf = m_top_hard_fork;
+ CHECK_AND_ASSERT_THROW_MES(tx_hf <= current_hf, "Too late for HF change: " << (int)tx_hf << " current: " << (int)current_hf);
+ CHECK_AND_ASSERT_THROW_MES(m_rct_config.bp_version < 2 || tx_hf >= 10, "HF too low for BPv2: " << (int)tx_hf);
std::list<cryptonote::transaction> tx_list;
for(const auto & tx : txs)
@@ -1808,7 +1851,7 @@ bool wallet_api_tests::generate(std::vector<test_event_entry>& events)
CHECK_AND_ASSERT_THROW_MES(w->init(daemon()->rpc_addr(), 0), "Wallet init fail");
CHECK_AND_ASSERT_THROW_MES(w->refresh(), "Refresh fail");
uint64_t balance = w->balance(0);
- MINFO("Balance: " << balance);
+ MDEBUG("Balance: " << balance);
CHECK_AND_ASSERT_THROW_MES(w->status() == Monero::PendingTransaction::Status_Ok, "Status nok");
auto addr = get_address(m_eve_account);
diff --git a/tests/trezor/trezor_tests.h b/tests/trezor/trezor_tests.h
index bed49fec4..46eb5e6a5 100644
--- a/tests/trezor/trezor_tests.h
+++ b/tests/trezor/trezor_tests.h
@@ -84,6 +84,8 @@ public:
virtual void mine_and_test(std::vector<test_event_entry>& events);
+ virtual void rewind_blocks(std::vector<test_event_entry>& events, size_t rewind_n, uint8_t hf);
+
virtual void set_hard_fork(uint8_t hf);
crypto::hash head_hash() const { return get_block_hash(m_head); }