1
0
Fork 0
forked from lthn/blockchain

Merge branch 'release'

This commit is contained in:
sowle 2019-10-05 06:57:03 +03:00
commit 40ba8cdfe4
No known key found for this signature in database
GPG key ID: C07A24B2D89D49FC
146 changed files with 4704 additions and 1306 deletions

View file

@ -4,7 +4,7 @@ set (lmdb_sources mdb.c midl.c)
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
if(NOT MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-field-initializers -Wno-missing-braces -Wno-aggregate-return -Wno-discarded-qualifiers -Wno-unused-but-set-variable")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-missing-field-initializers -Wno-missing-braces -Wno-aggregate-return -Wno-discarded-qualifiers -Wno-unused-but-set-variable -Wno-implicit-fallthrough -Wno-maybe-uninitialized ")
endif()
if(FREEBSD)
add_definitions(-DMDB_DSYNC=O_SYNC)

View file

@ -52,6 +52,7 @@
#endif
#include "include_base_utils.h"
#include "string_coding.h"
namespace epee
{
@ -222,13 +223,23 @@ namespace file_io_utils
return str_result;
}
#endif
inline const std::wstring& convert_utf8_to_wstring_if_needed(const std::wstring& s)
{
return s;
}
inline std::wstring convert_utf8_to_wstring_if_needed(const std::string& s)
{
return epee::string_encoding::utf8_to_wstring(s);
}
template<class t_string>
bool is_file_exist(const t_string& path)
{
boost::filesystem::path p(path);
return boost::filesystem::exists(p);
}
{
boost::filesystem::path p(convert_utf8_to_wstring_if_needed(path));
return boost::filesystem::exists(p);
}
/*
inline
@ -261,19 +272,18 @@ namespace file_io_utils
template<class t_string>
bool save_string_to_file_throw(const t_string& path_to_file, const std::string& str)
{
//std::ofstream fstream;
boost::filesystem::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
fstream << str;
fstream.close();
return true;
//std::ofstream fstream;
boost::filesystem::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(convert_utf8_to_wstring_if_needed(path_to_file), std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
fstream << str;
fstream.close();
return true;
}
template<class t_string>
bool save_string_to_file(const t_string& path_to_file, const std::string& str)
{
try
{
return save_string_to_file_throw(path_to_file, str);
@ -290,13 +300,13 @@ namespace file_io_utils
}
template<class t_string>
bool load_file_to_string(const t_string& path_to_file, std::string& target_str)
bool load_file_to_string(const t_string& path_to_file, std::string& target_str)
{
try
{
boost::filesystem::ifstream fstream;
//fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate);
fstream.open(convert_utf8_to_wstring_if_needed(path_to_file), std::ios_base::binary | std::ios_base::in | std::ios::ate);
if (!fstream.good())
return false;
std::ifstream::pos_type file_size = fstream.tellg();
@ -315,7 +325,6 @@ namespace file_io_utils
fstream.close();
return true;
}
catch (...)
{
return false;
@ -353,7 +362,7 @@ namespace file_io_utils
bool get_file_time(const std::string& path_to_file, OUT time_t& ft)
{
boost::system::error_code ec;
ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec);
ft = boost::filesystem::last_write_time(epee::string_encoding::utf8_to_wstring(path_to_file), ec);
if(!ec)
return true;
else
@ -364,7 +373,7 @@ namespace file_io_utils
bool set_file_time(const std::string& path_to_file, const time_t& ft)
{
boost::system::error_code ec;
boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec);
boost::filesystem::last_write_time(epee::string_encoding::utf8_to_wstring(path_to_file), ft, ec);
if(!ec)
return true;
else
@ -380,16 +389,18 @@ namespace file_io_utils
typedef int native_filesystem_handle;
#endif
// uses UTF-8 for unicode names for all systems
inline bool open_and_lock_file(const std::string file_path, native_filesystem_handle& h_file)
{
#ifdef WIN32
h_file = ::CreateFileA(file_path.c_str(), // name of the write
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
OPEN_ALWAYS, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
std::wstring file_path_w = epee::string_encoding::utf8_to_wstring(file_path);
h_file = ::CreateFileW(file_path_w.c_str(), // name of the file
GENERIC_WRITE, // open for writing
0, // do not share
NULL, // default security
OPEN_ALWAYS, // create new file only
FILE_ATTRIBUTE_NORMAL, // normal file
NULL); // no attr. template
if (h_file == INVALID_HANDLE_VALUE)
return false;
else
@ -465,20 +476,21 @@ namespace file_io_utils
bool copy_file(const std::string& source, const std::string& destination)
{
boost::system::error_code ec;
boost::filesystem::copy_file(source, destination, ec);
boost::filesystem::copy_file(epee::string_encoding::utf8_to_wstring(source), epee::string_encoding::utf8_to_wstring(destination), ec);
if (ec)
return false;
else
return true;
}
inline
bool append_string_to_file(const std::string& path_to_file, const std::string& str)
{
try
{
std::ofstream fstream;
boost::filesystem::ofstream fstream;
fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit);
fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
fstream.open(epee::string_encoding::utf8_to_wstring(path_to_file), std::ios_base::binary | std::ios_base::out | std::ios_base::app);
fstream << str;
fstream.close();
return true;
@ -550,7 +562,7 @@ namespace file_io_utils
{
boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
for ( boost::filesystem::directory_iterator itr( path ); itr != end_itr; ++itr )
for ( boost::filesystem::directory_iterator itr( epee::string_encoding::utf8_to_wstring(path) ); itr != end_itr; ++itr )
{
if ( only_files && boost::filesystem::is_directory(itr->status()) )
{

View file

@ -240,7 +240,7 @@ namespace math_helper
}
}
PUSH_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_GCC_WARNING(strict-aliasing)
inline
uint64_t generated_random_uint64()
@ -248,7 +248,7 @@ DISABLE_GCC_WARNING(strict-aliasing)
boost::uuids::uuid id___ = boost::uuids::random_generator()();
return *reinterpret_cast<uint64_t*>(&id___.data[0]); //(*reinterpret_cast<uint64_t*>(&id___.data[0]) ^ *reinterpret_cast<uint64_t*>(&id___.data[8]));
}
POP_WARNINGS
POP_GCC_WARNINGS
template<int default_interval, bool start_immediate = true>
class once_a_time_seconds
{

View file

@ -54,7 +54,7 @@
#endif
#include "os_defenitions.h"
#include "warnings.h"
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4100)
@ -65,6 +65,7 @@ DISABLE_VS_WARNINGS(4100)
#include "syncobj.h"
#include "sync_locked_object.h"
#include "string_coding.h"
#define LOG_LEVEL_SILENT -1
@ -694,13 +695,13 @@ namespace log_space
class file_output_stream : public ibase_log_stream
{
public:
typedef std::map<std::string, std::ofstream*> named_log_streams;
typedef std::map<std::string, boost::filesystem::ofstream*> named_log_streams;
file_output_stream( std::string default_log_file_name, std::string log_path )
file_output_stream( const std::string& default_log_file_name, const std::string& log_path )
{
m_default_log_filename = default_log_file_name;
m_max_logfile_size = 0;
m_default_log_path = log_path;
m_default_log_path_w = epee::string_encoding::utf8_to_wstring(log_path);
m_pdefault_file_stream = add_new_stream_and_open(default_log_file_name.c_str());
}
@ -718,20 +719,22 @@ namespace log_space
}
private:
named_log_streams m_log_file_names;
std::string m_default_log_path;
std::ofstream* m_pdefault_file_stream;
std::wstring m_default_log_path_w;
boost::filesystem::ofstream* m_pdefault_file_stream;
std::string m_log_rotate_cmd;
std::string m_default_log_filename;
uint64_t m_max_logfile_size;
std::ofstream* add_new_stream_and_open(const char* pstream_name)
// gets utf-8 encoded string
boost::filesystem::ofstream* add_new_stream_and_open(const char* pstream_name)
{
//log_space::rotate_log_file((m_default_log_path + "\\" + pstream_name).c_str());
boost::system::error_code ec;
boost::filesystem::create_directories(m_default_log_path, ec);
std::ofstream* pstream = (m_log_file_names[pstream_name] = new std::ofstream);
std::string target_path = m_default_log_path + "/" + pstream_name;
boost::filesystem::create_directories(m_default_log_path_w, ec);
boost::filesystem::ofstream* pstream = (m_log_file_names[pstream_name] = new boost::filesystem::ofstream);
std::wstring target_path = m_default_log_path_w + L"/" + epee::string_encoding::utf8_to_wstring(pstream_name);
pstream->open( target_path.c_str(), std::ios_base::out | std::ios::app /*ios_base::trunc */);
if(pstream->fail())
return NULL;
@ -754,7 +757,7 @@ namespace log_space
virtual bool out_buffer( const char* buffer, int buffer_len, int log_level, int color, const char* plog_name = NULL )
{
std::ofstream* m_target_file_stream = m_pdefault_file_stream;
boost::filesystem::ofstream* m_target_file_stream = m_pdefault_file_stream;
if(plog_name)
{ //find named stream
named_log_streams::iterator it = m_log_file_names.find(plog_name);
@ -769,9 +772,10 @@ namespace log_space
m_target_file_stream->write(buffer, buffer_len );
m_target_file_stream->flush();
/*
if(m_max_logfile_size)
{
std::ofstream::pos_type pt = m_target_file_stream->tellp();
boost::filesystem::ofstream::pos_type pt = m_target_file_stream->tellp();
uint64_t current_sz = pt;
if(current_sz > m_max_logfile_size)
{
@ -818,12 +822,13 @@ namespace log_space
misc_utils::call_sys_cmd(m_log_rotate_cmd_local_copy);
}
m_target_file_stream->open( (m_default_log_path + "/" + log_file_name).c_str(), std::ios_base::out | std::ios::app /*ios_base::trunc */);
m_target_file_stream->open( (m_default_log_path + "/" + log_file_name).c_str(), std::ios_base::out | std::ios::app / * ios_base::trunc * /);
if(m_target_file_stream->fail())
return false;
}
}
*/
return true;
}
int get_type(){return LOGGER_FILE;}
@ -1369,7 +1374,7 @@ namespace log_space
if(!plogger) return false;
return plogger->remove_logger(type);
}
PUSH_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
static int get_set_log_detalisation_level(bool is_need_set = false, int log_level_to_set = LOG_LEVEL_1)
{
@ -1381,7 +1386,7 @@ DISABLE_GCC_WARNING(maybe-uninitialized)
}
return log_detalisation_level;
}
POP_WARNINGS
POP_GCC_WARNINGS
static int get_set_time_level(bool is_need_set = false, int time_log_level = LOG_LEVEL_0)
{
static int val_time_log_level = LOG_LEVEL_0;
@ -1700,6 +1705,6 @@ POP_WARNINGS
} // namespace epee
POP_WARNINGS
POP_VS_WARNINGS
#endif //_MISC_LOG_EX_H_

View file

@ -36,7 +36,7 @@
#include "misc_language.h"
#include "warnings.h"
PUSH_WARNINGS
PUSH_VS_WARNINGS
namespace epee {
namespace net_utils {
/************************************************************************/
@ -474,7 +474,7 @@ bool boosted_tcp_server<t_protocol_handler>::init_server(uint32_t port, const st
CATCH_ENTRY_L0("boosted_tcp_server<t_protocol_handler>::init_server", false);
}
//-----------------------------------------------------------------------------
PUSH_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
template<class t_protocol_handler>
bool boosted_tcp_server<t_protocol_handler>::init_server(const std::string port, const std::string& address)
@ -487,7 +487,7 @@ bool boosted_tcp_server<t_protocol_handler>::init_server(const std::string port,
}
return this->init_server(p, address);
}
POP_WARNINGS
POP_GCC_WARNINGS
//---------------------------------------------------------------------------------
template<class t_protocol_handler>
bool boosted_tcp_server<t_protocol_handler>::worker_thread()
@ -794,4 +794,4 @@ bool boosted_tcp_server<t_protocol_handler>::connect_async(const std::string& ad
}
} // namespace net_utils
} // namespace epee
POP_WARNINGS
POP_VS_WARNINGS

View file

@ -37,7 +37,7 @@
#define HTTP_MAX_PRE_COMMAND_LINE_CHARS 20
#define HTTP_MAX_HEADER_LEN 100000
PUSH_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
@ -690,7 +690,7 @@ namespace net_utils
}
}
POP_WARNINGS
POP_GCC_WARNINGS
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------

View file

@ -101,7 +101,7 @@ namespace epee
return load_t_from_binary(out, f_buff);
}
//-----------------------------------------------------------------------------------------------------------
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4100)
template<class t_struct>
bool store_t_to_binary(const t_struct& str_in, std::string& binary_buff, size_t indent = 0)
@ -110,7 +110,7 @@ DISABLE_VS_WARNINGS(4100)
str_in.store(ps);
return ps.store_to_binary(binary_buff);
}
POP_WARNINGS
POP_VS_WARNINGS
//-----------------------------------------------------------------------------------------------------------
template<class t_struct>
std::string store_t_to_binary(const t_struct& str_in, size_t indent = 0)

View file

@ -45,7 +45,7 @@ namespace epee
return sizeof(pack_value);
}
PUSH_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_GCC_WARNING(strict-aliasing)
template<class t_stream>
size_t pack_varint(t_stream& strm, size_t val)
@ -67,7 +67,7 @@ namespace epee
return pack_varint_t<uint64_t>(strm, PORTABLE_RAW_SIZE_MARK_INT64, val);
}
}
POP_WARNINGS
POP_GCC_WARNINGS
template<class t_stream>
bool put_string(t_stream& strm, const std::string& v)

View file

@ -41,33 +41,37 @@ namespace epee
template<typename from_type, typename to_type>
void convert_int_to_uint(const from_type& from, to_type& to)
{
PUSH_WARNINGS
PUSH_VS_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_VS_WARNINGS(4018)
CHECK_AND_ASSERT_THROW_MES(from >=0, "unexpected int value with signed storage value less than 0, and unsigned receiver value: " << from);
DISABLE_GCC_AND_CLANG_WARNING(sign-compare)
CHECK_AND_ASSERT_THROW_MES(from <= std::numeric_limits<to_type>::max(), "int value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with max possible value = " << std::numeric_limits<to_type>::max());
to = static_cast<to_type>(from);
POP_WARNINGS
POP_GCC_WARNINGS
POP_VS_WARNINGS
}
template<typename from_type, typename to_type>
void convert_int_to_int(const from_type& from, to_type& to)
{
CHECK_AND_ASSERT_THROW_MES(from >= boost::numeric::bounds<to_type>::lowest(), "int value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with lowest possible value = " << boost::numeric::bounds<to_type>::lowest());
PUSH_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_CLANG_WARNING(tautological-constant-out-of-range-compare)
CHECK_AND_ASSERT_THROW_MES(from <= std::numeric_limits<to_type>::max(), "int value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with max possible value = " << std::numeric_limits<to_type>::max());
POP_WARNINGS
POP_GCC_WARNINGS
to = static_cast<to_type>(from);
}
template<typename from_type, typename to_type>
void convert_uint_to_any_int(const from_type& from, to_type& to)
{
PUSH_WARNINGS
PUSH_VS_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_VS_WARNINGS(4018)
DISABLE_CLANG_WARNING(tautological-constant-out-of-range-compare)
CHECK_AND_ASSERT_THROW_MES(from <= std::numeric_limits<to_type>::max(), "uint value overhead: try to set value " << from << " to type " << typeid(to_type).name() << " with max possible value = " << std::numeric_limits<to_type>::max());
to = static_cast<to_type>(from);
POP_WARNINGS
POP_GCC_WARNINGS
POP_VS_WARNINGS
}
template<typename from_type, typename to_type, bool, bool> //is from signed, is from to signed

View file

@ -42,6 +42,7 @@
#include <boost/filesystem.hpp>
#include "warnings.h"
#include "auto_val_init.h"
#include "string_coding.h"
#ifndef OUT
@ -215,7 +216,7 @@ namespace string_tools
return t_pod;
}
//----------------------------------------------------------------------------
PUSH_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_GCC_WARNING(maybe-uninitialized)
template<class XType>
inline bool get_xtype_from_string(OUT XType& val, const std::string& str_id)
@ -246,7 +247,7 @@ DISABLE_GCC_WARNING(maybe-uninitialized)
return true;
}
POP_WARNINGS
POP_GCC_WARNINGS
//---------------------------------------------------
template<typename int_t>
bool get_xnum_from_hex_string(const std::string str, int_t& res )
@ -536,38 +537,15 @@ POP_WARNINGS
return module_folder;
}
//----------------------------------------------------------------------------
#ifdef _WIN32
inline std::string get_current_module_path()
inline bool set_module_name_and_folder(const std::string& path_to_process_)
{
char pname [5000] = {0};
GetModuleFileNameA( NULL, pname, sizeof(pname));
pname[sizeof(pname)-1] = 0; //be happy ;)
return pname;
}
#endif
//----------------------------------------------------------------------------
inline bool set_module_name_and_folder(const std::string& path_to_process_)
{
std::string path_to_process = path_to_process_;
boost::system::error_code ec;
path_to_process = boost::filesystem::canonical(path_to_process, ec).string();
#ifdef _WIN32
path_to_process = get_current_module_path();
#endif
std::string::size_type a = path_to_process.rfind( '\\' );
if(a == std::string::npos )
{
a = path_to_process.rfind( '/' );
}
if ( a != std::string::npos )
{
get_current_module_name() = path_to_process.substr(a+1, path_to_process.size());
get_current_module_folder() = path_to_process.substr(0, a);
return true;
}else
return false;
boost::filesystem::path path(epee::string_encoding::utf8_to_wstring(path_to_process_));
}
get_current_module_folder() = epee::string_encoding::wstring_to_utf8(path.parent_path().wstring());
get_current_module_name() = epee::string_encoding::wstring_to_utf8(path.filename().wstring());
return true;
}
//----------------------------------------------------------------------------
inline bool trim_left(std::string& str)
{

View file

@ -59,10 +59,10 @@ namespace misc_utils
char tmpbuf[200] = {0};
tm* pt = NULL;
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4996)
pt = localtime(&time_);
POP_WARNINGS
POP_VS_WARNINGS
if(pt)
strftime( tmpbuf, 199, "%d.%m.%Y %H:%M:%S", pt );
@ -81,10 +81,10 @@ POP_WARNINGS
char tmpbuf[200] = {0};
tm* pt = NULL;
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4996)
pt = localtime(&time_);
POP_WARNINGS
POP_VS_WARNINGS
if(pt)
strftime( tmpbuf, 199, "%Y_%m_%d %H_%M_%S", pt );
@ -109,10 +109,10 @@ POP_WARNINGS
{
char tmpbuf[200] = {0};
tm* pt = NULL;
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4996)
pt = gmtime(&time_);
POP_WARNINGS
POP_VS_WARNINGS
strftime( tmpbuf, 199, "%a, %d %b %Y %H:%M:%S GMT", pt );
return tmpbuf;
}
@ -126,7 +126,7 @@ POP_WARNINGS
tail = -tail;
res = "-";
}
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4244)
int days = tail/(60*60*24);
tail = tail%(60*60*24);
@ -135,7 +135,7 @@ DISABLE_VS_WARNINGS(4244)
int minutes = tail/(60);
tail = tail%(60);
int seconds = tail;
POP_WARNINGS
POP_VS_WARNINGS
res += std::string("d") + boost::lexical_cast<std::string>(days) + ".h" + boost::lexical_cast<std::string>(hours) + ".m" + boost::lexical_cast<std::string>(minutes) + ".s" + boost::lexical_cast<std::string>(seconds);
return res;
}

View file

@ -2,8 +2,12 @@
#if defined(_MSC_VER)
#define PUSH_WARNINGS __pragma(warning(push))
#define POP_WARNINGS __pragma(warning(pop))
#define PUSH_VS_WARNINGS __pragma(warning(push))
#define POP_VS_WARNINGS __pragma(warning(pop))
#define PUSH_GCC_WARNINGS
#define POP_GCC_WARNINGS
#define DISABLE_VS_WARNINGS(w) __pragma(warning(disable: w))
#define DISABLE_GCC_WARNING(w)
#define DISABLE_CLANG_WARNING(w)
@ -13,8 +17,12 @@
#include <boost/preprocessor/stringize.hpp>
#define PUSH_WARNINGS _Pragma("GCC diagnostic push")
#define POP_WARNINGS _Pragma("GCC diagnostic pop")
#define PUSH_VS_WARNINGS
#define POP_VS_WARNINGS
#define PUSH_GCC_WARNINGS _Pragma("GCC diagnostic push")
#define POP_GCC_WARNINGS _Pragma("GCC diagnostic pop")
#define DISABLE_VS_WARNINGS(w)
#if defined(__clang__)

View file

@ -21,8 +21,8 @@ namespace tools
bool serialize_obj_to_file(t_object& obj, const std::string& file_path)
{
TRY_ENTRY();
std::ofstream data_file;
data_file.open( file_path , std::ios_base::binary | std::ios_base::out| std::ios::trunc);
boost::filesystem::ofstream data_file;
data_file.open( epee::string_encoding::utf8_to_wstring(file_path) , std::ios_base::binary | std::ios_base::out| std::ios::trunc);
if(data_file.fail())
return false;
@ -64,8 +64,8 @@ namespace tools
{
TRY_ENTRY();
std::ifstream data_file;
data_file.open( file_path, std::ios_base::binary | std::ios_base::in);
boost::filesystem::ifstream data_file;
data_file.open( epee::string_encoding::utf8_to_wstring(file_path), std::ios_base::binary | std::ios_base::in);
if(data_file.fail())
return false;
boost::archive::binary_iarchive a(data_file);

View file

@ -29,4 +29,5 @@ namespace command_line
const arg_descriptor<bool> arg_disable_stop_if_time_out_of_sync = { "disable-stop-if-time-out-of-sync", "Do not stop the daemon if serious time synchronization problem is detected", false, true };
const arg_descriptor<bool> arg_disable_stop_on_low_free_space = { "disable-stop-on-low-free-space", "Do not stop the daemon if free space at data dir is critically low", false, true };
const arg_descriptor<bool> arg_enable_offers_service = { "enable_offers_service", "Enables marketplace feature", false, false};
}

View file

@ -122,7 +122,7 @@ namespace command_line
boost::program_options::basic_parsed_options<charT> parse_command_line(int argc, const charT* const argv[],
const boost::program_options::options_description& desc, bool allow_unregistered = false)
{
auto parser = boost::program_options::command_line_parser(argc, argv);
auto parser = boost::program_options::basic_command_line_parser<charT>(argc, argv);
parser.options(desc);
if (allow_unregistered)
{
@ -187,4 +187,5 @@ namespace command_line
extern const arg_descriptor<bool> arg_disable_upnp;
extern const arg_descriptor<bool> arg_disable_stop_if_time_out_of_sync;
extern const arg_descriptor<bool> arg_disable_stop_on_low_free_space;
extern const arg_descriptor<bool> arg_enable_offers_service;
}

View file

@ -659,28 +659,27 @@ namespace tools
{
return bdb.size(m_h);
}
size_t clear()
bool clear()
{
bdb.clear(m_h);
bool result = bdb.clear(m_h);
m_isolation.isolated_write_access<bool>([&](){
size_cache_valid = false;
return true;
});
return true;
return result;
}
bool erase_validate(const t_key& k)
{
auto res_ptr = this->get(k);
bdb.erase(m_h, k);
bool result = bdb.erase(m_h, k);
m_isolation.isolated_write_access<bool>([&](){
size_cache_valid = false;
return true;
});
return static_cast<bool>(res_ptr);
return result;
}
void erase(const t_key& k)
{
bdb.erase(m_h, k);
@ -861,13 +860,10 @@ namespace tools
operator t_value() const
{
static_assert(std::is_pod<t_value>::value, "t_value must be a POD type.");
std::shared_ptr<const t_value> value_ptr = m_accessor.template explicit_get<t_key, t_value, access_strategy_selector<is_t_strategy> >(m_key);
if (value_ptr.get())
return *value_ptr.get();
std::shared_ptr<const t_value> vptr = m_accessor.template explicit_get<t_key, t_value, access_strategy_selector<false> >(m_key);
if (vptr.get())
{
return *vptr.get();
}
return AUTO_VAL_INIT(t_value());
}
};

View file

@ -49,10 +49,6 @@ namespace tools
CHECK_AND_ASSERT_MESS_LMDB_DB(res, false, "Unable to mdb_env_set_mapsize");
m_path = path_;
#ifdef WIN32
m_path = epee::string_encoding::convert_ansii_to_utf8(m_path);
#endif
CHECK_AND_ASSERT_MES(tools::create_directories_if_necessary(m_path), false, "create_directories_if_necessary failed: " << m_path);
res = mdb_env_open(m_penv, m_path.c_str(), MDB_NORDAHEAD , 0644);

265
src/common/ntp.cpp Normal file
View file

@ -0,0 +1,265 @@
// Copyright (c) 2019 Zano Project
// Note: class udp_blocking_client is a slightly modified version of an example
// taken from https://www.boost.org/doc/libs/1_53_0/doc/html/boost_asio/example/timeouts/blocking_udp_client.cpp
//
// Copyright (c) 2003-2012 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <cstdlib>
#include <iostream>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/io_service.hpp>
#include <boost/asio/ip/udp.hpp>
#include <boost/bind.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/array.hpp>
#include <epee/include/misc_log_ex.h>
#include <chrono>
#include "ntp.h"
using boost::asio::deadline_timer;
using boost::asio::ip::udp;
//----------------------------------------------------------------------
//
// This class manages socket timeouts by applying the concept of a deadline.
// Each asynchronous operation is given a deadline by which it must complete.
// Deadlines are enforced by an "actor" that persists for the lifetime of the
// client object:
//
// +----------------+
// | |
// | check_deadline |<---+
// | | |
// +----------------+ | async_wait()
// | |
// +---------+
//
// If the actor determines that the deadline has expired, any outstanding
// socket operations are cancelled. The socket operations themselves are
// implemented as transient actors:
//
// +---------------+
// | |
// | receive |
// | |
// +---------------+
// |
// async_- | +----------------+
// receive() | | |
// +--->| handle_receive |
// | |
// +----------------+
//
// The client object runs the io_service to block thread execution until the
// actor completes.
//
namespace
{
class udp_blocking_client
{
public:
udp_blocking_client(const udp::endpoint& listen_endpoint, udp::socket& socket, boost::asio::io_service& io_service)
: socket_(socket),
io_service_(io_service),
deadline_(io_service)
{
// No deadline is required until the first socket operation is started. We
// set the deadline to positive infinity so that the actor takes no action
// until a specific deadline is set.
deadline_.expires_at(boost::posix_time::pos_infin);
// Start the persistent actor that checks for deadline expiry.
check_deadline();
}
std::size_t receive(const boost::asio::mutable_buffer& buffer,
boost::posix_time::time_duration timeout, boost::system::error_code& ec)
{
// Set a deadline for the asynchronous operation.
deadline_.expires_from_now(timeout);
// Set up the variables that receive the result of the asynchronous
// operation. The error code is set to would_block to signal that the
// operation is incomplete. Asio guarantees that its asynchronous
// operations will never fail with would_block, so any other value in
// ec indicates completion.
ec = boost::asio::error::would_block;
std::size_t length = 0;
// Start the asynchronous operation itself. The handle_receive function
// used as a callback will update the ec and length variables.
socket_.async_receive(boost::asio::buffer(buffer),
boost::bind(&udp_blocking_client::handle_receive, _1, _2, &ec, &length));
// Block until the asynchronous operation has completed.
do io_service_.run_one(); while (ec == boost::asio::error::would_block);
return length;
}
private:
void check_deadline()
{
// Check whether the deadline has passed. We compare the deadline against
// the current time since a new asynchronous operation may have moved the
// deadline before this actor had a chance to run.
if (deadline_.expires_at() <= deadline_timer::traits_type::now())
{
// The deadline has passed. The outstanding asynchronous operation needs
// to be cancelled so that the blocked receive() function will return.
//
// Please note that cancel() has portability issues on some versions of
// Microsoft Windows, and it may be necessary to use close() instead.
// Consult the documentation for cancel() for further information.
socket_.cancel();
// There is no longer an active deadline. The expiry is set to positive
// infinity so that the actor takes no action until a new deadline is set.
deadline_.expires_at(boost::posix_time::pos_infin);
}
// Put the actor back to sleep.
deadline_.async_wait(boost::bind(&udp_blocking_client::check_deadline, this));
}
static void handle_receive(
const boost::system::error_code& ec, std::size_t length,
boost::system::error_code* out_ec, std::size_t* out_length)
{
*out_ec = ec;
*out_length = length;
}
private:
boost::asio::io_service& io_service_;
udp::socket& socket_;
deadline_timer deadline_;
};
#pragma pack(push, 1)
struct ntp_packet
{
uint8_t li_vn_mode; // Eight bits. li, vn, and mode.
// li. Two bits. Leap indicator.
// vn. Three bits. Version number of the protocol.
// mode. Three bits. Client will pick mode 3 for client.
uint8_t stratum; // Eight bits. Stratum level of the local clock.
uint8_t poll; // Eight bits. Maximum interval between successive messages.
uint8_t precision; // Eight bits. Precision of the local clock.
uint32_t rootDelay; // 32 bits. Total round trip delay time.
uint32_t rootDispersion; // 32 bits. Max error aloud from primary clock source.
uint32_t refId; // 32 bits. Reference clock identifier.
uint32_t refTm_s; // 32 bits. Reference time-stamp seconds.
uint32_t refTm_f; // 32 bits. Reference time-stamp fraction of a second.
uint64_t orig_tm; // 64 bits. Originate time-stamp (set by client)
uint32_t rxTm_s; // 32 bits. Received time-stamp seconds.
uint32_t rxTm_f; // 32 bits. Received time-stamp fraction of a second.
uint32_t txTm_s; // 32 bits and the most important field the client cares about. Transmit time-stamp seconds.
uint32_t txTm_f; // 32 bits. Transmit time-stamp fraction of a second.
}; // Total: 384 bits or 48 bytes.
#pragma pack(pop)
static_assert(sizeof(ntp_packet) == 48, "ntp_packet has invalid size");
} // namespace
namespace tools
{
int64_t get_ntp_time(const std::string& host_name, size_t timeout_sec)
{
try
{
boost::asio::io_service io_service;
boost::asio::ip::udp::resolver resolver(io_service);
boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), host_name, "ntp");
boost::asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query);
boost::asio::ip::udp::socket socket(io_service);
socket.open(boost::asio::ip::udp::v4());
ntp_packet packet_sent = AUTO_VAL_INIT(packet_sent);
packet_sent.li_vn_mode = 0x1b;
auto packet_sent_time = std::chrono::high_resolution_clock::now();
socket.send_to(boost::asio::buffer(&packet_sent, sizeof packet_sent), receiver_endpoint);
ntp_packet packet_received = AUTO_VAL_INIT(packet_received);
boost::asio::ip::udp::endpoint sender_endpoint;
udp_blocking_client ubc(sender_endpoint, socket, io_service);
boost::system::error_code ec;
size_t len = ubc.receive(boost::asio::buffer(&packet_received, sizeof packet_received), boost::posix_time::seconds(timeout_sec), ec);
if (ec)
{
LOG_PRINT_L3("NTP: get_ntp_time(" << host_name << "): boost error: " << ec.message());
return 0;
}
auto packet_received_time = std::chrono::high_resolution_clock::now();
int64_t roundtrip_mcs = std::chrono::duration_cast<std::chrono::microseconds>(packet_received_time - packet_sent_time).count();
uint64_t roundtrip_s = roundtrip_mcs > 2000000 ? roundtrip_mcs / 2000000 : 0;
time_t ntp_time = ntohl(packet_received.txTm_s);
if (ntp_time <= 2208988800U)
{
LOG_PRINT_L3("NTP: get_ntp_time(" << host_name << "): wrong txTm_s: " << packet_received.txTm_s);
return 0;
}
// LOG_PRINT_L2("NTP: get_ntp_time(" << host_name << "): RAW time received: " << ntp_time << ", refTm_s: " << ntohl(packet_received.refTm_s) << ", stratum: " << packet_received.stratum << ", round: " << roundtrip_mcs);
ntp_time -= 2208988800U; // Unix time starts from 01/01/1970 == 2208988800U
ntp_time += roundtrip_s;
return ntp_time;
}
catch (const std::exception& e)
{
LOG_PRINT_L2("NTP: get_ntp_time(" << host_name << "): exception: " << e.what());
return 0;
}
catch (...)
{
LOG_PRINT_L2("NTP: get_ntp_time(" << host_name << "): unknown exception");
return 0;
}
}
#define TIME_SYNC_NTP_SERVERS "time1.google.com", "time2.google.com", "time3.google.com", "time4.google.com" /* , "pool.ntp.org" -- we need to request a vender zone before using this pool */
#define TIME_SYNC_NTP_TIMEOUT_SEC 5
#define TIME_SYNC_NTP_ATTEMPTS_COUNT 3 // max number of attempts when getting time from NTP server
int64_t get_ntp_time()
{
static const std::vector<std::string> ntp_servers { TIME_SYNC_NTP_SERVERS };
for (size_t att = 0; att < TIME_SYNC_NTP_ATTEMPTS_COUNT; ++att)
{
const std::string& ntp_server = ntp_servers[att % ntp_servers.size()];
LOG_PRINT_L3("NTP: trying to get time from " << ntp_server);
int64_t time = get_ntp_time(ntp_server, TIME_SYNC_NTP_TIMEOUT_SEC);
if (time > 0)
{
LOG_PRINT_L3("NTP: " << ntp_server << " responded with " << time << " (" << epee::misc_utils::get_time_str_v2(time) << ")");
return time;
}
}
LOG_PRINT_RED("NTP: unable to get time from NTP with " << TIME_SYNC_NTP_ATTEMPTS_COUNT << " trials", LOG_LEVEL_2);
return 0; // smth went wrong
}
} // namespace tools

18
src/common/ntp.h Normal file
View file

@ -0,0 +1,18 @@
// Copyright (c) 2019 Zano Project
#pragma once
#include <cstdint>
#include <string>
namespace tools
{
// requests current time via NTP from 'host_hame' using 'timeout_sec'
// may return zero -- means error
int64_t get_ntp_time(const std::string& host_name, size_t timeout_sec = 5);
// request time via predefined NTP servers
// may return zero -- mean error
int64_t get_ntp_time();
} // namespace tools

View file

@ -24,6 +24,8 @@ using namespace epee;
#include <boost/asio.hpp>
#include "string_coding.h"
namespace tools
{
std::function<void(void)> signal_handler::m_handler;
@ -450,18 +452,22 @@ std::string get_nix_version_display_string()
#ifdef WIN32
std::string get_special_folder_path(int nfolder, bool iscreate)
std::wstring get_special_folder_path_w(int nfolder, bool iscreate)
{
namespace fs = boost::filesystem;
char psz_path[MAX_PATH] = "";
wchar_t psz_path[MAX_PATH] = L"";
if(SHGetSpecialFolderPathA(NULL, psz_path, nfolder, iscreate))
if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate))
{
return psz_path;
}
LOG_ERROR("SHGetSpecialFolderPathA() failed, could not obtain requested path.");
return "";
LOG_ERROR("SHGetSpecialFolderPathW(" << nfolder << ", " << iscreate << ") failed, could not obtain requested path.");
return L"";
}
std::string get_special_folder_path_utf8(int nfolder, bool iscreate)
{
return epee::string_encoding::wstring_to_utf8(get_special_folder_path_w(nfolder, iscreate));
}
#endif
@ -476,9 +482,9 @@ std::string get_nix_version_display_string()
#ifdef WIN32
// Windows
#ifdef _M_X64
config_folder = get_special_folder_path(CSIDL_APPDATA, true) + "/" + CURRENCY_NAME_SHORT;
config_folder = get_special_folder_path_utf8(CSIDL_APPDATA, true) + "/" + CURRENCY_NAME_SHORT;
#else
config_folder = get_special_folder_path(CSIDL_APPDATA, true) + "/" + CURRENCY_NAME_SHORT + "-x86";
config_folder = get_special_folder_path_utf8(CSIDL_APPDATA, true) + "/" + CURRENCY_NAME_SHORT + "-x86";
#endif
#else
std::string pathRet;
@ -518,7 +524,7 @@ std::string get_nix_version_display_string()
std::string wallets_dir;
#ifdef WIN32
// Windows
wallets_dir = get_special_folder_path(CSIDL_PERSONAL, true) + "/" + CURRENCY_NAME_BASE;
wallets_dir = get_special_folder_path_utf8(CSIDL_PERSONAL, true) + "/" + CURRENCY_NAME_BASE;
#else
std::string pathRet;
char* pszHome = getenv("HOME");
@ -553,7 +559,7 @@ std::string get_nix_version_display_string()
{
namespace fs = boost::filesystem;
boost::system::error_code ec;
fs::path fs_path(path);
fs::path fs_path = epee::string_encoding::utf8_to_wstring(path);
if (fs::is_directory(fs_path, ec))
{
return true;
@ -652,38 +658,4 @@ std::string get_nix_version_display_string()
return static_cast<uint64_t>(in.tellg());
}
int64_t get_ntp_time(const std::string& host_name)
{
try
{
boost::asio::io_service io_service;
boost::asio::ip::udp::resolver resolver(io_service);
boost::asio::ip::udp::resolver::query query(boost::asio::ip::udp::v4(), host_name, "ntp");
boost::asio::ip::udp::endpoint receiver_endpoint = *resolver.resolve(query);
boost::asio::ip::udp::socket socket(io_service);
socket.open(boost::asio::ip::udp::v4());
boost::array<unsigned char, 48> send_buf = { { 010, 0, 0, 0, 0, 0, 0, 0, 0 } };
socket.send_to(boost::asio::buffer(send_buf), receiver_endpoint);
boost::array<unsigned long, 1024> recv_buf;
boost::asio::ip::udp::endpoint sender_endpoint;
size_t len = socket.receive_from(boost::asio::buffer(recv_buf), sender_endpoint);
time_t time_recv = ntohl((time_t)recv_buf[4]);
time_recv -= 2208988800U; //Unix time starts from 01/01/1970 == 2208988800U
return time_recv;
}
catch (const std::exception& e)
{
LOG_PRINT_L2("get_ntp_time(): exception: " << e.what());
return 0;
}
catch (...)
{
return 0;
}
}
} // namespace tools

View file

@ -17,6 +17,7 @@
#include "crypto/hash.h"
#include "misc_language.h"
#include "p2p/p2p_protocol_defs.h"
#include "ntp.h"
#if defined(WIN32)
#include <dbghelp.h>
@ -274,6 +275,4 @@ namespace tools
static std::function<void(int, void*)> m_fatal_handler;
};
int64_t get_ntp_time(const std::string& host_name);
}

160
src/crypto/blake2-impl.h Normal file
View file

@ -0,0 +1,160 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#ifndef BLAKE2_IMPL_H
#define BLAKE2_IMPL_H
#include <stdint.h>
#include <string.h>
#if !defined(__cplusplus) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L)
#if defined(_MSC_VER)
#define BLAKE2_INLINE __inline
#elif defined(__GNUC__)
#define BLAKE2_INLINE __inline__
#else
#define BLAKE2_INLINE
#endif
#else
#define BLAKE2_INLINE inline
#endif
static BLAKE2_INLINE uint32_t load32( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint32_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
return (( uint32_t )( p[0] ) << 0) |
(( uint32_t )( p[1] ) << 8) |
(( uint32_t )( p[2] ) << 16) |
(( uint32_t )( p[3] ) << 24) ;
#endif
}
static BLAKE2_INLINE uint64_t load64( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint64_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
return (( uint64_t )( p[0] ) << 0) |
(( uint64_t )( p[1] ) << 8) |
(( uint64_t )( p[2] ) << 16) |
(( uint64_t )( p[3] ) << 24) |
(( uint64_t )( p[4] ) << 32) |
(( uint64_t )( p[5] ) << 40) |
(( uint64_t )( p[6] ) << 48) |
(( uint64_t )( p[7] ) << 56) ;
#endif
}
static BLAKE2_INLINE uint16_t load16( const void *src )
{
#if defined(NATIVE_LITTLE_ENDIAN)
uint16_t w;
memcpy(&w, src, sizeof w);
return w;
#else
const uint8_t *p = ( const uint8_t * )src;
return ( uint16_t )((( uint32_t )( p[0] ) << 0) |
(( uint32_t )( p[1] ) << 8));
#endif
}
static BLAKE2_INLINE void store16( void *dst, uint16_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = ( uint8_t * )dst;
*p++ = ( uint8_t )w; w >>= 8;
*p++ = ( uint8_t )w;
#endif
}
static BLAKE2_INLINE void store32( void *dst, uint32_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = ( uint8_t * )dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
#endif
}
static BLAKE2_INLINE void store64( void *dst, uint64_t w )
{
#if defined(NATIVE_LITTLE_ENDIAN)
memcpy(dst, &w, sizeof w);
#else
uint8_t *p = ( uint8_t * )dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
p[4] = (uint8_t)(w >> 32);
p[5] = (uint8_t)(w >> 40);
p[6] = (uint8_t)(w >> 48);
p[7] = (uint8_t)(w >> 56);
#endif
}
static BLAKE2_INLINE uint64_t load48( const void *src )
{
const uint8_t *p = ( const uint8_t * )src;
return (( uint64_t )( p[0] ) << 0) |
(( uint64_t )( p[1] ) << 8) |
(( uint64_t )( p[2] ) << 16) |
(( uint64_t )( p[3] ) << 24) |
(( uint64_t )( p[4] ) << 32) |
(( uint64_t )( p[5] ) << 40) ;
}
static BLAKE2_INLINE void store48( void *dst, uint64_t w )
{
uint8_t *p = ( uint8_t * )dst;
p[0] = (uint8_t)(w >> 0);
p[1] = (uint8_t)(w >> 8);
p[2] = (uint8_t)(w >> 16);
p[3] = (uint8_t)(w >> 24);
p[4] = (uint8_t)(w >> 32);
p[5] = (uint8_t)(w >> 40);
}
static BLAKE2_INLINE uint32_t rotr32( const uint32_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 32 - c ) );
}
static BLAKE2_INLINE uint64_t rotr64( const uint64_t w, const unsigned c )
{
return ( w >> c ) | ( w << ( 64 - c ) );
}
/* prevents compiler optimizing out memset() */
static BLAKE2_INLINE void secure_zero_memory(void *v, size_t n)
{
static void *(*const volatile memset_v)(void *, int, size_t) = &memset;
memset_v(v, 0, n);
}
#endif

200
src/crypto/blake2.h Normal file
View file

@ -0,0 +1,200 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#ifndef BLAKE2_H
#define BLAKE2_H
#include <stddef.h>
#include <stdint.h>
#if defined(_MSC_VER)
#define BLAKE2_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
#else
#define BLAKE2_PACKED(x) x __attribute__((packed))
#endif
#if defined(__cplusplus)
extern "C" {
#endif
enum blake2s_constant
{
BLAKE2S_BLOCKBYTES = 64,
BLAKE2S_OUTBYTES = 32,
BLAKE2S_KEYBYTES = 32,
BLAKE2S_SALTBYTES = 8,
BLAKE2S_PERSONALBYTES = 8
};
enum blake2b_constant
{
BLAKE2B_BLOCKBYTES = 128,
BLAKE2B_OUTBYTES = 64,
BLAKE2B_KEYBYTES = 64,
BLAKE2B_SALTBYTES = 16,
BLAKE2B_PERSONALBYTES = 16
};
typedef struct blake2s_state__
{
uint32_t h[8];
uint32_t t[2];
uint32_t f[2];
uint8_t buf[BLAKE2S_BLOCKBYTES];
size_t buflen;
size_t outlen;
uint8_t last_node;
} blake2s_state;
typedef struct blake2b_state__
{
uint64_t h[8];
uint64_t t[2];
uint64_t f[2];
uint8_t buf[BLAKE2B_BLOCKBYTES];
size_t buflen;
size_t outlen;
uint8_t last_node;
} blake2b_state;
typedef struct blake2sp_state__
{
blake2s_state S[8][1];
blake2s_state R[1];
uint8_t buf[8 * BLAKE2S_BLOCKBYTES];
size_t buflen;
size_t outlen;
} blake2sp_state;
typedef struct blake2bp_state__
{
blake2b_state S[4][1];
blake2b_state R[1];
uint8_t buf[4 * BLAKE2B_BLOCKBYTES];
size_t buflen;
size_t outlen;
} blake2bp_state;
BLAKE2_PACKED(struct blake2s_param__
{
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint32_t node_offset; /* 12 */
uint16_t xof_length; /* 14 */
uint8_t node_depth; /* 15 */
uint8_t inner_length; /* 16 */
/* uint8_t reserved[0]; */
uint8_t salt[BLAKE2S_SALTBYTES]; /* 24 */
uint8_t personal[BLAKE2S_PERSONALBYTES]; /* 32 */
});
typedef struct blake2s_param__ blake2s_param;
BLAKE2_PACKED(struct blake2b_param__
{
uint8_t digest_length; /* 1 */
uint8_t key_length; /* 2 */
uint8_t fanout; /* 3 */
uint8_t depth; /* 4 */
uint32_t leaf_length; /* 8 */
uint32_t node_offset; /* 12 */
uint32_t xof_length; /* 16 */
uint8_t node_depth; /* 17 */
uint8_t inner_length; /* 18 */
uint8_t reserved[14]; /* 32 */
uint8_t salt[BLAKE2B_SALTBYTES]; /* 48 */
uint8_t personal[BLAKE2B_PERSONALBYTES]; /* 64 */
});
typedef struct blake2b_param__ blake2b_param;
typedef struct blake2xs_state__
{
blake2s_state S[1];
blake2s_param P[1];
} blake2xs_state;
typedef struct blake2xb_state__
{
blake2b_state S[1];
blake2b_param P[1];
} blake2xb_state;
/* Padded structs result in a compile-time error */
enum {
BLAKE2_DUMMY_1 = 1/(sizeof(blake2s_param) == BLAKE2S_OUTBYTES),
BLAKE2_DUMMY_2 = 1/(sizeof(blake2b_param) == BLAKE2B_OUTBYTES)
};
// static_assert(sizeof(blake2s_param) == BLAKE2S_OUTBYTES, "Wrong size of blake2s_param");
// static_assert(sizeof(blake2b_param) == BLAKE2B_OUTBYTES, "Wrong size of blake2b_param");
/* Streaming API */
int blake2s_init( blake2s_state *S, size_t outlen );
int blake2s_init_key( blake2s_state *S, size_t outlen, const void *key, size_t keylen );
int blake2s_init_param( blake2s_state *S, const blake2s_param *P );
int blake2s_update( blake2s_state *S, const void *in, size_t inlen );
int blake2s_final( blake2s_state *S, void *out, size_t outlen );
int blake2b_init( blake2b_state *S, size_t outlen );
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen );
int blake2b_init_param( blake2b_state *S, const blake2b_param *P );
int blake2b_update( blake2b_state *S, const void *in, size_t inlen );
int blake2b_final( blake2b_state *S, void *out, size_t outlen );
int blake2sp_init( blake2sp_state *S, size_t outlen );
int blake2sp_init_key( blake2sp_state *S, size_t outlen, const void *key, size_t keylen );
int blake2sp_update( blake2sp_state *S, const void *in, size_t inlen );
int blake2sp_final( blake2sp_state *S, void *out, size_t outlen );
int blake2bp_init( blake2bp_state *S, size_t outlen );
int blake2bp_init_key( blake2bp_state *S, size_t outlen, const void *key, size_t keylen );
int blake2bp_update( blake2bp_state *S, const void *in, size_t inlen );
int blake2bp_final( blake2bp_state *S, void *out, size_t outlen );
/* Variable output length API */
int blake2xs_init( blake2xs_state *S, const size_t outlen );
int blake2xs_init_key( blake2xs_state *S, const size_t outlen, const void *key, size_t keylen );
int blake2xs_update( blake2xs_state *S, const void *in, size_t inlen );
int blake2xs_final(blake2xs_state *S, void *out, size_t outlen);
int blake2xb_init( blake2xb_state *S, const size_t outlen );
int blake2xb_init_key( blake2xb_state *S, const size_t outlen, const void *key, size_t keylen );
int blake2xb_update( blake2xb_state *S, const void *in, size_t inlen );
int blake2xb_final(blake2xb_state *S, void *out, size_t outlen);
/* Simple API */
int blake2s( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
int blake2sp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
int blake2bp( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
int blake2xs( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
int blake2xb( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
/* This is simply an alias for blake2b */
int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen );
#if defined(__cplusplus)
}
#endif
#endif

379
src/crypto/blake2b-ref.c Normal file
View file

@ -0,0 +1,379 @@
/*
BLAKE2 reference source code package - reference C implementations
Copyright 2012, Samuel Neves <sneves@dei.uc.pt>. You may use this under the
terms of the CC0, the OpenSSL Licence, or the Apache Public License 2.0, at
your option. The terms of these licenses can be found at:
- CC0 1.0 Universal : http://creativecommons.org/publicdomain/zero/1.0
- OpenSSL license : https://www.openssl.org/source/license.html
- Apache 2.0 : http://www.apache.org/licenses/LICENSE-2.0
More information about the BLAKE2 hash function can be found at
https://blake2.net.
*/
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include "blake2.h"
#include "blake2-impl.h"
static const uint64_t blake2b_IV[8] =
{
0x6a09e667f3bcc908ULL, 0xbb67ae8584caa73bULL,
0x3c6ef372fe94f82bULL, 0xa54ff53a5f1d36f1ULL,
0x510e527fade682d1ULL, 0x9b05688c2b3e6c1fULL,
0x1f83d9abfb41bd6bULL, 0x5be0cd19137e2179ULL
};
static const uint8_t blake2b_sigma[12][16] =
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } ,
{ 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } ,
{ 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } ,
{ 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } ,
{ 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } ,
{ 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } ,
{ 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } ,
{ 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } ,
{ 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } ,
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } ,
{ 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 }
};
static void blake2b_set_lastnode( blake2b_state *S )
{
S->f[1] = (uint64_t)-1;
}
/* Some helper functions, not necessarily useful */
static int blake2b_is_lastblock( const blake2b_state *S )
{
return S->f[0] != 0;
}
static void blake2b_set_lastblock( blake2b_state *S )
{
if( S->last_node ) blake2b_set_lastnode( S );
S->f[0] = (uint64_t)-1;
}
static void blake2b_increment_counter( blake2b_state *S, const uint64_t inc )
{
S->t[0] += inc;
S->t[1] += ( S->t[0] < inc );
}
static void blake2b_init0( blake2b_state *S )
{
size_t i;
memset( S, 0, sizeof( blake2b_state ) );
for( i = 0; i < 8; ++i ) S->h[i] = blake2b_IV[i];
}
/* init xors IV with input parameter block */
int blake2b_init_param( blake2b_state *S, const blake2b_param *P )
{
const uint8_t *p = ( const uint8_t * )( P );
size_t i;
blake2b_init0( S );
/* IV XOR ParamBlock */
for( i = 0; i < 8; ++i )
S->h[i] ^= load64( p + sizeof( S->h[i] ) * i );
S->outlen = P->digest_length;
return 0;
}
int blake2b_init( blake2b_state *S, size_t outlen )
{
blake2b_param P[1];
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
P->digest_length = (uint8_t)outlen;
P->key_length = 0;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, 0 );
store32( &P->xof_length, 0 );
P->node_depth = 0;
P->inner_length = 0;
memset( P->reserved, 0, sizeof( P->reserved ) );
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
return blake2b_init_param( S, P );
}
int blake2b_init_key( blake2b_state *S, size_t outlen, const void *key, size_t keylen )
{
blake2b_param P[1];
if ( ( !outlen ) || ( outlen > BLAKE2B_OUTBYTES ) ) return -1;
if ( !key || !keylen || keylen > BLAKE2B_KEYBYTES ) return -1;
P->digest_length = (uint8_t)outlen;
P->key_length = (uint8_t)keylen;
P->fanout = 1;
P->depth = 1;
store32( &P->leaf_length, 0 );
store32( &P->node_offset, 0 );
store32( &P->xof_length, 0 );
P->node_depth = 0;
P->inner_length = 0;
memset( P->reserved, 0, sizeof( P->reserved ) );
memset( P->salt, 0, sizeof( P->salt ) );
memset( P->personal, 0, sizeof( P->personal ) );
if( blake2b_init_param( S, P ) < 0 ) return -1;
{
uint8_t block[BLAKE2B_BLOCKBYTES];
memset( block, 0, BLAKE2B_BLOCKBYTES );
memcpy( block, key, keylen );
blake2b_update( S, block, BLAKE2B_BLOCKBYTES );
secure_zero_memory( block, BLAKE2B_BLOCKBYTES ); /* Burn the key from stack */
}
return 0;
}
#define G(r,i,a,b,c,d) \
do { \
a = a + b + m[blake2b_sigma[r][2*i+0]]; \
d = rotr64(d ^ a, 32); \
c = c + d; \
b = rotr64(b ^ c, 24); \
a = a + b + m[blake2b_sigma[r][2*i+1]]; \
d = rotr64(d ^ a, 16); \
c = c + d; \
b = rotr64(b ^ c, 63); \
} while(0)
#define ROUND(r) \
do { \
G(r,0,v[ 0],v[ 4],v[ 8],v[12]); \
G(r,1,v[ 1],v[ 5],v[ 9],v[13]); \
G(r,2,v[ 2],v[ 6],v[10],v[14]); \
G(r,3,v[ 3],v[ 7],v[11],v[15]); \
G(r,4,v[ 0],v[ 5],v[10],v[15]); \
G(r,5,v[ 1],v[ 6],v[11],v[12]); \
G(r,6,v[ 2],v[ 7],v[ 8],v[13]); \
G(r,7,v[ 3],v[ 4],v[ 9],v[14]); \
} while(0)
static void blake2b_compress( blake2b_state *S, const uint8_t block[BLAKE2B_BLOCKBYTES] )
{
uint64_t m[16];
uint64_t v[16];
size_t i;
for( i = 0; i < 16; ++i ) {
m[i] = load64( block + i * sizeof( m[i] ) );
}
for( i = 0; i < 8; ++i ) {
v[i] = S->h[i];
}
v[ 8] = blake2b_IV[0];
v[ 9] = blake2b_IV[1];
v[10] = blake2b_IV[2];
v[11] = blake2b_IV[3];
v[12] = blake2b_IV[4] ^ S->t[0];
v[13] = blake2b_IV[5] ^ S->t[1];
v[14] = blake2b_IV[6] ^ S->f[0];
v[15] = blake2b_IV[7] ^ S->f[1];
ROUND( 0 );
ROUND( 1 );
ROUND( 2 );
ROUND( 3 );
ROUND( 4 );
ROUND( 5 );
ROUND( 6 );
ROUND( 7 );
ROUND( 8 );
ROUND( 9 );
ROUND( 10 );
ROUND( 11 );
for( i = 0; i < 8; ++i ) {
S->h[i] = S->h[i] ^ v[i] ^ v[i + 8];
}
}
#undef G
#undef ROUND
int blake2b_update( blake2b_state *S, const void *pin, size_t inlen )
{
const unsigned char * in = (const unsigned char *)pin;
if( inlen > 0 )
{
size_t left = S->buflen;
size_t fill = BLAKE2B_BLOCKBYTES - left;
if( inlen > fill )
{
S->buflen = 0;
memcpy( S->buf + left, in, fill ); /* Fill buffer */
blake2b_increment_counter( S, BLAKE2B_BLOCKBYTES );
blake2b_compress( S, S->buf ); /* Compress */
in += fill; inlen -= fill;
while(inlen > BLAKE2B_BLOCKBYTES) {
blake2b_increment_counter(S, BLAKE2B_BLOCKBYTES);
blake2b_compress( S, in );
in += BLAKE2B_BLOCKBYTES;
inlen -= BLAKE2B_BLOCKBYTES;
}
}
memcpy( S->buf + S->buflen, in, inlen );
S->buflen += inlen;
}
return 0;
}
int blake2b_final( blake2b_state *S, void *out, size_t outlen )
{
uint8_t buffer[BLAKE2B_OUTBYTES] = {0};
size_t i;
if( out == NULL || outlen < S->outlen )
return -1;
if( blake2b_is_lastblock( S ) )
return -1;
blake2b_increment_counter( S, S->buflen );
blake2b_set_lastblock( S );
memset( S->buf + S->buflen, 0, BLAKE2B_BLOCKBYTES - S->buflen ); /* Padding */
blake2b_compress( S, S->buf );
for( i = 0; i < 8; ++i ) /* Output full hash to temp buffer */
store64( buffer + sizeof( S->h[i] ) * i, S->h[i] );
memcpy( out, buffer, S->outlen );
secure_zero_memory(buffer, sizeof(buffer));
return 0;
}
/* inlen, at least, should be uint64_t. Others can be size_t. */
int blake2b( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen )
{
blake2b_state S[1];
/* Verify parameters */
if ( NULL == in && inlen > 0 ) return -1;
if ( NULL == out ) return -1;
if( NULL == key && keylen > 0 ) return -1;
if( !outlen || outlen > BLAKE2B_OUTBYTES ) return -1;
if( keylen > BLAKE2B_KEYBYTES ) return -1;
if( keylen > 0 )
{
if( blake2b_init_key( S, outlen, key, keylen ) < 0 ) return -1;
}
else
{
if( blake2b_init( S, outlen ) < 0 ) return -1;
}
blake2b_update( S, ( const uint8_t * )in, inlen );
blake2b_final( S, out, outlen );
return 0;
}
int blake2( void *out, size_t outlen, const void *in, size_t inlen, const void *key, size_t keylen ) {
return blake2b(out, outlen, in, inlen, key, keylen);
}
#if defined(SUPERCOP)
int crypto_hash( unsigned char *out, unsigned char *in, unsigned long long inlen )
{
return blake2b( out, BLAKE2B_OUTBYTES, in, inlen, NULL, 0 );
}
#endif
#if defined(BLAKE2B_SELFTEST)
#include <string.h>
#include "blake2-kat.h"
int main( void )
{
uint8_t key[BLAKE2B_KEYBYTES];
uint8_t buf[BLAKE2_KAT_LENGTH];
size_t i, step;
for( i = 0; i < BLAKE2B_KEYBYTES; ++i )
key[i] = ( uint8_t )i;
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
buf[i] = ( uint8_t )i;
/* Test simple API */
for( i = 0; i < BLAKE2_KAT_LENGTH; ++i )
{
uint8_t hash[BLAKE2B_OUTBYTES];
blake2b( hash, BLAKE2B_OUTBYTES, buf, i, key, BLAKE2B_KEYBYTES );
if( 0 != memcmp( hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES ) )
{
goto fail;
}
}
/* Test streaming API */
for(step = 1; step < BLAKE2B_BLOCKBYTES; ++step) {
for (i = 0; i < BLAKE2_KAT_LENGTH; ++i) {
uint8_t hash[BLAKE2B_OUTBYTES];
blake2b_state S;
uint8_t * p = buf;
size_t mlen = i;
int err = 0;
if( (err = blake2b_init_key(&S, BLAKE2B_OUTBYTES, key, BLAKE2B_KEYBYTES)) < 0 ) {
goto fail;
}
while (mlen >= step) {
if ( (err = blake2b_update(&S, p, step)) < 0 ) {
goto fail;
}
mlen -= step;
p += step;
}
if ( (err = blake2b_update(&S, p, mlen)) < 0) {
goto fail;
}
if ( (err = blake2b_final(&S, hash, BLAKE2B_OUTBYTES)) < 0) {
goto fail;
}
if (0 != memcmp(hash, blake2b_keyed_kat[i], BLAKE2B_OUTBYTES)) {
goto fail;
}
}
}
puts( "ok" );
return 0;
fail:
puts("error");
return -1;
}
#endif

View file

@ -304,7 +304,7 @@ namespace crypto {
ge_tobytes(&image, &point2);
}
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4200)
struct rs_comm_entry
{
@ -314,7 +314,7 @@ struct rs_comm_entry
hash h;
struct rs_comm_entry ab[];
};
POP_WARNINGS
POP_VS_WARNINGS
static inline size_t rs_comm_size(size_t pubs_count) {
return sizeof(rs_comm)+pubs_count * sizeof(rs_comm_entry);

View file

@ -17,7 +17,7 @@
#include "warnings.h"
PUSH_WARNINGS
PUSH_GCC_WARNINGS
DISABLE_CLANG_WARNING(unused-private-field)
@ -236,3 +236,4 @@ POD_MAKE_COMPARABLE(crypto, signature)
POD_MAKE_COMPARABLE(crypto, key_derivation)
POD_MAKE_LESS_OPERATOR(crypto, hash)
POD_MAKE_LESS_OPERATOR(crypto, key_image)
POP_GCC_WARNINGS

View file

@ -22,7 +22,7 @@ static inline const void *cpadd(const void *p, size_t i) {
return (const char *) p + i;
}
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4267)
static_assert(sizeof(size_t) == 4 || sizeof(size_t) == 8, "size_t must be 4 or 8 bytes long");
static inline void place_length(uint8_t *buffer, size_t bufsize, size_t length) {
@ -32,7 +32,7 @@ static inline void place_length(uint8_t *buffer, size_t bufsize, size_t length)
*(uint64_t *) padd(buffer, bufsize - 8) = swap64be(length);
}
}
POP_WARNINGS
POP_VS_WARNINGS
#pragma pack(push, 1)
union hash_state {

View file

@ -8,7 +8,11 @@
#include "common/pod-class.h"
#include "generic-ops.h"
#include "warnings.h"
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4804)
#include "blake2.h"
POP_VS_WARNINGS
namespace crypto {
extern "C" {
@ -41,6 +45,12 @@ namespace crypto {
tree_hash(reinterpret_cast<const char (*)[HASH_SIZE]>(hashes), count, reinterpret_cast<char *>(&root_hash));
}
inline hash blake2_hash(const void *data, std::size_t length) {
hash h;
blake2(&h, sizeof(h), data, length, nullptr, 0);
return h;
}
}
POD_MAKE_HASHABLE(crypto, hash)

View file

@ -10,14 +10,14 @@
//#include "initializer.h"
#include "random.h"
static void generate_system_random_bytes(size_t n, void *result);
static_assert(RANDOM_STATE_SIZE >= HASH_DATA_AREA, "Invalid RANDOM_STATE_SIZE");
#if defined(_WIN32)
#include <windows.h>
#include <wincrypt.h>
static void generate_system_random_bytes(size_t n, void *result) {
void generate_system_random_bytes(size_t n, void *result) {
HCRYPTPROV prov;
#define must_succeed(x) do if (!(x)) assert(0); while (0)
if(!CryptAcquireContext(&prov, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT))
@ -40,7 +40,7 @@ static void generate_system_random_bytes(size_t n, void *result) {
#include <sys/types.h>
#include <unistd.h>
static void generate_system_random_bytes(size_t n, void *result) {
void generate_system_random_bytes(size_t n, void *result) {
int fd;
if ((fd = open("/dev/urandom", O_RDONLY | O_NOCTTY | O_CLOEXEC)) < 0) {
err(EXIT_FAILURE, "open /dev/urandom");
@ -68,7 +68,7 @@ static void generate_system_random_bytes(size_t n, void *result) {
#endif
/* static */ union hash_state state; // NOTE: 'static' is commented out here to be able to store/load global random generator state in tests (see also random_helper.h)
static union hash_state state;
#if !defined(NDEBUG)
static volatile int curstate; /* To catch thread safety problems. */
@ -105,6 +105,57 @@ void grant_random_initialize(void)
}
}
void random_prng_initialize_with_seed(uint64_t seed)
{
grant_random_initialize();
#if !defined(NDEBUG)
assert(curstate == 1);
curstate = 3;
#endif
memset(&state, 0, sizeof state);
memcpy(&state, &seed, sizeof seed);
for(size_t i = 0, count = seed & 31; i < count; ++i)
hash_permutation(&state);
#if !defined(NDEBUG)
assert(curstate == 3);
curstate = 1;
#endif
}
void random_prng_get_state(void *state_buffer, const size_t buffer_size)
{
grant_random_initialize();
#if !defined(NDEBUG)
assert(curstate == 1);
curstate = 4;
#endif
assert(sizeof state == buffer_size);
memcpy(state_buffer, &state, buffer_size);
#if !defined(NDEBUG)
assert(curstate == 4);
curstate = 1;
#endif
}
void random_prng_set_state(const void *state_buffer, const size_t buffer_size)
{
grant_random_initialize();
#if !defined(NDEBUG)
assert(curstate == 1);
curstate = 5;
#endif
assert(sizeof state == buffer_size);
memcpy(&state, state_buffer, buffer_size);
#if !defined(NDEBUG)
assert(curstate == 5);
curstate = 1;
#endif
}
void generate_random_bytes(size_t n, void *result) {
grant_random_initialize();
#if !defined(NDEBUG)

View file

@ -1,3 +1,5 @@
// Copyright (c) 2018-2019 Zano Project
// Copyright (c) 2014-2018 The Boolberry developers
// Copyright (c) 2012-2013 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -5,6 +7,31 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
// use the cryptographically secure Pseudo-Random Number Generator provided by the operating system
void generate_system_random_bytes(size_t n, void *result);
void generate_random_bytes(size_t n, void *result);
void grant_random_initialize(void);
// checks if PRNG is initialized and initializes it if necessary
void grant_random_initialize(void);
#define RANDOM_STATE_SIZE 200
// explicitly define USE_INSECURE_RANDOM_RPNG_ROUTINES for using random_initialize_with_seed
#ifdef USE_INSECURE_RANDOM_RPNG_ROUTINES
// reinitializes PRNG with the given seed
// !!!ATTENTION!!!! Improper use of this routine may lead to SECURITY BREACH!
// Use with care and ONLY for tests or debug purposes!
void random_prng_initialize_with_seed(uint64_t seed);
// gets internal RPNG state (state_buffer should be 200 bytes long)
void random_prng_get_state(void *state_buffer, const size_t buffer_size);
// sets internal RPNG state (state_buffer should be 200 bytes long)
// !!!ATTENTION!!!! Improper use of this routine may lead to SECURITY BREACH!
// Use with care and ONLY for tests or debug purposes!
void random_prng_set_state(const void *state_buffer, const size_t buffer_size);
#endif // #ifdef USE_INSECURE_RANDOM_RPNG_ROUTINES

View file

@ -225,10 +225,10 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro
// remove old incompatible DB
const std::string old_db_folder_path = m_config_folder + "/" CURRENCY_BLOCKCHAINDATA_FOLDERNAME_OLD;
if (boost::filesystem::exists(old_db_folder_path))
if (boost::filesystem::exists(epee::string_encoding::utf8_to_wstring(old_db_folder_path)))
{
LOG_PRINT_YELLOW("Removing old DB in " << old_db_folder_path << "...", LOG_LEVEL_0);
boost::filesystem::remove_all(old_db_folder_path);
boost::filesystem::remove_all(epee::string_encoding::utf8_to_wstring(old_db_folder_path));
}
const std::string db_folder_path = m_config_folder + "/" CURRENCY_BLOCKCHAINDATA_FOLDERNAME;
@ -242,7 +242,7 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro
{
// if DB could not be opened -- try to remove the whole folder and re-open DB
LOG_PRINT_YELLOW("Failed to initialize database in folder: " << db_folder_path << ", first attempt", LOG_LEVEL_0);
boost::filesystem::remove_all(db_folder_path);
boost::filesystem::remove_all(epee::string_encoding::utf8_to_wstring(db_folder_path));
res = m_db.open(db_folder_path, cache_size_l1);
CHECK_AND_ASSERT_MES(res, false, "Failed to initialize database in folder: " << db_folder_path << ", second attempt");
}
@ -312,7 +312,7 @@ bool blockchain_storage::init(const std::string& config_folder, const boost::pro
m_db_addr_to_alias.deinit();
m_db_per_block_gindex_incs.deinit();
m_db.close();
size_t files_removed = boost::filesystem::remove_all(db_folder_path);
size_t files_removed = boost::filesystem::remove_all(epee::string_encoding::utf8_to_wstring(db_folder_path));
LOG_PRINT_L1(files_removed << " files at " << db_folder_path << " removed");
// try to re-create DB and re-init containers
@ -1821,8 +1821,8 @@ bool blockchain_storage::is_reorganize_required(const block_extended_info& main_
main_cumul_diff.pow_diff = main_pow_diff_end - main_pow_diff_begin;
//TODO: measurement of precise cumulative difficult
wide_difficulty_type alt = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, alt_cumul_diff, main_cumul_diff);
wide_difficulty_type main = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, main_cumul_diff, alt_cumul_diff);
boost::multiprecision::uint1024_t alt = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, alt_cumul_diff, main_cumul_diff);
boost::multiprecision::uint1024_t main = get_a_to_b_relative_cumulative_difficulty(difficulty_pos_at_split_point, difficulty_pow_at_split_point, main_cumul_diff, alt_cumul_diff);
LOG_PRINT_L1("[FORK_CHOICE]: " << ENDL
<< "difficulty_pow_at_split_point:" << difficulty_pow_at_split_point << ENDL
<< "difficulty_pos_at_split_point:" << difficulty_pos_at_split_point << ENDL
@ -2644,7 +2644,8 @@ void blockchain_storage::print_blockchain_with_tx(uint64_t start_index, uint64_t
{
boost::filesystem::ofstream ss;
ss.exceptions(/*std::ifstream::failbit |*/ std::ifstream::badbit);
ss.open(log_space::log_singletone::get_default_log_folder() + "/blockchain_with_tx.txt", std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
ss.open(epee::string_encoding::utf8_to_wstring(log_space::log_singletone::get_default_log_folder() + "/blockchain_with_tx.txt"),
std::ios_base::binary | std::ios_base::out | std::ios_base::trunc);
CRITICAL_REGION_LOCAL(m_read_lock);
@ -2723,7 +2724,6 @@ void blockchain_storage::print_db_cache_perfeormance_data() const
void blockchain_storage::get_last_n_x_blocks(uint64_t n, bool pos_blocks, std::list<std::shared_ptr<const block_extended_info>>& blocks) const
{
uint64_t count = 0;
bool looking_for_a_pos = true;
for (uint64_t i = m_db_blocks.size() - 1; i != 0; --i)
{
auto block_ptr = m_db_blocks[i];
@ -4870,7 +4870,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
CHECK_AND_ASSERT_MES_NO_RET(add_res, "handle_block_to_main_chain: failed to add transaction back to transaction pool");
purge_block_data_from_blockchain(bl, tx_processed_count);
add_block_as_invalid(bl, id);
LOG_PRINT_L0("Block with id " << id << " added as invalid becouse of wrong inputs in transactions");
LOG_PRINT_L0("Block with id " << id << " added as invalid because of wrong inputs in transactions");
bvc.m_verification_failed = true;
return false;
}
@ -5370,7 +5370,7 @@ bool blockchain_storage::build_stake_modifier(stake_modifier_type& sm, const alt
else
{
bool r = string_tools::parse_tpod_from_hex_string(POS_STARTER_KERNEL_HASH, sm.last_pos_kernel_id);
CHECK_AND_ASSERT_MES(r, false, "Failed to parse POS_STARTER_MODFIFIER");
CHECK_AND_ASSERT_MES(r, false, "Failed to parse POS_STARTER_KERNEL_HASH");
}
sm.last_pow_id = get_block_hash(pbei_last_pow->bl);

View file

@ -255,13 +255,13 @@ namespace currency
END_SERIALIZE()
};
struct tx_message
struct tx_derivation_hint
{
std::string msg;
BEGIN_SERIALIZE()
FIELD(msg)
END_SERIALIZE()
END_SERIALIZE()
};
struct tx_service_attachment
@ -382,7 +382,7 @@ namespace currency
END_SERIALIZE()
};
struct etc_tx_derivation_hint
struct etc_tx_uint16_t
{
uint16_t v;
BEGIN_SERIALIZE()
@ -390,7 +390,7 @@ namespace currency
END_SERIALIZE()
};
typedef boost::mpl::vector<tx_service_attachment, tx_comment, tx_payer, tx_receiver, tx_message, std::string, tx_crypto_checksum, etc_tx_time, etc_tx_details_unlock_time, etc_tx_details_expiration_time, etc_tx_details_flags, crypto::public_key, extra_attachment_info, extra_alias_entry, extra_user_data, extra_padding, etc_tx_derivation_hint, etc_tx_details_unlock_time2> all_payload_types;
typedef boost::mpl::vector<tx_service_attachment, tx_comment, tx_payer, tx_receiver, tx_derivation_hint, std::string, tx_crypto_checksum, etc_tx_time, etc_tx_details_unlock_time, etc_tx_details_expiration_time, etc_tx_details_flags, crypto::public_key, extra_attachment_info, extra_alias_entry, extra_user_data, extra_padding, etc_tx_uint16_t, etc_tx_details_unlock_time2> all_payload_types;
typedef boost::make_variant_over<all_payload_types>::type attachment_v;
typedef boost::make_variant_over<all_payload_types>::type extra_v;
typedef boost::make_variant_over<all_payload_types>::type payload_items_v;
@ -602,7 +602,7 @@ SET_VARIANT_TAGS(currency::tx_comment, 7, "comment");
SET_VARIANT_TAGS(currency::tx_payer, 8, "payer");
SET_VARIANT_TAGS(std::string, 9, "string");
SET_VARIANT_TAGS(currency::tx_crypto_checksum, 10, "checksum");
SET_VARIANT_TAGS(currency::tx_message, 11, "message");
SET_VARIANT_TAGS(currency::tx_derivation_hint, 11, "derivation_hint");
SET_VARIANT_TAGS(currency::tx_service_attachment, 12, "attachment");
//SET_VARIANT_TAGS(currency::tx_onetime_secret_key, 13, "sec_key");
SET_VARIANT_TAGS(currency::etc_tx_details_unlock_time, 14, "unlock_time");
@ -616,7 +616,7 @@ SET_VARIANT_TAGS(currency::extra_user_data, 19, "user_data");
SET_VARIANT_TAGS(currency::extra_alias_entry, 20, "alias_entry");
SET_VARIANT_TAGS(currency::extra_padding, 21, "extra_padding");
SET_VARIANT_TAGS(crypto::public_key, 22, "pub_key");
SET_VARIANT_TAGS(currency::etc_tx_derivation_hint, 23, "derive_hint");
SET_VARIANT_TAGS(currency::etc_tx_uint16_t, 23, "etc_tx_uint16");
SET_VARIANT_TAGS(uint16_t, 24, "derive_xor");
//txout_v
SET_VARIANT_TAGS(currency::ref_by_id, 25, "ref_by_id");

View file

@ -107,7 +107,7 @@ namespace boost
a & x.derivation_hash;
}
template <class Archive>
inline void serialize(Archive &a, currency::tx_message &x, const boost::serialization::version_type ver)
inline void serialize(Archive &a, currency::tx_derivation_hint &x, const boost::serialization::version_type ver)
{
a & x.msg;
}
@ -211,7 +211,7 @@ namespace boost
}
template <class Archive>
inline void serialize(Archive &a, currency::etc_tx_derivation_hint &at, const boost::serialization::version_type ver)
inline void serialize(Archive &a, currency::etc_tx_uint16_t&at, const boost::serialization::version_type ver)
{
a & at.v;
}

View file

@ -18,6 +18,7 @@ using namespace epee;
#include "currency_core/currency_config.h"
#include "currency_format_utils.h"
#include "misc_language.h"
#include "string_coding.h"
#define MINIMUM_REQUIRED_FREE_SPACE_BYTES (1024 * 1024 * 100)
@ -717,10 +718,27 @@ namespace currency
//-----------------------------------------------------------------------------------------------
bool core::check_if_free_space_critically_low(uint64_t* p_available_space /* = nullptr */)
{
boost::filesystem::space_info si = boost::filesystem::space(m_config_folder);
if (p_available_space != nullptr)
*p_available_space = si.available;
return si.available < MINIMUM_REQUIRED_FREE_SPACE_BYTES;
namespace fs = boost::filesystem;
try
{
CHECK_AND_ASSERT_MES(tools::create_directories_if_necessary(m_config_folder), false, "create_directories_if_necessary failed: " << m_config_folder);
std::wstring config_folder_w = epee::string_encoding::utf8_to_wstring(m_config_folder);
fs::space_info si = fs::space(config_folder_w);
if (p_available_space != nullptr)
*p_available_space = si.available;
return si.available < MINIMUM_REQUIRED_FREE_SPACE_BYTES;
}
catch (std::exception& e)
{
LOG_ERROR("failed to determine free space: " << e.what());
return false;
}
catch (...)
{
LOG_ERROR("failed to determine free space: unknown exception");
return false;
}
}
void core::check_free_space()

View file

@ -21,7 +21,7 @@
#include "warnings.h"
#include "crypto/hash.h"
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4355)
namespace currency
@ -159,4 +159,4 @@ namespace currency
};
}
POP_WARNINGS
POP_VS_WARNINGS

View file

@ -516,6 +516,17 @@ namespace currency
return r;
}
//---------------------------------------------------------------
uint16_t get_derivation_hint(const crypto::key_derivation& derivation)
{
crypto::hash h = blake2_hash(&derivation, sizeof(derivation));
uint16_t* pderiv_hash_as_array = (uint16_t*)&h;
uint16_t res = pderiv_hash_as_array[0];
for (size_t i = 1; i != sizeof(h) / sizeof(uint16_t); i++)
res ^= pderiv_hash_as_array[i];
return res;
}
//---------------------------------------------------------------
uint64_t get_string_uint64_hash(const std::string& str)
{
crypto::hash h = crypto::cn_fast_hash(str.data(), str.size());
@ -523,15 +534,22 @@ namespace currency
return phash_as_array[0] ^ phash_as_array[1] ^ phash_as_array[2] ^ phash_as_array[3];
}
//---------------------------------------------------------------
uint16_t get_derivation_xor(const crypto::key_derivation& derivation)
tx_derivation_hint make_tx_derivation_hint_from_uint16(uint16_t hint)
{
uint16_t* pderiv_as_array = (uint16_t*)&derivation;
uint16_t res = pderiv_as_array[0];
for (size_t i = 1; i != sizeof(derivation) / sizeof(uint16_t); i++)
res ^= pderiv_as_array[i];
return res;
tx_derivation_hint dh = AUTO_VAL_INIT(dh);
dh.msg.assign((const char*)&hint, sizeof(hint));
return dh;
}
//---------------------------------------------------------------
// bool get_uint16_from_tx_derivation_hint(const tx_derivation_hint& dh, uint16_t& hint)
// {
// tx_derivation_hint dh;
// if (dh.msg.size() != sizeof(hint))
// return false;
// hint = *((uint16_t*)dh.msg.data());
// return true;
// }
//---------------------------------------------------------------
bool construct_tx_out(const tx_destination_entry& de, const crypto::secret_key& tx_sec_key, size_t output_index, transaction& tx, std::set<uint16_t>& deriv_cache, uint8_t tx_outs_attr)
{
CHECK_AND_ASSERT_MES(de.addr.size() == 1 || (de.addr.size() > 1 && de.minimum_sigs <= de.addr.size()), false, "Invalid destination entry: amount: " << de.amount << " minimum_sigs: " << de.minimum_sigs << " addr.size(): " << de.addr.size());
@ -551,12 +569,12 @@ namespace currency
crypto::key_derivation derivation = AUTO_VAL_INIT(derivation);
bool r = derive_public_key_from_target_address(apa, tx_sec_key, output_index, out_eph_public_key, derivation);
CHECK_AND_ASSERT_MES(r, false, "failed to derive_public_key_from_target_address");
etc_tx_derivation_hint dh = AUTO_VAL_INIT(dh);
dh.v = get_derivation_xor(derivation);
if (deriv_cache.count(dh.v) == 0)
uint16_t hint = get_derivation_hint(derivation);
if (deriv_cache.count(hint) == 0)
{
tx.extra.push_back(dh);
deriv_cache.insert(dh.v);
tx.extra.push_back(make_tx_derivation_hint_from_uint16(hint));
deriv_cache.insert(hint);
}
}
target_keys.push_back(out_eph_public_key);
@ -646,11 +664,6 @@ namespace currency
crypto::chacha_crypt(m.acc_addr, m_key);
m_was_crypted_entries = true;
}
void operator()(tx_message& m)
{
crypto::chacha_crypt(m.msg, m_key);
m_was_crypted_entries = true;
}
void operator()(tx_service_attachment& sa)
{
if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY)
@ -686,13 +699,6 @@ namespace currency
rdecrypted_att.push_back(local_comment);
}
void operator()(const tx_message& m)
{
tx_message local_msg = m;
crypto::chacha_crypt(local_msg.msg, rkey);
rdecrypted_att.push_back(local_msg);
}
void operator()(const tx_service_attachment& sa)
{
tx_service_attachment local_sa = sa;
@ -1544,14 +1550,19 @@ namespace currency
bool check_tx_derivation_hint(const transaction& tx, const crypto::key_derivation& derivation)
{
bool found_der_xor = false;
uint16_t my_derive_xor = get_derivation_xor(derivation);
uint16_t hint = get_derivation_hint(derivation);
tx_derivation_hint dh = make_tx_derivation_hint_from_uint16(hint);
for (auto& e : tx.extra)
{
if (e.type() == typeid(etc_tx_derivation_hint))
if (e.type() == typeid(tx_derivation_hint))
{
found_der_xor = true;
if (my_derive_xor == boost::get<etc_tx_derivation_hint>(e).v)
return true;
const tx_derivation_hint& tdh = boost::get<tx_derivation_hint>(e);
if (tdh.msg.size() == sizeof(uint16_t))
{
found_der_xor = true;
if (dh.msg == tdh.msg)
return true;
}
}
}
//if tx doesn't have any hints - feature is not supported, use full scan
@ -1726,7 +1737,13 @@ namespace currency
}
return true;
}
//------------------------------------------------------------------
bool validate_password(const std::string& password)
{
static const std::string allowed_password_symbols = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz~!?@#$%^&*_+|{}[]()<>:;\"'-=\\/.,";
size_t n = password.find_first_not_of(allowed_password_symbols, 0);
return n == std::string::npos;
}
//------------------------------------------------------------------
#define ANTI_OVERFLOW_AMOUNT 1000000
@ -2204,9 +2221,9 @@ namespace currency
return true;
}
bool operator()(const tx_message& ee)
bool operator()(const tx_derivation_hint& ee)
{
tv.type = "message";
tv.type = "derivation_hint";
tv.short_view = std::to_string(ee.msg.size()) + " bytes";
tv.datails_view = epee::string_tools::buff_to_hex_nodelimer(ee.msg);
@ -2220,7 +2237,7 @@ namespace currency
return true;
}
bool operator()(const etc_tx_derivation_hint& dh)
bool operator()(const etc_tx_uint16_t& dh)
{
tv.type = "XOR";
tv.short_view = epee::string_tools::pod_to_hex(dh);
@ -2702,7 +2719,7 @@ namespace currency
}
wide_difficulty_type get_a_to_b_relative_cumulative_difficulty(const wide_difficulty_type& difficulty_pos_at_split_point,
boost::multiprecision::uint1024_t get_a_to_b_relative_cumulative_difficulty(const wide_difficulty_type& difficulty_pos_at_split_point,
const wide_difficulty_type& difficulty_pow_at_split_point,
const difficulties& a_diff,
const difficulties& b_diff )
@ -2717,20 +2734,20 @@ namespace currency
boost::multiprecision::uint1024_t res =
(basic_sum * a_pow_cumulative_difficulty * a_pos_cumulative_difficulty) / (boost::multiprecision::uint1024_t(b_pow_cumulative_difficulty)*b_pos_cumulative_difficulty);
if (res > boost::math::tools::max_value<wide_difficulty_type>())
{
ASSERT_MES_AND_THROW("[INTERNAL ERROR]: Failed to get_a_to_b_relative_cumulative_difficulty, res = " << res << ENDL
<< ", difficulty_pos_at_split_point: " << difficulty_pos_at_split_point << ENDL
<< ", difficulty_pow_at_split_point:" << difficulty_pow_at_split_point << ENDL
<< ", a_pos_cumulative_difficulty:" << a_pos_cumulative_difficulty << ENDL
<< ", b_pos_cumulative_difficulty:" << b_pos_cumulative_difficulty << ENDL
<< ", a_pow_cumulative_difficulty:" << a_pow_cumulative_difficulty << ENDL
<< ", b_pow_cumulative_difficulty:" << b_pow_cumulative_difficulty << ENDL
);
}
// if (res > boost::math::tools::max_value<wide_difficulty_type>())
// {
// ASSERT_MES_AND_THROW("[INTERNAL ERROR]: Failed to get_a_to_b_relative_cumulative_difficulty, res = " << res << ENDL
// << ", difficulty_pos_at_split_point: " << difficulty_pos_at_split_point << ENDL
// << ", difficulty_pow_at_split_point:" << difficulty_pow_at_split_point << ENDL
// << ", a_pos_cumulative_difficulty:" << a_pos_cumulative_difficulty << ENDL
// << ", b_pos_cumulative_difficulty:" << b_pos_cumulative_difficulty << ENDL
// << ", a_pow_cumulative_difficulty:" << a_pow_cumulative_difficulty << ENDL
// << ", b_pow_cumulative_difficulty:" << b_pow_cumulative_difficulty << ENDL
// );
// }
TRY_ENTRY();
wide_difficulty_type short_res = res.convert_to<wide_difficulty_type>();
return short_res;
// wide_difficulty_type short_res = res.convert_to<wide_difficulty_type>();
return res;
CATCH_ENTRY_WITH_FORWARDING_EXCEPTION();
}

View file

@ -21,7 +21,6 @@
#include "crypto/crypto.h"
#include "crypto/hash.h"
#include "difficulty.h"
//#include "offers_services_helpers.h"
#include "rpc/core_rpc_server_commands_defs.h"
#include "bc_payments_id_service.h"
#include "bc_attachments_helpers_basic.h"
@ -29,6 +28,7 @@
#include "currency_format_utils_blocks.h"
#include "currency_format_utils_transactions.h"
// ------ get_tx_type_definition -------------
#define GUI_TX_TYPE_NORMAL 0
#define GUI_TX_TYPE_PUSH_OFFER 1
@ -163,6 +163,7 @@ namespace currency
uint64_t get_string_uint64_hash(const std::string& str);
bool construct_tx_out(const tx_destination_entry& de, const crypto::secret_key& tx_sec_key, size_t output_index, transaction& tx, std::set<uint16_t>& deriv_cache, uint8_t tx_outs_attr = CURRENCY_TO_KEY_OUT_RELAXED);
bool validate_alias_name(const std::string& al);
bool validate_password(const std::string& password);
void get_attachment_extra_info_details(const std::vector<attachment_v>& attachment, extra_attachment_info& eai);
bool construct_tx(const account_keys& sender_account_keys,
const std::vector<tx_source_entry>& sources,
@ -604,7 +605,7 @@ namespace currency
wide_difficulty_type pow_diff;
};
wide_difficulty_type get_a_to_b_relative_cumulative_difficulty(const wide_difficulty_type& difficulty_pos_at_split_point,
boost::multiprecision::uint1024_t get_a_to_b_relative_cumulative_difficulty(const wide_difficulty_type& difficulty_pos_at_split_point,
const wide_difficulty_type& difficulty_pow_at_split_point,
const difficulties& a_diff,
const difficulties& b_diff

View file

@ -125,4 +125,69 @@ namespace bc_services
typedef boost::variant<offer_details, update_offer, cancel_offer> offers_attachment_t;
inline std::string transform_double_to_string(const double& a)
{
return std::to_string(a);
}
inline double transform_string_to_double(const std::string& d)
{
double n = 0;
epee::string_tools::get_xtype_from_string(n, d);
return n;
}
struct core_offers_filter
{
uint64_t order_by;
bool reverse;
uint64_t offset;
uint64_t limit;
//filter entry
uint64_t timestamp_start;
uint64_t timestamp_stop;
uint64_t offer_type_mask;
uint64_t amount_low_limit;
uint64_t amount_up_limit;
double rate_low_limit;
double rate_up_limit;
std::list<std::string> payment_types;
std::string location_country;
std::string location_city;
std::string target;
std::string primary;
bool bonus;
std::string category;
std::string keyword;
bool fake;
uint64_t current_time;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(order_by)
KV_SERIALIZE(reverse)
KV_SERIALIZE(offset)
KV_SERIALIZE(limit)
KV_SERIALIZE(timestamp_start)
KV_SERIALIZE(timestamp_stop)
KV_SERIALIZE(offer_type_mask)
KV_SERIALIZE(amount_low_limit)
KV_SERIALIZE(amount_up_limit)
KV_SERIALIZE_CUSTOM(rate_low_limit, std::string, bc_services::transform_double_to_string, bc_services::transform_string_to_double)
KV_SERIALIZE_CUSTOM(rate_up_limit, std::string, bc_services::transform_double_to_string, bc_services::transform_string_to_double)
KV_SERIALIZE(payment_types)
KV_SERIALIZE(location_country)
KV_SERIALIZE(location_city)
KV_SERIALIZE(target)
KV_SERIALIZE(primary)
KV_SERIALIZE(bonus)
KV_SERIALIZE(category)
KV_SERIALIZE(keyword)
KV_SERIALIZE(fake)
END_KV_SERIALIZE_MAP()
};
}

View file

@ -17,17 +17,7 @@
namespace bc_services
{
std::string transform_double_to_string(const double& a)
{
return std::to_string(a);
}
double transform_string_to_double(const std::string& d)
{
double n = 0;
epee::string_tools::get_xtype_from_string(n, d);
return n;
}
bool order_offers_by_timestamp(const offer_details_ex* a, const offer_details_ex* b)
{

View file

@ -18,60 +18,6 @@
namespace bc_services
{
std::string transform_double_to_string(const double& a);
double transform_string_to_double(const std::string& d);
struct core_offers_filter
{
uint64_t order_by;
bool reverse;
uint64_t offset;
uint64_t limit;
//filter entry
uint64_t timestamp_start;
uint64_t timestamp_stop;
uint64_t offer_type_mask;
uint64_t amount_low_limit;
uint64_t amount_up_limit;
double rate_low_limit;
double rate_up_limit;
std::list<std::string> payment_types;
std::string location_country;
std::string location_city;
std::string target;
std::string primary;
bool bonus;
std::string category;
std::string keyword;
bool fake;
uint64_t current_time;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(order_by)
KV_SERIALIZE(reverse)
KV_SERIALIZE(offset)
KV_SERIALIZE(limit)
KV_SERIALIZE(timestamp_start)
KV_SERIALIZE(timestamp_stop)
KV_SERIALIZE(offer_type_mask)
KV_SERIALIZE(amount_low_limit)
KV_SERIALIZE(amount_up_limit)
KV_SERIALIZE_CUSTOM(rate_low_limit, std::string, bc_services::transform_double_to_string, bc_services::transform_string_to_double)
KV_SERIALIZE_CUSTOM(rate_up_limit, std::string, bc_services::transform_double_to_string, bc_services::transform_string_to_double)
KV_SERIALIZE(payment_types)
KV_SERIALIZE(location_country)
KV_SERIALIZE(location_city)
KV_SERIALIZE(target)
KV_SERIALIZE(primary)
KV_SERIALIZE(bonus)
KV_SERIALIZE(category)
KV_SERIALIZE(keyword)
KV_SERIALIZE(fake)
END_KV_SERIALIZE_MAP()
};
struct offer_id
{

View file

@ -1125,10 +1125,10 @@ namespace currency
// remove old incompartible DB
const std::string old_db_folder_path = m_config_folder + "/" CURRENCY_POOLDATA_FOLDERNAME_OLD;
if (boost::filesystem::exists(old_db_folder_path))
if (boost::filesystem::exists(epee::string_encoding::utf8_to_wstring(old_db_folder_path)))
{
LOG_PRINT_YELLOW("Removing old DB in " << old_db_folder_path << "...", LOG_LEVEL_0);
boost::filesystem::remove_all(old_db_folder_path);
boost::filesystem::remove_all(epee::string_encoding::utf8_to_wstring(old_db_folder_path));
}
const std::string db_folder_path = m_config_folder + "/" CURRENCY_POOLDATA_FOLDERNAME;
@ -1142,7 +1142,7 @@ namespace currency
{
// if DB could not be opened -- try to remove the whole folder and re-open DB
LOG_PRINT_YELLOW("Failed to initialize database in folder: " << db_folder_path << ", first attempt", LOG_LEVEL_0);
boost::filesystem::remove_all(db_folder_path);
boost::filesystem::remove_all(epee::string_encoding::utf8_to_wstring(db_folder_path));
res = m_db.open(db_folder_path, cache_size_l1);
CHECK_AND_ASSERT_MES(res, false, "Failed to initialize database in folder: " << db_folder_path << ", second attempt");
}
@ -1182,7 +1182,7 @@ namespace currency
m_db_alias_addresses.deinit();
m_db_solo_options.deinit();
m_db.close();
size_t files_removed = boost::filesystem::remove_all(db_folder_path);
size_t files_removed = boost::filesystem::remove_all(epee::string_encoding::utf8_to_wstring(db_folder_path));
LOG_PRINT_L1(files_removed << " files at " << db_folder_path << " removed");
// try to re-create DB and re-init containers

View file

@ -19,7 +19,7 @@
#undef LOG_DEFAULT_CHANNEL
#define LOG_DEFAULT_CHANNEL "currency_protocol"
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4355)
#define ASYNC_RELAY_MODE
@ -145,4 +145,4 @@ namespace currency
#undef LOG_DEFAULT_CHANNEL
#define LOG_DEFAULT_CHANNEL NULL
POP_WARNINGS
POP_VS_WARNINGS

View file

@ -770,36 +770,14 @@ namespace currency
#define TIME_SYNC_DELTA_RING_BUFFER_SIZE 8
#define TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE (60 * 5) // max acceptable difference between time delta median among peers and local time (seconds)
#define TIME_SYNC_NTP_TO_LOCAL_MAX_DIFFERENCE (60 * 5) // max acceptable difference between NTP time and local time (seconds)
#define TIME_SYNC_NTP_SERVERS { "time.google.com", "0.pool.ntp.org", "1.pool.ntp.org", "2.pool.ntp.org", "3.pool.ntp.org" }
#define TIME_SYNC_NTP_ATTEMPTS_COUNT 3 // max number of attempts when getting time from NTP server
static int64_t get_ntp_time()
{
static const std::vector<std::string> ntp_servers TIME_SYNC_NTP_SERVERS;
for (size_t att = 0; att < TIME_SYNC_NTP_ATTEMPTS_COUNT; ++att)
{
size_t i = 0;
crypto::generate_random_bytes(sizeof(i), &i);
const std::string& ntp_server = ntp_servers[i % ntp_servers.size()];
LOG_PRINT_L3("NTP: trying to get time from " << ntp_server);
int64_t time = tools::get_ntp_time(ntp_server);
if (time > 0)
{
LOG_PRINT_L2("NTP: " << ntp_server << " responded with " << time << " (" << epee::misc_utils::get_time_str_v2(time) << ")");
return time;
}
LOG_PRINT_L2("NTP: cannot get time from " << ntp_server);
}
return 0; // smth went wrong
}
template<class t_core>
bool t_currency_protocol_handler<t_core>::add_time_delta_and_check_time_sync(int64_t time_delta)
{
CRITICAL_REGION_LOCAL(m_time_deltas_lock);
auto get_core_time = [this] { return m_core.get_blockchain_storage().get_core_runtime_config().get_core_time(); };
m_time_deltas.push_back(time_delta);
while (m_time_deltas.size() > TIME_SYNC_DELTA_RING_BUFFER_SIZE)
m_time_deltas.pop_front();
@ -813,7 +791,8 @@ namespace currency
LOG_PRINT_MAGENTA("TIME: network time difference is " << m_last_median2local_time_difference << " (max is " << TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE << ")", LOG_LEVEL_2);
if (std::abs(m_last_median2local_time_difference) > TIME_SYNC_DELTA_TO_LOCAL_MAX_DIFFERENCE)
{
int64_t ntp_time = get_ntp_time();
int64_t ntp_time = tools::get_ntp_time();
LOG_PRINT_L2("NTP: received time " << ntp_time << " (" << epee::misc_utils::get_time_str_v2(ntp_time) << "), diff: " << std::showpos << get_core_time() - ntp_time);
if (ntp_time == 0)
{
// error geting ntp time
@ -823,7 +802,7 @@ namespace currency
// got ntp time correctly
// update local time, because getting ntp time could be time consuming
uint64_t local_time_2 = m_core.get_blockchain_storage().get_core_runtime_config().get_core_time();
uint64_t local_time_2 = get_core_time();
m_last_ntp2local_time_difference = local_time_2 - ntp_time;
if (std::abs(m_last_ntp2local_time_difference) > TIME_SYNC_NTP_TO_LOCAL_MAX_DIFFERENCE)
{

View file

@ -87,6 +87,13 @@ struct core_critical_error_handler_t : public currency::i_critical_error_handler
bool dont_stop_on_low_space;
};
void terminate_handler_func()
{
LOG_ERROR("\n\nTERMINATE HANDLER\n"); // should print callstack
std::fflush(nullptr); // all open output streams are flushed
std::abort(); // default terminate handler's behavior
}
int main(int argc, char* argv[])
{
try
@ -112,6 +119,9 @@ int main(int argc, char* argv[])
// setup custom callstack retrieving function
epee::misc_utils::get_callstack(tools::get_callstack);
// setup custom terminate functions
std::set_terminate(&terminate_handler_func);
po::options_description desc_cmd_only("Command line options");
po::options_description desc_cmd_sett("Command line options and settings options", 130, 83);
@ -130,6 +140,7 @@ int main(int argc, char* argv[])
command_line::add_arg(desc_cmd_sett, command_line::arg_show_rpc_autodoc);
command_line::add_arg(desc_cmd_sett, command_line::arg_disable_stop_if_time_out_of_sync);
command_line::add_arg(desc_cmd_sett, command_line::arg_disable_stop_on_low_free_space);
command_line::add_arg(desc_cmd_sett, command_line::arg_enable_offers_service);
arg_market_disable.default_value = true;
@ -162,8 +173,8 @@ int main(int argc, char* argv[])
std::string data_dir = command_line::get_arg(vm, command_line::arg_data_dir);
std::string config = command_line::get_arg(vm, command_line::arg_config_file);
boost::filesystem::path data_dir_path(data_dir);
boost::filesystem::path config_path(config);
boost::filesystem::path data_dir_path(epee::string_encoding::utf8_to_wstring(data_dir));
boost::filesystem::path config_path(epee::string_encoding::utf8_to_wstring(config));
if (!config_path.has_parent_path())
{
config_path = data_dir_path / config_path;
@ -223,8 +234,14 @@ int main(int argc, char* argv[])
command_line::get_arg(vm, command_line::arg_disable_stop_on_low_free_space));
ccore.set_critical_error_handler(&cceh);
//ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&offers_service);
std::shared_ptr<currency::stratum_server> stratum_server_ptr;
if (command_line::get_arg(vm, command_line::arg_enable_offers_service))
{
ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&offers_service);
}
std::shared_ptr<currency::stratum_server> stratum_server_ptr;
if (stratum_enabled)
stratum_server_ptr = std::make_shared<currency::stratum_server>(&ccore);

View file

@ -17,7 +17,7 @@
#include "currency_core/bc_offers_service.h"
#include "serialization/binary_utils.h"
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4100)
class daemon_commands_handler
@ -70,6 +70,9 @@ public:
m_cmd_binder.set_handler("print_tx_outputs_usage", boost::bind(&daemon_commands_handler::print_tx_outputs_usage, this, _1), "Analyse if tx outputs for involved in subsequent transactions");
m_cmd_binder.set_handler("print_difficulties_of_last_n_blocks", boost::bind(&daemon_commands_handler::print_difficulties_of_last_n_blocks, this, _1), "Print difficulties of last n blocks");
#ifdef _DEBUG
m_cmd_binder.set_handler("debug_set_time_adj", boost::bind(&daemon_commands_handler::debug_set_time_adj, this, _1), "DEBUG: set core time adjustment");
#endif
}
bool start_handling()
@ -824,9 +827,51 @@ private:
LOG_PRINT_L0(ENDL << epee::deadlock_guard_singleton::get_dlg_state());
return true;
}
//--------------------------------------------------------------------------------
#ifdef _DEBUG
static std::atomic<int64_t>& debug_core_time_shift_accessor()
{
static std::atomic<int64_t> time_shift(0);
return time_shift;
}
static uint64_t debug_core_time_function()
{
return (int64_t)time(NULL) + debug_core_time_shift_accessor().load(std::memory_order_relaxed);
}
bool debug_set_time_adj(const std::vector<std::string>& args)
{
if (args.size() != 1)
{
LOG_PRINT_RED("one arg required: signed time shift in seconds", LOG_LEVEL_0);
return false;
}
int64_t time_shift = 0;
if (!epee::string_tools::string_to_num_fast(args[0], time_shift))
{
LOG_PRINT_RED("could not parse: " << args[0], LOG_LEVEL_0);
return false;
}
uint64_t time_before = debug_core_time_function();
debug_core_time_shift_accessor().store(time_shift);
uint64_t time_after = debug_core_time_function();
currency::blockchain_storage& bcs = m_srv.get_payload_object().get_core().get_blockchain_storage();
currency::core_runtime_config crc = bcs.get_core_runtime_config();
crc.get_core_time = &debug_core_time_function;
bcs.set_core_runtime_config(crc);
LOG_PRINT_L0("debug time shift set to " << time_shift << " : time before: " << time_before << ", time_after: " << time_after);
return true;
}
#endif
};
POP_WARNINGS
POP_VS_WARNINGS

View file

@ -40,7 +40,8 @@ daemon_backend::daemon_backend():m_pview(&m_view_stub),
m_offers_service(nullptr),
m_ui_opt(AUTO_VAL_INIT(m_ui_opt)),
m_remote_node_mode(false),
m_is_pos_allowed(false)
m_is_pos_allowed(false),
m_qt_logs_enbaled(false)
{
m_offers_service.set_disabled(true);
//m_ccore.get_blockchain_storage().get_attachment_services_manager().add_service(&m_offers_service);
@ -52,6 +53,7 @@ const command_line::arg_descriptor<std::string> arg_xcode_stub = {"-NSDocumentRe
const command_line::arg_descriptor<bool> arg_enable_gui_debug_mode = { "gui-debug-mode", "Enable debug options in GUI", false, true };
const command_line::arg_descriptor<uint32_t> arg_qt_remote_debugging_port = { "remote-debugging-port", "Specify port for Qt remote debugging", 30333, true };
const command_line::arg_descriptor<std::string> arg_remote_node = { "remote-node", "Switch GUI to work with remote node instead of local daemon", "", true };
const command_line::arg_descriptor<bool> arg_enable_qt_logs = { "enable-qt-logs", "Forward Qt log messages into main log", false, true };
void wallet_lock_time_watching_policy::watch_lock_time(uint64_t lock_time)
{
@ -66,6 +68,13 @@ daemon_backend::~daemon_backend()
stop();
}
void terminate_handler_func()
{
LOG_ERROR("\n\nTERMINATE HANDLER\n"); // should print callstack
std::fflush(nullptr); // all open output streams are flushed
std::abort(); // default terminate handler's behavior
}
bool daemon_backend::init(int argc, char* argv[], view::i_view* pview_handler)
{
m_stop_singal_sent = false;
@ -88,6 +97,9 @@ bool daemon_backend::init(int argc, char* argv[], view::i_view* pview_handler)
// setup custom callstack retrieving function
epee::misc_utils::get_callstack(tools::get_callstack);
// setup custom terminate functions
std::set_terminate(&terminate_handler_func);
//#if !defined(NDEBUG)
// log_space::log_singletone::add_logger(LOGGER_DEBUGGER, nullptr, nullptr);
//#endif
@ -114,9 +126,7 @@ bool daemon_backend::init(int argc, char* argv[], view::i_view* pview_handler)
command_line::add_arg(desc_cmd_sett, arg_enable_gui_debug_mode);
command_line::add_arg(desc_cmd_sett, arg_qt_remote_debugging_port);
command_line::add_arg(desc_cmd_sett, arg_remote_node);
command_line::add_arg(desc_cmd_sett, arg_enable_qt_logs);
currency::core::init_options(desc_cmd_sett);
@ -144,8 +154,8 @@ bool daemon_backend::init(int argc, char* argv[], view::i_view* pview_handler)
m_data_dir = command_line::get_arg(m_vm, command_line::arg_data_dir);
std::string config = command_line::get_arg(m_vm, command_line::arg_config_file);
boost::filesystem::path data_dir_path(m_data_dir);
boost::filesystem::path config_path(config);
boost::filesystem::path data_dir_path(epee::string_encoding::utf8_to_wstring(m_data_dir));
boost::filesystem::path config_path(epee::string_encoding::utf8_to_wstring(config));
if (!config_path.has_parent_path())
{
config_path = data_dir_path / config_path;
@ -210,6 +220,8 @@ bool daemon_backend::init(int argc, char* argv[], view::i_view* pview_handler)
// configure for remote node
}
m_qt_logs_enbaled = command_line::get_arg(m_vm, arg_enable_qt_logs);
m_pview->init(path_to_html);
if (!coomand_line_parsed)
@ -383,6 +395,7 @@ bool daemon_backend::deinit_local_daemon()
LOG_PRINT_L0("Deinitializing p2p...");
//dsi.text_state = "Deinitializing p2p";
m_pview->update_daemon_status(dsi);
m_p2psrv.deinit();
m_ccore.set_currency_protocol(NULL);
m_cprotocol.set_p2p_endpoint(NULL);
@ -1118,7 +1131,7 @@ std::string daemon_backend::get_wallet_info(size_t wallet_id, view::wallet_info&
GET_WALLET_OPT_BY_ID(wallet_id, w);
return get_wallet_info(w, wi);
}
std::string daemon_backend::get_contracts(size_t wallet_id, std::vector<tools::wallet_rpc::escrow_contract_details>& contracts)
std::string daemon_backend::get_contracts(size_t wallet_id, std::vector<tools::wallet_public::escrow_contract_details>& contracts)
{
tools::wallet2::escrow_contracts_container cc;
GET_WALLET_OPT_BY_ID(wallet_id, w);
@ -1135,49 +1148,45 @@ std::string daemon_backend::get_contracts(size_t wallet_id, std::vector<tools::w
size_t i = 0;
for (auto& c: cc)
{
static_cast<tools::wallet_rpc::escrow_contract_details_basic&>(contracts[i]) = c.second;
static_cast<tools::wallet_public::escrow_contract_details_basic&>(contracts[i]) = c.second;
contracts[i].contract_id = c.first;
i++;
}
return API_RETURN_CODE_OK;
}
std::string daemon_backend::create_proposal(size_t wallet_id,
const bc_services::contract_private_details& escrow_details,
const std::string& payment_id,
uint64_t expiration_period,
uint64_t fee,
uint64_t b_fee)
std::string daemon_backend::create_proposal(const view::create_proposal_param_gui& cpp)
{
tools::wallet2::escrow_contracts_container cc;
GET_WALLET_OPT_BY_ID(wallet_id, w);
//tools::wallet2::escrow_contracts_container cc;
GET_WALLET_OPT_BY_ID(cpp.wallet_id, w);
try
{
currency::transaction tx = AUTO_VAL_INIT(tx);
currency::transaction template_tx = AUTO_VAL_INIT(template_tx);
w.w->get()->send_escrow_proposal(escrow_details, 0, 0, expiration_period, fee, b_fee, payment_id, tx, template_tx);
w.w->get()->send_escrow_proposal(cpp, tx, template_tx);
//TODO: add some
return API_RETURN_CODE_OK;
}
catch (const tools::error::not_enough_money& e)
{
LOG_ERROR(get_wallet_log_prefix(wallet_id) + "send_escrow_proposal error: API_RETURN_CODE_NOT_ENOUGH_MONEY: " << e.what());
LOG_ERROR(get_wallet_log_prefix(cpp.wallet_id) + "send_escrow_proposal error: API_RETURN_CODE_NOT_ENOUGH_MONEY: " << e.what());
std::string err_code = API_RETURN_CODE_NOT_ENOUGH_MONEY;
return err_code;
}
catch (const std::exception& e)
{
LOG_ERROR(get_wallet_log_prefix(wallet_id) + "send_escrow_proposal error: " << e.what());
LOG_ERROR(get_wallet_log_prefix(cpp.wallet_id) + "send_escrow_proposal error: " << e.what());
std::string err_code = API_RETURN_CODE_INTERNAL_ERROR;
err_code += std::string(":") + e.what();
return err_code;
}
catch (...)
{
LOG_ERROR(get_wallet_log_prefix(wallet_id) + "send_escrow_proposal error: unknown error");
LOG_ERROR(get_wallet_log_prefix(cpp.wallet_id) + "send_escrow_proposal error: unknown error");
return API_RETURN_CODE_INTERNAL_ERROR;
}
}
std::string daemon_backend::accept_proposal(size_t wallet_id, const crypto::hash& contract_id)
{
GET_WALLET_OPT_BY_ID(wallet_id, w);
@ -1287,7 +1296,7 @@ std::string daemon_backend::start_pos_mining(uint64_t wallet_id)
wo.need_to_update_wallet_info = true;
return API_RETURN_CODE_OK;
}
std::string daemon_backend::get_mining_history(uint64_t wallet_id, tools::wallet_rpc::mining_history& mh)
std::string daemon_backend::get_mining_history(uint64_t wallet_id, tools::wallet_public::mining_history& mh)
{
GET_WALLET_OPT_BY_ID(wallet_id, wo);
@ -1410,10 +1419,10 @@ std::string daemon_backend::push_update_offer(const bc_services::update_offer_de
}
}
// std::string daemon_backend::get_all_offers(currency::COMMAND_RPC_GET_ALL_OFFERS::response& od)
// std::string daemon_backend::get_all_offers(currency::COMMAND_RPC_GET_OFFERS_EX::response& od)
// {
// currency::COMMAND_RPC_GET_ALL_OFFERS::request rq = AUTO_VAL_INIT(rq);
// m_rpc_proxy->call_COMMAND_RPC_GET_ALL_OFFERS(rq, od);
// currency::COMMAND_RPC_GET_OFFERS_EX::request rq = AUTO_VAL_INIT(rq);
// m_rpc_proxy->call_COMMAND_RPC_GET_OFFERS_EX(rq, od);
// return API_RETURN_CODE_OK;
// }
@ -1443,7 +1452,7 @@ void daemon_backend::on_new_block(size_t wallet_id, uint64_t /*height*/, const c
}
void daemon_backend::on_transfer2(size_t wallet_id, const tools::wallet_rpc::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined)
void daemon_backend::on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined)
{
view::transfer_event_info tei = AUTO_VAL_INIT(tei);
tei.ti = wti;
@ -1466,7 +1475,7 @@ void daemon_backend::on_sync_progress(size_t wallet_id, const uint64_t& percents
wspp.wallet_id = wallet_id;
m_pview->wallet_sync_progress(wspp);
}
void daemon_backend::on_transfer_canceled(size_t wallet_id, const tools::wallet_rpc::wallet_transfer_info& wti)
void daemon_backend::on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti)
{
view::transfer_event_info tei = AUTO_VAL_INIT(tei);
tei.ti = wti;
@ -1526,7 +1535,7 @@ void daemon_backend::wallet_vs_options::worker_func()
auto w_ptr = *w; // get locked exclusive access to the wallet first (it's more likely that wallet is locked for a long time than 'offers')
auto offers_list_proxy = *offers; // than get locked exclusive access to offers
offers_list_proxy->clear();
(*w_ptr)->get_actual_offers(*offers_list_proxy, false);
(*w_ptr)->get_actual_offers(*offers_list_proxy);
}
wallet_state = wsi.wallet_state = view::wallet_status_info::wallet_state_ready;

View file

@ -8,7 +8,7 @@
#include <boost/program_options.hpp>
#include "warnings.h"
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4100)
DISABLE_VS_WARNINGS(4503)
#include "include_base_utils.h"
@ -30,7 +30,7 @@ using namespace epee;
#include "wallet/wallet2.h"
#include "wallet_id_adapter.h"
POP_WARNINGS
POP_VS_WARNINGS
namespace po = boost::program_options;
@ -90,23 +90,19 @@ public:
std::string run_wallet(uint64_t wallet_id);
std::string get_recent_transfers(size_t wallet_id, uint64_t offset, uint64_t count, view::transfers_array& tr_hist);
std::string get_wallet_info(size_t wallet_id, view::wallet_info& wi);
std::string get_contracts(size_t wallet_id, std::vector<tools::wallet_rpc::escrow_contract_details>& contracts);
std::string create_proposal(size_t wallet_id, const bc_services::contract_private_details& escrow, const std::string& payment_id,
uint64_t expiration_period,
uint64_t fee,
uint64_t b_fee);
std::string get_contracts(size_t wallet_id, std::vector<tools::wallet_public::escrow_contract_details>& contracts);
std::string create_proposal(const view::create_proposal_param_gui& cpp);
std::string accept_proposal(size_t wallet_id, const crypto::hash& contract_id);
std::string release_contract(size_t wallet_id, const crypto::hash& contract_id, const std::string& contract_over_type);
std::string request_cancel_contract(size_t wallet_id, const crypto::hash& contract_id, uint64_t fee, uint64_t expiration_period);
std::string accept_cancel_contract(size_t wallet_id, const crypto::hash& contract_id);
std::string get_wallet_info(wallet_vs_options& w, view::wallet_info& wi);
std::string close_wallet(size_t wallet_id);
std::string push_offer(size_t wallet_id, const bc_services::offer_details_ex& od, currency::transaction& res_tx);
std::string cancel_offer(const view::cancel_offer_param& co, currency::transaction& res_tx);
std::string push_update_offer(const bc_services::update_offer_details& uo, currency::transaction& res_tx);
//std::string get_all_offers(currency::COMMAND_RPC_GET_ALL_OFFERS::response& od);
//std::string get_all_offers(currency::COMMAND_RPC_GET_OFFERS_EX::response& od);
std::string get_offers_ex(const bc_services::core_offers_filter& cof, std::list<bc_services::offer_details_ex>& offers, uint64_t& total_count);
std::string get_aliases(view::alias_set& al_set);
std::string get_alias_info_by_address(const std::string& addr, currency::alias_rpc_details& res_details);
@ -119,7 +115,7 @@ public:
std::string start_pos_mining(uint64_t wallet_id);
std::string stop_pos_mining(uint64_t wallet_id);
std::string check_available_sources(uint64_t wallet_id, std::list<uint64_t>& amounts);
std::string get_mining_history(uint64_t wallet_id, tools::wallet_rpc::mining_history& wrpc);
std::string get_mining_history(uint64_t wallet_id, tools::wallet_public::mining_history& wrpc);
std::string get_wallet_restore_info(uint64_t wallet_id, std::string& restore_key);
std::string backup_wallet(uint64_t wallet_id, const std::wstring& path);
std::string reset_wallet_password(uint64_t wallet_id, const std::string& pass);
@ -142,6 +138,7 @@ public:
void unsubscribe_to_core_events();
void get_gui_options(view::gui_options& opt);
std::string get_wallet_log_prefix(size_t wallet_id) const;
bool is_qt_logs_enabled() const { return m_qt_logs_enbaled; }
private:
void main_worker(const po::variables_map& vm);
@ -157,10 +154,10 @@ private:
static void prepare_wallet_status_info(wallet_vs_options& wo, view::wallet_status_info& wsi);
//----- i_backend_wallet_callback ------
virtual void on_new_block(size_t wallet_id, uint64_t height, const currency::block& block);
virtual void on_transfer2(size_t wallet_id, const tools::wallet_rpc::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined);
virtual void on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined);
virtual void on_pos_block_found(size_t wallet_id, const currency::block& /*block*/);
virtual void on_sync_progress(size_t wallet_id, const uint64_t& /*percents*/);
virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_rpc::wallet_transfer_info& wti);
virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti);
std::thread m_main_worker_thread;
std::atomic<bool> m_stop_singal_sent;
@ -187,6 +184,7 @@ private:
currency::core_rpc_server m_rpc_server;
bool m_remote_node_mode;
bool m_qt_logs_enbaled;
std::atomic<bool> m_is_pos_allowed;

View file

@ -75,14 +75,14 @@ namespace gui_tools
{
namespace fs = boost::filesystem;
char pszPath[MAX_PATH] = "";
wchar_t pszPath[MAX_PATH] = L"";
if (SHGetSpecialFolderPathA(NULL, pszPath, nFolder, fCreate))
if (SHGetSpecialFolderPathW(NULL, pszPath, nFolder, fCreate))
{
return fs::path(pszPath);
}
//LogPrintf("SHGetSpecialFolderPathA() failed, could not obtain requested path.\n");
//LogPrintf("SHGetSpecialFolderPathW() failed, could not obtain requested path.\n");
return fs::path("");
}
#endif

View file

@ -316,12 +316,12 @@ bool MainWindow::load_app_config()
CATCH_ENTRY2(false);
}
bool MainWindow::init(const std::string& htmlPath)
bool MainWindow::init(const std::string& html_path)
{
TRY_ENTRY();
//QtWebEngine::initialize();
init_tray_icon(htmlPath);
set_html_path(htmlPath);
init_tray_icon(html_path);
set_html_path(html_path);
m_backend.subscribe_to_core_events(this);
@ -354,7 +354,7 @@ void MainWindow::on_menu_show()
CATCH_ENTRY2(void());
}
void MainWindow::init_tray_icon(const std::string& htmlPath)
void MainWindow::init_tray_icon(const std::string& html_path)
{
TRY_ENTRY();
if (!QSystemTrayIcon::isSystemTrayAvailable())
@ -384,14 +384,14 @@ void MainWindow::init_tray_icon(const std::string& htmlPath)
//setup icon
#ifdef TARGET_OS_MAC
m_normal_icon_path = htmlPath + "/files/app22macos.png"; // X11 tray icon size is 22x22
m_blocked_icon_path = htmlPath + "/files/app22macos_blocked.png"; // X11 tray icon size is 22x22
m_normal_icon_path = html_path + "/files/app22macos.png"; // X11 tray icon size is 22x22
m_blocked_icon_path = html_path + "/files/app22macos_blocked.png"; // X11 tray icon size is 22x22
#else
m_normal_icon_path = htmlPath + "/files/app22windows.png"; // X11 tray icon size is 22x22
m_blocked_icon_path = htmlPath + "/files/app22windows_blocked.png"; // X11 tray icon size
m_normal_icon_path = html_path + "/files/app22windows.png"; // X11 tray icon size is 22x22
m_blocked_icon_path = html_path + "/files/app22windows_blocked.png"; // X11 tray icon size
#endif
//setWindowIcon(QIcon(iconPath.c_str()));
QIcon qi(m_normal_icon_path.c_str());
QIcon qi( QString::fromWCharArray(epee::string_encoding::utf8_to_wstring(m_normal_icon_path).c_str()) );
qi.setIsMask(true);
m_tray_icon->setIcon(qi);
m_tray_icon->setToolTip(CURRENCY_NAME_BASE);
@ -411,7 +411,7 @@ void MainWindow::bool_toggle_icon(const QString& param)
else
path = m_normal_icon_path;
QIcon qi(path.c_str());
QIcon qi( QString::fromWCharArray(epee::string_encoding::utf8_to_wstring(path).c_str()) );
qi.setIsMask(true);
m_tray_icon->setIcon(qi);
CATCH_ENTRY2(void());
@ -609,10 +609,45 @@ bool MainWindow::show_msg_box(const std::string& message)
return true;
CATCH_ENTRY2(false);
}
void qt_log_message_handler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QByteArray local_msg = msg.toLocal8Bit();
const char* msg_type = "";
switch (type)
{
case QtDebugMsg: msg_type = "DEBG "; break;
case QtInfoMsg: msg_type = "INFO "; break;
case QtWarningMsg: msg_type = "WARN "; break;
case QtCriticalMsg: msg_type = "CRIT "; break;
case QtFatalMsg: msg_type = "FATAL "; break;
}
if (context.file == nullptr && context.function == nullptr)
{
// no debug info
LOG_PRINT("[QT] " << msg_type << local_msg.constData(), LOG_LEVEL_0);
}
else
{
// some debug info
LOG_PRINT("[QT] " << msg_type << local_msg.constData() << " @ " << (context.file ? context.file : "") << ":" << context.line << ", " << (context.function ? context.function : ""), LOG_LEVEL_0);
}
}
bool MainWindow::init_backend(int argc, char* argv[])
{
TRY_ENTRY();
return m_backend.init(argc, argv, this);
if (!m_backend.init(argc, argv, this))
return false;
if (m_backend.is_qt_logs_enabled())
{
qInstallMessageHandler(qt_log_message_handler);
QLoggingCategory::setFilterRules("*=true"); // enable all logs
}
return true;
CATCH_ENTRY2(false);
}
@ -771,7 +806,7 @@ bool MainWindow::set_html_path(const std::string& path)
TRY_ENTRY();
//init_tray_icon(path);
#ifdef _MSC_VER
QString url = QString::fromUtf8(epee::string_encoding::convert_ansii_to_utf8(path).c_str()) + "/index.html";
QString url = QString::fromUtf8(path.c_str()) + "/index.html";
load_file(url);
#else
// load_file(QString((std::string("file://") + path + "/index.html").c_str()));
@ -999,6 +1034,7 @@ void MainWindow::on_complete_events()
}
CATCH_ENTRY2(void());
}
void MainWindow::on_clear_events()
{
TRY_ENTRY();
@ -1020,9 +1056,13 @@ QString MainWindow::get_secure_app_data(const QString& param)
}
std::string app_data_buff;
bool r = file_io_utils::load_file_to_string(m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME, app_data_buff);
std::string filename = m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME;
bool r = file_io_utils::load_file_to_string(filename, app_data_buff);
if (!r)
{
LOG_PRINT_L1("config file was not loaded: " << m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME);
return "";
}
if (app_data_buff.size() < sizeof(app_data_file_binary_header))
{
@ -1037,7 +1077,7 @@ QString MainWindow::get_secure_app_data(const QString& param)
const app_data_file_binary_header* phdr = reinterpret_cast<const app_data_file_binary_header*>(app_data_buff.data());
if (phdr->m_signature != APP_DATA_FILE_BINARY_SIGNATURE)
{
LOG_ERROR("password missmatch: provided pass: " << pwd.pass);
LOG_ERROR("password missmatch");
view::api_response ar;
ar.error_code = API_RETURN_CODE_WRONG_PASSWORD;
return MAKE_RESPONSE(ar);
@ -1045,23 +1085,38 @@ QString MainWindow::get_secure_app_data(const QString& param)
m_master_password = pwd.pass;
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
LOG_PRINT_L0("get_secure_app_data, pass hash: " << master_password_hash);
return app_data_buff.substr(sizeof(app_data_file_binary_header)).c_str();
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
}
QString MainWindow::set_master_password(const QString& param)
{
view::api_response ar;
view::password_data pwd = AUTO_VAL_INIT(pwd);
if (!epee::serialization::load_t_from_json(pwd, param.toStdString()))
{
view::api_response ar;
ar.error_code = API_RETURN_CODE_BAD_ARG;
return MAKE_RESPONSE(ar);
}
if (!currency::validate_password(pwd.pass))
{
ar.error_code = API_RETURN_CODE_BAD_ARG;
return MAKE_RESPONSE(ar);
}
m_master_password = pwd.pass;
view::api_response ar;
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
LOG_PRINT_L0("set_master_password, pass hash: " << master_password_hash);
ar.error_code = API_RETURN_CODE_OK;
return MAKE_RESPONSE(ar);
}
@ -1076,11 +1131,18 @@ QString MainWindow::check_master_password(const QString& param)
ar.error_code = API_RETURN_CODE_BAD_ARG;
return MAKE_RESPONSE(ar);
}
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
crypto::hash pwd_pre_hash = crypto::cn_fast_hash(pwd.pass.c_str(), pwd.pass.length());
crypto::hash pwd_hash = crypto::cn_fast_hash(&pwd_pre_hash, sizeof pwd_pre_hash);
if (m_master_password != pwd.pass)
{
ar.error_code = API_RETURN_CODE_WRONG_PASSWORD;
}else
LOG_PRINT_L0("check_master_password: pwd hash: " << pwd_hash << ", expected: " << master_password_hash);
}
else
{
ar.error_code = API_RETURN_CODE_OK;
}
@ -1099,18 +1161,27 @@ QString MainWindow::store_app_data(const QString& param)
return MAKE_RESPONSE(ar);
}
//bool r = file_io_utils::save_string_to_file(m_backend.get_config_folder() + "/" + GUI_CONFIG_FILENAME, param.toStdString());
bool r = file_io_utils::save_string_to_file(m_backend.get_config_folder() + "/" + GUI_CONFIG_FILENAME, param.toStdString());
//view::api_response ar;
if (r)
ar.error_code = API_RETURN_CODE_OK;
else
ar.error_code = API_RETURN_CODE_FAIL;
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
LOG_PRINT_L0("store_app_data, pass hash: " << master_password_hash);
std::string filename = m_backend.get_config_folder() + "/" + GUI_CONFIG_FILENAME;
bool r = file_io_utils::save_string_to_file(filename, param.toStdString());
if (r)
{
ar.error_code = API_RETURN_CODE_OK;
LOG_PRINT_L1("config saved: " << filename);
}
else
{
ar.error_code = API_RETURN_CODE_FAIL;
LOG_PRINT_L1("config save failed: " << filename);
}
//ar.error_code = store_to_file((m_backend.get_config_folder() + "/" + GUI_CONFIG_FILENAME).c_str(), param).toStdString();
return MAKE_RESPONSE(ar);
CATCH_ENTRY_FAIL_API_RESPONCE();
}
QString MainWindow::is_file_exist(const QString& path)
{
TRY_ENTRY();
@ -1123,7 +1194,7 @@ QString MainWindow::is_file_exist(const QString& path)
}
catch (const std::exception& ex)
{
LOG_ERROR("FILED TO STORE TO FILE: " << path.toStdString() << " ERROR:" << ex.what());
LOG_ERROR("failed to check file existance: " << path.toStdString() << " ERROR:" << ex.what());
return QString(API_RETURN_CODE_ALREADY_EXISTS) + ": " + ex.what();
}
@ -1133,6 +1204,7 @@ QString MainWindow::is_file_exist(const QString& path)
}
CATCH_ENTRY2(API_RETURN_CODE_INTERNAL_ERROR);
}
QString MainWindow::store_to_file(const QString& path, const QString& buff)
{
TRY_ENTRY();
@ -1221,6 +1293,10 @@ QString MainWindow::store_secure_app_data(const QString& param)
else
ar.error_code = API_RETURN_CODE_FAIL;
crypto::hash master_password_pre_hash = crypto::cn_fast_hash(m_master_password.c_str(), m_master_password.length());
crypto::hash master_password_hash = crypto::cn_fast_hash(&master_password_pre_hash, sizeof master_password_pre_hash);
LOG_PRINT_L0("store_secure_app_data, r = " << r << ", pass hash: " << master_password_hash);
return MAKE_RESPONSE(ar);
CATCH_ENTRY_FAIL_API_RESPONCE();
}
@ -1232,7 +1308,7 @@ QString MainWindow::have_secure_app_data()
view::api_response ar = AUTO_VAL_INIT(ar);
boost::system::error_code ec;
if (boost::filesystem::exists(m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME, ec))
if (boost::filesystem::exists(epee::string_encoding::utf8_to_wstring(m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME), ec))
ar.error_code = API_RETURN_CODE_TRUE;
else
ar.error_code = API_RETURN_CODE_FALSE;
@ -1240,6 +1316,7 @@ QString MainWindow::have_secure_app_data()
return MAKE_RESPONSE(ar);
CATCH_ENTRY_FAIL_API_RESPONCE();
}
QString MainWindow::drop_secure_app_data()
{
TRY_ENTRY();
@ -1247,13 +1324,14 @@ QString MainWindow::drop_secure_app_data()
view::api_response ar = AUTO_VAL_INIT(ar);
boost::system::error_code ec;
if (boost::filesystem::remove(m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME, ec))
if (boost::filesystem::remove(epee::string_encoding::utf8_to_wstring(m_backend.get_config_folder() + "/" + GUI_SECURE_CONFIG_FILENAME), ec))
ar.error_code = API_RETURN_CODE_TRUE;
else
ar.error_code = API_RETURN_CODE_FALSE;
return MAKE_RESPONSE(ar);
CATCH_ENTRY_FAIL_API_RESPONCE();
}
QString MainWindow::get_all_aliases()
{
TRY_ENTRY();
@ -1333,7 +1411,7 @@ QString MainWindow::get_log_level(const QString& param)
// return MAKE_RESPONSE(ar);
// }
//
// currency::COMMAND_RPC_GET_ALL_OFFERS::response rp = AUTO_VAL_INIT(rp);
// currency::COMMAND_RPC_GET_OFFERS_EX::response rp = AUTO_VAL_INIT(rp);
// ar.error_code = m_backend.get_all_offers(rp);
//
// std::string buff = epee::serialization::store_t_to_json(rp);
@ -1422,7 +1500,7 @@ QString MainWindow::get_contracts(const QString& param)
TRY_ENTRY();
LOG_API_TIMING();
PREPARE_ARG_FROM_JSON(view::wallet_id_obj, owd);
PREPARE_RESPONSE(view::contracts_array, ar);
PREPARE_RESPONSE(tools::wallet_public::contracts_array, ar);
ar.error_code = m_backend.get_contracts(owd.wallet_id, ar.response_data.contracts);
return MAKE_RESPONSE(ar);
@ -1433,16 +1511,14 @@ QString MainWindow::create_proposal(const QString& param)
{
TRY_ENTRY();
LOG_API_TIMING();
PREPARE_ARG_FROM_JSON(view::create_proposal_param, cpp);
PREPARE_RESPONSE(view::contracts_array, ar);
ar.error_code = m_backend.create_proposal(cpp.wallet_id, cpp.details, cpp.payment_id, cpp.expiration_period, cpp.fee, cpp.b_fee);
PREPARE_ARG_FROM_JSON(view::create_proposal_param_gui, cpp);
PREPARE_RESPONSE(tools::wallet_public::contracts_array, ar);
ar.error_code = m_backend.create_proposal(cpp);
return MAKE_RESPONSE(ar);
CATCH_ENTRY_FAIL_API_RESPONCE();
}
QString MainWindow::accept_proposal(const QString& param)
{
TRY_ENTRY();
@ -1459,7 +1535,7 @@ QString MainWindow::release_contract(const QString& param)
{
TRY_ENTRY();
LOG_API_TIMING();
PREPARE_ARG_FROM_JSON(view::accept_proposal_param, rcp);
PREPARE_ARG_FROM_JSON(view::release_contract_param, rcp);
PREPARE_RESPONSE(view::api_void, ar);
ar.error_code = m_backend.release_contract(rcp.wallet_id, rcp.contract_id, rcp.release_type);
@ -1536,7 +1612,7 @@ QString MainWindow::get_my_offers(const QString& param)
LOG_API_TIMING();
//return que_call2<view::open_wallet_request>("open_wallet", param, [this](const view::open_wallet_request& owd, view::api_response& ar){
PREPARE_ARG_FROM_JSON(bc_services::core_offers_filter, f);
PREPARE_RESPONSE(currency::COMMAND_RPC_GET_ALL_OFFERS::response, ar);
PREPARE_RESPONSE(currency::COMMAND_RPC_GET_OFFERS_EX::response, ar);
ar.error_code = m_backend.get_my_offers(f, ar.response_data.offers);
return MAKE_RESPONSE(ar);
CATCH_ENTRY_FAIL_API_RESPONCE();
@ -1546,7 +1622,7 @@ QString MainWindow::get_fav_offers(const QString& param)
TRY_ENTRY();
LOG_API_TIMING();
PREPARE_ARG_FROM_JSON(view::get_fav_offers_request, f);
PREPARE_RESPONSE(currency::COMMAND_RPC_GET_ALL_OFFERS::response, ar);
PREPARE_RESPONSE(currency::COMMAND_RPC_GET_OFFERS_EX::response, ar);
ar.error_code = m_backend.get_fav_offers(f.ids, f.filter, ar.response_data.offers);
return MAKE_RESPONSE(ar);
CATCH_ENTRY_FAIL_API_RESPONCE();
@ -1589,7 +1665,7 @@ QString MainWindow::get_offers_ex(const QString& param)
LOG_API_TIMING();
//return que_call2<bc_services::core_offers_filter>("get_offers_ex", param, [this](const bc_services::core_offers_filter& f, view::api_response& ar){
PREPARE_ARG_FROM_JSON(bc_services::core_offers_filter, f);
PREPARE_RESPONSE(currency::COMMAND_RPC_GET_ALL_OFFERS::response, ar);
PREPARE_RESPONSE(currency::COMMAND_RPC_GET_OFFERS_EX::response, ar);
ar.error_code = m_backend.get_offers_ex(f, ar.response_data.offers, ar.response_data.total_offers);
return MAKE_RESPONSE(ar);
CATCH_ENTRY_FAIL_API_RESPONCE();
@ -1604,7 +1680,6 @@ QString MainWindow::push_offer(const QString& param)
PREPARE_ARG_FROM_JSON(view::push_offer_param, a);
PREPARE_RESPONSE(view::transfer_response, ar);
currency::transaction res_tx = AUTO_VAL_INIT(res_tx);
ar.error_code = m_backend.push_offer(a.wallet_id, a.od, res_tx);
@ -1683,7 +1758,7 @@ QString MainWindow::get_mining_history(const QString& param)
LOG_API_TIMING();
//return prepare_call<view::wallet_id_obj, tools::wallet_rpc::mining_history>("get_mining_history", param, [this](const view::wallet_id_obj& a, view::api_response& ar) {
PREPARE_ARG_FROM_JSON(view::wallet_id_obj, a);
PREPARE_RESPONSE(tools::wallet_rpc::mining_history, ar);
PREPARE_RESPONSE(tools::wallet_public::mining_history, ar);
ar.error_code = m_backend.get_mining_history(a.wallet_id, ar.response_data);
if (ar.error_code != API_RETURN_CODE_OK)

View file

@ -11,16 +11,16 @@
#ifndef Q_MOC_RUN
#include "warnings.h"
PUSH_WARNINGS
PUSH_VS_WARNINGS
DISABLE_VS_WARNINGS(4100)
DISABLE_VS_WARNINGS(4503)
#include "serialization/keyvalue_serialization.h"
#include "storages/portable_storage_template_helper.h"
#include "rpc/core_rpc_server_commands_defs.h"
#include "wallet/wallet_rpc_server_commans_defs.h"
#include "wallet/wallet_public_structs_defs.h"
#include "currency_core/offers_services_helpers.h"
#include "currency_core/basic_api_response_codes.h"
POP_WARNINGS
POP_VS_WARNINGS
#endif
@ -340,7 +340,7 @@ public:
struct transfer_event_info
{
tools::wallet_rpc::wallet_transfer_info ti;
tools::wallet_public::wallet_transfer_info ti;
uint64_t unlocked_balance;
uint64_t balance;
uint64_t total_mined;
@ -357,8 +357,8 @@ public:
struct transfers_array
{
std::vector<tools::wallet_rpc::wallet_transfer_info> unconfirmed;
std::vector<tools::wallet_rpc::wallet_transfer_info> history;
std::vector<tools::wallet_public::wallet_transfer_info> unconfirmed;
std::vector<tools::wallet_public::wallet_transfer_info> history;
uint64_t total_history_items;
BEGIN_KV_SERIALIZE_MAP()
@ -439,16 +439,6 @@ public:
};
struct contracts_array
{
std::vector<tools::wallet_rpc::escrow_contract_details> contracts;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(contracts)
END_KV_SERIALIZE_MAP()
};
struct header_entry
{
std::string field;
@ -583,24 +573,6 @@ public:
};
struct create_proposal_param
{
uint64_t wallet_id;
bc_services::contract_private_details details;
std::string payment_id;
uint64_t expiration_period;
uint64_t fee;
uint64_t b_fee;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(wallet_id)
KV_SERIALIZE(details)
KV_SERIALIZE(payment_id)
KV_SERIALIZE(expiration_period)
KV_SERIALIZE(fee)
KV_SERIALIZE(b_fee)
END_KV_SERIALIZE_MAP()
};
struct wallet_and_contract_id_param
{
@ -614,7 +586,7 @@ public:
END_KV_SERIALIZE_MAP()
};
struct accept_proposal_param : public wallet_and_contract_id_param
struct release_contract_param : public wallet_and_contract_id_param
{
std::string release_type;
@ -644,7 +616,16 @@ public:
KV_SERIALIZE(expiration_period)
KV_CHAIN_BASE(contract_and_fee_param)
END_KV_SERIALIZE_MAP()
};
struct create_proposal_param_gui : public tools::wallet_public::create_proposal_param
{
uint64_t wallet_id;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(wallet_id)
KV_CHAIN_BASE(tools::wallet_public::create_proposal_param)
END_KV_SERIALIZE_MAP()
};
struct address_validation_response

View file

@ -12,10 +12,10 @@ class i_backend_wallet_callback
{
public:
virtual void on_new_block(size_t wallet_id, uint64_t /*height*/, const currency::block& /*block*/) {}
virtual void on_transfer2(size_t wallet_id, const tools::wallet_rpc::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) {}
virtual void on_transfer2(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) {}
virtual void on_pos_block_found(size_t wallet_id, const currency::block& /*block*/) {}
virtual void on_sync_progress(size_t wallet_id, const uint64_t& /*percents*/) {}
virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_rpc::wallet_transfer_info& wti) {}
virtual void on_transfer_canceled(size_t wallet_id, const tools::wallet_public::wallet_transfer_info& wti) {}
};
struct i_wallet_to_i_backend_adapter: public tools::i_wallet2_callback
@ -27,7 +27,7 @@ struct i_wallet_to_i_backend_adapter: public tools::i_wallet2_callback
virtual void on_new_block(uint64_t height, const currency::block& block) {
m_pbackend->on_new_block(m_wallet_id, height, block);
}
virtual void on_transfer2(const tools::wallet_rpc::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) {
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) {
m_pbackend->on_transfer2(m_wallet_id, wti, balance, unlocked_balance, total_mined);
}
virtual void on_pos_block_found(const currency::block& wti) {
@ -36,7 +36,7 @@ struct i_wallet_to_i_backend_adapter: public tools::i_wallet2_callback
virtual void on_sync_progress(const uint64_t& progress) {
m_pbackend->on_sync_progress(m_wallet_id, progress);
}
virtual void on_transfer_canceled(const tools::wallet_rpc::wallet_transfer_info& wti) {
virtual void on_transfer_canceled(const tools::wallet_public::wallet_transfer_info& wti) {
m_pbackend->on_transfer_canceled(m_wallet_id, wti);
}
private:

View file

@ -150,6 +150,14 @@
"TIME3": "1 hour",
"TIME4": "Never"
},
"LANGUAGE": {
"TITLE": "Languages",
"EN": "English",
"FR": "French",
"DE": "Deutsch",
"IT": "Italian",
"PT": "Portuguese"
},
"MASTER_PASSWORD": {
"TITLE": "Update master password",
"OLD": "Old password",
@ -172,6 +180,7 @@
"AVAILABLE_BALANCE": "Available <b>{{available}} {{currency}}<b/>",
"LOCKED_BALANCE": "Locked <b>{{locked}} {{currency}}<b/>",
"LOCKED_BALANCE_LINK": "What does that mean?",
"CLOSE_MESSAGE": "<span class=\"message\">Remove wallet from the list</span> <br> <span>(To access it youll have to add it again)</span>",
"TABS": {
"SEND": "Send",
"RECEIVE": "Receive",
@ -179,6 +188,12 @@
"CONTRACTS": "Contracts",
"MESSAGES": "Messages",
"STAKING": "Staking"
},
"TOOLTIPS": {
"EDIT_ALIAS": "Edit alias",
"TRANSFER_ALIAS": "Transfer alias",
"SETTINGS": "Settings",
"CLOSE": "Close wallet"
}
},
"WALLET_DETAILS": {
@ -453,7 +468,8 @@
"ERROR": "Error",
"SUCCESS": "Success",
"INFO": "Information",
"OK": "OK"
"OK": "OK",
"CANCEL": "Cancel"
},
"CONFIRM": {
"BUTTON_CONFIRM": "Send",

View file

@ -1,19 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
<!-- Generator: Adobe Illustrator 23.0.5, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st0{fill:#42A5F5;}
</style>
<title>icons_5</title>
<g id="f31d9964-f67b-451c-9eb6-78b833647305">
<path class="st0" d="M299.9,197.6c9.3-16.7,14.2-35.5,14.1-54.6c0-70-43.4-105-97-105s-97,35-97,105c-0.1,19.1,4.8,38,14.2,54.6
C89.2,218.8,68.5,274.1,50,346l334-0.1C365.5,274,344.8,218.8,299.9,197.6z M178.1,94c11.6-11.6,27.6-14,38.9-14s27.3,2.4,38.9,14
c13.3,13.2,16.1,34,16.1,49c0,34.7-24.7,63-55,63s-55-28.3-55-63C162,115.7,170.7,101.3,178.1,94z M128.8,256.5
c10.1-14.3,21.1-22.1,36.1-25c31.4,22,73.1,22,104.5-0.1c14.9,2.9,25.9,10.8,35.9,25c8.9,12.6,16.3,29.3,22.7,47.5L106.1,304
C112.5,285.8,119.9,269.1,128.8,256.5z"/>
<path class="st0" d="M32.5,261H0v42h18.2C23,287,27.6,273.3,32.5,261z"/>
<path class="st0" d="M83,182c-0.9-3.6-1.7-7.3-2.4-11H0v42h56.8C64.2,201.6,73,191.2,83,182z"/>
<path class="st0" d="M88.8,81H0v42h79C80.4,108.6,83.7,94.5,88.8,81z"/>
</g>
<path class="st0" d="M299.8688965,197.5991211C309.2000122,180.9190063,314.0674133,162.1126099,314,143c0-70-43.4283447-105-97-105
s-97,35-97,105c-0.067482,19.1287231,4.8083801,37.9504089,14.1549072,54.6403809
C89.2226563,218.8474121,68.4660568,274.09021,50,346l334-0.0964355
C365.5390625,274.013916,344.7792969,218.8364258,299.8688965,197.5991211z M178.0637207,93.9938965
C189.6651611,82.4277267,205.6410065,80,217,80s27.3348389,2.4277267,38.9362793,13.9938965
C269.2130127,107.2301025,272,127.9494629,272,143c0,34.7382813-24.6730042,63-55,63s-55-28.2617188-55-63
C162,115.7322998,170.7354736,101.2995605,178.0637207,93.9938965z M128.7593994,256.5493164
c10.1036377-14.295166,21.1329346-22.1210938,36.0562744-25.0251465
c31.352066,21.9882507,73.1230164,21.9658966,104.4515381-0.0559082
c14.8673096,2.9362793,25.869751,10.7570801,35.944458,24.9881592
c8.9063721,12.5805664,16.3375244,29.3043213,22.7064209,47.4633789l-221.8294678,0.0639954
C112.4510498,285.8366699,119.87146,269.1243896,128.7593994,256.5493164z"/>
<path class="st0" d="M32.4565392,261H0v42h18.2427998C22.95117,287.0407715,27.6054707,273.2824707,32.4565392,261z"/>
<path class="st0" d="M82.9628906,181.9945068C82.0220032,178.3674316,81.2279968,174.6973877,80.5518799,171H0v42h56.8131104
C64.2091751,201.6196442,72.9933243,191.2043915,82.9628906,181.9945068z"/>
<path class="st0" d="M88.7985764,81H0v42h78.9995117C80.3876266,108.6271896,83.6829224,94.5031357,88.7985764,81z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because one or more lines are too long

View file

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g id="logout">
<polygon class="st0" points="68.5,0 68.5,90 110.5,90 110.5,42 341.5,42 341.5,342 110.5,342 110.5,294 68.5,294 68.5,384
383.5,384 383.5,0 "/>
<polygon class="st0" points="194.5,270 282,192 194.5,114.5 194.5,171 0,171 0,213 194.5,213 "/>
</g>
<svg id="ab50e553-f2b3-4433-b3ff-0d9613f08375" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 383.5 384">
<defs>
<style>
.ecae9e89-1a50-4e7d-886b-c0873462098f {
fill: #42a5f5;
}
</style>
</defs>
<title>exit</title>
<g id="be098581-bbc7-4930-ae81-d0f1e45068cd" data-name="logout">
<polygon class="ecae9e89-1a50-4e7d-886b-c0873462098f" points="68.5 0 68.5 90 110.5 90 110.5 42 341.5 42 341.5 342 110.5 342 110.5 294 68.5 294 68.5 384 383.5 384 383.5 0 68.5 0"/>
<polygon class="ecae9e89-1a50-4e7d-886b-c0873462098f" points="185.5 270 273 192 185.5 114.5 185.5 171 0 171 0 213 185.5 213 185.5 270"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 672 B

After

Width:  |  Height:  |  Size: 676 B

View file

@ -1,17 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g id="settings">
<path class="st0" d="M384,213.3v-42.7h-65.9c-3.1-18.9-10.4-37-21.3-52.7l46.5-46.5l-30.5-30.3L266,87.7
c-15.7-11-33.8-18.3-52.7-21.3V0h-42.7v65.9c-18.9,3.1-37,10.4-52.7,21.3L71.3,41.2L41.2,71.3L87.7,118
c-11,15.7-18.3,33.8-21.3,52.7H0v42.7h65.9c3.1,18.9,10.4,37,21.3,52.7l-46.1,46.7l30.1,30.1l46.5-46.5
c15.7,11,33.8,18.3,52.7,21.3V384h42.7v-65.9c18.9-3.1,37-10.4,52.7-21.3l46.5,46.5l30.1-30.1l-46.5-46.5
c11-15.7,18.3-33.8,21.3-52.7H384V213.3z M102.6,192c0-49.4,40-89.4,89.4-89.4s89.4,40,89.4,89.4s-40,89.4-89.4,89.4
C142.7,281.3,102.7,241.3,102.6,192z"/>
<circle class="st0" cx="192" cy="192" r="41"/>
</g>
<svg id="a22f0928-30d8-4699-903e-959bbb5157b6" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384.00001 384.00001">
<defs>
<style>
.b2acf0b3-a12d-45f7-a117-55ab824eefa9 {
fill: #42a5f5;
}
</style>
</defs>
<title>settings</title>
<g id="aa4a36a4-78af-43f5-b1fa-6aab82396505" data-name="settings">
<path class="b2acf0b3-a12d-45f7-a117-55ab824eefa9" d="M384,213.33334V170.66667H318.08a127.9996,127.9996,0,0,0-21.33334-52.69334l46.50668-46.50667L312.74667,41.17333,266.02668,87.68a128.00008,128.00008,0,0,0-52.69334-21.33334V0H170.66667V65.92a128,128,0,0,0-52.69334,21.33333l-46.72-46.08-30.08,30.08,46.50668,46.72a128.00014,128.00014,0,0,0-21.33334,52.69334H0v42.66667H65.92a127.99993,127.99993,0,0,0,21.33333,52.69334l-46.08,46.72,30.08,30.08L117.76,296.32a127.99957,127.99957,0,0,0,52.69335,21.33333V384H213.12V318.08a127.99949,127.99949,0,0,0,52.69334-21.33334L312.32,343.25335l30.08-30.08-46.50668-46.50667a127.99973,127.99973,0,0,0,21.33334-52.69334H384ZM102.61334,192A89.38668,89.38668,0,1,1,192,281.38669,89.38664,89.38664,0,0,1,102.61334,192Z" transform="translate(0 0)"/>
<circle class="b2acf0b3-a12d-45f7-a117-55ab824eefa9" cx="192.00001" cy="192.00001" r="40.99999"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -873,7 +873,7 @@ input[type='checkbox'].style-checkbox {
}
}
app-modal-container {
app-modal-container, app-confirm-modal {
.modal {

View file

@ -1,19 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
<!-- Generator: Adobe Illustrator 23.0.5, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st0{fill:#42A5F5;}
</style>
<title>icons_5</title>
<g id="f31d9964-f67b-451c-9eb6-78b833647305">
<path class="st0" d="M299.9,197.6c9.3-16.7,14.2-35.5,14.1-54.6c0-70-43.4-105-97-105s-97,35-97,105c-0.1,19.1,4.8,38,14.2,54.6
C89.2,218.8,68.5,274.1,50,346l334-0.1C365.5,274,344.8,218.8,299.9,197.6z M178.1,94c11.6-11.6,27.6-14,38.9-14s27.3,2.4,38.9,14
c13.3,13.2,16.1,34,16.1,49c0,34.7-24.7,63-55,63s-55-28.3-55-63C162,115.7,170.7,101.3,178.1,94z M128.8,256.5
c10.1-14.3,21.1-22.1,36.1-25c31.4,22,73.1,22,104.5-0.1c14.9,2.9,25.9,10.8,35.9,25c8.9,12.6,16.3,29.3,22.7,47.5L106.1,304
C112.5,285.8,119.9,269.1,128.8,256.5z"/>
<path class="st0" d="M32.5,261H0v42h18.2C23,287,27.6,273.3,32.5,261z"/>
<path class="st0" d="M83,182c-0.9-3.6-1.7-7.3-2.4-11H0v42h56.8C64.2,201.6,73,191.2,83,182z"/>
<path class="st0" d="M88.8,81H0v42h79C80.4,108.6,83.7,94.5,88.8,81z"/>
</g>
<path class="st0" d="M299.8688965,197.5991211C309.2000122,180.9190063,314.0674133,162.1126099,314,143c0-70-43.4283447-105-97-105
s-97,35-97,105c-0.067482,19.1287231,4.8083801,37.9504089,14.1549072,54.6403809
C89.2226563,218.8474121,68.4660568,274.09021,50,346l334-0.0964355
C365.5390625,274.013916,344.7792969,218.8364258,299.8688965,197.5991211z M178.0637207,93.9938965
C189.6651611,82.4277267,205.6410065,80,217,80s27.3348389,2.4277267,38.9362793,13.9938965
C269.2130127,107.2301025,272,127.9494629,272,143c0,34.7382813-24.6730042,63-55,63s-55-28.2617188-55-63
C162,115.7322998,170.7354736,101.2995605,178.0637207,93.9938965z M128.7593994,256.5493164
c10.1036377-14.295166,21.1329346-22.1210938,36.0562744-25.0251465
c31.352066,21.9882507,73.1230164,21.9658966,104.4515381-0.0559082
c14.8673096,2.9362793,25.869751,10.7570801,35.944458,24.9881592
c8.9063721,12.5805664,16.3375244,29.3043213,22.7064209,47.4633789l-221.8294678,0.0639954
C112.4510498,285.8366699,119.87146,269.1243896,128.7593994,256.5493164z"/>
<path class="st0" d="M32.4565392,261H0v42h18.2427998C22.95117,287.0407715,27.6054707,273.2824707,32.4565392,261z"/>
<path class="st0" d="M82.9628906,181.9945068C82.0220032,178.3674316,81.2279968,174.6973877,80.5518799,171H0v42h56.8131104
C64.2091751,201.6196442,72.9933243,191.2043915,82.9628906,181.9945068z"/>
<path class="st0" d="M88.7985764,81H0v42h78.9995117C80.3876266,108.6271896,83.6829224,94.5031357,88.7985764,81z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View file

@ -1,31 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#SVGID_1_);}
.st1{fill:url(#SVGID_2_);}
.st2{fill:url(#SVGID_3_);}
</style>
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="512.55" y1="984.3" x2="512.55" y2="39.3" gradientTransform="matrix(1 0 0 -1 0 1024)">
<stop offset="0" style="stop-color:#1ECED0"/>
<stop offset="0.5" style="stop-color:#8AA9F4"/>
<stop offset="1" style="stop-color:#6A44FB"/>
</linearGradient>
<polygon class="st0" points="679.6,984.7 193.5,305.1 344.4,39.7 831.6,715.3 "/>
<linearGradient id="SVGID_2_" gradientUnits="userSpaceOnUse" x1="217.75" y1="700.86" x2="217.75" y2="382.2152" gradientTransform="matrix(1 0 0 -1 0 1024)">
<stop offset="0" style="stop-color:#57B7E3"/>
<stop offset="1" style="stop-color:#7E8AF4;stop-opacity:0"/>
</linearGradient>
<polygon class="st1" points="193.5,305.1 435.5,643.4 0,643.4 "/>
<linearGradient id="SVGID_3_" gradientUnits="userSpaceOnUse" x1="807.25" y1="332.3745" x2="807.25" y2="641.9303" gradientTransform="matrix(1 0 0 -1 0 1024)">
<stop offset="0" style="stop-color:#7C83F4"/>
<stop offset="1" style="stop-color:#68B0E9;stop-opacity:0"/>
</linearGradient>
<polygon class="st2" points="831.6,715.3 590.5,381 1024,381 "/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g id="logout">
<polygon class="st0" points="68.5,0 68.5,90 110.5,90 110.5,42 341.5,42 341.5,342 110.5,342 110.5,294 68.5,294 68.5,384
383.5,384 383.5,0 "/>
<polygon class="st0" points="194.5,270 282,192 194.5,114.5 194.5,171 0,171 0,213 194.5,213 "/>
</g>
<svg id="ab50e553-f2b3-4433-b3ff-0d9613f08375" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 383.5 384">
<defs>
<style>
.ecae9e89-1a50-4e7d-886b-c0873462098f {
fill: #42a5f5;
}
</style>
</defs>
<title>exit</title>
<g id="be098581-bbc7-4930-ae81-d0f1e45068cd" data-name="logout">
<polygon class="ecae9e89-1a50-4e7d-886b-c0873462098f" points="68.5 0 68.5 90 110.5 90 110.5 42 341.5 42 341.5 342 110.5 342 110.5 294 68.5 294 68.5 384 383.5 384 383.5 0 68.5 0"/>
<polygon class="ecae9e89-1a50-4e7d-886b-c0873462098f" points="185.5 270 273 192 185.5 114.5 185.5 171 0 171 0 213 185.5 213 185.5 270"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 672 B

After

Width:  |  Height:  |  Size: 676 B

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -5800,8 +5800,8 @@ __webpack_require__.r(__webpack_exports__);
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
__webpack_require__(/*! d:\Projects\zano\src\gui\qt-daemon\html_source\src\polyfills.ts */"./src/polyfills.ts");
module.exports = __webpack_require__(/*! d:\Projects\zano\src\gui\qt-daemon\html_source\node_modules\@angular-devkit\build-angular\src\angular-cli-files\models\jit-polyfills.js */"./node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/jit-polyfills.js");
__webpack_require__(/*! D:\Projects\zano\src\gui\qt-daemon\html_source\src\polyfills.ts */"./src/polyfills.ts");
module.exports = __webpack_require__(/*! D:\Projects\zano\src\gui\qt-daemon\html_source\node_modules\@angular-devkit\build-angular\src\angular-cli-files\models\jit-polyfills.js */"./node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/jit-polyfills.js");
/***/ })

View file

@ -1,17 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g id="settings">
<path class="st0" d="M384,213.3v-42.7h-65.9c-3.1-18.9-10.4-37-21.3-52.7l46.5-46.5l-30.5-30.3L266,87.7
c-15.7-11-33.8-18.3-52.7-21.3V0h-42.7v65.9c-18.9,3.1-37,10.4-52.7,21.3L71.3,41.2L41.2,71.3L87.7,118
c-11,15.7-18.3,33.8-21.3,52.7H0v42.7h65.9c3.1,18.9,10.4,37,21.3,52.7l-46.1,46.7l30.1,30.1l46.5-46.5
c15.7,11,33.8,18.3,52.7,21.3V384h42.7v-65.9c18.9-3.1,37-10.4,52.7-21.3l46.5,46.5l30.1-30.1l-46.5-46.5
c11-15.7,18.3-33.8,21.3-52.7H384V213.3z M102.6,192c0-49.4,40-89.4,89.4-89.4s89.4,40,89.4,89.4s-40,89.4-89.4,89.4
C142.7,281.3,102.7,241.3,102.6,192z"/>
<circle class="st0" cx="192" cy="192" r="41"/>
</g>
<svg id="a22f0928-30d8-4699-903e-959bbb5157b6" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384.00001 384.00001">
<defs>
<style>
.b2acf0b3-a12d-45f7-a117-55ab824eefa9 {
fill: #42a5f5;
}
</style>
</defs>
<title>settings</title>
<g id="aa4a36a4-78af-43f5-b1fa-6aab82396505" data-name="settings">
<path class="b2acf0b3-a12d-45f7-a117-55ab824eefa9" d="M384,213.33334V170.66667H318.08a127.9996,127.9996,0,0,0-21.33334-52.69334l46.50668-46.50667L312.74667,41.17333,266.02668,87.68a128.00008,128.00008,0,0,0-52.69334-21.33334V0H170.66667V65.92a128,128,0,0,0-52.69334,21.33333l-46.72-46.08-30.08,30.08,46.50668,46.72a128.00014,128.00014,0,0,0-21.33334,52.69334H0v42.66667H65.92a127.99993,127.99993,0,0,0,21.33333,52.69334l-46.08,46.72,30.08,30.08L117.76,296.32a127.99957,127.99957,0,0,0,52.69335,21.33333V384H213.12V318.08a127.99949,127.99949,0,0,0,52.69334-21.33334L312.32,343.25335l30.08-30.08-46.50668-46.50667a127.99973,127.99973,0,0,0,21.33334-52.69334H384ZM102.61334,192A89.38668,89.38668,0,1,1,192,281.38669,89.38664,89.38664,0,0,1,102.61334,192Z" transform="translate(0 0)"/>
<circle class="b2acf0b3-a12d-45f7-a117-55ab824eefa9" cx="192.00001" cy="192.00001" r="40.99999"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,13 @@
<div class="modal">
<div class="content">
<i class="icon info"></i>
<div class="message-container">
<span [innerHTML]="message"></span>
</div>
</div>
<div class="wrap-btn">
<button type="button" class="action-button" (click)="onSubmit()" #btn>{{ 'MODALS.OK' | translate }}</button>
<button type="button" class="action-button" (click)="onClose()">{{ 'MODALS.CANCEL' | translate }}</button>
</div>
<button type="button" class="close-button" (click)="onClose()"><i class="icon close"></i></button>
</div>

View file

@ -0,0 +1,80 @@
:host {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.25);
}
.modal {
position: relative;
display: flex;
flex-direction: column;
background-position: center;
background-size: 200%;
padding: 2rem;
min-width: 34rem;
max-width: 60rem;
.content {
display: flex;
margin: 1.2rem 0;
.icon {
flex: 0 0 auto;
width: 4.4rem;
height: 4.4rem;
&.info {
mask: url(~src/assets/icons/modal-info.svg) no-repeat center;
}
}
.message-container {
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: center;
margin-left: 2rem;
.message {
font-size: 1.3rem;
line-height: 1.8rem;
margin-top: 0.4rem;
}
}
}
.wrap-btn {
display: flex;
}
.action-button {
margin: 1.2rem auto 0.6rem;
width: 10rem;
height: 2.4rem;
}
.close-button {
position: absolute;
top: 0;
right: 0;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
margin: 0;
padding: 0;
width: 2.4rem;
height: 2.4rem;
.icon {
mask: url(~src/assets/icons/close.svg) no-repeat center;
width: 2.4rem;
height: 2.4rem;
}
}
}

View file

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ConfirmModalComponent } from './confirm-modal.component';
describe('ConfirmModalComponent', () => {
let component: ConfirmModalComponent;
let fixture: ComponentFixture<ConfirmModalComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ConfirmModalComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ConfirmModalComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View file

@ -0,0 +1,27 @@
import { Component, OnInit, Input, Output, EventEmitter, ViewChild, ElementRef } from '@angular/core';
@Component({
selector: 'app-confirm-modal',
templateUrl: './confirm-modal.component.html',
styleUrls: ['./confirm-modal.component.scss']
})
export class ConfirmModalComponent implements OnInit {
@Input() message: string;
@Output() confirmed: EventEmitter<boolean> = new EventEmitter<boolean>();
@ViewChild('btn') button: ElementRef;
constructor() { }
ngOnInit() {
this.button.nativeElement.focus();
}
onSubmit() {
this.confirmed.emit(true);
}
onClose() {
this.confirmed.emit(false);
}
}

View file

@ -13,6 +13,7 @@ export class TooltipDirective implements OnDestroy {
@Input() placement: string;
@Input() tooltipClass: string;
@Input() timeout = 0;
@Input() timeDelay = 0;
@Input() delay = 0;
@Input() showWhenNoOverflow = true;
@Output() onHide = new EventEmitter<boolean>();
@ -23,6 +24,8 @@ export class TooltipDirective implements OnDestroy {
removeTooltipTimeout;
removeTooltipTimeoutInner;
removeTooltipTimeDelay;
constructor(private el: ElementRef, private renderer: Renderer2, private route: ActivatedRoute) {
}
@ -30,7 +33,13 @@ export class TooltipDirective implements OnDestroy {
if (this.showWhenNoOverflow || (!this.showWhenNoOverflow && this.el.nativeElement.offsetWidth < this.el.nativeElement.scrollWidth)) {
this.cursor = 'pointer';
if (!this.tooltip) {
this.show();
if (this.timeDelay !== 0) {
this.removeTooltipTimeDelay = setTimeout(() => {
this.show();
}, this.timeDelay);
} else {
this.show();
}
} else {
this.cancelHide();
}
@ -38,6 +47,7 @@ export class TooltipDirective implements OnDestroy {
}
@HostListener('mouseleave') onMouseLeave() {
clearTimeout(this.removeTooltipTimeDelay);
if (this.tooltip) {
this.hide();
}

View file

@ -0,0 +1,8 @@
import { SafeHTMLPipe } from './safe-html.pipe';
describe('SafeHTMLPipe', () => {
it('create an instance', () => {
const pipe = new SafeHTMLPipe();
expect(pipe).toBeTruthy();
});
});

View file

@ -0,0 +1,15 @@
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({
name: 'safeHTML'
})
export class SafeHTMLPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) { }
transform(html: string) {
return this.sanitizer.bypassSecurityTrustHtml(html);
}
}

View file

@ -58,6 +58,8 @@ export class VariablesService {
public contacts: Array<Contact> = [];
public newContact: Contact = {name: null, address: null, notes: null};
public pattern = '^[a-zA-Z0-9_.\\\]\*\|\~\!\?\@\#\$\%\^\&\+\{\}\(\)\<\>\:\;\"\'\-\=\/\,\[\\\\]*$';
getExpMedTsEvent = new BehaviorSubject(null);
getHeightAppEvent = new BehaviorSubject(null);
getHeightMaxEvent = new BehaviorSubject(null);

View file

@ -38,7 +38,7 @@ export class AppComponent implements OnInit, OnDestroy {
private intToMoneyPipe: IntToMoneyPipe,
private modalService: ModalService
) {
translate.addLangs(['en', 'fr']);
translate.addLangs(['en', 'fr', 'de', 'it', 'pt']);
translate.setDefaultLang('en');
// const browserLang = translate.getBrowserLang();
// translate.use(browserLang.match(/en|fr/) ? browserLang : 'en');
@ -62,7 +62,7 @@ export class AppComponent implements OnInit, OnDestroy {
this.translate.instant('BACKEND_LOCALIZATION.TRAY_MENU_SHOW'),
this.translate.instant('BACKEND_LOCALIZATION.TRAY_MENU_MINIMIZE')
];
this.backend.setBackendLocalization(stringsArray, 'en');
this.backend.setBackendLocalization(stringsArray, this.variablesService.settings.language);
} else {
console.warn('wait translate use');
setTimeout(() => {
@ -516,7 +516,7 @@ export class AppComponent implements OnInit, OnDestroy {
this.variablesService.settings.theme = this.variablesService.defaultTheme;
this.renderer.addClass(document.body, 'theme-' + this.variablesService.settings.theme);
}
this.translate.use(this.variablesService.settings.language);
this.setBackendLocalization();
this.backend.setLogLevel(this.variablesService.settings.appLog);

View file

@ -40,6 +40,7 @@ import { IntToMoneyPipe } from './_helpers/pipes/int-to-money.pipe';
import { HistoryTypeMessagesPipe } from './_helpers/pipes/history-type-messages.pipe';
import { ContractStatusMessagesPipe } from './_helpers/pipes/contract-status-messages.pipe';
import { ContractTimeLeftPipe } from './_helpers/pipes/contract-time-left.pipe';
import { SafeHTMLPipe } from './_helpers/pipes/safe-html.pipe';
import { TooltipDirective } from './_helpers/directives/tooltip.directive';
import { InputValidateDirective } from './_helpers/directives/input-validate/input-validate.directive';
import { StakingSwitchComponent } from './_helpers/directives/staking-switch/staking-switch.component';
@ -56,12 +57,14 @@ import { ContactsComponent } from './contacts/contacts.component';
import { AddContactsComponent } from './add-contacts/add-contacts.component';
import { ContactSendComponent } from './contact-send/contact-send.component';
import { ExportImportComponent } from './export-import/export-import.component';
import { ConfirmModalComponent } from './_helpers/directives/confirm-modal/confirm-modal.component';
export function HttpLoaderFactory(httpClient: HttpClient) {
return new TranslateHttpLoader(httpClient, './assets/i18n/', '.json');
}
import { PapaParseModule } from 'ngx-papaparse';
// import * as more from 'highcharts/highcharts-more.src';
// import * as exporting from 'highcharts/modules/exporting.src';
// import * as highstock from 'highcharts/modules/stock.src';
@ -118,7 +121,9 @@ export function highchartsFactory() {
ContactsComponent,
AddContactsComponent,
ContactSendComponent,
ExportImportComponent
ExportImportComponent,
SafeHTMLPipe,
ConfirmModalComponent
],
imports: [
BrowserModule,
@ -148,7 +153,8 @@ export function highchartsFactory() {
],
entryComponents: [
ModalContainerComponent,
SendModalComponent
SendModalComponent,
ConfirmModalComponent
],
bootstrap: [AppComponent]
})

View file

@ -32,6 +32,11 @@
<div class="input-block">
<label for="wallet-password">{{ 'CREATE_WALLET.PASS' | translate }}</label>
<input type="password" id="wallet-password" formControlName="password" [attr.readonly]="walletSaved ? '' : null" (contextmenu)="variablesService.onContextMenuPasteSelect($event)">
<div class="error-block" *ngIf="createForm.controls['password'].dirty && createForm.controls['password'].errors">
<div *ngIf="createForm.controls['password'].errors.pattern">
{{ 'ERRORS.WRONG_PASSWORD' | translate }}
</div>
</div>
</div>
<div class="input-block">

View file

@ -23,7 +23,7 @@ export class CreateWalletComponent implements OnInit {
}
return null;
}]),
password: new FormControl(''),
password: new FormControl('', Validators.pattern(this.variablesService.pattern)),
confirm: new FormControl('')
}, function (g: FormGroup) {
return g.get('password').value === g.get('confirm').value ? null : {'confirm_mismatch': true};

View file

@ -59,16 +59,15 @@ export class HistoryComponent implements OnInit, OnDestroy, AfterViewChecked {
time(item: Transaction) {
const now = new Date().getTime();
const unlockTime = now + ((item.unlock_time - this.variablesService.height_app) * 60 * 1000);
const unlockTime = now + ((item.unlock_time - this.variablesService.height_max) * 60 * 1000);
return unlockTime;
}
isLocked(item: Transaction) {
if ((item.unlock_time > 500000000) && (item.unlock_time > new Date().getTime() / 1000)) {
console.log(new Date().getTime());
return true;
}
if ((item.unlock_time < 500000000) && (item.unlock_time > this.variablesService.height_app)) {
if ((item.unlock_time < 500000000) && (item.unlock_time > this.variablesService.height_max)) {
return true;
}
return false;

View file

@ -2,13 +2,18 @@
<div class="wrap-login">
<div class="logo"></div>
<div class="logo" [innerHTML]="logo | safeHTML"></div>
<form *ngIf="type === 'reg'" class="form-login" [formGroup]="regForm" (ngSubmit)="onSubmitCreatePass()">
<div class="input-block">
<label for="master-pass">{{ 'LOGIN.SETUP_MASTER_PASS' | translate }}</label>
<input type="password" id="master-pass" formControlName="password" (contextmenu)="variablesService.onContextMenuPasteSelect($event)">
<div class="error-block" *ngIf="regForm.controls['password'].dirty && regForm.controls['password'].errors">
<div *ngIf="regForm.controls['password'].errors.pattern">
{{ 'ERRORS.WRONG_PASSWORD' | translate }}
</div>
</div>
</div>
<div class="input-block">
@ -22,7 +27,7 @@
</div>
<div class="wrap-button">
<button type="submit" class="blue-button" [disabled]="!regForm.controls['password'].value.length || !regForm.controls['confirmation'].value.length || (regForm.errors && regForm.errors['mismatch'])">{{ 'LOGIN.BUTTON_NEXT' | translate }}</button>
<button type="submit" class="blue-button" [disabled]="!regForm.controls['password'].value.length || !regForm.controls['confirmation'].value.length || (regForm.errors && regForm.errors['mismatch']) || regForm.controls['password'].errors">{{ 'LOGIN.BUTTON_NEXT' | translate }}</button>
<button type="button" class="blue-button" (click)="onSkipCreatePass()" [disabled]="regForm.controls['password'].value.length || regForm.controls['confirmation'].value.length">{{ 'LOGIN.BUTTON_SKIP' | translate }}</button>
</div>

View file

@ -14,9 +14,12 @@
max-width: 40rem;
.logo {
background: url(../../assets/icons/logo.svg) no-repeat center;
width: 100%;
height: 15rem;
display: flex;
justify-content: center;
&::ng-deep svg {
width: 15rem;
}
}
.form-login {

View file

@ -1,11 +1,13 @@
import {Component, NgZone, OnInit, OnDestroy} from '@angular/core';
import {FormGroup, FormControl} from '@angular/forms';
import {FormGroup, FormControl, Validators} from '@angular/forms';
import {ActivatedRoute, Router} from '@angular/router';
import {BackendService} from '../_helpers/services/backend.service';
import {VariablesService} from '../_helpers/services/variables.service';
import {ModalService} from '../_helpers/services/modal.service';
import {Wallet} from '../_helpers/models/wallet.model';
import icons from '../../assets/icons/icons.json';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
@ -16,11 +18,13 @@ export class LoginComponent implements OnInit, OnDestroy {
queryRouting;
regForm = new FormGroup({
password: new FormControl(''),
password: new FormControl('',
Validators.pattern(this.variablesService.pattern)),
confirmation: new FormControl('')
}, function (g: FormGroup) {
}, [function (g: FormGroup) {
return g.get('password').value === g.get('confirmation').value ? null : {'mismatch': true};
});
}
]);
authForm = new FormGroup({
password: new FormControl('')
@ -28,6 +32,8 @@ export class LoginComponent implements OnInit, OnDestroy {
type = 'reg';
logo = icons.logo;
constructor(
private route: ActivatedRoute,
private router: Router,

View file

@ -32,6 +32,11 @@
<div class="input-block half-block">
<label for="wallet-password">{{ 'RESTORE_WALLET.PASS' | translate }}</label>
<input type="password" id="wallet-password" formControlName="password" [attr.readonly]="walletSaved ? '' : null" (contextmenu)="variablesService.onContextMenuPasteSelect($event)">
<div class="error-block" *ngIf="restoreForm.controls['password'].dirty && restoreForm.controls['password'].errors">
<div *ngIf="restoreForm.controls['password'].errors.pattern">
{{ 'ERRORS.WRONG_PASSWORD' | translate }}
</div>
</div>
</div>
<div class="input-block half-block">

View file

@ -24,7 +24,7 @@ export class RestoreWalletComponent implements OnInit {
return null;
}]),
key: new FormControl('', Validators.required),
password: new FormControl(''),
password: new FormControl('', Validators.pattern(this.variablesService.pattern)),
confirm: new FormControl('')
}, function (g: FormGroup) {
return g.get('password').value === g.get('confirm').value ? null : {'confirm_mismatch': true};

View file

@ -31,6 +31,25 @@
</button>
</div>
<div class="lock-selection">
<label class="lock-selection-title">{{ 'SETTINGS.LANGUAGE.TITLE' | translate }}</label>
<ng-select class="custom-select"
[items]="languagesOptions"
bindValue="name"
bindLabel="language"
[(ngModel)]="variablesService.settings.language"
[clearable]="false"
[searchable]="false"
(change)="onLanguageChange()">
<ng-template ng-label-tmp let-item="item">
{{item.language | translate}}
</ng-template>
<ng-template ng-option-tmp let-item="item" let-index="index">
{{item.language | translate}}
</ng-template>
</ng-select>
</div>
<div class="lock-selection">
<label class="lock-selection-title">{{ 'SETTINGS.APP_LOCK.TITLE' | translate }}</label>
<ng-select class="custom-select"
@ -78,6 +97,11 @@
<div class="input-block">
<label for="new-password">{{ 'SETTINGS.MASTER_PASSWORD.NEW' | translate }}</label>
<input type="password" id="new-password" formControlName="new_password" (contextmenu)="variablesService.onContextMenuPasteSelect($event)"/>
<div class="error-block" *ngIf="changeForm.controls['new_password'].dirty && changeForm.controls['new_password'].errors">
<div *ngIf="changeForm.controls['new_password'].errors.pattern">
{{ 'ERRORS.WRONG_PASSWORD' | translate }}
</div>
</div>
</div>
<div class="input-block">

View file

@ -1,8 +1,9 @@
import {Component, NgZone, OnInit, Renderer2} from '@angular/core';
import {VariablesService} from '../_helpers/services/variables.service';
import {BackendService} from '../_helpers/services/backend.service';
import {FormControl, FormGroup} from '@angular/forms';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {Location} from '@angular/common';
import { TranslateService } from '@ngx-translate/core';
@Component({
selector: 'app-settings',
@ -14,6 +15,28 @@ export class SettingsComponent implements OnInit {
theme: string;
scale: number;
changeForm: any;
languagesOptions = [
{
name: 'en',
language: 'SETTINGS.LANGUAGE.EN'
},
{
name: 'fr',
language: 'SETTINGS.LANGUAGE.FR'
},
{
name: 'de',
language: 'SETTINGS.LANGUAGE.DE'
},
{
name: 'it',
language: 'SETTINGS.LANGUAGE.IT'
},
{
name: 'pt',
language: 'SETTINGS.LANGUAGE.PT'
}
];
appLockOptions = [
{
id: 5,
@ -79,13 +102,14 @@ export class SettingsComponent implements OnInit {
public variablesService: VariablesService,
private backend: BackendService,
private location: Location,
public translate: TranslateService,
private ngZone: NgZone
) {
this.theme = this.variablesService.settings.theme;
this.scale = this.variablesService.settings.scale;
this.changeForm = new FormGroup({
password: new FormControl(''),
new_password: new FormControl(''),
new_password: new FormControl('', Validators.pattern(this.variablesService.pattern)),
new_confirmation: new FormControl('')
}, [(g: FormGroup) => {
return g.get('new_password').value === g.get('new_confirmation').value ? null : {'confirm_mismatch': true};
@ -133,15 +157,14 @@ export class SettingsComponent implements OnInit {
} else {
console.log(data['error_code']);
}
})
});
} else {
this.backend.dropSecureAppData();
}
this.changeForm.reset();
}
}
onLockChange() {
if (this.variablesService.appLogin) {
this.variablesService.restartCountdown();
@ -154,6 +177,11 @@ export class SettingsComponent implements OnInit {
this.backend.storeAppData();
}
onLanguageChange() {
this.translate.use(this.variablesService.settings.language);
this.backend.storeAppData();
}
back() {
this.location.back();
}

View file

@ -38,27 +38,40 @@
</div>
</div>
<div class="sidebar-settings">
<div class="wrap-button" routerLinkActive="active" *ngIf="variablesService.appPass === ''; else contactsShow" tooltip="{{ 'SIDEBAR.CONTACTS_TOOLTIP' | translate }}" placement="top" tooltipClass="table-tooltip account-tooltip" [delay]="500">
<button (click)="contactsRoute()" [class.disabled]="variablesService.daemon_state !== 2 || variablesService.appPass === ''" [disabled]="variablesService.daemon_state !== 2 || variablesService.appPass === ''">
<div class="wrap-button" routerLinkActive="active" *ngIf="variablesService.appPass === ''; else contactsShow" tooltip="{{ 'SIDEBAR.CONTACTS_TOOLTIP' | translate }}" placement="top" tooltipClass="table-tooltip account-tooltip" [delay]="500" [timeDelay]="1500">
<button (click)="contactsRoute()" [class.disabled]="variablesService.daemon_state !== 2 || variablesService.appPass === ''"
[disabled]="variablesService.daemon_state !== 2 || variablesService.appPass === ''">
<i class="icon contacts"></i>
<span>{{ 'SIDEBAR.CONTACTS' | translate }}</span>
</button>
</div>
<ng-template #contactsShow>
<div class="wrap-button" routerLinkActive="active">
<button (click)="contactsRoute()">
<i class="icon contacts"></i>
<button (click)="contactsRoute()"
(mouseover)="menuItem = true"
(mouseleave)="menuItem = false"
>
<i class="icon contacts" *ngIf="!menuItem; else svgContacts"></i>
<ng-template #svgContacts>
<div class="animated" [innerHTML]="contacts | safeHTML"></div>
</ng-template>
<span>{{ 'SIDEBAR.CONTACTS' | translate }}</span>
</button>
</div>
</ng-template>
<div class="wrap-button" routerLinkActive="active">
<button [routerLink]="['/settings']">
<i class="icon settings"></i>
<button [routerLink]="['/settings']"
(mouseover)="menuItemHovered = true"
(mouseleave)="menuItemHovered = false"
>
<i class="icon settings" *ngIf="!menuItemHovered; else svgSetting"></i>
<ng-template #svgSetting>
<div class="animated" [innerHTML]="settings | safeHTML"></div>
</ng-template>
<span>{{ 'SIDEBAR.SETTINGS' | translate }}</span>
</button>
</div>
<div class="wrap-button" *ngIf="variablesService.appPass === ''; else masterPass" tooltip="{{ 'SIDEBAR.LOG_OUT_TOOLTIP' | translate }}" placement="bottom" tooltipClass="table-tooltip account-tooltip" [delay]="500">
<div class="wrap-button" *ngIf="variablesService.appPass === ''; else masterPass" tooltip="{{ 'SIDEBAR.LOG_OUT_TOOLTIP' | translate }}" placement="bottom" tooltipClass="table-tooltip account-tooltip" [delay]="500" [timeDelay]="1500">
<button (click)="logOut()" [class.disabled]="variablesService.appPass === ''" [disabled]="variablesService.appPass === ''">
<i class="icon logout"></i>
<span>{{ 'SIDEBAR.LOG_OUT' | translate }}</span>
@ -66,8 +79,15 @@
</div>
<ng-template #masterPass>
<div class="wrap-button">
<button (click)="logOut()">
<i class="icon logout"></i>
<button
(mouseover)="itemHovered = true"
(mouseleave)="itemHovered = false"
(click)="logOut()">
<i class="icon logout" *ngIf="!itemHovered; else svgLogout"></i>
<ng-template #svgLogout>
<div class="animated" [innerHTML]="exit | safeHTML"></div>
</ng-template>
<span>{{ 'SIDEBAR.LOG_OUT' | translate }}</span>
</button>
</div>

View file

@ -7,6 +7,23 @@
max-width: 25rem;
}
.animated {
display: flex;
justify-content: center;
align-items: center;
margin-right: 1.2rem;
&::ng-deep svg {
width: 2rem;
height: 2rem;
path, circle, polygon {
fill: #4db1ff;
}
}
}
.sidebar-accounts {
position: relative;
display: flex;
@ -204,8 +221,8 @@
.icon {
margin-right: 1.2rem;
width: 1.7rem;
height: 1.7rem;
width: 2rem;
height: 2rem;
&.contacts {
mask: url(../../assets/icons/contacts.svg) no-repeat center;

View file

@ -4,6 +4,8 @@ import {VariablesService} from '../_helpers/services/variables.service';
import {BackendService} from '../_helpers/services/backend.service';
import { ModalService } from '../_helpers/services/modal.service';
import icons from '../../assets/icons/icons.json';
@Component({
selector: 'app-sidebar',
templateUrl: './sidebar.component.html',
@ -14,6 +16,10 @@ export class SidebarComponent implements OnInit, OnDestroy {
walletActive: number;
contacts = icons.contacts;
settings = icons.settings;
exit = icons.exit;
constructor(
private route: ActivatedRoute,
private router: Router,

View file

@ -8,16 +8,16 @@
<div class="alias" *ngIf="variablesService.currentWallet.alias.hasOwnProperty('name') && variablesService.currentWallet.loaded && variablesService.daemon_state === 2">
<span>{{variablesService.currentWallet.alias['name']}}</span>
<ng-container *ngIf="variablesService.currentWallet.alias_available">
<i class="icon edit" [routerLink]="['/edit-alias']"></i>
<i class="icon transfer" [routerLink]="['/transfer-alias']"></i>
<i class="icon edit" [routerLink]="['/edit-alias']" tooltip="{{ 'WALLET.TOOLTIPS.EDIT_ALIAS' | translate }}" placement="bottom-right" tooltipClass="table-tooltip account-tooltip" [delay]="500" [timeDelay]="1500"></i>
<i class="icon transfer" [routerLink]="['/transfer-alias']" tooltip="{{ 'WALLET.TOOLTIPS.TRANSFER_ALIAS' | translate }}" placement="right" tooltipClass="table-tooltip account-tooltip" [delay]="500" [timeDelay]="1500"></i>
</ng-container>
</div>
</div>
<div>
<button [routerLink]="['/details']" routerLinkActive="active">
<button [routerLink]="['/details']" routerLinkActive="active" tooltip="{{ 'WALLET.TOOLTIPS.SETTINGS' | translate }}" placement="left" tooltipClass="table-tooltip account-tooltip" [delay]="500" [timeDelay]="1500">
<i class="icon details"></i>
</button>
<button type="button" (click)="closeWallet()">
<button type="button" (click)="showDialog()" tooltip="{{ 'WALLET.TOOLTIPS.CLOSE' | translate }}" placement="bottom-right" tooltipClass="table-tooltip account-tooltip" [delay]="500" [timeDelay]="1500">
<i class="icon close-wallet"></i>
</button>
</div>
@ -33,8 +33,11 @@
<div class="tabs">
<div class="tabs-header">
<ng-container *ngFor="let tab of tabs; let index = index">
<div class="tab" [class.active]="tab.active" [class.disabled]="(tab.link === '/send' || tab.link === '/contracts' || tab.link === '/staking') && (variablesService.daemon_state !== 2 || !variablesService.currentWallet.loaded)" (click)="changeTab(index)">
<i class="icon" [ngClass]="tab.icon"></i>
<div class="tab" [class.active]="tab.active" [class.disabled]="(tab.link === '/send' || tab.link === '/contracts' || tab.link === '/staking') && (variablesService.daemon_state !== 2 || !variablesService.currentWallet.loaded)" (click)="changeTab(index)" (mouseover)="itemHovered(index, true)" (mouseleave)="itemHovered(index, false)">
<i class="icon" [ngClass]="tab.icon" *ngIf="!tab.itemHovered; else svgAnimated"></i>
<ng-template #svgAnimated>
<div class="animated" [innerHTML]="tab.animated | safeHTML"></div>
</ng-template>
<span>{{ tab.title | translate }}</span>
<span class="indicator" *ngIf="tab.indicator">{{variablesService.currentWallet.new_contracts}}</span>
</div>
@ -45,3 +48,4 @@
</div>
</div>
<app-confirm-modal *ngIf="isModalDialogVisible" [message]=" 'WALLET.CLOSE_MESSAGE' | translate " (confirmed)="confirmed($event)"></app-confirm-modal>

View file

@ -158,10 +158,27 @@
padding: 0 1rem;
height: 5rem;
.animated {
display: flex;
justify-content: center;
align-items: center;
margin-right: 1.3rem;
}
.animated ::ng-deep svg {
width: 2rem;
height: 2rem;
path, circle, polygon {
fill: #4db1ff;
}
}
.icon {
margin-right: 1.3rem;
width: 1.7rem;
height: 1.7rem;
width: 2rem;
height: 2rem;
&.send {
mask: url(../../assets/icons/send.svg) no-repeat center;

View file

@ -6,6 +6,8 @@ import {TranslateService} from '@ngx-translate/core';
import {IntToMoneyPipe} from '../_helpers/pipes/int-to-money.pipe';
import {Subscription} from 'rxjs';
import icons from '../../assets/icons/icons.json';
@Component({
selector: 'app-wallet',
templateUrl: './wallet.component.html',
@ -19,6 +21,7 @@ export class WalletComponent implements OnInit, OnDestroy {
copyAnimation = false;
copyAnimationTimeout;
balanceTooltip;
isModalDialogVisible = false;
@ViewChild('scrolledContent') private scrolledContent: ElementRef;
@ -28,42 +31,54 @@ export class WalletComponent implements OnInit, OnDestroy {
icon: 'history',
link: '/history',
indicator: false,
active: true
active: true,
animated: icons.history,
itemHovered: false
},
{
title: 'WALLET.TABS.SEND',
icon: 'send',
link: '/send',
indicator: false,
active: false
active: false,
animated: icons.send,
itemHovered: false
},
{
title: 'WALLET.TABS.RECEIVE',
icon: 'receive',
link: '/receive',
indicator: false,
active: false
active: false,
animated: icons.receive,
itemHovered: false
},
{
title: 'WALLET.TABS.CONTRACTS',
icon: 'contracts',
link: '/contracts',
indicator: 1,
active: false
active: false,
animated: icons.contracts,
itemHovered: false
},
/*{
title: 'WALLET.TABS.MESSAGES',
icon: 'messages',
link: '/messages',
indicator: 32,
active: false
active: false,
animated: icons.messages,
itemHovered: false
},*/
{
title: 'WALLET.TABS.STAKING',
icon: 'staking',
link: '/staking',
indicator: false,
active: false
active: false,
animated: icons.staking,
itemHovered: false
}
];
aliasSubscription: Subscription;
@ -128,6 +143,10 @@ export class WalletComponent implements OnInit, OnDestroy {
});
}
itemHovered(index, state: boolean) {
this.tabs[index].itemHovered = state;
}
copyAddress() {
this.backend.setClipboard(this.variablesService.currentWallet.address);
this.copyAnimation = true;
@ -164,6 +183,17 @@ export class WalletComponent implements OnInit, OnDestroy {
this.backend.openUrlInBrowser(link);
}
showDialog() {
this.isModalDialogVisible = true;
}
confirmed(confirmed: boolean) {
if (confirmed) {
this.closeWallet();
}
this.isModalDialogVisible = false;
}
closeWallet() {
this.backend.closeWallet(this.variablesService.currentWallet.wallet_id, () => {
for (let i = this.variablesService.wallets.length - 1; i >= 0; i--) {

View file

@ -150,6 +150,14 @@
"TIME3": "1 hour",
"TIME4": "Never"
},
"LANGUAGE": {
"TITLE": "Languages",
"EN": "English",
"FR": "French",
"DE": "Deutsch",
"IT": "Italian",
"PT": "Portuguese"
},
"MASTER_PASSWORD": {
"TITLE": "Update master password",
"OLD": "Old password",
@ -172,6 +180,7 @@
"AVAILABLE_BALANCE": "Available <b>{{available}} {{currency}}<b/>",
"LOCKED_BALANCE": "Locked <b>{{locked}} {{currency}}<b/>",
"LOCKED_BALANCE_LINK": "What does that mean?",
"CLOSE_MESSAGE": "<span class=\"message\">Remove wallet from the list</span> <br> <span>(To access it youll have to add it again)</span>",
"TABS": {
"SEND": "Send",
"RECEIVE": "Receive",
@ -179,6 +188,12 @@
"CONTRACTS": "Contracts",
"MESSAGES": "Messages",
"STAKING": "Staking"
},
"TOOLTIPS": {
"EDIT_ALIAS": "Edit alias",
"TRANSFER_ALIAS": "Transfer alias",
"SETTINGS": "Settings",
"CLOSE": "Close wallet"
}
},
"WALLET_DETAILS": {
@ -453,7 +468,8 @@
"ERROR": "Error",
"SUCCESS": "Success",
"INFO": "Information",
"OK": "OK"
"OK": "OK",
"CANCEL": "Cancel"
},
"CONFIRM": {
"BUTTON_CONFIRM": "Send",

View file

@ -1,19 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
<!-- Generator: Adobe Illustrator 23.0.5, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st0{fill:#42A5F5;}
</style>
<title>icons_5</title>
<g id="f31d9964-f67b-451c-9eb6-78b833647305">
<path class="st0" d="M299.9,197.6c9.3-16.7,14.2-35.5,14.1-54.6c0-70-43.4-105-97-105s-97,35-97,105c-0.1,19.1,4.8,38,14.2,54.6
C89.2,218.8,68.5,274.1,50,346l334-0.1C365.5,274,344.8,218.8,299.9,197.6z M178.1,94c11.6-11.6,27.6-14,38.9-14s27.3,2.4,38.9,14
c13.3,13.2,16.1,34,16.1,49c0,34.7-24.7,63-55,63s-55-28.3-55-63C162,115.7,170.7,101.3,178.1,94z M128.8,256.5
c10.1-14.3,21.1-22.1,36.1-25c31.4,22,73.1,22,104.5-0.1c14.9,2.9,25.9,10.8,35.9,25c8.9,12.6,16.3,29.3,22.7,47.5L106.1,304
C112.5,285.8,119.9,269.1,128.8,256.5z"/>
<path class="st0" d="M32.5,261H0v42h18.2C23,287,27.6,273.3,32.5,261z"/>
<path class="st0" d="M83,182c-0.9-3.6-1.7-7.3-2.4-11H0v42h56.8C64.2,201.6,73,191.2,83,182z"/>
<path class="st0" d="M88.8,81H0v42h79C80.4,108.6,83.7,94.5,88.8,81z"/>
</g>
<path class="st0" d="M299.8688965,197.5991211C309.2000122,180.9190063,314.0674133,162.1126099,314,143c0-70-43.4283447-105-97-105
s-97,35-97,105c-0.067482,19.1287231,4.8083801,37.9504089,14.1549072,54.6403809
C89.2226563,218.8474121,68.4660568,274.09021,50,346l334-0.0964355
C365.5390625,274.013916,344.7792969,218.8364258,299.8688965,197.5991211z M178.0637207,93.9938965
C189.6651611,82.4277267,205.6410065,80,217,80s27.3348389,2.4277267,38.9362793,13.9938965
C269.2130127,107.2301025,272,127.9494629,272,143c0,34.7382813-24.6730042,63-55,63s-55-28.2617188-55-63
C162,115.7322998,170.7354736,101.2995605,178.0637207,93.9938965z M128.7593994,256.5493164
c10.1036377-14.295166,21.1329346-22.1210938,36.0562744-25.0251465
c31.352066,21.9882507,73.1230164,21.9658966,104.4515381-0.0559082
c14.8673096,2.9362793,25.869751,10.7570801,35.944458,24.9881592
c8.9063721,12.5805664,16.3375244,29.3043213,22.7064209,47.4633789l-221.8294678,0.0639954
C112.4510498,285.8366699,119.87146,269.1243896,128.7593994,256.5493164z"/>
<path class="st0" d="M32.4565392,261H0v42h18.2427998C22.95117,287.0407715,27.6054707,273.2824707,32.4565392,261z"/>
<path class="st0" d="M82.9628906,181.9945068C82.0220032,178.3674316,81.2279968,174.6973877,80.5518799,171H0v42h56.8131104
C64.2091751,201.6196442,72.9933243,191.2043915,82.9628906,181.9945068z"/>
<path class="st0" d="M88.7985764,81H0v42h78.9995117C80.3876266,108.6271896,83.6829224,94.5031357,88.7985764,81z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

File diff suppressed because one or more lines are too long

View file

@ -1,13 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g id="logout">
<polygon class="st0" points="68.5,0 68.5,90 110.5,90 110.5,42 341.5,42 341.5,342 110.5,342 110.5,294 68.5,294 68.5,384
383.5,384 383.5,0 "/>
<polygon class="st0" points="194.5,270 282,192 194.5,114.5 194.5,171 0,171 0,213 194.5,213 "/>
</g>
<svg id="ab50e553-f2b3-4433-b3ff-0d9613f08375" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 383.5 384">
<defs>
<style>
.ecae9e89-1a50-4e7d-886b-c0873462098f {
fill: #42a5f5;
}
</style>
</defs>
<title>exit</title>
<g id="be098581-bbc7-4930-ae81-d0f1e45068cd" data-name="logout">
<polygon class="ecae9e89-1a50-4e7d-886b-c0873462098f" points="68.5 0 68.5 90 110.5 90 110.5 42 341.5 42 341.5 342 110.5 342 110.5 294 68.5 294 68.5 384 383.5 384 383.5 0 68.5 0"/>
<polygon class="ecae9e89-1a50-4e7d-886b-c0873462098f" points="185.5 270 273 192 185.5 114.5 185.5 171 0 171 0 213 185.5 213 185.5 270"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 672 B

After

Width:  |  Height:  |  Size: 676 B

View file

@ -1,17 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="icons" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 384 384" style="enable-background:new 0 0 384 384;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<g id="settings">
<path class="st0" d="M384,213.3v-42.7h-65.9c-3.1-18.9-10.4-37-21.3-52.7l46.5-46.5l-30.5-30.3L266,87.7
c-15.7-11-33.8-18.3-52.7-21.3V0h-42.7v65.9c-18.9,3.1-37,10.4-52.7,21.3L71.3,41.2L41.2,71.3L87.7,118
c-11,15.7-18.3,33.8-21.3,52.7H0v42.7h65.9c3.1,18.9,10.4,37,21.3,52.7l-46.1,46.7l30.1,30.1l46.5-46.5
c15.7,11,33.8,18.3,52.7,21.3V384h42.7v-65.9c18.9-3.1,37-10.4,52.7-21.3l46.5,46.5l30.1-30.1l-46.5-46.5
c11-15.7,18.3-33.8,21.3-52.7H384V213.3z M102.6,192c0-49.4,40-89.4,89.4-89.4s89.4,40,89.4,89.4s-40,89.4-89.4,89.4
C142.7,281.3,102.7,241.3,102.6,192z"/>
<circle class="st0" cx="192" cy="192" r="41"/>
</g>
<svg id="a22f0928-30d8-4699-903e-959bbb5157b6" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384.00001 384.00001">
<defs>
<style>
.b2acf0b3-a12d-45f7-a117-55ab824eefa9 {
fill: #42a5f5;
}
</style>
</defs>
<title>settings</title>
<g id="aa4a36a4-78af-43f5-b1fa-6aab82396505" data-name="settings">
<path class="b2acf0b3-a12d-45f7-a117-55ab824eefa9" d="M384,213.33334V170.66667H318.08a127.9996,127.9996,0,0,0-21.33334-52.69334l46.50668-46.50667L312.74667,41.17333,266.02668,87.68a128.00008,128.00008,0,0,0-52.69334-21.33334V0H170.66667V65.92a128,128,0,0,0-52.69334,21.33333l-46.72-46.08-30.08,30.08,46.50668,46.72a128.00014,128.00014,0,0,0-21.33334,52.69334H0v42.66667H65.92a127.99993,127.99993,0,0,0,21.33333,52.69334l-46.08,46.72,30.08,30.08L117.76,296.32a127.99957,127.99957,0,0,0,52.69335,21.33333V384H213.12V318.08a127.99949,127.99949,0,0,0,52.69334-21.33334L312.32,343.25335l30.08-30.08-46.50668-46.50667a127.99973,127.99973,0,0,0,21.33334-52.69334H384ZM102.61334,192A89.38668,89.38668,0,1,1,192,281.38669,89.38664,89.38664,0,0,1,102.61334,192Z" transform="translate(0 0)"/>
<circle class="b2acf0b3-a12d-45f7-a117-55ab824eefa9" cx="192.00001" cy="192.00001" r="40.99999"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -873,7 +873,7 @@ input[type='checkbox'].style-checkbox {
}
}
app-modal-container {
app-modal-container, app-confirm-modal {
.modal {

View file

@ -16,6 +16,8 @@
"lib": [
"es2018",
"dom"
]
],
"resolveJsonModule": true,
"esModuleInterop": true
}
}

View file

@ -42,8 +42,16 @@ int main(int argc, char *argv[])
#endif
#ifdef WIN32
WCHAR sz_file_name[MAX_PATH + 1] = L"";
::GetModuleFileNameW(NULL, sz_file_name, MAX_PATH + 1);
std::string path_to_process_utf8 = epee::string_encoding::wstring_to_utf8(sz_file_name);
#else
std::string path_to_process_utf8 = argv[0];
#endif
TRY_ENTRY();
epee::string_tools::set_module_name_and_folder(argv[0]);
epee::string_tools::set_module_name_and_folder(path_to_process_utf8);
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#ifdef _MSC_VER
#if _MSC_VER >= 1910

Some files were not shown because too many files have changed in this diff Show more