Merge commit '2287fb9' into CherryPickUnboundWindowsBuildFix

This commit is contained in:
doy-lee 2018-10-22 15:43:00 +11:00
commit 913b3a40b5
54 changed files with 468 additions and 114 deletions

View File

@ -885,7 +885,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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -887,7 +887,7 @@ namespace cryptonote
m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos, include_sensitive_data](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){
tx_info txi;
txi.id_hash = epee::string_tools::pod_to_hex(txid);
txi.tx_blob = epee::string_tools::buff_to_hex_nodelimer(*bd);
txi.tx_blob = *bd;
transaction tx;
if (!parse_and_validate_tx_from_blob(*bd, tx))
{

View File

@ -138,13 +138,18 @@ bool t_daemon::run(bool interactive)
throw std::runtime_error{"Can't run stopped daemon"};
}
std::atomic<bool> stop(false);
boost::thread([&stop, 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);
this->stop_p2p();
}).detach();
tools::signal_handler::install([&stop](int){ stop = true; });
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

@ -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

@ -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

@ -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"),

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;
@ -6979,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;
@ -6993,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;
}
@ -7077,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
@ -7097,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

@ -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

@ -629,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
@ -636,4 +637,5 @@ int main(int argc, char** argv)
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
CATCH_ENTRY_L0("main", 1);
}

View File

@ -216,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);
@ -234,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;
}