Merge pull request #291 from Doy-lee/LokiMergeUpstream

Loki Merge Upstream until 2018-10-22 #2287fb9
This commit is contained in:
Doyle 2018-10-23 10:57:37 +11:00 committed by GitHub
commit ba9bcdd4dc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
70 changed files with 589 additions and 188 deletions

View file

@ -58,7 +58,7 @@ script:
- export TRAVIS_COMMIT_LOG=`git log --format=fuller -1`
- OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
- if [ -z "$NO_DEPENDS" ]; then $DOCKER_EXEC ccache --max-size=$CCACHE_SIZE; fi
- $DOCKER_EXEC bash -c "mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=$TRAVIS_BUILD_DIR/contrib/depends/$HOST/share/toolchain.cmake .. && make $MAKEJOBS"
- $DOCKER_EXEC bash -c "mkdir build && cd build && cmake -DCMAKE_TOOLCHAIN_FILE=$TRAVIS_BUILD_DIR/contrib/depends/$HOST/share/toolchain.cmake -DTRAVIS=true .. && make $MAKEJOBS"
- export LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/contrib/depends/$HOST/lib
after_script:
- echo $TRAVIS_COMMIT_RANGE

View file

@ -41,6 +41,7 @@ if (IOS)
endif()
cmake_minimum_required(VERSION 2.8.7)
message(STATUS "CMake version ${CMAKE_VERSION}")
project(loki)
@ -144,7 +145,6 @@ if(ARCH_ID STREQUAL "ppc64le")
set(PPC64LE 1)
set(PPC64 0)
set(PPC 0)
endif()
if(ARCH_ID STREQUAL "powerpc64" OR ARCH_ID STREQUAL "ppc64")
@ -433,6 +433,8 @@ if (UNIX AND NOT APPLE)
# Note that at the time of this writing the -Wstrict-prototypes flag added below will make this fail
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads)
add_c_flag_if_supported(-pthread CMAKE_C_FLAGS)
add_cxx_flag_if_supported(-pthread CMAKE_CXX_FLAGS)
endif()
# Handle OpenSSL, used for sha256sum on binary updates and light wallet ssl http
@ -522,10 +524,8 @@ if(MSVC)
include_directories(SYSTEM src/platform/msc)
else()
include(TestCXXAcceptsFlag)
if (NOT ARM6)
if(NOT DEPENDS OR DEPENDS AND NOT ARM)
set(ARCH native CACHE STRING "CPU to build for: -march value or 'default' to not pass -march at all")
endif()
if (NOT ARCH)
set(ARCH native CACHE STRING "CPU to build for: -march value or 'default' to not pass -march at all")
endif()
message(STATUS "Building on ${CMAKE_SYSTEM_PROCESSOR} for ${ARCH}")
if(ARCH STREQUAL "default")
@ -887,7 +887,7 @@ endif()
include_directories(SYSTEM ${Boost_INCLUDE_DIRS})
if(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wa,-mbig-obj")
set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32)
set(EXTRA_LIBRARIES mswsock;ws2_32;iphlpapi;crypt32;bcrypt)
if(DEPENDS)
set(ICU_LIBRARIES ${Boost_LOCALE_LIBRARY} sicuio sicuin sicuuc sicudt sicutu iconv)
else()

View file

@ -126,6 +126,7 @@ COPY . .
ENV USE_SINGLE_BUILDDIR=1
ARG NPROC
RUN set -ex && \
git submodule init && git submodule update && \
rm -rf build && \
if [ -z "$NPROC" ] ; \
then make -j$(nproc) release-static ; \

View file

@ -388,7 +388,7 @@ Then you can run make as usual.
# Get binaries
docker cp loki-android:/src/build/release/bin .
### Building portable statically linked binaries (Cross Compiling)
### Building portable statically linked binaries
By default, in either dynamically or statically linked builds, binaries target the specific host processor on which the build happens and are not portable to other processors. Portable binaries can be built using the following targets:
@ -400,6 +400,68 @@ By default, in either dynamically or statically linked builds, binaries target t
* ```make release-static-win64``` builds binaries on 64-bit Windows portable across 64-bit Windows systems
* ```make release-static-win32``` builds binaries on 64-bit or 32-bit Windows portable across 32-bit Windows systems
### Cross Compiling
You can also cross-compile static binaries on Linux for Windows and macOS with the `depends` system. Go to `contrib/depends` and type:
* ```make HOST=x86_64-linux-gnu``` for 64-bit linux binaries.
* ```make HOST=x86_64-w64-mingw32``` for 64-bit windows binaries. Requires: python3 nsis g++-mingw-w64-x86-64 wine1.6 bc
* ```make HOST=x86_64-apple-darwin11``` for darwin binaries. Requires: cmake imagemagick libcap-dev librsvg2-bin libz-dev libbz2-dev libtiff-tools python-dev
* ```make HOST=i686-linux-gnu``` for 32-bit linux binaries. Requires: g++-multilib bc
* ```make HOST=i686-w64-mingw32``` for 32-bit windows binaries. Requires: python3 nsis g++-mingw-w64-i686
* ```make HOST=arm-linux-gnueabihf``` for armv6 binaries. Requires: g++-arm-linux-gnueabihf
The required packages are the names for each toolchain on apt. Depending on your distro, they may have different names.
Then go back to the source dir and type:
* ```cmake -DCMAKE_TOOLCHAIN_FILE=`pwd`/contrib/depends/<chosen triplet>/share/toolchain.cmake```
Where <chosen triplet> is one of the above mentioned targets.
Using `depends` might also be easier to compile Monero on Windows than using MSys. Activate Windows Subsystem for Linux (WSL) with a distro (for example Ubuntu), install the apt build-essentials and follow the `depends` steps as depicted above.
## Installing Monero from a package
**DISCLAIMER: These packages are not part of this repository or maintained by this project's contributors, and as such, do not go through the same review process to ensure their trustworthiness and security.**
Packages are available for
* Ubuntu and [snap supported](https://snapcraft.io/docs/core/install) systems, via a community contributed build.
snap install monero --beta
Installing a snap is very quick. Snaps are secure. They are isolated with all of their dependencies. Snaps also auto update when a new version is released.
* Arch Linux (via [AUR](https://aur.archlinux.org/)):
- Stable release: [`monero`](https://aur.archlinux.org/packages/monero)
- Bleeding edge: [`monero-git`](https://aur.archlinux.org/packages/monero-git)
* Void Linux:
xbps-install -S monero
* GuixSD
guix package -i monero
* Docker
# Build using all available cores
docker build -t monero .
# or build using a specific number of cores (reduce RAM requirement)
docker build --build-arg NPROC=1 -t monero .
# either run in foreground
docker run -it -v /monero/chain:/root/.bitmonero -v /monero/wallet:/wallet -p 18080:18080 monero
# or in background
docker run -it -d -v /monero/chain:/root/.bitmonero -v /monero/wallet:/wallet -p 18080:18080 monero
* The build needs 3 GB space.
* Wait one hour or more
Packaging for your favorite distribution would be a welcome contribution!
## Running lokid
The build places the binary in `bin/` sub-directory within the build directory

View file

@ -51,7 +51,9 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
SET(APPLE True)
SET(BUILD_TAG "mac-x64")
SET(BUILD_64 ON)
if(NOT TRAVIS)
SET(ARCH "x86_64")
endif()
SET(BREW OFF)
SET(PORT OFF)
SET(CMAKE_OSX_SYSROOT "@sdk@/MacOSX10.11.sdk/")

View file

@ -352,8 +352,11 @@ eof:
std::string command;
bool get_line_ret = m_stdin_reader.get_line(command);
if (!m_running || m_stdin_reader.eos())
if (!m_running)
break;
if (m_stdin_reader.eos())
{
MGINFO("EOF on stdin, exiting");
break;
}
if (!get_line_ret)

View file

@ -147,7 +147,8 @@ namespace misc_utils
{}
~call_befor_die()
{
m_func();
try { m_func(); }
catch (...) { /* ignore */ }
}
};

View file

@ -246,7 +246,6 @@ namespace net_utils
m_timer(io_serice)
{}
boost::asio::deadline_timer m_timer;
uint64_t m_period;
};
template <class t_handler>
@ -262,25 +261,27 @@ namespace net_utils
{
return m_handler();
}
uint64_t m_period;
};
template<class t_handler>
bool add_idle_handler(t_handler t_callback, uint64_t timeout_ms)
{
boost::shared_ptr<idle_callback_conext_base> ptr(new idle_callback_conext<t_handler>(io_service_, t_callback, timeout_ms));
boost::shared_ptr<idle_callback_conext<t_handler>> ptr(new idle_callback_conext<t_handler>(io_service_, t_callback, timeout_ms));
//needed call handler here ?...
ptr->m_timer.expires_from_now(boost::posix_time::milliseconds(ptr->m_period));
ptr->m_timer.async_wait(boost::bind(&boosted_tcp_server<t_protocol_handler>::global_timer_handler, this, ptr));
ptr->m_timer.async_wait(boost::bind(&boosted_tcp_server<t_protocol_handler>::global_timer_handler<t_handler>, this, ptr));
return true;
}
bool global_timer_handler(/*const boost::system::error_code& err, */boost::shared_ptr<idle_callback_conext_base> ptr)
template<class t_handler>
bool global_timer_handler(/*const boost::system::error_code& err, */boost::shared_ptr<idle_callback_conext<t_handler>> ptr)
{
//if handler return false - he don't want to be called anymore
if(!ptr->call_handler())
return true;
ptr->m_timer.expires_from_now(boost::posix_time::milliseconds(ptr->m_period));
ptr->m_timer.async_wait(boost::bind(&boosted_tcp_server<t_protocol_handler>::global_timer_handler, this, ptr));
ptr->m_timer.async_wait(boost::bind(&boosted_tcp_server<t_protocol_handler>::global_timer_handler<t_handler>, this, ptr));
return true;
}

View file

@ -43,6 +43,8 @@
#include <boost/date_time/posix_time/posix_time.hpp> // TODO
#include <boost/thread/thread.hpp> // TODO
#include <boost/thread/condition_variable.hpp> // TODO
#include "warnings.h"
#include "string_tools.h"
#include "misc_language.h"
#include "net/local_ip.h"
#include "pragma_comp_defs.h"
@ -51,8 +53,6 @@
#include <iomanip>
#include <algorithm>
#include "../../../../src/cryptonote_core/cryptonote_core.h" // e.g. for the send_stop_signal()
#undef LOKI_DEFAULT_LOG_CATEGORY
#define LOKI_DEFAULT_LOG_CATEGORY "net"
@ -149,10 +149,8 @@ PRAGMA_WARNING_DISABLE_VS(4355)
const unsigned long ip_{boost::asio::detail::socket_ops::host_to_network_long(remote_ep.address().to_v4().to_ulong())};
m_local = epee::net_utils::is_ip_loopback(ip_) || epee::net_utils::is_ip_local(ip_);
// create a random uuid
boost::uuids::uuid random_uuid;
// that stuff turns out to be included, even though it's from src... Taking advantage
random_uuid = crypto::rand<boost::uuids::uuid>();
// create a random uuid, we don't need crypto strength here
const boost::uuids::uuid random_uuid = boost::uuids::random_generator()();
context.set_details(random_uuid, epee::net_utils::ipv4_network_address(ip_, remote_ep.port()), is_income);
_dbg3("[sock " << socket_.native_handle() << "] new connection from " << print_connection_context_short(context) <<

View file

@ -92,7 +92,6 @@ class connection_basic { // not-templated base class for rapid developmet of som
critical_section m_send_que_lock;
std::list<std::string> m_send_que;
volatile bool m_is_multithreaded;
double m_start_time;
/// Strand to ensure the connection's handlers are not called concurrently.
boost::asio::io_service::strand strand_;
/// Socket for the connection.
@ -112,8 +111,6 @@ class connection_basic { // not-templated base class for rapid developmet of som
void logger_handle_net_write(size_t size); // network data written
void logger_handle_net_read(size_t size); // network data read
void set_start_time();
// config for rate limit
static void set_rate_up_limit(uint64_t limit);

View file

@ -32,6 +32,7 @@
#include "string_tools.h"
#include "file_io_utils.h"
#include "net_parse_helpers.h"
#include "time_helper.h"
#undef LOKI_DEFAULT_LOG_CATEGORY
#define LOKI_DEFAULT_LOG_CATEGORY "net.http"

View file

@ -99,7 +99,7 @@ public:
size_t get_connections_count();
void set_handler(levin_commands_handler<t_connection_context>* handler, void (*destroy)(levin_commands_handler<t_connection_context>*) = NULL);
async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE)
async_protocol_handler_config():m_pcommands_handler(NULL), m_pcommands_handler_destroy(NULL), m_max_packet_size(LEVIN_DEFAULT_MAX_PACKET_SIZE), m_invoke_timeout(LEVIN_DEFAULT_TIMEOUT_PRECONFIGURED)
{}
~async_protocol_handler_config() { set_handler(NULL, NULL); }
void del_out_connections(size_t count);
@ -272,6 +272,8 @@ public:
m_wait_count = 0;
m_oponent_protocol_ver = 0;
m_connection_initialized = false;
m_invoke_buf_ready = 0;
m_invoke_result_code = LEVIN_ERROR_CONNECTION;
}
virtual ~async_protocol_handler()
{

View file

@ -250,22 +250,15 @@ void connection_basic::sleep_before_packet(size_t packet_size, int phase, int q
}
}
void connection_basic::set_start_time() {
CRITICAL_REGION_LOCAL( network_throttle_manager::m_lock_get_global_throttle_out );
m_start_time = network_throttle_manager::get_global_throttle_out().get_time_seconds();
}
void connection_basic::do_send_handler_write(const void* ptr , size_t cb ) {
// No sleeping here; sleeping is done once and for all in connection<t_protocol_handler>::handle_write
MTRACE("handler_write (direct) - before ASIO write, for packet="<<cb<<" B (after sleep)");
set_start_time();
}
void connection_basic::do_send_handler_write_from_queue( const boost::system::error_code& e, size_t cb, int q_len ) {
// No sleeping here; sleeping is done once and for all in connection<t_protocol_handler>::handle_write
MTRACE("handler_write (after write, from queue="<<q_len<<") - before ASIO write, for packet="<<cb<<" B (after sleep)");
set_start_time();
}
void connection_basic::logger_handle_net_read(size_t size) { // network data read

View file

@ -28,6 +28,13 @@
#ifndef _MLOG_H_
#define _MLOG_H_
#ifdef _WIN32
#include <windows.h>
#ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
#define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
#endif
#endif
#include <time.h>
#include <atomic>
#include <boost/filesystem.hpp>
@ -117,6 +124,31 @@ static const char *get_default_categories(int level)
return categories;
}
#ifdef WIN32
bool EnableVTMode()
{
// Set output mode to handle virtual terminal sequences
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
if (hOut == INVALID_HANDLE_VALUE)
{
return false;
}
DWORD dwMode = 0;
if (!GetConsoleMode(hOut, &dwMode))
{
return false;
}
dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
if (!SetConsoleMode(hOut, dwMode))
{
return false;
}
return true;
}
#endif
void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size, const std::size_t max_log_files)
{
el::Configurations c;
@ -202,6 +234,9 @@ void mlog_configure(const std::string &filename_base, bool console, const std::s
loki_log = get_default_categories(0);
}
mlog_set_log(loki_log);
#ifdef WIN32
EnableVTMode();
#endif
}
void mlog_set_categories(const char *categories)

View file

@ -146,6 +146,7 @@ network_throttle::network_throttle(const std::string &nameshort, const std::stri
m_network_add_cost = 128;
m_network_minimal_segment = 256;
m_network_max_segment = 1024*1024;
m_start_time = 0;
m_any_packet_yet = false;
m_slot_size = 1.0; // hard coded in few places
m_target_speed = 16 * 1024; // other defaults are probably defined in the command-line parsing code when this class is used e.g. as main global throttle

View file

@ -183,7 +183,7 @@ target_link_libraries(blockchain_blackball
set_property(TARGET blockchain_blackball
PROPERTY
OUTPUT_NAME "loki-blockchain-blackball")
OUTPUT_NAME "loki-blockchain-mark-spent-outputs")
install(TARGETS blockchain_blackball DESTINATION bin)

View file

@ -227,7 +227,7 @@ static void init(std::string cache_filename)
bool tx_active = false;
int dbr;
MINFO("Creating blackball cache in " << cache_filename);
MINFO("Creating spent output cache in " << cache_filename);
tools::create_directories_if_necessary(cache_filename);
@ -1020,7 +1020,7 @@ int main(int argc, char* argv[])
po::options_description desc_cmd_only("Command line options");
po::options_description desc_cmd_sett("Command line options and settings options");
const command_line::arg_descriptor<std::string> arg_blackball_db_dir = {
"blackball-db-dir", "Specify blackball database directory",
"spent-output-db-dir", "Specify spent output database directory",
get_default_db_path(),
};
const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""};
@ -1077,7 +1077,7 @@ int main(int argc, char* argv[])
return 1;
}
mlog_configure(mlog_get_default_log_path("loki-blockchain-blackball.log"), true);
mlog_configure(mlog_get_default_log_path("loki-blockchain-find-spent-outputs.log"), true);
if (!command_line::is_arg_defaulted(vm, arg_log_level))
mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
else
@ -1134,10 +1134,10 @@ int main(int argc, char* argv[])
core_storage[n] = &(blockchain_objects->m_blockchain);
}
const std::string cache_dir = (output_file_path / "blackball-cache").string();
const std::string cache_dir = (output_file_path / "spent-outputs-cache").string();
init(cache_dir);
LOG_PRINT_L0("Scanning for blackballable outputs...");
LOG_PRINT_L0("Scanning for spent outputs...");
size_t done = 0;
@ -1235,7 +1235,7 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, absolute[0]);
if (opt_verbose)
{
MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in a 1-ring");
MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in a 1-ring");
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
}
blackballs.push_back(output);
@ -1249,7 +1249,7 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, absolute[o]);
if (opt_verbose)
{
MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in " << new_ring.size() << " identical " << new_ring.size() << "-rings");
MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in " << new_ring.size() << " identical " << new_ring.size() << "-rings");
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
}
blackballs.push_back(output);
@ -1264,7 +1264,7 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, absolute[o]);
if (opt_verbose)
{
MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in " << new_ring.size() << " subsets of " << new_ring.size() << "-rings");
MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in " << new_ring.size() << " subsets of " << new_ring.size() << "-rings");
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
}
blackballs.push_back(output);
@ -1300,7 +1300,7 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(txin.amount, common[0]);
if (opt_verbose)
{
MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in rings with a single common element");
MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in rings with a single common element");
std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush;
}
blackballs.push_back(output);
@ -1412,7 +1412,7 @@ int main(int argc, char* argv[])
const std::pair<uint64_t, uint64_t> output = std::make_pair(od.amount, last_unknown);
if (opt_verbose)
{
MINFO("Blackballing output " << output.first << "/" << output.second << ", due to being used in a " <<
MINFO("Marking output " << output.first << "/" << output.second << " as spent, due to being used in a " <<
absolute.size() << "-ring where all other outputs are known to be spent");
}
blackballs.push_back(output);
@ -1440,7 +1440,7 @@ int main(int argc, char* argv[])
skip_secondary_passes:
uint64_t diff = get_num_spent_outputs() - start_blackballed_outputs;
LOG_PRINT_L0(std::to_string(diff) << " new outputs blackballed, " << get_num_spent_outputs() << " total outputs blackballed");
LOG_PRINT_L0(std::to_string(diff) << " new outputs marked as spent, " << get_num_spent_outputs() << " total outputs marked as spent");
MDB_txn *txn;
dbr = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
@ -1480,7 +1480,7 @@ skip_secondary_passes:
mdb_txn_abort(txn);
}
LOG_PRINT_L0("Blockchain blackball data exported OK");
LOG_PRINT_L0("Blockchain spent output data exported OK");
close_db(env0, txn0, cur0, dbi0);
close();
return 0;

View file

@ -350,7 +350,9 @@ public:
using error_type = std::error_code;
//! Create a successful object.
expect() = default;
expect() noexcept
: code_()
{}
expect(std::error_code const& code) noexcept
: code_(code)

View file

@ -60,7 +60,7 @@ namespace
DWORD mode_old;
::GetConsoleMode(h_cin, &mode_old);
DWORD mode_new = mode_old & ~((hide_input ? ENABLE_ECHO_INPUT : 0) | ENABLE_LINE_INPUT);
DWORD mode_new = mode_old & ~(hide_input ? ENABLE_ECHO_INPUT : 0);
::SetConsoleMode(h_cin, mode_new);
bool r = true;
@ -78,7 +78,11 @@ namespace
{
break;
}
else if (ucs2_ch == L'\n' || ucs2_ch == L'\r')
else if (ucs2_ch == L'\r')
{
continue;
}
else if (ucs2_ch == L'\n')
{
std::cout << std::endl;
break;
@ -158,6 +162,13 @@ namespace
if (!aPass.empty())
{
aPass.pop_back();
if (!hide_input)
std::cout << "\b\b\b \b\b\b" << std::flush;
}
else
{
if (!hide_input)
std::cout << "\b\b \b\b" << std::flush;
}
}
else

View file

@ -38,6 +38,7 @@
#endif
#include "misc_log_ex.h"
#include "util.h"
#include "spawn.h"
namespace tools
@ -101,6 +102,8 @@ int spawn(const char *filename, const std::vector<std::string>& args, bool wait)
// child
if (pid == 0)
{
tools::closefrom(3);
close(0);
char *envp[] = {NULL};
execve(filename, argv, envp);
MERROR("Failed to execve: " << strerror(errno));

View file

@ -49,11 +49,19 @@ threadpool::~threadpool() {
}
void threadpool::stop() {
try
{
const boost::unique_lock<boost::mutex> lock(mutex);
running = false;
has_work.notify_all();
}
catch (...)
{
// if the lock throws, we're just do it without a lock and hope,
// since the alternative is terminate
running = false;
has_work.notify_all();
}
for (size_t i = 0; i<threads.size(); i++) {
try { threads[i].join(); }
catch (...) { /* ignore */ }
@ -103,11 +111,13 @@ unsigned int threadpool::get_max_concurrency() const {
threadpool::waiter::~waiter()
{
try
{
boost::unique_lock<boost::mutex> lock(mt);
if (num)
MERROR("wait should have been called before waiter dtor - waiting now");
}
catch (...) { /* ignore */ }
try
{
wait(NULL);

View file

@ -29,6 +29,7 @@
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include <unistd.h>
#include <cstdio>
#ifdef __GLIBC__
@ -234,7 +235,7 @@ namespace tools
MERROR("Failed to open " << filename << ": " << std::error_code(GetLastError(), std::system_category()));
}
#else
m_fd = open(filename.c_str(), O_RDONLY | O_CREAT, 0666);
m_fd = open(filename.c_str(), O_RDONLY | O_CREAT | O_CLOEXEC, 0666);
if (m_fd != -1)
{
if (flock(m_fd, LOCK_EX | LOCK_NB) == -1)
@ -968,4 +969,23 @@ std::string get_nix_version_display_string()
}
#endif
void closefrom(int fd)
{
#if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
::closefrom(fd);
#else
#if defined __GLIBC__
const int sc_open_max = sysconf(_SC_OPEN_MAX);
const int MAX_FDS = std::min(65536, sc_open_max);
#else
const int MAX_FDS = 65536;
#endif
while (fd < MAX_FDS)
{
close(fd);
++fd;
}
#endif
}
}

View file

@ -238,4 +238,6 @@ namespace tools
#ifdef _WIN32
std::string input_line_win();
#endif
void closefrom(int fd);
}

View file

@ -196,6 +196,7 @@ namespace cryptonote
public:
transaction_prefix(){}
bool is_deregister_tx() const { return (version >= version_3_per_output_unlock_times) && is_deregister; }
uint64_t get_unlock_time(size_t out_index) const
{
if (version >= version_3_per_output_unlock_times)
@ -236,7 +237,6 @@ namespace cryptonote
void set_hash_valid(bool v) const { hash_valid.store(v,std::memory_order_release); }
bool is_blob_size_valid() const { return blob_size_valid.load(std::memory_order_acquire); }
void set_blob_size_valid(bool v) const { blob_size_valid.store(v,std::memory_order_release); }
bool is_deregister_tx() const { return (version >= version_3_per_output_unlock_times) && is_deregister; }
BEGIN_SERIALIZE_OBJECT()
if (!typename Archive<W>::is_saving())

View file

@ -203,6 +203,16 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------
bool parse_and_validate_tx_prefix_from_blob(const blobdata& tx_blob, transaction_prefix& tx)
{
std::stringstream ss;
ss << tx_blob;
binary_archive<false> ba(ss);
bool r = ::serialization::serialize_noeof(ba, tx);
CHECK_AND_ASSERT_MES(r, false, "Failed to parse transaction prefix from blob");
return true;
}
//---------------------------------------------------------------
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash)
{
std::stringstream ss;

View file

@ -52,6 +52,7 @@ namespace cryptonote
//---------------------------------------------------------------
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h);
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx);
bool parse_and_validate_tx_prefix_from_blob(const blobdata& tx_blob, transaction_prefix& tx);
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash);
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx);
bool parse_and_validate_tx_base_from_blob(const blobdata& tx_blob, transaction& tx);

View file

@ -200,7 +200,7 @@ namespace cryptonote
float hr = static_cast<float>(total_hr)/static_cast<float>(m_last_hash_rates.size());
const auto flags = std::cout.flags();
const auto precision = std::cout.precision();
std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << flags << precision << ENDL;
std::cout << "hashrate: " << std::setprecision(4) << std::fixed << hr << std::setiosflags(flags) << std::setprecision(precision) << ENDL;
}
}
m_last_hr_merge_time = misc_utils::get_tick_count();

View file

@ -306,6 +306,9 @@ uint64_t Blockchain::get_current_blockchain_height() const
bool Blockchain::init(BlockchainDB* db, const network_type nettype, bool offline, const cryptonote::test_options *test_options, difficulty_type fixed_difficulty)
{
LOG_PRINT_L3("Blockchain::" << __func__);
CHECK_AND_ASSERT_MES(nettype != FAKECHAIN || test_options, false, "fake chain network type used without options");
CRITICAL_REGION_LOCAL(m_tx_pool);
CRITICAL_REGION_LOCAL1(m_blockchain_lock);
@ -2386,7 +2389,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
const bool bulletproof = rct::is_rct_bulletproof(tx.rct_signatures.type);
if (bulletproof || !tx.rct_signatures.p.bulletproofs.empty())
{
MERROR("Bulletproofs are not allowed before v10");
MERROR_VER("Bulletproofs are not allowed before v10");
tvc.m_invalid_output = true;
return false;
}
@ -2396,7 +2399,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
const bool borromean = rct::is_rct_borromean(tx.rct_signatures.type);
if (borromean)
{
MERROR("Borromean range proofs are not allowed after v10");
MERROR_VER("Borromean range proofs are not allowed after v10");
tvc.m_invalid_output = true;
return false;
}

View file

@ -918,16 +918,19 @@ namespace cryptonote
}
waiter.wait(&tpool);
it = tx_blobs.begin();
std::vector<bool> already_have(tx_blobs.size(), false);
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
if (!results[i].res)
continue;
if(m_mempool.have_tx(results[i].hash))
{
LOG_PRINT_L2("tx " << results[i].hash << "already have transaction in tx_pool");
already_have[i] = true;
}
else if(m_blockchain_storage.have_tx(results[i].hash))
{
LOG_PRINT_L2("tx " << results[i].hash << " already have transaction in blockchain");
already_have[i] = true;
}
else
{
@ -949,7 +952,7 @@ namespace cryptonote
std::vector<tx_verification_batch_info> tx_info;
tx_info.reserve(tx_blobs.size());
for (size_t i = 0; i < tx_blobs.size(); i++) {
if (!results[i].res)
if (!results[i].res || already_have[i])
continue;
tx_info.push_back({&results[i].tx, results[i].hash, tvc[i], results[i].res});
}
@ -959,6 +962,8 @@ namespace cryptonote
bool ok = true;
it = tx_blobs.begin();
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
if (already_have[i])
continue;
if (!results[i].res)
{
ok = false;

View file

@ -298,7 +298,7 @@ namespace cryptonote
CRITICAL_REGION_LOCAL1(m_blockchain);
LockedTXN lock(m_blockchain);
m_blockchain.add_txpool_tx(tx, meta);
if (!insert_key_images(tx, kept_by_block))
if (!insert_key_images(tx, id, kept_by_block))
return false;
m_txs_by_fee_and_receive_time.emplace(std::tuple<bool, double, std::time_t>(tx.is_deregister_tx(), fee / (double)tx_weight, receive_time), id);
}
@ -338,9 +338,10 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL1(m_blockchain);
LockedTXN lock(m_blockchain);
m_blockchain.remove_txpool_tx(get_transaction_hash(tx));
const crypto::hash txid = get_transaction_hash(tx);
m_blockchain.remove_txpool_tx(txid);
m_blockchain.add_txpool_tx(tx, meta);
if (!insert_key_images(tx, kept_by_block))
if (!insert_key_images(tx, txid, kept_by_block))
return false;
m_txs_by_fee_and_receive_time.emplace(std::tuple<bool, double, std::time_t>(tx.is_deregister_tx(), fee / (double)tx_weight, receive_time), id);
}
@ -397,20 +398,26 @@ namespace cryptonote
LockedTXN lock(m_blockchain);
bool changed = false;
auto prune_tx = [this](sorted_tx_container::iterator &it, crypto::hash const &txid, transaction const &tx, cryptonote::blobdata const &tx_blob, bool &changed)
auto prune_tx = [this](sorted_tx_container::iterator &it, crypto::hash const &txid, txpool_tx_meta_t const &meta, bool &changed)
{
const uint64_t tx_fee = std::get<1>(it->first);
const double fee_per_byte = tx_fee / tx_blob.size();
const uint64_t tx_weight = get_transaction_weight(tx, tx_blob.size());
cryptonote::blobdata tx_blob = m_blockchain.get_txpool_tx_blob(txid);
cryptonote::transaction_prefix tx;
if (!parse_and_validate_tx_prefix_from_blob(tx_blob, tx))
{
return false;
}
// remove first, in case this throws, so key images aren't removed
MINFO("Pruning tx " << txid << " from txpool: weight: " << tx_weight << ", fee/byte: " << fee_per_byte);
const uint64_t tx_fee = std::get<1>(it->first);
MINFO("Pruning tx " << txid << " from txpool: weight: " << meta.weight << ", fee/byte: " << tx_fee);
m_blockchain.remove_txpool_tx(txid);
m_txpool_weight -= tx_weight;
remove_transaction_keyimages(tx);
MINFO("Pruned tx " << txid << " from txpool: weight: " << tx_weight << ", fee/byte: " << fee_per_byte);
m_txpool_weight -= meta.weight;
remove_transaction_keyimages(tx, txid);
MINFO("Pruned tx " << txid << " from txpool: weight: " << meta.weight << ", fee/byte: " << tx_fee);
it = m_txs_by_fee_and_receive_time.erase(it);
changed = true;
return true;
};
for (auto it = m_txs_by_fee_and_receive_time.begin(); it != m_txs_by_fee_and_receive_time.end(); )
@ -437,15 +444,11 @@ namespace cryptonote
continue;
}
cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(txid);
cryptonote::transaction tx;
if (!parse_and_validate_tx_from_blob(txblob, tx))
if (!prune_tx(it, txid, meta, changed))
{
MERROR("Failed to parse tx from txpool");
return;
}
prune_tx(it, txid, tx, txblob, changed);
}
catch (const std::exception &e)
{
@ -475,14 +478,12 @@ namespace cryptonote
--it;
continue;
}
cryptonote::blobdata txblob = m_blockchain.get_txpool_tx_blob(txid);
cryptonote::transaction tx;
if (!parse_and_validate_tx_from_blob(txblob, tx))
if (!prune_tx(it, txid, meta, changed))
{
MERROR("Failed to parse tx from txpool");
return;
}
prune_tx(it, txid, tx, txblob, changed);
}
catch (const std::exception &e)
{
@ -496,11 +497,10 @@ namespace cryptonote
MINFO("Pool weight after pruning is larger than limit: " << m_txpool_weight << "/" << bytes);
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::insert_key_images(const transaction &tx, bool kept_by_block)
bool tx_memory_pool::insert_key_images(const transaction_prefix &tx, const crypto::hash &id, bool kept_by_block)
{
for(const auto& in: tx.vin)
{
const crypto::hash id = get_transaction_hash(tx);
CHECKED_GET_SPECIFIC_VARIANT(in, const txin_to_key, txin, false);
std::unordered_set<crypto::hash>& kei_image_set = m_spent_key_images[txin.k_image];
CHECK_AND_ASSERT_MES(kept_by_block || kei_image_set.size() == 0, false, "internal error: kept_by_block=" << kept_by_block
@ -516,19 +516,17 @@ namespace cryptonote
//FIXME: Can return early before removal of all of the key images.
// At the least, need to make sure that a false return here
// is treated properly. Should probably not return early, however.
bool tx_memory_pool::remove_transaction_keyimages(const transaction& tx)
bool tx_memory_pool::remove_transaction_keyimages(const transaction_prefix& tx, const crypto::hash &actual_hash)
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
// ND: Speedup
// 1. Move transaction hash calcuation outside of loop. ._.
crypto::hash actual_hash = get_transaction_hash(tx);
for(const txin_v& vi: tx.vin)
{
CHECKED_GET_SPECIFIC_VARIANT(vi, const txin_to_key, txin, false);
auto it = m_spent_key_images.find(txin.k_image);
CHECK_AND_ASSERT_MES(it != m_spent_key_images.end(), false, "failed to find transaction input in key images. img=" << txin.k_image << ENDL
<< "transaction id = " << get_transaction_hash(tx));
<< "transaction id = " << actual_hash);
std::unordered_set<crypto::hash>& key_image_set = it->second;
CHECK_AND_ASSERT_MES(key_image_set.size(), false, "empty key_image set, img=" << txin.k_image << ENDL
<< "transaction id = " << actual_hash);
@ -581,7 +579,7 @@ namespace cryptonote
// remove first, in case this throws, so key images aren't removed
m_blockchain.remove_txpool_tx(id);
m_txpool_weight -= tx_weight;
remove_transaction_keyimages(tx);
remove_transaction_keyimages(tx, id);
}
catch (const std::exception &e)
{
@ -613,7 +611,7 @@ namespace cryptonote
{
CRITICAL_REGION_LOCAL(m_transactions_lock);
CRITICAL_REGION_LOCAL1(m_blockchain);
std::unordered_set<crypto::hash> remove;
std::list<std::pair<crypto::hash, uint64_t>> remove;
m_blockchain.for_all_txpool_txes([this, &remove](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata*) {
uint64_t tx_age = time(nullptr) - meta.receive_time;
@ -631,7 +629,7 @@ namespace cryptonote
m_txs_by_fee_and_receive_time.erase(sorted_it);
}
m_timed_out_transactions.insert(txid);
remove.insert(txid);
remove.push_back(std::make_pair(txid, meta.weight));
}
return true;
}, false);
@ -639,13 +637,14 @@ namespace cryptonote
if (!remove.empty())
{
LockedTXN lock(m_blockchain);
for (const crypto::hash &txid: remove)
for (const std::pair<crypto::hash, uint64_t> &entry: remove)
{
const crypto::hash &txid = entry.first;
try
{
cryptonote::blobdata bd = m_blockchain.get_txpool_tx_blob(txid);
cryptonote::transaction tx;
if (!parse_and_validate_tx_from_blob(bd, tx))
cryptonote::transaction_prefix tx;
if (!parse_and_validate_tx_prefix_from_blob(bd, tx))
{
MERROR("Failed to parse tx from txpool");
// continue
@ -654,8 +653,8 @@ namespace cryptonote
{
// remove first, so we only remove key images if the tx removal succeeds
m_blockchain.remove_txpool_tx(txid);
m_txpool_weight -= get_transaction_weight(tx, bd.size());
remove_transaction_keyimages(tx);
m_txpool_weight -= entry.second;
remove_transaction_keyimages(tx, txid);
}
}
catch (const std::exception &e)
@ -1162,7 +1161,7 @@ namespace cryptonote
return true;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::have_key_images(const std::unordered_set<crypto::key_image>& k_images, const transaction& tx)
bool tx_memory_pool::have_key_images(const std::unordered_set<crypto::key_image>& k_images, const transaction_prefix& tx)
{
for(size_t i = 0; i!= tx.vin.size(); i++)
{
@ -1173,7 +1172,7 @@ namespace cryptonote
return false;
}
//---------------------------------------------------------------------------------
bool tx_memory_pool::append_key_images(std::unordered_set<crypto::key_image>& k_images, const transaction& tx)
bool tx_memory_pool::append_key_images(std::unordered_set<crypto::key_image>& k_images, const transaction_prefix& tx)
{
for(size_t i = 0; i!= tx.vin.size(); i++)
{
@ -1420,7 +1419,7 @@ namespace cryptonote
// remove tx from db first
m_blockchain.remove_txpool_tx(txid);
m_txpool_weight -= get_transaction_weight(tx, txblob.size());
remove_transaction_keyimages(tx);
remove_transaction_keyimages(tx, txid);
auto sorted_it = find_tx_in_sorted_container(txid);
if (sorted_it == m_txs_by_fee_and_receive_time.end())
{
@ -1463,14 +1462,14 @@ namespace cryptonote
bool r = m_blockchain.for_all_txpool_txes([this, &remove, kept](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd) {
if (!!kept != !!meta.kept_by_block)
return true;
cryptonote::transaction tx;
if (!parse_and_validate_tx_from_blob(*bd, tx))
cryptonote::transaction_prefix tx;
if (!parse_and_validate_tx_prefix_from_blob(*bd, tx))
{
MWARNING("Failed to parse tx from txpool, removing");
remove.push_back(txid);
return true;
}
if (!insert_key_images(tx, meta.kept_by_block))
if (!insert_key_images(tx, txid, meta.kept_by_block))
{
MFATAL("Failed to insert key images from txpool tx");
return false;

View file

@ -432,7 +432,7 @@ namespace cryptonote
*
* @return true on success, false on error
*/
bool insert_key_images(const transaction &tx, bool kept_by_block);
bool insert_key_images(const transaction_prefix &tx, const crypto::hash &txid, bool kept_by_block);
/**
* @brief remove old transactions from the pool
@ -484,10 +484,11 @@ namespace cryptonote
* a transaction from the pool.
*
* @param tx the transaction
* @param txid the transaction's hash
*
* @return false if any key images to be removed cannot be found, otherwise true
*/
bool remove_transaction_keyimages(const transaction& tx);
bool remove_transaction_keyimages(const transaction_prefix& tx, const crypto::hash &txid);
/**
* @brief check if any of a transaction's spent key images are present in a given set
@ -497,7 +498,7 @@ namespace cryptonote
*
* @return true if any key images present in the set, otherwise false
*/
static bool have_key_images(const std::unordered_set<crypto::key_image>& kic, const transaction& tx);
static bool have_key_images(const std::unordered_set<crypto::key_image>& kic, const transaction_prefix& tx);
/**
* @brief append the key images from a transaction to the given set
@ -507,7 +508,7 @@ namespace cryptonote
*
* @return false if any append fails, otherwise true
*/
static bool append_key_images(std::unordered_set<crypto::key_image>& kic, const transaction& tx);
static bool append_key_images(std::unordered_set<crypto::key_image>& kic, const transaction_prefix& tx);
/**
* @brief check if a transaction is a valid candidate for inclusion in a block
@ -515,11 +516,11 @@ namespace cryptonote
* @param txd the transaction to check (and info about it)
* @param txid the txid of the transaction to check
* @param txblob the transaction blob to check
* @param tx the parsed transaction, if successful
* @param tx the parsed transaction prefix, if successful
*
* @return true if the transaction is good to go, otherwise false
*/
bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const;
bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction&tx) const;
/**
* @brief mark all transactions double spending the one passed

View file

@ -137,7 +137,19 @@ bool t_daemon::run(bool interactive)
{
throw std::runtime_error{"Can't run stopped daemon"};
}
tools::signal_handler::install(std::bind(&daemonize::t_daemon::stop_p2p, this));
std::atomic<bool> stop(false), shutdown(false);
boost::thread stop_thread = boost::thread([&stop, &shutdown, this] {
while (!stop)
epee::misc_utils::sleep_no_w(100);
if (shutdown)
this->stop_p2p();
});
epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){
stop = true;
stop_thread.join();
});
tools::signal_handler::install([&stop, &shutdown](int){ stop = shutdown = true; });
try
{

View file

@ -32,6 +32,7 @@
#include "common/util.h"
#include "daemonizer/windows_service.h"
#include "daemonizer/windows_service_runner.h"
#include "cryptonote_core/cryptonote_core.h"
#include <shlobj.h>
#include <boost/filesystem/operations.hpp>

View file

@ -30,6 +30,7 @@
#include <map>
#include "cryptonote_basic/cryptonote_basic.h"
#include "cryptonote_basic/tx_extra.h"
#include "cryptonote_core/cryptonote_core.h"
#include "cryptonote_core/blockchain.h"
#include "p2p/p2p_protocol_defs.h"
#include "net/connection_basic.hpp"

View file

@ -13,6 +13,7 @@
//
#if defined(HAVE_HIDAPI)
#include <boost/scope_exit.hpp>
#include "log.hpp"
#include "device_io_hid.hpp"
@ -69,11 +70,47 @@ namespace hw {
void device_io_hid::connect(void *params) {
hid_conn_params *p = (struct hid_conn_params*)params;
this->connect(p->vid, p->pid, p->interface_number, p->usage_page, p->interface_OR_page);
this->connect(p->vid, p->pid, p->interface_number, p->usage_page);
}
void device_io_hid::connect(unsigned int vid, unsigned int pid, unsigned int interface_number, unsigned int usage_page, bool interface_OR_page ) {
hid_device_info *hwdev_info, *hwdev_info_list;
hid_device_info *device_io_hid::find_device(hid_device_info *devices_list, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page) {
bool select_any = !interface_number && !usage_page;
MDEBUG( "Looking for " <<
(select_any ? "any HID Device" : "HID Device with") <<
(interface_number ? (" interface_number " + std::to_string(interface_number.value())) : "") <<
((interface_number && usage_page) ? " or" : "") <<
(usage_page ? (" usage_page " + std::to_string(usage_page.value())) : ""));
hid_device_info *result = nullptr;
for (; devices_list != nullptr; devices_list = devices_list->next) {
BOOST_SCOPE_EXIT(&devices_list, &result) {
MDEBUG( (result == devices_list ? "SELECTED" : "SKIPPED ") <<
" HID Device" <<
" path " << safe_hid_path(devices_list) <<
" interface_number " << devices_list->interface_number <<
" usage_page " << devices_list->usage_page);
}
BOOST_SCOPE_EXIT_END
if (result != nullptr) {
continue;
}
if (select_any) {
result = devices_list;
} else if (interface_number && devices_list->interface_number == interface_number.value()) {
result = devices_list;
} else if (usage_page && devices_list->usage_page == usage_page.value()) {
result = devices_list;
}
}
return result;
}
void device_io_hid::connect(unsigned int vid, unsigned int pid, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page) {
hid_device_info *hwdev_info_list;
hid_device *hwdev;
this->disconnect();
@ -81,17 +118,8 @@ namespace hw {
hwdev_info_list = hid_enumerate(vid, pid);
ASSERT_X(hwdev_info_list, "Unable to enumerate device "+std::to_string(vid)+":"+std::to_string(vid)+ ": "+ safe_hid_error(this->usb_device));
hwdev = NULL;
hwdev_info = hwdev_info_list;
while (hwdev_info) {
if ((interface_OR_page && ((usage_page == 0xffa0) || (interface_number == 0))) ||
((usage_page == 0xffa0) && (interface_number == 0)) ) {
MDEBUG("HID Device found: " << safe_hid_path(hwdev_info));
hwdev = hid_open_path(hwdev_info->path);
break;
} else {
MDEBUG("HID Device discard: " << safe_hid_path(hwdev_info) << "("+std::to_string(hwdev_info->usage_page) << "," << std::to_string(hwdev_info->interface_number) << ")");
}
hwdev_info = hwdev_info->next;
if (hid_device_info *device = find_device(hwdev_info_list, interface_number, usage_page)) {
hwdev = hid_open_path(device->path);
}
hid_free_enumeration(hwdev_info_list);
ASSERT_X(hwdev, "Unable to open device "+std::to_string(pid)+":"+std::to_string(vid));

View file

@ -29,6 +29,7 @@
#if defined(HAVE_HIDAPI)
#include <boost/optional/optional.hpp>
#include <hidapi/hidapi.h>
#include "device_io.hpp"
@ -52,9 +53,8 @@ namespace hw {
struct hid_conn_params {
unsigned int vid;
unsigned int pid;
unsigned int interface_number;
unsigned int usage_page;
bool interface_OR_page ;
int interface_number;
unsigned short usage_page;
};
@ -82,13 +82,11 @@ namespace hw {
unsigned int wrapCommand(const unsigned char *command, size_t command_len, unsigned char *out, size_t out_len);
unsigned int unwrapReponse(const unsigned char *data, size_t data_len, unsigned char *out, size_t out_len);
hid_device_info *find_device(hid_device_info *devices_list, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page);
public:
bool hid_verbose = false;
static const unsigned int OR_SELECT = 1;
static const unsigned int AND_SELECT = 2;
static const unsigned short DEFAULT_CHANNEL = 0x0001;
static const unsigned char DEFAULT_TAG = 0x01;
static const unsigned int DEFAULT_PACKET_SIZE = 64;
@ -100,7 +98,7 @@ namespace hw {
void init();
void connect(void *params);
void connect(unsigned int vid, unsigned int pid, unsigned int interface_number, unsigned int usage_page, bool interface_OR_page );
void connect(unsigned int vid, unsigned int pid, boost::optional<int> interface_number, boost::optional<unsigned short> usage_page);
bool connected() const;
int exchange(unsigned char *command, unsigned int cmd_len, unsigned char *response, unsigned int max_resp_len);
void disconnect();

View file

@ -341,7 +341,7 @@ namespace hw {
bool device_ledger::connect(void) {
this->disconnect();
hw_device.connect(0x2c97,0x0001, 0, 0xffa0, hw_device.OR_SELECT);
hw_device.connect(0x2c97, 0x0001, 0, 0xffa0);
this->reset();
#ifdef DEBUG_HWDEVICE
cryptonote::account_public_address pubkey;

View file

@ -29,6 +29,7 @@
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#include "common/command_line.h"
#include "cryptonote_core/cryptonote_core.h"
#include "net_node.h"
namespace nodetool

View file

@ -931,7 +931,7 @@ namespace nodetool
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()),
epee::string_tools::num_to_string_fast(ipv4.port()),
m_config.m_net_config.connection_timeout,
con, m_bind_ip.empty() ? "0.0.0.0" : m_bind_ip);
con);
if(!res)
{
@ -996,7 +996,7 @@ namespace nodetool
bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(ipv4.ip()),
epee::string_tools::num_to_string_fast(ipv4.port()),
m_config.m_net_config.connection_timeout,
con, m_bind_ip.empty() ? "0.0.0.0" : m_bind_ip);
con);
if (!res) {
bool is_priority = is_priority_node(na);
@ -1611,7 +1611,7 @@ namespace nodetool
return false;
}
return true;
}, m_bind_ip.empty() ? "0.0.0.0" : m_bind_ip);
});
if(!r)
{
LOG_WARNING_CC(context, "Failed to call connect_async, network error.");

View file

@ -918,6 +918,8 @@ namespace cryptonote
return r;
m_core.get_pool_transactions_and_spent_keys_info(res.transactions, res.spent_key_images, !request_has_rpc_origin || !m_restricted);
for (tx_info& txi : res.transactions)
txi.tx_blob = epee::string_tools::buff_to_hex_nodelimer(txi.tx_blob);
res.status = CORE_RPC_STATUS_OK;
return true;
}
@ -1084,7 +1086,7 @@ namespace cryptonote
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Internal error: failed to create block template";
LOG_ERROR("Failed to tx pub key in coinbase extra");
LOG_ERROR("Failed to get tx pub key in coinbase extra");
return false;
}
res.reserved_offset = slow_memmem((void*)block_blob.data(), block_blob.size(), &tx_pub_key, sizeof(tx_pub_key));
@ -2164,6 +2166,8 @@ namespace cryptonote
try
{
// 0 is placeholder for the whole chain
const uint64_t req_to_height = req.to_height ? req.to_height : (m_core.get_current_blockchain_height() - 1);
for (uint64_t amount: req.amounts)
{
static struct D
@ -2176,7 +2180,7 @@ namespace cryptonote
} d;
boost::unique_lock<boost::mutex> lock(d.mutex);
if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req.to_height)
if (d.cached && amount == 0 && d.cached_from == req.from_height && d.cached_to == req_to_height)
{
res.distributions.push_back({amount, d.cached_start_height, req.binary, d.cached_distribution, d.cached_base});
if (!req.cumulative)
@ -2191,23 +2195,23 @@ namespace cryptonote
std::vector<uint64_t> distribution;
uint64_t start_height, base;
if (!m_core.get_output_distribution(amount, req.from_height, req.to_height, start_height, distribution, base))
if (!m_core.get_output_distribution(amount, req.from_height, req_to_height, start_height, distribution, base))
{
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
error_resp.message = "Failed to get rct distribution";
return false;
}
if (req.to_height > 0 && req.to_height >= req.from_height)
if (req_to_height > 0 && req_to_height >= req.from_height)
{
uint64_t offset = std::max(req.from_height, start_height);
if (offset <= req.to_height && req.to_height - offset + 1 < distribution.size())
distribution.resize(req.to_height - offset + 1);
if (offset <= req_to_height && req_to_height - offset + 1 < distribution.size())
distribution.resize(req_to_height - offset + 1);
}
if (amount == 0)
{
d.cached_from = req.from_height;
d.cached_to = req.to_height;
d.cached_to = req_to_height;
d.cached_distribution = distribution;
d.cached_start_height = start_height;
d.cached_base = base;

View file

@ -67,7 +67,7 @@ class classname \
// NOTE: when using a type with multiple template parameters,
// replace any comma in the template specifier with the macro
// above, or the preprocessor will eat the comma in a bad way.
#define RPC_MESSAGE_MEMBER(type, name) type name;
#define RPC_MESSAGE_MEMBER(type, name) type name = type{}
namespace cryptonote

View file

@ -318,7 +318,7 @@ namespace serialization {
* \brief self explanatory
*/
template<class Stream>
bool do_check_stream_state(Stream& s, boost::mpl::bool_<true>)
bool do_check_stream_state(Stream& s, boost::mpl::bool_<true>, bool noeof)
{
return s.good();
}
@ -329,13 +329,13 @@ namespace serialization {
* \detailed Also checks to make sure that the stream is not at EOF
*/
template<class Stream>
bool do_check_stream_state(Stream& s, boost::mpl::bool_<false>)
bool do_check_stream_state(Stream& s, boost::mpl::bool_<false>, bool noeof)
{
bool result = false;
if (s.good())
{
std::ios_base::iostate state = s.rdstate();
result = EOF == s.peek();
result = noeof || EOF == s.peek();
s.clear(state);
}
return result;
@ -347,9 +347,9 @@ namespace serialization {
* \brief calls detail::do_check_stream_state for ar
*/
template<class Archive>
bool check_stream_state(Archive& ar)
bool check_stream_state(Archive& ar, bool noeof = false)
{
return detail::do_check_stream_state(ar.stream(), typename Archive::is_saving());
return detail::do_check_stream_state(ar.stream(), typename Archive::is_saving(), noeof);
}
/*! \fn serialize
@ -360,6 +360,17 @@ namespace serialization {
inline bool serialize(Archive &ar, T &v)
{
bool r = do_serialize(ar, v);
return r && check_stream_state(ar);
return r && check_stream_state(ar, false);
}
/*! \fn serialize
*
* \brief serializes \a v into \a ar
*/
template <class Archive, class T>
inline bool serialize_noeof(Archive &ar, T &v)
{
bool r = do_serialize(ar, v);
return r && check_stream_state(ar, true);
}
}

View file

@ -1664,7 +1664,7 @@ bool simple_wallet::blackball(const std::vector<std::string> &args)
uint64_t amount = std::numeric_limits<uint64_t>::max(), offset, num_offsets;
if (args.size() == 0)
{
fail_msg_writer() << tr("usage: blackball <amount>/<offset> | <filename> [add]");
fail_msg_writer() << tr("usage: mark_output_spent <amount>/<offset> | <filename> [add]");
return true;
}
@ -1742,7 +1742,7 @@ bool simple_wallet::blackball(const std::vector<std::string> &args)
}
catch (const std::exception &e)
{
fail_msg_writer() << tr("Failed to blackball output: ") << e.what();
fail_msg_writer() << tr("Failed to mark output spent: ") << e.what();
}
return true;
@ -1753,7 +1753,7 @@ bool simple_wallet::unblackball(const std::vector<std::string> &args)
std::pair<uint64_t, uint64_t> output;
if (args.size() != 1)
{
fail_msg_writer() << tr("usage: unblackball <amount>/<offset>");
fail_msg_writer() << tr("usage: mark_output_unspent <amount>/<offset>");
return true;
}
@ -1769,7 +1769,7 @@ bool simple_wallet::unblackball(const std::vector<std::string> &args)
}
catch (const std::exception &e)
{
fail_msg_writer() << tr("Failed to unblackball output: ") << e.what();
fail_msg_writer() << tr("Failed to mark output unspent: ") << e.what();
}
return true;
@ -1780,7 +1780,7 @@ bool simple_wallet::blackballed(const std::vector<std::string> &args)
std::pair<uint64_t, uint64_t> output;
if (args.size() != 1)
{
fail_msg_writer() << tr("usage: blackballed <amount>/<offset>");
fail_msg_writer() << tr("usage: is_output_spent <amount>/<offset>");
return true;
}
@ -1793,13 +1793,13 @@ bool simple_wallet::blackballed(const std::vector<std::string> &args)
try
{
if (m_wallet->is_output_blackballed(output))
message_writer() << tr("Blackballed: ") << output.first << "/" << output.second;
message_writer() << tr("Spent: ") << output.first << "/" << output.second;
else
message_writer() << tr("not blackballed: ") << output.first << "/" << output.second;
message_writer() << tr("Not spent: ") << output.first << "/" << output.second;
}
catch (const std::exception &e)
{
fail_msg_writer() << tr("Failed to unblackball output: ") << e.what();
fail_msg_writer() << tr("Failed to check whether output is spent: ") << e.what();
}
return true;
@ -2589,18 +2589,18 @@ simple_wallet::simple_wallet()
boost::bind(&simple_wallet::save_known_rings, this, _1),
tr("save_known_rings"),
tr("Save known rings to the shared rings database"));
m_cmd_binder.set_handler("blackball",
m_cmd_binder.set_handler("mark_output_spent",
boost::bind(&simple_wallet::blackball, this, _1),
tr("blackball <amount>/<offset> | <filename> [add]"),
tr("Blackball output(s) so they never get selected as fake outputs in a ring"));
m_cmd_binder.set_handler("unblackball",
tr("mark_output_spent <amount>/<offset> | <filename> [add]"),
tr("Mark output(s) as spent so they never get selected as fake outputs in a ring"));
m_cmd_binder.set_handler("mark_output_unspent",
boost::bind(&simple_wallet::unblackball, this, _1),
tr("unblackball <amount>/<offset>"),
tr("Unblackballs an output so it may get selected as a fake output in a ring"));
m_cmd_binder.set_handler("blackballed",
tr("mark_output_unspent <amount>/<offset>"),
tr("Marks an output as unspent so it may get selected as a fake output in a ring"));
m_cmd_binder.set_handler("is_output_spent",
boost::bind(&simple_wallet::blackballed, this, _1),
tr("blackballed <amount>/<offset>"),
tr("Checks whether an output is blackballed"));
tr("is_output_spent <amount>/<offset>"),
tr("Checks whether an output is marked as spent"));
m_cmd_binder.set_handler("version",
boost::bind(&simple_wallet::version, this, _1),
tr("version"),
@ -3020,7 +3020,7 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
return false;
}
crypto::secret_key viewkey;
if (viewkey_string.hex_to_pod(unwrap(unwrap(viewkey))))
if (!viewkey_string.hex_to_pod(unwrap(unwrap(viewkey))))
{
fail_msg_writer() << tr("failed to parse view key secret key");
return false;

View file

@ -777,7 +777,7 @@ bool WalletImpl::setPassword(const std::string &password)
{
clearStatus();
try {
m_wallet->rewrite(m_wallet->get_wallet_file(), password);
m_wallet->change_password(m_wallet->get_wallet_file(), m_password, password);
m_password = password;
} catch (const std::exception &e) {
setStatusError(e.what());
@ -2162,7 +2162,7 @@ bool WalletImpl::blackballOutputs(const std::vector<std::string> &outputs, bool
bool ret = m_wallet->set_blackballed_outputs(raw_outputs, add);
if (!ret)
{
setStatusError(tr("Failed to set blackballed outputs"));
setStatusError(tr("Failed to mark outputs as spent"));
return false;
}
return true;
@ -2184,7 +2184,7 @@ bool WalletImpl::blackballOutput(const std::string &amount, const std::string &o
bool ret = m_wallet->blackball_output(std::make_pair(raw_amount, raw_offset));
if (!ret)
{
setStatusError(tr("Failed to blackball output"));
setStatusError(tr("Failed to mark output as spent"));
return false;
}
return true;
@ -2206,7 +2206,7 @@ bool WalletImpl::unblackballOutput(const std::string &amount, const std::string
bool ret = m_wallet->unblackball_output(std::make_pair(raw_amount, raw_offset));
if (!ret)
{
setStatusError(tr("Failed to unblackball output"));
setStatusError(tr("Failed to mark output as unspent"));
return false;
}
return true;

View file

@ -413,13 +413,13 @@ bool ringdb::blackball_worker(const std::vector<std::pair<uint64_t, uint64_t>> &
switch (op)
{
case BLACKBALL_BLACKBALL:
MDEBUG("Blackballing output " << output.first << "/" << output.second);
MDEBUG("Marking output " << output.first << "/" << output.second << " as spent");
dbr = mdb_cursor_put(cursor, &key, &data, MDB_APPENDDUP);
if (dbr == MDB_KEYEXIST)
dbr = 0;
break;
case BLACKBALL_UNBLACKBALL:
MDEBUG("Unblackballing output " << output.first << "/" << output.second);
MDEBUG("Marking output " << output.first << "/" << output.second << " as unspent");
dbr = mdb_cursor_get(cursor, &key, &data, MDB_GET_BOTH);
if (dbr == 0)
dbr = mdb_cursor_del(cursor, 0);

View file

@ -38,6 +38,8 @@
#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/trim.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/join.hpp>
#include <boost/range/adaptor/transformed.hpp>
#include "include_base_utils.h"
using namespace epee;
@ -3671,6 +3673,7 @@ bool wallet2::query_device(hw::device::device_type& device_type, const std::stri
if (json.Parse(account_data.c_str()).HasParseError() || !json.IsObject())
crypto::chacha8(keys_file_data.account_data.data(), keys_file_data.account_data.size(), key, keys_file_data.iv, &account_data[0]);
device_type = hw::device::device_type::SOFTWARE;
// The contents should be JSON if the wallet follows the new format.
if (json.Parse(account_data.c_str()).HasParseError())
{
@ -6978,6 +6981,8 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
LOG_PRINT_L1("Selecting real output: " << td.m_global_output_index << " for " << print_money(amount));
}
std::unordered_map<const char*, std::set<uint64_t>> picks;
// while we still need more mixins
uint64_t num_usable_outs = num_outs;
bool allow_blackballed = false;
@ -6992,7 +6997,7 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
// outputs, we still need to reach the minimum ring size)
if (allow_blackballed)
break;
MINFO("Not enough non blackballed outputs, we'll allow blackballed ones");
MINFO("Not enough output not marked as spent, we'll allow outputs marked as spent");
allow_blackballed = true;
num_usable_outs = num_outs;
}
@ -7076,11 +7081,15 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
}
seen_indices.emplace(i);
LOG_PRINT_L2("picking " << i << " as " << type);
picks[type].insert(i);
req.outputs.push_back({amount, i});
++num_found;
}
for (const auto &pick: picks)
MDEBUG("picking " << pick.first << " outputs: " <<
boost::join(pick.second | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " "));
// if we had enough unusable outputs, we might fall off here and still
// have too few outputs, so we stuff with one to keep counts good, and
// we'll error out later
@ -7096,8 +7105,15 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
[](const get_outputs_out &a, const get_outputs_out &b) { return a.index < b.index; });
}
for (auto i: req.outputs)
LOG_PRINT_L1("asking for output " << i.index << " for " << print_money(i.amount));
if (ELPP->vRegistry()->allowed(el::Level::Debug, LOKI_DEFAULT_LOG_CATEGORY))
{
std::map<uint64_t, std::set<uint64_t>> outs;
for (const auto &i: req.outputs)
outs[i.amount].insert(i.index);
for (const auto &o: outs)
MDEBUG("asking for outputs with amount " << print_money(o.first) << ": " <<
boost::join(o.second | boost::adaptors::transformed([](uint64_t out){return std::to_string(out);}), " "));
}
// get the keys for those
m_daemon_rpc_mutex.lock();

View file

@ -2823,8 +2823,7 @@ namespace tools
{
try
{
m_wallet->rewrite(m_wallet->get_wallet_file(), req.new_password);
m_wallet->store();
m_wallet->change_password(m_wallet->get_wallet_file(), req.old_password, req.new_password);
LOG_PRINT_L0("Wallet password changed.");
}
catch (const std::exception& e)

View file

@ -36,6 +36,7 @@
#include <string>
#include "common/util.h"
#include "net/http_server_impl_base.h"
#include "math_helper.h"
#include "wallet_rpc_server_commands_defs.h"
#include "wallet2.h"

View file

@ -122,6 +122,11 @@ int main(int argc, char* argv[])
if (run_all)
{
GENERATE_AND_PLAY(gen_simple_chain_001);
GENERATE_AND_PLAY(gen_simple_chain_split_1);
GENERATE_AND_PLAY(gen_chain_switch_1);
GENERATE_AND_PLAY(gen_ring_signature_1);
GENERATE_AND_PLAY(gen_ring_signature_2);
GENERATE_AND_PLAY(one_block);
// Block verification tests
@ -139,6 +144,7 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(gen_block_unlock_time_is_timestamp_in_future);
GENERATE_AND_PLAY(gen_block_height_is_low);
GENERATE_AND_PLAY(gen_block_height_is_high);
GENERATE_AND_PLAY(gen_block_miner_tx_has_2_in);
GENERATE_AND_PLAY(gen_block_miner_tx_has_2_tx_gen_in);
GENERATE_AND_PLAY(gen_block_miner_tx_with_txin_to_key);
GENERATE_AND_PLAY(gen_block_miner_tx_out_is_big);
@ -180,15 +186,7 @@ int main(int argc, char* argv[])
// TODO(loki): Tests we need to fix
#if 0
GENERATE_AND_PLAY(gen_simple_chain_001);
GENERATE_AND_PLAY(gen_simple_chain_split_1);
GENERATE_AND_PLAY(gen_chain_switch_1);
GENERATE_AND_PLAY(gen_ring_signature_1);
GENERATE_AND_PLAY(gen_ring_signature_2);
//GENERATE_AND_PLAY(gen_ring_signature_big); // Takes up to XXX hours (if CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW == 10)
Block verification tests
GENERATE_AND_PLAY(gen_block_miner_tx_has_2_in);
//GENERATE_AND_PLAY(gen_block_invalid_binary_format); // Takes up to 3 hours, if CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW == 500, up to 30 minutes, if CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW == 10
// Transaction verification tests
@ -282,6 +280,7 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(gen_multisig_tx_valid_25_1_2_many_inputs);
GENERATE_AND_PLAY(gen_multisig_tx_valid_48_1_234);
GENERATE_AND_PLAY(gen_multisig_tx_valid_48_1_234_many_inputs);
#endif
}

View file

@ -35,6 +35,7 @@
#include <vector>
#include "warnings.h"
#include "misc_log_ex.h"
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "crypto-tests.h"
@ -59,6 +60,7 @@ bool operator !=(const key_derivation &a, const key_derivation &b) {
DISABLE_GCC_WARNING(maybe-uninitialized)
int main(int argc, char *argv[]) {
TRY_ENTRY();
fstream input;
string cmd;
size_t test = 0;
@ -266,4 +268,5 @@ error:
error = true;
}
return error ? 1 : 0;
CATCH_ENTRY_L0("main", 1);
}

View file

@ -26,10 +26,6 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
if(WIN32)
set(EXTRA_LIBRARIES "${EXTRA_LIBRARIES};bcrypt")
endif()
set(functional_tests_sources
main.cpp
transactions_flow_test.cpp

View file

@ -68,7 +68,9 @@ int Base58Fuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
Base58Fuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -61,6 +61,8 @@ int BlockFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
BlockFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -65,6 +65,8 @@ int BulletproofFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
BulletproofFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -95,7 +95,9 @@ int ColdOutputsFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
ColdOutputsFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -97,6 +97,8 @@ int ColdTransactionFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
ColdTransactionFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -92,7 +92,9 @@ int HTTPClientFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
HTTPClientFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -341,7 +341,9 @@ int LevinFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
LevinFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -70,7 +70,9 @@ int PortableStorageFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
PortableStorageFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -70,7 +70,9 @@ int PortableStorageFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
PortableStorageFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -68,7 +68,9 @@ int ParseURLFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
ParseURLFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -92,6 +92,8 @@ int SignatureFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
SignatureFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -61,6 +61,8 @@ int TransactionFuzzer::run(const std::string &filename)
int main(int argc, const char **argv)
{
TRY_ENTRY();
TransactionFuzzer fuzzer;
return run_fuzzer(argc, argv, fuzzer);
CATCH_ENTRY_L0("main", 1);
}

View file

@ -41,6 +41,7 @@
#include "misc_language.h"
#include "misc_log_ex.h"
#include "storages/levin_abstract_invoke2.h"
#include "common/util.h"
#include "net_load_tests.h"
@ -628,6 +629,7 @@ TEST_F(net_load_test_clt, permament_open_and_close_and_connections_closed_by_ser
int main(int argc, char** argv)
{
TRY_ENTRY();
tools::on_startup();
epee::debug::get_set_enable_assert(true, false);
//set up logging options
@ -635,4 +637,5 @@ int main(int argc, char** argv)
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
CATCH_ENTRY_L0("main", 1);
}

View file

@ -34,6 +34,7 @@
#include "include_base_utils.h"
#include "misc_log_ex.h"
#include "storages/levin_abstract_invoke2.h"
#include "common/util.h"
#include "net_load_tests.h"
@ -215,6 +216,7 @@ namespace
int main(int argc, char** argv)
{
TRY_ENTRY();
tools::on_startup();
//set up logging options
mlog_configure(mlog_get_default_log_path("net_load_tests_srv.log"), true);
@ -233,4 +235,5 @@ int main(int argc, char** argv)
if (!tcp_server.run_server(thread_count, true))
return 2;
return 0;
CATCH_ENTRY_L0("main", 1);
}

View file

@ -61,6 +61,7 @@ set(unit_tests_sources
mul_div.cpp
multiexp.cpp
multisig.cpp
notify.cpp
parse_amount.cpp
random.cpp
serialization.cpp
@ -123,4 +124,8 @@ SET_PROPERTY(SOURCE memwipe.cpp PROPERTY COMPILE_FLAGS -Ofast)
add_test(
NAME unit_tests
COMMAND unit_tests --data-dir "${TEST_DATA_DIR}")
COMMAND unit_tests --data-dir "${TEST_DATA_DIR} --binary-dir ${CMAKE_BINARY_DIR}")
add_executable(test_notifier test_notifier.cpp)
target_link_libraries(test_notifier ${EXTRA_LIBRARIES})
set_property(TARGET test_notifier PROPERTY FOLDER "tests")

View file

@ -84,3 +84,24 @@ TEST(aligned, contents_smaller)
aligned_free(ptr2);
}
TEST(aligned, alignment)
{
static const size_t good_alignments[] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192};
for (size_t a = 0; a <= 8192; ++a)
{
bool good = false;
for (const auto t: good_alignments) if (a == t) good = true;
void *ptr = aligned_malloc(1, a);
if (good)
{
ASSERT_TRUE(ptr != NULL);
aligned_free(ptr);
}
else
{
ASSERT_TRUE(ptr == NULL);
}
}
ASSERT_TRUE(aligned_malloc(1, ~0) == NULL);
}

View file

@ -0,0 +1,57 @@
// Copyright (c) 2018, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "gtest/gtest.h"
#include <boost/filesystem.hpp>
#include "misc_language.h"
#include "string_tools.h"
#include "file_io_utils.h"
#include "common/notify.h"
TEST(notify, works)
{
char name_template[] = "/tmp/monero-notify-unit-test-XXXXXX";
int fd = mkstemp(name_template);
ASSERT_TRUE(fd >= 0);
close(fd);
const std::string spec = epee::string_tools::get_current_module_folder() + "/test_notifier " + name_template + " %s";
tools::Notify notify(spec.c_str());
notify.notify("1111111111111111111111111111111111111111111111111111111111111111");
epee::misc_utils::sleep_no_w(100);
std::string s;
ASSERT_TRUE(epee::file_io_utils::load_file_to_string(name_template, s));
ASSERT_TRUE(s == "1111111111111111111111111111111111111111111111111111111111111111");
boost::filesystem::remove(name_template);
}

View file

@ -136,21 +136,21 @@ TEST(ringdb, different_genesis)
ASSERT_FALSE(ringdb.get_ring(KEY_2, KEY_IMAGE_1, outs2));
}
TEST(blackball, not_found)
TEST(spent_outputs, not_found)
{
RingDB ringdb;
ASSERT_TRUE(ringdb.blackball(OUTPUT_1));
ASSERT_FALSE(ringdb.blackballed(OUTPUT_2));
}
TEST(blackball, found)
TEST(spent_outputs, found)
{
RingDB ringdb;
ASSERT_TRUE(ringdb.blackball(OUTPUT_1));
ASSERT_TRUE(ringdb.blackballed(OUTPUT_1));
}
TEST(blackball, vector)
TEST(spent_outputs, vector)
{
RingDB ringdb;
std::vector<std::pair<uint64_t, uint64_t>> outputs;
@ -174,7 +174,7 @@ TEST(blackball, vector)
ASSERT_TRUE(ringdb.blackballed(std::make_pair(30, 5)));
}
TEST(blackball, unblackball)
TEST(spent_outputs, mark_as_unspent)
{
RingDB ringdb;
ASSERT_TRUE(ringdb.blackball(OUTPUT_1));
@ -182,7 +182,7 @@ TEST(blackball, unblackball)
ASSERT_FALSE(ringdb.blackballed(OUTPUT_1));
}
TEST(blackball, clear)
TEST(spent_outputs, clear)
{
RingDB ringdb;
ASSERT_TRUE(ringdb.blackball(OUTPUT_1));

View file

@ -0,0 +1,54 @@
// Copyright (c) 2018, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(int argc, char **argv)
{
if (argc < 3)
{
fprintf(stderr, "usage: %s <filename> <hash>\n", argv[0]);
return 1;
}
const char *filename = argv[1];
const char *hash = argv[2];
FILE *f = fopen(filename, "a+");
if (!f)
{
fprintf(stderr, "error opening file %s: %s\n", filename, strerror(errno));
return 1;
}
fprintf(f, "%s", hash);
fclose(f);
return 0;
}