1
0
Fork 0
forked from lthn/blockchain

Merge branch 'develop' into develop_mobile

This commit is contained in:
cryptozoidberg 2021-08-17 12:13:54 +02:00
commit d1121f3ff9
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
48 changed files with 761 additions and 155 deletions

View file

@ -17,9 +17,9 @@ Be sure to clone the repository properly:\
| llvm/clang (Linux) | UNKNOWN | 7.0.1 | 8.0.0 |
| [MSVC](https://visualstudio.microsoft.com/downloads/) (Windows) | 2015 (14.0 update 1) | 2017 (15.9.0) | 2019 |
| [XCode](https://developer.apple.com/downloads/) (macOS) | 9.2 | 12.3 | 12.3 |
| [CMake](https://cmake.org/download/) | 2.8.6 | 3.15.5 | 3.18.1 |
| [Boost](https://www.boost.org/users/download/) | 1.56 | 1.68 | 1.69 |
| [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.11.2 | 5.13.2 |
| [CMake](https://cmake.org/download/) | 2.8.6 | 3.15.5 | 3.20 |
| [Boost](https://www.boost.org/users/download/) | 1.56 | 1.68 | 1.76 |
| [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.11.2 | 5.15.2 |
Note:\
[*server version*] denotes steps required for building command-line tools (daemon, simplewallet, etc.).\
@ -39,7 +39,7 @@ Recommended OS version: Ubuntu 18.04 LTS.
[*GUI version*]
sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen mesa-common-dev libglu1-mesa-dev`
sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen mesa-common-dev libglu1-mesa-dev
2. Download and build Boost
@ -85,6 +85,8 @@ For instance, by adding the following lines to `~/.bashrc`
make -j1 daemon simplewallet
**NOTICE**: If you are building on a machine with a relatively high amount of RAM or with the proper setting of virtual memory, then you can use `-j2` or `-j` option to speed up the building process. Use with caution.
**NOTICE 2**: If you'd like to build binaries for the testnet, use `cmake -D TESTNET=TRUE ..` instead of `cmake ..` .
1. Building GUI:

View file

@ -65,6 +65,8 @@ namespace epee
}
#define STD_TRY_CATCH_LOCATION(return_val) STD_TRY_CATCH(LOCATION_SS, return_val)
/* helper class, to make able get namespace via decltype()::*/
template<class base_class>
class namespace_accessor: public base_class{};

View file

@ -132,17 +132,21 @@ DISABLE_VS_WARNINGS(4100)
#define LOG_PRINT_CHANNEL_NO_POSTFIX2(log_channel, log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x; epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);CATCH_ALL_DO_NOTHING();}}
#define LOG_PRINT_CHANNEL2(log_channel, log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);CATCH_ALL_DO_NOTHING();}}
#define LOG_PRINT_CHANNEL2_CB(log_channel, log_name, x, y, cb) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, false, log_name);cb(ss________.str());CATCH_ALL_DO_NOTHING();}}
#define LOG_PRINT_CHANNEL_COLOR2(log_channel, log_name, x, y, color) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, color, false, log_name);CATCH_ALL_DO_NOTHING();}}
#define LOG_PRINT_CHANNEL_COLOR2_CB(log_channel, log_name, x, y, color, cb) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, color, false, log_name); cb(ss________.str());CATCH_ALL_DO_NOTHING();}}
#define LOG_PRINT_CHANNEL_2_JORNAL(log_channel, log_name, x, y) {if ( y <= epee::log_space::log_singletone::get_log_detalisation_level() && epee::log_space::log_singletone::channel_enabled(log_channel))\
{TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << x << std::endl;epee::log_space::log_singletone::do_log_message(ss________.str(), y, epee::log_space::console_color_default, true, log_name);CATCH_ALL_DO_NOTHING();}}
#define LOG_ERROR2(log_name, x) { \
TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << "[ERROR] Location: " << std::endl << LOCATION_SS << epee::misc_utils::get_callstack() << " Message:" << std::endl << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str(), LOG_LEVEL_0, epee::log_space::console_color_red, true, log_name); LOCAL_ASSERT(0); epee::log_space::increase_error_count(LOG_DEFAULT_CHANNEL);CATCH_ALL_DO_NOTHING();}
#define LOG_ERROR2_CB(log_name, x, cb) { \
TRY_ENTRY();std::stringstream ss________; ss________ << epee::log_space::log_singletone::get_prefix_entry() << "[ERROR] Location: " << std::endl << LOCATION_SS << epee::misc_utils::get_callstack() << " Message:" << std::endl << x << std::endl; epee::log_space::log_singletone::do_log_message(ss________.str(), LOG_LEVEL_0, epee::log_space::console_color_red, true, log_name); LOCAL_ASSERT(0); epee::log_space::increase_error_count(LOG_DEFAULT_CHANNEL); cb(ss________.str()); CATCH_ALL_DO_NOTHING();}
#define LOG_ERROR2(log_name, x) LOG_ERROR2_CB(log_name, x, epee::log_space::log_stub)
#define LOG_PRINT_CHANNEL2(log_channel, log_name, x, y) LOG_PRINT_CHANNEL2_CB(log_channel, log_name, x, y, epee::log_space::log_stub)
#define LOG_PRINT_CHANNEL_COLOR2(log_channel, log_name, x, y, color) LOG_PRINT_CHANNEL_COLOR2_CB(log_channel, log_name, x, y, color, epee::log_space::log_stub)
#define LOG_FRAME2(log_name, x, y) epee::log_space::log_frame frame(x, y, log_name)
@ -163,7 +167,9 @@ DISABLE_VS_WARNINGS(4100)
#define LOG_PRINT_NO_PREFIX_NO_POSTFIX2(log_name, x, y) LOG_PRINT_CHANNEL_NO_PREFIX_NO_POSTFIX2(LOG_DEFAULT_CHANNEL, log_name, x, y)
#define LOG_PRINT_NO_POSTFIX2(log_name, x, y) LOG_PRINT_CHANNEL_NO_POSTFIX2(LOG_DEFAULT_CHANNEL, log_name, x, y)
#define LOG_PRINT2(log_name, x, y) LOG_PRINT_CHANNEL2(LOG_DEFAULT_CHANNEL, log_name, x, y)
#define LOG_PRINT2_CB(log_name, x, y, cb) LOG_PRINT_CHANNEL2_CB(LOG_DEFAULT_CHANNEL, log_name, x, y, cb)
#define LOG_PRINT_COLOR2(log_name, x, y, color) LOG_PRINT_CHANNEL_COLOR2(LOG_DEFAULT_CHANNEL, log_name, x, y, color)
#define LOG_PRINT_COLOR2_CB(log_name, x, y, color, cb) LOG_PRINT_CHANNEL_COLOR2_CB(LOG_DEFAULT_CHANNEL, log_name, x, y, color, cb)
#define LOG_PRINT2_JORNAL(log_name, x, y) LOG_PRINT_CHANNEL_2_JORNAL(LOG_DEFAULT_CHANNEL, log_name, x, y)
#ifndef LOG_DEFAULT_TARGET
@ -173,17 +179,28 @@ DISABLE_VS_WARNINGS(4100)
#define LOG_PRINT_NO_POSTFIX(mess, level) LOG_PRINT_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level)
#define LOG_PRINT_NO_PREFIX(mess, level) LOG_PRINT_NO_PREFIX2(LOG_DEFAULT_TARGET, mess, level)
#define LOG_PRINT_NO_PREFIX_NO_POSTFIX(mess, level) LOG_PRINT_NO_PREFIX_NO_POSTFIX2(LOG_DEFAULT_TARGET, mess, level)
#define LOG_PRINT(mess, level) LOG_PRINT2(LOG_DEFAULT_TARGET, mess, level)
#define LOG_PRINT(mess, level) LOG_PRINT2(LOG_DEFAULT_TARGET, mess, level)
#define LOG_PRINT_CB(mess, level, cb) LOG_PRINT2_CB(LOG_DEFAULT_TARGET, mess, level, cb)
#define LOG_PRINT_COLOR_CB(mess, level, color, cb) LOG_PRINT_COLOR2_CB(LOG_DEFAULT_TARGET, mess, level, color, cb)
#define LOG_COLOR_RED epee::log_space::console_color_red
#define LOG_COLOR_GREEN epee::log_space::console_color_green
#define LOG_COLOR_BLUE epee::log_space::console_color_blue
#define LOG_COLOR_YELLOW epee::log_space::console_color_yellow
#define LOG_COLOR_CYAN epee::log_space::console_color_cyan
#define LOG_COLOR_MAGENTA epee::log_space::console_color_magenta
#define LOG_PRINT_COLOR(mess, level, color) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, color)
#define LOG_PRINT_RED(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_red)
#define LOG_PRINT_GREEN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_green)
#define LOG_PRINT_BLUE(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_blue)
#define LOG_PRINT_YELLOW(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_yellow)
#define LOG_PRINT_CYAN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_cyan)
#define LOG_PRINT_MAGENTA(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, epee::log_space::console_color_magenta)
#define LOG_PRINT_RED(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_RED)
#define LOG_PRINT_GREEN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_GREEN)
#define LOG_PRINT_BLUE(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_BLUE)
#define LOG_PRINT_YELLOW(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_YELLOW)
#define LOG_PRINT_CYAN(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_CYAN)
#define LOG_PRINT_MAGENTA(mess, level) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, level, LOG_COLOR_MAGENTA)
#define LOG_PRINT_RED_L0(mess) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, LOG_LEVEL_0, epee::log_space::console_color_red)
#define LOG_PRINT_RED_L0(mess) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, LOG_LEVEL_0, epee::log_space::console_color_red)
#define LOG_PRINT_GREEN_L0(mess) LOG_PRINT_COLOR2(LOG_DEFAULT_TARGET, mess, LOG_LEVEL_0, epee::log_space::console_color_green)
#define LOG_PRINT_L0(mess) LOG_PRINT(mess, LOG_LEVEL_0)
#define LOG_PRINT_L1(mess) LOG_PRINT(mess, LOG_LEVEL_1)
@ -193,6 +210,7 @@ DISABLE_VS_WARNINGS(4100)
#define LOG_PRINT_J(mess, level) LOG_PRINT2_JORNAL(LOG_DEFAULT_TARGET, mess, level)
#define LOG_ERROR(mess) LOG_ERROR2(LOG_DEFAULT_TARGET, mess)
#define LOG_ERROR_CB(mess, cb) LOG_ERROR2_CB(LOG_DEFAULT_TARGET, mess, cb)
#define LOG_FRAME(mess, level) LOG_FRAME2(LOG_DEFAULT_TARGET, mess, level)
#define LOG_VALUE(mess, level) LOG_VALUE2(LOG_DEFAULT_TARGET, mess, level)
#define LOG_ARRAY(mess, level) LOG_ARRAY2(LOG_DEFAULT_TARGET, mess, level)
@ -333,7 +351,8 @@ namespace log_space
/* */
/************************************************************************/
#define CONSOLE_DEFAULT_STREAM std::cout
inline void log_stub(const std::string& /**/) {}
struct delete_ptr
{

View file

@ -26,6 +26,7 @@
#pragma once
#include <boost/mpl/vector.hpp>
#include <deque>
namespace epee

View file

@ -94,9 +94,28 @@ namespace epee
return serialization::load_t_from_binary(result_struct, pri->m_body);
}
template<class t_request, class t_response, class t_transport>
bool invoke_http_json_rpc(const std::string& url, const std::string& method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, epee::json_rpc::error& err, unsigned int timeout = 5000, const std::string& http_method = "GET", const std::string& req_id = "0")
{
epee::json_rpc::request<t_request> req_t = AUTO_VAL_INIT(req_t);
req_t.jsonrpc = "2.0";
req_t.id = req_id;
req_t.method = method_name;
req_t.params = out_struct;
epee::json_rpc::response<t_response, epee::json_rpc::error> resp_t = AUTO_VAL_INIT(resp_t);
if (!epee::net_utils::invoke_http_json_remote_command2(url, req_t, resp_t, transport, timeout, http_method))
{
return false;
}
err = resp_t.error;
result_struct = resp_t.result;
return true;
}
template<class t_request, class t_response, class t_transport>
bool invoke_http_json_rpc(const std::string& url, const std::string& method_name, const t_request& out_struct, t_response& result_struct, t_transport& transport, unsigned int timeout = 5000, const std::string& http_method = "GET", const std::string& req_id = "0")
{
{
epee::json_rpc::request<t_request> req_t = AUTO_VAL_INIT(req_t);
req_t.jsonrpc = "2.0";
req_t.id = req_id;

View file

@ -28,6 +28,7 @@
#pragma once
#include <boost/mpl/contains.hpp>
#include "misc_language.h"
#include "portable_storage_base.h"
#include "portable_storage_to_bin.h"

View file

@ -199,6 +199,7 @@ if(BUILD_GUI)
if(APPLE)
target_link_libraries(Zano ${COCOA_LIBRARY})
set_property(TARGET Zano PROPERTY XCODE_ATTRIBUTE_ENABLE_HARDENED_RUNTIME YES)
endif()
if(MSVC)
target_link_libraries(Zano shlwapi.lib)

View file

@ -15,20 +15,20 @@ bool parse_hash256(const std::string str_hash, crypto::hash& hash);
template <class T>
std::ostream &print_t(std::ostream &o, const T &v)
{
return o << "<" << epee::string_tools::pod_to_hex(v) << ">";
return o << "" << epee::string_tools::pod_to_hex(v) << "";
}
template <class T>
std::ostream &print16(std::ostream &o, const T &v)
{
return o << "<" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..>";
return o << "" << epee::string_tools::pod_to_hex(v).substr(0, 5) << "..";
}
template <class T>
std::string print16(const T &v)
{
return std::string("<") + epee::string_tools::pod_to_hex(v).substr(0, 5) + "..>";
return std::string("") + epee::string_tools::pod_to_hex(v).substr(0, 5) + "..";
}

View file

@ -21,8 +21,8 @@ namespace tools
};
#ifndef TESTNET
static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.43.225/pre-download/zano_mdbx_95_1000000.pak", "6b0bbba85bc420eaae5ec68373e528f70bffaa17fb111c796e951d06ad71e4fe", 1104150892, 2147450880 };
static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.43.225/pre-download/zano_lmdb_95_1000000.pak", "b4d45c727dbf1b92671f9fd1a9624e79019e890bd3d33cb71e011ab4bcb0d21e", 1450748151, 2114449408 };
static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_1161000.pak", "26660ffcdaf80a43a586e64a1a6da042dcb9ff3b58e14ce1ec9a775b995dc146", 1330022593, 2684313600 };
static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_1161000.pak", "9dd03f08dea396fe32e6483a8221b292be35fa41c29748f119f11c3275956cdc", 1787475468, 2600247296 };
#else
static constexpr pre_download_entry c_pre_download_mdbx = { "", "", 0, 0 };
static constexpr pre_download_entry c_pre_download_lmdb = { "", "", 0, 0 };
@ -50,7 +50,8 @@ namespace tools
boost::system::error_code ec;
uint64_t sz = boost::filesystem::file_size(db_main_file_path, ec);
if (pre_download.unpacked_size == 0 || !(ec || (pre_download.unpacked_size > sz && pre_download.unpacked_size - sz > pre_download_min_size_difference) || command_line::has_arg(vm, command_line::arg_force_predownload)) )
bool flag_force_predownload = command_line::has_arg(vm, command_line::arg_force_predownload);
if (pre_download.unpacked_size == 0 || !(ec || (pre_download.unpacked_size > sz && pre_download.unpacked_size - sz > pre_download_min_size_difference) || flag_force_predownload) )
{
LOG_PRINT_MAGENTA("Pre-downloading not needed (db file size = " << sz << ")", LOG_LEVEL_0);
return true;
@ -92,15 +93,15 @@ namespace tools
r = cl.download_and_unzip(cb, downloading_file_path, url, 5000 /* timout */, "GET", std::string(), 30 /* fails count */);
if (!r)
{
LOG_PRINT_RED("Download failed", LOG_LEVEL_0);
return false;
LOG_PRINT_RED("Downloading failed", LOG_LEVEL_0);
return !flag_force_predownload; // fatal error only if force-predownload
}
crypto::hash data_hash = hash_stream.calculate_hash();
if (epee::string_tools::pod_to_hex(data_hash) != pre_download.hash)
{
LOG_ERROR("hash missmatch in downloaded file, got: " << epee::string_tools::pod_to_hex(data_hash) << ", expected: " << pre_download.hash);
return false;
return !flag_force_predownload; // fatal error only if force-predownload
}
LOG_PRINT_GREEN("Download succeeded, hash " << pre_download.hash << " is correct" , LOG_LEVEL_0);

View file

@ -593,6 +593,7 @@ bool handle_get_daemon_info(po::variables_map& vm)
PRINT_FIELD_NAME(res.performance_data, "", tx_append_time)
PRINT_FIELD_NAME(res.performance_data, "", tx_append_rl_wait)
PRINT_FIELD_NAME(res.performance_data, "", tx_append_is_expired)
PRINT_FIELD_NAME(res.performance_data, "", tx_mixin_count)
PRINT_FIELD_NAME(res.performance_data, "", tx_check_inputs_prefix_hash)
PRINT_FIELD_NAME(res.performance_data, "", tx_check_inputs_attachment_check)
PRINT_FIELD_NAME(res.performance_data, "", tx_check_inputs_loop)

View file

@ -433,6 +433,17 @@ namespace crypto
}; // struct scalar_t
//
// Global constants
//
extern const scalar_t c_scalar_1;
extern const scalar_t c_scalar_L;
extern const scalar_t c_scalar_Lm1;
extern const scalar_t c_scalar_P;
extern const scalar_t c_scalar_Pm1;
extern const scalar_t c_scalar_256m1;
extern const scalar_t c_scalar_1div8;
//
//
@ -486,6 +497,7 @@ namespace crypto
zero();
}
// as we're using additive notation, zero means identity group element here and after
void zero()
{
ge_p3_0(&m_p3);
@ -497,6 +509,11 @@ namespace crypto
return fe_isnonzero(m_p3.X) * fe_cmp(m_p3.Y, m_p3.Z) == 0;
}
bool is_in_main_subgroup() const
{
return (c_scalar_L * *this).is_zero();
}
bool from_public_key(const crypto::public_key& pk)
{
return ge_frombytes_vartime(&m_p3, reinterpret_cast<const unsigned char*>(&pk)) == 0;
@ -862,14 +879,6 @@ namespace crypto
//
extern const point_g_t c_point_G;
extern const scalar_t c_scalar_1;
extern const scalar_t c_scalar_L;
extern const scalar_t c_scalar_Lm1;
extern const scalar_t c_scalar_P;
extern const scalar_t c_scalar_Pm1;
extern const scalar_t c_scalar_256m1;
extern const scalar_t c_scalar_1div8;
extern const point_t c_point_H;
extern const point_t c_point_0;

View file

@ -16,13 +16,15 @@
#define SEED_PHRASE_V2_WORDS_COUNT 26
#ifndef FORCE_HEADER_ONLY
#define KV_SERIALIZE_ADDRESS_AS_TEXT_N(varialble, val_name) \
KV_SERIALIZE_CUSTOM_N(varialble, std::string, currency::transform_addr_to_str, currency::transform_str_to_addr, val_name)
#define KV_SERIALIZE_ADDRESS_AS_TEXT_N(varialble, val_name) \
KV_SERIALIZE_CUSTOM_N(varialble, std::string, currency::transform_addr_to_str, currency::transform_str_to_addr, val_name)
#define KV_SERIALIZE_ADDRESS_AS_TEXT(varialble) KV_SERIALIZE_ADDRESS_AS_TEXT_N(varialble, #varialble)
#define KV_SERIALIZE_ADDRESS_AS_TEXT(varialble) KV_SERIALIZE_ADDRESS_AS_TEXT_N(varialble, #varialble)
#else
#define KV_SERIALIZE_ADDRESS_AS_TEXT_N(varialble, val_name)
#define KV_SERIALIZE_ADDRESS_AS_TEXT(varialble)
#endif
namespace currency
{
@ -97,6 +99,7 @@ namespace currency
std::vector<unsigned char> m_keys_seed_binary;
};
const static account_keys null_acc_keys = AUTO_VAL_INIT(null_acc_keys);
std::string transform_addr_to_str(const account_public_address& addr);
account_public_address transform_str_to_addr(const std::string& str);

View file

@ -3816,12 +3816,14 @@ namespace currency
const crypto::hash& m_tx_id;
const crypto::hash& m_bl_id;
const uint64_t m_bl_height;
add_transaction_input_visitor(blockchain_storage& bcs, blockchain_storage::key_images_container& m_db_spent_keys, const crypto::hash& tx_id, const crypto::hash& bl_id, const uint64_t bl_height) :
uint64_t &m_mixins_count;
add_transaction_input_visitor(blockchain_storage& bcs, blockchain_storage::key_images_container& m_db_spent_keys, const crypto::hash& tx_id, const crypto::hash& bl_id, const uint64_t bl_height, uint64_t& mixins_count) :
m_bcs(bcs),
m_db_spent_keys(m_db_spent_keys),
m_tx_id(tx_id),
m_bl_id(bl_id),
m_bl_height(bl_height)
m_bl_height(bl_height),
m_mixins_count(mixins_count)
{}
bool operator()(const txin_to_key& in) const
{
@ -3846,7 +3848,8 @@ namespace currency
return false;
}
}
if (m_mixins_count < in.key_offsets.size())
m_mixins_count = in.key_offsets.size();
return true;
}
bool operator()(const txin_htlc& in) const
@ -3896,11 +3899,11 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const
process_blockchain_tx_attachments(tx, bl_height, bl_id, timestamp);
TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_process_attachment);
uint64_t mixins_count = 0;
TIME_MEASURE_START_PD(tx_process_inputs);
for(const txin_v& in : tx.vin)
{
if(!boost::apply_visitor(add_transaction_input_visitor(*this, m_db_spent_keys, tx_id, bl_id, bl_height), in))
if(!boost::apply_visitor(add_transaction_input_visitor(*this, m_db_spent_keys, tx_id, bl_id, bl_height, mixins_count), in))
{
LOG_ERROR("critical internal error: add_transaction_input_visitor failed. but key_images should be already checked");
purge_transaction_keyimages_from_blockchain(tx, false);
@ -3913,6 +3916,13 @@ bool blockchain_storage::add_transaction_from_block(const transaction& tx, const
}
}
TIME_MEASURE_FINISH_PD_COND(need_to_profile, tx_process_inputs);
if (need_to_profile && mixins_count > 0)
{
m_performance_data.tx_mixin_count.push(mixins_count);
#ifdef _DEBUG
LOG_PRINT_L0("[TX_MIXINS]: " << mixins_count);
#endif
}
//check if there is already transaction with this hash
TIME_MEASURE_START_PD(tx_check_exist);

View file

@ -73,33 +73,35 @@ namespace currency
epee::math_helper::average<uint64_t, 5> target_calculating_calc;
//tx processing zone
epee::math_helper::average<uint64_t, 5> tx_check_inputs_time;
epee::math_helper::average<uint64_t, 5> tx_add_one_tx_time;
epee::math_helper::average<uint64_t, 5> tx_process_extra;
epee::math_helper::average<uint64_t, 5> tx_process_attachment;
epee::math_helper::average<uint64_t, 5> tx_process_inputs ;
epee::math_helper::average<uint64_t, 5> tx_push_global_index;
epee::math_helper::average<uint64_t, 5> tx_check_exist;
epee::math_helper::average<uint64_t, 5> tx_print_log;
epee::math_helper::average<uint64_t, 5> tx_prapare_append;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_time;
epee::math_helper::average<uint64_t, 1> tx_add_one_tx_time;
epee::math_helper::average<uint64_t, 1> tx_process_extra;
epee::math_helper::average<uint64_t, 1> tx_process_attachment;
epee::math_helper::average<uint64_t, 1> tx_process_inputs ;
epee::math_helper::average<uint64_t, 1> tx_push_global_index;
epee::math_helper::average<uint64_t, 1> tx_check_exist;
epee::math_helper::average<uint64_t, 1> tx_print_log;
epee::math_helper::average<uint64_t, 1> tx_prapare_append;
epee::math_helper::average<uint64_t, 5> tx_append_time;
epee::math_helper::average<uint64_t, 5> tx_append_rl_wait;
epee::math_helper::average<uint64_t, 5> tx_append_is_expired;
epee::math_helper::average<uint64_t, 1> tx_append_time;
epee::math_helper::average<uint64_t, 1> tx_append_rl_wait;
epee::math_helper::average<uint64_t, 1> tx_append_is_expired;
epee::math_helper::average<uint64_t, 5> tx_store_db;
epee::math_helper::average<uint64_t, 1> tx_store_db;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_prefix_hash;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_attachment_check;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_kimage_check;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_ch_in_val_sig;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_get_item_size;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_relative_to_absolute;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_loop;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_loop_get_subitem;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_loop_find_tx;
epee::math_helper::average<uint64_t, 5> tx_check_inputs_loop_scan_outputkeys_loop_handle_output;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_prefix_hash;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_attachment_check;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_kimage_check;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_ch_in_val_sig;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_get_item_size;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_relative_to_absolute;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_loop;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_loop_get_subitem;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_loop_find_tx;
epee::math_helper::average<uint64_t, 1> tx_check_inputs_loop_scan_outputkeys_loop_handle_output;
epee::math_helper::average<uint64_t, 1> tx_mixin_count;
//TODO: move this to suitable place or remove it all

View file

@ -17,13 +17,14 @@ namespace currency
inline bool create_checkpoints(currency::checkpoints& checkpoints)
{
#ifdef TESTNET
//ADD_CHECKPOINT(50000, "492ef71f5d722a8a182d65eb0ff731b740e023a2d64881f43db9af7b39ba7988");
#else
// MAINNET
ADD_CHECKPOINT(425000, "46a6c36d5dec2d484d5e4845a8525ca322aafc06915ed9c8da2a241b51b7d1e8");
ADD_CHECKPOINT(525000, "8c1ac57e67448130207a224b2d6e33ccdc64d6dd1c59dbcf9ad2361dc0d07d51");
ADD_CHECKPOINT(600000, "d9fe316086e1aaea07d94082973ec764eff5fc5a05ed6e1eca273cee59daeeb4");
ADD_CHECKPOINT(900000, "2205b73cd79d4937b087b02a8b001171b73c34464bc4a952834eaf7c2bd63e86");
ADD_CHECKPOINT(425000, "46a6c36d5dec2d484d5e4845a8525ca322aafc06915ed9c8da2a241b51b7d1e8");
ADD_CHECKPOINT(525000, "8c1ac57e67448130207a224b2d6e33ccdc64d6dd1c59dbcf9ad2361dc0d07d51");
ADD_CHECKPOINT(600000, "d9fe316086e1aaea07d94082973ec764eff5fc5a05ed6e1eca273cee59daeeb4");
ADD_CHECKPOINT(900000, "2205b73cd79d4937b087b02a8b001171b73c34464bc4a952834eaf7c2bd63e86");
ADD_CHECKPOINT(1161000, "96990d851b484e30190678756ba2a4d3a2f92b987e2470728ac1e38b2bf35908");
#endif
return true;

View file

@ -383,11 +383,25 @@ namespace currency
FIELD(security)
FIELD(flags)
END_SERIALIZE()
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(service_id)
KV_SERIALIZE(instruction)
KV_SERIALIZE_BLOB_AS_HEX_STRING(body)
KV_SERIALIZE_CONTAINER_POD_AS_BLOB(security)
KV_SERIALIZE(flags)
END_KV_SERIALIZE_MAP()
};
// applicable flags for tx_service_attachment::flags, can be combined using bitwise OR
#define TX_SERVICE_ATTACHMENT_ENCRYPT_BODY static_cast<uint8_t>(1 << 0)
#define TX_SERVICE_ATTACHMENT_DEFLATE_BODY static_cast<uint8_t>(1 << 1)
#define TX_SERVICE_ATTACHMENT_ENCRYPT_BODY static_cast<uint8_t>(1 << 0)
#define TX_SERVICE_ATTACHMENT_DEFLATE_BODY static_cast<uint8_t>(1 << 1)
// with this flag enabled body encrypted/decrypted with the key created as a derivation from onetime key and "spend keys" of receiver
#define TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE static_cast<uint8_t>(1 << 2)
// add proof of content, without revealing secrete
#define TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF static_cast<uint8_t>(1 << 3)
//,
@ -690,6 +704,7 @@ namespace currency
return k;
}
};
const static keypair null_keypair = AUTO_VAL_INIT(null_keypair);
//---------------------------------------------------------------
//PoS
//based from ppcoin/novacoin approach

View file

@ -759,8 +759,12 @@ namespace currency
struct encrypt_attach_visitor : public boost::static_visitor<void>
{
bool& m_was_crypted_entries;
const keypair& m_onetime_keypair;
const account_public_address& m_destination_addr;
const crypto::key_derivation& m_key;
encrypt_attach_visitor(bool& was_crypted_entries, const crypto::key_derivation& key) :m_was_crypted_entries(was_crypted_entries), m_key(key)
encrypt_attach_visitor(bool& was_crypted_entries, const crypto::key_derivation& key, const keypair& onetime_keypair = null_keypair, const account_public_address& destination_addr = null_pub_addr) :
m_was_crypted_entries(was_crypted_entries), m_key(key), m_onetime_keypair(onetime_keypair), m_destination_addr(destination_addr)
{}
void operator()(tx_comment& comment)
{
@ -789,6 +793,7 @@ namespace currency
}
void operator()(tx_service_attachment& sa)
{
const std::string original_body = sa.body;
if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY)
{
zlib_helper::pack(sa.body);
@ -796,7 +801,28 @@ namespace currency
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY)
{
crypto::chacha_crypt(sa.body, m_key);
crypto::key_derivation derivation_local = m_key;
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE)
{
CHECK_AND_ASSERT_THROW_MES(m_destination_addr.spend_public_key != currency::null_pkey && m_onetime_keypair.sec != currency::null_skey, "tx_service_attachment with TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE: keys uninitialized");
//encrypt with "spend keys" only, to prevent auditable watchers decrypt it
bool r = crypto::generate_key_derivation(m_destination_addr.spend_public_key, m_onetime_keypair.sec, derivation_local);
CHECK_AND_ASSERT_THROW_MES(r, "tx_service_attachment with TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE: Failed to make derivation");
crypto::chacha_crypt(sa.body, derivation_local);
}
else
{
crypto::chacha_crypt(sa.body, derivation_local);
}
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF)
{
//take hash from derivation and use it as a salt
crypto::hash derivation_hash = crypto::cn_fast_hash(&derivation_local, sizeof(derivation_local));
std::string salted_body = original_body;
string_tools::apped_pod_to_strbuff(salted_body, derivation_hash);
crypto::hash proof_hash = crypto::cn_fast_hash(salted_body.data(), salted_body.size());
sa.security.push_back(*(crypto::public_key*)&proof_hash);
}
m_was_crypted_entries = true;
}
}
@ -808,12 +834,18 @@ namespace currency
struct decrypt_attach_visitor : public boost::static_visitor<void>
{
const account_keys& m_acc_keys;
const crypto::public_key& m_tx_onetime_pubkey;
const crypto::key_derivation& rkey;
std::vector<payload_items_v>& rdecrypted_att;
decrypt_attach_visitor(const crypto::key_derivation& key,
std::vector<payload_items_v>& decrypted_att) :
std::vector<payload_items_v>& decrypted_att,
const account_keys& acc_keys = null_acc_keys,
const crypto::public_key& tx_onetime_pubkey = null_pkey) :
rkey(key),
rdecrypted_att(decrypted_att)
rdecrypted_att(decrypted_att),
m_acc_keys(acc_keys),
m_tx_onetime_pubkey(tx_onetime_pubkey)
{}
void operator()(const tx_comment& comment)
{
@ -825,15 +857,44 @@ namespace currency
void operator()(const tx_service_attachment& sa)
{
tx_service_attachment local_sa = sa;
crypto::key_derivation derivation_local = rkey;
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY)
{
crypto::chacha_crypt(local_sa.body, rkey);
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE)
{
if (m_acc_keys.spend_secret_key == null_skey)
{
//this watch only wallet, decrypting supposed to be impossible
return;
}
CHECK_AND_ASSERT_THROW_MES(m_acc_keys.spend_secret_key != currency::null_skey && m_tx_onetime_pubkey != currency::null_pkey, "tx_service_attachment with TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE: keys uninitialized");
bool r = crypto::generate_key_derivation(m_tx_onetime_pubkey, m_acc_keys.spend_secret_key, derivation_local);
CHECK_AND_ASSERT_THROW_MES(r, "Failed to generate_key_derivation at TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE");
crypto::chacha_crypt(local_sa.body, derivation_local);
}
else
{
crypto::chacha_crypt(local_sa.body, derivation_local);
}
}
if (sa.flags&TX_SERVICE_ATTACHMENT_DEFLATE_BODY)
{
zlib_helper::unpack(local_sa.body);
}
if (sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_BODY && sa.flags&TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF)
{
CHECK_AND_ASSERT_MES(sa.security.size() == 1, void(), "Unexpected key in tx_service_attachment with TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE");
//take hash from derivation and use it as a salt
crypto::hash derivation_hash = crypto::cn_fast_hash(&derivation_local, sizeof(derivation_local));
std::string salted_body = local_sa.body;
string_tools::apped_pod_to_strbuff(salted_body, derivation_hash);
crypto::hash proof_hash = crypto::cn_fast_hash(salted_body.data(), salted_body.size());
CHECK_AND_ASSERT_MES(*(crypto::public_key*)&proof_hash == sa.security.front(), void(), "Proof hash missmatch on decrypting with TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF");
}
rdecrypted_att.push_back(local_sa);
}
@ -870,9 +931,10 @@ namespace currency
//---------------------------------------------------------------
template<class items_container_t>
bool decrypt_payload_items(const crypto::key_derivation& derivation, const items_container_t& items_to_decrypt, std::vector<payload_items_v>& decrypted_att)
bool decrypt_payload_items(const crypto::key_derivation& derivation, const items_container_t& items_to_decrypt, std::vector<payload_items_v>& decrypted_att, const account_keys& acc_keys = null_acc_keys,
const crypto::public_key& tx_onetime_pubkey = null_pkey)
{
decrypt_attach_visitor v(derivation, decrypted_att);
decrypt_attach_visitor v(derivation, decrypted_att, acc_keys, tx_onetime_pubkey);
for (auto& a : items_to_decrypt)
boost::apply_visitor(v, a);
@ -955,8 +1017,8 @@ namespace currency
return true;
}
decrypt_payload_items(derivation, tx.extra, decrypted_items);
decrypt_payload_items(derivation, tx.attachment, decrypted_items);
decrypt_payload_items(derivation, tx.extra, decrypted_items, is_income ? acc_keys: account_keys(), get_tx_pub_key_from_extra(tx));
decrypt_payload_items(derivation, tx.attachment, decrypted_items, is_income ? acc_keys : account_keys(), get_tx_pub_key_from_extra(tx));
return true;
}
@ -969,11 +1031,11 @@ namespace currency
bool was_attachment_crypted_entries = false;
bool was_extra_crypted_entries = false;
encrypt_attach_visitor v(was_attachment_crypted_entries, derivation);
encrypt_attach_visitor v(was_attachment_crypted_entries, derivation, tx_random_key, destination_addr);
for (auto& a : tx.attachment)
boost::apply_visitor(v, a);
encrypt_attach_visitor v2(was_extra_crypted_entries, derivation);
encrypt_attach_visitor v2(was_extra_crypted_entries, derivation, tx_random_key, destination_addr);
for (auto& a : tx.extra)
boost::apply_visitor(v2, a);
@ -2888,6 +2950,13 @@ namespace currency
return tools::base58::encode_addr(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX, t_serializable_object_to_blob(addr)); // new format Zano address (normal)
}
//-----------------------------------------------------------------------
bool is_address_like_wrapped(const std::string& addr)
{
if (addr.length() == 42 && addr.substr(0, 2) == "0x")
return true;
else return false;
}
//-----------------------------------------------------------------------
std::string get_account_address_and_payment_id_as_str(const account_public_address& addr, const payment_id_t& payment_id)
{
if (addr.flags == 0)

View file

@ -289,6 +289,7 @@ namespace currency
bool decrypt_payload_items(bool is_income, const transaction& tx, const account_keys& acc_keys, std::vector<payload_items_v>& decrypted_items);
void encrypt_attachments(transaction& tx, const account_keys& sender_keys, const account_public_address& destination_addr, const keypair& tx_random_key);
bool is_derivation_used_to_encrypt(const transaction& tx, const crypto::key_derivation& derivation);
bool is_address_like_wrapped(const std::string& addr);
void load_wallet_transfer_info_flags(tools::wallet_public::wallet_transfer_info& x);
uint64_t get_tx_type(const transaction& tx);
uint64_t get_tx_type_ex(const transaction& tx, tx_out& htlc_out, txin_htlc& htlc_in);

View file

@ -66,7 +66,6 @@ POP_VS_WARNINGS
#include <boost/serialization/variant.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/version.hpp>
#include <boost/spirit/home/support/detail/endian/endian.hpp>
#include <boost/thread.hpp>
#include <boost/timer/timer.hpp>
#include <boost/type_traits/is_arithmetic.hpp>

View file

@ -210,6 +210,7 @@ namespace currency
res.performance_data.tx_append_time = pd.tx_append_time.get_avg();
res.performance_data.tx_append_rl_wait = pd.tx_append_rl_wait.get_avg();
res.performance_data.tx_append_is_expired = pd.tx_append_is_expired.get_avg();
res.performance_data.tx_mixin_count = pd.tx_mixin_count.get_avg();
res.performance_data.tx_store_db = pd.tx_store_db.get_avg();

View file

@ -500,6 +500,8 @@ namespace currency
uint64_t tx_print_log;
uint64_t tx_prapare_append;
uint64_t tx_mixin_count;
uint64_t tx_store_db;
@ -547,6 +549,7 @@ namespace currency
KV_SERIALIZE(tx_store_db)
KV_SERIALIZE(tx_print_log)
KV_SERIALIZE(tx_prapare_append)
KV_SERIALIZE(tx_mixin_count)
KV_SERIALIZE(tx_check_inputs_prefix_hash)
KV_SERIALIZE(tx_check_inputs_attachment_check)

View file

@ -20,6 +20,7 @@
#include "wallet/wallet_rpc_server.h"
#include "version.h"
#include "string_coding.h"
#include "wallet/wrap_service.h"
#include <cstdlib>
@ -191,7 +192,7 @@ simple_wallet::simple_wallet()
m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, _1), "Show current wallet balance");
m_cmd_binder.set_handler("incoming_transfers", boost::bind(&simple_wallet::show_incoming_transfers, this, _1), "incoming_transfers [available|unavailable] - Show incoming transfers - all of them or filter them by availability");
m_cmd_binder.set_handler("incoming_counts", boost::bind(&simple_wallet::show_incoming_transfers_counts, this, _1), "incoming_transfers counts");
m_cmd_binder.set_handler("list_recent_transfers", boost::bind(&simple_wallet::list_recent_transfers, this, _1), "list_recent_transfers - Show recent maximum 1000 transfers");
m_cmd_binder.set_handler("list_recent_transfers", boost::bind(&simple_wallet::list_recent_transfers, this, _1), "list_recent_transfers [offset] [count] - Show recent maximum 1000 transfers, offset default = 0, count default = 100 ");
m_cmd_binder.set_handler("export_recent_transfers", boost::bind(&simple_wallet::export_recent_transfers, this, _1), "list_recent_transfers_tx - Write recent transfer in json to wallet_recent_transfers.txt");
m_cmd_binder.set_handler("list_outputs", boost::bind(&simple_wallet::list_outputs, this, _1), "list_outputs [spent|unspent] - Lists all the outputs that have ever been sent to this wallet if called without arguments, otherwise it lists only the spent or unspent outputs");
m_cmd_binder.set_handler("dump_transfers", boost::bind(&simple_wallet::dump_trunsfers, this, _1), "dump_transfers - Write transfers in json to dump_transfers.txt");
@ -753,7 +754,7 @@ bool print_wti(const tools::wallet_public::wallet_transfer_info& wti)
remote_side += remote_side.empty() ? it : (separator + it);
}
message_writer(cl) << epee::misc_utils::get_time_str_v2(wti.timestamp) << " "
success_msg_writer(cl) << "[" << wti.transfer_internal_index << "]" << epee::misc_utils::get_time_str_v2(wti.timestamp) << " "
<< (wti.is_income ? "Received " : "Sent ")
<< print_money(wti.amount) << "(fee:" << print_money(wti.fee) << ") "
<< remote_side
@ -765,9 +766,15 @@ bool simple_wallet::list_recent_transfers(const std::vector<std::string>& args)
{
std::vector<tools::wallet_public::wallet_transfer_info> unconfirmed;
std::vector<tools::wallet_public::wallet_transfer_info> recent;
uint64_t offset = 0;
if (args.size() > 0)
offset = std::stoll(args[0]);
uint64_t count = 1000;
if (args.size() > 1)
count = std::stoll(args[1]);
uint64_t total = 0;
uint64_t last_index = 0;
m_wallet->get_recent_transfers_history(recent, 0, 0, total, last_index, false);
m_wallet->get_recent_transfers_history(recent, offset, count, total, last_index, false, false);
m_wallet->get_unconfirmed_transfers(unconfirmed, false);
//workaround for missed fee
@ -1208,13 +1215,32 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
return true;
}
std::vector<extra_v> extra;
vector<currency::tx_destination_entry> dsts;
bool wrapped_transaction = false;
for (size_t i = 0; i < local_args.size(); i += 2)
{
std::string integrated_payment_id;
currency::tx_destination_entry de;
de.addr.resize(1);
if(!(de.addr.size() == 1 && m_wallet->get_transfer_address(local_args[i], de.addr.front(), integrated_payment_id)))
//check if address looks like wrapped address
if (is_address_like_wrapped(local_args[i]))
{
success_msg_writer(true) << "Address " << local_args[i] << " recognized as wrapped address, creating wrapping transaction...";
//put into service attachment specially encrypted entry which will contain wrap address and network
tx_service_attachment sa = AUTO_VAL_INIT(sa);
sa.service_id = BC_WRAP_SERVICE_ID;
sa.instruction = BC_WRAP_SERVICE_INSTRUCTION_ERC20;
sa.flags = TX_SERVICE_ATTACHMENT_ENCRYPT_BODY | TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE;
sa.body = local_args[i];
extra.push_back(sa);
currency::account_public_address acc = AUTO_VAL_INIT(acc);
currency::get_account_address_from_str(acc, BC_WRAP_SERVICE_CUSTODY_WALLET);
de.addr.front() = acc;
wrapped_transaction = true;
//encrypt body with a special way
}else if(!(de.addr.size() == 1 && m_wallet->get_transfer_address(local_args[i], de.addr.front(), integrated_payment_id)))
{
fail_msg_writer() << "wrong address: " << local_args[i];
return true;
@ -1258,13 +1284,19 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
try
{
currency::transaction tx;
std::vector<extra_v> extra;
m_wallet->transfer(dsts, fake_outs_count, 0, m_wallet->get_core_runtime_config().tx_default_fee, extra, attachments, tx);
if (!m_wallet->is_watch_only())
success_msg_writer(true) << "Money successfully sent, transaction " << get_transaction_hash(tx) << ", " << get_object_blobsize(tx) << " bytes";
{
if(wrapped_transaction)
success_msg_writer(true) << "Money successfully sent to wZano custody wallet, transaction " << get_transaction_hash(tx) << ", " << get_object_blobsize(tx) << " bytes";
else
success_msg_writer(true) << "Money successfully sent, transaction " << get_transaction_hash(tx) << ", " << get_object_blobsize(tx) << " bytes";
}
else
{
success_msg_writer(true) << "Transaction prepared for signing and saved into \"zano_tx_unsigned\" file, use full wallet to sign transfer and then use \"submit_transfer\" on this wallet to broadcast the transaction to the network";
}
}
catch (const tools::error::daemon_busy&)
{

View file

@ -5,9 +5,9 @@
#define PROJECT_MAJOR_VERSION "1"
#define PROJECT_MINOR_VERSION "2"
#define PROJECT_REVISION "0"
#define PROJECT_REVISION "1"
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
#define PROJECT_VERSION_BUILD_NO 121
#define PROJECT_VERSION_BUILD_NO 124
#define PROJECT_VERSION_BUILD_NO_STR STRINGIFY_EXPAND(PROJECT_VERSION_BUILD_NO)
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO_STR "[" BUILD_COMMIT_ID "]"

View file

@ -367,15 +367,30 @@ namespace plain_wallet
currency::account_public_address apa = AUTO_VAL_INIT(apa);
currency::payment_id_t pid = AUTO_VAL_INIT(pid);
bool valid = false;
if(currency::get_account_address_and_payment_id_from_str(apa, pid, addr))
bool wrap = false;
while (true)
{
valid = true;
if (currency::is_address_like_wrapped(addr))
{
wrap = true;
valid = true;
break;
}
if (currency::get_account_address_and_payment_id_from_str(apa, pid, addr))
{
valid = true;
}
break;
}
//lazy to make struct for it
std::stringstream res;
res << "{ \"valid\": " << (valid?"true":"false") << ", \"auditable\": "
<< (apa.is_auditable() ? "true" : "false")
<< ",\"payment_id\": " << (pid.size() ? "true" : "false") << "}";
<< ",\"payment_id\": " << (pid.size() ? "true" : "false")
<< ",\"wrap\": " << (wrap ? "true" : "false")
<< "}";
return res.str();
}

View file

@ -709,6 +709,15 @@ void wallet2::prepare_wti_decrypted_attachments(wallet_public::wallet_transfer_i
}
get_payment_id_from_tx(decrypted_att, wti.payment_id);
for (const auto& item : decrypted_att)
{
if (item.type() == typeid(currency::tx_service_attachment))
{
wti.service_entries.push_back(boost::get<currency::tx_service_attachment>(item));
}
}
if (wti.is_income)
{
account_public_address sender_address = AUTO_VAL_INIT(sender_address);
@ -1238,7 +1247,7 @@ void wallet2::prepare_wti(wallet_public::wallet_transfer_info& wti, uint64_t hei
wti.tx_blob_size = static_cast<uint32_t>(currency::get_object_blobsize(wti.tx));
wti.tx_hash = currency::get_transaction_hash(tx);
load_wallet_transfer_info_flags(wti);
bc_services::extract_market_instructions(wti.srv_attachments, tx.attachment);
bc_services::extract_market_instructions(wti.marketplace_entries, tx.attachment);
// escrow transactions, which are built with TX_FLAG_SIGNATURE_MODE_SEPARATE flag actually encrypt attachments
// with buyer as a sender, and seller as receiver, despite the fact that for both sides transaction seen as outgoing
@ -1654,7 +1663,7 @@ void wallet2::handle_pulled_blocks(size_t& blocks_added, std::atomic<bool>& stop
//block matched in that number
last_matched_index = height;
been_matched_block = true;
WLT_LOG_L2("Block " << bl_id << " @ " << height << " is already in wallet's blockchain");
WLT_LOG_L4("Block " << bl_id << " @ " << height << " is already in wallet's blockchain");
}
else
{
@ -3202,28 +3211,49 @@ uint64_t wallet2::get_transfer_entries_count()
return m_transfers.size();
}
//----------------------------------------------------------------------------------------------------
void wallet2::get_recent_transfers_history(std::vector<wallet_public::wallet_transfer_info>& trs, size_t offset, size_t count, uint64_t& total, uint64_t& last_item_index, bool exclude_mining_txs)
template<typename callback_t, typename iterator_t>
bool enum_container(iterator_t it_begin, iterator_t it_end, callback_t cb)
{
for (iterator_t it = it_begin; it != it_end; it++)
{
if (!cb(*it, it - it_begin))
return true;
}
return true;
}
//----------------------------------------------------------------------------------------------------
void wallet2::get_recent_transfers_history(std::vector<wallet_public::wallet_transfer_info>& trs, size_t offset, size_t count, uint64_t& total, uint64_t& last_item_index, bool exclude_mining_txs, bool start_from_end)
{
if (!count || offset >= m_transfer_history.size())
return;
for (auto it = m_transfer_history.rbegin() + offset; it != m_transfer_history.rend(); it++)
{
auto cb = [&](wallet_public::wallet_transfer_info& wti, size_t local_offset) {
if (exclude_mining_txs)
{
if(currency::is_coinbase(it->tx))
continue;
if (currency::is_coinbase(wti.tx))
return true;
}
trs.push_back(*it);
trs.push_back(wti);
load_wallet_transfer_info_flags(trs.back());
last_item_index = it - m_transfer_history.rbegin();
last_item_index = offset + local_offset;
trs.back().transfer_internal_index = last_item_index;
if (trs.size() >= count)
{
break;
return false;
}
}
return true;
};
if(start_from_end)
enum_container(m_transfer_history.rbegin() + offset, m_transfer_history.rend(), cb);
else
enum_container(m_transfer_history.begin() + offset, m_transfer_history.end(), cb);
total = m_transfer_history.size();
}
//----------------------------------------------------------------------------------------------------
bool wallet2::get_transfer_address(const std::string& adr_str, currency::account_public_address& addr, std::string& payment_id)
@ -4588,7 +4618,7 @@ bool wallet2::extract_offers_from_transfer_entry(size_t i, std::unordered_map<cr
case GUI_TX_TYPE_PUSH_OFFER:
{
bc_services::offer_details od;
if (!get_type_in_variant_container(m_transfer_history[i].srv_attachments, od))
if (!get_type_in_variant_container(m_transfer_history[i].marketplace_entries, od))
{
WLT_LOG_ERROR("Transaction history entry " << i << " market as type " << m_transfer_history[i].tx_type << " but get_type_in_variant_container returned false for bc_services::offer_details");
break;
@ -4609,7 +4639,7 @@ bool wallet2::extract_offers_from_transfer_entry(size_t i, std::unordered_map<cr
case GUI_TX_TYPE_UPDATE_OFFER:
{
bc_services::update_offer uo;
if (!get_type_in_variant_container(m_transfer_history[i].srv_attachments, uo))
if (!get_type_in_variant_container(m_transfer_history[i].marketplace_entries, uo))
{
WLT_LOG_ERROR("Transaction history entry " << i << " market as type " << m_transfer_history[i].tx_type << " but get_type_in_variant_container returned false for update_offer");
break;
@ -4641,7 +4671,7 @@ bool wallet2::extract_offers_from_transfer_entry(size_t i, std::unordered_map<cr
case GUI_TX_TYPE_CANCEL_OFFER:
{
bc_services::cancel_offer co;
if (!get_type_in_variant_container(m_transfer_history[i].srv_attachments, co))
if (!get_type_in_variant_container(m_transfer_history[i].marketplace_entries, co))
{
WLT_LOG_ERROR("Transaction history entry " << i << " market as type " << m_transfer_history[i].tx_type << " but get_type_in_variant_container returned false for cancel_offer");
break;

View file

@ -509,7 +509,7 @@ namespace tools
currency::account_base& get_account() { return m_account; }
const currency::account_base& get_account() const { return m_account; }
void get_recent_transfers_history(std::vector<wallet_public::wallet_transfer_info>& trs, size_t offset, size_t count, uint64_t& total, uint64_t& last_item_index, bool exclude_mining_txs = false);
void get_recent_transfers_history(std::vector<wallet_public::wallet_transfer_info>& trs, size_t offset, size_t count, uint64_t& total, uint64_t& last_item_index, bool exclude_mining_txs = false, bool start_from_end = true);
uint64_t get_recent_transfers_total_count();
uint64_t get_transfer_entries_count();
void get_unconfirmed_transfers(std::vector<wallet_public::wallet_transfer_info>& trs, bool exclude_mining_txs = false);
@ -595,12 +595,12 @@ namespace tools
void transfer(construct_tx_param& ctp,
currency::transaction &tx,
bool send_to_network,
std::string* p_unsigned_filename_or_tx_blob_str);
std::string* p_unsigned_filename_or_tx_blob_str = nullptr);
void transfer(construct_tx_param& ctp,
currency::finalized_tx& result,
bool send_to_network,
std::string* p_unsigned_filename_or_tx_blob_str);
std::string* p_unsigned_filename_or_tx_blob_str = nullptr);
template<typename destination_split_strategy_t>
@ -860,6 +860,7 @@ namespace tools
uint64_t get_sync_progress();
uint64_t get_wallet_file_size()const;
void set_use_deffered_global_outputs(bool use);
construct_tx_param get_default_construct_tx_param_inital();
/*
create_htlc_proposal: if htlc_hash == null_hash, then this wallet is originator of the atomic process, and
@ -949,7 +950,7 @@ private:
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const wallet_public::wallet_transfer_info& wti) const;
void change_contract_state(wallet_public::escrow_contract_details_basic& contract, uint32_t new_state, const crypto::hash& contract_id, const std::string& reason = "internal intention") const;
construct_tx_param get_default_construct_tx_param_inital();
const construct_tx_param& get_default_construct_tx_param();
uint64_t get_tx_expiration_median() const;
@ -1062,10 +1063,9 @@ private:
} // namespace tools
BOOST_CLASS_VERSION(tools::wallet2, WALLET_FILE_SERIALIZATION_VERSION)
BOOST_CLASS_VERSION(tools::wallet_public::wallet_transfer_info, 9)
BOOST_CLASS_VERSION(tools::wallet_public::wallet_transfer_info, 10)
BOOST_CLASS_VERSION(tools::wallet2::transfer_details, 3)
namespace boost
{
namespace serialization
@ -1147,8 +1147,11 @@ namespace boost
a & x.comment;
a & x.contract;
a & x.selected_indicies;
a & x.srv_attachments;
a & x.marketplace_entries;
a & x.unlock_time;
if (ver < 10)
return;
a & x.service_entries;
}
template <class Archive>

View file

@ -105,16 +105,19 @@ namespace wallet_public
bool is_mining;
uint64_t tx_type;
wallet_transfer_info_details td;
std::vector<currency::tx_service_attachment> service_entries;
//not included in streaming serialization
uint64_t fee;
bool show_sender;
std::vector<escrow_contract_details> contract;
uint16_t extra_flags;
uint64_t transfer_internal_index;
//not included in kv serialization map
currency::transaction tx;
std::vector<uint64_t> selected_indicies;
std::list<bc_services::offers_attachment_t> srv_attachments;
std::list<bc_services::offers_attachment_t> marketplace_entries;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(amount)
@ -136,6 +139,8 @@ namespace wallet_public
KV_SERIALIZE(tx_type)
KV_SERIALIZE(show_sender)
KV_SERIALIZE(contract)
KV_SERIALIZE(service_entries)
KV_SERIALIZE(transfer_internal_index)
END_KV_SERIALIZE_MAP()
};
@ -254,6 +259,7 @@ namespace wallet_public
uint64_t transfer_entries_count;
bool is_whatch_only;
std::vector<std::string> utxo_distribution;
uint64_t current_height;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(address)
@ -262,6 +268,7 @@ namespace wallet_public
KV_SERIALIZE(transfer_entries_count)
KV_SERIALIZE(is_whatch_only)
KV_SERIALIZE(utxo_distribution)
KV_SERIALIZE(current_height)
END_KV_SERIALIZE_MAP()
};
};
@ -299,6 +306,7 @@ namespace wallet_public
uint64_t transfer_entries_count;
uint64_t balance;
uint64_t unlocked_balance;
uint64_t curent_height;
BEGIN_KV_SERIALIZE_MAP()
@ -306,9 +314,14 @@ namespace wallet_public
KV_SERIALIZE(transfer_entries_count)
KV_SERIALIZE(balance)
KV_SERIALIZE(unlocked_balance)
KV_SERIALIZE(curent_height)
END_KV_SERIALIZE_MAP()
};
#define ORDER_FROM_BEGIN_TO_END "FROM_BEGIN_TO_END"
#define ORDER_FROM_FROM_END_TO_BEGIN "FROM_END_TO_BEGIN"
struct COMMAND_RPC_GET_RECENT_TXS_AND_INFO
{
struct request
@ -329,12 +342,16 @@ namespace wallet_public
*/
bool update_provision_info;
bool exclude_mining_txs;
bool exclude_unconfirmed;
std::string order; // "FROM_BEGIN_TO_END" or "FROM_END_TO_BEGIN"
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(offset)
KV_SERIALIZE(count)
KV_SERIALIZE(update_provision_info)
KV_SERIALIZE(exclude_mining_txs)
KV_SERIALIZE(exclude_unconfirmed)
KV_SERIALIZE(order)
END_KV_SERIALIZE_MAP()
};
@ -379,16 +396,19 @@ namespace wallet_public
std::string comment;
bool push_payer;
bool hide_receiver;
std::vector<currency::tx_service_attachment> service_entries;
bool service_entries_permanent;
BEGIN_KV_SERIALIZE_MAP()
KV_SERIALIZE(destinations)
KV_SERIALIZE(fee)
KV_SERIALIZE(mixin)
//KV_SERIALIZE(unlock_time)
KV_SERIALIZE(payment_id)
KV_SERIALIZE(comment)
KV_SERIALIZE(push_payer)
KV_SERIALIZE(hide_receiver)
KV_SERIALIZE(service_entries)
KV_SERIALIZE(service_entries_permanent)
END_KV_SERIALIZE_MAP()
};

View file

@ -208,6 +208,7 @@ namespace tools
for (const auto& ent : distribution)
res.utxo_distribution.push_back(currency::print_money_brief(ent.first) + ":" + std::to_string(ent.second));
res.current_height = m_wallet.get_top_block_height();
return true;
}
catch (std::exception& e)
@ -245,12 +246,18 @@ namespace tools
res.pi.balance = m_wallet.balance(res.pi.unlocked_balance);
res.pi.transfer_entries_count = m_wallet.get_transfer_entries_count();
res.pi.transfers_count = m_wallet.get_recent_transfers_total_count();
res.pi.curent_height = m_wallet.get_top_block_height();
}
if (req.offset == 0)
if (req.offset == 0 && !req.exclude_unconfirmed)
m_wallet.get_unconfirmed_transfers(res.transfers, req.exclude_mining_txs);
m_wallet.get_recent_transfers_history(res.transfers, req.offset, req.count, res.total_transfers, res.last_item_index, req.exclude_mining_txs);
bool start_from_end = true;
if (req.order == ORDER_FROM_BEGIN_TO_END)
{
start_from_end = false;
}
m_wallet.get_recent_transfers_history(res.transfers, req.offset, req.count, res.total_transfers, res.last_item_index, req.exclude_mining_txs, start_from_end);
return true;
}
@ -279,7 +286,18 @@ namespace tools
return false;
}
std::vector<currency::tx_destination_entry> dsts;
construct_tx_param ctp = m_wallet.get_default_construct_tx_param_inital();
if (req.service_entries_permanent)
{
//put it to extra
ctp.extra.insert(ctp.extra.end(), req.service_entries.begin(), req.service_entries.end());
}
else
{
//put it to attachments
ctp.attachments.insert(ctp.extra.end(), req.service_entries.begin(), req.service_entries.end());
}
std::vector<currency::tx_destination_entry>& dsts = ctp.dsts;
for (auto it = req.destinations.begin(); it != req.destinations.end(); it++)
{
currency::tx_destination_entry de;
@ -306,8 +324,8 @@ namespace tools
}
try
{
std::vector<currency::attachment_v> attachments;
std::vector<currency::extra_v> extra;
std::vector<currency::attachment_v>& attachments = ctp.attachments;
std::vector<currency::extra_v>& extra = ctp.extra;
if (!payment_id.empty() && !currency::set_payment_id_to_tx(attachments, payment_id))
{
er.code = WALLET_RPC_ERROR_CODE_WRONG_PAYMENT_ID;
@ -336,10 +354,11 @@ namespace tools
}
}
currency::transaction tx;
currency::finalized_tx result = AUTO_VAL_INIT(result);
std::string unsigned_tx_blob_str;
m_wallet.transfer(dsts, req.mixin, 0/*req.unlock_time*/, req.fee, extra, attachments, detail::ssi_digit, tx_dust_policy(DEFAULT_DUST_THRESHOLD), tx, CURRENCY_TO_KEY_OUT_RELAXED, true, 0, true, &unsigned_tx_blob_str);
ctp.fee = req.fee;
ctp.fake_outputs_count = 0;
m_wallet.transfer(ctp, result, true, &unsigned_tx_blob_str);
if (m_wallet.is_watch_only())
{
res.tx_unsigned_hex = epee::string_tools::buff_to_hex_nodelimer(unsigned_tx_blob_str); // watch-only wallets could not sign and relay transactions
@ -347,8 +366,8 @@ namespace tools
}
else
{
res.tx_hash = epee::string_tools::pod_to_hex(currency::get_transaction_hash(tx));
res.tx_size = get_object_blobsize(tx);
res.tx_hash = epee::string_tools::pod_to_hex(currency::get_transaction_hash(result.tx));
res.tx_size = get_object_blobsize(result.tx);
}
return true;
}

View file

@ -66,10 +66,10 @@ namespace tools
MAP_JON_RPC_WE("marketplace_push_update_offer", on_marketplace_push_update_offer, wallet_public::COMMAND_MARKETPLACE_PUSH_UPDATE_OFFER)
MAP_JON_RPC_WE("marketplace_cancel_offer", on_marketplace_cancel_offer, wallet_public::COMMAND_MARKETPLACE_CANCEL_OFFER)
//HTLC API
MAP_JON_RPC_WE("atomics_create_htlc_proposal", on_create_htlc_proposal, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL)
MAP_JON_RPC_WE("atomics_get_list_of_active_htlc", on_get_list_of_active_htlc, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC)
MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC)
MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED)
MAP_JON_RPC_WE("atomics_create_htlc_proposal", on_create_htlc_proposal, wallet_public::COMMAND_CREATE_HTLC_PROPOSAL)
MAP_JON_RPC_WE("atomics_get_list_of_active_htlc", on_get_list_of_active_htlc, wallet_public::COMMAND_GET_LIST_OF_ACTIVE_HTLC)
MAP_JON_RPC_WE("atomics_redeem_htlc", on_redeem_htlc, wallet_public::COMMAND_REDEEM_HTLC)
MAP_JON_RPC_WE("atomics_check_htlc_redeemed", on_check_htlc_redeemed, wallet_public::COMMAND_CHECK_HTLC_REDEEMED)
END_JSON_RPC_MAP()
END_URI_MAP2()

View file

@ -1753,7 +1753,11 @@ std::string wallets_manager::get_offers_ex(const bc_services::core_offers_filter
std::string wallets_manager::validate_address(const std::string& addr_str, std::string& payment_id)
{
currency::account_public_address acc = AUTO_VAL_INIT(acc);
if (currency::get_account_address_and_payment_id_from_str(acc, payment_id, addr_str))
if (currency::is_address_like_wrapped(addr_str))
{
return API_RETURN_CODE_TRUE;
}
else if (currency::get_account_address_and_payment_id_from_str(acc, payment_id, addr_str))
return API_RETURN_CODE_TRUE;
else
return API_RETURN_CODE_FALSE;

13
src/wallet/wrap_service.h Normal file
View file

@ -0,0 +1,13 @@
// Copyright (c) 2014-2018 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#define BC_WRAP_SERVICE_ID "W"
#define BC_WRAP_SERVICE_INSTRUCTION_ERC20 "ERC20" //erc20 wrap operation
#define BC_WRAP_SERVICE_INSTRUCTION_UNWRAP "UNWRAP" //erc20 unwrap operation
#define BC_WRAP_SERVICE_CUSTODY_WALLET "aZxaszi4TaDCUqRCmqe23HASryshQNHmBSFnUN1pY8VsRfss2ZSMGBpLhdFtHgKmFr353NneaYRT6CpSz7zA3EC9bocQcq7m9nP"

View file

@ -1029,6 +1029,9 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(atomic_test_wrong_redeem_wrong_refund);
GENERATE_AND_PLAY(atomic_test_altchain_simple);
GENERATE_AND_PLAY(atomic_test_check_hardfork_rules);
GENERATE_AND_PLAY(isolate_auditable_and_proof);
// GENERATE_AND_PLAY(gen_block_reward);

View file

@ -39,3 +39,4 @@
#include "hard_fork_1.h"
#include "hard_fork_2.h"
#include "atomic_tests.h"
#include "isolate_auditable_and_proof.h"

View file

@ -0,0 +1,125 @@
// Copyright (c) 2014-2021 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "chaingen.h"
#include "escrow_wallet_tests.h"
#include "random_helper.h"
#include "chaingen_helpers.h"
#include "isolate_auditable_and_proof.h"
#include "wallet/wrap_service.h"
#include "wallet/wallet_rpc_server.h"
using namespace epee;
using namespace crypto;
using namespace currency;
isolate_auditable_and_proof::isolate_auditable_and_proof()
{
REGISTER_CALLBACK_METHOD(isolate_auditable_and_proof, c1);
REGISTER_CALLBACK_METHOD(isolate_auditable_and_proof, configure_core);
}
bool isolate_auditable_and_proof::generate(std::vector<test_event_entry>& events) const
{
random_state_test_restorer::reset_random(0); // to make the test deterministic
m_genesis_timestamp = 1450000000;
test_core_time::adjust(m_genesis_timestamp);
epee::debug::get_set_enable_assert(true, true);
currency::account_base genesis_acc;
genesis_acc.generate();
m_mining_accunt.generate();
m_mining_accunt.set_createtime(m_genesis_timestamp);
block blk_0 = AUTO_VAL_INIT(blk_0);
generator.construct_genesis_block(blk_0, genesis_acc, test_core_time::get_time());
events.push_back(blk_0);
DO_CALLBACK(events, "configure_core");
REWIND_BLOCKS_N(events, blk_0r, blk_0, m_mining_accunt, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5);
DO_CALLBACK(events, "c1");
epee::debug::get_set_enable_assert(true, false);
return true;
}
bool isolate_auditable_and_proof::configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
return true;
}
/************************************************************************/
/* */
/************************************************************************/
bool isolate_auditable_and_proof::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
epee::debug::get_set_enable_assert(true, true);
misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&](){epee::debug::get_set_enable_assert(true, false); });
LOG_PRINT_MAGENTA("Mining Address: " << currency::get_account_address_as_str(m_mining_accunt.get_public_address()), LOG_LEVEL_0);
currency::account_base auditable_test;
auditable_test.generate(true);
auditable_test.set_createtime(m_genesis_timestamp);
LOG_PRINT_MAGENTA(": " << currency::get_account_address_as_str(auditable_test.get_public_address()), LOG_LEVEL_0);
std::shared_ptr<tools::wallet2> auditable_test_instance = init_playtime_test_wallet(events, c, auditable_test);
#define AMOUNT_TO_TRANSFER_LOCAL (TESTS_DEFAULT_FEE*10)
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, m_mining_accunt);
miner_wlt->refresh();
//create transaction that use TX_SERVICE_ATTACHMENT_ENCRYPT_BODY and TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE
//{
std::vector<extra_v> extra;
std::vector<currency::attachment_v> attachments;
std::vector<currency::tx_destination_entry> dsts;
currency::tx_destination_entry de;
de.addr.resize(1);
//put into service attachment specially encrypted entry which will contain wrap address and network
tx_service_attachment sa = AUTO_VAL_INIT(sa);
sa.service_id = BC_WRAP_SERVICE_ID;
sa.instruction = BC_WRAP_SERVICE_INSTRUCTION_ERC20;
sa.flags = TX_SERVICE_ATTACHMENT_ENCRYPT_BODY | TX_SERVICE_ATTACHMENT_ENCRYPT_BODY_ISOLATE_AUDITABLE| TX_SERVICE_ATTACHMENT_ENCRYPT_ADD_PROOF;
sa.body = "0xAb5801a7D398351b8bE11C439e05C5B3259aeC9B";
extra.push_back(sa);
currency::account_public_address acc = AUTO_VAL_INIT(acc);
de.addr.front() = auditable_test.get_public_address();
de.amount = AMOUNT_TO_TRANSFER_LOCAL;
dsts.push_back(de);
currency::transaction tx = AUTO_VAL_INIT(tx);
miner_wlt->transfer(dsts, 0, 0, miner_wlt->get_core_runtime_config().tx_default_fee, extra, attachments, tx);
//}
bool r = mine_next_pow_blocks_in_playtime(m_mining_accunt.get_public_address(), c, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
CHECK_AND_ASSERT_MES(r, false, "mine_next_pow_blocks_in_playtime failed");
miner_wlt->refresh();
auditable_test_instance->refresh();
epee::json_rpc::error je;
tools::wallet_rpc_server::connection_context ctx;
tools::wallet_rpc_server miner_wlt_rpc(*auditable_test_instance);
tools::wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO::request req = AUTO_VAL_INIT(req);
tools::wallet_public::COMMAND_RPC_GET_RECENT_TXS_AND_INFO::response res = AUTO_VAL_INIT(res);
req.count = 100;
req.offset = 0;
miner_wlt_rpc.on_get_recent_txs_and_info(req, res, je, ctx);
CHECK_AND_ASSERT_MES(res.transfers.size() == 1, false, "res.transfers.size() == 1 failed");
CHECK_AND_ASSERT_MES(res.transfers[0].service_entries.size(), false, "res.transfers[0].service_entries.size() failed");
CHECK_AND_ASSERT_MES(res.transfers[0].service_entries[0].body == sa.body, false, "res.transfers[0].service_entries[0].body == sa.body failed");
CHECK_AND_ASSERT_MES(res.transfers[0].service_entries[0].service_id == sa.service_id, false, "res.transfers[0].service_entries[0].service_id == sa.service_id failed");
CHECK_AND_ASSERT_MES(res.transfers[0].service_entries[0].instruction == sa.instruction, false, "res.transfers[0].service_entries[0].instruction == sa.instruction failed");
return true;
}

View file

@ -0,0 +1,19 @@
// Copyright (c) 2014-2021 Zano Project
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#pragma once
#include "chaingen.h"
#include "wallet_tests_basic.h"
struct isolate_auditable_and_proof : public wallet_test
{
isolate_auditable_and_proof();
bool generate(std::vector<test_event_entry>& events) const;
virtual bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
virtual bool configure_core(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
protected:
mutable uint64_t m_genesis_timestamp;
mutable currency::account_base m_mining_accunt;
};

View file

@ -1097,6 +1097,52 @@ TEST(crypto, point_basics)
return true;
}
TEST(crypto, neg_identity)
{
point_t z = c_point_0; // 0 group element (identity)
public_key z_pk = z.to_public_key(); // pub key, corresponding to 0 ge (pub key is not zero bitwise)
public_key z_neg_pk = z_pk;
((unsigned char*)&z_neg_pk)[31] = 0x80; // set sign bit manually
std::cout << "-Identity = " << z_pk << ENDL;
point_t z_neg;
ASSERT_FALSE(z_neg.from_public_key(z_neg_pk)); // negative identity should not be loaded
key_image z_ki;
memset(&z_ki, 0, sizeof(z_ki));
((unsigned char*)&z_ki)[00] = 0x01; // y = 1
ASSERT_TRUE(validate_key_image(z_ki));
key_image z_neg_ki = z_ki;
((unsigned char*)&z_neg_ki)[31] = 0x80; // set sign bit manually
ASSERT_FALSE(validate_key_image(z_neg_ki)); // negative identity should not be loaded
// also do zero-byte pub key / key image checks
public_key zzz_pk;
memset(&zzz_pk, 0, sizeof public_key);
ASSERT_TRUE(check_key(zzz_pk));
point_t zzz;
ASSERT_TRUE(zzz.from_public_key(zzz_pk));
ASSERT_FALSE(zzz.is_in_main_subgroup());
key_image zzz_ki;
memset(&zzz_ki, 0, sizeof key_image);
ASSERT_FALSE(validate_key_image(zzz_ki));
point_t zzz2;
ASSERT_TRUE(zzz2.from_key_image(zzz_ki));
ASSERT_FALSE(zzz2.is_in_main_subgroup());
ASSERT_EQ(zzz, zzz2);
return true;
}
TEST(crypto, scalar_reciprocal)
{
int64_t test_nums[] = { 1, 2, 10 };

View file

@ -33,8 +33,20 @@ int main(int argc, char** argv)
epee::log_space::log_singletone::get_default_log_file().c_str(),
epee::log_space::log_singletone::get_default_log_folder().c_str());
std::string buf1 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_ADDRESS_BASE58_PREFIX);
std::string buf2 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_BASE58_PREFIX);
std::string buf3 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_INTEG_ADDRESS_V2_BASE58_PREFIX);
std::string buf4 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_AUDITABLE_ADDRESS_BASE58_PREFIX);
std::string buf5 = tools::get_varint_data<uint64_t>(CURRENCY_PUBLIC_AUDITABLE_INTEG_ADDRESS_BASE58_PREFIX);
std::cout << "Buf1: " << epee::string_tools::buff_to_hex_nodelimer(buf1) << ENDL;
std::cout << "Buf2: " << epee::string_tools::buff_to_hex_nodelimer(buf2) << ENDL;
std::cout << "Buf3: " << epee::string_tools::buff_to_hex_nodelimer(buf3) << ENDL;
std::cout << "Buf4: " << epee::string_tools::buff_to_hex_nodelimer(buf4) << ENDL;
std::cout << "Buf5: " << epee::string_tools::buff_to_hex_nodelimer(buf5) << ENDL;
do_htlc_hash_tests();
//run_serialization_performance_test();
//return 1;

View file

@ -1,4 +1,5 @@
set -x #echo on
set -x # echo on
set +e # switch off exit on error
curr_path=${BASH_SOURCE%/*}
# check that all the required environment vars are set
@ -21,6 +22,11 @@ if [ "$testnet" == true ]; then
ARCHIVE_NAME_PREFIX=${ARCHIVE_NAME_PREFIX}testnet-
fi
######### DEBUG ##########
#cd "$ZANO_BUILD_DIR/release/src"
#rm *.dmg
#if false; then
##### end of DEBUG ######
rm -rf $ZANO_BUILD_DIR; mkdir -p "$ZANO_BUILD_DIR/release"; cd "$ZANO_BUILD_DIR/release"
@ -101,12 +107,13 @@ if [ $? -ne 0 ]; then
exit 1
fi
codesign -s "Zano" --deep -vv -f Zano.app
codesign -s "Developer ID Application: Zano Limited" --timestamp --options runtime -f --entitlements ../../../utils/macos_entitlements.plist --deep ./Zano.app
if [ $? -ne 0 ]; then
echo "Failed to sign application"
echo "Failed to sign Zano.app"
exit 1
fi
read version_str <<< $(DYLD_LIBRARY_PATH=$ZANO_BOOST_LIBS_PATH ./connectivity_tool --version | awk '/^Zano/ { print $2 }')
version_str=${version_str}
echo $version_str
@ -125,6 +132,8 @@ if [ $? -ne 0 ]; then
exit 1
fi
#fi
package_filename=${ARCHIVE_NAME_PREFIX}${version_str}.dmg
source ../../../utils/macosx_dmg_builder.sh
@ -134,12 +143,11 @@ if [ $? -ne 0 ]; then
exit 1
fi
cd ../../..
echo "Build success"
echo "############### Uploading... ################"
package_filepath=$ZANO_BUILD_DIR/release/src/$package_filename
package_filepath=$package_filename
scp $package_filepath zano_build_server:/var/www/html/builds/
if [ $? -ne 0 ]; then
@ -157,3 +165,58 @@ sha256: $checksum"
echo "$mail_msg"
echo "$mail_msg" | mail -s "Zano macOS-x64 ${build_prefix_label}${testnet_label}build $version_str" ${emails}
######################
# notarization
######################
cd package_folder
echo "Notarizing..."
# creating archive for notarizing
echo "Creating archive for notarizing"
rm -f Zano.zip
/usr/bin/ditto -c -k --keepParent ./Zano.app ./Zano.zip
tmpfile="tmptmptmp"
xcrun altool --notarize-app --primary-bundle-id "org.zano.desktop" -u "andrey@zano.org" -p "@keychain:Developer-altool" --file ./Zano.zip > $tmpfile 2>&1
NOTARIZE_RES=$?
NOTARIZE_OUTPUT=$( cat $tmpfile )
rm $tmpfile
echo "NOTARIZE_OUTPUT=$NOTARIZE_OUTPUT"
if [ $NOTARIZE_RES -ne 0 ]; then
echo "Notarization failed"
exit 1
fi
GUID=$(echo "$NOTARIZE_OUTPUT" | egrep -Ewo '[[:xdigit:]]{8}(-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}')
if [ ${#GUID} -ne 36 ]; then
echo "Couldn't get correct GUID from the response, got only \"$GUID\""
exit 1
fi
success=0
# check notarization status
for i in {1..10}; do
xcrun altool --notarization-info $GUID -u "andrey@zano.org" -p "@keychain:Developer-altool" > $tmpfile 2>&1
NOTARIZE_OUTPUT=$( cat $tmpfile )
rm $tmpfile
NOTARIZATION_LOG_URL=$(echo "$NOTARIZE_OUTPUT" | sed -n "s/.*LogFileURL\: \([[:graph:]]*\).*/\1/p")
if [ ${#NOTARIZATION_LOG_URL} -ge 30 ]; then
success=1
curl -L $NOTARIZATION_LOG_URL
break
fi
sleep 60
done
if [ $success -ne 1 ]; then
echo "Build notarization failed"
exit 1
fi
echo "Notarization done"

View file

@ -170,11 +170,11 @@ set installer_path=%BUILDS_PATH%\builds\%installer_file%
@echo " SIGNING ...."
:: %ZANO_SIGN_CMD% %installer_path%
:: IF %ERRORLEVEL% NEQ 0 (
:: @echo "failed to sign installer"
:: goto error
:: )
%ZANO_SIGN_CMD% %installer_path%
IF %ERRORLEVEL% NEQ 0 (
@echo "failed to sign installer"
goto error
)
@echo " UPLOADING TO SERVER ...."

View file

@ -0,0 +1,8 @@
@echo off
rem
rem This file contains local path settings for your own personal dev environment.
rem Rename to configure_local_paths.cmd and do not commit.
rem
set QT_PREFIX_PATH=C:\dev\_sdk\Qt5.15.2\5.15.2
set BOOST_ROOT=C:\dev\_sdk\boost_1_76_0

View file

@ -0,0 +1,7 @@
call configure_local_paths_msvs2019.cmd
cd ..
@mkdir build_msvc2019_64_tn
cd build_msvc2019_64_tn
cmake -D TESTNET=TRUE -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2019_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.2" -G "Visual Studio 16 2019" -A x64 -T host=x64 ".."

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
</dict>
</plist>

View file

@ -19,6 +19,7 @@ function build_fancy_dmg() # $1 - path to package folder, $2 - dmg output filena
--icon Zano.app 112 115 \
--hide-extension Zano.app \
--app-drop-link 365 115 \
--no-internet-enable \
$2 \
$1

View file

@ -5,7 +5,7 @@ case $1 in
cat <<'EOM'
graph_title performance_transactions
graph_vlabel mcs
graph_category daemon
graph_category transactions
tx_add_one_tx_time.label tx_add_one_tx_time
tx_add_one_tx_time.draw LINE
tx_append_time.label tx_append_time

View file

@ -5,7 +5,7 @@ case $1 in
cat <<'EOM'
graph_title performance_tranactions_inp
graph_vlabel mcs
graph_category daemon.inp
graph_category transactions.inp
tx_check_inputs_prefix_hash.label prefix_hash
tx_check_inputs_prefix_hash.draw AREA
tx_check_inputs_attachment_check.label attachment_check

View file

@ -5,7 +5,7 @@ case $1 in
cat <<'EOM'
graph_title performance_tranactions_inp.every_inp
graph_vlabel mcs
graph_category daemon.inp
graph_category transactions.inp
tx_check_inputs_loop_kimage_check.label kimage_check
tx_check_inputs_loop_kimage_check.draw AREA
tx_check_inputs_loop_ch_in_val_sig.label ch_in_val_sig

View file

@ -5,7 +5,7 @@ case $1 in
cat <<'EOM'
graph_title performance_tranactions_inp.every_inp.every_key
graph_vlabel mcs
graph_category daemon.inp
graph_category transactions.inp
tx_check_inputs_loop_scan_outputkeys_loop_get_subitem.label get_subitem
tx_check_inputs_loop_scan_outputkeys_loop_get_subitem.draw AREA
tx_check_inputs_loop_scan_outputkeys_loop_find_tx.label find_tx

View file

@ -0,0 +1,17 @@
#!/bin/bash
case $1 in
config)
cat <<'EOM'
graph_args --alt-autoscale
graph_title mixins
graph_vlabel mixins
graph_category transactions
mixins.label mixins
EOM
exit 0;;
esac
printf "mixins.value "
connectivity_tool --ip=127.0.0.1 --rpc-port=$ZANO_RPC_PORT --timeout=1000 --rpc-get-daemon-info --getinfo-flags-hex="0x0000000000010000" | grep tx_mixin_count | cut -d ' ' -f2