forked from lthn/blockchain
Merge branch 'release'
This commit is contained in:
commit
c070839a28
81 changed files with 2843 additions and 1538 deletions
4
.gitmodules
vendored
4
.gitmodules
vendored
|
|
@ -5,3 +5,7 @@
|
|||
path = src/gui/qt-daemon/layout
|
||||
url = https://github.com/hyle-team/zano_ui.git
|
||||
branch = main
|
||||
[submodule "contrib/tor-connect"]
|
||||
path = contrib/tor-connect
|
||||
url = https://github.com/hyle-team/tor-connect.git
|
||||
branch = main
|
||||
|
|
@ -56,18 +56,23 @@ if(APPLE)
|
|||
endif()
|
||||
|
||||
set(USE_PCH FALSE CACHE BOOL "Use shared precompiled headers")
|
||||
set(DISABLE_TOR FALSE CACHE BOOL "Disable TOR library(and related tor-connect submodule)")
|
||||
set(TESTNET FALSE CACHE BOOL "Compile for testnet")
|
||||
set(BUILD_GUI FALSE CACHE BOOL "Build qt-daemon")
|
||||
|
||||
include_directories(src contrib/eos_portable_archive contrib contrib/epee/include "${CMAKE_BINARY_DIR}/version" "${CMAKE_BINARY_DIR}/contrib/zlib")
|
||||
|
||||
add_definitions(-DSTATICLIB)
|
||||
|
||||
set(TESTNET FALSE CACHE BOOL "Compile for testnet")
|
||||
if(TESTNET)
|
||||
message("!!!!!! NOTICE: Project is building for TESTNET !!!!!!")
|
||||
add_definitions(-DTESTNET)
|
||||
endif()
|
||||
|
||||
set(BUILD_GUI FALSE CACHE BOOL "Build qt-daemon")
|
||||
if(DISABLE_TOR)
|
||||
message("NOTICE: Building with disabled TOR support!")
|
||||
add_definitions(-DDISABLE_TOR)
|
||||
endif()
|
||||
|
||||
|
||||
set(STATIC ${MSVC} CACHE BOOL "Link libraries statically")
|
||||
|
|
@ -197,7 +202,7 @@ elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
|||
set(Boost_LIBRARY_DIRS "${Boost_LIBRARY_DIRS}/${CMAKE_ANDROID_ARCH_ABI}/")
|
||||
set(Boost_LIBRARIES "${Boost_LIBRARY_DIRS}libboost_system.a;${Boost_LIBRARY_DIRS}libboost_filesystem.a;${Boost_LIBRARY_DIRS}libboost_thread.a;${Boost_LIBRARY_DIRS}libboost_timer.a;${Boost_LIBRARY_DIRS}libboost_date_time.a;${Boost_LIBRARY_DIRS}libboost_chrono.a;${Boost_LIBRARY_DIRS}libboost_regex.a;${Boost_LIBRARY_DIRS}libboost_serialization.a;${Boost_LIBRARY_DIRS}libboost_atomic.a;${Boost_LIBRARY_DIRS}libboost_program_options.a")
|
||||
else()
|
||||
find_package(Boost 1.55 REQUIRED COMPONENTS system filesystem thread timer date_time chrono regex serialization atomic program_options locale)
|
||||
find_package(Boost 1.70 REQUIRED COMPONENTS system filesystem thread timer date_time chrono regex serialization atomic program_options locale)
|
||||
endif()
|
||||
|
||||
|
||||
|
|
|
|||
51
README.md
51
README.md
|
|
@ -18,7 +18,8 @@ Be sure to clone the repository properly:\
|
|||
| [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.20 |
|
||||
| [Boost](https://www.boost.org/users/download/) | 1.56 | 1.68 | 1.76 |
|
||||
| [Boost](https://www.boost.org/users/download/) | 1.70 | 1.70 | 1.76 |
|
||||
| [OpenSSL](https://www.openssl.org/source/) [(win)](https://slproweb.com/products/Win32OpenSSL.html) | - | 1.1.1n | 1.1.1n |
|
||||
| [Qt](https://download.qt.io/archive/qt/) (*only for GUI*) | 5.8.0 | 5.11.2 | 5.15.2 |
|
||||
|
||||
Note:\
|
||||
|
|
@ -35,18 +36,18 @@ Recommended OS version: Ubuntu 18.04 LTS.
|
|||
|
||||
[*server version*]
|
||||
|
||||
sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen
|
||||
sudo apt-get install -y build-essential g++ python-dev autotools-dev libicu-dev libbz2-dev cmake git screen checkinstall zlib1g-dev
|
||||
|
||||
[*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 checkinstall zlib1g-dev mesa-common-dev libglu1-mesa-dev
|
||||
|
||||
2. Download and build Boost
|
||||
|
||||
wget https://boostorg.jfrog.io/artifactory/main/release/1.68.0/source/boost_1_68_0.tar.bz2
|
||||
tar -xjf boost_1_68_0.tar.bz2
|
||||
cd boost_1_68_0
|
||||
./bootstrap.sh --with-libraries=system,filesystem,thread,date_time,chrono,regex,serialization,atomic,program_options,locale,timer
|
||||
curl -OL https://boostorg.jfrog.io/artifactory/main/release/1.70.0/source/boost_1_70_0.tar.bz2
|
||||
tar -xjf boost_1_70_0.tar.bz2
|
||||
cd boost_1_70_0
|
||||
./bootstrap.sh --with-libraries=system,filesystem,thread,date_time,chrono,regex,serialization,atomic,program_options,locale,timer,log
|
||||
./b2
|
||||
|
||||
3. Install Qt\
|
||||
|
|
@ -54,28 +55,44 @@ Recommended OS version: Ubuntu 18.04 LTS.
|
|||
|
||||
[*GUI version*]
|
||||
|
||||
wget https://download.qt.io/new_archive/qt/5.11/5.11.2/qt-opensource-linux-x64-5.11.2.run
|
||||
curl -OL https://download.qt.io/new_archive/qt/5.11/5.11.2/qt-opensource-linux-x64-5.11.2.run
|
||||
chmod +x qt-opensource-linux-x64-5.11.2.run
|
||||
./qt-opensource-linux-x64-5.11.2.run
|
||||
Then follow the instructions in Wizard. Don't forget to tick the WebEngine module checkbox!
|
||||
|
||||
4. Set environment variables properly\
|
||||
|
||||
4. Install OpenSSL
|
||||
|
||||
We recommend installing OpenSSL v1.1.1n locally unless you would like to use the same version system-wide.
|
||||
|
||||
curl -OL https://www.openssl.org/source/openssl-1.1.1n.tar.gz
|
||||
tar xaf openssl-1.1.1n.tar.gz
|
||||
cd openssl-1.1.1n/
|
||||
./config --prefix=/home/user/openssl --openssldir=/home/user/openssl shared zlib
|
||||
make
|
||||
make test
|
||||
make install
|
||||
|
||||
|
||||
5. Set environment variables properly\
|
||||
For instance, by adding the following lines to `~/.bashrc`
|
||||
|
||||
[*server version*]
|
||||
|
||||
export BOOST_ROOT=/home/user/boost_1_68_0
|
||||
export BOOST_ROOT=/home/user/boost_1_70_0
|
||||
export OPENSSL_ROOT_DIR=/home/user/openssl
|
||||
|
||||
|
||||
[*GUI version*]
|
||||
|
||||
export BOOST_ROOT=/home/user/boost_1_68_0
|
||||
export BOOST_ROOT=/home/user/boost_1_70_0
|
||||
export OPENSSL_ROOT_DIR=/home/user/openssl
|
||||
export QT_PREFIX_PATH=/home/user/Qt5.11.2/5.11.2/gcc_64
|
||||
|
||||
|
||||
|
||||
5. Building binaries
|
||||
1. Building daemon and simplewallet:
|
||||
6. Build the binaries
|
||||
1. Build daemon and simplewallet:
|
||||
|
||||
cd zano/ && make -j1
|
||||
or
|
||||
|
|
@ -88,7 +105,7 @@ For instance, by adding the following lines to `~/.bashrc`
|
|||
|
||||
**NOTICE 2**: If you'd like to build binaries for the testnet, use `cmake -D TESTNET=TRUE ..` instead of `cmake ..` .
|
||||
|
||||
1. Building GUI:
|
||||
1. Build GUI:
|
||||
|
||||
cd zano
|
||||
utils/build_sript_linux.sh
|
||||
|
|
@ -99,9 +116,9 @@ For instance, by adding the following lines to `~/.bashrc`
|
|||
|
||||
### Windows
|
||||
Recommended OS version: Windows 7 x64.
|
||||
1. Install required prerequisites (Boost, Qt, CMake).
|
||||
1. Install required prerequisites (Boost, Qt, CMake, OpenSSL).
|
||||
2. Edit paths in `utils/configure_local_paths.cmd`.
|
||||
3. Run `utils/configure_win64_msvs2015_gui.cmd` or `utils/configure_win64_msvs2017_gui.cmd` according to your MSVC version.
|
||||
3. Run one of `utils/configure_win64_msvsNNNN_gui.cmd` according to your MSVC version.
|
||||
4. Go to the build folder and open generated Zano.sln in MSVC.
|
||||
5. Build.
|
||||
|
||||
|
|
@ -115,7 +132,7 @@ In order to correctly deploy Qt GUI application, you also need to do the followi
|
|||
<br />
|
||||
|
||||
### macOS
|
||||
Recommended OS version: macOS Sierra 10.15.4 x64.
|
||||
Recommended OS version: macOS Big Sur 11.4 x64.
|
||||
1. Install required prerequisites.
|
||||
2. Set environment variables as stated in `utils/macosx_build_config.command`.
|
||||
3. `mkdir build` <br> `cd build` <br> `cmake ..` <br> `make`
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@ add_subdirectory(zlib)
|
|||
add_subdirectory(db)
|
||||
add_subdirectory(ethereum)
|
||||
|
||||
if( NOT DISABLE_TOR)
|
||||
add_subdirectory(tor-connect)
|
||||
endif()
|
||||
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
message("excluded upnp support for IOS build")
|
||||
|
|
@ -17,6 +21,10 @@ set_property(TARGET libminiupnpc-static PROPERTY FOLDER "contrib")
|
|||
set_property(TARGET zlibstatic PROPERTY FOLDER "contrib")
|
||||
set_property(TARGET mdbx PROPERTY FOLDER "contrib")
|
||||
set_property(TARGET lmdb PROPERTY FOLDER "contrib")
|
||||
if( NOT DISABLE_TOR)
|
||||
set_property(TARGET tor-connect PROPERTY FOLDER "contrib")
|
||||
endif()
|
||||
|
||||
set_property(TARGET upnpc-static mdbx_chk mdbx_copy mdbx_dump mdbx_load mdbx_stat PROPERTY FOLDER "unused")
|
||||
|
||||
if(MSVC)
|
||||
|
|
|
|||
|
|
@ -3,10 +3,10 @@
|
|||
|
||||
#include "internals.h"
|
||||
|
||||
#if MDBX_VERSION_MAJOR != ${MDBX_VERSION_MAJOR} || \
|
||||
MDBX_VERSION_MINOR != ${MDBX_VERSION_MINOR}
|
||||
#error "API version mismatch! Had `git fetch --tags` done?"
|
||||
#endif
|
||||
//#if MDBX_VERSION_MAJOR != ${MDBX_VERSION_MAJOR} || \
|
||||
// MDBX_VERSION_MINOR != ${MDBX_VERSION_MINOR}
|
||||
//#error "API version mismatch! Had `git fetch --tags` done?"
|
||||
//#endif
|
||||
|
||||
static const char sourcery[] = STRINGIFY(MDBX_BUILD_SOURCERY);
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,8 @@
|
|||
#include <limits>
|
||||
#include <set>
|
||||
#include <iterator>
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <boost/thread.hpp>
|
||||
#include "include_base_utils.h"
|
||||
#include "auto_val_init.h"
|
||||
|
|
@ -111,17 +113,6 @@ namespace misc_utils
|
|||
return (std::numeric_limits<t_type>::max)();
|
||||
}
|
||||
|
||||
// TEMPLATE STRUCT less
|
||||
template<class _Ty>
|
||||
struct less_as_pod
|
||||
: public std::binary_function<_Ty, _Ty, bool>
|
||||
{ // functor for operator<
|
||||
bool operator()(const _Ty& _Left, const _Ty& _Right) const
|
||||
{ // apply operator< to operands
|
||||
return memcmp(&_Left, &_Right, sizeof(_Left)) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
template<class _Ty>
|
||||
bool is_less_as_pod(const _Ty& _Left, const _Ty& _Right)
|
||||
{ // apply operator< to operands
|
||||
|
|
|
|||
|
|
@ -693,7 +693,7 @@ bool boosted_tcp_server<t_protocol_handler>::connect(const std::string& adr, con
|
|||
shared_context->cond.notify_one();
|
||||
};
|
||||
|
||||
sock_.async_connect(remote_endpoint, boost::bind<void>(connect_callback, _1, local_shared_context));
|
||||
sock_.async_connect(remote_endpoint, boost::bind<void>(connect_callback, boost::placeholders::_1, local_shared_context));
|
||||
while(local_shared_context->ec == boost::asio::error::would_block) {
|
||||
bool r = false;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -831,7 +831,7 @@ using namespace std;
|
|||
return false;
|
||||
}else
|
||||
{ //Apparently there are no signs of the form of transfer, will receive data until the connection is closed
|
||||
m_state = reciev_machine_state_error;
|
||||
m_state = reciev_machine_state_body_connection_close;
|
||||
LOG_PRINT("Undefinded transfer type, consider http_body_transfer_connection_close method. header: " << m_header_cache, LOG_LEVEL_2);
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,11 +46,12 @@ namespace levin
|
|||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
class levin_client_impl
|
||||
template<typename transport_t>
|
||||
class levin_client_impl_t
|
||||
{
|
||||
public:
|
||||
levin_client_impl();
|
||||
virtual ~levin_client_impl();
|
||||
levin_client_impl_t();
|
||||
virtual ~levin_client_impl_t();
|
||||
|
||||
bool connect(u_long ip, int port, unsigned int timeout, const std::string& bind_ip = "0.0.0.0");
|
||||
bool connect(const std::string& addr, int port, unsigned int timeout, const std::string& bind_ip = "0.0.0.0");
|
||||
|
|
@ -61,26 +62,30 @@ namespace levin
|
|||
virtual int notify(int command, const std::string& in_buff);
|
||||
|
||||
protected:
|
||||
net_utils::blocked_mode_client m_transport;
|
||||
transport_t m_transport;
|
||||
//net_utils::blocked_mode_client m_transport;
|
||||
};
|
||||
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
class levin_client_impl2: public levin_client_impl
|
||||
template<typename transport_t>
|
||||
class levin_client_impl2: public levin_client_impl_t<transport_t>
|
||||
{
|
||||
public:
|
||||
|
||||
int invoke(int command, const std::string& in_buff, std::string& buff_out);
|
||||
int notify(int command, const std::string& in_buff);
|
||||
|
||||
transport_t& get_transport() {return this->m_transport;}
|
||||
};
|
||||
|
||||
}
|
||||
namespace net_utils
|
||||
{
|
||||
typedef levin::levin_client_impl levin_client;
|
||||
typedef levin::levin_client_impl2 levin_client2;
|
||||
typedef levin::levin_client_impl_t<net_utils::blocked_mode_client> levin_client;
|
||||
typedef levin::levin_client_impl2<net_utils::blocked_mode_client> levin_client2;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -32,175 +32,174 @@
|
|||
#include "string_tools.h"
|
||||
namespace epee
|
||||
{
|
||||
namespace levin
|
||||
{
|
||||
inline
|
||||
bool levin_client_impl::connect(u_long ip, int port, unsigned int timeout, const std::string& bind_ip)
|
||||
{
|
||||
return m_transport.connect(string_tools::get_ip_string_from_int32(ip), port, timeout, timeout, bind_ip);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
bool levin_client_impl::connect(const std::string& addr, int port, unsigned int timeout, const std::string& bind_ip)
|
||||
{
|
||||
return m_transport.connect(addr, port, timeout, timeout, bind_ip);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
bool levin_client_impl::is_connected()
|
||||
{
|
||||
return m_transport.is_connected();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
bool levin_client_impl::disconnect()
|
||||
{
|
||||
return m_transport.disconnect();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
levin_client_impl::levin_client_impl()
|
||||
{
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
levin_client_impl::~levin_client_impl()
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
int levin_client_impl::invoke(int command, const std::string& in_buff, std::string& buff_out)
|
||||
{
|
||||
if(!is_connected())
|
||||
return -1;
|
||||
|
||||
bucket_head head = {0};
|
||||
head.m_signature = LEVIN_SIGNATURE;
|
||||
head.m_cb = in_buff.size();
|
||||
head.m_have_to_return_data = true;
|
||||
head.m_command = command;
|
||||
if(!m_transport.send(&head, sizeof(head)))
|
||||
return -1;
|
||||
|
||||
if(!m_transport.send(in_buff))
|
||||
return -1;
|
||||
|
||||
std::string local_buff;
|
||||
if(!m_transport.recv_n(local_buff, sizeof(bucket_head)))
|
||||
return -1;
|
||||
|
||||
head = *(bucket_head*)local_buff.data();
|
||||
|
||||
|
||||
if(head.m_signature!=LEVIN_SIGNATURE)
|
||||
{
|
||||
LOG_PRINT_L0("Signature missmatch in response");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!m_transport.recv_n(buff_out, head.m_cb))
|
||||
return -1;
|
||||
|
||||
return head.m_return_code;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
int levin_client_impl::notify(int command, const std::string& in_buff)
|
||||
{
|
||||
if(!is_connected())
|
||||
return -1;
|
||||
|
||||
bucket_head head = {0};
|
||||
head.m_signature = LEVIN_SIGNATURE;
|
||||
head.m_cb = in_buff.size();
|
||||
head.m_have_to_return_data = false;
|
||||
head.m_command = command;
|
||||
|
||||
if(!m_transport.send((const char*)&head, sizeof(head)))
|
||||
return -1;
|
||||
|
||||
if(!m_transport.send(in_buff))
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
int levin_client_impl2::invoke(int command, const std::string& in_buff, std::string& buff_out)
|
||||
{
|
||||
if(!is_connected())
|
||||
return -1;
|
||||
|
||||
bucket_head2 head = {0};
|
||||
head.m_signature = LEVIN_SIGNATURE;
|
||||
head.m_cb = in_buff.size();
|
||||
head.m_have_to_return_data = true;
|
||||
head.m_command = static_cast<uint32_t>(command);
|
||||
head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
|
||||
head.m_flags = LEVIN_PACKET_REQUEST;
|
||||
if(!m_transport.send(&head, sizeof(head)))
|
||||
return -1;
|
||||
|
||||
if(!m_transport.send(in_buff))
|
||||
return -1;
|
||||
|
||||
//Since other side of connection could be running by async server,
|
||||
//we can receive some unexpected notify(forwarded broadcast notifications for example).
|
||||
//let's ignore every notify in the channel until we get invoke response
|
||||
std::string local_buff;
|
||||
|
||||
while (true)
|
||||
namespace levin
|
||||
{
|
||||
if (!m_transport.recv_n(local_buff, sizeof(bucket_head2)))
|
||||
return LEVIN_ERROR_NET_ERROR;
|
||||
|
||||
head = *(bucket_head2*)local_buff.data();
|
||||
if (head.m_signature != LEVIN_SIGNATURE)
|
||||
template<typename transport_t>
|
||||
bool levin_client_impl_t<transport_t>::connect(u_long ip, int port, unsigned int timeout, const std::string& bind_ip)
|
||||
{
|
||||
LOG_PRINT_L0("Signature missmatch in response");
|
||||
return LEVIN_ERROR_SIGNATURE_MISMATCH;
|
||||
return m_transport.connect(string_tools::get_ip_string_from_int32(ip), port, timeout, timeout, bind_ip);
|
||||
}
|
||||
if (!m_transport.recv_n(buff_out, head.m_cb))
|
||||
return LEVIN_ERROR_NET_ERROR;
|
||||
|
||||
//now check if this is response to invoke (and extra validate if it's response to this(!) invoke)
|
||||
if (head.m_flags&LEVIN_PACKET_RESPONSE)
|
||||
//------------------------------------------------------------------------------
|
||||
template<typename transport_t>
|
||||
bool levin_client_impl_t<transport_t>::connect(const std::string& addr, int port, unsigned int timeout, const std::string& bind_ip)
|
||||
{
|
||||
//we got response, extra validate if its response to our request
|
||||
CHECK_AND_ASSERT_MES(head.m_command == static_cast<uint32_t>(command), LEVIN_ERROR_PROTOCOL_INCONSISTENT, "command id missmatch in response: " << head.m_command << ", expected: " << command);
|
||||
return m_transport.connect(addr, port, timeout, timeout, bind_ip);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
template<typename transport_t>
|
||||
bool levin_client_impl_t<transport_t>::is_connected()
|
||||
{
|
||||
return m_transport.is_connected();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
template<typename transport_t>
|
||||
bool levin_client_impl_t<transport_t>::disconnect()
|
||||
{
|
||||
return m_transport.disconnect();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
template<typename transport_t>
|
||||
levin_client_impl_t<transport_t>::levin_client_impl_t()
|
||||
{
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
template<typename transport_t>
|
||||
levin_client_impl_t<transport_t>::~levin_client_impl_t()
|
||||
{
|
||||
disconnect();
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
template<typename transport_t>
|
||||
int levin_client_impl_t<transport_t>::invoke(int command, const std::string& in_buff, std::string& buff_out)
|
||||
{
|
||||
if (!is_connected())
|
||||
return -1;
|
||||
|
||||
bucket_head head = { 0 };
|
||||
head.m_signature = LEVIN_SIGNATURE;
|
||||
head.m_cb = in_buff.size();
|
||||
head.m_have_to_return_data = true;
|
||||
head.m_command = command;
|
||||
if (!m_transport.send(&head, sizeof(head)))
|
||||
return -1;
|
||||
|
||||
if (!m_transport.send(in_buff))
|
||||
return -1;
|
||||
|
||||
std::string local_buff;
|
||||
if (!m_transport.recv_n(local_buff, sizeof(bucket_head)))
|
||||
return -1;
|
||||
|
||||
head = *(bucket_head*)local_buff.data();
|
||||
|
||||
|
||||
if (head.m_signature != LEVIN_SIGNATURE)
|
||||
{
|
||||
LOG_PRINT_L0("Signature missmatch in response");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!m_transport.recv_n(buff_out, head.m_cb))
|
||||
return -1;
|
||||
|
||||
return head.m_return_code;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
template<typename transport_t>
|
||||
int levin_client_impl_t<transport_t>::notify(int command, const std::string& in_buff)
|
||||
{
|
||||
if (!this->is_connected())
|
||||
return -1;
|
||||
|
||||
bucket_head head = { 0 };
|
||||
head.m_signature = LEVIN_SIGNATURE;
|
||||
head.m_cb = in_buff.size();
|
||||
head.m_have_to_return_data = false;
|
||||
head.m_command = command;
|
||||
|
||||
if (!m_transport.send((const char*)&head, sizeof(head)))
|
||||
return -1;
|
||||
|
||||
if (!m_transport.send(in_buff))
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
template<typename transport_t>
|
||||
int levin_client_impl2<transport_t>::invoke(int command, const std::string& in_buff, std::string& buff_out)
|
||||
{
|
||||
if (!this->is_connected())
|
||||
return -1;
|
||||
|
||||
bucket_head2 head = { 0 };
|
||||
head.m_signature = LEVIN_SIGNATURE;
|
||||
head.m_cb = in_buff.size();
|
||||
head.m_have_to_return_data = true;
|
||||
head.m_command = static_cast<uint32_t>(command);
|
||||
head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
|
||||
head.m_flags = LEVIN_PACKET_REQUEST;
|
||||
if (!this->m_transport.send(&head, sizeof(head)))
|
||||
return -1;
|
||||
|
||||
if (!this->m_transport.send(in_buff))
|
||||
return -1;
|
||||
|
||||
//Since other side of connection could be running by async server,
|
||||
//we can receive some unexpected notify(forwarded broadcast notifications for example).
|
||||
//let's ignore every notify in the channel until we get invoke response
|
||||
std::string local_buff;
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (!this->m_transport.recv_n(local_buff, sizeof(bucket_head2)))
|
||||
return LEVIN_ERROR_NET_ERROR;
|
||||
|
||||
head = *(bucket_head2*)local_buff.data();
|
||||
if (head.m_signature != LEVIN_SIGNATURE)
|
||||
{
|
||||
LOG_PRINT_L0("Signature missmatch in response");
|
||||
return LEVIN_ERROR_SIGNATURE_MISMATCH;
|
||||
}
|
||||
if (!this->m_transport.recv_n(buff_out, head.m_cb))
|
||||
return LEVIN_ERROR_NET_ERROR;
|
||||
|
||||
//now check if this is response to invoke (and extra validate if it's response to this(!) invoke)
|
||||
if (head.m_flags&LEVIN_PACKET_RESPONSE)
|
||||
{
|
||||
//we got response, extra validate if its response to our request
|
||||
CHECK_AND_ASSERT_MES(head.m_command == static_cast<uint32_t>(command), LEVIN_ERROR_PROTOCOL_INCONSISTENT, "command id missmatch in response: " << head.m_command << ", expected: " << command);
|
||||
return head.m_return_code;
|
||||
}
|
||||
}
|
||||
//never comes here
|
||||
return LEVIN_ERROR_INTERNAL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
template<typename transport_t>
|
||||
int levin_client_impl2<transport_t>::notify(int command, const std::string& in_buff)
|
||||
{
|
||||
if (!this->is_connected())
|
||||
return -1;
|
||||
|
||||
bucket_head2 head = { 0 };
|
||||
head.m_signature = LEVIN_SIGNATURE;
|
||||
head.m_cb = in_buff.size();
|
||||
head.m_have_to_return_data = false;
|
||||
head.m_command = command;
|
||||
head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
|
||||
head.m_flags = LEVIN_PACKET_REQUEST;
|
||||
|
||||
if (!this->m_transport.send((const char*)&head, sizeof(head)))
|
||||
return -1;
|
||||
|
||||
if (!this->m_transport.send(in_buff))
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
//never comes here
|
||||
return LEVIN_ERROR_INTERNAL;
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
inline
|
||||
int levin_client_impl2::notify(int command, const std::string& in_buff)
|
||||
{
|
||||
if(!is_connected())
|
||||
return -1;
|
||||
|
||||
bucket_head2 head = {0};
|
||||
head.m_signature = LEVIN_SIGNATURE;
|
||||
head.m_cb = in_buff.size();
|
||||
head.m_have_to_return_data = false;
|
||||
head.m_command = command;
|
||||
head.m_protocol_version = LEVIN_PROTOCOL_VER_1;
|
||||
head.m_flags = LEVIN_PACKET_REQUEST;
|
||||
|
||||
if(!m_transport.send((const char*)&head, sizeof(head)))
|
||||
return -1;
|
||||
|
||||
if(!m_transport.send(in_buff))
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
|
@ -27,6 +27,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/mpl/vector.hpp>
|
||||
#include <boost/mpl/contains.hpp>
|
||||
#include <deque>
|
||||
|
||||
namespace epee
|
||||
|
|
|
|||
|
|
@ -267,20 +267,20 @@ namespace epee
|
|||
|
||||
#define HANDLE_INVOKE2(command_id, func, type_name_in, typename_out) \
|
||||
if(!is_notify && command_id == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in, typename_out>(this, command, in_buff, buff_out, boost::bind(func, this, _1, _2, _3, _4), context);}
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in, typename_out>(this, command, in_buff, buff_out, boost::bind(func, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4), context);}
|
||||
|
||||
#define HANDLE_INVOKE_T2(COMMAND, func) \
|
||||
if(!is_notify && COMMAND::ID == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename COMMAND::request, typename COMMAND::response>(command, in_buff, buff_out, boost::bind(func, this, _1, _2, _3, _4), context);}
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename COMMAND::request, typename COMMAND::response>(command, in_buff, buff_out, boost::bind(func, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3, boost::placeholders::_4), context);}
|
||||
|
||||
|
||||
#define HANDLE_NOTIFY2(command_id, func, type_name_in) \
|
||||
if(is_notify && command_id == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in>(this, command, in_buff, boost::bind(func, this, _1, _2, _3), context);}
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, type_name_in>(this, command, in_buff, boost::bind(func, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3), context);}
|
||||
|
||||
#define HANDLE_NOTIFY_T2(NOTIFY, func) \
|
||||
if(is_notify && NOTIFY::ID == command) \
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename NOTIFY::request>(this, command, in_buff, boost::bind(func, this, _1, _2, _3), context);}
|
||||
{handled=true;return epee::net_utils::buff_to_t_adapter<internal_owner_type_name, typename NOTIFY::request>(this, command, in_buff, boost::bind(func, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3), context);}
|
||||
|
||||
|
||||
#define CHAIN_INVOKE_MAP2(func) \
|
||||
|
|
|
|||
1
contrib/tor-connect
Submodule
1
contrib/tor-connect
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit aa509880f06292ac8078046f3d49ff854e400716
|
||||
|
|
@ -121,16 +121,19 @@ add_library(currency_core ${CURRENCY_CORE})
|
|||
add_dependencies(currency_core version ${PCH_LIB_NAME})
|
||||
ENABLE_SHARED_PCH(currency_core CURRENCY_CORE)
|
||||
|
||||
add_library(wallet ${WALLET})
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Android" )
|
||||
add_library(wallet ${WALLET})
|
||||
add_dependencies(wallet version ${PCH_LIB_NAME})
|
||||
target_link_libraries(wallet currency_core crypto common zlibstatic ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES} android log)
|
||||
else()
|
||||
add_library(wallet ${WALLET})
|
||||
add_dependencies(wallet version ${PCH_LIB_NAME})
|
||||
ENABLE_SHARED_PCH(wallet WALLET)
|
||||
endif()
|
||||
|
||||
if(NOT DISABLE_TOR)
|
||||
target_link_libraries(wallet tor-connect)
|
||||
endif()
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -159,7 +162,7 @@ target_link_libraries(currency_core lmdb mdbx)
|
|||
|
||||
add_executable(daemon ${DAEMON} ${P2P} ${CURRENCY_PROTOCOL})
|
||||
add_dependencies(daemon version)
|
||||
target_link_libraries(daemon rpc stratum currency_core crypto common libminiupnpc-static zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
target_link_libraries(daemon rpc stratum currency_core crypto common libminiupnpc-static zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
ENABLE_SHARED_PCH(daemon DAEMON)
|
||||
ENABLE_SHARED_PCH_EXECUTABLE(daemon)
|
||||
|
||||
|
|
@ -170,8 +173,9 @@ ENABLE_SHARED_PCH(connectivity_tool CONN_TOOL)
|
|||
ENABLE_SHARED_PCH_EXECUTABLE(connectivity_tool)
|
||||
|
||||
add_executable(simplewallet ${SIMPLEWALLET})
|
||||
add_dependencies(simplewallet version)
|
||||
add_dependencies(simplewallet version)
|
||||
target_link_libraries(simplewallet wallet rpc currency_core crypto common zlibstatic ethash ${CMAKE_THREAD_LIBS_INIT} ${Boost_LIBRARIES})
|
||||
|
||||
ENABLE_SHARED_PCH(simplewallet SIMPLEWALLET)
|
||||
ENABLE_SHARED_PCH_EXECUTABLE(simplewallet)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,36 +10,36 @@
|
|||
|
||||
namespace command_line
|
||||
{
|
||||
const arg_descriptor<bool> arg_help = {"help", "Produce help message"};
|
||||
const arg_descriptor<bool> arg_version = {"version", "Output version information"};
|
||||
const arg_descriptor<std::string> arg_data_dir = {"data-dir", "Specify data directory", ""};
|
||||
const arg_descriptor<bool> arg_help ("help", "Produce help message");
|
||||
const arg_descriptor<bool> arg_version ("version", "Output version information");
|
||||
const arg_descriptor<std::string> arg_data_dir ("data-dir", "Specify data directory", "");
|
||||
|
||||
const arg_descriptor<int> arg_stop_after_height = { "stop-after-height", "If specified, the daemon will stop immediately after a block with the given height is added", 0 };
|
||||
const arg_descriptor<int> arg_stop_after_height ( "stop-after-height", "If specified, the daemon will stop immediately after a block with the given height is added", 0 );
|
||||
|
||||
const arg_descriptor<std::string> arg_config_file = { "config-file", "Specify configuration file", std::string(CURRENCY_NAME_SHORT ".conf") };
|
||||
const arg_descriptor<bool> arg_os_version = { "os-version", "" };
|
||||
const arg_descriptor<std::string> arg_config_file ( "config-file", "Specify configuration file", std::string(CURRENCY_NAME_SHORT ".conf") );
|
||||
const arg_descriptor<bool> arg_os_version ( "os-version", "" );
|
||||
|
||||
const arg_descriptor<std::string> arg_log_dir = { "log-dir", "", "", true};
|
||||
const arg_descriptor<std::string> arg_log_file = { "log-file", "", "" };
|
||||
const arg_descriptor<int> arg_log_level = { "log-level", "", LOG_LEVEL_0, true };
|
||||
const arg_descriptor<std::string> arg_log_dir ( "log-dir", "");
|
||||
const arg_descriptor<std::string> arg_log_file ( "log-file", "", "");
|
||||
const arg_descriptor<int> arg_log_level ( "log-level", "");
|
||||
|
||||
const arg_descriptor<bool> arg_console = { "no-console", "Disable daemon console commands" };
|
||||
const arg_descriptor<bool> arg_show_details = { "currency-details", "Display currency details" };
|
||||
const arg_descriptor<bool> arg_show_rpc_autodoc = { "show_rpc_autodoc", "Display rpc auto-generated documentation template" };
|
||||
const arg_descriptor<bool> arg_console ( "no-console", "Disable daemon console commands" );
|
||||
const arg_descriptor<bool> arg_show_details ( "currency-details", "Display currency details" );
|
||||
const arg_descriptor<bool> arg_show_rpc_autodoc ( "show_rpc_autodoc", "Display rpc auto-generated documentation template" );
|
||||
|
||||
const arg_descriptor<bool> arg_disable_upnp = { "disable-upnp", "Disable UPnP (enhances local network privacy)", false, true };
|
||||
const arg_descriptor<bool> arg_disable_ntp = { "disable-ntp", "Disable NTP, could enhance to time synchronization issue but increase network privacy, consider using disable-stop-if-time-out-of-sync with it", false, true };
|
||||
const arg_descriptor<bool> arg_disable_upnp ( "disable-upnp", "Disable UPnP (enhances local network privacy)");
|
||||
const arg_descriptor<bool> arg_disable_ntp ( "disable-ntp", "Disable NTP, could enhance to time synchronization issue but increase network privacy, consider using disable-stop-if-time-out-of-sync with it");
|
||||
|
||||
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};
|
||||
const arg_descriptor<std::string> arg_db_engine = { "db-engine", "Specify database engine for storage. May be \"lmdb\"(default) or \"mdbx\"", ARG_DB_ENGINE_LMDB, false };
|
||||
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");
|
||||
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");
|
||||
const arg_descriptor<bool> arg_enable_offers_service ( "enable-offers-service", "Enables marketplace feature", false);
|
||||
const arg_descriptor<std::string> arg_db_engine ( "db-engine", "Specify database engine for storage. May be \"lmdb\"(default) or \"mdbx\"", ARG_DB_ENGINE_LMDB );
|
||||
|
||||
const arg_descriptor<bool> arg_no_predownload = { "no-predownload", "Do not pre-download blockchain database", };
|
||||
const arg_descriptor<bool> arg_force_predownload = { "force-predownload", "Pre-download blockchain database regardless of it's status", };
|
||||
const arg_descriptor<bool> arg_validate_predownload = { "validate-predownload", "Paranoid mode, re-validate each block from pre-downloaded database and rebuild own database", };
|
||||
const arg_descriptor<std::string> arg_predownload_link = { "predownload-link", "Override url for blockchain database pre-downloading", "", true };
|
||||
const arg_descriptor<bool> arg_no_predownload ( "no-predownload", "Do not pre-download blockchain database");
|
||||
const arg_descriptor<bool> arg_force_predownload ( "force-predownload", "Pre-download blockchain database regardless of it's status");
|
||||
const arg_descriptor<bool> arg_validate_predownload ( "validate-predownload", "Paranoid mode, re-validate each block from pre-downloaded database and rebuild own database");
|
||||
const arg_descriptor<std::string> arg_predownload_link ( "predownload-link", "Override url for blockchain database pre-downloading");
|
||||
|
||||
const arg_descriptor<std::string> arg_deeplink = { "deeplink-params", "Deeplink parameter, in that case app just forward params to running app", "", true };
|
||||
const arg_descriptor<std::string> arg_deeplink ( "deeplink-params", "Deeplink parameter, in that case app just forward params to running app");
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,32 +26,38 @@ namespace command_line
|
|||
arg_descriptor(const char* _name, const char* _description):
|
||||
name(_name),
|
||||
description(_description),
|
||||
not_use_default(true),
|
||||
use_default(false),
|
||||
default_value(T())
|
||||
{}
|
||||
arg_descriptor(const char* _name, const char* _description, const T& default_val) :
|
||||
name(_name),
|
||||
description(_description),
|
||||
not_use_default(false),
|
||||
use_default(true),
|
||||
default_value(default_val)
|
||||
{}
|
||||
arg_descriptor(const char* _name, const char* _description, const T& default_val, bool not_use_default) :
|
||||
name(_name),
|
||||
description(_description),
|
||||
default_value(default_val),
|
||||
not_use_default(not_use_default)
|
||||
{}
|
||||
// arg_descriptor(const char* _name, const char* _description, const T& default_val, bool not_use_default) :
|
||||
// name(_name),
|
||||
// description(_description),
|
||||
// default_value(default_val),
|
||||
// not_use_default(not_use_default)
|
||||
// {}
|
||||
|
||||
|
||||
|
||||
const char* name;
|
||||
const char* description;
|
||||
bool use_default;
|
||||
T default_value;
|
||||
bool not_use_default;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct arg_descriptor<std::vector<T>, false>
|
||||
{
|
||||
arg_descriptor(const char* _name, const char* _description) :
|
||||
name(_name),
|
||||
description(_description)
|
||||
{}
|
||||
|
||||
typedef std::vector<T> value_type;
|
||||
|
||||
const char* name;
|
||||
|
|
@ -79,7 +85,7 @@ namespace command_line
|
|||
boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, false>& arg)
|
||||
{
|
||||
auto semantic = boost::program_options::value<T>();
|
||||
if (!arg.not_use_default)
|
||||
if (arg.use_default)
|
||||
semantic->default_value(arg.default_value);
|
||||
return semantic;
|
||||
}
|
||||
|
|
@ -88,7 +94,7 @@ namespace command_line
|
|||
boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, false>& arg, const T& def)
|
||||
{
|
||||
auto semantic = boost::program_options::value<T>();
|
||||
if (!arg.not_use_default)
|
||||
if (arg.use_default)
|
||||
semantic->default_value(def);
|
||||
return semantic;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ public:
|
|||
// 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));
|
||||
boost::bind(&udp_blocking_client::handle_receive, boost::placeholders::_1, boost::placeholders::_2, &ec, &length));
|
||||
|
||||
// Block until the asynchronous operation has completed.
|
||||
do io_service_.run_one(); while (ec == boost::asio::error::would_block);
|
||||
|
|
@ -194,7 +194,12 @@ namespace tools
|
|||
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);
|
||||
auto send_res = socket.send_to(boost::asio::buffer(&packet_sent, sizeof packet_sent), receiver_endpoint);
|
||||
if (send_res != sizeof packet_sent)
|
||||
{
|
||||
LOG_PRINT_L3("NTP: get_ntp_time(" << host_name << "): wrong send_res: " << send_res << ", expected sizeof packet_sent = " << sizeof packet_sent);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ntp_packet packet_received = AUTO_VAL_INIT(packet_received);
|
||||
boost::asio::ip::udp::endpoint sender_endpoint;
|
||||
|
|
|
|||
|
|
@ -21,8 +21,8 @@ namespace tools
|
|||
};
|
||||
|
||||
#ifndef TESTNET
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_1480000.pak", "2b664de02450cc0082efb6c75824d33ffe694b9b17b21fc7966bcb9be9ac31f7", 1570460883, 3221176320 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_1480000.pak", "67770faa7db22dfe97982611d7471ba5673145589e81e02ed99832644ae328f6", 2042582638, 2968252416 };
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "http://95.217.42.247/pre-download/zano_mdbx_95_1569000.pak", "c2aff6fb65c2d7a40492738c75d1d04f2f35388d3c1a664aeb77420f2d90d644", 1740147926, 3221176320 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "http://95.217.42.247/pre-download/zano_lmdb_95_1569000.pak", "f673636638b666b36c976168a3c64b2fd1fcf071c41b5d9cf01ed58a5924f80a", 2244905636, 3216977920 };
|
||||
#else
|
||||
static constexpr pre_download_entry c_pre_download_mdbx = { "", "", 0, 0 };
|
||||
static constexpr pre_download_entry c_pre_download_lmdb = { "", "", 0, 0 };
|
||||
|
|
|
|||
|
|
@ -51,11 +51,11 @@ namespace utils
|
|||
int num_threads = std::thread::hardware_concurrency();
|
||||
this->init(num_threads);
|
||||
}
|
||||
void init(unsigned int num_threads)
|
||||
void init(size_t num_threads)
|
||||
{
|
||||
m_is_stop = false;
|
||||
|
||||
for (int i = 0; i < num_threads; i++)
|
||||
for (size_t i = 0; i < num_threads; i++)
|
||||
{
|
||||
m_threads.push_back(std::thread([this]() {this->worker_func(); }));
|
||||
}
|
||||
|
|
@ -81,7 +81,7 @@ namespace utils
|
|||
std::mutex batch_mutex;
|
||||
|
||||
|
||||
std::atomic<size_t> cnt = 0;
|
||||
std::atomic<size_t> cnt(0);
|
||||
for (const auto& jb : cntr)
|
||||
{
|
||||
call_executor_base* pjob = jb.get();
|
||||
|
|
|
|||
17
src/common/tor_helper.h
Normal file
17
src/common/tor_helper.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// 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
|
||||
|
||||
#include "tor-connect/torlib/tor_wrapper.h"
|
||||
|
||||
|
||||
|
||||
namespace tools
|
||||
{
|
||||
typedef epee::levin::levin_client_impl2<tools::tor::tor_transport> levin_over_tor_client;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -38,32 +38,32 @@ using namespace nodetool;
|
|||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_ip = {"ip", "set ip", "127.0.0.1", false};
|
||||
const command_line::arg_descriptor<size_t> arg_port = {"port", "set port"};
|
||||
const command_line::arg_descriptor<size_t> arg_rpc_port = {"rpc-port", "set rpc port", RPC_DEFAULT_PORT, false};
|
||||
const command_line::arg_descriptor<uint32_t> arg_timeout = {"timeout", "set timeout", 5000, false};
|
||||
const command_line::arg_descriptor<std::string> arg_priv_key = {"private-key", "private key to subscribe debug command", "", true};
|
||||
const command_line::arg_descriptor<uint64_t> arg_peer_id = {"peer-id", "peerid if known(if not - will be requested)", 0};
|
||||
const command_line::arg_descriptor<bool> arg_generate_keys = {"generate-keys-pair", "generate private and public keys pair"};
|
||||
const command_line::arg_descriptor<bool> arg_request_stat_info = {"request-stat-info", "request statistics information"};
|
||||
const command_line::arg_descriptor<uint64_t> arg_log_journal_len = { "log-journal-len", "Specify length of list of last error messages in log", 0, true };
|
||||
const command_line::arg_descriptor<bool> arg_request_net_state = {"request-net-state", "request network state information (peer list, connections count)"};
|
||||
const command_line::arg_descriptor<bool> arg_get_daemon_info = {"rpc-get-daemon-info", "request daemon state info vie rpc (--rpc-port option should be set ).", "", true};
|
||||
const command_line::arg_descriptor<bool> arg_get_aliases = {"rpc-get-aliases", "request daemon aliases all list", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_increment_build_no = { "increment-build-no", "Increment build nimber", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_upate_maintainers_info = {"update-maintainers-info", "Push maintainers info into the network, update-maintainers-info=file-with-info.json", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_update_build_no = {"update-build-no", "Updated version number in version template file", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_genesis = {"generate-genesis", "Generate genesis coinbase based on config file", "", true };
|
||||
const command_line::arg_descriptor<uint64_t> arg_genesis_split_amount = { "genesis-split-amount", "Set split amount for generating genesis block", 0, true };
|
||||
const command_line::arg_descriptor<std::string> arg_get_info_flags = { "getinfo-flags-hex", "Set of bits for rpc-get-daemon-info", "", true };
|
||||
const command_line::arg_descriptor<int64_t> arg_set_peer_log_level = { "set-peer-log-level", "Set log level for remote peer", 0, true };
|
||||
const command_line::arg_descriptor<std::string> arg_download_peer_log = { "download-peer-log", "Download log from remote peer <starting_offset>[,<count>]", "", true };
|
||||
const command_line::arg_descriptor<bool> arg_do_consloe_log = { "do-console-log", "Tool generates debug console output(debug purposes)", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_generate_integrated_address = { "generate-integrated-address", "Tool create integrated address from simple address and payment_id", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_pack_file = {"pack-file", "perform gzip-packing and calculate hash for a given file", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_unpack_file = {"unpack-file", "Perform gzip-unpacking and calculate hash for a given file", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_target_file = {"target-file", "Specify target file for pack-file and unpack-file commands", "", true };
|
||||
//const command_line::arg_descriptor<std::string> arg_send_ipc = {"send-ipc", "Send IPC request to UI", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_ip ("ip", "set ip", "127.0.0.1");
|
||||
const command_line::arg_descriptor<size_t> arg_port ("port", "set port");
|
||||
const command_line::arg_descriptor<size_t> arg_rpc_port ("rpc-port", "set rpc port", RPC_DEFAULT_PORT);
|
||||
const command_line::arg_descriptor<uint32_t> arg_timeout ("timeout", "set timeout", 5000);
|
||||
const command_line::arg_descriptor<std::string> arg_priv_key ("private-key", "private key to subscribe debug command");
|
||||
const command_line::arg_descriptor<uint64_t> arg_peer_id ("peer-id", "peerid if known(if not - will be requested)", 0);
|
||||
const command_line::arg_descriptor<bool> arg_generate_keys ("generate-keys-pair", "generate private and public keys pair");
|
||||
const command_line::arg_descriptor<bool> arg_request_stat_info ("request-stat-info", "request statistics information");
|
||||
const command_line::arg_descriptor<uint64_t> arg_log_journal_len ( "log-journal-len", "Specify length of list of last error messages in log");
|
||||
const command_line::arg_descriptor<bool> arg_request_net_state ("request-net-state", "request network state information (peer list, connections count)");
|
||||
const command_line::arg_descriptor<bool> arg_get_daemon_info ("rpc-get-daemon-info", "request daemon state info vie rpc (--rpc-port option should be set ).");
|
||||
const command_line::arg_descriptor<bool> arg_get_aliases ("rpc-get-aliases", "request daemon aliases all list");
|
||||
const command_line::arg_descriptor<std::string> arg_increment_build_no ( "increment-build-no", "Increment build nimber");
|
||||
const command_line::arg_descriptor<std::string> arg_upate_maintainers_info ("update-maintainers-info", "Push maintainers info into the network, update-maintainers-info=file-with-info.json");
|
||||
const command_line::arg_descriptor<std::string> arg_update_build_no ("update-build-no", "Updated version number in version template file");
|
||||
const command_line::arg_descriptor<std::string> arg_generate_genesis ("generate-genesis", "Generate genesis coinbase based on config file");
|
||||
const command_line::arg_descriptor<uint64_t> arg_genesis_split_amount ( "genesis-split-amount", "Set split amount for generating genesis block");
|
||||
const command_line::arg_descriptor<std::string> arg_get_info_flags ( "getinfo-flags-hex", "Set of bits for rpc-get-daemon-info", "");
|
||||
const command_line::arg_descriptor<int64_t> arg_set_peer_log_level ( "set-peer-log-level", "Set log level for remote peer");
|
||||
const command_line::arg_descriptor<std::string> arg_download_peer_log ( "download-peer-log", "Download log from remote peer <starting_offset>[,<count>]");
|
||||
const command_line::arg_descriptor<bool> arg_do_consloe_log ( "do-console-log", "Tool generates debug console output(debug purposes)");
|
||||
const command_line::arg_descriptor<std::string> arg_generate_integrated_address ( "generate-integrated-address", "Tool create integrated address from simple address and payment_id");
|
||||
const command_line::arg_descriptor<std::string> arg_pack_file ("pack-file", "perform gzip-packing and calculate hash for a given file");
|
||||
const command_line::arg_descriptor<std::string> arg_unpack_file ("unpack-file", "Perform gzip-unpacking and calculate hash for a given file");
|
||||
const command_line::arg_descriptor<std::string> arg_target_file ("target-file", "Specify target file for pack-file and unpack-file commands");
|
||||
//const command_line::arg_descriptor<std::string> arg_send_ipc ("send-ipc", "Send IPC request to UI");
|
||||
}
|
||||
|
||||
typedef COMMAND_REQUEST_STAT_INFO_T<t_currency_protocol_handler<core>::stat_info> COMMAND_REQUEST_STAT_INFO;
|
||||
|
|
@ -640,7 +640,7 @@ bool handle_request_stat(po::variables_map& vm, peerid_type peer_id)
|
|||
|
||||
response_schema rs = AUTO_VAL_INIT(rs);
|
||||
|
||||
levin::levin_client_impl2 transport;
|
||||
net_utils::levin_client2 transport;
|
||||
if(!transport.connect(command_line::get_arg(vm, arg_ip), static_cast<int>(command_line::get_arg(vm, arg_port)), static_cast<int>(command_line::get_arg(vm, arg_timeout))))
|
||||
{
|
||||
std::cout << "{" << ENDL << " \"status\": \"ERROR: " << "Failed to connect to " << command_line::get_arg(vm, arg_ip) << ":" << command_line::get_arg(vm, arg_port) << "\"" << ENDL << "}" << ENDL;
|
||||
|
|
@ -878,7 +878,7 @@ bool generate_and_print_keys()
|
|||
}
|
||||
//---------------------------------------------------------------------------------------------------------------
|
||||
template<class command_t>
|
||||
bool invoke_debug_command(po::variables_map& vm, const crypto::secret_key& sk, levin::levin_client_impl2& transport, peerid_type& peer_id, typename command_t::request& req, typename command_t::response& rsp)
|
||||
bool invoke_debug_command(po::variables_map& vm, const crypto::secret_key& sk, net_utils::levin_client2& transport, peerid_type& peer_id, typename command_t::request& req, typename command_t::response& rsp)
|
||||
{
|
||||
if (!transport.is_connected())
|
||||
{
|
||||
|
|
@ -933,7 +933,7 @@ bool handle_set_peer_log_level(po::variables_map& vm)
|
|||
return false;
|
||||
}
|
||||
|
||||
levin::levin_client_impl2 transport;
|
||||
net_utils::levin_client2 transport;
|
||||
peerid_type peer_id = 0;
|
||||
|
||||
COMMAND_SET_LOG_LEVEL::request req = AUTO_VAL_INIT(req);
|
||||
|
|
@ -982,7 +982,7 @@ bool handle_download_peer_log(po::variables_map& vm)
|
|||
}
|
||||
uint64_t start_offset = static_cast<uint64_t>(start_offset_signed);
|
||||
|
||||
levin::levin_client_impl2 transport;
|
||||
net_utils::levin_client2 transport;
|
||||
peerid_type peer_id = 0;
|
||||
|
||||
COMMAND_REQUEST_LOG::request req = AUTO_VAL_INIT(req);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ namespace crypto
|
|||
const scalar_t c_scalar_1div8 = { 0x6106e529e2dc2f79, 0x07d39db37d1cdad0, 0x0, 0x0600000000000000 };
|
||||
|
||||
const point_t c_point_H = { 0x05087c1f5b9b32d6, 0x00547595f445c3b5, 0x764df64578552f2a, 0x8a49a651e0e0da45 }; // == Hp(G), this is being checked in bpp_basics
|
||||
const point_t c_point_H2 = { 0x70c8d1ab9dbf1cc0, 0xc561bb12639a8516, 0x3cfff1def9e5b268, 0xe0936386f3bcce1a }; // == Hp("h2_generator"), cheched in bpp_basics
|
||||
const point_t c_point_0 = point_t(point_t::tag_zero());
|
||||
|
||||
} // namespace crypto
|
||||
|
|
|
|||
|
|
@ -431,6 +431,31 @@ namespace crypto
|
|||
return result;
|
||||
}
|
||||
|
||||
// Little-endian assumed; TODO: consider Big-endian support
|
||||
bool get_bit(uint8_t bit_index) const
|
||||
{
|
||||
return (m_u64[bit_index >> 6] & (1ull << (bit_index & 63))) != 0;
|
||||
}
|
||||
|
||||
// Little-endian assumed; TODO: consider Big-endian support
|
||||
void set_bit(size_t bit_index)
|
||||
{
|
||||
m_u64[bit_index >> 6] |= (1ull << (bit_index & 63));
|
||||
}
|
||||
|
||||
// Little-endian assumed; TODO: consider Big-endian support
|
||||
void clear_bit(size_t bit_index)
|
||||
{
|
||||
m_u64[bit_index >> 6] &= ~(1ull << (bit_index & 63));
|
||||
}
|
||||
|
||||
static scalar_t power_of_2(uint8_t exponent)
|
||||
{
|
||||
scalar_t result = 0;
|
||||
result.set_bit(exponent);
|
||||
return result;
|
||||
}
|
||||
|
||||
}; // struct scalar_t
|
||||
|
||||
//
|
||||
|
|
@ -890,6 +915,7 @@ namespace crypto
|
|||
extern const point_g_t c_point_G;
|
||||
|
||||
extern const point_t c_point_H;
|
||||
extern const point_t c_point_H2;
|
||||
extern const point_t c_point_0;
|
||||
|
||||
//
|
||||
|
|
@ -1063,6 +1089,21 @@ namespace crypto
|
|||
ge_bytes_hash_to_ec_32(&result.m_p3, (const unsigned char*)&p);
|
||||
return result;
|
||||
}
|
||||
|
||||
static point_t hp(const scalar_t& s)
|
||||
{
|
||||
point_t result;
|
||||
ge_bytes_hash_to_ec_32(&result.m_p3, s.data());
|
||||
return result;
|
||||
}
|
||||
|
||||
static point_t hp(const void* data, size_t size)
|
||||
{
|
||||
point_t result;
|
||||
ge_bytes_hash_to_ec(&result.m_p3, data, size);
|
||||
return result;
|
||||
}
|
||||
|
||||
}; // hash_helper_t struct
|
||||
|
||||
|
||||
|
|
|
|||
699
src/crypto/range_proof_bpp.h
Normal file
699
src/crypto/range_proof_bpp.h
Normal file
|
|
@ -0,0 +1,699 @@
|
|||
// Copyright (c) 2021-2022 Zano Project (https://zano.org/)
|
||||
// Copyright (c) 2021-2022 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// This file contains the implementation of range proof protocol.
|
||||
// Namely, Bulletproofs+ https://eprint.iacr.org/2020/735
|
||||
//
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
struct bpp_signature
|
||||
{
|
||||
std::vector<public_key> L; // size = ceil( log_2(m * n) )
|
||||
std::vector<public_key> R;
|
||||
public_key A0;
|
||||
public_key A;
|
||||
public_key B;
|
||||
scalar_t r;
|
||||
scalar_t s;
|
||||
scalar_t delta;
|
||||
};
|
||||
|
||||
#define DBG_VAL_PRINT(x) std::cout << #x ": " << x << ENDL
|
||||
#define DBG_PRINT(x) std::cout << x << ENDL
|
||||
|
||||
template<typename CT>
|
||||
bool bpp_gen(const scalar_vec_t& values, const scalar_vec_t& masks, bpp_signature& sig, std::vector<point_t>& commitments, uint8_t* p_err = nullptr)
|
||||
{
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("bpp_gen: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
static_assert(CT::c_bpp_n <= 255, "too big N");
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(values.size() > 0 && values.size() <= CT::c_bpp_values_max && values.size() == masks.size(), 1);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(masks.is_reduced(), 3);
|
||||
|
||||
const size_t c_bpp_log2_m = constexpr_ceil_log2(values.size());
|
||||
const size_t c_bpp_m = 1ull << c_bpp_log2_m;
|
||||
const size_t c_bpp_mn = c_bpp_m * CT::c_bpp_n;
|
||||
const size_t c_bpp_log2_mn = c_bpp_log2_m + CT::c_bpp_log2_n;
|
||||
|
||||
// pre-multiply all output points by c_scalar_1div8
|
||||
// in order to enforce these points to be in the prime-order subgroup (after mul by 8 in bpp_verify())
|
||||
|
||||
// calc commitments vector as commitments[i] = 1/8 * values[i] * G + 1/8 * masks[i] * H
|
||||
commitments.resize(values.size());
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
CT::calc_pedersen_commitment(values[i] * c_scalar_1div8, masks[i] * c_scalar_1div8, commitments[i]);
|
||||
|
||||
|
||||
// s.a. BP+ paper, page 15, eq. 11
|
||||
// decompose v into aL and aR:
|
||||
// v = aL o (1, 2, 2^2, ..., 2^n-1), o - component-wise product aka Hadamard product
|
||||
// aR = aL - (1, 1, ... 1)
|
||||
// aR o aL = 0
|
||||
|
||||
// aLs = (aL_0, aL_1, ..., aL_m-1) -- `bit` matrix of c_bpp_m x c_bpp_n, each element is a scalar
|
||||
|
||||
scalar_mat_t<CT::c_bpp_n> aLs(c_bpp_mn), aRs(c_bpp_mn);
|
||||
aLs.zero();
|
||||
aRs.zero();
|
||||
// m >= values.size, first set up [0..values.size-1], then -- [values.size..m-1] (padding area)
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
{
|
||||
const scalar_t& v = values[i];
|
||||
for (uint8_t j = 0; j < CT::c_bpp_n; ++j)
|
||||
{
|
||||
if (v.get_bit(j))
|
||||
aLs(i, j) = c_scalar_1; // aL = 1, aR = 0
|
||||
else
|
||||
aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = values.size(); i < c_bpp_m; ++i)
|
||||
for (size_t j = 0; j < CT::c_bpp_n; ++j)
|
||||
aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1
|
||||
|
||||
|
||||
// using e as Fiat-Shamir transcript
|
||||
scalar_t e = CT::get_initial_transcript();
|
||||
DBG_PRINT("initial transcript: " << e);
|
||||
|
||||
hash_helper_t::hs_t hsc;
|
||||
CT::update_transcript(hsc, e, commitments);
|
||||
|
||||
// BP+ paper, page 15: The prover begins with sending A = g^aL h^aR h^alpha (group element)
|
||||
// so we calculate A0 = alpha * H + SUM(aL_i * G_i) + SUM(aR_i * H_i)
|
||||
|
||||
scalar_t alpha = scalar_t::random();
|
||||
point_t A0 = alpha * CT::bpp_H;
|
||||
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
A0 += aLs[i] * CT::get_generator(false, i) + aRs[i] * CT::get_generator(true, i);
|
||||
|
||||
// part of 1/8 defense scheme
|
||||
A0 *= c_scalar_1div8;
|
||||
A0.to_public_key(sig.A0);
|
||||
|
||||
DBG_VAL_PRINT(alpha);
|
||||
DBG_VAL_PRINT(A0);
|
||||
|
||||
// calculate scalar challenges y and z
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A0);
|
||||
scalar_t y = hsc.calc_hash();
|
||||
scalar_t z = hash_helper_t::hs(y);
|
||||
e = z; // transcript for further steps
|
||||
DBG_VAL_PRINT(y);
|
||||
DBG_VAL_PRINT(z);
|
||||
|
||||
// Computing vector d for aggregated version of the protocol (BP+ paper, page 17)
|
||||
// (note: elements are stored column-by-column in memory)
|
||||
// d = | 1 * z^(2*1), 1 * z^(2*2), 1 * z^(2*3), ..., 1 * z^(2*m) |
|
||||
// | 2 * z^(2*1), 2 * z^(2*2), 2 * z^(2*3), ..., 2 * z^(2*m) |
|
||||
// | 4 * z^(2*1), 4 * z^(2*2), 4 * z^(2*3), ..., 4 * z^(2*m) |
|
||||
// | ....................................................................................... |
|
||||
// | 2^(n-1) * z^(2*1), 2^(n-1) * z^(2*2), 2^(n-1) * z^(2*3), ..., 2^(n-1) * z^(2*m)) |
|
||||
// Note: sum(d_i) = (2^n - 1) * ((z^2)^1 + (z^2)^2 + ... (z^2)^m)) = (2^n-1) * sum_of_powers(x^2, log(m))
|
||||
|
||||
scalar_t z_sq = z * z;
|
||||
scalar_mat_t<CT::c_bpp_n> d(c_bpp_mn);
|
||||
d(0, 0) = z_sq;
|
||||
// first row
|
||||
for (size_t i = 1; i < c_bpp_m; ++i)
|
||||
d(i, 0) = d(i - 1, 0) * z_sq;
|
||||
// all rows
|
||||
for (size_t j = 1; j < CT::c_bpp_n; ++j)
|
||||
for (size_t i = 0; i < c_bpp_m; ++i)
|
||||
d(i, j) = d(i, j - 1) + d(i, j - 1);
|
||||
|
||||
DBG_PRINT("Hs(d): " << d.calc_hs());
|
||||
|
||||
// calculate extended Vandermonde vector y = (1, y, y^2, ..., y^(mn+1)) (BP+ paper, page 18, Fig. 3)
|
||||
// (calculate two more elements (1 and y^(mn+1)) for convenience)
|
||||
scalar_vec_t y_powers(c_bpp_mn + 2);
|
||||
y_powers[0] = 1;
|
||||
for (size_t i = 1; i <= c_bpp_mn + 1; ++i)
|
||||
y_powers[i] = y_powers[i - 1] * y;
|
||||
|
||||
const scalar_t& y_mn_p1 = y_powers[c_bpp_mn + 1];
|
||||
|
||||
DBG_PRINT("Hs(y_powers): " << y_powers.calc_hs());
|
||||
|
||||
// aL_hat = aL - 1*z
|
||||
scalar_vec_t aLs_hat = aLs - z;
|
||||
// aL_hat = aR + d o y^leftarr + 1*z where y^leftarr = (y^n, y^(n-1), ..., y) (BP+ paper, page 18, Fig. 3)
|
||||
scalar_vec_t aRs_hat = aRs + z;
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
aRs_hat[i] += d[i] * y_powers[c_bpp_mn - i];
|
||||
|
||||
DBG_PRINT("Hs(aLs_hat): " << aLs_hat.calc_hs());
|
||||
DBG_PRINT("Hs(aRs_hat): " << aRs_hat.calc_hs());
|
||||
|
||||
// calculate alpha_hat
|
||||
// alpha_hat = alpha + SUM(z^(2j) * gamma_j * y^(mn+1)) for j = 1..m
|
||||
// i.e. \hat{\alpha} = \alpha + y^{m n+1} \sum_{j = 1}^{m} z^{2j} \gamma_j
|
||||
scalar_t alpha_hat = 0;
|
||||
for (size_t i = 0; i < masks.size(); ++i)
|
||||
alpha_hat += d(i, 0) * masks[i];
|
||||
alpha_hat = alpha + y_mn_p1 * alpha_hat;
|
||||
|
||||
DBG_VAL_PRINT(alpha_hat);
|
||||
|
||||
// calculate 1, y^-1, y^-2, ...
|
||||
const scalar_t y_inverse = y.reciprocal();
|
||||
scalar_vec_t y_inverse_powers(c_bpp_mn / 2 + 1); // the greatest power we need is c_bpp_mn/2 (at the first reduction round)
|
||||
y_inverse_powers[0] = 1;
|
||||
for (size_t i = 1, size = y_inverse_powers.size(); i < size; ++i)
|
||||
y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inverse;
|
||||
|
||||
// prepare generator's vector
|
||||
std::vector<point_t> g(c_bpp_mn), h(c_bpp_mn);
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
{
|
||||
g[i] = CT::get_generator(false, i);
|
||||
h[i] = CT::get_generator(true, i);
|
||||
}
|
||||
|
||||
// WIP zk-argument called with zk-WIP(g, h, G, H, A_hat, aL_hat, aR_hat, alpha_hat)
|
||||
|
||||
scalar_vec_t& a = aLs_hat;
|
||||
scalar_vec_t& b = aRs_hat;
|
||||
|
||||
sig.L.resize(c_bpp_log2_mn);
|
||||
sig.R.resize(c_bpp_log2_mn);
|
||||
|
||||
// zk-WIP reduction rounds (s.a. the preprint page 13 Fig. 1)
|
||||
for (size_t n = c_bpp_mn / 2, ni = 0; n >= 1; n /= 2, ++ni)
|
||||
{
|
||||
DBG_PRINT(ENDL << "#" << ni);
|
||||
|
||||
// zk-WIP(g, h, G, H, P, a, b, alpha)
|
||||
|
||||
scalar_t dL = scalar_t::random();
|
||||
DBG_VAL_PRINT(dL);
|
||||
scalar_t dR = scalar_t::random();
|
||||
DBG_VAL_PRINT(dR);
|
||||
|
||||
// a = (a1, a2), b = (b1, b2) -- vectors of scalars
|
||||
// cL = <a1, ((y, y^2, ...) o b2)> -- scalar
|
||||
scalar_t cL = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
cL += a[i] * y_powers[i + 1] * b[n + i];
|
||||
|
||||
DBG_VAL_PRINT(cL);
|
||||
|
||||
// cR = <a2, ((y, y^2, ...) o b1)> * y^n -- scalar
|
||||
scalar_t cR = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
cR += a[n + i] * y_powers[i + 1] * b[i];
|
||||
cR *= y_powers[n];
|
||||
|
||||
DBG_VAL_PRINT(cR);
|
||||
|
||||
// L = y^-n * a1 * g2 + b2 * h1 + cL * G + dL * H -- point
|
||||
point_t sum = c_point_0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
sum += a[i] * g[n + i];
|
||||
point_t L;
|
||||
CT::calc_pedersen_commitment(cL, dL, L);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
L += b[n + i] * h[i];
|
||||
L += y_inverse_powers[n] * sum;
|
||||
L *= c_scalar_1div8;
|
||||
DBG_VAL_PRINT(L);
|
||||
|
||||
// R = y^n * a2 * g1 + b1 * h2 + cR * G + dR * H -- point
|
||||
sum.zero();
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
sum += a[n + i] * g[i];
|
||||
point_t R;
|
||||
CT::calc_pedersen_commitment(cR, dR, R);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
R += b[i] * h[n + i];
|
||||
R += y_powers[n] * sum;
|
||||
R *= c_scalar_1div8;
|
||||
DBG_VAL_PRINT(R);
|
||||
|
||||
// put L, R to the sig
|
||||
L.to_public_key(sig.L[ni]);
|
||||
R.to_public_key(sig.R[ni]);
|
||||
|
||||
// update the transcript
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.L[ni]);
|
||||
hsc.add_pub_key(sig.R[ni]);
|
||||
e = hsc.calc_hash();
|
||||
DBG_VAL_PRINT(e);
|
||||
|
||||
// recalculate arguments for the next round
|
||||
scalar_t e_squared = e * e;
|
||||
scalar_t e_inverse = e.reciprocal();
|
||||
scalar_t e_inverse_squared = e_inverse * e_inverse;
|
||||
scalar_t e_y_inv_n = e * y_inverse_powers[n];
|
||||
scalar_t e_inv_y_n = e_inverse * y_powers[n];
|
||||
|
||||
// g_hat = e^-1 * g1 + (e * y^-n) * g2 -- vector of points
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
g[i] = e_inverse * g[i] + e_y_inv_n * g[n + i];
|
||||
|
||||
// h_hat = e * h1 + e^-1 * h2 -- vector of points
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
h[i] = e * h[i] + e_inverse * h[n + i];
|
||||
|
||||
// P_hat = e^2 * L + P + e^-2 * R -- point
|
||||
|
||||
// a_hat = e * a1 + e^-1 * y^n * a2 -- vector of scalars
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
a[i] = e * a[i] + e_inv_y_n * a[n + i];
|
||||
|
||||
// b_hat = e^-1 * b1 + e * b2 -- vector of scalars
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
b[i] = e_inverse * b[i] + e * b[n + i];
|
||||
|
||||
// alpha_hat = e^2 * dL + alpha + e^-2 * dR -- scalar
|
||||
alpha_hat += e_squared * dL + e_inverse_squared * dR;
|
||||
|
||||
// run next iteraton zk-WIP(g_hat, h_hat, G, H, P_hat, a_hat, b_hat, alpha_hat)
|
||||
}
|
||||
DBG_PRINT("");
|
||||
|
||||
// zk-WIP last round
|
||||
scalar_t r = scalar_t::random();
|
||||
scalar_t s = scalar_t::random();
|
||||
scalar_t delta = scalar_t::random();
|
||||
scalar_t eta = scalar_t::random();
|
||||
DBG_VAL_PRINT(r);
|
||||
DBG_VAL_PRINT(s);
|
||||
DBG_VAL_PRINT(delta);
|
||||
DBG_VAL_PRINT(eta);
|
||||
|
||||
// A = r * g + s * h + (r y b + s y a) * G + delta * H -- point
|
||||
point_t A = c_point_0;
|
||||
CT::calc_pedersen_commitment(y * (r * b[0] + s * a[0]), delta, A);
|
||||
A += r * g[0] + s * h[0];
|
||||
A *= c_scalar_1div8;
|
||||
A.to_public_key(sig.A);
|
||||
DBG_VAL_PRINT(A);
|
||||
|
||||
// B = (r * y * s) * G + eta * H
|
||||
point_t B = c_point_0;
|
||||
CT::calc_pedersen_commitment(r * y * s, eta, B);
|
||||
B *= c_scalar_1div8;
|
||||
B.to_public_key(sig.B);
|
||||
DBG_VAL_PRINT(B);
|
||||
|
||||
// update the transcript
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A);
|
||||
hsc.add_pub_key(sig.B);
|
||||
e = hsc.calc_hash();
|
||||
DBG_VAL_PRINT(e);
|
||||
|
||||
// finalize the signature
|
||||
sig.r = r + e * a[0];
|
||||
sig.s = s + e * b[0];
|
||||
sig.delta = eta + e * delta + e * e * alpha_hat;
|
||||
DBG_VAL_PRINT(sig.r);
|
||||
DBG_VAL_PRINT(sig.s);
|
||||
DBG_VAL_PRINT(sig.delta);
|
||||
|
||||
return true;
|
||||
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
|
||||
} // bpp_gen()
|
||||
|
||||
|
||||
struct bpp_sig_commit_ref_t
|
||||
{
|
||||
bpp_sig_commit_ref_t(const bpp_signature& sig, const std::vector<point_t>& commitments)
|
||||
: sig(sig)
|
||||
, commitments(commitments)
|
||||
{}
|
||||
const bpp_signature& sig;
|
||||
const std::vector<point_t>& commitments;
|
||||
};
|
||||
|
||||
|
||||
template<typename CT>
|
||||
bool bpp_verify(const std::vector<bpp_sig_commit_ref_t>& sigs, uint8_t* p_err = nullptr)
|
||||
{
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("bpp_verify: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
DBG_PRINT(ENDL << " . . . . bpp_verify() . . . . ");
|
||||
|
||||
static_assert(CT::c_bpp_n <= 255, "too big N");
|
||||
const size_t kn = sigs.size();
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(kn > 0, 1);
|
||||
|
||||
struct intermediate_element_t
|
||||
{
|
||||
scalar_t y;
|
||||
scalar_t z;
|
||||
scalar_t z_sq;
|
||||
scalar_vec_t e;
|
||||
scalar_vec_t e_sq;
|
||||
scalar_t e_final;
|
||||
scalar_t e_final_sq;
|
||||
size_t inv_e_offset; // offset in batch_for_inverse
|
||||
size_t inv_y_offset; // offset in batch_for_inverse
|
||||
size_t c_bpp_log2_m;
|
||||
size_t c_bpp_m;
|
||||
size_t c_bpp_mn;
|
||||
point_t A;
|
||||
point_t A0;
|
||||
point_t B;
|
||||
std::vector<point_t> L;
|
||||
std::vector<point_t> R;
|
||||
};
|
||||
std::vector<intermediate_element_t> interms(kn);
|
||||
|
||||
size_t c_bpp_log2_m_max = 0;
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
const bpp_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bpp_signature& sig = bsc.sig;
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(bsc.commitments.size() > 0, 2);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() > 0 && sig.L.size() == sig.R.size(), 3);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.r.is_reduced() && sig.s.is_reduced() && sig.delta.is_reduced(), 4);
|
||||
|
||||
intermediate_element_t& interm = interms[k];
|
||||
interm.c_bpp_log2_m = constexpr_ceil_log2(bsc.commitments.size());
|
||||
if (c_bpp_log2_m_max < interm.c_bpp_log2_m)
|
||||
c_bpp_log2_m_max = interm.c_bpp_log2_m;
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() == interm.c_bpp_log2_m + CT::c_bpp_log2_n, 5);
|
||||
|
||||
interm.c_bpp_m = 1ull << interm.c_bpp_log2_m;
|
||||
interm.c_bpp_mn = interm.c_bpp_m * CT::c_bpp_n;
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A0.from_public_key(sig.A0), 6);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A.from_public_key(sig.A), 7);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.B.from_public_key(sig.B), 8);
|
||||
interm.L.resize(sig.L.size());
|
||||
interm.R.resize(sig.R.size());
|
||||
for (size_t i = 0; i < interm.L.size(); ++i)
|
||||
{
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.L[i].from_public_key(sig.L[i]), 9);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.R[i].from_public_key(sig.R[i]), 10);
|
||||
}
|
||||
}
|
||||
const size_t c_bpp_m_max = 1ull << c_bpp_log2_m_max;
|
||||
const size_t c_bpp_mn_max = c_bpp_m_max * CT::c_bpp_n;
|
||||
const size_t c_bpp_LR_size_max = c_bpp_log2_m_max + CT::c_bpp_log2_n;
|
||||
|
||||
|
||||
//
|
||||
// prepare stuff
|
||||
//
|
||||
/*
|
||||
std::vector<point_t> g(c_bpp_mn_max), h(c_bpp_mn_max);
|
||||
for (size_t i = 0; i < c_bpp_mn_max; ++i)
|
||||
{
|
||||
g[i] = CT::get_generator(false, i);
|
||||
h[i] = CT::get_generator(true, i);
|
||||
}
|
||||
*/
|
||||
|
||||
scalar_vec_t batch_for_inverse;
|
||||
batch_for_inverse.reserve(kn + kn * c_bpp_LR_size_max);
|
||||
|
||||
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
DBG_PRINT(ENDL << "SIG #" << k);
|
||||
const bpp_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bpp_signature& sig = bsc.sig;
|
||||
intermediate_element_t& interm = interms[k];
|
||||
|
||||
// restore y and z
|
||||
// using e as Fiat-Shamir transcript
|
||||
scalar_t e = CT::get_initial_transcript();
|
||||
DBG_PRINT("initial transcript: " << e);
|
||||
hash_helper_t::hs_t hsc;
|
||||
CT::update_transcript(hsc, e, bsc.commitments);
|
||||
// calculate scalar challenges y and z
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A0);
|
||||
hsc.assign_calc_hash(interm.y);
|
||||
interm.z = hash_helper_t::hs(interm.y);
|
||||
interm.z_sq = interm.z * interm.z;
|
||||
DBG_VAL_PRINT(interm.y);
|
||||
DBG_VAL_PRINT(interm.z);
|
||||
e = interm.z; // transcript for further steps
|
||||
|
||||
interm.inv_y_offset = batch_for_inverse.size();
|
||||
batch_for_inverse.push_back(interm.y);
|
||||
interm.inv_e_offset = batch_for_inverse.size();
|
||||
|
||||
interm.e.resize(sig.L.size());
|
||||
interm.e_sq.resize(sig.L.size());
|
||||
|
||||
for (size_t i = 0; i < sig.L.size(); ++i)
|
||||
{
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.L[i]);
|
||||
hsc.add_pub_key(sig.R[i]);
|
||||
hsc.assign_calc_hash(e);
|
||||
interm.e[i] = e;
|
||||
interm.e_sq[i] = e * e;
|
||||
DBG_PRINT("e[" << i << "]: " << e);
|
||||
batch_for_inverse.push_back(e);
|
||||
}
|
||||
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A);
|
||||
hsc.add_pub_key(sig.B);
|
||||
hsc.assign_calc_hash(interm.e_final);
|
||||
interm.e_final_sq = interm.e_final * interm.e_final;
|
||||
DBG_VAL_PRINT(interm.e_final);
|
||||
}
|
||||
|
||||
batch_for_inverse.invert();
|
||||
|
||||
// Notation:
|
||||
// 1_vec ^ n = (1, 1, 1, ..., 1)
|
||||
// 2_vec ^ n = (2^0, 2^1, 2^2, ..., 2^(n-1))
|
||||
// -1_vec ^ n = ((-1)^0, (-1)^1, (-1)^2, ... (-1)^(n-1)) = (1, -1, 1, -1, ...)
|
||||
// y<^n = (y^n, y^(n-1), ..., y^1)
|
||||
// y>^n = (y^1, y^2, ..., y^n)
|
||||
|
||||
// from page 13, Fig 1:
|
||||
// Verifier outputs Accept IFF the following equality holds (single proof):
|
||||
// P^e^2 * A^e * B == g ^ (r' e) * h ^ (s' e) * G ^ (r' y s') * H ^ delta'
|
||||
// (where g and h are calculated in each round)
|
||||
// The same equation in additive notation:
|
||||
// e^2 * P + e * A + B == (r' * e) * g + (s' * e) * h + (r' y s') * G + delta' * H
|
||||
// <=>
|
||||
// (r' * e) * g + (s' * e) * h + (r' y s') * G + delta' * H - e^2 * P - e * A - B == 0 (*)
|
||||
// where A, B, r', s', delta' is taken from the signature
|
||||
// and P_{k+1} = e^2 * L_k + P_k + e^-2 * R_k for all rounds
|
||||
//
|
||||
// from page 18, Fig 3:
|
||||
// P and V computes:
|
||||
// A_hat = A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h +
|
||||
// + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) +
|
||||
// + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G
|
||||
// (calculated once)
|
||||
//
|
||||
// As suggested in Section 6.1 "Practical Optimizations":
|
||||
// 1) g and h exponentianions can be optimized in order not to be calculated at each round as the following (page 20):
|
||||
//
|
||||
// (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta' * H -
|
||||
// - e^2 * A_hat
|
||||
// - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j)
|
||||
// - e * A - B = 0 (**)
|
||||
//
|
||||
// where:
|
||||
// g, h - vector of fixed generators
|
||||
// s_vec_i = y^(1-i) * PROD{j=1..log(n)}(e_j ^ b(i,j))
|
||||
// s'_vec_i = PROD{j=1..log(n)}(e_j ^ -b(i,j))
|
||||
// b(i, j) = { 2 * ((1<<(j-1)) & (i-1)) - 1) (counting both from 1) (page 20)
|
||||
// b(i, j) = { 2 * ((1<<j) & i) - 1) (counting both from 0)
|
||||
//
|
||||
// 2) we gonna aggregate all (**) for each round by multiplying them to a random weights and then sum up
|
||||
// insert A_hat into (**) =>
|
||||
|
||||
// (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta' * H -
|
||||
// - e^2 * (A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h +
|
||||
// + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) +
|
||||
// + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G
|
||||
// )
|
||||
// - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j)
|
||||
// - e * A - B = 0
|
||||
|
||||
// =>
|
||||
|
||||
// (for single signature)
|
||||
//
|
||||
// (r' * e * s_vec - e^2 * (- 1_vec^(mn) * z)) * g | these are
|
||||
// + (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z)) * h | fixed generators
|
||||
// + (r' y s' - e^2 * ((z - z^2)*SUM(y^>mn) - z*y^(mn+1)*SUM(d)) * G | across all
|
||||
// + delta' * H | the signatures
|
||||
//
|
||||
// - e^2 * A0
|
||||
// - e^2 * y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j))
|
||||
// - e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j)
|
||||
// - e * A - B = 0 (***)
|
||||
//
|
||||
// All (***) will be muptiplied by random weightning factor and then summed up.
|
||||
|
||||
// Calculate cummulative sclalar multiplicand for fixed generators across all the sigs.
|
||||
scalar_vec_t g_scalars;
|
||||
g_scalars.resize(c_bpp_mn_max, 0);
|
||||
scalar_vec_t h_scalars;
|
||||
h_scalars.resize(c_bpp_mn_max, 0);
|
||||
scalar_t G_scalar = 0;
|
||||
scalar_t H_scalar = 0;
|
||||
point_t summand = c_point_0;
|
||||
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
DBG_PRINT(ENDL << "SIG #" << k);
|
||||
const bpp_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bpp_signature& sig = bsc.sig;
|
||||
intermediate_element_t& interm = interms[k];
|
||||
|
||||
// random weightning factor for speed-optimized batch verification (preprint page 20)
|
||||
const scalar_t rwf = scalar_t::random();
|
||||
DBG_PRINT("rwf: " << rwf);
|
||||
|
||||
// prepare d vector (see also d structure description in proof function)
|
||||
scalar_mat_t<CT::c_bpp_n> d(interm.c_bpp_mn);
|
||||
d(0, 0) = interm.z_sq;
|
||||
// first row
|
||||
for (size_t i = 1; i < interm.c_bpp_m; ++i)
|
||||
d(i, 0) = d(i - 1, 0) * interm.z_sq;
|
||||
// all rows
|
||||
for (size_t j = 1; j < CT::c_bpp_n; ++j)
|
||||
for (size_t i = 0; i < interm.c_bpp_m; ++i)
|
||||
d(i, j) = d(i, j - 1) + d(i, j - 1);
|
||||
// sum(d) (see also note in proof function for this)
|
||||
const scalar_t sum_d = CT::get_2_to_the_power_of_N_minus_1() * sum_of_powers(interm.z_sq, interm.c_bpp_log2_m);
|
||||
|
||||
DBG_PRINT("Hs(d): " << d.calc_hs());
|
||||
DBG_PRINT("sum(d): " << sum_d);
|
||||
|
||||
const scalar_t& y_inv = batch_for_inverse[interm.inv_y_offset];
|
||||
auto get_e_inv = [&](size_t i) { return batch_for_inverse[interm.inv_e_offset + i]; }; // i belongs to [0; L.size()-1]
|
||||
|
||||
// prepare s_vec (unlike the paper here we moved y-component out of s_vec for convenience, so s_vec'[x] = s_vec[~x & (MN-1)])
|
||||
// complexity (sc_mul's): MN+2*log2(MN)-2
|
||||
// the idea is the following:
|
||||
// s_vec[00000b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^-1 * (e_1)^-1 * (e_0)^-1
|
||||
// s_vec[00101b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^+1 * (e_1)^-1 * (e_0)^+1
|
||||
const size_t log2_mn = sig.L.size(); // at the beginning we made sure that sig.L.size() == c_bpp_log2_m + c_bpp_log2_n
|
||||
scalar_vec_t s_vec(interm.c_bpp_mn);
|
||||
s_vec[0] = get_e_inv(0);
|
||||
for (size_t i = 1; i < log2_mn; ++i)
|
||||
s_vec[0] *= get_e_inv(i); // s_vec[0] = (e_0)^-1 * (e_1)^-1 * .. (e_{log2_mn-1})^-1
|
||||
DBG_PRINT("[0] " << s_vec[0]);
|
||||
for (size_t i = 1; i < interm.c_bpp_mn; ++i)
|
||||
{
|
||||
size_t base_el_index = i & (i - 1); // base element index: 0, 0, 2, 0, 4, 4, 6, 0, 8, 8, 10... base element differs in one bit (0) from the current one (1)
|
||||
size_t bit_index = log2_mn - calc_lsb_32((uint32_t)i) - 1; // the bit index where current element has the difference with the base
|
||||
s_vec[i] = s_vec[base_el_index] * interm.e_sq[bit_index]; // (e_j)^-1 * (e_j)^2 = (e_j)^+1
|
||||
DBG_PRINT("[" << i << "] " << " " << base_el_index << ", " << bit_index << " : " << s_vec[i]);
|
||||
}
|
||||
|
||||
// prepare y_inv vector
|
||||
scalar_vec_t y_inverse_powers(interm.c_bpp_mn);
|
||||
y_inverse_powers[0] = 1;
|
||||
for (size_t i = 1; i < interm.c_bpp_mn; ++i)
|
||||
y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inv;
|
||||
|
||||
// y^(mn+1)
|
||||
scalar_t y_power_mnp1 = interm.y;
|
||||
for (size_t i = 0; i < log2_mn; ++i)
|
||||
y_power_mnp1 *= y_power_mnp1;
|
||||
y_power_mnp1 *= interm.y;
|
||||
DBG_VAL_PRINT(y_power_mnp1);
|
||||
|
||||
// now calculate all multiplicands for common generators
|
||||
|
||||
// g vector multiplicands:
|
||||
// rwf * (r' * e * (1, y^-1, y^-2, ...) o s_vec + e^2 * z) =
|
||||
// rwf * r' * e * ((1, y^-1, ...) o s_vec) + rwf * e^2 * z * (1, 1, ...)
|
||||
scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z;
|
||||
scalar_t rwf_r_e = rwf * interm.e_final * sig.r;
|
||||
for (size_t i = 0; i < interm.c_bpp_mn; ++i)
|
||||
g_scalars[i] += rwf_r_e * y_inverse_powers[i] * s_vec[i] + rwf_e_sq_z;
|
||||
|
||||
DBG_PRINT("Hs(g_scalars): " << g_scalars.calc_hs());
|
||||
|
||||
// h vector multiplicands:
|
||||
// rwf * (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z))
|
||||
// rwf * s' * e * s'_vec - rwf * e^2 * z * (1, 1...) - rwf * e^2 * (d o y<^(mn))
|
||||
//scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z;
|
||||
scalar_t rwf_s_e = rwf * sig.s * interm.e_final;
|
||||
scalar_t rwf_e_sq_y = rwf * interm.e_final_sq * interm.y;
|
||||
for (size_t i = interm.c_bpp_mn - 1; i != SIZE_MAX; --i)
|
||||
{
|
||||
h_scalars[i] += rwf_s_e * s_vec[interm.c_bpp_mn - 1 - i] - rwf_e_sq_z - rwf_e_sq_y * d[i];
|
||||
rwf_e_sq_y *= interm.y;
|
||||
}
|
||||
|
||||
DBG_PRINT("Hs(h_scalars): " << h_scalars.calc_hs());
|
||||
|
||||
// G point multiplicands:
|
||||
// rwf * (r' y s' - e ^ 2 * ((z - z ^ 2)*SUM(y^>mn) - z * y^(mn+1) * SUM(d)) =
|
||||
// = rwf * r' y s' - rwf * e^2 * (z - z ^ 2)*SUM(y^>mn) + rwf * e^2 * z * y^(mn+1) * SUM(d)
|
||||
G_scalar += rwf * sig.r * interm.y * sig.s + rwf_e_sq_y * sum_d * interm.z;
|
||||
G_scalar -= rwf * interm.e_final_sq * (interm.z - interm.z_sq) * sum_of_powers(interm.y, log2_mn);
|
||||
DBG_PRINT("sum_y: " << sum_of_powers(interm.y, log2_mn));
|
||||
DBG_PRINT("G_scalar: " << G_scalar);
|
||||
|
||||
// H point multiplicands:
|
||||
// rwf * delta
|
||||
H_scalar += rwf * sig.delta;
|
||||
DBG_PRINT("H_scalar: " << H_scalar);
|
||||
|
||||
// uncommon generators' multiplicands
|
||||
point_t summand_8 = c_point_0; // this summand to be multiplied by 8 before adding to the main summand
|
||||
// - rwf * e^2 * A0
|
||||
summand_8 -= rwf * interm.e_final_sq * interm.A0;
|
||||
DBG_PRINT("A0_scalar: " << c_scalar_Lm1 * interm.e_final_sq * rwf);
|
||||
|
||||
// - rwf * e^2 * y^(mn+1) * (SUM{j=1..m} (z^2)^j * V_j))
|
||||
scalar_t e_sq_y_mn1_z_sq_power = rwf * interm.e_final_sq * y_power_mnp1;
|
||||
for (size_t j = 0; j < bsc.commitments.size(); ++j)
|
||||
{
|
||||
e_sq_y_mn1_z_sq_power *= interm.z_sq;
|
||||
summand_8 -= e_sq_y_mn1_z_sq_power * bsc.commitments[j];
|
||||
DBG_PRINT("V_scalar[" << j << "]: " << c_scalar_Lm1 * e_sq_y_mn1_z_sq_power);
|
||||
}
|
||||
|
||||
// - rwf * e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j)
|
||||
scalar_t rwf_e_sq = rwf * interm.e_final_sq;
|
||||
for (size_t j = 0; j < log2_mn; ++j)
|
||||
{
|
||||
summand_8 -= rwf_e_sq * (interm.e_sq[j] * interm.L[j] + get_e_inv(j) * get_e_inv(j) * interm.R[j]);
|
||||
DBG_PRINT("L_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * interm.e_sq[j]);
|
||||
DBG_PRINT("R_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * get_e_inv(j) * get_e_inv(j));
|
||||
}
|
||||
|
||||
// - rwf * e * A - rwf * B = 0
|
||||
summand_8 -= rwf * interm.e_final * interm.A + rwf * interm.B;
|
||||
DBG_PRINT("A_scalar: " << c_scalar_Lm1 * rwf * interm.e_final);
|
||||
DBG_PRINT("B_scalar: " << c_scalar_Lm1 * rwf);
|
||||
|
||||
summand_8.modify_mul8();
|
||||
summand += summand_8;
|
||||
}
|
||||
|
||||
point_t GH_exponents = c_point_0;
|
||||
CT::calc_pedersen_commitment(G_scalar, H_scalar, GH_exponents);
|
||||
bool result = multiexp_and_check_being_zero<CT>(g_scalars, h_scalars, summand + GH_exponents);
|
||||
if (result)
|
||||
DBG_PRINT(ENDL << " . . . . bpp_verify() -- SUCCEEDED!!!" << ENDL);
|
||||
return result;
|
||||
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
|
||||
}
|
||||
|
||||
} // namespace crypto
|
||||
719
src/crypto/range_proof_bppe.h
Normal file
719
src/crypto/range_proof_bppe.h
Normal file
|
|
@ -0,0 +1,719 @@
|
|||
// Copyright (c) 2022 Zano Project (https://zano.org/)
|
||||
// Copyright (c) 2022 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// This file contains the implementation of range proof protocol.
|
||||
// Namely, Bulletproofs+ https://eprint.iacr.org/2020/735
|
||||
// Double-blinded commitments extension implemented as in Appendix D in the Zarcanum whitepaper: https://eprint.iacr.org/2021/1478
|
||||
|
||||
namespace crypto
|
||||
{
|
||||
struct bppe_signature
|
||||
{
|
||||
std::vector<public_key> L; // size = log_2(m * n)
|
||||
std::vector<public_key> R;
|
||||
public_key A0;
|
||||
public_key A;
|
||||
public_key B;
|
||||
scalar_t r;
|
||||
scalar_t s;
|
||||
scalar_t delta_1;
|
||||
scalar_t delta_2;
|
||||
};
|
||||
|
||||
#define DBG_VAL_PRINT(x) std::cout << #x ": " << x << ENDL
|
||||
#define DBG_PRINT(x) std::cout << x << ENDL
|
||||
|
||||
template<typename CT>
|
||||
bool bppe_gen(const scalar_vec_t& values, const scalar_vec_t& masks, const scalar_vec_t& masks2, bppe_signature& sig, std::vector<point_t>& commitments, uint8_t* p_err = nullptr)
|
||||
{
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("bppe_gen: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
static_assert(CT::c_bpp_n <= 255, "too big N");
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(values.size() > 0 && values.size() <= CT::c_bpp_values_max && values.size() == masks.size() && masks.size() == masks2.size(), 1);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(masks.is_reduced() && masks2.is_reduced(), 3);
|
||||
|
||||
const size_t c_bpp_log2_m = constexpr_ceil_log2(values.size());
|
||||
const size_t c_bpp_m = 1ull << c_bpp_log2_m;
|
||||
const size_t c_bpp_mn = c_bpp_m * CT::c_bpp_n;
|
||||
const size_t c_bpp_log2_mn = c_bpp_log2_m + CT::c_bpp_log2_n;
|
||||
|
||||
// pre-multiply all output points by c_scalar_1div8
|
||||
// in order to enforce these points to be in the prime-order subgroup (after mul by 8 in bpp_verify())
|
||||
|
||||
// calc commitments vector as commitments[i] = 1/8 * values[i] * G + 1/8 * masks[i] * H + 1/8 * masks2[i] * H2
|
||||
commitments.resize(values.size());
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
CT::calc_pedersen_commitment_2(values[i] * c_scalar_1div8, masks[i] * c_scalar_1div8, masks2[i] * c_scalar_1div8, commitments[i]);
|
||||
|
||||
|
||||
// s.a. BP+ paper, page 15, eq. 11
|
||||
// decompose v into aL and aR:
|
||||
// v = aL o (1, 2, 2^2, ..., 2^n-1), o - component-wise product aka Hadamard product
|
||||
// aR = aL - (1, 1, ... 1)
|
||||
// aR o aL = 0
|
||||
|
||||
// aLs = (aL_0, aL_1, ..., aL_m-1) -- `bit` matrix of c_bpp_m x c_bpp_n, each element is a scalar
|
||||
|
||||
scalar_mat_t<CT::c_bpp_n> aLs(c_bpp_mn), aRs(c_bpp_mn);
|
||||
aLs.zero();
|
||||
aRs.zero();
|
||||
// m >= values.size, first set up [0..values.size-1], then -- [values.size..m-1] (padding area)
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
{
|
||||
const scalar_t& v = values[i];
|
||||
for (uint8_t j = 0; j < CT::c_bpp_n; ++j)
|
||||
{
|
||||
if (v.get_bit(j))
|
||||
aLs(i, j) = c_scalar_1; // aL = 1, aR = 0
|
||||
else
|
||||
aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = values.size(); i < c_bpp_m; ++i)
|
||||
for (size_t j = 0; j < CT::c_bpp_n; ++j)
|
||||
aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1
|
||||
|
||||
|
||||
// using e as Fiat-Shamir transcript
|
||||
scalar_t e = CT::get_initial_transcript();
|
||||
DBG_PRINT("initial transcript: " << e);
|
||||
|
||||
hash_helper_t::hs_t hsc;
|
||||
CT::update_transcript(hsc, e, commitments);
|
||||
|
||||
// Zarcanum paper, page 33, Fig. D.3: The prover chooses alpha_1, alpha_2 and computes A = g^aL h^aR h_1^alpha_1 h_2^alpha_2
|
||||
// so we calculate A0 = alpha_1 * H + alpha_2 * H_2 + SUM(aL_i * G_i) + SUM(aR_i * H_i)
|
||||
|
||||
scalar_t alpha_1 = scalar_t::random(), alpha_2 = scalar_t::random();
|
||||
point_t A0 = alpha_1 * CT::bpp_H + alpha_2 * CT::bpp_H2;
|
||||
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
A0 += aLs[i] * CT::get_generator(false, i) + aRs[i] * CT::get_generator(true, i);
|
||||
|
||||
// part of 1/8 defense scheme
|
||||
A0 *= c_scalar_1div8;
|
||||
A0.to_public_key(sig.A0);
|
||||
|
||||
DBG_VAL_PRINT(alpha_1);
|
||||
DBG_VAL_PRINT(alpha_2);
|
||||
DBG_VAL_PRINT(A0);
|
||||
|
||||
// calculate scalar challenges y and z
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A0);
|
||||
scalar_t y = hsc.calc_hash();
|
||||
scalar_t z = hash_helper_t::hs(y);
|
||||
e = z; // transcript for further steps
|
||||
DBG_VAL_PRINT(y);
|
||||
DBG_VAL_PRINT(z);
|
||||
|
||||
// Computing vector d for aggregated version of the protocol (BP+ paper, page 17)
|
||||
// (note: elements are stored column-by-column in memory)
|
||||
// d = | 1 * z^(2*1), 1 * z^(2*2), 1 * z^(2*3), ..., 1 * z^(2*m) |
|
||||
// | 2 * z^(2*1), 2 * z^(2*2), 2 * z^(2*3), ..., 2 * z^(2*m) |
|
||||
// | 4 * z^(2*1), 4 * z^(2*2), 4 * z^(2*3), ..., 4 * z^(2*m) |
|
||||
// | ....................................................................................... |
|
||||
// | 2^(n-1) * z^(2*1), 2^(n-1) * z^(2*2), 2^(n-1) * z^(2*3), ..., 2^(n-1) * z^(2*m)) |
|
||||
// Note: sum(d_i) = (2^n - 1) * ((z^2)^1 + (z^2)^2 + ... (z^2)^m)) = (2^n-1) * sum_of_powers(x^2, log(m))
|
||||
|
||||
scalar_t z_sq = z * z;
|
||||
scalar_mat_t<CT::c_bpp_n> d(c_bpp_mn);
|
||||
d(0, 0) = z_sq;
|
||||
// first row
|
||||
for (size_t i = 1; i < c_bpp_m; ++i)
|
||||
d(i, 0) = d(i - 1, 0) * z_sq;
|
||||
// all rows
|
||||
for (size_t j = 1; j < CT::c_bpp_n; ++j)
|
||||
for (size_t i = 0; i < c_bpp_m; ++i)
|
||||
d(i, j) = d(i, j - 1) + d(i, j - 1);
|
||||
|
||||
DBG_PRINT("Hs(d): " << d.calc_hs());
|
||||
|
||||
// calculate extended Vandermonde vector y = (1, y, y^2, ..., y^(mn+1)) (BP+ paper, page 18, Fig. 3)
|
||||
// (calculate two more elements (1 and y^(mn+1)) for convenience)
|
||||
scalar_vec_t y_powers(c_bpp_mn + 2);
|
||||
y_powers[0] = 1;
|
||||
for (size_t i = 1; i <= c_bpp_mn + 1; ++i)
|
||||
y_powers[i] = y_powers[i - 1] * y;
|
||||
|
||||
const scalar_t& y_mn_p1 = y_powers[c_bpp_mn + 1];
|
||||
|
||||
DBG_PRINT("Hs(y_powers): " << y_powers.calc_hs());
|
||||
|
||||
// aL_hat = aL - 1*z
|
||||
scalar_vec_t aLs_hat = aLs - z;
|
||||
// aL_hat = aR + d o y^leftarr + 1*z where y^leftarr = (y^n, y^(n-1), ..., y) (BP+ paper, page 18, Fig. 3)
|
||||
scalar_vec_t aRs_hat = aRs + z;
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
aRs_hat[i] += d[i] * y_powers[c_bpp_mn - i];
|
||||
|
||||
DBG_PRINT("Hs(aLs_hat): " << aLs_hat.calc_hs());
|
||||
DBG_PRINT("Hs(aRs_hat): " << aRs_hat.calc_hs());
|
||||
|
||||
// calculate alpha_hat
|
||||
// alpha_hat_1 = alpha_1 + SUM(z^(2j) * gamma_1,j * y^(mn+1)) for j = 1..m
|
||||
// alpha_hat_2 = alpha_2 + SUM(z^(2j) * gamma_2,j * y^(mn+1)) for j = 1..m
|
||||
// i.e. \hat{\alpha} = \alpha + y^{m n+1} \sum_{j = 1}^{m} z^{2j} \gamma_j
|
||||
scalar_t alpha_hat_1 = 0, alpha_hat_2 = 0;
|
||||
for (size_t i = 0; i < masks.size(); ++i)
|
||||
{
|
||||
alpha_hat_1 += d(i, 0) * masks[i];
|
||||
alpha_hat_2 += d(i, 0) * masks2[i];
|
||||
}
|
||||
alpha_hat_1 = alpha_1 + y_mn_p1 * alpha_hat_1;
|
||||
alpha_hat_2 = alpha_2 + y_mn_p1 * alpha_hat_2;
|
||||
|
||||
DBG_VAL_PRINT(alpha_hat_1);
|
||||
DBG_VAL_PRINT(alpha_hat_2);
|
||||
|
||||
// calculate 1, y^-1, y^-2, ...
|
||||
const scalar_t y_inverse = y.reciprocal();
|
||||
scalar_vec_t y_inverse_powers(c_bpp_mn / 2 + 1); // the greatest power we need is c_bpp_mn/2 (at the first reduction round)
|
||||
y_inverse_powers[0] = 1;
|
||||
for (size_t i = 1, size = y_inverse_powers.size(); i < size; ++i)
|
||||
y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inverse;
|
||||
|
||||
// prepare generator's vector
|
||||
std::vector<point_t> g(c_bpp_mn), h(c_bpp_mn);
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
{
|
||||
g[i] = CT::get_generator(false, i);
|
||||
h[i] = CT::get_generator(true, i);
|
||||
}
|
||||
|
||||
// WIP zk-argument called with zk-WIP(g, h, G, H, H2, A_hat, aL_hat, aR_hat, alpha_hat_1, alpha_hat_2)
|
||||
|
||||
scalar_vec_t& a = aLs_hat;
|
||||
scalar_vec_t& b = aRs_hat;
|
||||
|
||||
sig.L.resize(c_bpp_log2_mn);
|
||||
sig.R.resize(c_bpp_log2_mn);
|
||||
|
||||
// zk-WIP reduction rounds (s.a. Zarcanum preprint page 24 Fig. D.1)
|
||||
for (size_t n = c_bpp_mn / 2, ni = 0; n >= 1; n /= 2, ++ni)
|
||||
{
|
||||
DBG_PRINT(ENDL << "#" << ni);
|
||||
|
||||
// zk-WIP(g, h, G, H, H2, P, a, b, alpha_1, alpha_2)
|
||||
|
||||
scalar_t dL = scalar_t::random(), dL2 = scalar_t::random();
|
||||
DBG_VAL_PRINT(dL); DBG_VAL_PRINT(dL2);
|
||||
scalar_t dR = scalar_t::random(), dR2 = scalar_t::random();
|
||||
DBG_VAL_PRINT(dR); DBG_VAL_PRINT(dR2);
|
||||
|
||||
// a = (a1, a2), b = (b1, b2) -- vectors of scalars
|
||||
// cL = <a1, ((y, y^2, ...) o b2)> -- scalar
|
||||
scalar_t cL = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
cL += a[i] * y_powers[i + 1] * b[n + i];
|
||||
|
||||
DBG_VAL_PRINT(cL);
|
||||
|
||||
// cR = <a2, ((y, y^2, ...) o b1)> * y^n -- scalar
|
||||
scalar_t cR = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
cR += a[n + i] * y_powers[i + 1] * b[i];
|
||||
cR *= y_powers[n];
|
||||
|
||||
DBG_VAL_PRINT(cR);
|
||||
|
||||
// L = y^-n * a1 * g2 + b2 * h1 + cL * G + dL * H + dL2 * H2 -- point
|
||||
point_t sum = c_point_0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
sum += a[i] * g[n + i];
|
||||
point_t L;
|
||||
CT::calc_pedersen_commitment_2(cL, dL, dL2, L);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
L += b[n + i] * h[i];
|
||||
L += y_inverse_powers[n] * sum;
|
||||
L *= c_scalar_1div8;
|
||||
DBG_VAL_PRINT(L);
|
||||
|
||||
// R = y^n * a2 * g1 + b1 * h2 + cR * G + dR * H + dR2 * H2 -- point
|
||||
sum.zero();
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
sum += a[n + i] * g[i];
|
||||
point_t R;
|
||||
CT::calc_pedersen_commitment_2(cR, dR, dR2, R);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
R += b[i] * h[n + i];
|
||||
R += y_powers[n] * sum;
|
||||
R *= c_scalar_1div8;
|
||||
DBG_VAL_PRINT(R);
|
||||
|
||||
// put L, R to the sig
|
||||
L.to_public_key(sig.L[ni]);
|
||||
R.to_public_key(sig.R[ni]);
|
||||
|
||||
// update the transcript
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.L[ni]);
|
||||
hsc.add_pub_key(sig.R[ni]);
|
||||
e = hsc.calc_hash();
|
||||
DBG_VAL_PRINT(e);
|
||||
|
||||
// recalculate arguments for the next round
|
||||
scalar_t e_squared = e * e;
|
||||
scalar_t e_inverse = e.reciprocal();
|
||||
scalar_t e_inverse_squared = e_inverse * e_inverse;
|
||||
scalar_t e_y_inv_n = e * y_inverse_powers[n];
|
||||
scalar_t e_inv_y_n = e_inverse * y_powers[n];
|
||||
|
||||
// g_hat = e^-1 * g1 + (e * y^-n) * g2 -- vector of points
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
g[i] = e_inverse * g[i] + e_y_inv_n * g[n + i];
|
||||
|
||||
// h_hat = e * h1 + e^-1 * h2 -- vector of points
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
h[i] = e * h[i] + e_inverse * h[n + i];
|
||||
|
||||
// P_hat = e^2 * L + P + e^-2 * R -- point
|
||||
|
||||
// a_hat = e * a1 + e^-1 * y^n * a2 -- vector of scalars
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
a[i] = e * a[i] + e_inv_y_n * a[n + i];
|
||||
|
||||
// b_hat = e^-1 * b1 + e * b2 -- vector of scalars
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
b[i] = e_inverse * b[i] + e * b[n + i];
|
||||
|
||||
// alpha_hat_1 = e^2 * dL + alpha_1 + e^-2 * dR -- scalar
|
||||
// alpha_hat_2 = e^2 * dL2 + alpha_2 + e^-2 * dR2 -- scalar
|
||||
alpha_hat_1 += e_squared * dL + e_inverse_squared * dR;
|
||||
alpha_hat_2 += e_squared * dL2 + e_inverse_squared * dR2;
|
||||
|
||||
// run next iteraton zk-WIP(g_hat, h_hat, G, H, H2, P_hat, a_hat, b_hat, alpha_hat_1, alpha_hat_2)
|
||||
}
|
||||
DBG_PRINT("");
|
||||
|
||||
// zk-WIP last round
|
||||
scalar_t r = scalar_t::random();
|
||||
scalar_t s = scalar_t::random();
|
||||
scalar_t delta_1 = scalar_t::random(), delta_2 = scalar_t::random();
|
||||
scalar_t eta_1 = scalar_t::random(), eta_2 = scalar_t::random();
|
||||
DBG_VAL_PRINT(r);
|
||||
DBG_VAL_PRINT(s);
|
||||
DBG_VAL_PRINT(delta_1); DBG_VAL_PRINT(delta_2);
|
||||
DBG_VAL_PRINT(eta_1); DBG_VAL_PRINT(eta_2);
|
||||
|
||||
// A = r * g + s * h + (r y b + s y a) * G + delta_1 * H + delta_2 * H2 -- point
|
||||
point_t A = c_point_0;
|
||||
CT::calc_pedersen_commitment_2(y * (r * b[0] + s * a[0]), delta_1, delta_2, A);
|
||||
A += r * g[0] + s * h[0];
|
||||
A *= c_scalar_1div8;
|
||||
A.to_public_key(sig.A);
|
||||
DBG_VAL_PRINT(A);
|
||||
|
||||
// B = (r * y * s) * G + eta_1 * H + eta_2 * H2
|
||||
point_t B = c_point_0;
|
||||
CT::calc_pedersen_commitment_2(r * y * s, eta_1, eta_2, B);
|
||||
B *= c_scalar_1div8;
|
||||
B.to_public_key(sig.B);
|
||||
DBG_VAL_PRINT(B);
|
||||
|
||||
// update the transcript
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A);
|
||||
hsc.add_pub_key(sig.B);
|
||||
e = hsc.calc_hash();
|
||||
DBG_VAL_PRINT(e);
|
||||
|
||||
// finalize the signature
|
||||
sig.r = r + e * a[0];
|
||||
sig.s = s + e * b[0];
|
||||
sig.delta_1 = eta_1 + e * delta_1 + e * e * alpha_hat_1;
|
||||
sig.delta_2 = eta_2 + e * delta_2 + e * e * alpha_hat_2;
|
||||
DBG_VAL_PRINT(sig.r);
|
||||
DBG_VAL_PRINT(sig.s);
|
||||
DBG_VAL_PRINT(sig.delta_1);
|
||||
DBG_VAL_PRINT(sig.delta_2);
|
||||
|
||||
return true;
|
||||
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
|
||||
} // bppe_gen()
|
||||
|
||||
|
||||
struct bppe_sig_commit_ref_t
|
||||
{
|
||||
bppe_sig_commit_ref_t(const bppe_signature& sig, const std::vector<point_t>& commitments)
|
||||
: sig(sig)
|
||||
, commitments(commitments)
|
||||
{}
|
||||
const bppe_signature& sig;
|
||||
const std::vector<point_t>& commitments;
|
||||
};
|
||||
|
||||
|
||||
template<typename CT>
|
||||
bool bppe_verify(const std::vector<bppe_sig_commit_ref_t>& sigs, uint8_t* p_err = nullptr)
|
||||
{
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("bppe_verify: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
DBG_PRINT(ENDL << " . . . . bppe_verify() . . . . ");
|
||||
|
||||
static_assert(CT::c_bpp_n <= 255, "too big N");
|
||||
const size_t kn = sigs.size();
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(kn > 0, 1);
|
||||
|
||||
struct intermediate_element_t
|
||||
{
|
||||
scalar_t y;
|
||||
scalar_t z;
|
||||
scalar_t z_sq;
|
||||
scalar_vec_t e;
|
||||
scalar_vec_t e_sq;
|
||||
scalar_t e_final;
|
||||
scalar_t e_final_sq;
|
||||
size_t inv_e_offset; // offset in batch_for_inverse
|
||||
size_t inv_y_offset; // offset in batch_for_inverse
|
||||
size_t c_bpp_log2_m;
|
||||
size_t c_bpp_m;
|
||||
size_t c_bpp_mn;
|
||||
point_t A;
|
||||
point_t A0;
|
||||
point_t B;
|
||||
std::vector<point_t> L;
|
||||
std::vector<point_t> R;
|
||||
};
|
||||
std::vector<intermediate_element_t> interms(kn);
|
||||
|
||||
size_t c_bpp_log2_m_max = 0;
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
const bppe_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bppe_signature& sig = bsc.sig;
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(bsc.commitments.size() > 0, 2);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() > 0 && sig.L.size() == sig.R.size(), 3);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.r.is_reduced() && sig.s.is_reduced() && sig.delta_1.is_reduced() && sig.delta_2.is_reduced(), 4);
|
||||
|
||||
intermediate_element_t& interm = interms[k];
|
||||
interm.c_bpp_log2_m = constexpr_ceil_log2(bsc.commitments.size());
|
||||
if (c_bpp_log2_m_max < interm.c_bpp_log2_m)
|
||||
c_bpp_log2_m_max = interm.c_bpp_log2_m;
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() == interm.c_bpp_log2_m + CT::c_bpp_log2_n, 5);
|
||||
|
||||
interm.c_bpp_m = 1ull << interm.c_bpp_log2_m;
|
||||
interm.c_bpp_mn = interm.c_bpp_m * CT::c_bpp_n;
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A0.from_public_key(sig.A0), 6);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A.from_public_key(sig.A), 7);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.B.from_public_key(sig.B), 8);
|
||||
interm.L.resize(sig.L.size());
|
||||
interm.R.resize(sig.R.size());
|
||||
for (size_t i = 0; i < interm.L.size(); ++i)
|
||||
{
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.L[i].from_public_key(sig.L[i]), 9);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.R[i].from_public_key(sig.R[i]), 10);
|
||||
}
|
||||
}
|
||||
const size_t c_bpp_m_max = 1ull << c_bpp_log2_m_max;
|
||||
const size_t c_bpp_mn_max = c_bpp_m_max * CT::c_bpp_n;
|
||||
const size_t c_bpp_LR_size_max = c_bpp_log2_m_max + CT::c_bpp_log2_n;
|
||||
|
||||
|
||||
//
|
||||
// prepare stuff
|
||||
//
|
||||
/*
|
||||
std::vector<point_t> g(c_bpp_mn_max), h(c_bpp_mn_max);
|
||||
for (size_t i = 0; i < c_bpp_mn_max; ++i)
|
||||
{
|
||||
g[i] = CT::get_generator(false, i);
|
||||
h[i] = CT::get_generator(true, i);
|
||||
}
|
||||
*/
|
||||
|
||||
scalar_vec_t batch_for_inverse;
|
||||
batch_for_inverse.reserve(kn + kn * c_bpp_LR_size_max);
|
||||
|
||||
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
DBG_PRINT(ENDL << "SIG #" << k);
|
||||
const bppe_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bppe_signature& sig = bsc.sig;
|
||||
intermediate_element_t& interm = interms[k];
|
||||
|
||||
// restore y and z
|
||||
// using e as Fiat-Shamir transcript
|
||||
scalar_t e = CT::get_initial_transcript();
|
||||
DBG_PRINT("initial transcript: " << e);
|
||||
hash_helper_t::hs_t hsc;
|
||||
CT::update_transcript(hsc, e, bsc.commitments);
|
||||
// calculate scalar challenges y and z
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A0);
|
||||
hsc.assign_calc_hash(interm.y);
|
||||
interm.z = hash_helper_t::hs(interm.y);
|
||||
interm.z_sq = interm.z * interm.z;
|
||||
DBG_VAL_PRINT(interm.y);
|
||||
DBG_VAL_PRINT(interm.z);
|
||||
e = interm.z; // transcript for further steps
|
||||
|
||||
interm.inv_y_offset = batch_for_inverse.size();
|
||||
batch_for_inverse.push_back(interm.y);
|
||||
interm.inv_e_offset = batch_for_inverse.size();
|
||||
|
||||
interm.e.resize(sig.L.size());
|
||||
interm.e_sq.resize(sig.L.size());
|
||||
|
||||
for (size_t i = 0; i < sig.L.size(); ++i)
|
||||
{
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.L[i]);
|
||||
hsc.add_pub_key(sig.R[i]);
|
||||
hsc.assign_calc_hash(e);
|
||||
interm.e[i] = e;
|
||||
interm.e_sq[i] = e * e;
|
||||
DBG_PRINT("e[" << i << "]: " << e);
|
||||
batch_for_inverse.push_back(e);
|
||||
}
|
||||
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A);
|
||||
hsc.add_pub_key(sig.B);
|
||||
hsc.assign_calc_hash(interm.e_final);
|
||||
interm.e_final_sq = interm.e_final * interm.e_final;
|
||||
DBG_VAL_PRINT(interm.e_final);
|
||||
}
|
||||
|
||||
batch_for_inverse.invert();
|
||||
|
||||
// Notation:
|
||||
// 1_vec ^ n = (1, 1, 1, ..., 1)
|
||||
// 2_vec ^ n = (2^0, 2^1, 2^2, ..., 2^(n-1))
|
||||
// -1_vec ^ n = ((-1)^0, (-1)^1, (-1)^2, ... (-1)^(n-1)) = (1, -1, 1, -1, ...)
|
||||
// y<^n = (y^n, y^(n-1), ..., y^1)
|
||||
// y>^n = (y^1, y^2, ..., y^n)
|
||||
|
||||
// from Zarcanum page 24, Fig D.1:
|
||||
// Verifier outputs Accept IFF the following holds:
|
||||
// P^e^2 * A^e * B == g ^ (r' e) * h ^ (s' e) * G ^ (r' y s') * H ^ delta'_1 * H2 ^ delta'_2
|
||||
// (where g and h are calculated in each round)
|
||||
// The same equation in additive notation:
|
||||
// e^2 * P + e * A + B == (r' * e) * g + (s' * e) * h + (r' y s') * G + delta'_1 * H + delta'_2 * H2
|
||||
// <=>
|
||||
// (r' * e) * g + (s' * e) * h + (r' y s') * G + delta'_1 * H + delta'_2 * H2 - e^2 * P - e * A - B == 0 (*)
|
||||
// where A, B, r', s', delta'_1, delta'_2 is taken from the signature
|
||||
// and P_{k+1} = e^2 * L_k + P_k + e^-2 * R_k for all rounds
|
||||
//
|
||||
// from Zarcanum preprint page 33, Fig D.3:
|
||||
// P and V computes:
|
||||
// A_hat = A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h +
|
||||
// + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) +
|
||||
// + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G
|
||||
// (calculated once)
|
||||
//
|
||||
// As suggested in BPP preprint Section 6.1 "Practical Optimizations":
|
||||
// 1) g and h exponentianions can be optimized in order not to be calculated at each round
|
||||
// as the following (page 20, with delta'_2 and H2 added):
|
||||
//
|
||||
// (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta'_1 * H + delta'_2 * H2 -
|
||||
// - e^2 * A_hat
|
||||
// - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j)
|
||||
// - e * A - B = 0 (**)
|
||||
//
|
||||
// where:
|
||||
// g, h - vector of fixed generators
|
||||
// s_vec_i = y^(1-i) * PROD{j=1..log(n)}(e_j ^ b(i,j))
|
||||
// s'_vec_i = PROD{j=1..log(n)}(e_j ^ -b(i,j))
|
||||
// b(i, j) = { 2 * ((1<<(j-1)) & (i-1)) - 1) (counting both from 1) (page 20)
|
||||
// b(i, j) = { 2 * ((1<<j) & i) - 1) (counting both from 0)
|
||||
//
|
||||
// 2) we gonna aggregate all (**) for each round by multiplying them to a random weights and then sum up
|
||||
// insert A_hat into (**) =>
|
||||
|
||||
// (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta'_1 * H + delta'_2 * H2 -
|
||||
// - e^2 * (A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h +
|
||||
// + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) +
|
||||
// + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G
|
||||
// )
|
||||
// - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j)
|
||||
// - e * A - B = 0
|
||||
|
||||
// =>
|
||||
|
||||
// (for single signature)
|
||||
//
|
||||
// (r' * e * s_vec - e^2 * (- 1_vec^(mn) * z)) * g | these are
|
||||
// + (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z)) * h | fixed generators
|
||||
// + (r' y s' - e^2 * ((z - z^2)*SUM(y^>mn) - z*y^(mn+1)*SUM(d)) * G | across all
|
||||
// + delta'_1 * H | the signatures
|
||||
// + delta'_2 * H2 | the signatures
|
||||
//
|
||||
// - e^2 * A0
|
||||
// - e^2 * y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j))
|
||||
// - e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j)
|
||||
// - e * A - B = 0 (***)
|
||||
//
|
||||
// All (***) will be muptiplied by random weightning factor and then summed up.
|
||||
|
||||
// Calculate cummulative sclalar multiplicand for fixed generators across all the sigs.
|
||||
scalar_vec_t g_scalars;
|
||||
g_scalars.resize(c_bpp_mn_max, 0);
|
||||
scalar_vec_t h_scalars;
|
||||
h_scalars.resize(c_bpp_mn_max, 0);
|
||||
scalar_t G_scalar = 0;
|
||||
scalar_t H_scalar = 0;
|
||||
scalar_t H2_scalar = 0;
|
||||
point_t summand = c_point_0;
|
||||
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
DBG_PRINT(ENDL << "SIG #" << k);
|
||||
const bppe_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bppe_signature& sig = bsc.sig;
|
||||
intermediate_element_t& interm = interms[k];
|
||||
|
||||
// random weightning factor for speed-optimized batch verification (preprint page 20)
|
||||
const scalar_t rwf = scalar_t::random();
|
||||
DBG_PRINT("rwf: " << rwf);
|
||||
|
||||
// prepare d vector (see also d structure description in proof function)
|
||||
scalar_mat_t<CT::c_bpp_n> d(interm.c_bpp_mn);
|
||||
d(0, 0) = interm.z_sq;
|
||||
// first row
|
||||
for (size_t i = 1; i < interm.c_bpp_m; ++i)
|
||||
d(i, 0) = d(i - 1, 0) * interm.z_sq;
|
||||
// all rows
|
||||
for (size_t j = 1; j < CT::c_bpp_n; ++j)
|
||||
for (size_t i = 0; i < interm.c_bpp_m; ++i)
|
||||
d(i, j) = d(i, j - 1) + d(i, j - 1);
|
||||
// sum(d) (see also note in proof function for this)
|
||||
const scalar_t sum_d = CT::get_2_to_the_power_of_N_minus_1() * sum_of_powers(interm.z_sq, interm.c_bpp_log2_m);
|
||||
|
||||
DBG_PRINT("Hs(d): " << d.calc_hs());
|
||||
DBG_PRINT("sum(d): " << sum_d);
|
||||
|
||||
const scalar_t& y_inv = batch_for_inverse[interm.inv_y_offset];
|
||||
auto get_e_inv = [&](size_t i) { return batch_for_inverse[interm.inv_e_offset + i]; }; // i belongs to [0; L.size()-1]
|
||||
|
||||
// prepare s_vec (unlike the paper here we moved y-component out of s_vec for convenience, so s_vec'[x] = s_vec[~x & (MN-1)])
|
||||
// complexity (sc_mul's): MN+2*log2(MN)-2
|
||||
// the idea is the following:
|
||||
// s_vec[00000b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^-1 * (e_1)^-1 * (e_0)^-1
|
||||
// s_vec[00101b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^+1 * (e_1)^-1 * (e_0)^+1
|
||||
const size_t log2_mn = sig.L.size(); // at the beginning we made sure that sig.L.size() == c_bpp_log2_m + c_bpp_log2_n
|
||||
scalar_vec_t s_vec(interm.c_bpp_mn);
|
||||
s_vec[0] = get_e_inv(0);
|
||||
for (size_t i = 1; i < log2_mn; ++i)
|
||||
s_vec[0] *= get_e_inv(i); // s_vec[0] = (e_0)^-1 * (e_1)^-1 * .. (e_{log2_mn-1})^-1
|
||||
DBG_PRINT("[0] " << s_vec[0]);
|
||||
for (size_t i = 1; i < interm.c_bpp_mn; ++i)
|
||||
{
|
||||
size_t base_el_index = i & (i - 1); // base element index: 0, 0, 2, 0, 4, 4, 6, 0, 8, 8, 10... base element differs in one bit (0) from the current one (1)
|
||||
size_t bit_index = log2_mn - calc_lsb_32((uint32_t)i) - 1; // the bit index where current element has the difference with the base
|
||||
s_vec[i] = s_vec[base_el_index] * interm.e_sq[bit_index]; // (e_j)^-1 * (e_j)^2 = (e_j)^+1
|
||||
DBG_PRINT("[" << i << "] " << " " << base_el_index << ", " << bit_index << " : " << s_vec[i]);
|
||||
}
|
||||
|
||||
// prepare y_inv vector
|
||||
scalar_vec_t y_inverse_powers(interm.c_bpp_mn);
|
||||
y_inverse_powers[0] = 1;
|
||||
for (size_t i = 1; i < interm.c_bpp_mn; ++i)
|
||||
y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inv;
|
||||
|
||||
// y^(mn+1)
|
||||
scalar_t y_power_mnp1 = interm.y;
|
||||
for (size_t i = 0; i < log2_mn; ++i)
|
||||
y_power_mnp1 *= y_power_mnp1;
|
||||
y_power_mnp1 *= interm.y;
|
||||
DBG_VAL_PRINT(y_power_mnp1);
|
||||
|
||||
// now calculate all multiplicands for common generators
|
||||
|
||||
// g vector multiplicands:
|
||||
// rwf * (r' * e * (1, y^-1, y^-2, ...) o s_vec + e^2 * z) =
|
||||
// rwf * r' * e * ((1, y^-1, ...) o s_vec) + rwf * e^2 * z * (1, 1, ...)
|
||||
scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z;
|
||||
scalar_t rwf_r_e = rwf * interm.e_final * sig.r;
|
||||
for (size_t i = 0; i < interm.c_bpp_mn; ++i)
|
||||
g_scalars[i] += rwf_r_e * y_inverse_powers[i] * s_vec[i] + rwf_e_sq_z;
|
||||
|
||||
DBG_PRINT("Hs(g_scalars): " << g_scalars.calc_hs());
|
||||
|
||||
// h vector multiplicands:
|
||||
// rwf * (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z))
|
||||
// rwf * s' * e * s'_vec - rwf * e^2 * z * (1, 1...) - rwf * e^2 * (d o y<^(mn))
|
||||
//scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z;
|
||||
scalar_t rwf_s_e = rwf * sig.s * interm.e_final;
|
||||
scalar_t rwf_e_sq_y = rwf * interm.e_final_sq * interm.y;
|
||||
for (size_t i = interm.c_bpp_mn - 1; i != SIZE_MAX; --i)
|
||||
{
|
||||
h_scalars[i] += rwf_s_e * s_vec[interm.c_bpp_mn - 1 - i] - rwf_e_sq_z - rwf_e_sq_y * d[i];
|
||||
rwf_e_sq_y *= interm.y;
|
||||
}
|
||||
|
||||
DBG_PRINT("Hs(h_scalars): " << h_scalars.calc_hs());
|
||||
|
||||
// G point multiplicands:
|
||||
// rwf * (r' y s' - e ^ 2 * ((z - z ^ 2)*SUM(y^>mn) - z * y^(mn+1) * SUM(d)) =
|
||||
// = rwf * r' y s' - rwf * e^2 * (z - z ^ 2)*SUM(y^>mn) + rwf * e^2 * z * y^(mn+1) * SUM(d)
|
||||
G_scalar += rwf * sig.r * interm.y * sig.s + rwf_e_sq_y * sum_d * interm.z;
|
||||
G_scalar -= rwf * interm.e_final_sq * (interm.z - interm.z_sq) * sum_of_powers(interm.y, log2_mn);
|
||||
DBG_PRINT("sum_y: " << sum_of_powers(interm.y, log2_mn));
|
||||
DBG_PRINT("G_scalar: " << G_scalar);
|
||||
|
||||
// H point multiplicands:
|
||||
// rwf * delta_1
|
||||
H_scalar += rwf * sig.delta_1;
|
||||
DBG_PRINT("H_scalar: " << H_scalar);
|
||||
|
||||
// H2 point multiplicands:
|
||||
// rwf * delta_2
|
||||
H2_scalar += rwf * sig.delta_2;
|
||||
DBG_PRINT("H2_scalar: " << H2_scalar);
|
||||
|
||||
// uncommon generators' multiplicands
|
||||
point_t summand_8 = c_point_0; // this summand to be multiplied by 8 before adding to the main summand
|
||||
// - rwf * e^2 * A0
|
||||
summand_8 -= rwf * interm.e_final_sq * interm.A0;
|
||||
DBG_PRINT("A0_scalar: " << c_scalar_Lm1 * interm.e_final_sq * rwf);
|
||||
|
||||
// - rwf * e^2 * y^(mn+1) * (SUM{j=1..m} (z^2)^j * V_j))
|
||||
scalar_t e_sq_y_mn1_z_sq_power = rwf * interm.e_final_sq * y_power_mnp1;
|
||||
for (size_t j = 0; j < bsc.commitments.size(); ++j)
|
||||
{
|
||||
e_sq_y_mn1_z_sq_power *= interm.z_sq;
|
||||
summand_8 -= e_sq_y_mn1_z_sq_power * bsc.commitments[j];
|
||||
DBG_PRINT("V_scalar[" << j << "]: " << c_scalar_Lm1 * e_sq_y_mn1_z_sq_power);
|
||||
}
|
||||
|
||||
// - rwf * e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j)
|
||||
scalar_t rwf_e_sq = rwf * interm.e_final_sq;
|
||||
for (size_t j = 0; j < log2_mn; ++j)
|
||||
{
|
||||
summand_8 -= rwf_e_sq * (interm.e_sq[j] * interm.L[j] + get_e_inv(j) * get_e_inv(j) * interm.R[j]);
|
||||
DBG_PRINT("L_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * interm.e_sq[j]);
|
||||
DBG_PRINT("R_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * get_e_inv(j) * get_e_inv(j));
|
||||
}
|
||||
|
||||
// - rwf * e * A - rwf * B = 0
|
||||
summand_8 -= rwf * interm.e_final * interm.A + rwf * interm.B;
|
||||
DBG_PRINT("A_scalar: " << c_scalar_Lm1 * rwf * interm.e_final);
|
||||
DBG_PRINT("B_scalar: " << c_scalar_Lm1 * rwf);
|
||||
|
||||
summand_8.modify_mul8();
|
||||
summand += summand_8;
|
||||
}
|
||||
|
||||
point_t GH_exponents = c_point_0;
|
||||
CT::calc_pedersen_commitment_2(G_scalar, H_scalar, H2_scalar, GH_exponents);
|
||||
bool result = multiexp_and_check_being_zero<CT>(g_scalars, h_scalars, summand + GH_exponents);
|
||||
if (result)
|
||||
DBG_PRINT(ENDL << " . . . . bppe_verify() -- SUCCEEDED!!!" << ENDL);
|
||||
return result;
|
||||
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
|
||||
}
|
||||
|
||||
} // namespace crypto
|
||||
|
|
@ -6,7 +6,4 @@
|
|||
|
||||
namespace crypto
|
||||
{
|
||||
const point_t& bpp_crypto_trait_zano::bpp_H = c_point_H;
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,9 @@
|
|||
// Copyright (c) 2021 Zano Project (https://zano.org/)
|
||||
// Copyright (c) 2021 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Copyright (c) 2021-2022 Zano Project (https://zano.org/)
|
||||
// Copyright (c) 2021-2022 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#pragma once
|
||||
|
||||
//
|
||||
// This file contains the implementation of range proof protocol.
|
||||
// Namely, Bulletproofs+ https://eprint.iacr.org/2020/735.pdf
|
||||
//
|
||||
|
||||
#include "epee/include/misc_log_ex.h"
|
||||
#include "crypto-sugar.h"
|
||||
|
||||
|
|
@ -28,27 +23,23 @@ namespace crypto
|
|||
return result;
|
||||
}
|
||||
|
||||
constexpr size_t c_bpp_log2_n = 6;
|
||||
constexpr size_t c_bpp_n = 64; // 2^64 is the upper bound for the witness's range
|
||||
constexpr size_t c_bpp_values_max = 16; // maximum number of elements in BP+ proof, i.e. max allowed BP+ outputs
|
||||
constexpr size_t c_bpp_mn_max = c_bpp_n * c_bpp_values_max;
|
||||
|
||||
// returns greatest k, s.t. 2**k <= v
|
||||
// tests in crypto_tests_range_proofs.h
|
||||
constexpr size_t constexpr_floor_log2(size_t v)
|
||||
{
|
||||
return v <= 1 ? 0 : constexpr_floor_log2(v >> 1) + 1;
|
||||
}
|
||||
|
||||
// returns smallest k, s.t. v <= 2**k
|
||||
inline size_t calc_exp_power_of_2_upper_bound(size_t v)
|
||||
// tests in crypto_tests_range_proofs.h
|
||||
constexpr size_t constexpr_ceil_log2(size_t v)
|
||||
{
|
||||
constexpr size_t max_v = (SIZE_MAX >> 1) + 1;
|
||||
//if (v > max_v)
|
||||
// return 0;
|
||||
|
||||
size_t pow = 1, result = 0;
|
||||
while (v > pow)
|
||||
{
|
||||
pow <<= 1;
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
return v <= 1 ? 0 : constexpr_floor_log2(v - 1) + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// returns least significant bit uing de Bruijn sequence
|
||||
// http://graphics.stanford.edu/~seander/bithacks.html
|
||||
inline uint8_t calc_lsb_32(uint32_t v)
|
||||
|
|
@ -61,17 +52,28 @@ namespace crypto
|
|||
return multiply_de_bruijn_bit_position[((uint32_t)((v & -(int32_t)v) * 0x077CB531U)) >> 27];
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
// crypto trait for Zano
|
||||
////////////////////////////////////////
|
||||
template<size_t N = 64, size_t values_max = 16>
|
||||
struct bpp_crypto_trait_zano
|
||||
{
|
||||
static constexpr size_t c_bpp_n = N; // the upper bound for the witness's range
|
||||
static constexpr size_t c_bpp_values_max = values_max; // maximum number of elements in BP+ proof, i.e. max allowed BP+ outputs
|
||||
static constexpr size_t c_bpp_log2_n = constexpr_ceil_log2(c_bpp_n);
|
||||
static constexpr size_t c_bpp_mn_max = c_bpp_n * c_bpp_values_max;
|
||||
|
||||
static void calc_pedersen_commitment(const scalar_t& value, const scalar_t& mask, point_t& commitment)
|
||||
{
|
||||
commitment = value * c_point_G + mask * c_point_H;
|
||||
}
|
||||
|
||||
static void calc_pedersen_commitment_2(const scalar_t& value, const scalar_t& mask1, const scalar_t& mask2, point_t& commitment)
|
||||
{
|
||||
commitment = value * c_point_G + mask1 * c_point_H + mask2 * c_point_H2;
|
||||
}
|
||||
|
||||
static const scalar_t& get_initial_transcript()
|
||||
{
|
||||
static scalar_t value = hash_helper_t::hs("Zano BP+ initial transcript");
|
||||
|
|
@ -86,6 +88,7 @@ namespace crypto
|
|||
e = hsc.calc_hash();
|
||||
}
|
||||
|
||||
// TODO: refactor with proper OOB handling
|
||||
static const point_t& get_generator(bool select_H, size_t index)
|
||||
{
|
||||
if (index >= c_bpp_mn_max)
|
||||
|
|
@ -107,333 +110,29 @@ namespace crypto
|
|||
return generators[2 * index + (select_H ? 1 : 0)];
|
||||
}
|
||||
|
||||
static const scalar_t& get_2_to_the_power_of_N_minus_1()
|
||||
{
|
||||
static scalar_t result = scalar_t::power_of_2(c_bpp_n) - 1;
|
||||
return result;
|
||||
}
|
||||
|
||||
static const point_t& bpp_H;
|
||||
};
|
||||
static const point_t& bpp_H2;
|
||||
}; // struct bpp_crypto_trait_zano
|
||||
|
||||
template<size_t N, size_t values_max>
|
||||
const point_t& bpp_crypto_trait_zano<N, values_max>::bpp_H = c_point_H;
|
||||
|
||||
template<size_t N, size_t values_max>
|
||||
const point_t& bpp_crypto_trait_zano<N, values_max>::bpp_H2 = c_point_H2;
|
||||
|
||||
|
||||
struct bpp_signature
|
||||
{
|
||||
std::vector<public_key> L; // size = log_2(m * n)
|
||||
std::vector<public_key> R;
|
||||
public_key A0;
|
||||
public_key A;
|
||||
public_key B;
|
||||
scalar_t r;
|
||||
scalar_t s;
|
||||
scalar_t delta;
|
||||
};
|
||||
|
||||
#define DBG_VAL_PRINT(x) std::cout << #x ": " << x << ENDL
|
||||
#define DBG_PRINT(x) std::cout << x << ENDL
|
||||
|
||||
template<typename CT>
|
||||
bool bpp_gen(const std::vector<uint64_t>& values, const scalar_vec_t& masks, bpp_signature& sig, std::vector<point_t>& commitments, uint8_t* p_err = nullptr)
|
||||
{
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("bpp_gen: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(values.size() > 0 && values.size() <= c_bpp_values_max && values.size() == masks.size(), 1);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(masks.is_reduced(), 3);
|
||||
|
||||
const size_t c_bpp_log2_m = calc_exp_power_of_2_upper_bound(values.size());
|
||||
const size_t c_bpp_m = 1ull << c_bpp_log2_m;
|
||||
const size_t c_bpp_mn = c_bpp_m * c_bpp_n;
|
||||
const size_t c_bpp_log2_mn = c_bpp_log2_m + c_bpp_log2_n;
|
||||
|
||||
// pre-multiply all output points by c_scalar_1div8
|
||||
// in order to enforce these points to be in the prime-order subgroup (after mul by 8 in bpp_verify())
|
||||
|
||||
// calc commitments vector as commitments[i] = 1/8 * values[i] * G + 1/8 * masks[i] * H
|
||||
commitments.resize(values.size());
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
CT::calc_pedersen_commitment(scalar_t(values[i]) * c_scalar_1div8, masks[i] * c_scalar_1div8, commitments[i]);
|
||||
|
||||
|
||||
// s.a. BP+ paper, page 15, eq. 11
|
||||
// decompose v into aL and aR:
|
||||
// v = aL o (1, 2, 2^2, ..., 2^n-1), o - component-wise product aka Hadamard product
|
||||
// aR = aL - (1, 1, ... 1)
|
||||
// aR o aL = 0
|
||||
|
||||
// aLs = (aL_0, aL_1, ..., aL_m-1) -- `bit` matrix of c_bpp_m x c_bpp_n, each element is a scalar
|
||||
|
||||
scalar_mat_t<c_bpp_n> aLs(c_bpp_mn), aRs(c_bpp_mn);
|
||||
aLs.zero();
|
||||
aRs.zero();
|
||||
// m >= values.size, first set up [0..values.size-1], then -- [values.size..m-1] (padding area)
|
||||
for (size_t i = 0; i < values.size(); ++i)
|
||||
{
|
||||
uint64_t v = values[i];
|
||||
for (size_t j = 0; j < c_bpp_n; ++j)
|
||||
{
|
||||
if (v & 1)
|
||||
aLs(i, j) = c_scalar_1; // aL = 1, aR = 0
|
||||
else
|
||||
aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1
|
||||
v >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = values.size(); i < c_bpp_m; ++i)
|
||||
for (size_t j = 0; j < c_bpp_n; ++j)
|
||||
aRs(i, j) = c_scalar_Lm1; // aL = 0, aR = -1
|
||||
|
||||
|
||||
// using e as Fiat-Shamir transcript
|
||||
scalar_t e = CT::get_initial_transcript();
|
||||
DBG_PRINT("initial transcript: " << e);
|
||||
|
||||
hash_helper_t::hs_t hsc;
|
||||
CT::update_transcript(hsc, e, commitments);
|
||||
|
||||
// BP+ paper, page 15: The prover begins with sending A = g^aL h^aR h^alpha (group element)
|
||||
// so we calculate A0 = alpha * H + SUM(aL_i * G_i) + SUM(aR_i * H_i)
|
||||
|
||||
scalar_t alpha = scalar_t::random();
|
||||
point_t A0 = alpha * CT::bpp_H;
|
||||
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
A0 += aLs[i] * CT::get_generator(false, i) + aRs[i] * CT::get_generator(true, i);
|
||||
|
||||
// part of 1/8 defense scheme
|
||||
A0 *= c_scalar_1div8;
|
||||
A0.to_public_key(sig.A0);
|
||||
|
||||
DBG_VAL_PRINT(alpha);
|
||||
DBG_VAL_PRINT(A0);
|
||||
|
||||
// calculate scalar challenges y and z
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A0);
|
||||
scalar_t y = hsc.calc_hash();
|
||||
scalar_t z = hash_helper_t::hs(y);
|
||||
e = z; // transcript for further steps
|
||||
DBG_VAL_PRINT(y);
|
||||
DBG_VAL_PRINT(z);
|
||||
|
||||
// Computing vector d for aggregated version of the protocol (BP+ paper, page 17)
|
||||
// (note: elements is stored column-by-column in memory)
|
||||
// d = | 1 * z^(2*1), 1 * z^(2*2), 1 * z^(2*3), ..., 1 * z^(2*m) |
|
||||
// | 2 * z^(2*1), 2 * z^(2*2), 2 * z^(2*3), ..., 2 * z^(2*m) |
|
||||
// | 4 * z^(2*1), 4 * z^(2*2), 4 * z^(2*3), ..., 4 * z^(2*m) |
|
||||
// | ....................................................................................... |
|
||||
// | 2^(n-1) * z^(2*1), 2^(n-1) * z^(2*2), 2^(n-1) * z^(2*3), ..., 2^(n-1) * z^(2*m)) |
|
||||
// Note: sum(d_i) = (2^n - 1) * ((z^2)^1 + (z^2)^2 + ... (z^2)^m)) = (2^n-1) * sum_of_powers(x^2, log(m))
|
||||
|
||||
scalar_t z_sq = z * z;
|
||||
scalar_mat_t<c_bpp_n> d(c_bpp_mn);
|
||||
d(0, 0) = z_sq;
|
||||
// first row
|
||||
for (size_t i = 1; i < c_bpp_m; ++i)
|
||||
d(i, 0) = d(i - 1, 0) * z_sq;
|
||||
// all rows
|
||||
for (size_t j = 1; j < c_bpp_n; ++j)
|
||||
for (size_t i = 0; i < c_bpp_m; ++i)
|
||||
d(i, j) = d(i, j - 1) + d(i, j - 1);
|
||||
|
||||
DBG_PRINT("Hs(d): " << d.calc_hs());
|
||||
|
||||
// calculate extended Vandermonde vector y = (1, y, y^2, ..., y^(mn+1)) (BP+ paper, page 18, Fig. 3)
|
||||
// (calculate two more elements (1 and y^(mn+1)) for convenience)
|
||||
scalar_vec_t y_powers(c_bpp_mn + 2);
|
||||
y_powers[0] = 1;
|
||||
for (size_t i = 1; i <= c_bpp_mn + 1; ++i)
|
||||
y_powers[i] = y_powers[i - 1] * y;
|
||||
|
||||
const scalar_t& y_mn_p1 = y_powers[c_bpp_mn + 1];
|
||||
|
||||
DBG_PRINT("Hs(y_powers): " << y_powers.calc_hs());
|
||||
|
||||
// aL_hat = aL - 1*z
|
||||
scalar_vec_t aLs_hat = aLs - z;
|
||||
// aL_hat = aR + d o y^leftarr + 1*z where y^leftarr = (y^n, y^(n-1), ..., y) (BP+ paper, page 18, Fig. 3)
|
||||
scalar_vec_t aRs_hat = aRs + z;
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
aRs_hat[i] += d[i] * y_powers[c_bpp_mn - i];
|
||||
|
||||
DBG_PRINT("Hs(aLs_hat): " << aLs_hat.calc_hs());
|
||||
DBG_PRINT("Hs(aRs_hat): " << aRs_hat.calc_hs());
|
||||
|
||||
// calculate alpha_hat
|
||||
// alpha_hat = alpha + SUM(z^(2j) * gamma_j * y^(mn+1)) for j = 1..m
|
||||
// i.e. \hat{\alpha} = \alpha + y^{m n+1} \sum_{j = 1}^{m} z^{2j} \gamma_j
|
||||
scalar_t alpha_hat = 0;
|
||||
for (size_t i = 0; i < masks.size(); ++i)
|
||||
alpha_hat += d(i, 0) * masks[i];
|
||||
alpha_hat = alpha + y_mn_p1 * alpha_hat;
|
||||
|
||||
DBG_VAL_PRINT(alpha_hat);
|
||||
|
||||
// calculate y^-1, y^-2, ...
|
||||
const scalar_t y_inverse = y.reciprocal();
|
||||
scalar_vec_t y_inverse_powers(c_bpp_mn / 2 + 1); // the greatest power we need is c_bpp_mn/2 (at the first reduction round)
|
||||
y_inverse_powers[0] = 1;
|
||||
for (size_t i = 1, size = y_inverse_powers.size(); i < size; ++i)
|
||||
y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inverse;
|
||||
|
||||
// prepare generator's vector
|
||||
std::vector<point_t> g(c_bpp_mn), h(c_bpp_mn);
|
||||
for (size_t i = 0; i < c_bpp_mn; ++i)
|
||||
{
|
||||
g[i] = CT::get_generator(false, i);
|
||||
h[i] = CT::get_generator(true, i);
|
||||
}
|
||||
|
||||
// WIP zk-argument called with zk-WIP(g, h, G, H, A_hat, aL_hat, aR_hat, alpha_hat)
|
||||
|
||||
scalar_vec_t& a = aLs_hat;
|
||||
scalar_vec_t& b = aRs_hat;
|
||||
|
||||
sig.L.resize(c_bpp_log2_mn);
|
||||
sig.R.resize(c_bpp_log2_mn);
|
||||
|
||||
// zk-WIP reduction rounds (s.a. the preprint page 13 Fig. 1)
|
||||
for (size_t n = c_bpp_mn / 2, ni = 0; n >= 1; n /= 2, ++ni)
|
||||
{
|
||||
DBG_PRINT(ENDL << "#" << ni);
|
||||
|
||||
// zk-WIP(g, h, G, H, P, a, b, alpha)
|
||||
|
||||
scalar_t dL = scalar_t::random();
|
||||
DBG_VAL_PRINT(dL);
|
||||
scalar_t dR = scalar_t::random();
|
||||
DBG_VAL_PRINT(dR);
|
||||
|
||||
// a = (a1, a2), b = (b1, b2) -- vectors of scalars
|
||||
// cL = <a1, ((y, y^2, ...) o b2)> -- scalar
|
||||
scalar_t cL = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
cL += a[i] * y_powers[i + 1] * b[n + i];
|
||||
|
||||
DBG_VAL_PRINT(cL);
|
||||
|
||||
// cR = <a2, ((y, y^2, ...) o b1)> * y^n -- scalar
|
||||
scalar_t cR = 0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
cR += a[n + i] * y_powers[i + 1] * b[i];
|
||||
cR *= y_powers[n];
|
||||
|
||||
DBG_VAL_PRINT(cR);
|
||||
|
||||
// L = y^-n * a1 * g2 + b2 * h1 + cL * G + dL * H -- point
|
||||
point_t sum = c_point_0;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
sum += a[i] * g[n + i];
|
||||
point_t L;
|
||||
CT::calc_pedersen_commitment(cL, dL, L);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
L += b[n + i] * h[i];
|
||||
L += y_inverse_powers[n] * sum;
|
||||
L *= c_scalar_1div8;
|
||||
DBG_VAL_PRINT(L);
|
||||
|
||||
// R = y^n * a2 * g1 + b1 * h2 + cR * G + dR * H -- point
|
||||
sum.zero();
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
sum += a[n + i] * g[i];
|
||||
point_t R;
|
||||
CT::calc_pedersen_commitment(cR, dR, R);
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
R += b[i] * h[n + i];
|
||||
R += y_powers[n] * sum;
|
||||
R *= c_scalar_1div8;
|
||||
DBG_VAL_PRINT(R);
|
||||
|
||||
// put L, R to the sig
|
||||
L.to_public_key(sig.L[ni]);
|
||||
R.to_public_key(sig.R[ni]);
|
||||
|
||||
// update the transcript
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.L[ni]);
|
||||
hsc.add_pub_key(sig.R[ni]);
|
||||
e = hsc.calc_hash();
|
||||
DBG_VAL_PRINT(e);
|
||||
|
||||
// recalculate arguments for the next round
|
||||
scalar_t e_squared = e * e;
|
||||
scalar_t e_inverse = e.reciprocal();
|
||||
scalar_t e_inverse_squared = e_inverse * e_inverse;
|
||||
scalar_t e_y_inv_n = e * y_inverse_powers[n];
|
||||
scalar_t e_inv_y_n = e_inverse * y_powers[n];
|
||||
|
||||
// g_hat = e^-1 * g1 + (e * y^-n) * g2 -- vector of points
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
g[i] = e_inverse * g[i] + e_y_inv_n * g[n + i];
|
||||
|
||||
// h_hat = e * h1 + e^-1 * h2 -- vector of points
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
h[i] = e * h[i] + e_inverse * h[n + i];
|
||||
|
||||
// P_hat = e^2 * L + P + e^-2 * R -- point
|
||||
|
||||
// a_hat = e * a1 + e^-1 * y^n * a2 -- vector of scalars
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
a[i] = e * a[i] + e_inv_y_n * a[n + i];
|
||||
|
||||
// b_hat = e^-1 * b1 + e * b2 -- vector of scalars
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
b[i] = e_inverse * b[i] + e * b[n + i];
|
||||
|
||||
// alpha_hat = e^2 * dL + alpha + e^-2 * dR -- scalar
|
||||
alpha_hat += e_squared * dL + e_inverse_squared * dR;
|
||||
|
||||
// run next iteraton zk-WIP(g_hat, h_hat, G, H, P_hat, a_hat, b_hat, alpha_hat)
|
||||
}
|
||||
DBG_PRINT("");
|
||||
|
||||
// zk-WIP last round
|
||||
scalar_t r = scalar_t::random();
|
||||
scalar_t s = scalar_t::random();
|
||||
scalar_t delta = scalar_t::random();
|
||||
scalar_t eta = scalar_t::random();
|
||||
DBG_VAL_PRINT(r);
|
||||
DBG_VAL_PRINT(s);
|
||||
DBG_VAL_PRINT(delta);
|
||||
DBG_VAL_PRINT(eta);
|
||||
|
||||
// A = r * g + s * h + (r y b + s y a) * G + delta * H -- point
|
||||
point_t A = c_point_0;
|
||||
CT::calc_pedersen_commitment(y * (r * b[0] + s * a[0]), delta, A);
|
||||
A += r * g[0] + s * h[0];
|
||||
A *= c_scalar_1div8;
|
||||
A.to_public_key(sig.A);
|
||||
DBG_VAL_PRINT(A);
|
||||
|
||||
// B = (r * y * s) * G + eta * H
|
||||
point_t B = c_point_0;
|
||||
CT::calc_pedersen_commitment(r * y * s, eta, B);
|
||||
B *= c_scalar_1div8;
|
||||
B.to_public_key(sig.B);
|
||||
DBG_VAL_PRINT(B);
|
||||
|
||||
// update the transcript
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A);
|
||||
hsc.add_pub_key(sig.B);
|
||||
e = hsc.calc_hash();
|
||||
DBG_VAL_PRINT(e);
|
||||
|
||||
// finalize the signature
|
||||
sig.r = r + e * a[0];
|
||||
sig.s = s + e * b[0];
|
||||
sig.delta = eta + e * delta + e * e * alpha_hat;
|
||||
DBG_VAL_PRINT(sig.r);
|
||||
DBG_VAL_PRINT(sig.s);
|
||||
DBG_VAL_PRINT(sig.delta);
|
||||
|
||||
return true;
|
||||
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
|
||||
} // bpp_gen()
|
||||
|
||||
|
||||
// efficient multiexponentiation (naive stub implementation atm, TODO)
|
||||
template<typename CT>
|
||||
bool multiexp_and_check_being_zero(const scalar_vec_t& g_scalars, const scalar_vec_t& h_scalars, const point_t& summand)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(g_scalars.size() < c_bpp_mn_max, false, "g_scalars oversized");
|
||||
CHECK_AND_ASSERT_MES(h_scalars.size() < c_bpp_mn_max, false, "h_scalars oversized");
|
||||
CHECK_AND_ASSERT_MES(g_scalars.size() < CT::c_bpp_mn_max, false, "g_scalars oversized");
|
||||
CHECK_AND_ASSERT_MES(h_scalars.size() < CT::c_bpp_mn_max, false, "h_scalars oversized");
|
||||
|
||||
point_t result = summand;
|
||||
|
||||
|
|
@ -452,372 +151,7 @@ namespace crypto
|
|||
}
|
||||
|
||||
|
||||
struct bpp_sig_commit_ref_t
|
||||
{
|
||||
bpp_sig_commit_ref_t(const bpp_signature& sig, const std::vector<point_t>& commitments)
|
||||
: sig(sig)
|
||||
, commitments(commitments)
|
||||
{}
|
||||
const bpp_signature& sig;
|
||||
const std::vector<point_t>& commitments;
|
||||
};
|
||||
|
||||
|
||||
template<typename CT>
|
||||
bool bpp_verify(const std::vector<bpp_sig_commit_ref_t>& sigs, uint8_t* p_err = nullptr)
|
||||
{
|
||||
#define CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(cond, err_code) \
|
||||
if (!(cond)) { LOG_PRINT_RED("bpp_verify: \"" << #cond << "\" is false at " << LOCATION_SS << ENDL << "error code = " << err_code, LOG_LEVEL_3); \
|
||||
if (p_err) { *p_err = err_code; } return false; }
|
||||
|
||||
DBG_PRINT(ENDL << " . . . . bpp_verify() . . . . ");
|
||||
|
||||
const size_t kn = sigs.size();
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(kn > 0, 1);
|
||||
|
||||
struct intermediate_element_t
|
||||
{
|
||||
scalar_t y;
|
||||
scalar_t z;
|
||||
scalar_t z_sq;
|
||||
scalar_vec_t e;
|
||||
scalar_vec_t e_sq;
|
||||
scalar_t e_final;
|
||||
scalar_t e_final_sq;
|
||||
size_t inv_e_offset; // offset in batch_for_inverse
|
||||
size_t inv_y_offset; // offset in batch_for_inverse
|
||||
size_t c_bpp_log2_m;
|
||||
size_t c_bpp_m;
|
||||
size_t c_bpp_mn;
|
||||
point_t A;
|
||||
point_t A0;
|
||||
point_t B;
|
||||
std::vector<point_t> L;
|
||||
std::vector<point_t> R;
|
||||
};
|
||||
std::vector<intermediate_element_t> interms(kn);
|
||||
|
||||
size_t c_bpp_log2_m_max = 0;
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
const bpp_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bpp_signature& sig = bsc.sig;
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(bsc.commitments.size() > 0, 2);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() > 0 && sig.L.size() == sig.R.size(), 3);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.r.is_reduced() && sig.s.is_reduced() && sig.delta.is_reduced(), 4);
|
||||
|
||||
intermediate_element_t& interm = interms[k];
|
||||
interm.c_bpp_log2_m = calc_exp_power_of_2_upper_bound(bsc.commitments.size());
|
||||
if (c_bpp_log2_m_max < interm.c_bpp_log2_m)
|
||||
c_bpp_log2_m_max = interm.c_bpp_log2_m;
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(sig.L.size() == interm.c_bpp_log2_m + c_bpp_log2_n, 5);
|
||||
|
||||
interm.c_bpp_m = 1ull << interm.c_bpp_log2_m;
|
||||
interm.c_bpp_mn = interm.c_bpp_m * c_bpp_n;
|
||||
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A0.from_public_key(sig.A0), 6);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.A.from_public_key(sig.A), 7);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.B.from_public_key(sig.B), 8);
|
||||
interm.L.resize(sig.L.size());
|
||||
interm.R.resize(sig.R.size());
|
||||
for (size_t i = 0; i < interm.L.size(); ++i)
|
||||
{
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.L[i].from_public_key(sig.L[i]), 9);
|
||||
CHECK_AND_FAIL_WITH_ERROR_IF_FALSE(interm.R[i].from_public_key(sig.R[i]), 10);
|
||||
}
|
||||
}
|
||||
const size_t c_bpp_m_max = 1ull << c_bpp_log2_m_max;
|
||||
const size_t c_bpp_mn_max = c_bpp_m_max * c_bpp_n;
|
||||
const size_t c_bpp_LR_size_max = c_bpp_log2_m_max + c_bpp_log2_n;
|
||||
|
||||
|
||||
//
|
||||
// prepare stuff
|
||||
//
|
||||
/*
|
||||
std::vector<point_t> g(c_bpp_mn_max), h(c_bpp_mn_max);
|
||||
for (size_t i = 0; i < c_bpp_mn_max; ++i)
|
||||
{
|
||||
g[i] = CT::get_generator(false, i);
|
||||
h[i] = CT::get_generator(true, i);
|
||||
}
|
||||
*/
|
||||
|
||||
scalar_vec_t batch_for_inverse;
|
||||
batch_for_inverse.reserve(kn + kn * c_bpp_LR_size_max);
|
||||
|
||||
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
DBG_PRINT(ENDL << "SIG #" << k);
|
||||
const bpp_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bpp_signature& sig = bsc.sig;
|
||||
intermediate_element_t& interm = interms[k];
|
||||
|
||||
// restore y and z
|
||||
// using e as Fiat-Shamir transcript
|
||||
scalar_t e = CT::get_initial_transcript();
|
||||
DBG_PRINT("initial transcript: " << e);
|
||||
hash_helper_t::hs_t hsc;
|
||||
CT::update_transcript(hsc, e, bsc.commitments);
|
||||
// calculate scalar challenges y and z
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A0);
|
||||
hsc.assign_calc_hash(interm.y);
|
||||
interm.z = hash_helper_t::hs(interm.y);
|
||||
interm.z_sq = interm.z * interm.z;
|
||||
DBG_VAL_PRINT(interm.y);
|
||||
DBG_VAL_PRINT(interm.z);
|
||||
e = interm.z; // transcript for further steps
|
||||
|
||||
interm.inv_y_offset = batch_for_inverse.size();
|
||||
batch_for_inverse.push_back(interm.y);
|
||||
interm.inv_e_offset = batch_for_inverse.size();
|
||||
|
||||
interm.e.resize(sig.L.size());
|
||||
interm.e_sq.resize(sig.L.size());
|
||||
|
||||
for (size_t i = 0; i < sig.L.size(); ++i)
|
||||
{
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.L[i]);
|
||||
hsc.add_pub_key(sig.R[i]);
|
||||
hsc.assign_calc_hash(e);
|
||||
interm.e[i] = e;
|
||||
interm.e_sq[i] = e * e;
|
||||
DBG_PRINT("e[" << i << "]: " << e);
|
||||
batch_for_inverse.push_back(e);
|
||||
}
|
||||
|
||||
hsc.add_scalar(e);
|
||||
hsc.add_pub_key(sig.A);
|
||||
hsc.add_pub_key(sig.B);
|
||||
hsc.assign_calc_hash(interm.e_final);
|
||||
interm.e_final_sq = interm.e_final * interm.e_final;
|
||||
DBG_VAL_PRINT(interm.e_final);
|
||||
}
|
||||
|
||||
batch_for_inverse.invert();
|
||||
|
||||
// Notation:
|
||||
// 1_vec ^ n = (1, 1, 1, ..., 1)
|
||||
// 2_vec ^ n = (2^0, 2^1, 2^2, ..., 2^(n-1))
|
||||
// -1_vec ^ n = ((-1)^0, (-1)^1, (-1)^2, ... (-1)^(n-1)) = (1, -1, 1, -1, ...)
|
||||
// y<^n = (y^n, y^(n-1), ..., y^1)
|
||||
// y>^n = (y^1, y^2, ..., y^n)
|
||||
|
||||
// from page 13, Fig 1:
|
||||
// Verifier outputs Accept IFF the following equality holds (single proof):
|
||||
// P^e^2 * A^e * B == g ^ (r' e) * h ^ (s' e) * G ^ (r' y s') * H ^ delta'
|
||||
// (where g and h are calculated in each round)
|
||||
// The same equation in additive notation:
|
||||
// e^2 * P + e * A + B == (r' * e) * g + (s' * e) * h + (r' y s') * G + delta' * H
|
||||
// <=>
|
||||
// (r' * e) * g + (s' * e) * h + (r' y s') * G + delta' * H - e^2 * P - e * A - B == 0 (*)
|
||||
// where A, B, r', s', delta' is taken from the signature
|
||||
// and P_{k+1} = e^2 * L_k + P_k + e^-2 * R_k for all rounds
|
||||
//
|
||||
// from page 18, Fig 3:
|
||||
// P and V computes:
|
||||
// A_hat = A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h +
|
||||
// + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) +
|
||||
// + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G
|
||||
// (calculated once)
|
||||
//
|
||||
// As suggested in Section 6.1 "Practical Optimizations":
|
||||
// 1) g and h exponentianions can be optimized in order not to be calculated at each round as the following (page 20):
|
||||
//
|
||||
// (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta' * H -
|
||||
// - e^2 * A_hat
|
||||
// - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j)
|
||||
// - e * A - B = 0 (**)
|
||||
//
|
||||
// where:
|
||||
// g, h - vector of fixed generators
|
||||
// s_vec_i = y^(1-i) * PROD{j=1..log(n)}(e_j ^ b(i,j))
|
||||
// s'_vec_i = PROD{j=1..log(n)}(e_j ^ -b(i,j))
|
||||
// b(i, j) = { 2 * ((1<<(j-1)) & (i-1)) - 1) (counting both from 1) (page 20)
|
||||
// b(i, j) = { 2 * ((1<<j) & i) - 1) (counting both from 0)
|
||||
//
|
||||
// 2) we gonna aggregate all (**) for each round by multiplying them to a random weights and then sum up
|
||||
// insert A_hat into (**) =>
|
||||
|
||||
// (r' * e * s_vec) * g + (s' * e * s'_vec) * h + (r' y s') * G + delta' * H -
|
||||
// - e^2 * (A0 + (- 1^(mn) * z) * g + (d o y<^(mn) + 1^(mn) * z) * h +
|
||||
// + y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j) +
|
||||
// + (z*SUM(y^>mn) - z*y^(mn+1)*SUM(d) - z^2 * SUM(y^>mn)) * G
|
||||
// )
|
||||
// - SUM{j=1..log(n)}(e_final^2 * e_j^2 * L_j + e_final^2 * e_j^-2 * R_j)
|
||||
// - e * A - B = 0
|
||||
|
||||
// =>
|
||||
|
||||
// (for single signature)
|
||||
//
|
||||
// (r' * e * s_vec - e^2 * (- 1_vec^(mn) * z)) * g | these are
|
||||
// + (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z)) * h | fixed generators
|
||||
// + (r' y s' - e^2 * ((z - z^2)*SUM(y^>mn) - z*y^(mn+1)*SUM(d)) * G | across all
|
||||
// + delta' * H | the signatures
|
||||
//
|
||||
// - e^2 * A0
|
||||
// - e^2 * y^(mn+1) * (SUM{j=1..m} z^(2j) * V_j))
|
||||
// - e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j)
|
||||
// - e * A - B = 0 (***)
|
||||
//
|
||||
// All (***) will be muptiplied by random weightning factor and then summed up.
|
||||
|
||||
// Calculate cummulative sclalar multiplicand for fixed generators across all the sigs.
|
||||
scalar_vec_t g_scalars;
|
||||
g_scalars.resize(c_bpp_mn_max, 0);
|
||||
scalar_vec_t h_scalars;
|
||||
h_scalars.resize(c_bpp_mn_max, 0);
|
||||
scalar_t G_scalar = 0;
|
||||
scalar_t H_scalar = 0;
|
||||
point_t summand = c_point_0;
|
||||
|
||||
for (size_t k = 0; k < kn; ++k)
|
||||
{
|
||||
DBG_PRINT(ENDL << "SIG #" << k);
|
||||
const bpp_sig_commit_ref_t& bsc = sigs[k];
|
||||
const bpp_signature& sig = bsc.sig;
|
||||
intermediate_element_t& interm = interms[k];
|
||||
|
||||
// random weightning factor for speed-optimized batch verification (preprint page 20)
|
||||
const scalar_t rwf = scalar_t::random();
|
||||
DBG_PRINT("rwf: " << rwf);
|
||||
|
||||
// prepare d vector (see also d structure description in proof function)
|
||||
scalar_mat_t<c_bpp_n> d(interm.c_bpp_mn);
|
||||
d(0, 0) = interm.z_sq;
|
||||
// first row
|
||||
for (size_t i = 1; i < interm.c_bpp_m; ++i)
|
||||
d(i, 0) = d(i - 1, 0) * interm.z_sq;
|
||||
// all rows
|
||||
for (size_t j = 1; j < c_bpp_n; ++j)
|
||||
for (size_t i = 0; i < interm.c_bpp_m; ++i)
|
||||
d(i, j) = d(i, j - 1) + d(i, j - 1);
|
||||
// sum(d) (see also note in proof function for this)
|
||||
static const scalar_t c_scalar_2_power_n_minus_1 = { 0xffffffffffffffff, 0x0000000000000000, 0x0000000000000000, 0x0000000000000000 };
|
||||
const scalar_t sum_d = c_scalar_2_power_n_minus_1 * sum_of_powers(interm.z_sq, interm.c_bpp_log2_m);
|
||||
|
||||
DBG_PRINT("Hs(d): " << d.calc_hs());
|
||||
DBG_PRINT("sum(d): " << sum_d);
|
||||
|
||||
const scalar_t& y_inv = batch_for_inverse[interm.inv_y_offset];
|
||||
auto get_e_inv = [&](size_t i) { return batch_for_inverse[interm.inv_e_offset + i]; }; // i belongs to [0; L.size()-1]
|
||||
|
||||
// prepare s_vec (unlike the paper here we moved y-component out of s_vec for convenience, so s_vec'[x] = s_vec[~x & (MN-1)])
|
||||
// complexity (sc_mul's): MN+2*log2(MN)-2
|
||||
// the idea is the following:
|
||||
// s_vec[00000b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^-1 * (e_1)^-1 * (e_0)^-1
|
||||
// s_vec[00101b] = ... * (e_4)^-1 * (e_3)^-1 * (e_2)^+1 * (e_1)^-1 * (e_0)^+1
|
||||
const size_t log2_mn = sig.L.size(); // at the beginning we made sure that sig.L.size() == c_bpp_log2_m + c_bpp_log2_n
|
||||
scalar_vec_t s_vec(interm.c_bpp_mn);
|
||||
s_vec[0] = get_e_inv(0);
|
||||
for (size_t i = 1; i < log2_mn; ++i)
|
||||
s_vec[0] *= get_e_inv(i); // s_vec[0] = (e_0)^-1 * (e_1)^-1 * .. (e_{log2_mn-1})^-1
|
||||
DBG_PRINT("[0] " << s_vec[0]);
|
||||
for (size_t i = 1; i < interm.c_bpp_mn; ++i)
|
||||
{
|
||||
size_t base_el_index = i & (i - 1); // base element index: 0, 0, 2, 0, 4, 4, 6, 0, 8, 8, 10... base element differs in one bit (0) from the current one (1)
|
||||
size_t bit_index = log2_mn - calc_lsb_32((uint32_t)i) - 1; // the bit index where current element has the difference with the base
|
||||
s_vec[i] = s_vec[base_el_index] * interm.e_sq[bit_index]; // (e_j)^-1 * (e_j)^2 = (e_j)^+1
|
||||
DBG_PRINT("[" << i << "] " << " " << base_el_index << ", " << bit_index << " : " << s_vec[i]);
|
||||
}
|
||||
|
||||
// prepare y_inv vector
|
||||
scalar_vec_t y_inverse_powers(interm.c_bpp_mn);
|
||||
y_inverse_powers[0] = 1;
|
||||
for (size_t i = 1; i < interm.c_bpp_mn; ++i)
|
||||
y_inverse_powers[i] = y_inverse_powers[i - 1] * y_inv;
|
||||
|
||||
// y^(mn+1)
|
||||
scalar_t y_power_mnp1 = interm.y;
|
||||
for (size_t i = 0; i < log2_mn; ++i)
|
||||
y_power_mnp1 *= y_power_mnp1;
|
||||
y_power_mnp1 *= interm.y;
|
||||
DBG_VAL_PRINT(y_power_mnp1);
|
||||
|
||||
// now calculate all multiplicands for common generators
|
||||
|
||||
// g vector multiplicands:
|
||||
// rwf * (r' * e * (1, y^-1, y^-2, ...) o s_vec + e^2 * z) =
|
||||
// rwf * r' * e * ((1, y^-1, ...) o s_vec) + rwf * e^2 * z * (1, 1, ...)
|
||||
scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z;
|
||||
scalar_t rwf_r_e = rwf * interm.e_final * sig.r;
|
||||
for (size_t i = 0; i < interm.c_bpp_mn; ++i)
|
||||
g_scalars[i] += rwf_r_e * y_inverse_powers[i] * s_vec[i] + rwf_e_sq_z;
|
||||
|
||||
DBG_PRINT("Hs(g_scalars): " << g_scalars.calc_hs());
|
||||
|
||||
// h vector multiplicands:
|
||||
// rwf * (s' * e * s'_vec - e^2 * (d o y<^(mn) + 1_vec^(mn) * z))
|
||||
// rwf * s' * e * s'_vec - rwf * e^2 * z * (1, 1...) - rwf * e^2 * (d o y<^(mn))
|
||||
//scalar_t rwf_e_sq_z = rwf * interm.e_final_sq * interm.z;
|
||||
scalar_t rwf_s_e = rwf * sig.s * interm.e_final;
|
||||
scalar_t rwf_e_sq_y = rwf * interm.e_final_sq * interm.y;
|
||||
for (size_t i = interm.c_bpp_mn - 1; i != SIZE_MAX; --i)
|
||||
{
|
||||
h_scalars[i] += rwf_s_e * s_vec[interm.c_bpp_mn - 1 - i] - rwf_e_sq_z - rwf_e_sq_y * d[i];
|
||||
rwf_e_sq_y *= interm.y;
|
||||
}
|
||||
|
||||
DBG_PRINT("Hs(h_scalars): " << h_scalars.calc_hs());
|
||||
|
||||
// G point multiplicands:
|
||||
// rwf * (r' y s' - e ^ 2 * ((z - z ^ 2)*SUM(y^>mn) - z * y^(mn+1) * SUM(d)) =
|
||||
// = rwf * r' y s' - rwf * e^2 * (z - z ^ 2)*SUM(y^>mn) + rwf * e^2 * z * y^(mn+1) * SUM(d)
|
||||
G_scalar += rwf * sig.r * interm.y * sig.s + rwf_e_sq_y * sum_d * interm.z;
|
||||
G_scalar -= rwf * interm.e_final_sq * (interm.z - interm.z_sq) * sum_of_powers(interm.y, log2_mn);
|
||||
DBG_PRINT("sum_y: " << sum_of_powers(interm.y, log2_mn));
|
||||
DBG_PRINT("G_scalar: " << G_scalar);
|
||||
|
||||
// H point multiplicands:
|
||||
// rwf * delta
|
||||
H_scalar += rwf * sig.delta;
|
||||
DBG_PRINT("H_scalar: " << H_scalar);
|
||||
|
||||
// uncommon generators' multiplicands
|
||||
point_t summand_8 = c_point_0; // this summand to be multiplied by 8 before adding to the main summand
|
||||
// - rwf * e^2 * A0
|
||||
summand_8 -= rwf * interm.e_final_sq * interm.A0;
|
||||
DBG_PRINT("A0_scalar: " << c_scalar_Lm1 * interm.e_final_sq * rwf);
|
||||
|
||||
// - rwf * e^2 * y^(mn+1) * (SUM{j=1..m} (z^2)^j * V_j))
|
||||
scalar_t e_sq_y_mn1_z_sq_power = rwf * interm.e_final_sq * y_power_mnp1;
|
||||
for (size_t j = 0; j < bsc.commitments.size(); ++j)
|
||||
{
|
||||
e_sq_y_mn1_z_sq_power *= interm.z_sq;
|
||||
summand_8 -= e_sq_y_mn1_z_sq_power * bsc.commitments[j];
|
||||
DBG_PRINT("V_scalar[" << j << "]: " << c_scalar_Lm1 * e_sq_y_mn1_z_sq_power);
|
||||
}
|
||||
|
||||
// - rwf * e^2 * SUM{j=1..log(n)}(e_j^2 * L_j + e_j^-2 * R_j)
|
||||
scalar_t rwf_e_sq = rwf * interm.e_final_sq;
|
||||
for (size_t j = 0; j < log2_mn; ++j)
|
||||
{
|
||||
summand_8 -= rwf_e_sq * (interm.e_sq[j] * interm.L[j] + get_e_inv(j) * get_e_inv(j) * interm.R[j]);
|
||||
DBG_PRINT("L_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * interm.e_sq[j]);
|
||||
DBG_PRINT("R_scalar[" << j << "]: " << c_scalar_Lm1 * rwf_e_sq * get_e_inv(j) * get_e_inv(j));
|
||||
}
|
||||
|
||||
// - rwf * e * A - rwf * B = 0
|
||||
summand_8 -= rwf * interm.e_final * interm.A + rwf * interm.B;
|
||||
DBG_PRINT("A_scalar: " << c_scalar_Lm1 * rwf * interm.e_final);
|
||||
DBG_PRINT("B_scalar: " << c_scalar_Lm1 * rwf);
|
||||
|
||||
summand_8.modify_mul8();
|
||||
summand += summand_8;
|
||||
}
|
||||
|
||||
point_t GH_exponents = c_point_0;
|
||||
CT::calc_pedersen_commitment(G_scalar, H_scalar, GH_exponents);
|
||||
bool result = multiexp_and_check_being_zero<CT>(g_scalars, h_scalars, summand + GH_exponents);
|
||||
if (result)
|
||||
DBG_PRINT(ENDL << " . . . . bpp_verify() -- SUCCEEDED!!!" << ENDL);
|
||||
return result;
|
||||
#undef CHECK_AND_FAIL_WITH_ERROR_IF_FALSE
|
||||
}
|
||||
|
||||
} // namespace crypto
|
||||
|
||||
#include "range_proof_bpp.h"
|
||||
#include "range_proof_bppe.h"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "storages/portable_storage_template_helper.h"
|
||||
|
||||
|
||||
command_line::arg_descriptor<bool> arg_market_disable = { "disable-market", "Start GUI with market service disabled", false, true };
|
||||
command_line::arg_descriptor<bool> arg_market_disable ( "disable-market", "Start GUI with market service disabled");
|
||||
|
||||
|
||||
namespace bc_services
|
||||
|
|
|
|||
|
|
@ -80,8 +80,8 @@ DISABLE_VS_WARNINGS(4267)
|
|||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<uint32_t> arg_db_cache_l1 = { "db-cache-l1", "Specify size of memory mapped db cache file", 0, true };
|
||||
const command_line::arg_descriptor<uint32_t> arg_db_cache_l2 = { "db-cache-l2", "Specify cached elements in db helpers", 0, true };
|
||||
const command_line::arg_descriptor<uint32_t> arg_db_cache_l1 ( "db-cache-l1", "Specify size of memory mapped db cache file");
|
||||
const command_line::arg_descriptor<uint32_t> arg_db_cache_l2 ( "db-cache-l2", "Specify cached elements in db helpers");
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -250,6 +250,8 @@
|
|||
|
||||
|
||||
|
||||
|
||||
static_assert(CURRENCY_MINER_TX_MAX_OUTS <= CURRENCY_TX_MAX_ALLOWED_OUTS, "Miner tx must obey normal tx max outs limit");
|
||||
static_assert(PREMINE_AMOUNT / WALLET_MAX_ALLOWED_OUTPUT_AMOUNT < CURRENCY_MINER_TX_MAX_OUTS, "Premine can't be divided into reasonable number of outs");
|
||||
|
||||
#define CURRENCY_RELAY_TXS_MAX_COUNT 5
|
||||
|
|
@ -33,10 +33,10 @@ namespace currency
|
|||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_extra_messages = {"extra-messages-file", "Specify file for extra messages to include into coinbase transactions", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_start_mining = {"start-mining", "Specify wallet address to mining for", "", true};
|
||||
const command_line::arg_descriptor<uint32_t> arg_mining_threads = {"mining-threads", "Specify mining threads count", 0, true};
|
||||
const command_line::arg_descriptor<std::string> arg_block_template_extra_text = { "miner-text-info", "Set block extra text info", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_extra_messages ("extra-messages-file", "Specify file for extra messages to include into coinbase transactions");
|
||||
const command_line::arg_descriptor<std::string> arg_start_mining ("start-mining", "Specify wallet address to mining for");
|
||||
const command_line::arg_descriptor<uint32_t> arg_mining_threads ("mining-threads", "Specify mining threads count");
|
||||
const command_line::arg_descriptor<std::string> arg_block_template_extra_text ( "miner-text-info", "Set block extra text info");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -666,7 +666,7 @@ namespace currency
|
|||
bool tx_memory_pool::force_relay_pool() const
|
||||
{
|
||||
LOG_PRINT_GREEN("Preparing relay message...", LOG_LEVEL_0);
|
||||
NOTIFY_NEW_TRANSACTIONS::request r = AUTO_VAL_INIT(r);
|
||||
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request r = AUTO_VAL_INIT(r);
|
||||
|
||||
m_db_transactions.enumerate_items([&](uint64_t i, const crypto::hash& k, const tx_details& v)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ namespace currency
|
|||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
struct NOTIFY_NEW_TRANSACTIONS
|
||||
struct NOTIFY_OR_INVOKE_NEW_TRANSACTIONS
|
||||
{
|
||||
const static int ID = BC_COMMANDS_POOL_BASE + 2;
|
||||
|
||||
|
|
@ -83,6 +83,16 @@ namespace currency
|
|||
KV_SERIALIZE(txs)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct response
|
||||
{
|
||||
std::string code;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(code)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
};
|
||||
/************************************************************************/
|
||||
/* */
|
||||
|
|
|
|||
|
|
@ -35,14 +35,15 @@ namespace currency
|
|||
typedef core_stat_info stat_info;
|
||||
typedef t_currency_protocol_handler<t_core> currency_protocol_handler;
|
||||
typedef CORE_SYNC_DATA payload_type;
|
||||
typedef std::pair<NOTIFY_NEW_TRANSACTIONS::request, currency_connection_context> relay_que_entry;
|
||||
typedef std::pair<NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request, currency_connection_context> relay_que_entry;
|
||||
|
||||
t_currency_protocol_handler(t_core& rcore, nodetool::i_p2p_endpoint<connection_context>* p_net_layout);
|
||||
~t_currency_protocol_handler();
|
||||
|
||||
BEGIN_INVOKE_MAP2(currency_protocol_handler)
|
||||
HANDLE_NOTIFY_T2(NOTIFY_NEW_BLOCK, ¤cy_protocol_handler::handle_notify_new_block)
|
||||
HANDLE_NOTIFY_T2(NOTIFY_NEW_TRANSACTIONS, ¤cy_protocol_handler::handle_notify_new_transactions)
|
||||
HANDLE_NOTIFY_T2(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS, ¤cy_protocol_handler::handle_notify_new_transactions)
|
||||
HANDLE_INVOKE_T2(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS, ¤cy_protocol_handler::handle_invoke_new_transaction)
|
||||
HANDLE_NOTIFY_T2(NOTIFY_REQUEST_GET_OBJECTS, ¤cy_protocol_handler::handle_request_get_objects)
|
||||
HANDLE_NOTIFY_T2(NOTIFY_RESPONSE_GET_OBJECTS, ¤cy_protocol_handler::handle_response_get_objects)
|
||||
HANDLE_NOTIFY_T2(NOTIFY_REQUEST_CHAIN, ¤cy_protocol_handler::handle_request_chain)
|
||||
|
|
@ -76,16 +77,18 @@ namespace currency
|
|||
private:
|
||||
//----------------- commands handlers ----------------------------------------------
|
||||
int handle_notify_new_block(int command, NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& context);
|
||||
int handle_notify_new_transactions(int command, NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& context);
|
||||
int handle_notify_new_transactions(int command, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& context);
|
||||
int handle_invoke_new_transaction(int command, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& req, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response& rsp, currency_connection_context& context);
|
||||
int handle_request_get_objects(int command, NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context);
|
||||
int handle_response_get_objects(int command, NOTIFY_RESPONSE_GET_OBJECTS::request& arg, currency_connection_context& context);
|
||||
int handle_request_chain(int command, NOTIFY_REQUEST_CHAIN::request& arg, currency_connection_context& context);
|
||||
int handle_response_chain_entry(int command, NOTIFY_RESPONSE_CHAIN_ENTRY::request& arg, currency_connection_context& context);
|
||||
|
||||
|
||||
|
||||
|
||||
//----------------- i_bc_protocol_layout ---------------------------------------
|
||||
virtual bool relay_block(NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& exclude_context);
|
||||
virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context);
|
||||
virtual bool relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context);
|
||||
//----------------------------------------------------------------------------------
|
||||
//bool get_payload_sync_data(HANDSHAKE_DATA::request& hshd, currency_connection_context& context);
|
||||
bool request_missing_objects(currency_connection_context& context, bool check_having_blocks);
|
||||
|
|
@ -93,7 +96,7 @@ namespace currency
|
|||
void relay_que_worker();
|
||||
void process_current_relay_que(const std::list<relay_que_entry>& que);
|
||||
bool check_stop_flag_and_drop_cc(currency_connection_context& context);
|
||||
|
||||
int handle_new_transaction_from_net(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& req, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response& rsp, currency_connection_context& context, bool is_notify);
|
||||
t_core& m_core;
|
||||
|
||||
nodetool::p2p_endpoint_stub<connection_context> m_p2p_stub;
|
||||
|
|
|
|||
|
|
@ -369,45 +369,79 @@ namespace currency
|
|||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_notify_new_transactions(int command, NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& context)
|
||||
int t_currency_protocol_handler<t_core>::handle_notify_new_transactions(int command, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& context)
|
||||
{
|
||||
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response rsp_dummy = AUTO_VAL_INIT(rsp_dummy);
|
||||
return this->handle_new_transaction_from_net(arg, rsp_dummy, context, true);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_invoke_new_transaction(int command, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& req, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response& rsp, currency_connection_context& context)
|
||||
{
|
||||
return this->handle_new_transaction_from_net(req, rsp, context, false);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_new_transaction_from_net(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response& rsp, currency_connection_context& context, bool is_notify)
|
||||
{
|
||||
//do not process requests if it comes from node wich is debugged
|
||||
if (m_debug_ip_address != 0 && context.m_remote_ip == m_debug_ip_address)
|
||||
{
|
||||
rsp.code = API_RETURN_CODE_ACCESS_DENIED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if(context.m_state != currency_connection_context::state_normal)
|
||||
//if(context.m_state != currency_connection_context::state_normal)
|
||||
// return 1;
|
||||
if (!this->is_synchronized())
|
||||
{
|
||||
rsp.code = API_RETURN_CODE_BUSY;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint64_t inital_tx_count = arg.txs.size();
|
||||
|
||||
if (inital_tx_count > CURRENCY_RELAY_TXS_MAX_COUNT)
|
||||
{
|
||||
LOG_PRINT_L1("NOTIFY_NEW_TRANSACTIONS: To many transactions in NOTIFY_OR_INVOKE_NEW_TRANSACTIONS(" << inital_tx_count << ")");
|
||||
rsp.code = API_RETURN_CODE_OVERFLOW;
|
||||
return 1;
|
||||
}
|
||||
|
||||
TIME_MEASURE_START_MS(new_transactions_handle_time);
|
||||
for(auto tx_blob_it = arg.txs.begin(); tx_blob_it!=arg.txs.end();)
|
||||
for (auto tx_blob_it = arg.txs.begin(); tx_blob_it != arg.txs.end();)
|
||||
{
|
||||
currency::tx_verification_context tvc = AUTO_VAL_INIT(tvc);
|
||||
|
||||
m_core.handle_incoming_tx(*tx_blob_it, tvc, false);
|
||||
if(tvc.m_verification_failed)
|
||||
if (tvc.m_verification_failed)
|
||||
{
|
||||
LOG_PRINT_L0("NOTIFY_NEW_TRANSACTIONS: Tx verification failed, dropping connection");
|
||||
m_p2p->drop_connection(context);
|
||||
|
||||
if(is_notify)
|
||||
m_p2p->drop_connection(context);
|
||||
else
|
||||
rsp.code = API_RETURN_CODE_FAIL;
|
||||
return 1;
|
||||
}
|
||||
if(tvc.m_should_be_relayed)
|
||||
if (tvc.m_should_be_relayed)
|
||||
++tx_blob_it;
|
||||
else
|
||||
arg.txs.erase(tx_blob_it++);
|
||||
}
|
||||
|
||||
if(arg.txs.size())
|
||||
if (arg.txs.size())
|
||||
{
|
||||
//TODO: add announce usage here
|
||||
relay_transactions(arg, context);
|
||||
}
|
||||
TIME_MEASURE_FINISH_MS(new_transactions_handle_time);
|
||||
|
||||
LOG_PRINT_L2("NOTIFY_NEW_TRANSACTIONS: " << new_transactions_handle_time << "ms (inital_tx_count: " << inital_tx_count << ", relayed_tx_count: " << arg.txs.size() << ")");
|
||||
|
||||
return true;
|
||||
LOG_PRINT_L2("NOTIFY_OR_INVOKE_NEW_TRANSACTIONS(is_notify=" << is_notify <<"): " << new_transactions_handle_time << "ms (inital_tx_count: " << inital_tx_count << ", relayed_tx_count: " << arg.txs.size() << ")");
|
||||
rsp.code = API_RETURN_CODE_OK;
|
||||
return 1;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
int t_currency_protocol_handler<t_core>::handle_request_get_objects(int command, NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context)
|
||||
|
|
@ -756,7 +790,7 @@ namespace currency
|
|||
m_p2p->get_connections(connections);
|
||||
for (auto& cc : connections)
|
||||
{
|
||||
NOTIFY_NEW_TRANSACTIONS::request req = AUTO_VAL_INIT(req);
|
||||
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request req = AUTO_VAL_INIT(req);
|
||||
for (auto& qe : que)
|
||||
{
|
||||
//exclude relaying to original sender
|
||||
|
|
@ -766,7 +800,7 @@ namespace currency
|
|||
}
|
||||
if (req.txs.size())
|
||||
{
|
||||
post_notify<NOTIFY_NEW_TRANSACTIONS>(req, cc);
|
||||
post_notify<NOTIFY_OR_INVOKE_NEW_TRANSACTIONS>(req, cc);
|
||||
|
||||
if (debug_ss.tellp())
|
||||
debug_ss << ", ";
|
||||
|
|
@ -944,7 +978,7 @@ namespace currency
|
|||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------
|
||||
template<class t_core>
|
||||
bool t_currency_protocol_handler<t_core>::relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context)
|
||||
bool t_currency_protocol_handler<t_core>::relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context)
|
||||
{
|
||||
#ifdef ASYNC_RELAY_MODE
|
||||
{
|
||||
|
|
@ -956,7 +990,7 @@ namespace currency
|
|||
//m_relay_que_cv.notify_all();
|
||||
return true;
|
||||
#else
|
||||
return relay_post_notify<NOTIFY_NEW_TRANSACTIONS>(arg, exclude_context);
|
||||
return relay_post_notify<NOTIFY_OR_INVOKE_NEW_TRANSACTIONS>(arg, exclude_context);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace currency
|
|||
struct i_currency_protocol
|
||||
{
|
||||
virtual bool relay_block(NOTIFY_NEW_BLOCK::request& arg, currency_connection_context& exclude_context)=0;
|
||||
virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context)=0;
|
||||
virtual bool relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency_connection_context& exclude_context)=0;
|
||||
//virtual bool request_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, currency_connection_context& context)=0;
|
||||
};
|
||||
|
||||
|
|
@ -30,7 +30,7 @@ namespace currency
|
|||
{
|
||||
return false;
|
||||
}
|
||||
virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request& /*arg*/, currency_connection_context& /*exclude_context*/)
|
||||
virtual bool relay_transactions(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& /*arg*/, currency_connection_context& /*exclude_context*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_cmd_only, command_line::arg_version);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_os_version);
|
||||
// tools::get_default_data_dir() can't be called during static initialization
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_data_dir, tools::get_default_data_dir());
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_data_dir, tools::get_default_data_dir());
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_stop_after_height);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_config_file);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_disable_upnp);
|
||||
|
|
@ -154,8 +154,8 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_cmd_sett, command_line::arg_log_dir);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_log_level);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_console);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_show_details);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_show_rpc_autodoc);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_show_details);
|
||||
command_line::add_arg(desc_cmd_only, 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);
|
||||
|
|
@ -168,7 +168,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
|
||||
arg_market_disable.default_value = true;
|
||||
arg_market_disable.not_use_default = false;
|
||||
arg_market_disable.use_default = true;
|
||||
|
||||
currency::core::init_options(desc_cmd_sett);
|
||||
currency::core_rpc_server::init_options(desc_cmd_sett);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/bind/placeholders.hpp>
|
||||
|
||||
#include "console_handler.h"
|
||||
#include "p2p/net_node.h"
|
||||
|
|
@ -18,6 +19,8 @@
|
|||
#include "serialization/binary_utils.h"
|
||||
#include "simplewallet/password_container.h"
|
||||
|
||||
namespace ph = boost::placeholders;
|
||||
|
||||
PUSH_VS_WARNINGS
|
||||
DISABLE_VS_WARNINGS(4100)
|
||||
|
||||
|
|
@ -31,49 +34,49 @@ class daemon_commands_handler
|
|||
public:
|
||||
daemon_commands_handler(nodetool::node_server<currency::t_currency_protocol_handler<currency::core> >& srv, currency::core_rpc_server& rpc) :m_srv(srv), m_rpc(rpc)
|
||||
{
|
||||
m_cmd_binder.set_handler("help", boost::bind(&console_handlers_binder::help, &m_cmd_binder, _1), "Show this help");
|
||||
m_cmd_binder.set_handler("print_pl", boost::bind(&daemon_commands_handler::print_pl, this, _1), "Print peer list");
|
||||
m_cmd_binder.set_handler("print_cn", boost::bind(&daemon_commands_handler::print_cn, this, _1), "Print connections");
|
||||
m_cmd_binder.set_handler("print_bc", boost::bind(&daemon_commands_handler::print_bc, this, _1), "Print blockchain info in a given blocks range, print_bc <begin_height> [<end_height>]");
|
||||
m_cmd_binder.set_handler("print_bc_tx", boost::bind(&daemon_commands_handler::print_bc_tx, this, _1), "Print blockchain info with trnsactions in a given blocks range, print_bc <begin_height> [<end_height>]");
|
||||
//m_cmd_binder.set_handler("print_bci", boost::bind(&daemon_commands_handler::print_bci, this, _1));
|
||||
m_cmd_binder.set_handler("print_bc_outs", boost::bind(&daemon_commands_handler::print_bc_outs, this, _1));
|
||||
m_cmd_binder.set_handler("print_market", boost::bind(&daemon_commands_handler::print_market, this, _1));
|
||||
m_cmd_binder.set_handler("print_bc_outs_stats", boost::bind(&daemon_commands_handler::print_bc_outs_stats, this, _1));
|
||||
m_cmd_binder.set_handler("print_block", boost::bind(&daemon_commands_handler::print_block, this, _1), "Print block, print_block <block_hash> | <block_height>");
|
||||
m_cmd_binder.set_handler("print_block_info", boost::bind(&daemon_commands_handler::print_block_info, this, _1), "Print block info, print_block <block_hash> | <block_height>");
|
||||
m_cmd_binder.set_handler("print_tx_prun_info", boost::bind(&daemon_commands_handler::print_tx_prun_info, this, _1), "Print tx prunning info");
|
||||
m_cmd_binder.set_handler("print_tx", boost::bind(&daemon_commands_handler::print_tx, this, _1), "Print transaction, print_tx <transaction_hash>");
|
||||
m_cmd_binder.set_handler("start_mining", boost::bind(&daemon_commands_handler::start_mining, this, _1), "Start mining for specified address, start_mining <addr> [threads=1]");
|
||||
m_cmd_binder.set_handler("stop_mining", boost::bind(&daemon_commands_handler::stop_mining, this, _1), "Stop mining");
|
||||
m_cmd_binder.set_handler("print_pool", boost::bind(&daemon_commands_handler::print_pool, this, _1), "Print transaction pool (long format)");
|
||||
m_cmd_binder.set_handler("print_pool_sh", boost::bind(&daemon_commands_handler::print_pool_sh, this, _1), "Print transaction pool (short format)");
|
||||
m_cmd_binder.set_handler("show_hr", boost::bind(&daemon_commands_handler::show_hr, this, _1), "Start showing hash rate");
|
||||
m_cmd_binder.set_handler("hide_hr", boost::bind(&daemon_commands_handler::hide_hr, this, _1), "Stop showing hash rate");
|
||||
m_cmd_binder.set_handler("save", boost::bind(&daemon_commands_handler::save, this, _1), "Save blockchain");
|
||||
m_cmd_binder.set_handler("print_daemon_stat", boost::bind(&daemon_commands_handler::print_daemon_stat, this, _1), "Print daemon stat");
|
||||
m_cmd_binder.set_handler("print_debug_stat", boost::bind(&daemon_commands_handler::print_debug_stat, this, _1), "Print debug stat info");
|
||||
m_cmd_binder.set_handler("get_transactions_statics", boost::bind(&daemon_commands_handler::get_transactions_statistics, this, _1), "Calculates transactions statistics");
|
||||
m_cmd_binder.set_handler("force_relay_tx_pool", boost::bind(&daemon_commands_handler::force_relay_tx_pool, this, _1), "re-relay all transactions from pool");
|
||||
m_cmd_binder.set_handler("enable_channel", boost::bind(&daemon_commands_handler::enable_channel, this, _1), "Enable specified log channel");
|
||||
m_cmd_binder.set_handler("disable_channel", boost::bind(&daemon_commands_handler::disable_channel, this, _1), "Enable specified log channel");
|
||||
m_cmd_binder.set_handler("clear_cache", boost::bind(&daemon_commands_handler::clear_cache, this, _1), "Clear blockchain storage cache");
|
||||
m_cmd_binder.set_handler("clear_altblocks", boost::bind(&daemon_commands_handler::clear_altblocks, this, _1), "Clear blockchain storage cache");
|
||||
m_cmd_binder.set_handler("truncate_bc", boost::bind(&daemon_commands_handler::truncate_bc, this, _1), "Truncate blockchain to specified height");
|
||||
m_cmd_binder.set_handler("inspect_block_index", boost::bind(&daemon_commands_handler::inspect_block_index, this, _1), "Inspects block index for internal errors");
|
||||
m_cmd_binder.set_handler("print_db_performance_data", boost::bind(&daemon_commands_handler::print_db_performance_data, this, _1), "Dumps all db containers performance counters");
|
||||
m_cmd_binder.set_handler("search_by_id", boost::bind(&daemon_commands_handler::search_by_id, this, _1), "Search all possible elemets by given id");
|
||||
m_cmd_binder.set_handler("find_key_image", boost::bind(&daemon_commands_handler::find_key_image, this, _1), "Try to find tx related to key_image");
|
||||
m_cmd_binder.set_handler("rescan_aliases", boost::bind(&daemon_commands_handler::rescan_aliases, this, _1), "Debug function");
|
||||
m_cmd_binder.set_handler("forecast_difficulty", boost::bind(&daemon_commands_handler::forecast_difficulty, this, _1), "Prints PoW and PoS difficulties for as many future blocks as possible based on current conditions");
|
||||
m_cmd_binder.set_handler("print_deadlock_guard", boost::bind(&daemon_commands_handler::print_deadlock_guard, this, _1), "Print all threads which is blocked or involved in mutex ownership");
|
||||
m_cmd_binder.set_handler("print_block_from_hex_blob", boost::bind(&daemon_commands_handler::print_block_from_hex_blob, this, _1), "Unserialize block from hex binary data to json-like representation");
|
||||
m_cmd_binder.set_handler("print_tx_from_hex_blob", boost::bind(&daemon_commands_handler::print_tx_from_hex_blob, this, _1), "Unserialize transaction from hex binary data to json-like representation");
|
||||
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");
|
||||
m_cmd_binder.set_handler("debug_remote_node_mode", boost::bind(&daemon_commands_handler::debug_remote_node_mode, this, _1), "<ip-address> - If node got connected put node into 'debug mode' i.e. no sync process of other communication except ping responses, maintenance secrete key will be requested");
|
||||
m_cmd_binder.set_handler("help", boost::bind(&console_handlers_binder::help, &m_cmd_binder, ph::_1), "Show this help");
|
||||
m_cmd_binder.set_handler("print_pl", boost::bind(&daemon_commands_handler::print_pl, this, ph::_1), "Print peer list");
|
||||
m_cmd_binder.set_handler("print_cn", boost::bind(&daemon_commands_handler::print_cn, this, ph::_1), "Print connections");
|
||||
m_cmd_binder.set_handler("print_bc", boost::bind(&daemon_commands_handler::print_bc, this, ph::_1), "Print blockchain info in a given blocks range, print_bc <begin_height> [<end_height>]");
|
||||
m_cmd_binder.set_handler("print_bc_tx", boost::bind(&daemon_commands_handler::print_bc_tx, this, ph::_1), "Print blockchain info with trnsactions in a given blocks range, print_bc <begin_height> [<end_height>]");
|
||||
//m_cmd_binder.set_handler("print_bci", boost::bind(&daemon_commands_handler::print_bci, this, ph::_1));
|
||||
m_cmd_binder.set_handler("print_bc_outs", boost::bind(&daemon_commands_handler::print_bc_outs, this, ph::_1));
|
||||
m_cmd_binder.set_handler("print_market", boost::bind(&daemon_commands_handler::print_market, this, ph::_1));
|
||||
m_cmd_binder.set_handler("print_bc_outs_stats", boost::bind(&daemon_commands_handler::print_bc_outs_stats, this, ph::_1));
|
||||
m_cmd_binder.set_handler("print_block", boost::bind(&daemon_commands_handler::print_block, this, ph::_1), "Print block, print_block <block_hash> | <block_height>");
|
||||
m_cmd_binder.set_handler("print_block_info", boost::bind(&daemon_commands_handler::print_block_info, this, ph::_1), "Print block info, print_block <block_hash> | <block_height>");
|
||||
m_cmd_binder.set_handler("print_tx_prun_info", boost::bind(&daemon_commands_handler::print_tx_prun_info, this, ph::_1), "Print tx prunning info");
|
||||
m_cmd_binder.set_handler("print_tx", boost::bind(&daemon_commands_handler::print_tx, this, ph::_1), "Print transaction, print_tx <transaction_hash>");
|
||||
m_cmd_binder.set_handler("start_mining", boost::bind(&daemon_commands_handler::start_mining, this, ph::_1), "Start mining for specified address, start_mining <addr> [threads=1]");
|
||||
m_cmd_binder.set_handler("stop_mining", boost::bind(&daemon_commands_handler::stop_mining, this, ph::_1), "Stop mining");
|
||||
m_cmd_binder.set_handler("print_pool", boost::bind(&daemon_commands_handler::print_pool, this, ph::_1), "Print transaction pool (long format)");
|
||||
m_cmd_binder.set_handler("print_pool_sh", boost::bind(&daemon_commands_handler::print_pool_sh, this, ph::_1), "Print transaction pool (short format)");
|
||||
m_cmd_binder.set_handler("show_hr", boost::bind(&daemon_commands_handler::show_hr, this, ph::_1), "Start showing hash rate");
|
||||
m_cmd_binder.set_handler("hide_hr", boost::bind(&daemon_commands_handler::hide_hr, this, ph::_1), "Stop showing hash rate");
|
||||
m_cmd_binder.set_handler("save", boost::bind(&daemon_commands_handler::save, this, ph::_1), "Save blockchain");
|
||||
m_cmd_binder.set_handler("print_daemon_stat", boost::bind(&daemon_commands_handler::print_daemon_stat, this, ph::_1), "Print daemon stat");
|
||||
m_cmd_binder.set_handler("print_debug_stat", boost::bind(&daemon_commands_handler::print_debug_stat, this, ph::_1), "Print debug stat info");
|
||||
m_cmd_binder.set_handler("get_transactions_statics", boost::bind(&daemon_commands_handler::get_transactions_statistics, this, ph::_1), "Calculates transactions statistics");
|
||||
m_cmd_binder.set_handler("force_relay_tx_pool", boost::bind(&daemon_commands_handler::force_relay_tx_pool, this, ph::_1), "re-relay all transactions from pool");
|
||||
m_cmd_binder.set_handler("enable_channel", boost::bind(&daemon_commands_handler::enable_channel, this, ph::_1), "Enable specified log channel");
|
||||
m_cmd_binder.set_handler("disable_channel", boost::bind(&daemon_commands_handler::disable_channel, this, ph::_1), "Enable specified log channel");
|
||||
m_cmd_binder.set_handler("clear_cache", boost::bind(&daemon_commands_handler::clear_cache, this, ph::_1), "Clear blockchain storage cache");
|
||||
m_cmd_binder.set_handler("clear_altblocks", boost::bind(&daemon_commands_handler::clear_altblocks, this, ph::_1), "Clear blockchain storage cache");
|
||||
m_cmd_binder.set_handler("truncate_bc", boost::bind(&daemon_commands_handler::truncate_bc, this, ph::_1), "Truncate blockchain to specified height");
|
||||
m_cmd_binder.set_handler("inspect_block_index", boost::bind(&daemon_commands_handler::inspect_block_index, this, ph::_1), "Inspects block index for internal errors");
|
||||
m_cmd_binder.set_handler("print_db_performance_data", boost::bind(&daemon_commands_handler::print_db_performance_data, this, ph::_1), "Dumps all db containers performance counters");
|
||||
m_cmd_binder.set_handler("search_by_id", boost::bind(&daemon_commands_handler::search_by_id, this, ph::_1), "Search all possible elemets by given id");
|
||||
m_cmd_binder.set_handler("find_key_image", boost::bind(&daemon_commands_handler::find_key_image, this, ph::_1), "Try to find tx related to key_image");
|
||||
m_cmd_binder.set_handler("rescan_aliases", boost::bind(&daemon_commands_handler::rescan_aliases, this, ph::_1), "Debug function");
|
||||
m_cmd_binder.set_handler("forecast_difficulty", boost::bind(&daemon_commands_handler::forecast_difficulty, this, ph::_1), "Prints PoW and PoS difficulties for as many future blocks as possible based on current conditions");
|
||||
m_cmd_binder.set_handler("print_deadlock_guard", boost::bind(&daemon_commands_handler::print_deadlock_guard, this, ph::_1), "Print all threads which is blocked or involved in mutex ownership");
|
||||
m_cmd_binder.set_handler("print_block_from_hex_blob", boost::bind(&daemon_commands_handler::print_block_from_hex_blob, this, ph::_1), "Unserialize block from hex binary data to json-like representation");
|
||||
m_cmd_binder.set_handler("print_tx_from_hex_blob", boost::bind(&daemon_commands_handler::print_tx_from_hex_blob, this, ph::_1), "Unserialize transaction from hex binary data to json-like representation");
|
||||
m_cmd_binder.set_handler("print_tx_outputs_usage", boost::bind(&daemon_commands_handler::print_tx_outputs_usage, this, ph::_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, ph::_1), "Print difficulties of last n blocks");
|
||||
m_cmd_binder.set_handler("debug_remote_node_mode", boost::bind(&daemon_commands_handler::debug_remote_node_mode, this, ph::_1), "<ip-address> - If node got connected put node into 'debug mode' i.e. no sync process of other communication except ping responses, maintenance secrete key will be requested");
|
||||
#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");
|
||||
m_cmd_binder.set_handler("debug_set_time_adj", boost::bind(&daemon_commands_handler::debug_set_time_adj, this, ph::_1), "DEBUG: set core time adjustment");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -100,6 +100,7 @@ MainWindow::MainWindow()
|
|||
, m_system_shutdown(false)
|
||||
, m_view(nullptr)
|
||||
, m_channel(nullptr)
|
||||
, m_ui_dispatch_id_counter(0)
|
||||
{
|
||||
#ifndef _MSC_VER
|
||||
//workaround for macos broken tolower from std, very dirty hack
|
||||
|
|
@ -415,7 +416,7 @@ bool MainWindow::init(const std::string& html_path)
|
|||
//QtWebEngine::initialize();
|
||||
init_tray_icon(html_path);
|
||||
set_html_path(html_path);
|
||||
|
||||
m_threads_pool.init(2);
|
||||
m_backend.subscribe_to_core_events(this);
|
||||
|
||||
bool r = QSslSocket::supportsSsl();
|
||||
|
|
@ -920,6 +921,41 @@ QString MainWindow::start_backend(const QString& params)
|
|||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
||||
QString MainWindow::sync_call(const QString& func_name, const QString& params)
|
||||
{
|
||||
if (func_name == "transfer")
|
||||
{
|
||||
return this->transfer(params);
|
||||
}
|
||||
else if (func_name == "test_call")
|
||||
{
|
||||
return params;
|
||||
}
|
||||
else
|
||||
{
|
||||
return QString(QString() + "{ \"status\": \"Method '" + func_name + "' not found\"}");
|
||||
}
|
||||
}
|
||||
|
||||
QString MainWindow::async_call(const QString& func_name, const QString& params)
|
||||
{
|
||||
|
||||
uint64_t job_id = m_ui_dispatch_id_counter++;
|
||||
QString method_name = func_name;
|
||||
QString argements = params;
|
||||
|
||||
auto async_callback = [this, method_name, argements, job_id]()
|
||||
{
|
||||
QString res_str = this->sync_call(method_name, argements);
|
||||
this->dispatch_async_call_result(std::to_string(job_id).c_str(), res_str); //general function
|
||||
};
|
||||
|
||||
m_threads_pool.add_job(async_callback);
|
||||
LOG_PRINT_L2("[UI_ASYNC_CALL]: started " << method_name.toStdString() << ", job id: " << job_id);
|
||||
return QString::fromStdString(std::string("{ \"job_id\": ") + std::to_string(job_id) + "}");
|
||||
}
|
||||
|
||||
|
||||
bool MainWindow::update_wallet_status(const view::wallet_status_info& wsi)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
|
@ -947,6 +983,17 @@ bool MainWindow::set_options(const view::gui_options& opt)
|
|||
CATCH_ENTRY2(false);
|
||||
}
|
||||
|
||||
bool MainWindow::update_tor_status(const view::current_action_status& opt)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
std::string json_str;
|
||||
epee::serialization::store_t_to_json(opt, json_str, 0, epee::serialization::eol_lf);
|
||||
LOG_PRINT_L0("SENDING SIGNAL -> [HANDLE_CURRENT_ACTION_STATE]:" << std::endl << json_str);
|
||||
QMetaObject::invokeMethod(this, "handle_current_action_state", Qt::QueuedConnection, Q_ARG(QString, json_str.c_str()));
|
||||
return true;
|
||||
CATCH_ENTRY2(false);
|
||||
}
|
||||
|
||||
bool MainWindow::nativeEventFilter(const QByteArray &eventType, void *message, long *result)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
|
|
@ -1654,6 +1701,20 @@ QString MainWindow::get_log_level(const QString& param)
|
|||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
||||
QString MainWindow::set_enable_tor(const QString& param)
|
||||
{
|
||||
TRY_ENTRY();
|
||||
LOG_API_TIMING();
|
||||
PREPARE_ARG_FROM_JSON(currency::struct_with_one_t_type<bool>, enabl_tor);
|
||||
m_backend.set_use_tor(enabl_tor.v);
|
||||
//epee::log_space::get_set_log_detalisation_level(true, enabl_tor.v);
|
||||
default_ar.error_code = API_RETURN_CODE_OK;
|
||||
LOG_PRINT("[TOR]: Enable TOR set to " << enabl_tor.v, LOG_LEVEL_MIN);
|
||||
|
||||
return MAKE_RESPONSE(default_ar);
|
||||
CATCH_ENTRY_FAIL_API_RESPONCE();
|
||||
}
|
||||
|
||||
// QString MainWindow::dump_all_offers()
|
||||
// {
|
||||
// LOG_API_TIMING();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@
|
|||
#include "currency_core/offers_services_helpers.h"
|
||||
#endif
|
||||
|
||||
#include "common/threads_pool.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QWebEngineView;
|
||||
class QLineEdit;
|
||||
|
|
@ -137,6 +139,7 @@ public:
|
|||
QString stop_pos_mining(const QString& param);
|
||||
QString set_log_level(const QString& param);
|
||||
QString get_log_level(const QString& param);
|
||||
QString set_enable_tor(const QString& param);
|
||||
// QString dump_all_offers();
|
||||
QString webkit_launched_script();
|
||||
QString get_smart_wallet_info(const QString& param);
|
||||
|
|
@ -179,6 +182,9 @@ public:
|
|||
QString is_remnotenode_mode_preconfigured();
|
||||
QString start_backend(const QString& params);
|
||||
|
||||
QString async_call(const QString& func_name, const QString& params);
|
||||
QString sync_call(const QString& func_name, const QString& params);
|
||||
|
||||
//for test purposes onlys
|
||||
QString request_dummy();
|
||||
|
||||
|
|
@ -192,11 +198,11 @@ signals:
|
|||
void wallet_sync_progress(const QString str);
|
||||
void handle_internal_callback(const QString str, const QString callback_name);
|
||||
void update_pos_mining_text(const QString str);
|
||||
void do_dispatch(const QString status, const QString params); //general function
|
||||
void on_core_event(const QString method_name); //general function
|
||||
void set_options(const QString str); //general function
|
||||
void get_wallet_name();
|
||||
void handle_deeplink_click(const QString str);
|
||||
void handle_current_action_state(const QString str);
|
||||
void dispatch_async_call_result(const QString id, const QString resp); //general function
|
||||
|
||||
private:
|
||||
//-------------------- i_core_event_handler --------------------
|
||||
|
|
@ -216,6 +222,7 @@ private:
|
|||
virtual bool init(const std::string& path);
|
||||
virtual bool pos_block_found(const currency::block& block_found);
|
||||
virtual bool set_options(const view::gui_options& opt);
|
||||
virtual bool update_tor_status(const view::current_action_status& opt);
|
||||
//--------- QAbstractNativeEventFilter ---------------------------
|
||||
virtual bool nativeEventFilter(const QByteArray &eventType, void *message, long *result);
|
||||
//----------------------------------------------
|
||||
|
|
@ -257,6 +264,8 @@ private:
|
|||
std::atomic<bool> m_gui_deinitialize_done_1;
|
||||
std::atomic<bool> m_backend_stopped_2;
|
||||
std::atomic<bool> m_system_shutdown;
|
||||
std::atomic<uint64_t> m_ui_dispatch_id_counter;
|
||||
utils::threads_pool m_threads_pool;
|
||||
|
||||
std::string m_master_password;
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 709a1e6a3eb5ae7af48bbadf6b4c512b637b75b3
|
||||
Subproject commit b091d45ad697db2d35e94de41be3f175bad0f71d
|
||||
|
|
@ -26,18 +26,18 @@ namespace nodetool
|
|||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_ip = {"p2p-bind-ip", "Interface for p2p network protocol", "0.0.0.0"};
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_port = {"p2p-bind-port", "Port for p2p network protocol", boost::to_string(P2P_DEFAULT_PORT)};
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_external_port = {"p2p-external-port", "External port for p2p network protocol (if port forwarding used with NAT)", 0};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip = {"allow-local-ip", "Allow local ip add to peer list, mostly in debug purposes"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer = {"add-peer", "Manually add peer to local peerlist"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_priority_node = {"add-priority-node", "Specify list of peers to connect to and attempt to keep the connection open"};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_use_only_priority_nodes = {"use-only-priority-nodes", "Try to connect only to priority nodes"};
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_seed_node = {"seed-node", "Connect to a node to retrieve peer addresses, and disconnect"};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port = {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true};
|
||||
const command_line::arg_descriptor<bool> arg_p2p_offline_mode = { "offline-mode", "Don't connect to any node and reject any connections", false, true };
|
||||
const command_line::arg_descriptor<bool> arg_p2p_disable_debug_reqs = { "disable-debug-p2p-requests", "Disable p2p debug requests", false, true };
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_ip_auto_blocking = { "p2p-ip-auto-blocking", "Enable (1) or disable (0) peers auto-blocking by IP <0|1>. Default: 0", 0, false };
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_ip ("p2p-bind-ip", "Interface for p2p network protocol", "0.0.0.0");
|
||||
const command_line::arg_descriptor<std::string> arg_p2p_bind_port ("p2p-bind-port", "Port for p2p network protocol", boost::to_string(P2P_DEFAULT_PORT));
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_external_port ("p2p-external-port", "External port for p2p network protocol (if port forwarding used with NAT)", 0);
|
||||
const command_line::arg_descriptor<bool> arg_p2p_allow_local_ip ("allow-local-ip", "Allow local ip add to peer list, mostly in debug purposes");
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_peer ("add-peer", "Manually add peer to local peerlist");
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_add_priority_node ("add-priority-node", "Specify list of peers to connect to and attempt to keep the connection open");
|
||||
const command_line::arg_descriptor<bool> arg_p2p_use_only_priority_nodes ("use-only-priority-nodes", "Try to connect only to priority nodes");
|
||||
const command_line::arg_descriptor<std::vector<std::string> > arg_p2p_seed_node ("seed-node", "Connect to a node to retrieve peer addresses, and disconnect");
|
||||
const command_line::arg_descriptor<bool> arg_p2p_hide_my_port ("hide-my-port", "Do not announce yourself as peerlist candidate");
|
||||
const command_line::arg_descriptor<bool> arg_p2p_offline_mode ( "offline-mode", "Don't connect to any node and reject any connections");
|
||||
const command_line::arg_descriptor<bool> arg_p2p_disable_debug_reqs ( "disable-debug-p2p-requests", "Disable p2p debug requests");
|
||||
const command_line::arg_descriptor<uint32_t> arg_p2p_ip_auto_blocking ( "p2p-ip-auto-blocking", "Enable (1) or disable (0) peers auto-blocking by IP <0|1>. Default: 0", 1);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -22,9 +22,9 @@ namespace currency
|
|||
{
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_ip = {"rpc-bind-ip", "", "127.0.0.1"};
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_port = {"rpc-bind-port", "", std::to_string(RPC_DEFAULT_PORT)};
|
||||
const command_line::arg_descriptor<bool> arg_rpc_ignore_status = {"rpc-ignore-offline", "Let rpc calls despite online/offline status", false, true };
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_ip ("rpc-bind-ip", "", "127.0.0.1");
|
||||
const command_line::arg_descriptor<std::string> arg_rpc_bind_port ("rpc-bind-port", "", std::to_string(RPC_DEFAULT_PORT));
|
||||
const command_line::arg_descriptor<bool> arg_rpc_ignore_status ("rpc-ignore-offline", "Let rpc calls despite online/offline status");
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
void core_rpc_server::init_options(boost::program_options::options_description& desc)
|
||||
|
|
@ -705,7 +705,7 @@ namespace currency
|
|||
}
|
||||
|
||||
|
||||
NOTIFY_NEW_TRANSACTIONS::request r;
|
||||
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request r;
|
||||
r.txs.push_back(tx_blob);
|
||||
m_core.get_protocol()->relay_transactions(r, fake_context);
|
||||
//TODO: make sure that tx has reached other nodes here, probably wait to receive reflections from other nodes
|
||||
|
|
@ -716,7 +716,7 @@ namespace currency
|
|||
bool core_rpc_server::on_force_relaey_raw_txs(const COMMAND_RPC_FORCE_RELAY_RAW_TXS::request& req, COMMAND_RPC_FORCE_RELAY_RAW_TXS::response& res, connection_context& cntx)
|
||||
{
|
||||
CHECK_CORE_READY();
|
||||
NOTIFY_NEW_TRANSACTIONS::request r = AUTO_VAL_INIT(r);
|
||||
NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request r = AUTO_VAL_INIT(r);
|
||||
|
||||
for (const auto& t : req.txs_as_hex)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -33,30 +33,32 @@ using namespace epee;
|
|||
using namespace currency;
|
||||
using boost::lexical_cast;
|
||||
namespace po = boost::program_options;
|
||||
namespace ph = boost::placeholders;
|
||||
|
||||
#define EXTENDED_LOGS_FILE "wallet_details.log"
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_wallet_file = {"wallet-file", "Use wallet <arg>", ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_new_wallet = {"generate-new-wallet", "Generate new wallet and save it to <arg> or <address>.wallet by default", ""};
|
||||
const command_line::arg_descriptor<std::string> arg_generate_new_auditable_wallet = {"generate-new-auditable-wallet", "Generate new auditable wallet and store it to <arg>", ""};
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_address = {"daemon-address", "Use daemon instance at <host>:<port>", ""};
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_host = {"daemon-host", "Use daemon instance at host <arg> instead of localhost", ""};
|
||||
const command_line::arg_descriptor<std::string> arg_password = {"password", "Wallet password", "", true};
|
||||
const command_line::arg_descriptor<bool> arg_dont_refresh = { "no-refresh", "Do not refresh after load", false, true };
|
||||
const command_line::arg_descriptor<bool> arg_dont_set_date = { "no-set-creation-date", "Do not set wallet creation date", false, false };
|
||||
const command_line::arg_descriptor<int> arg_daemon_port = {"daemon-port", "Use daemon instance at port <arg> instead of default", 0};
|
||||
const command_line::arg_descriptor<uint32_t> arg_log_level = {"set-log", "", 0, true};
|
||||
const command_line::arg_descriptor<bool> arg_do_pos_mining = { "do-pos-mining", "Do PoS mining", false, false };
|
||||
const command_line::arg_descriptor<std::string> arg_pos_mining_reward_address = { "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" };
|
||||
const command_line::arg_descriptor<std::string> arg_restore_wallet = { "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to <arg>", "" };
|
||||
const command_line::arg_descriptor<bool> arg_offline_mode = { "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)", false, true };
|
||||
const command_line::arg_descriptor<std::string> arg_scan_for_wallet = { "scan-for-wallet", "", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_addr_to_compare = { "addr-to-compare", "", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_wallet_file ("wallet-file", "Use wallet <arg>", "");
|
||||
const command_line::arg_descriptor<std::string> arg_generate_new_wallet ("generate-new-wallet", "Generate new wallet and save it to <arg> or <address>.wallet by default", "");
|
||||
const command_line::arg_descriptor<std::string> arg_generate_new_auditable_wallet ("generate-new-auditable-wallet", "Generate new auditable wallet and store it to <arg>", "");
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_address ("daemon-address", "Use daemon instance at <host>:<port>", "");
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_host ("daemon-host", "Use daemon instance at host <arg> instead of localhost", "");
|
||||
const command_line::arg_descriptor<std::string> arg_password ("password", "Wallet password");
|
||||
const command_line::arg_descriptor<bool> arg_dont_refresh ( "no-refresh", "Do not refresh after load");
|
||||
const command_line::arg_descriptor<bool> arg_dont_set_date ( "no-set-creation-date", "Do not set wallet creation date", false);
|
||||
const command_line::arg_descriptor<int> arg_daemon_port ("daemon-port", "Use daemon instance at port <arg> instead of default", 0);
|
||||
const command_line::arg_descriptor<uint32_t> arg_log_level ("set-log", "");
|
||||
const command_line::arg_descriptor<bool> arg_do_pos_mining ( "do-pos-mining", "Do PoS mining", false);
|
||||
const command_line::arg_descriptor<std::string> arg_pos_mining_reward_address ( "pos-mining-reward-address", "Block reward will be sent to the giving address if specified", "" );
|
||||
const command_line::arg_descriptor<std::string> arg_restore_wallet ( "restore-wallet", "Restore wallet from seed phrase or tracking seed and save it to <arg>", "" );
|
||||
const command_line::arg_descriptor<bool> arg_offline_mode ( "offline-mode", "Don't connect to daemon, work offline (for cold-signing process)");
|
||||
const command_line::arg_descriptor<std::string> arg_scan_for_wallet ( "scan-for-wallet", "");
|
||||
const command_line::arg_descriptor<std::string> arg_addr_to_compare ( "addr-to-compare", "");
|
||||
const command_line::arg_descriptor<bool> arg_disable_tor_relay ( "disable-tor-relay", "Do PoS mining", false);
|
||||
|
||||
const command_line::arg_descriptor< std::vector<std::string> > arg_command = {"command", ""};
|
||||
const command_line::arg_descriptor< std::vector<std::string> > arg_command ("command", "");
|
||||
|
||||
inline std::string interpret_rpc_response(bool ok, const std::string& status)
|
||||
{
|
||||
|
|
@ -123,17 +125,9 @@ namespace
|
|||
m_flush = false;
|
||||
|
||||
LOG_PRINT(m_oss.str(), m_log_level)
|
||||
|
||||
if (epee::log_space::console_color_default == m_color)
|
||||
{
|
||||
std::cout << m_oss.str();
|
||||
}
|
||||
else
|
||||
{
|
||||
epee::log_space::set_console_color(m_color, m_bright);
|
||||
std::cout << m_oss.str();
|
||||
epee::log_space::reset_console_color();
|
||||
}
|
||||
epee::log_space::set_console_color(m_color, m_bright);
|
||||
std::cout << m_oss.str();
|
||||
epee::log_space::reset_console_color();
|
||||
std::cout << std::endl;
|
||||
}
|
||||
|
||||
|
|
@ -186,49 +180,51 @@ simple_wallet::simple_wallet()
|
|||
m_refresh_progress_reporter(*this),
|
||||
m_offline_mode(false)
|
||||
{
|
||||
m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, _1), "start_mining <threads_count> - Start mining in daemon");
|
||||
m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, _1), "Stop mining in daemon");
|
||||
m_cmd_binder.set_handler("refresh", boost::bind(&simple_wallet::refresh, this, _1), "Resynchronize transactions and balance");
|
||||
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 [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");
|
||||
m_cmd_binder.set_handler("dump_keyimages", boost::bind(&simple_wallet::dump_key_images, this, _1), "dump_keyimages - Write key_images in json to dump_key_images.txt");
|
||||
m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, _1), "payments <payment_id_1> [<payment_id_2> ... <payment_id_N>] - Show payments <payment_id_1>, ... <payment_id_N>");
|
||||
m_cmd_binder.set_handler("bc_height", boost::bind(&simple_wallet::show_blockchain_height, this, _1), "Show blockchain height");
|
||||
m_cmd_binder.set_handler("wallet_bc_height", boost::bind(&simple_wallet::show_wallet_bcheight, this, _1), "Show blockchain height");
|
||||
m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer, this, _1), "transfer <mixin_count> <addr_1> <amount_1> [<addr_2> <amount_2> ... <addr_N> <amount_N>] [payment_id] - Transfer <amount_1>,... <amount_N> to <address_1>,... <address_N>, respectively. <mixin_count> is the number of transactions yours is indistinguishable from (from 0 to maximum available), <payment_id> is an optional HEX-encoded string");
|
||||
m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this, _1), "set_log <level> - Change current log detalisation level, <level> is a number 0-4");
|
||||
m_cmd_binder.set_handler("enable_console_logger", boost::bind(&simple_wallet::enable_console_logger, this, _1), "Enables console logging");
|
||||
m_cmd_binder.set_handler("resync", boost::bind(&simple_wallet::resync_wallet, this, _1), "Causes wallet to reset all transfers and re-synchronize wallet");
|
||||
m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this, _1), "Show this help");
|
||||
m_cmd_binder.set_handler("get_transfer_info", boost::bind(&simple_wallet::get_transfer_info, this, _1), "displays transfer info by key_image or index");
|
||||
m_cmd_binder.set_handler("scan_for_collision", boost::bind(&simple_wallet::scan_for_key_image_collisions, this, _1), "Rescan transfers for key image collisions");
|
||||
m_cmd_binder.set_handler("fix_collisions", boost::bind(&simple_wallet::fix_collisions, this, _1), "Rescan transfers for key image collisions");
|
||||
m_cmd_binder.set_handler("scan_transfers_for_id", boost::bind(&simple_wallet::scan_transfers_for_id, this, _1), "Rescan transfers for tx_id");
|
||||
m_cmd_binder.set_handler("scan_transfers_for_ki", boost::bind(&simple_wallet::scan_transfers_for_ki, this, _1), "Rescan transfers for key image");
|
||||
m_cmd_binder.set_handler("print_utxo_distribution", boost::bind(&simple_wallet::print_utxo_distribution, this, _1), "Prints utxo distribution");
|
||||
m_cmd_binder.set_handler("sweep_below", boost::bind(&simple_wallet::sweep_below, this, _1), "sweep_below <mixin_count> <address> <amount_lower_limit> [payment_id] - Tries to transfers all coins with amount below the given limit to the given address");
|
||||
m_cmd_binder.set_handler("start_mining", boost::bind(&simple_wallet::start_mining, this, ph::_1), "start_mining <threads_count> - Start mining in daemon");
|
||||
m_cmd_binder.set_handler("stop_mining", boost::bind(&simple_wallet::stop_mining, this, ph::_1), "Stop mining in daemon");
|
||||
m_cmd_binder.set_handler("refresh", boost::bind(&simple_wallet::refresh, this, ph::_1), "Resynchronize transactions and balance");
|
||||
m_cmd_binder.set_handler("balance", boost::bind(&simple_wallet::show_balance, this, ph::_1), "Show current wallet balance");
|
||||
m_cmd_binder.set_handler("incoming_transfers", boost::bind(&simple_wallet::show_incoming_transfers, this, ph::_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, ph::_1), "incoming_transfers counts");
|
||||
m_cmd_binder.set_handler("list_recent_transfers", boost::bind(&simple_wallet::list_recent_transfers, this, ph::_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, ph::_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, ph::_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, ph::_1), "dump_transfers - Write transfers in json to dump_transfers.txt");
|
||||
m_cmd_binder.set_handler("dump_keyimages", boost::bind(&simple_wallet::dump_key_images, this, ph::_1), "dump_keyimages - Write key_images in json to dump_key_images.txt");
|
||||
m_cmd_binder.set_handler("payments", boost::bind(&simple_wallet::show_payments, this, ph::_1), "payments <payment_id_1> [<payment_id_2> ... <payment_id_N>] - Show payments <payment_id_1>, ... <payment_id_N>");
|
||||
m_cmd_binder.set_handler("bc_height", boost::bind(&simple_wallet::show_blockchain_height, this,ph::_1), "Show blockchain height");
|
||||
m_cmd_binder.set_handler("wallet_bc_height", boost::bind(&simple_wallet::show_wallet_bcheight, this,ph::_1), "Show blockchain height");
|
||||
m_cmd_binder.set_handler("transfer", boost::bind(&simple_wallet::transfer, this,ph::_1), "transfer <mixin_count> <addr_1> <amount_1> [<addr_2> <amount_2> ... <addr_N> <amount_N>] [payment_id] - Transfer <amount_1>,... <amount_N> to <address_1>,... <address_N>, respectively. <mixin_count> is the number of transactions yours is indistinguishable from (from 0 to maximum available), <payment_id> is an optional HEX-encoded string");
|
||||
m_cmd_binder.set_handler("set_log", boost::bind(&simple_wallet::set_log, this,ph::_1), "set_log <level> - Change current log detalisation level, <level> is a number 0-4");
|
||||
m_cmd_binder.set_handler("enable_console_logger", boost::bind(&simple_wallet::enable_console_logger, this,ph::_1), "Enables console logging");
|
||||
m_cmd_binder.set_handler("resync", boost::bind(&simple_wallet::resync_wallet, this,ph::_1), "Causes wallet to reset all transfers and re-synchronize wallet");
|
||||
m_cmd_binder.set_handler("help", boost::bind(&simple_wallet::help, this,ph::_1), "Show this help");
|
||||
m_cmd_binder.set_handler("get_transfer_info", boost::bind(&simple_wallet::get_transfer_info, this,ph::_1), "displays transfer info by key_image or index");
|
||||
m_cmd_binder.set_handler("scan_for_collision", boost::bind(&simple_wallet::scan_for_key_image_collisions, this,ph::_1), "Rescan transfers for key image collisions");
|
||||
m_cmd_binder.set_handler("fix_collisions", boost::bind(&simple_wallet::fix_collisions, this,ph::_1), "Rescan transfers for key image collisions");
|
||||
m_cmd_binder.set_handler("scan_transfers_for_id", boost::bind(&simple_wallet::scan_transfers_for_id, this,ph::_1), "Rescan transfers for tx_id");
|
||||
m_cmd_binder.set_handler("scan_transfers_for_ki", boost::bind(&simple_wallet::scan_transfers_for_ki, this,ph::_1), "Rescan transfers for key image");
|
||||
m_cmd_binder.set_handler("print_utxo_distribution", boost::bind(&simple_wallet::print_utxo_distribution, this,ph::_1), "Prints utxo distribution");
|
||||
m_cmd_binder.set_handler("sweep_below", boost::bind(&simple_wallet::sweep_below, this,ph::_1), "sweep_below <mixin_count> <address> <amount_lower_limit> [payment_id] - Tries to transfers all coins with amount below the given limit to the given address");
|
||||
|
||||
m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this, _1), "Show current wallet public address");
|
||||
m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::integrated_address, this, _1), "integrated_address [<payment_id>|<integrated_address] - encodes given payment_id along with wallet's address into an integrated address (random payment_id will be used if none is provided). Decodes given integrated_address into standard address");
|
||||
m_cmd_binder.set_handler("show_seed", boost::bind(&simple_wallet::show_seed, this, _1), "Display secret 24 word phrase that could be used to recover this wallet");
|
||||
m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this, _1), "Display secret spend key");
|
||||
m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this, _1), "Display secret view key");
|
||||
m_cmd_binder.set_handler("address", boost::bind(&simple_wallet::print_address, this,ph::_1), "Show current wallet public address");
|
||||
m_cmd_binder.set_handler("integrated_address", boost::bind(&simple_wallet::integrated_address, this,ph::_1), "integrated_address [<payment_id>|<integrated_address] - encodes given payment_id along with wallet's address into an integrated address (random payment_id will be used if none is provided). Decodes given integrated_address into standard address");
|
||||
m_cmd_binder.set_handler("show_seed", boost::bind(&simple_wallet::show_seed, this,ph::_1), "Display secret 24 word phrase that could be used to recover this wallet");
|
||||
m_cmd_binder.set_handler("spendkey", boost::bind(&simple_wallet::spendkey, this,ph::_1), "Display secret spend key");
|
||||
m_cmd_binder.set_handler("viewkey", boost::bind(&simple_wallet::viewkey, this,ph::_1), "Display secret view key");
|
||||
|
||||
m_cmd_binder.set_handler("get_tx_key", boost::bind(&simple_wallet::get_tx_key, this, _1), "Get transaction one-time secret key (r) for a given <txid>");
|
||||
m_cmd_binder.set_handler("get_tx_key", boost::bind(&simple_wallet::get_tx_key, this,ph::_1), "Get transaction one-time secret key (r) for a given <txid>");
|
||||
|
||||
m_cmd_binder.set_handler("tracking_seed", boost::bind(&simple_wallet::tracking_seed, this, _1), "For auditable wallets: prints tracking seed for wallet's audit by a third party");
|
||||
m_cmd_binder.set_handler("tracking_seed", boost::bind(&simple_wallet::tracking_seed, this,ph::_1), "For auditable wallets: prints tracking seed for wallet's audit by a third party");
|
||||
|
||||
m_cmd_binder.set_handler("save", boost::bind(&simple_wallet::save, this, _1), "Save wallet synchronized data");
|
||||
m_cmd_binder.set_handler("save_watch_only", boost::bind(&simple_wallet::save_watch_only, this, _1), "save_watch_only <filename> <password> - save as watch-only wallet file.");
|
||||
m_cmd_binder.set_handler("save", boost::bind(&simple_wallet::save, this,ph::_1), "Save wallet synchronized data");
|
||||
m_cmd_binder.set_handler("save_watch_only", boost::bind(&simple_wallet::save_watch_only, this,ph::_1), "save_watch_only <filename> <password> - save as watch-only wallet file.");
|
||||
|
||||
m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this, _1), "sign_transfer <unsgined_tx_file> <signed_tx_file> - sign unsigned tx from a watch-only wallet");
|
||||
m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this, _1), "submit_transfer <signed_tx_file> - broadcast signed tx");
|
||||
m_cmd_binder.set_handler("export_history", boost::bind(&simple_wallet::submit_transfer, this, _1), "Export transaction history in CSV file");
|
||||
m_cmd_binder.set_handler("sign_transfer", boost::bind(&simple_wallet::sign_transfer, this,ph::_1), "sign_transfer <unsgined_tx_file> <signed_tx_file> - sign unsigned tx from a watch-only wallet");
|
||||
m_cmd_binder.set_handler("submit_transfer", boost::bind(&simple_wallet::submit_transfer, this,ph::_1), "submit_transfer <signed_tx_file> - broadcast signed tx");
|
||||
m_cmd_binder.set_handler("export_history", boost::bind(&simple_wallet::submit_transfer, this,ph::_1), "Export transaction history in CSV file");
|
||||
m_cmd_binder.set_handler("tor_enable", boost::bind(&simple_wallet::tor_enable, this, _1), "Enable relaying transactions over TOR network(enabled by default)");
|
||||
m_cmd_binder.set_handler("tor_disable", boost::bind(&simple_wallet::tor_disable, this, _1), "Enable relaying transactions over TOR network(enabled by default)");
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
simple_wallet::~simple_wallet()
|
||||
|
|
@ -361,6 +357,11 @@ bool simple_wallet::init(const boost::program_options::variables_map& vm)
|
|||
bool r = open_wallet(m_wallet_file, pwd_container.password());
|
||||
CHECK_AND_ASSERT_MES(r, false, "could not open account");
|
||||
}
|
||||
if (m_disable_tor)
|
||||
{
|
||||
m_wallet->set_disable_tor_relay(true);
|
||||
message_writer(epee::log_space::console_color_default, true, std::string(), LOG_LEVEL_0) << "Notice: Relaying transactions over TOR disabled with command line parameter";
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -384,6 +385,7 @@ void simple_wallet::handle_command_line(const boost::program_options::variables_
|
|||
m_do_not_set_date = command_line::get_arg(vm, arg_dont_set_date);
|
||||
m_do_pos_mining = command_line::get_arg(vm, arg_do_pos_mining);
|
||||
m_restore_wallet = command_line::get_arg(vm, arg_restore_wallet);
|
||||
m_disable_tor = command_line::get_arg(vm, arg_disable_tor_relay);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::try_connect_to_daemon()
|
||||
|
|
@ -658,6 +660,34 @@ void simple_wallet::on_message(i_wallet2_callback::message_severity severity, co
|
|||
message_writer(color, true, std::string()) << m;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
void simple_wallet::on_tor_status_change(const std::string& state)
|
||||
{
|
||||
std::string human_message;
|
||||
if (state == TOR_LIB_STATE_INITIALIZING)
|
||||
human_message = "Initializing...";
|
||||
else if (state == TOR_LIB_STATE_DOWNLOADING_CONSENSUS)
|
||||
human_message = "Downloading consensus...";
|
||||
else if (state == TOR_LIB_STATE_MAKING_TUNNEL_A)
|
||||
human_message = "Building tunnel to A...";
|
||||
else if (state == TOR_LIB_STATE_MAKING_TUNNEL_B)
|
||||
human_message = "Building tunnel to B...";
|
||||
else if (state == TOR_LIB_STATE_CREATING_STREAM)
|
||||
human_message = "Creating stream...";
|
||||
else if (state == TOR_LIB_STATE_SUCCESS)
|
||||
human_message = "Successfully created stream";
|
||||
else if (state == TOR_LIB_STATE_FAILED)
|
||||
human_message = "Failed created stream";
|
||||
else if (state == WALLET_LIB_STATE_SENDING)
|
||||
human_message = "Sending transaction...";
|
||||
else if (state == WALLET_LIB_SENT_SUCCESS)
|
||||
human_message = "Successfully sent!";
|
||||
else if (state == WALLET_LIB_SEND_FAILED)
|
||||
human_message = "Sending failed";
|
||||
|
||||
|
||||
message_writer(epee::log_space::console_color_yellow, true, std::string("[TOR]: ")) << human_message;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::refresh(const std::vector<std::string>& args)
|
||||
{
|
||||
if (m_offline_mode)
|
||||
|
|
@ -1710,6 +1740,21 @@ bool simple_wallet::submit_transfer(const std::vector<std::string> &args)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::tor_enable(const std::vector<std::string> &args)
|
||||
{
|
||||
success_msg_writer(true) << "TOR relaying enabled";
|
||||
m_wallet->set_disable_tor_relay(false);
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::tor_disable(const std::vector<std::string> &args)
|
||||
{
|
||||
m_wallet->set_disable_tor_relay(true);
|
||||
success_msg_writer(true) << "TOR relaying disabled";
|
||||
return true;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool simple_wallet::sweep_below(const std::vector<std::string> &args)
|
||||
{
|
||||
|
|
@ -1960,6 +2005,8 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_params, command_line::arg_log_level);
|
||||
command_line::add_arg(desc_params, arg_scan_for_wallet);
|
||||
command_line::add_arg(desc_params, arg_addr_to_compare);
|
||||
command_line::add_arg(desc_params, arg_disable_tor_relay);
|
||||
|
||||
|
||||
tools::wallet_rpc_server::init_options(desc_params);
|
||||
|
||||
|
|
@ -2154,6 +2201,13 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
else // if(command_line::has_arg(vm, tools::wallet_rpc_server::arg_rpc_bind_port))
|
||||
{
|
||||
if (command_line::get_arg(vm, arg_do_pos_mining))
|
||||
{
|
||||
// PoS mining can be turned on only in RPC server mode, please provide --rpc-bind-port to make this
|
||||
fail_msg_writer() << "PoS mining can be turned on only in RPC server mode, please provide --rpc-bind-port=PORT_NO to enable staking in simplewallet";
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
//runs wallet with console interface
|
||||
sw->set_offline_mode(offline_mode);
|
||||
r = sw->init(vm);
|
||||
|
|
|
|||
|
|
@ -86,6 +86,8 @@ namespace currency
|
|||
bool sign_transfer(const std::vector<std::string> &args);
|
||||
bool submit_transfer(const std::vector<std::string> &args);
|
||||
bool sweep_below(const std::vector<std::string> &args);
|
||||
bool tor_enable(const std::vector<std::string> &args);
|
||||
bool tor_disable(const std::vector<std::string> &args);
|
||||
bool validate_wrap_status(uint64_t amount);
|
||||
|
||||
bool get_alias_from_daemon(const std::string& alias_name, currency::extra_alias_entry_base& ai);
|
||||
|
|
@ -98,6 +100,7 @@ namespace currency
|
|||
virtual void on_new_block(uint64_t height, const currency::block& block) override;
|
||||
virtual void on_transfer2(const tools::wallet_public::wallet_transfer_info& wti, uint64_t balance, uint64_t unlocked_balance, uint64_t total_mined) override;
|
||||
virtual void on_message(i_wallet2_callback::message_severity severity, const std::string& m) override;
|
||||
virtual void on_tor_status_change(const std::string& state) override;
|
||||
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
|
@ -166,6 +169,7 @@ namespace currency
|
|||
bool m_do_not_set_date;
|
||||
bool m_do_pos_mining;
|
||||
bool m_offline_mode;
|
||||
bool m_disable_tor;
|
||||
std::string m_restore_wallet;
|
||||
|
||||
epee::console_handlers_binder m_cmd_binder;
|
||||
|
|
|
|||
|
|
@ -39,25 +39,25 @@ namespace
|
|||
#define VDIFF_RETARGET_SHARES_COUNT 12 // enforce retargeting if this many shares are received (high performace in terms of current difficulty)
|
||||
#define VDIFF_VARIANCE_PERCENT_DEFAULT 25 // %
|
||||
|
||||
const command_line::arg_descriptor<bool> arg_stratum = {"stratum", "Stratum server: enable" };
|
||||
const command_line::arg_descriptor<std::string> arg_stratum_bind_ip = {"stratum-bind-ip", "Stratum server: IP to bind", STRATUM_BIND_IP_DEFAULT };
|
||||
const command_line::arg_descriptor<std::string> arg_stratum_bind_port = {"stratum-bind-port", "Stratum server: port to listen at", std::to_string(STRATUM_DEFAULT_PORT) };
|
||||
const command_line::arg_descriptor<size_t> arg_stratum_threads = {"stratum-threads-count", "Stratum server: number of server threads", STRATUM_THREADS_COUNT_DEFAULT };
|
||||
const command_line::arg_descriptor<bool> arg_stratum ("stratum", "Stratum server: enable" );
|
||||
const command_line::arg_descriptor<std::string> arg_stratum_bind_ip ("stratum-bind-ip", "Stratum server: IP to bind", STRATUM_BIND_IP_DEFAULT );
|
||||
const command_line::arg_descriptor<std::string> arg_stratum_bind_port ("stratum-bind-port", "Stratum server: port to listen at", std::to_string(STRATUM_DEFAULT_PORT) );
|
||||
const command_line::arg_descriptor<size_t> arg_stratum_threads ("stratum-threads-count", "Stratum server: number of server threads", STRATUM_THREADS_COUNT_DEFAULT );
|
||||
const command_line::arg_descriptor<std::string> arg_stratum_miner_address = {"stratum-miner-address", "Stratum server: miner address. All workers"
|
||||
" will mine to this address. If not set here, ALL workers should use the very same wallet address as username."
|
||||
" If set here - they're allowed to log in with username '" WORKER_ALLOWED_USERNAME "' instead of address.", "", true };
|
||||
" If set here - they're allowed to log in with username '" WORKER_ALLOWED_USERNAME "' instead of address."};
|
||||
|
||||
const command_line::arg_descriptor<size_t> arg_stratum_block_template_update_period = {"stratum-template-update-period",
|
||||
"Stratum server: if there are no new blocks, update block template this often (sec.)", STRATUM_BLOCK_TEMPLATE_UPD_PERIOD_DEFAULT };
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_hr_print_interval = {"stratum-hr-print-interval", "Stratum server: how often to print hashrate stats (sec.)", STRATUM_TOTAL_HR_PRINT_INTERVAL_S_DEFAULT };
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_hr_print_interval ("stratum-hr-print-interval", "Stratum server: how often to print hashrate stats (sec.)", STRATUM_TOTAL_HR_PRINT_INTERVAL_S_DEFAULT );
|
||||
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_target_min = {"stratum-vdiff-target-min", "Stratum server: minimum worker difficulty", VDIFF_TARGET_MIN_DEFAULT };
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_target_max = {"stratum-vdiff-target-max", "Stratum server: maximum worker difficulty", VDIFF_TARGET_MAX_DEFAULT };
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_target_time = {"stratum-vdiff-target-time", "Stratum server: target time per share (i.e. try to get one share per this many seconds)", VDIFF_TARGET_TIME_DEFAULT };
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_retarget_time = {"stratum-vdiff-retarget-time", "Stratum server: check to see if we should retarget this often (sec.)", VDIFF_RETARGET_TIME_DEFAULT };
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_retarget_shares = {"stratum-vdiff-retarget-shares", "Stratum server: enforce retargeting if got this many shares", VDIFF_RETARGET_SHARES_COUNT };
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_variance_percent = {"stratum-vdiff-variance-percent", "Stratum server: allow average time to very this % from target without retarget", VDIFF_VARIANCE_PERCENT_DEFAULT };
|
||||
const command_line::arg_descriptor<bool> arg_stratum_always_online = { "stratum-always-online", "Stratum server consider the core being synchronized regardless of online status, useful for debugging with --offline-mode" };
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_target_min ("stratum-vdiff-target-min", "Stratum server: minimum worker difficulty", VDIFF_TARGET_MIN_DEFAULT );
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_target_max ("stratum-vdiff-target-max", "Stratum server: maximum worker difficulty", VDIFF_TARGET_MAX_DEFAULT );
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_target_time ("stratum-vdiff-target-time", "Stratum server: target time per share (i.e. try to get one share per this many seconds)", VDIFF_TARGET_TIME_DEFAULT );
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_retarget_time ("stratum-vdiff-retarget-time", "Stratum server: check to see if we should retarget this often (sec.)", VDIFF_RETARGET_TIME_DEFAULT );
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_retarget_shares ("stratum-vdiff-retarget-shares", "Stratum server: enforce retargeting if got this many shares", VDIFF_RETARGET_SHARES_COUNT );
|
||||
const command_line::arg_descriptor<uint64_t> arg_stratum_vdiff_variance_percent ("stratum-vdiff-variance-percent", "Stratum server: allow average time to very this % from target without retarget", VDIFF_VARIANCE_PERCENT_DEFAULT );
|
||||
const command_line::arg_descriptor<bool> arg_stratum_always_online ( "stratum-always-online", "Stratum server consider the core being synchronized regardless of online status, useful for debugging with --offline-mode" );
|
||||
|
||||
//==============================================================================================================================
|
||||
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@
|
|||
#define BUILD_COMMIT_ID "@VERSION@"
|
||||
|
||||
#define PROJECT_MAJOR_VERSION "1"
|
||||
#define PROJECT_MINOR_VERSION "4"
|
||||
#define PROJECT_REVISION "1"
|
||||
#define PROJECT_MINOR_VERSION "5"
|
||||
#define PROJECT_REVISION "0"
|
||||
#define PROJECT_VERSION PROJECT_MAJOR_VERSION "." PROJECT_MINOR_VERSION "." PROJECT_REVISION
|
||||
|
||||
#define PROJECT_VERSION_BUILD_NO 142
|
||||
#define PROJECT_VERSION_BUILD_NO 143
|
||||
#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 "]"
|
||||
|
|
|
|||
|
|
@ -600,6 +600,18 @@ public:
|
|||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct current_action_status
|
||||
{
|
||||
uint64_t wallet_id;
|
||||
std::string status;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(wallet_id)
|
||||
KV_SERIALIZE(status)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
|
||||
struct wallet_sync_status_info
|
||||
{
|
||||
bool is_daemon_connected;
|
||||
|
|
@ -742,9 +754,11 @@ public:
|
|||
struct gui_options
|
||||
{
|
||||
bool use_debug_mode;
|
||||
bool disable_price_fetch;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(use_debug_mode)
|
||||
KV_SERIALIZE(disable_price_fetch)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
|
||||
};
|
||||
|
|
@ -828,6 +842,7 @@ public:
|
|||
virtual bool pos_block_found(const currency::block& block_found){ return true; }
|
||||
virtual bool money_transfer_cancel(const transfer_event_info& wsi){ return true; }
|
||||
virtual bool set_options(const gui_options& opt){ return true; }
|
||||
virtual bool update_tor_status(const current_action_status & opt) { return true; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
#include <iostream>
|
||||
#include <boost/utility/value_init.hpp>
|
||||
#include "include_base_utils.h"
|
||||
#include "net/levin_client.h"
|
||||
using namespace epee;
|
||||
|
||||
#include "string_coding.h"
|
||||
|
|
@ -30,8 +31,16 @@ using namespace epee;
|
|||
#include "version.h"
|
||||
#include "common/encryption_filter.h"
|
||||
#include "crypto/bitcoin/sha256_helper.h"
|
||||
#ifndef DISABLE_TOR
|
||||
#include "common/tor_helper.h"
|
||||
#endif
|
||||
|
||||
#include "storages/levin_abstract_invoke2.h"
|
||||
|
||||
using namespace currency;
|
||||
|
||||
|
||||
|
||||
#define MINIMUM_REQUIRED_WALLET_FREE_SPACE_BYTES (100*1024*1024) // 100 MB
|
||||
|
||||
#undef LOG_DEFAULT_CHANNEL
|
||||
|
|
@ -53,7 +62,8 @@ namespace tools
|
|||
m_minimum_height(WALLET_MINIMUM_HEIGHT_UNSET_CONST),
|
||||
m_pos_mint_packing_size(WALLET_DEFAULT_POS_MINT_PACKING_SIZE),
|
||||
m_current_wallet_file_size(0),
|
||||
m_use_deffered_global_outputs(false)
|
||||
m_use_deffered_global_outputs(false),
|
||||
m_disable_tor_relay(false)
|
||||
{
|
||||
m_core_runtime_config = currency::get_default_core_runtime_config();
|
||||
}
|
||||
|
|
@ -394,8 +404,9 @@ void wallet2::process_new_transaction(const currency::transaction& tx, uint64_t
|
|||
if (it != m_active_htlcs.end())
|
||||
{
|
||||
transfer_details& td = m_transfers[it->second];
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_ptx_wallet_info->m_tx.vout.size() > td.m_internal_output_index, "Internal error: wrong index in m_transfers");
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target.type() == typeid(txout_htlc), "Internal error: wrong index in m_transfers");
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(td.m_ptx_wallet_info->m_tx.vout.size() > td.m_internal_output_index, "Internal error: wrong td.m_internal_output_index: " << td.m_internal_output_index);
|
||||
const boost::typeindex::type_info& ti = td.m_ptx_wallet_info->m_tx.vout[td.m_internal_output_index].target.type();
|
||||
WLT_THROW_IF_FALSE_WALLET_INT_ERR_EX(ti == typeid(txout_htlc), "Internal error: wrong type of output's target: " << ti.name());
|
||||
//input spend active htlc
|
||||
m_transfers[it->second].m_spent_height = height;
|
||||
transfer_details_extra_option_htlc_info& tdeohi = get_or_add_field_to_variant_vector<transfer_details_extra_option_htlc_info>(td.varian_options);
|
||||
|
|
@ -3275,7 +3286,7 @@ void wallet2::wti_to_csv_entry(std::ostream& ss, const wallet_public::wallet_tra
|
|||
ss << (wti.is_income ? "in" : "out") << ",";
|
||||
ss << (wti.is_service ? "[SERVICE]" : "") << (wti.is_mixing ? "[MIXINS]" : "") << (wti.is_mining ? "[MINING]" : "") << ",";
|
||||
ss << wti.tx_type << ",";
|
||||
ss << wti.fee << ENDL;
|
||||
ss << print_money(wti.fee) << ENDL;
|
||||
};
|
||||
|
||||
void wallet2::wti_to_txt_line(std::ostream& ss, const wallet_public::wallet_transfer_info& wti, size_t index)
|
||||
|
|
@ -3316,7 +3327,7 @@ void wallet2::export_transaction_history(std::ostream& ss, const std::string& fo
|
|||
else
|
||||
{
|
||||
//csv by default
|
||||
ss << "N, Date, Amount, Comment, Address, ID, Height, Unlock timestamp, Tx size, Alias, In/Out, Flags, Type, Fee" << ENDL;
|
||||
ss << "N, Date, Amount, Comment, Address, ID, Height, Unlock timestamp, Tx size, Alias, PaymentID, In/Out, Flags, Type, Fee" << ENDL;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -3326,6 +3337,7 @@ void wallet2::export_transaction_history(std::ostream& ss, const std::string& fo
|
|||
if (currency::is_coinbase(wti.tx))
|
||||
return true;
|
||||
}
|
||||
wti.fee = currency::get_tx_fee(wti.tx);
|
||||
cb(ss, wti, index);
|
||||
return true;
|
||||
});
|
||||
|
|
@ -4581,22 +4593,76 @@ uint64_t wallet2::get_needed_money(uint64_t fee, const std::vector<currency::tx_
|
|||
}
|
||||
return needed_money;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
void wallet2::set_disable_tor_relay(bool disable)
|
||||
{
|
||||
m_disable_tor_relay = disable;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
void wallet2::notify_state_change(const std::string& state_code, const std::string& details)
|
||||
{
|
||||
m_wcallback->on_tor_status_change(state_code);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
void wallet2::send_transaction_to_network(const transaction& tx)
|
||||
{
|
||||
COMMAND_RPC_SEND_RAW_TX::request req;
|
||||
req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(tx));
|
||||
COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp;
|
||||
bool r = m_core_proxy->call_COMMAND_RPC_SEND_RAW_TX(req, daemon_send_resp);
|
||||
THROW_IF_TRUE_WALLET_EX(!r, error::no_connection_to_daemon, "sendrawtransaction");
|
||||
THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status == API_RETURN_CODE_BUSY, error::daemon_busy, "sendrawtransaction");
|
||||
THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status == API_RETURN_CODE_DISCONNECTED, error::no_connection_to_daemon, "Transfer attempt while daemon offline");
|
||||
THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status != API_RETURN_CODE_OK, error::tx_rejected, tx, daemon_send_resp.status);
|
||||
#ifndef DISABLE_TOR
|
||||
if (!m_disable_tor_relay)
|
||||
{
|
||||
//TODO check that core synchronized
|
||||
//epee::net_utils::levin_client2 p2p_client;
|
||||
|
||||
//make few attempts
|
||||
tools::levin_over_tor_client p2p_client;
|
||||
p2p_client.get_transport().set_notifier(this);
|
||||
bool succeseful_sent = false;
|
||||
for (size_t i = 0; i != 3; i++)
|
||||
{
|
||||
if (!p2p_client.connect("144.76.183.143", 2121, 10000))
|
||||
{
|
||||
continue;//THROW_IF_FALSE_WALLET_EX(false, error::no_connection_to_daemon, "Failed to connect to TOR node");
|
||||
}
|
||||
|
||||
|
||||
currency::NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request p2p_req = AUTO_VAL_INIT(p2p_req);
|
||||
currency::NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::response p2p_rsp = AUTO_VAL_INIT(p2p_rsp);
|
||||
p2p_req.txs.push_back(t_serializable_object_to_blob(tx));
|
||||
this->notify_state_change(WALLET_LIB_STATE_SENDING);
|
||||
epee::net_utils::invoke_remote_command2(NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::ID, p2p_req, p2p_rsp, p2p_client);
|
||||
p2p_client.disconnect();
|
||||
if (p2p_rsp.code == API_RETURN_CODE_OK)
|
||||
{
|
||||
this->notify_state_change(WALLET_LIB_SENT_SUCCESS);
|
||||
succeseful_sent = true;
|
||||
break;
|
||||
}
|
||||
this->notify_state_change(WALLET_LIB_SEND_FAILED);
|
||||
//checking if transaction got relayed to other nodes and
|
||||
//return;
|
||||
}
|
||||
if (!succeseful_sent)
|
||||
{
|
||||
this->notify_state_change(WALLET_LIB_SEND_FAILED);
|
||||
THROW_IF_FALSE_WALLET_EX(succeseful_sent, error::no_connection_to_daemon, "Faile to build TOR stream");
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif //
|
||||
{
|
||||
COMMAND_RPC_SEND_RAW_TX::request req;
|
||||
req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(tx));
|
||||
COMMAND_RPC_SEND_RAW_TX::response daemon_send_resp;
|
||||
bool r = m_core_proxy->call_COMMAND_RPC_SEND_RAW_TX(req, daemon_send_resp);
|
||||
THROW_IF_TRUE_WALLET_EX(!r, error::no_connection_to_daemon, "sendrawtransaction");
|
||||
THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status == API_RETURN_CODE_BUSY, error::daemon_busy, "sendrawtransaction");
|
||||
THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status == API_RETURN_CODE_DISCONNECTED, error::no_connection_to_daemon, "Transfer attempt while daemon offline");
|
||||
THROW_IF_TRUE_WALLET_EX(daemon_send_resp.status != API_RETURN_CODE_OK, error::tx_rejected, tx, daemon_send_resp.status);
|
||||
|
||||
WLT_LOG_L2("transaction " << get_transaction_hash(tx) << " generated ok and sent to daemon:" << ENDL << currency::obj_to_json_str(tx));
|
||||
}
|
||||
|
||||
WLT_LOG_L2("transaction " << get_transaction_hash(tx) << " generated ok and sent to daemon:" << ENDL << currency::obj_to_json_str(tx));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------------
|
||||
void wallet2::add_sent_tx_detailed_info(const transaction& tx,
|
||||
const std::vector<currency::tx_destination_entry>& destinations,
|
||||
const std::vector<uint64_t>& selected_transfers)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "currency_core/bc_escrow_service.h"
|
||||
#include "common/pod_array_file_container.h"
|
||||
#include "wallet_chain_shortener.h"
|
||||
#include "tor-connect/torlib/tor_lib_iface.h"
|
||||
|
||||
|
||||
#define WALLET_DEFAULT_TX_SPENDABLE_AGE 10
|
||||
|
|
@ -121,6 +122,7 @@ namespace tools
|
|||
virtual void on_sync_progress(const uint64_t& /*percents*/) {}
|
||||
virtual void on_transfer_canceled(const wallet_public::wallet_transfer_info& wti) {}
|
||||
virtual void on_message(message_severity /*severity*/, const std::string& /*m*/) {}
|
||||
virtual void on_tor_status_change(const std::string& state) {}
|
||||
};
|
||||
|
||||
struct tx_dust_policy
|
||||
|
|
@ -338,7 +340,7 @@ namespace tools
|
|||
// END_SERIALIZE()
|
||||
// };
|
||||
|
||||
class wallet2
|
||||
class wallet2: public tools::tor::t_transport_state_notifier
|
||||
{
|
||||
wallet2(const wallet2&) = delete;
|
||||
public:
|
||||
|
|
@ -861,6 +863,7 @@ namespace tools
|
|||
uint64_t get_wallet_file_size()const;
|
||||
void set_use_deffered_global_outputs(bool use);
|
||||
construct_tx_param get_default_construct_tx_param_inital();
|
||||
void set_disable_tor_relay(bool disable);
|
||||
|
||||
void export_transaction_history(std::ostream& ss, const std::string& format, bool include_pos_transactions = true);
|
||||
|
||||
|
|
@ -876,6 +879,11 @@ namespace tools
|
|||
bool check_htlc_redeemed(const crypto::hash& htlc_tx_id, std::string& origin, crypto::hash& redeem_tx_id);
|
||||
private:
|
||||
|
||||
// -------- t_transport_state_notifier ------------------------------------------------
|
||||
virtual void notify_state_change(const std::string& state_code, const std::string& details = std::string());
|
||||
// ------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
void add_transfers_to_expiration_list(const std::vector<uint64_t>& selected_transfers, uint64_t expiration, uint64_t change_amount, const crypto::hash& related_tx_id);
|
||||
void remove_transfer_from_expiration_list(uint64_t transfer_index);
|
||||
void load_keys(const std::string& keys_file_name, const std::string& password, uint64_t file_signature, keys_file_data& kf_data);
|
||||
|
|
@ -1060,6 +1068,7 @@ private:
|
|||
|
||||
mutable uint64_t m_current_wallet_file_size;
|
||||
bool m_use_deffered_global_outputs;
|
||||
bool m_disable_tor_relay;
|
||||
//this needed to access wallets state in coretests, for creating abnormal blocks and tranmsactions
|
||||
friend class test_generator;
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@
|
|||
|
||||
// TODO: get rid of all these types, leave only wallet_error with a string message and string/enum error designator
|
||||
|
||||
|
||||
#define WALLET_LIB_STATE_SENDING "STATE_SENDING"
|
||||
#define WALLET_LIB_SENT_SUCCESS "STATE_SENT_SUCCESS"
|
||||
#define WALLET_LIB_SEND_FAILED "STATE_SEND_FAILED"
|
||||
|
||||
|
||||
namespace tools
|
||||
{
|
||||
namespace error
|
||||
|
|
@ -64,7 +70,10 @@ namespace tools
|
|||
std::string to_string() const
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << m_loc << ':' << typeid(*this).name() << "[" << m_error_code << "]: " << Base::what();
|
||||
ss << m_loc << ':' << typeid(*this).name();
|
||||
if (!m_error_code.empty())
|
||||
ss << "[" << m_error_code << "]";
|
||||
ss << ": " << Base::what();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ public:
|
|||
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_public::wallet_transfer_info& wti) {}
|
||||
virtual void on_tor_status_change(size_t wallet_id, const std::string& state) {}
|
||||
};
|
||||
|
||||
struct i_wallet_to_i_backend_adapter: public tools::i_wallet2_callback
|
||||
|
|
@ -39,6 +40,11 @@ struct i_wallet_to_i_backend_adapter: public tools::i_wallet2_callback
|
|||
virtual void on_transfer_canceled(const tools::wallet_public::wallet_transfer_info& wti) {
|
||||
m_pbackend->on_transfer_canceled(m_wallet_id, wti);
|
||||
}
|
||||
virtual void on_tor_status_change(const std::string& state)
|
||||
{
|
||||
m_pbackend->on_tor_status_change(m_wallet_id, state);
|
||||
}
|
||||
|
||||
private:
|
||||
i_backend_wallet_callback* m_pbackend;
|
||||
size_t m_wallet_id;
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ using namespace epee;
|
|||
namespace tools
|
||||
{
|
||||
//-----------------------------------------------------------------------------------
|
||||
const command_line::arg_descriptor<std::string> wallet_rpc_server::arg_rpc_bind_port = {"rpc-bind-port", "Starts wallet as rpc server for wallet operations, sets bind port for server", "", true};
|
||||
const command_line::arg_descriptor<std::string> wallet_rpc_server::arg_rpc_bind_ip = {"rpc-bind-ip", "Specify ip to bind rpc server", "127.0.0.1"};
|
||||
const command_line::arg_descriptor<std::string> wallet_rpc_server::arg_miner_text_info = { "miner-text-info", "Wallet password", "", true };
|
||||
const command_line::arg_descriptor<bool> wallet_rpc_server::arg_deaf_mode = { "deaf", "Put wallet into 'deaf' mode make it ignore any rpc commands(usable for safe PoS mining)", false, true };
|
||||
const command_line::arg_descriptor<std::string> wallet_rpc_server::arg_rpc_bind_port ("rpc-bind-port", "Starts wallet as rpc server for wallet operations, sets bind port for server");
|
||||
const command_line::arg_descriptor<std::string> wallet_rpc_server::arg_rpc_bind_ip ("rpc-bind-ip", "Specify ip to bind rpc server", "127.0.0.1");
|
||||
const command_line::arg_descriptor<std::string> wallet_rpc_server::arg_miner_text_info ( "miner-text-info", "Wallet password");
|
||||
const command_line::arg_descriptor<bool> wallet_rpc_server::arg_deaf_mode ( "deaf", "Put wallet into 'deaf' mode make it ignore any rpc commands(usable for safe PoS mining)");
|
||||
|
||||
void wallet_rpc_server::init_options(boost::program_options::options_description& desc)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -51,15 +51,16 @@
|
|||
#define HTTP_PROXY_TIMEOUT 2000
|
||||
#define HTTP_PROXY_ATTEMPTS_COUNT 1
|
||||
|
||||
const command_line::arg_descriptor<bool> arg_alloc_win_console = { "alloc-win-console", "Allocates debug console with GUI", false };
|
||||
const command_line::arg_descriptor<std::string> arg_html_folder = { "html-path", "Manually set GUI html folder path", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_xcode_stub = { "-NSDocumentRevisionsDebugMode", "Substitute for xcode bug", "", true };
|
||||
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 };
|
||||
const command_line::arg_descriptor<bool> arg_alloc_win_console ( "alloc-win-console", "Allocates debug console with GUI", false );
|
||||
const command_line::arg_descriptor<std::string> arg_html_folder ( "html-path", "Manually set GUI html folder path");
|
||||
const command_line::arg_descriptor<std::string> arg_xcode_stub ( "-NSDocumentRevisionsDebugMode", "Substitute for xcode bug");
|
||||
const command_line::arg_descriptor<bool> arg_enable_gui_debug_mode ( "gui-debug-mode", "Enable debug options in GUI");
|
||||
const command_line::arg_descriptor<uint32_t> arg_qt_remote_debugging_port ( "remote-debugging-port", "Specify port for Qt remote debugging");
|
||||
const command_line::arg_descriptor<std::string> arg_remote_node ( "remote-node", "Switch GUI to work with remote node instead of local daemon");
|
||||
const command_line::arg_descriptor<bool> arg_enable_qt_logs ( "enable-qt-logs", "Forward Qt log messages into main log");
|
||||
const command_line::arg_descriptor<bool> arg_disable_logs_init("disable-logs-init", "Disable log initialization in GUI");
|
||||
const command_line::arg_descriptor<std::string> arg_qt_dev_tools = { "qt-dev-tools", "Enable main web page inspection with Chromium DevTools, <vertical|horizontal>[,scale], e.g. \"horizontal,1.3\"", "", false };
|
||||
const command_line::arg_descriptor<std::string> arg_qt_dev_tools ( "qt-dev-tools", "Enable main web page inspection with Chromium DevTools, <vertical|horizontal>[,scale], e.g. \"horizontal,1.3\"", "");
|
||||
const command_line::arg_descriptor<bool> arg_disable_price_fetch("gui-disable-price-fetch", "Disable price fetching in UI(for privacy matter)");
|
||||
|
||||
wallets_manager::wallets_manager():m_pview(&m_view_stub),
|
||||
m_stop_singal_sent(false),
|
||||
|
|
@ -81,7 +82,8 @@ wallets_manager::wallets_manager():m_pview(&m_view_stub),
|
|||
m_is_pos_allowed(false),
|
||||
m_qt_logs_enbaled(false),
|
||||
m_dont_save_wallet_at_stop(false),
|
||||
m_use_deffered_global_outputs(false)
|
||||
m_use_deffered_global_outputs(false),
|
||||
m_use_tor(true)
|
||||
{
|
||||
#ifndef MOBILE_WALLET_BUILD
|
||||
m_offers_service.set_disabled(true);
|
||||
|
|
@ -162,17 +164,17 @@ bool wallets_manager::init_command_line(int argc, char* argv[], std::string& fai
|
|||
command_line::add_arg(desc_cmd_only, command_line::arg_version);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_os_version);
|
||||
// tools::get_default_data_dir() can't be called during static initialization
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_data_dir, tools::get_default_data_dir());
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_data_dir, tools::get_default_data_dir());
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_stop_after_height);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_config_file);
|
||||
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_log_dir);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_log_level);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_console);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_show_details);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_show_details);
|
||||
command_line::add_arg(desc_cmd_sett, arg_alloc_win_console);
|
||||
command_line::add_arg(desc_cmd_sett, arg_html_folder);
|
||||
command_line::add_arg(desc_cmd_sett, arg_xcode_stub);
|
||||
command_line::add_arg(desc_cmd_only, arg_xcode_stub);
|
||||
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);
|
||||
|
|
@ -183,8 +185,10 @@ bool wallets_manager::init_command_line(int argc, char* argv[], std::string& fai
|
|||
command_line::add_arg(desc_cmd_sett, command_line::arg_force_predownload);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_validate_predownload);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_predownload_link);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_deeplink);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_deeplink);
|
||||
command_line::add_arg(desc_cmd_sett, command_line::arg_disable_ntp);
|
||||
command_line::add_arg(desc_cmd_sett, arg_disable_price_fetch);
|
||||
|
||||
|
||||
|
||||
#ifndef MOBILE_WALLET_BUILD
|
||||
|
|
@ -298,10 +302,15 @@ bool wallets_manager::init(view::i_view* pview_handler)
|
|||
{
|
||||
log_space::log_singletone::get_set_log_detalisation_level(true, command_line::get_arg(m_vm, command_line::arg_log_level));
|
||||
}
|
||||
if (command_line::has_arg(m_vm, arg_enable_gui_debug_mode))
|
||||
if (command_line::has_arg(m_vm, arg_enable_gui_debug_mode) && command_line::get_arg(m_vm, arg_enable_gui_debug_mode))
|
||||
{
|
||||
m_ui_opt.use_debug_mode = true;
|
||||
}
|
||||
if (command_line::has_arg(m_vm, arg_disable_price_fetch) && command_line::get_arg(m_vm, arg_disable_price_fetch))
|
||||
{
|
||||
m_ui_opt.disable_price_fetch = true;
|
||||
}
|
||||
|
||||
|
||||
//set up logging options
|
||||
std::string log_dir;
|
||||
|
|
@ -791,6 +800,8 @@ void wallets_manager::init_wallet_entry(wallet_vs_options& wo, uint64_t id)
|
|||
m_wallet_log_prefixes.resize(id + 1);
|
||||
m_wallet_log_prefixes[id] = std::string("[") + epee::string_tools::num_to_string_fast(id) + ":" + wo.w->get()->get_account().get_public_address_str().substr(0, 6) + "] ";
|
||||
}
|
||||
|
||||
wo.w->get()->set_disable_tor_relay(!m_use_tor);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1842,6 +1853,17 @@ void wallets_manager::on_pos_block_found(size_t wallet_id, const currency::block
|
|||
{
|
||||
m_pview->pos_block_found(b);
|
||||
}
|
||||
bool wallets_manager::set_use_tor(bool use_tor)
|
||||
{
|
||||
m_use_tor = use_tor;
|
||||
SHARED_CRITICAL_REGION_LOCAL(m_wallets_lock);
|
||||
for (auto& w : m_wallets)
|
||||
{
|
||||
w.second.w->get()->set_disable_tor_relay(!m_use_tor);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void wallets_manager::on_sync_progress(size_t wallet_id, const uint64_t& percents)
|
||||
{
|
||||
// do not lock m_wallets_lock down the callstack! It will lead to a deadlock, because wallet locked_object is aready locked
|
||||
|
|
@ -1871,6 +1893,13 @@ void wallets_manager::on_transfer_canceled(size_t wallet_id, const tools::wallet
|
|||
}
|
||||
m_pview->money_transfer_cancel(tei);
|
||||
}
|
||||
|
||||
void wallets_manager::on_tor_status_change(size_t wallet_id, const std::string& state)
|
||||
{
|
||||
view::current_action_status tsu = { wallet_id , state };
|
||||
m_pview->update_tor_status(tsu);
|
||||
}
|
||||
|
||||
void wallets_manager::wallet_vs_options::worker_func()
|
||||
{
|
||||
LOG_PRINT_GREEN("[WALLET_HANDLER] Wallet handler thread started, addr: " << w->get()->get_account().get_public_address_str(), LOG_LEVEL_0);
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ public:
|
|||
bool is_qt_logs_enabled() const { return m_qt_logs_enbaled; }
|
||||
std::string get_qt_dev_tools_option() const { return m_qt_dev_tools; }
|
||||
void set_use_deffered_global_outputs(bool use) { m_use_deffered_global_outputs = use; }
|
||||
|
||||
bool set_use_tor(bool use_tor);
|
||||
private:
|
||||
void main_worker(const po::variables_map& vm);
|
||||
bool init_local_daemon();
|
||||
|
|
@ -187,6 +187,8 @@ private:
|
|||
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_public::wallet_transfer_info& wti);
|
||||
virtual void on_tor_status_change(size_t wallet_id, const std::string& state);
|
||||
|
||||
|
||||
std::thread m_main_worker_thread;
|
||||
|
||||
|
|
@ -224,6 +226,7 @@ private:
|
|||
bool m_qt_logs_enbaled;
|
||||
std::string m_qt_dev_tools;
|
||||
std::atomic<bool> m_is_pos_allowed;
|
||||
std::atomic<bool> m_use_tor;
|
||||
|
||||
|
||||
std::map<size_t, wallet_vs_options> m_wallets;
|
||||
|
|
|
|||
|
|
@ -927,6 +927,7 @@ bool test_generator::init_test_wallet(const currency::account_base& account, con
|
|||
w->assign_account(account);
|
||||
w->set_genesis(genesis_hash);
|
||||
w->set_core_proxy(m_wallet_test_core_proxy);
|
||||
w->set_disable_tor_relay(true);
|
||||
|
||||
result = w;
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -997,10 +997,10 @@ void append_vector_by_another_vector(U& dst, const V& src)
|
|||
|
||||
|
||||
#define REGISTER_CALLBACK(CB_NAME, CLBACK) \
|
||||
register_callback(CB_NAME, boost::bind(&CLBACK, this, _1, _2, _3));
|
||||
register_callback(CB_NAME, boost::bind(&CLBACK, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3))
|
||||
|
||||
#define REGISTER_CALLBACK_METHOD(CLASS, METHOD) \
|
||||
register_callback(#METHOD, boost::bind(&CLASS::METHOD, this, _1, _2, _3));
|
||||
register_callback(#METHOD, boost::bind(&CLASS::METHOD, this, boost::placeholders::_1, boost::placeholders::_2, boost::placeholders::_3))
|
||||
|
||||
#define MAKE_GENESIS_BLOCK(VEC_EVENTS, BLK_NAME, MINER_ACC, TS) \
|
||||
test_generator generator; \
|
||||
|
|
|
|||
|
|
@ -21,13 +21,13 @@ namespace po = boost::program_options;
|
|||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<std::string> arg_test_data_path = {"test-data-path", "", ""};
|
||||
const command_line::arg_descriptor<bool> arg_generate_test_data = {"generate-test-data", ""};
|
||||
const command_line::arg_descriptor<bool> arg_play_test_data = {"play-test-data", ""};
|
||||
const command_line::arg_descriptor<bool> arg_generate_and_play_test_data = {"generate-and-play-test-data", ""};
|
||||
const command_line::arg_descriptor<bool> arg_test_transactions = {"test-transactions", ""};
|
||||
const command_line::arg_descriptor<std::string> arg_run_single_test = {"run-single-test", "" };
|
||||
const command_line::arg_descriptor<bool> arg_enable_debug_asserts = {"enable-debug-asserts", "" };
|
||||
const command_line::arg_descriptor<std::string> arg_test_data_path ("test-data-path", "", "");
|
||||
const command_line::arg_descriptor<bool> arg_generate_test_data ("generate-test-data", "");
|
||||
const command_line::arg_descriptor<bool> arg_play_test_data ("play-test-data", "");
|
||||
const command_line::arg_descriptor<bool> arg_generate_and_play_test_data ("generate-and-play-test-data", "");
|
||||
const command_line::arg_descriptor<bool> arg_test_transactions ("test-transactions", "");
|
||||
const command_line::arg_descriptor<std::string> arg_run_single_test ("run-single-test", "" );
|
||||
const command_line::arg_descriptor<bool> arg_enable_debug_asserts ("enable-debug-asserts", "" );
|
||||
|
||||
boost::program_options::variables_map g_vm;
|
||||
}
|
||||
|
|
@ -106,7 +106,7 @@ bool generate_and_play(const char* const genclass_name)
|
|||
std::vector<test_event_entry> events;
|
||||
bool generated = false;
|
||||
bool result = true;
|
||||
std::cout << concolor::bright_white << "#TEST# " << genclass_name << concolor::normal << std::endl;
|
||||
std::cout << ENDL << concolor::bright_white << "#TEST# " << genclass_name << concolor::normal << ENDL << ENDL;
|
||||
LOG_PRINT2("get_object_blobsize.log", "#TEST# " << genclass_name, LOG_LEVEL_3);
|
||||
|
||||
if (!clean_data_directory())
|
||||
|
|
@ -667,6 +667,7 @@ int main(int argc, char* argv[])
|
|||
command_line::add_arg(desc_options, arg_enable_debug_asserts);
|
||||
command_line::add_arg(desc_options, command_line::arg_data_dir, std::string("."));
|
||||
command_line::add_arg(desc_options, command_line::arg_stop_after_height);
|
||||
command_line::add_arg(desc_options, command_line::arg_disable_ntp);
|
||||
|
||||
currency::core::init_options(desc_options);
|
||||
tools::db::db_backend_selector::init_options(desc_options);
|
||||
|
|
|
|||
|
|
@ -922,6 +922,7 @@ bool hard_fork_2_awo_wallets_basic_test<before_hf_2>::c1(currency::core& c, size
|
|||
bob_wlt_awo->load(bob_wo_filename, "");
|
||||
bob_wlt_awo->set_core_runtime_config(c.get_blockchain_storage().get_core_runtime_config());
|
||||
bob_wlt_awo->set_core_proxy(m_core_proxy);
|
||||
bob_wlt_awo->set_disable_tor_relay(true);
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt, MK_TEST_COINS(110), false, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE), false, "");
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt, 0, false, CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 1 + WALLET_DEFAULT_TX_SPENDABLE_AGE), false, "");
|
||||
|
|
@ -1054,6 +1055,7 @@ bool hard_fork_2_awo_wallets_basic_test<before_hf_2>::c1(currency::core& c, size
|
|||
bob_wlt_awo_restored->restore(bob_wo_restored_filename, "", bob_tracking_seed, true, "");
|
||||
bob_wlt_awo_restored->set_core_runtime_config(c.get_blockchain_storage().get_core_runtime_config());
|
||||
bob_wlt_awo_restored->set_core_proxy(m_core_proxy);
|
||||
bob_wlt_awo_restored->set_disable_tor_relay(true);
|
||||
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob_awo_restored", bob_wlt_awo_restored, MK_TEST_COINS(3), false), false, "");
|
||||
|
||||
|
|
@ -1092,6 +1094,7 @@ bool hard_fork_2_awo_wallets_basic_test<before_hf_2>::c1(currency::core& c, size
|
|||
bob_wlt_non_auditable->restore(bob_non_auditable_filename, "", bob_seed, false, "");
|
||||
bob_wlt_non_auditable->set_core_runtime_config(c.get_blockchain_storage().get_core_runtime_config());
|
||||
bob_wlt_non_auditable->set_core_proxy(m_core_proxy);
|
||||
bob_wlt_non_auditable->set_disable_tor_relay(true);
|
||||
|
||||
// the balance for non-auditable wallet should be greather by mix_attr!=1 output (7 test coins + 1 left from prev step)
|
||||
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob_non_auditable", bob_wlt_non_auditable, MK_TEST_COINS(8), false), false, "");
|
||||
|
|
|
|||
|
|
@ -6,52 +6,6 @@
|
|||
#include "chaingen.h"
|
||||
#include "random_helper.h"
|
||||
|
||||
random_state_test_restorer::random_state_test_restorer()
|
||||
{
|
||||
crypto::random_prng_get_state(&m_state, sizeof m_state);
|
||||
}
|
||||
|
||||
random_state_test_restorer::~random_state_test_restorer()
|
||||
{
|
||||
crypto::random_prng_set_state(&m_state, sizeof m_state);
|
||||
}
|
||||
|
||||
void random_state_test_restorer::reset_random(uint64_t seed /* = 0 */)
|
||||
{
|
||||
crypto::random_prng_initialize_with_seed(seed);
|
||||
}
|
||||
|
||||
std::string get_random_text(size_t len)
|
||||
{
|
||||
static const char text_chars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "~!@#$%^&*()-=_+\\/?,.<>|{}[]`';:\" ";
|
||||
static const uint8_t text_chars_size = sizeof text_chars - 1; // to avoid '\0'
|
||||
std::string result;
|
||||
|
||||
if (len < 1)
|
||||
return result;
|
||||
|
||||
result.resize(len);
|
||||
char* result_buf = &result[0];
|
||||
uint8_t* rnd_indices = new uint8_t[len];
|
||||
crypto::generate_random_bytes(len, rnd_indices);
|
||||
|
||||
size_t n = len / 4, i;
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
result_buf[4 * i + 0] = text_chars[rnd_indices[4 * i + 0] % text_chars_size];
|
||||
result_buf[4 * i + 1] = text_chars[rnd_indices[4 * i + 1] % text_chars_size];
|
||||
result_buf[4 * i + 2] = text_chars[rnd_indices[4 * i + 2] % text_chars_size];
|
||||
result_buf[4 * i + 3] = text_chars[rnd_indices[4 * i + 3] % text_chars_size];
|
||||
}
|
||||
for (size_t j = i * 4; j < len; ++j)
|
||||
{
|
||||
result_buf[j] = text_chars[rnd_indices[j] % text_chars_size];
|
||||
}
|
||||
|
||||
delete[] rnd_indices;
|
||||
return result;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
bool random_state_manupulation_test()
|
||||
|
|
|
|||
|
|
@ -13,17 +13,56 @@
|
|||
// Remebers random state at ctor, restores it at dtor
|
||||
struct random_state_test_restorer
|
||||
{
|
||||
random_state_test_restorer();
|
||||
~random_state_test_restorer();
|
||||
static void reset_random(uint64_t seed = 0);
|
||||
|
||||
random_state_test_restorer()
|
||||
{
|
||||
crypto::random_prng_get_state(&m_state, sizeof m_state);
|
||||
}
|
||||
~random_state_test_restorer()
|
||||
{
|
||||
crypto::random_prng_set_state(&m_state, sizeof m_state);
|
||||
}
|
||||
static void reset_random(uint64_t seed = 0)
|
||||
{
|
||||
crypto::random_prng_initialize_with_seed(seed);
|
||||
}
|
||||
private:
|
||||
uint8_t m_state[RANDOM_STATE_SIZE];
|
||||
};
|
||||
|
||||
#endif // #ifdef USE_INSECURE_RANDOM_RPNG_ROUTINES
|
||||
|
||||
std::string get_random_text(size_t len);
|
||||
inline std::string get_random_text(size_t len)
|
||||
{
|
||||
{
|
||||
static const char text_chars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "~!@#$%^&*()-=_+\\/?,.<>|{}[]`';:\" ";
|
||||
static const uint8_t text_chars_size = sizeof text_chars - 1; // to avoid '\0'
|
||||
std::string result;
|
||||
|
||||
if (len < 1)
|
||||
return result;
|
||||
|
||||
result.resize(len);
|
||||
char* result_buf = &result[0];
|
||||
uint8_t* rnd_indices = new uint8_t[len];
|
||||
crypto::generate_random_bytes(len, rnd_indices);
|
||||
|
||||
size_t n = len / 4, i;
|
||||
for (i = 0; i < n; ++i)
|
||||
{
|
||||
result_buf[4 * i + 0] = text_chars[rnd_indices[4 * i + 0] % text_chars_size];
|
||||
result_buf[4 * i + 1] = text_chars[rnd_indices[4 * i + 1] % text_chars_size];
|
||||
result_buf[4 * i + 2] = text_chars[rnd_indices[4 * i + 2] % text_chars_size];
|
||||
result_buf[4 * i + 3] = text_chars[rnd_indices[4 * i + 3] % text_chars_size];
|
||||
}
|
||||
for (size_t j = i * 4; j < len; ++j)
|
||||
{
|
||||
result_buf[j] = text_chars[rnd_indices[j] % text_chars_size];
|
||||
}
|
||||
|
||||
delete[] rnd_indices;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
bool random_state_manupulation_test();
|
||||
bool random_evenness_test();
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public:
|
|||
//----------------- i_currency_protocol ---------------------------------------
|
||||
virtual bool relay_block(currency::NOTIFY_NEW_BLOCK::request& /*arg*/, currency::currency_connection_context& /*exclude_context*/) override { return false; }
|
||||
|
||||
virtual bool relay_transactions(currency::NOTIFY_NEW_TRANSACTIONS::request& arg, currency::currency_connection_context& /*exclude_context*/) override
|
||||
virtual bool relay_transactions(currency::NOTIFY_OR_INVOKE_NEW_TRANSACTIONS::request& arg, currency::currency_connection_context& /*exclude_context*/) override
|
||||
{
|
||||
if (m_core_listener)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -83,6 +83,7 @@ std::shared_ptr<tools::wallet2> wallet_test::init_playtime_test_wallet(const std
|
|||
w->assign_account(acc);
|
||||
w->set_genesis(genesis_hash);
|
||||
w->set_core_proxy(m_core_proxy);
|
||||
w->set_disable_tor_relay(true);
|
||||
return w;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "crypto/crypto-sugar.h"
|
||||
#include "crypto/range_proofs.h"
|
||||
#include "../core_tests/random_helper.h"
|
||||
|
||||
using namespace crypto;
|
||||
|
||||
|
|
@ -473,6 +474,7 @@ uint64_t hash_64(const void* data, size_t size)
|
|||
#define ASSERT_TRUE(expr) CHECK_AND_ASSERT_MES(expr, false, "This is not true: " #expr)
|
||||
#define ASSERT_FALSE(expr) CHECK_AND_ASSERT_MES((expr) == false, false, "This is not false: " #expr)
|
||||
#define ASSERT_EQ(a, b) CHECK_AND_ASSERT_MES(a == b, false, #a " != " #b "\n " << a << " != " << b)
|
||||
#define ASSERT_NEQ(a, b) CHECK_AND_ASSERT_MES(a != b, false, #a " == " #b "\n " << a)
|
||||
|
||||
typedef bool(*bool_func_ptr_t)();
|
||||
static std::vector<std::pair<std::string, bool_func_ptr_t>> g_tests;
|
||||
|
|
@ -487,6 +489,7 @@ struct test_keeper_t
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
#include "L2S.h"
|
||||
#include "crypto_tests_range_proofs.h"
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
|
@ -1803,6 +1806,68 @@ TEST(crypto, point_is_zero)
|
|||
}
|
||||
|
||||
|
||||
TEST(crypto, sc_get_bit)
|
||||
{
|
||||
static_assert(sizeof(scalar_t) * 8 == 256, "size missmatch");
|
||||
|
||||
scalar_t v = 0; // all bits are 0
|
||||
for (size_t n = 0; n < 256; ++n)
|
||||
{
|
||||
ASSERT_EQ(v.get_bit(static_cast<uint8_t>(n)), false);
|
||||
}
|
||||
|
||||
v = c_scalar_256m1; // all bits are 1
|
||||
for (size_t n = 0; n < 256; ++n)
|
||||
{
|
||||
ASSERT_EQ(v.get_bit(static_cast<uint8_t>(n)), true);
|
||||
}
|
||||
|
||||
// bits out of the [0; 255] range supposed to be always 0
|
||||
for (size_t n = 256; n < 2048; ++n)
|
||||
{
|
||||
ASSERT_EQ(v.get_bit(static_cast<uint8_t>(n)), false);
|
||||
}
|
||||
|
||||
// check random value
|
||||
const scalar_t x = scalar_t::random();
|
||||
for (size_t n = 0; n < 64; ++n)
|
||||
ASSERT_EQ(x.get_bit(static_cast<uint8_t>(n)), ((x.m_u64[0] & (1ull << (n - 0))) != 0));
|
||||
for (size_t n = 64; n < 128; ++n)
|
||||
ASSERT_EQ(x.get_bit(static_cast<uint8_t>(n)), ((x.m_u64[1] & (1ull << (n - 64))) != 0));
|
||||
for (size_t n = 128; n < 192; ++n)
|
||||
ASSERT_EQ(x.get_bit(static_cast<uint8_t>(n)), ((x.m_u64[2] & (1ull << (n - 128))) != 0));
|
||||
for (size_t n = 192; n < 256; ++n)
|
||||
ASSERT_EQ(x.get_bit(static_cast<uint8_t>(n)), ((x.m_u64[3] & (1ull << (n - 192))) != 0));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TEST(crypto, sc_set_bit_clear_bit)
|
||||
{
|
||||
static_assert(sizeof(scalar_t) * 8 == 256, "size missmatch");
|
||||
|
||||
// check random value
|
||||
const scalar_t x = scalar_t::random();
|
||||
scalar_t y = scalar_t::random();
|
||||
ASSERT_NEQ(x, y);
|
||||
|
||||
uint8_t i = 0;
|
||||
do
|
||||
{
|
||||
if (x.get_bit(i))
|
||||
y.set_bit(i);
|
||||
else
|
||||
y.clear_bit(i);
|
||||
} while(++i != 0);
|
||||
|
||||
ASSERT_EQ(x, y);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// test's runner
|
||||
//
|
||||
|
|
@ -1844,7 +1909,7 @@ int crypto_tests(const std::string& cmd_line_param)
|
|||
epee::log_space::log_singletone::get_default_log_folder().c_str());
|
||||
|
||||
|
||||
|
||||
size_t filtered_tests_count = 0;
|
||||
std::vector<size_t> failed_tests;
|
||||
for (size_t i = 0; i < g_tests.size(); ++i)
|
||||
{
|
||||
|
|
@ -1853,6 +1918,8 @@ int crypto_tests(const std::string& cmd_line_param)
|
|||
if (!wildcard_match(cmd_line_param.c_str(), test.first.c_str()))
|
||||
continue;
|
||||
|
||||
++filtered_tests_count;
|
||||
|
||||
LOG_PRINT(" " << std::setw(40) << std::left << test.first << " >", LOG_LEVEL_0);
|
||||
TIME_MEASURE_START(runtime);
|
||||
bool r = false;
|
||||
|
|
@ -1882,10 +1949,16 @@ int crypto_tests(const std::string& cmd_line_param)
|
|||
}
|
||||
}
|
||||
|
||||
if (filtered_tests_count == 0)
|
||||
{
|
||||
LOG_PRINT_YELLOW(ENDL << ENDL << "No tests were selected, check the filter mask", LOG_LEVEL_0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (failed_tests.empty())
|
||||
{
|
||||
LOG_PRINT_GREEN(ENDL, LOG_LEVEL_0);
|
||||
LOG_PRINT_GREEN("All tests passed okay", LOG_LEVEL_0);
|
||||
LOG_PRINT_GREEN(filtered_tests_count << " tests passed okay", LOG_LEVEL_0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
261
tests/functional_tests/crypto_tests_range_proofs.h
Normal file
261
tests/functional_tests/crypto_tests_range_proofs.h
Normal file
|
|
@ -0,0 +1,261 @@
|
|||
// Copyright (c) 2021 Zano Project (https://zano.org/)
|
||||
// Copyright (c) 2021 sowle (val@zano.org, crypto.sowle@gmail.com)
|
||||
// Distributed under the MIT/X11 software license, see the accompanying
|
||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
|
||||
#pragma once
|
||||
|
||||
// calc weighted inner pruduct of av and bv w.r.t. Vandermonde vector (y, y^2, y^3, ..., y^n)
|
||||
// <a, ((y, y^2, y^3, ...) o b)> = <c, (y, y^2, y^3, ...)> (<> -- standard inner product, o - componen-wise)
|
||||
// s.a. BP+ paper, pages 3-4
|
||||
bool wip_vandermonde(const scalar_vec_t& av, const scalar_vec_t& bv, const scalar_t& y, scalar_t& result)
|
||||
{
|
||||
result = 0;
|
||||
size_t n = av.size();
|
||||
if (n != bv.size())
|
||||
return false;
|
||||
|
||||
scalar_t y_powered = 1;
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
y_powered *= y;
|
||||
result.assign_muladd(av[i] * bv[i], y_powered, result); // result.a += av[i] * bv[i] * y_powered;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static_assert(constexpr_floor_log2(0) == 0, "");
|
||||
static_assert(constexpr_floor_log2(1) == 0, "");
|
||||
static_assert(constexpr_floor_log2(2) == 1, "");
|
||||
static_assert(constexpr_floor_log2(3) == 1, "");
|
||||
static_assert(constexpr_floor_log2(4) == 2, "");
|
||||
static_assert(constexpr_floor_log2(5) == 2, "");
|
||||
static_assert(constexpr_floor_log2(64) == 6, "");
|
||||
static_assert(constexpr_floor_log2(100) == 6, "");
|
||||
static_assert(constexpr_floor_log2(100000000) == 26, "");
|
||||
static_assert(constexpr_floor_log2(0x7fffffffffffffff) == 62, "");
|
||||
static_assert(constexpr_floor_log2(SIZE_MAX) == 63, "");
|
||||
|
||||
static_assert(constexpr_ceil_log2(0) == 0, "");
|
||||
static_assert(constexpr_ceil_log2(1) == 0, "");
|
||||
static_assert(constexpr_ceil_log2(2) == 1, "");
|
||||
static_assert(constexpr_ceil_log2(3) == 2, "");
|
||||
static_assert(constexpr_ceil_log2(4) == 2, "");
|
||||
static_assert(constexpr_ceil_log2(5) == 3, "");
|
||||
static_assert(constexpr_ceil_log2(64) == 6, "");
|
||||
static_assert(constexpr_ceil_log2(100) == 7, "");
|
||||
static_assert(constexpr_ceil_log2(100000000) == 27, "");
|
||||
static_assert(constexpr_ceil_log2(0x7fffffffffffffff) == 63, "");
|
||||
static_assert(constexpr_ceil_log2(SIZE_MAX) == 64, "");
|
||||
|
||||
|
||||
TEST(bpp, basics)
|
||||
{
|
||||
/*
|
||||
srand(0);
|
||||
for (size_t i = 0; i < 10; ++i)
|
||||
std::cout << scalar_t::random().to_string_as_secret_key() << ENDL;
|
||||
*/
|
||||
|
||||
point_t H = hash_helper_t::hp(c_point_G);
|
||||
ASSERT_EQ(H, c_point_H);
|
||||
std::string h2_hash_str("h2_generator");
|
||||
point_t H2 = hash_helper_t::hp(h2_hash_str.c_str(), h2_hash_str.size());
|
||||
ASSERT_EQ(H2, c_point_H2);
|
||||
LOG_PRINT_L0("c_point_0 = " << c_point_0 << " = { " << c_point_0.to_hex_comma_separated_uint64_str() << " }");
|
||||
LOG_PRINT_L0("Zano G = " << c_point_G << " = { " << c_point_G.to_hex_comma_separated_bytes_str() << " }");
|
||||
LOG_PRINT_L0("Zano H = " << H << " = { " << H.to_hex_comma_separated_uint64_str() << " }");
|
||||
LOG_PRINT_L0("Zano H2 = " << H2 << " = { " << H2.to_hex_comma_separated_uint64_str() << " }");
|
||||
|
||||
scalar_vec_t values = { 5 };
|
||||
scalar_vec_t masks = { 0 };
|
||||
bpp_signature bpp_sig;
|
||||
std::vector<point_t> commitments;
|
||||
uint8_t err = 0;
|
||||
|
||||
bool r = bpp_gen<bpp_crypto_trait_zano<>>(values, masks, bpp_sig, commitments, &err);
|
||||
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TEST(bpp, two)
|
||||
{
|
||||
std::vector<bpp_signature> signatures_vector;
|
||||
signatures_vector.reserve(10);
|
||||
std::vector<std::vector<point_t>> commitments_vector;
|
||||
commitments_vector.reserve(10);
|
||||
|
||||
std::vector<bpp_sig_commit_ref_t> sigs;
|
||||
uint8_t err = 0;
|
||||
bool r = false;
|
||||
|
||||
{
|
||||
signatures_vector.resize(signatures_vector.size() + 1);
|
||||
bpp_signature &bpp_sig = signatures_vector.back();
|
||||
commitments_vector.resize(commitments_vector.size() + 1);
|
||||
std::vector<point_t>& commitments = commitments_vector.back();
|
||||
|
||||
scalar_vec_t values = { 5 };
|
||||
scalar_vec_t masks = { scalar_t(77 + 256 * 77) };
|
||||
|
||||
r = bpp_gen<bpp_crypto_trait_zano<>>(values, masks, bpp_sig, commitments, &err);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
sigs.emplace_back(bpp_sig, commitments);
|
||||
}
|
||||
|
||||
{
|
||||
signatures_vector.resize(signatures_vector.size() + 1);
|
||||
bpp_signature &bpp_sig = signatures_vector.back();
|
||||
commitments_vector.resize(commitments_vector.size() + 1);
|
||||
std::vector<point_t>& commitments = commitments_vector.back();
|
||||
|
||||
scalar_vec_t values = { 5, 700, 8 };
|
||||
scalar_vec_t masks = { scalar_t(77 + 256 * 77), scalar_t(255), scalar_t(17) };
|
||||
|
||||
r = bpp_gen<bpp_crypto_trait_zano<>>(values, masks, bpp_sig, commitments, &err);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
sigs.emplace_back(bpp_sig, commitments);
|
||||
}
|
||||
|
||||
r = bpp_verify<bpp_crypto_trait_zano<>>(sigs, &err);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
TEST(bpp, power_256)
|
||||
{
|
||||
// make sure the BPP implementation supports values up to 2^256 (Zarcanum needs 2^170 since b_a < z * 2^64, where z = 2^106, s.a. Zarcanum preprint, page 21)
|
||||
std::vector<bpp_signature> signatures_vector;
|
||||
signatures_vector.reserve(10);
|
||||
std::vector<std::vector<point_t>> commitments_vector;
|
||||
commitments_vector.reserve(10);
|
||||
|
||||
std::vector<bpp_sig_commit_ref_t> sig_ñommit_refs;
|
||||
uint8_t err = 0;
|
||||
bool r = false;
|
||||
|
||||
{
|
||||
signatures_vector.resize(signatures_vector.size() + 1);
|
||||
bpp_signature &bpp_sig = signatures_vector.back();
|
||||
commitments_vector.resize(commitments_vector.size() + 1);
|
||||
std::vector<point_t>& commitments = commitments_vector.back();
|
||||
|
||||
scalar_vec_t values = { 5 };
|
||||
scalar_vec_t masks = { scalar_t(77 + 256 * 77) };
|
||||
|
||||
r = bpp_gen<bpp_crypto_trait_zano<>>(values, masks, bpp_sig, commitments, &err);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
sig_ñommit_refs.emplace_back(bpp_sig, commitments);
|
||||
}
|
||||
|
||||
{
|
||||
signatures_vector.resize(signatures_vector.size() + 1);
|
||||
bpp_signature &bpp_sig = signatures_vector.back();
|
||||
commitments_vector.resize(commitments_vector.size() + 1);
|
||||
std::vector<point_t>& commitments = commitments_vector.back();
|
||||
|
||||
scalar_vec_t values = { 5, 700, 8 };
|
||||
scalar_vec_t masks = { scalar_t(77 + 256 * 77), scalar_t(255), scalar_t(17) };
|
||||
|
||||
r = bpp_gen<bpp_crypto_trait_zano<>>(values, masks, bpp_sig, commitments, &err);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
sig_ñommit_refs.emplace_back(bpp_sig, commitments);
|
||||
}
|
||||
|
||||
r = bpp_verify<bpp_crypto_trait_zano<>>(sig_ñommit_refs, &err);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// tests for Bulletproofs+ Extended (with double-blinded commitments)
|
||||
//
|
||||
|
||||
|
||||
TEST(bppe, basics)
|
||||
{
|
||||
/*
|
||||
srand(0);
|
||||
for (size_t i = 0; i < 10; ++i)
|
||||
std::cout << scalar_t::random().to_string_as_secret_key() << ENDL;
|
||||
*/
|
||||
|
||||
scalar_vec_t values = { 5 };
|
||||
scalar_vec_t masks = { 0 };
|
||||
scalar_vec_t masks_2 = { 0 };
|
||||
|
||||
bppe_signature bppe_sig;
|
||||
std::vector<point_t> commitments;
|
||||
uint8_t err = 0;
|
||||
|
||||
bool r = bppe_gen<bpp_crypto_trait_zano<>>(values, masks, masks_2, bppe_sig, commitments, &err);
|
||||
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TEST(bppe, two)
|
||||
{
|
||||
std::vector<bppe_signature> signatures_vector;
|
||||
signatures_vector.reserve(10);
|
||||
std::vector<std::vector<point_t>> commitments_vector;
|
||||
commitments_vector.reserve(10);
|
||||
|
||||
std::vector<bppe_sig_commit_ref_t> sigs;
|
||||
uint8_t err = 0;
|
||||
bool r = false;
|
||||
|
||||
{
|
||||
signatures_vector.resize(signatures_vector.size() + 1);
|
||||
bppe_signature &bppe_sig = signatures_vector.back();
|
||||
commitments_vector.resize(commitments_vector.size() + 1);
|
||||
std::vector<point_t>& commitments = commitments_vector.back();
|
||||
|
||||
scalar_vec_t values = { 5 };
|
||||
scalar_vec_t masks = { scalar_t(77 + 256 * 77) };
|
||||
scalar_vec_t masks2 = { scalar_t(88 + 256 * 88) };
|
||||
|
||||
r = bppe_gen<bpp_crypto_trait_zano<>>(values, masks, masks2, bppe_sig, commitments, &err);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
sigs.emplace_back(bppe_sig, commitments);
|
||||
}
|
||||
|
||||
{
|
||||
signatures_vector.resize(signatures_vector.size() + 1);
|
||||
bppe_signature &bppe_sig = signatures_vector.back();
|
||||
commitments_vector.resize(commitments_vector.size() + 1);
|
||||
std::vector<point_t>& commitments = commitments_vector.back();
|
||||
|
||||
scalar_vec_t values = { 5, 700, 8 };
|
||||
scalar_vec_t masks = { scalar_t(77 + 256 * 77), scalar_t(255), scalar_t(17) };
|
||||
scalar_vec_t masks2 = { scalar_t(88 + 256 * 88), scalar_t(1), scalar_t(19) };
|
||||
|
||||
r = bppe_gen<bpp_crypto_trait_zano<>>(values, masks, masks2, bppe_sig, commitments, &err);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
sigs.emplace_back(bppe_sig, commitments);
|
||||
}
|
||||
|
||||
r = bppe_verify<bpp_crypto_trait_zano<>>(sigs, &err);
|
||||
ASSERT_TRUE(r);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -23,40 +23,40 @@ using namespace epee;
|
|||
|
||||
namespace po = boost::program_options;
|
||||
|
||||
const command_line::arg_descriptor<std::string> arg_test_core_prepare_and_store = { "prepare-and-store-events-to-file", "", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_test_core_load_and_replay = { "load-and-replay-events-from-file", "", "", true };
|
||||
const command_line::arg_descriptor<std::string> arg_test_core_prepare_and_store ( "prepare-and-store-events-to-file", "");
|
||||
const command_line::arg_descriptor<std::string> arg_test_core_load_and_replay ( "load-and-replay-events-from-file", "");
|
||||
|
||||
namespace
|
||||
{
|
||||
const command_line::arg_descriptor<bool> arg_test_transactions_flow = {"test-transactions-flow", ""};
|
||||
const command_line::arg_descriptor<bool> arg_test_miniupnp = {"test-miniupnp", ""};
|
||||
const command_line::arg_descriptor<bool> arg_test_core_concurrency = {"test-core-concurrency", ""};
|
||||
const command_line::arg_descriptor<bool> arg_test_transactions_flow ("test-transactions-flow", "");
|
||||
const command_line::arg_descriptor<bool> arg_test_miniupnp ("test-miniupnp", "");
|
||||
const command_line::arg_descriptor<bool> arg_test_core_concurrency ("test-core-concurrency", "");
|
||||
|
||||
const command_line::arg_descriptor<std::string> arg_working_folder = {"working-folder", "", "."};
|
||||
const command_line::arg_descriptor<std::string> arg_source_wallet = {"source-wallet", "", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_dest_wallet = {"dest-wallet", "", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_source_wallet_pass = {"source-wallet-pass", "", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_dest_wallet_pass = {"dest-wallet-pass", "", "", true};
|
||||
const command_line::arg_descriptor<std::string> arg_working_folder ("working-folder", "", ".");
|
||||
const command_line::arg_descriptor<std::string> arg_source_wallet ("source-wallet", "");
|
||||
const command_line::arg_descriptor<std::string> arg_dest_wallet ("dest-wallet", "");
|
||||
const command_line::arg_descriptor<std::string> arg_source_wallet_pass ("source-wallet-pass", "");
|
||||
const command_line::arg_descriptor<std::string> arg_dest_wallet_pass ("dest-wallet-pass", "");
|
||||
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_addr_a = {"daemon-addr-a", "", "127.0.0.1:8080"};
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_addr_b = {"daemon-addr-b", "", "127.0.0.1:8082"};
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_addr_a ("daemon-addr-a", "", "127.0.0.1:8080");
|
||||
const command_line::arg_descriptor<std::string> arg_daemon_addr_b ("daemon-addr-b", "", "127.0.0.1:8082");
|
||||
|
||||
const command_line::arg_descriptor<uint64_t> arg_transfer_amount = {"transfer-amount", "", 60000000000000};
|
||||
const command_line::arg_descriptor<size_t> arg_mix_in_factor = {"mix-in-factor", "", 10};
|
||||
const command_line::arg_descriptor<size_t> arg_tx_count = {"tx-count", "", 100};
|
||||
const command_line::arg_descriptor<size_t> arg_tx_per_second = {"tx-per-second", "", 20};
|
||||
const command_line::arg_descriptor<size_t> arg_test_repeat_count = {"test-repeat-count", "", 1};
|
||||
const command_line::arg_descriptor<size_t> arg_action = {"action", "", 0 };
|
||||
const command_line::arg_descriptor<size_t> arg_max_tx_in_pool = { "max-tx-in-pool", "", 10000 };
|
||||
const command_line::arg_descriptor<std::string> arg_data_dir = {"data-dir", "Specify data directory", "."};
|
||||
const command_line::arg_descriptor<size_t> arg_wthreads = {"wthreads", "number of writing threads to run", 1};
|
||||
const command_line::arg_descriptor<size_t> arg_rthreads = {"rthreads", "number of reading threads to run", 1};
|
||||
const command_line::arg_descriptor<size_t> arg_blocks = {"blocks", "number of blocks to generate", 250};
|
||||
const command_line::arg_descriptor<size_t> arg_generate_test_genesis_json = { "generate-test-genesis-json", "generates test genesis json, specify amount of accounts", 0, true };
|
||||
const command_line::arg_descriptor<bool> arg_deadlock_guard = { "test-deadlock-guard", "Do deadlock guard test", false, true };
|
||||
const command_line::arg_descriptor<std::string> arg_difficulty_analysis = { "difficulty-analysis", "Do difficulty analysis", "", true };
|
||||
const command_line::arg_descriptor<bool> arg_test_plain_wallet = { "test-plainwallet", "Do testing of plain wallet interface", false, true };
|
||||
const command_line::arg_descriptor<std::string> arg_crypto_tests = { "crypto-tests", "Run experimental crypto tests", "", true };
|
||||
const command_line::arg_descriptor<uint64_t> arg_transfer_amount ("transfer-amount", "", 60000000000000);
|
||||
const command_line::arg_descriptor<size_t> arg_mix_in_factor ("mix-in-factor", "", 10);
|
||||
const command_line::arg_descriptor<size_t> arg_tx_count ("tx-count", "", 100);
|
||||
const command_line::arg_descriptor<size_t> arg_tx_per_second ("tx-per-second", "", 20);
|
||||
const command_line::arg_descriptor<size_t> arg_test_repeat_count ("test-repeat-count", "", 1);
|
||||
const command_line::arg_descriptor<size_t> arg_action ("action", "", 0 );
|
||||
const command_line::arg_descriptor<size_t> arg_max_tx_in_pool ( "max-tx-in-pool", "", 10000 );
|
||||
const command_line::arg_descriptor<std::string> arg_data_dir ("data-dir", "Specify data directory", ".");
|
||||
const command_line::arg_descriptor<size_t> arg_wthreads ("wthreads", "number of writing threads to run", 1);
|
||||
const command_line::arg_descriptor<size_t> arg_rthreads ("rthreads", "number of reading threads to run", 1);
|
||||
const command_line::arg_descriptor<size_t> arg_blocks ("blocks", "number of blocks to generate", 250);
|
||||
const command_line::arg_descriptor<size_t> arg_generate_test_genesis_json ( "generate-test-genesis-json", "generates test genesis json, specify amount of accounts");
|
||||
const command_line::arg_descriptor<bool> arg_deadlock_guard ( "test-deadlock-guard", "Do deadlock guard test");
|
||||
const command_line::arg_descriptor<std::string> arg_difficulty_analysis ( "difficulty-analysis", "Do difficulty analysis");
|
||||
const command_line::arg_descriptor<bool> arg_test_plain_wallet ( "test-plainwallet", "Do testing of plain wallet interface");
|
||||
const command_line::arg_descriptor<std::string> arg_crypto_tests ( "crypto-tests", "Run experimental crypto tests");
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -66,9 +66,6 @@ int main(int argc, char* argv[])
|
|||
TRY_ENTRY();
|
||||
string_tools::set_module_name_and_folder(argv[0]);
|
||||
|
||||
uint64_t reward = 0;
|
||||
currency::get_block_reward(false, 500000, 589313, 10300000000000000, reward, 11030);
|
||||
|
||||
//set up logging options
|
||||
//log_space::get_set_log_detalisation_level(true, LOG_LEVEL_1);
|
||||
//log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2);
|
||||
|
|
|
|||
|
|
@ -3,16 +3,19 @@
|
|||
# Environment prerequisites:
|
||||
# 1) QT_PREFIX_PATH should be set to Qt libs folder
|
||||
# 2) BOOST_ROOT should be set to the root of Boost
|
||||
# 3) OPENSSL_ROOT_DIR should be set to the root of OpenSSL
|
||||
#
|
||||
# for example, place these lines to the end of your ~/.bashrc :
|
||||
#
|
||||
# export BOOST_ROOT=/home/user/boost_1_66_0
|
||||
# export QT_PREFIX_PATH=/home/user/Qt5.10.1/5.10.1/gcc_64
|
||||
# export OPENSSL_ROOT_DIR=/home/user/openssl
|
||||
|
||||
ARCHIVE_NAME_PREFIX=zano-linux-x64-
|
||||
|
||||
: "${BOOST_ROOT:?BOOST_ROOT should be set to the root of Boost, ex.: /home/user/boost_1_66_0}"
|
||||
: "${QT_PREFIX_PATH:?QT_PREFIX_PATH should be set to Qt libs folder, ex.: /home/user/Qt5.10.1/5.10.1/gcc_64}"
|
||||
: "${OPENSSL_ROOT_DIR:?OPENSSL_ROOT_DIR should be set to OpenSSL root folder, ex.: /home/user/openssl}"
|
||||
|
||||
if [ -n "$build_prefix" ]; then
|
||||
ARCHIVE_NAME_PREFIX=${ARCHIVE_NAME_PREFIX}${build_prefix}-
|
||||
|
|
@ -40,7 +43,7 @@ echo "--------------------------------------------------"
|
|||
echo "Building...."
|
||||
|
||||
rm -rf build; mkdir -p build/release; cd build/release;
|
||||
cmake $testnet_def -D STATIC=true -D ARCH=x86-64 -D BUILD_GUI=TRUE -D CMAKE_PREFIX_PATH="$QT_PREFIX_PATH" -D CMAKE_BUILD_TYPE=Release ../..
|
||||
cmake $testnet_def -D STATIC=true -D ARCH=x86-64 -D BUILD_GUI=TRUE -D OPENSSL_ROOT_DIR="$OPENSSL_ROOT_DIR" -D CMAKE_PREFIX_PATH="$QT_PREFIX_PATH" -D CMAKE_BUILD_TYPE=Release ../..
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to run cmake"
|
||||
exit 1
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ curr_path=${BASH_SOURCE%/*}
|
|||
: "${ZANO_BOOST_LIBS_PATH:?variable not set, see also macosx_build_config.command}"
|
||||
: "${ZANO_BUILD_DIR:?variable not set, see also macosx_build_config.command}"
|
||||
: "${CMAKE_OSX_SYSROOT:?CMAKE_OSX_SYSROOT should be set to macOS SDK path, e.g.: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk}"
|
||||
: "${OPENSSL_ROOT_DIR:?variable not set, see also macosx_build_config.command}"
|
||||
|
||||
ARCHIVE_NAME_PREFIX=zano-macos-x64-
|
||||
|
||||
|
|
@ -30,7 +31,7 @@ fi
|
|||
|
||||
rm -rf $ZANO_BUILD_DIR; mkdir -p "$ZANO_BUILD_DIR/release"; cd "$ZANO_BUILD_DIR/release"
|
||||
|
||||
cmake $testnet_def -D CMAKE_OSX_SYSROOT=$CMAKE_OSX_SYSROOT -D BUILD_GUI=TRUE -D CMAKE_PREFIX_PATH="$ZANO_QT_PATH/clang_64" -D CMAKE_BUILD_TYPE=Release -D BOOST_ROOT="$ZANO_BOOST_ROOT" -D BOOST_LIBRARYDIR="$ZANO_BOOST_LIBS_PATH" ../..
|
||||
cmake $testnet_def -D OPENSSL_ROOT_DIR=$OPENSSL_ROOT_DIR -D CMAKE_OSX_SYSROOT=$CMAKE_OSX_SYSROOT -D BUILD_GUI=TRUE -D CMAKE_PREFIX_PATH="$ZANO_QT_PATH/clang_64" -D CMAKE_BUILD_TYPE=Release -D BOOST_ROOT="$ZANO_BOOST_ROOT" -D BOOST_LIBRARYDIR="$ZANO_BOOST_LIBS_PATH" ../..
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to cmake"
|
||||
exit 1
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
SET QT_PREFIX_PATH=C:\dev\_sdk\Qt5.11.2\5.11.2\msvc2017_64
|
||||
SET INNOSETUP_PATH=C:\Program Files (x86)\Inno Setup 5\ISCC.exe
|
||||
SET ETC_BINARIES_PATH=C:\dev\deploy\etc-binaries
|
||||
SET BUILDS_PATH=C:\dev\deploy\zano
|
||||
call configure_local_paths.cmd
|
||||
|
||||
;; MSVC version-specific paths
|
||||
SET LOCAL_BOOST_LIB_PATH=%LOCAL_BOOST_PATH%\lib64-msvc-14.1
|
||||
SET QT_MSVC_PATH=%QT_PREFIX_PATH%\msvc2017_64
|
||||
|
||||
SET ACHIVE_NAME_PREFIX=zano-win-x64-
|
||||
SET LOCAL_BOOST_PATH=C:\dev\_sdk\boost_1_68_0
|
||||
SET LOCAL_BOOST_LIB_PATH=C:\dev\_sdk\boost_1_68_0\lib64-msvc-14.1
|
||||
SET MY_PATH=%~dp0
|
||||
SET SOURCES_PATH=%MY_PATH:~0,-7%
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ cd %SOURCES_PATH%
|
|||
rmdir build /s /q
|
||||
mkdir build
|
||||
cd build
|
||||
cmake %TESTNET_DEF% -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%" -D BUILD_GUI=TRUE -D STATIC=FALSE -G "Visual Studio 15 2017 Win64" -T host=x64 ..
|
||||
cmake %TESTNET_DEF% -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_MSVC_PATH%" -D BUILD_GUI=TRUE -D STATIC=FALSE -G "Visual Studio 15 2017 Win64" -T host=x64 ..
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
|
@ -108,7 +108,7 @@ copy /Y zanod.exe bunch
|
|||
copy /Y simplewallet.exe bunch
|
||||
copy /Y *.pdb bunch
|
||||
|
||||
%QT_PREFIX_PATH%\bin\windeployqt.exe bunch\Zano.exe
|
||||
%QT_MSVC_PATH%\bin\windeployqt.exe bunch\Zano.exe
|
||||
|
||||
cd bunch
|
||||
|
||||
|
|
|
|||
|
|
@ -1,184 +0,0 @@
|
|||
SET QT32_PREFIX_PATH=C:\Qt\Qt5.9.1\5.9.1\msvc2015
|
||||
SET INNOSETUP_PATH=C:\Program Files (x86)\Inno Setup 5\ISCC.exe
|
||||
SET ETC32_BINARIES_PATH=C:\home\deploy\etc-binaries-32
|
||||
SET BUILDS_PATH=C:\home\deploy\zano
|
||||
SET ACHIVE_NAME_PREFIX=zano-win-x32-webengine-
|
||||
SET SOURCES_PATH=C:\home\deploy\zano\src
|
||||
|
||||
SET LOCAL_BOOST_PATH_32=C:\local\boost_1_62_0
|
||||
SET LOCAL_BOOST_LIB_PATH_32=C:\local\boost_1_62_0\lib32-msvc-14.0
|
||||
|
||||
|
||||
@echo on
|
||||
|
||||
set BOOST_ROOT=%LOCAL_BOOST_PATH_32%
|
||||
set BOOST_LIBRARYDIR=%LOCAL_BOOST_LIB_PATH_32%
|
||||
|
||||
|
||||
|
||||
@echo "---------------- PREPARING BINARIES ---------------------------"
|
||||
@echo "---------------------------------------------------------------"
|
||||
|
||||
|
||||
|
||||
cd %SOURCES_PATH%
|
||||
git pull
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
@echo "---------------- BUILDING APPLICATIONS ------------------------"
|
||||
@echo "---------------------------------------------------------------"
|
||||
|
||||
|
||||
|
||||
|
||||
rmdir build /s /q
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -D CMAKE_PREFIX_PATH="%QT32_PREFIX_PATH%" -D BUILD_GUI=TRUE -D STATIC=FALSE -G "Visual Studio 14" ..
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
setLocal
|
||||
call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86_amd64
|
||||
|
||||
msbuild version.vcxproj /p:Configuration=Release /t:Build
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
msbuild src/daemon.vcxproj /p:Configuration=Release /t:Build
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
msbuild src/simplewallet.vcxproj /p:Configuration=Release /t:Build
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
msbuild src/zano.vcxproj /p:Configuration=Release /t:Build
|
||||
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
endlocal
|
||||
|
||||
@echo on
|
||||
echo "sources are built"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
cd %SOURCES_PATH%/build
|
||||
|
||||
set cmd=src\Release\simplewallet.exe --version
|
||||
FOR /F "tokens=3" %%a IN ('%cmd%') DO set version=%%a
|
||||
set version=%version:~0,-2%
|
||||
echo '%version%'
|
||||
|
||||
cd src\release
|
||||
|
||||
|
||||
|
||||
@echo on
|
||||
|
||||
|
||||
mkdir bunch
|
||||
|
||||
copy /Y zano.exe bunch
|
||||
copy /Y zanod.exe bunch
|
||||
copy /Y simplewallet.exe bunch
|
||||
copy /Y zano.exe bunch
|
||||
%QT32_PREFIX_PATH%\bin\windeployqt.exe bunch\Zano.exe
|
||||
|
||||
cd bunch
|
||||
|
||||
zip -r %BUILDS_PATH%\builds\%ACHIVE_NAME_PREFIX%%version%.zip *.*
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
@echo "Add html"
|
||||
|
||||
cd %SOURCES_PATH%\src\gui\qt-daemon\
|
||||
zip -r %BUILDS_PATH%\builds\%ACHIVE_NAME_PREFIX%%version%.zip html
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
@echo "Add runtime stuff"
|
||||
|
||||
|
||||
cd %ETC32_BINARIES_PATH%
|
||||
zip -r %BUILDS_PATH%\builds\%ACHIVE_NAME_PREFIX%%version%.zip *.*
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
cd %SOURCES_PATH%\build
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
@echo "---------------------------------------------------------------"
|
||||
@echo "-------------------Building installer--------------------------"
|
||||
@echo "---------------------------------------------------------------"
|
||||
|
||||
mkdir installer_src
|
||||
|
||||
|
||||
unzip %BUILDS_PATH%\builds\%ACHIVE_NAME_PREFIX%%version%.zip -d installer_src
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
"%INNOSETUP_PATH%" /dBinariesPath=../build/installer_src /DMyAppVersion=%version% /o%BUILDS_PATH%\builds\ /f%ACHIVE_NAME_PREFIX%%version%-installer ..\utils\setup_32.iss
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
@echo "---------------------------------------------------------------"
|
||||
@echo "---------------------------------------------------------------"
|
||||
|
||||
@echo " UPLOADING TO SERVER ...."
|
||||
|
||||
pscp -i C:\Users\Administrator\.ssh\putty.ppk %BUILDS_PATH%\builds\%ACHIVE_NAME_PREFIX%%version%-installer.exe root@95.216.11.16:/usr/share/nginx/html/%ACHIVE_NAME_PREFIX%%version%-installer.exe
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
@echo "FAILED TO UPLOAD TO SERVER"
|
||||
goto error
|
||||
)
|
||||
|
||||
echo "New build available at loaction: http://95.216.11.16/%ACHIVE_NAME_PREFIX%%version%-installer.exe"
|
||||
|
||||
|
||||
|
||||
|
||||
goto success
|
||||
|
||||
:error
|
||||
echo "BUILD FAILED"
|
||||
exit /B %ERRORLEVEL%
|
||||
|
||||
:success
|
||||
echo "BUILD SUCCESS"
|
||||
|
||||
cd ..
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
call utils/build_script_windows.bat
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
@echo "FAILED TO build_script_windows.bat"
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
call utils/build_script_windows32.bat
|
||||
IF %ERRORLEVEL% NEQ 0 (
|
||||
@echo "FAILED TO build_script_windows32.bat"
|
||||
goto error
|
||||
)
|
||||
|
||||
|
||||
|
||||
goto success
|
||||
|
||||
:error
|
||||
echo "BUILD FAILED"
|
||||
exit /B %ERRORLEVEL%
|
||||
|
||||
:success
|
||||
echo "BUILD SUCCESS"
|
||||
|
||||
|
|
@ -5,4 +5,9 @@ rem Rename to configure_local_paths.cmd and do not commit.
|
|||
rem
|
||||
|
||||
set QT_PREFIX_PATH=C:\dev\_sdk\Qt5.11.2\5.11.2
|
||||
set BOOST_ROOT=C:\dev\_sdk\boost_1_66_0
|
||||
set INNOSETUP_PATH=C:\Program Files (x86)\Inno Setup 5\ISCC.exe
|
||||
set ETC_BINARIES_PATH=C:\dev\deploy\etc-binaries
|
||||
set BUILDS_PATH=C:\dev\deploy\zano
|
||||
set LOCAL_BOOST_PATH=C:\dev\_sdk\boost_1_70_0
|
||||
set OPENSSL_ROOT_DIR=C:\dev\_sdk\OpenSSL-Win64
|
||||
set BOOST_ROOT=%LOCAL_BOOST_PATH%
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@ rem
|
|||
|
||||
set QT_PREFIX_PATH=C:\dev\_sdk\Qt5.15.2\5.15.2
|
||||
set BOOST_ROOT=C:\dev\_sdk\boost_1_76_0
|
||||
set OPENSSL_ROOT_DIR=C:\dev\_sdk\OpenSSL-Win64
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ cd ..
|
|||
@mkdir build_msvc2015_32
|
||||
cd build_msvc2015_32
|
||||
|
||||
cmake -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2015 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib32-msvc-14.0" -G "Visual Studio 14 2015" ".."
|
||||
cmake -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2015 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib32-msvc-14.0" -G "Visual Studio 14 2015" ".."
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ cd ..
|
|||
@mkdir build_msvc2013_64
|
||||
cd build_msvc2013_64
|
||||
|
||||
cmake -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2013_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-12.0" -G "Visual Studio 12 2013 Win64" ".."
|
||||
cmake -D BUILD_TESTS=TRUE -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2013_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-12.0" -G "Visual Studio 12 2013 Win64" ".."
|
||||
|
|
@ -4,4 +4,4 @@ cd ..
|
|||
@mkdir build_msvc2015_64
|
||||
cd build_msvc2015_64
|
||||
|
||||
cmake -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2015_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.0" -G "Visual Studio 14 2015 Win64" -T host=x64 ".."
|
||||
cmake -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2015_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.0" -G "Visual Studio 14 2015 Win64" -T host=x64 ".."
|
||||
|
|
@ -4,4 +4,4 @@ cd ..
|
|||
@mkdir build_msvc2017_64
|
||||
cd build_msvc2017_64
|
||||
|
||||
cmake -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2017_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.1" -G "Visual Studio 15 2017 Win64" -T host=x64 ".."
|
||||
cmake -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2017_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.1" -G "Visual Studio 15 2017 Win64" -T host=x64 ".."
|
||||
|
|
@ -4,4 +4,4 @@ cd ..
|
|||
@mkdir build_msvc2017_64_tn
|
||||
cd build_msvc2017_64_tn
|
||||
|
||||
cmake -D TESTNET=TRUE -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2017_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.1" -G "Visual Studio 15 2017 Win64" -T host=x64 ".."
|
||||
cmake -D TESTNET=TRUE -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -D CMAKE_PREFIX_PATH="%QT_PREFIX_PATH%"\msvc2017_64 -D BUILD_GUI=TRUE -D STATIC=FALSE -DBOOST_ROOT="%BOOST_ROOT%" -DBOOST_LIBRARYDIR="%BOOST_ROOT%\lib64-msvc-14.1" -G "Visual Studio 15 2017 Win64" -T host=x64 ".."
|
||||
|
|
@ -4,4 +4,4 @@ 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 ".."
|
||||
cmake -D TESTNET=TRUE -D USE_PCH=TRUE -D BUILD_TESTS=TRUE -D OPENSSL_ROOT_DIR="%OPENSSL_ROOT_DIR%" -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 ".."
|
||||
|
|
|
|||
|
|
@ -9,3 +9,4 @@ export ZANO_QT_PATH="/Users/roky/Qt5.6.0/5.6"
|
|||
export ZANO_BOOST_ROOT="/Users/roky/boost_1_60_0"
|
||||
export ZANO_BOOST_LIBS_PATH="$ZANO_BOOST_ROOT/stage/lib"
|
||||
export ZANO_BUILD_DIR="build_mac_osx_64"
|
||||
export OPENSSL_ROOT_DIR="/usr/local/opt/openssl"
|
||||
|
|
|
|||
1
utils/test_api_files/get_alias_details.json
Normal file
1
utils/test_api_files/get_alias_details.json
Normal file
|
|
@ -0,0 +1 @@
|
|||
{"method": "get_alias_details","params": {"alias": "zoidb"}}
|
||||
Loading…
Add table
Reference in a new issue