mirror of
				https://git.wownero.com/wownero/wownero.git
				synced 2024-08-15 01:03:23 +00:00 
			
		
		
		
	Merge branch '0.8.8update'
Update to newest version 0.8.8. See change log for details.
This commit is contained in:
		
						commit
						5c1b7c7224
					
				
					 50 changed files with 1179 additions and 417 deletions
				
			
		
							
								
								
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
.DS_Store
 | 
			
		||||
/build
 | 
			
		||||
/tags
 | 
			
		||||
/tags
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,8 +81,8 @@ else()
 | 
			
		|||
  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${DEBUG_FLAGS}")
 | 
			
		||||
  set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} ${RELEASE_FLAGS}")
 | 
			
		||||
  set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${RELEASE_FLAGS}")
 | 
			
		||||
  if(STATIC)
 | 
			
		||||
    set_static_flags()
 | 
			
		||||
  if(STATIC AND NOT APPLE)
 | 
			
		||||
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc -static-libstdc++")
 | 
			
		||||
  endif()
 | 
			
		||||
endif()
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ if(STATIC)
 | 
			
		|||
  set(Boost_USE_STATIC_LIBS ON)
 | 
			
		||||
  set(Boost_USE_STATIC_RUNTIME ON)
 | 
			
		||||
endif()
 | 
			
		||||
find_package(Boost 1.53 REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization atomic program_options)
 | 
			
		||||
find_package(Boost 1.53 REQUIRED COMPONENTS system filesystem thread date_time chrono regex serialization program_options)
 | 
			
		||||
if((${Boost_MAJOR_VERSION} EQUAL 1) AND (${Boost_MINOR_VERSION} EQUAL 54))
 | 
			
		||||
  message(SEND_ERROR "Boost version 1.54 is unsupported, more details are available here http://goo.gl/RrCFmA")
 | 
			
		||||
endif()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,19 @@
 | 
			
		|||
Bitmonero
 | 
			
		||||
 | 
			
		||||
Release notes 0.8.8
 | 
			
		||||
 | 
			
		||||
- JSON RPC v2.0 compatibility
 | 
			
		||||
- JSON RPC over TCP added- Further optimizations
 | 
			
		||||
- Fixed a bug with checkpoints behavior
 | 
			
		||||
- UI improvements for daemon
 | 
			
		||||
- Fixed COIN value (10^12)
 | 
			
		||||
- Raised minimum fee to 5 * (10^9)
 | 
			
		||||
- Temporary fix for block reward DoS attack
 | 
			
		||||
 | 
			
		||||
Release notes 0.8.7
 | 
			
		||||
 | 
			
		||||
- Slow hash optimizations
 | 
			
		||||
 | 
			
		||||
Release notes 0.8.6
 | 
			
		||||
 | 
			
		||||
- Simplwallet can set extra for transfers
 | 
			
		||||
| 
						 | 
				
			
			@ -21,17 +35,13 @@ Release notes 0.8.4
 | 
			
		|||
Release notes 0.8.3
 | 
			
		||||
 | 
			
		||||
- JSON RPC for wallet
 | 
			
		||||
- fixed bug with blockchain storing
 | 
			
		||||
- fixed bug with correct display of transfer's change 
 | 
			
		||||
- bug fix in simple wallet
 | 
			
		||||
- Fixed bug with blockchain storing
 | 
			
		||||
- Fixed bug with correct display of transfer's change 
 | 
			
		||||
- Bug fix in simple wallet
 | 
			
		||||
 | 
			
		||||
Release notes 0.8.2
 | 
			
		||||
 | 
			
		||||
- now wallet is still working when daemon stores blockchain and can't serve clients; 
 | 
			
		||||
- no-console option for a daemon; 
 | 
			
		||||
- fixed problem with network synchronization; 
 | 
			
		||||
- major bug fix in simple wallet. 
 | 
			
		||||
 | 
			
		||||
Release notes 0.8.1
 | 
			
		||||
 | 
			
		||||
Bytecoin project is moved to GitHub
 | 
			
		||||
- Now wallet is still working when daemon stores blockchain and can't serve clients
 | 
			
		||||
- No-console option for a daemon
 | 
			
		||||
- Fixed problem with network synchronization
 | 
			
		||||
- Major bug fix in simple wallet
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -267,23 +267,6 @@ namespace epee
 | 
			
		|||
        if(0 == command.compare("exit") || 0 == command.compare("q"))
 | 
			
		||||
        {
 | 
			
		||||
          continue_handle = false;
 | 
			
		||||
        }else if (!command.compare(0, 7, "set_log"))
 | 
			
		||||
        {
 | 
			
		||||
          //parse set_log command
 | 
			
		||||
          if(command.size() != 9)
 | 
			
		||||
          {
 | 
			
		||||
            std::cout << "wrong syntax: " << command << std::endl << "use set_log n" << std::endl;
 | 
			
		||||
            continue;
 | 
			
		||||
          }
 | 
			
		||||
          uint16_t n = 0;
 | 
			
		||||
          if(!string_tools::get_xtype_from_string(n, command.substr(8, 1)))
 | 
			
		||||
          {
 | 
			
		||||
            std::cout << "wrong syntax: " << command << std::endl << "use set_log n" << std::endl;
 | 
			
		||||
            continue;
 | 
			
		||||
          }
 | 
			
		||||
          log_space::get_set_log_detalisation_level(true, n);
 | 
			
		||||
          std::cout << "New log level set " << n;
 | 
			
		||||
          LOG_PRINT_L2("New log level set " << n);
 | 
			
		||||
        }else if (command.empty())
 | 
			
		||||
        {
 | 
			
		||||
          continue;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -52,11 +52,11 @@ PRAGMA_WARNING_DISABLE_VS(4355)
 | 
			
		|||
    typename t_protocol_handler::config_type& config, volatile uint32_t& sock_count, i_connection_filter* &pfilter)
 | 
			
		||||
                          : strand_(io_service),
 | 
			
		||||
                            socket_(io_service),
 | 
			
		||||
                            m_protocol_handler(this, config, context), 
 | 
			
		||||
                            m_want_close_connection(0), 
 | 
			
		||||
                            m_was_shutdown(0), 
 | 
			
		||||
                            m_ref_sockets_count(sock_count), 
 | 
			
		||||
                            m_pfilter(pfilter)
 | 
			
		||||
                            m_pfilter(pfilter),
 | 
			
		||||
                            m_protocol_handler(this, config, context)
 | 
			
		||||
  {
 | 
			
		||||
    boost::interprocess::ipcdetail::atomic_inc32(&m_ref_sockets_count);
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,20 +55,20 @@ namespace net_utils
 | 
			
		|||
		/************************************************************************/
 | 
			
		||||
		/*                                                                      */
 | 
			
		||||
		/************************************************************************/
 | 
			
		||||
    template<class t_connection_context  = net_utils::connection_context_base>
 | 
			
		||||
		template<class t_connection_context  = net_utils::connection_context_base>
 | 
			
		||||
		class simple_http_connection_handler
 | 
			
		||||
		{
 | 
			
		||||
		public:
 | 
			
		||||
      typedef t_connection_context connection_context;//t_connection_context net_utils::connection_context_base connection_context;
 | 
			
		||||
			typedef t_connection_context connection_context;//t_connection_context net_utils::connection_context_base connection_context;
 | 
			
		||||
			typedef http_server_config config_type;
 | 
			
		||||
 | 
			
		||||
			simple_http_connection_handler(i_service_endpoint* psnd_hndlr, config_type& config);
 | 
			
		||||
			virtual ~simple_http_connection_handler(){}
 | 
			
		||||
 | 
			
		||||
      bool release_protocol()
 | 
			
		||||
      {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
			bool release_protocol()
 | 
			
		||||
			{
 | 
			
		||||
				return true;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			virtual bool thread_init()
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -85,10 +85,6 @@ namespace net_utils
 | 
			
		|||
			}
 | 
			
		||||
			virtual bool handle_recv(const void* ptr, size_t cb);
 | 
			
		||||
			virtual bool handle_request(const http::http_request_info& query_info, http_response_info& response);
 | 
			
		||||
    
 | 
			
		||||
      
 | 
			
		||||
      //temporary here
 | 
			
		||||
      //bool parse_uri(const std::string uri, uri_content& content);
 | 
			
		||||
 | 
			
		||||
		private:
 | 
			
		||||
			enum machine_state{
 | 
			
		||||
| 
						 | 
				
			
			@ -142,34 +138,37 @@ namespace net_utils
 | 
			
		|||
			i_service_endpoint* m_psnd_hndlr; 
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
    template<class t_connection_context>
 | 
			
		||||
		template<class t_connection_context>
 | 
			
		||||
		struct i_http_server_handler
 | 
			
		||||
		{
 | 
			
		||||
			virtual ~i_http_server_handler(){}
 | 
			
		||||
			virtual bool handle_http_request(const http_request_info& query_info, http_response_info& response, t_connection_context& m_conn_context)=0;
 | 
			
		||||
      virtual bool init_server_thread(){return true;}
 | 
			
		||||
			virtual bool handle_http_request(const http_request_info& query_info,
 | 
			
		||||
																						 http_response_info& response,
 | 
			
		||||
																						 t_connection_context& m_conn_context) = 0;
 | 
			
		||||
			virtual bool init_server_thread(){return true;}
 | 
			
		||||
			virtual bool deinit_server_thread(){return true;}
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
    template<class t_connection_context>
 | 
			
		||||
		template<class t_connection_context>
 | 
			
		||||
		struct custum_handler_config: public http_server_config
 | 
			
		||||
		{
 | 
			
		||||
			i_http_server_handler<t_connection_context>* m_phandler;
 | 
			
		||||
		};
 | 
			
		||||
 | 
			
		||||
    /************************************************************************/
 | 
			
		||||
    /*                                                                      */
 | 
			
		||||
    /************************************************************************/
 | 
			
		||||
		/************************************************************************/
 | 
			
		||||
		/*                                                                      */
 | 
			
		||||
		/************************************************************************/
 | 
			
		||||
 | 
			
		||||
    template<class t_connection_context = net_utils::connection_context_base>
 | 
			
		||||
		template<class t_connection_context = net_utils::connection_context_base>
 | 
			
		||||
		class http_custom_handler: public simple_http_connection_handler<t_connection_context>
 | 
			
		||||
		{
 | 
			
		||||
		public:
 | 
			
		||||
			typedef custum_handler_config<t_connection_context> config_type;
 | 
			
		||||
			
 | 
			
		||||
			http_custom_handler(i_service_endpoint* psnd_hndlr, config_type& config, t_connection_context& conn_context):simple_http_connection_handler<t_connection_context>(psnd_hndlr, config), 
 | 
			
		||||
				m_config(config),
 | 
			
		||||
				m_conn_context(conn_context)
 | 
			
		||||
			http_custom_handler(i_service_endpoint* psnd_hndlr, config_type& config, t_connection_context& conn_context)
 | 
			
		||||
				: simple_http_connection_handler<t_connection_context>(psnd_hndlr, config),
 | 
			
		||||
					m_config(config),
 | 
			
		||||
					m_conn_context(conn_context)
 | 
			
		||||
			{}
 | 
			
		||||
			inline bool handle_request(const http_request_info& query_info, http_response_info& response)
 | 
			
		||||
			{
 | 
			
		||||
| 
						 | 
				
			
			@ -191,8 +190,8 @@ namespace net_utils
 | 
			
		|||
			{
 | 
			
		||||
				return m_config.m_phandler->deinit_server_thread();
 | 
			
		||||
			}
 | 
			
		||||
      void handle_qued_callback()   
 | 
			
		||||
      {}
 | 
			
		||||
			void handle_qued_callback()
 | 
			
		||||
			{}
 | 
			
		||||
			bool after_init_connection()
 | 
			
		||||
			{
 | 
			
		||||
				return true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,9 +26,10 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
#pragma once 
 | 
			
		||||
#include "serialization/keyvalue_serialization.h"
 | 
			
		||||
#include "storages/portable_storage_template_helper.h"
 | 
			
		||||
#include "http_base.h"
 | 
			
		||||
#include "jsonrpc_structs.h"
 | 
			
		||||
#include "storages/portable_storage.h"
 | 
			
		||||
#include "storages/portable_storage_template_helper.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define CHAIN_HTTP_TO_MAP2(context_type) bool handle_http_request(const epee::net_utils::http::http_request_info& query_info, \
 | 
			
		||||
| 
						 | 
				
			
			@ -109,98 +110,6 @@
 | 
			
		|||
#define END_URI_MAP2() return handled;}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
namespace epee 
 | 
			
		||||
{
 | 
			
		||||
  namespace json_rpc
 | 
			
		||||
  {
 | 
			
		||||
    template<typename t_param>
 | 
			
		||||
    struct request
 | 
			
		||||
    {
 | 
			
		||||
      std::string jsonrpc;
 | 
			
		||||
      std::string method;
 | 
			
		||||
      epee::serialization::storage_entry id;
 | 
			
		||||
      t_param     params;
 | 
			
		||||
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(jsonrpc)
 | 
			
		||||
        KV_SERIALIZE(id)
 | 
			
		||||
        KV_SERIALIZE(method)
 | 
			
		||||
        KV_SERIALIZE(params)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct error
 | 
			
		||||
    {
 | 
			
		||||
      int64_t code;
 | 
			
		||||
      std::string message;
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(code)
 | 
			
		||||
        KV_SERIALIZE(message)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    struct dummy_error
 | 
			
		||||
    {
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct dummy_result
 | 
			
		||||
    {
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename t_param, typename t_error>
 | 
			
		||||
    struct response
 | 
			
		||||
    {
 | 
			
		||||
      std::string jsonrpc;
 | 
			
		||||
      t_param     result;
 | 
			
		||||
      epee::serialization::storage_entry id;
 | 
			
		||||
      t_error     error;
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(jsonrpc)
 | 
			
		||||
        KV_SERIALIZE(id)
 | 
			
		||||
        KV_SERIALIZE(result)
 | 
			
		||||
        KV_SERIALIZE(error)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename t_param>
 | 
			
		||||
    struct response<t_param, dummy_error>
 | 
			
		||||
    {
 | 
			
		||||
      std::string jsonrpc;
 | 
			
		||||
      t_param     result;
 | 
			
		||||
      epee::serialization::storage_entry id;
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(jsonrpc)
 | 
			
		||||
        KV_SERIALIZE(id)
 | 
			
		||||
        KV_SERIALIZE(result)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename t_error>
 | 
			
		||||
    struct response<dummy_result, t_error>
 | 
			
		||||
    {
 | 
			
		||||
      std::string jsonrpc;
 | 
			
		||||
      t_error     error;
 | 
			
		||||
      epee::serialization::storage_entry id;
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(jsonrpc)
 | 
			
		||||
        KV_SERIALIZE(id)
 | 
			
		||||
        KV_SERIALIZE(error)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef response<dummy_result, error> error_response;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define BEGIN_JSON_RPC_MAP(uri)    else if(query_info.m_URI == uri) \
 | 
			
		||||
    { \
 | 
			
		||||
    uint64_t ticks = epee::misc_utils::get_tick_count(); \
 | 
			
		||||
| 
						 | 
				
			
			@ -315,6 +224,6 @@ namespace epee
 | 
			
		|||
  rsp.error.message = "Method not found"; \
 | 
			
		||||
  epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_info.m_body); \
 | 
			
		||||
  return true; \
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										167
									
								
								contrib/epee/include/net/jsonrpc_protocol_handler.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								contrib/epee/include/net/jsonrpc_protocol_handler.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,167 @@
 | 
			
		|||
#ifndef JSONRPC_PROTOCOL_HANDLER_H
 | 
			
		||||
#define	JSONRPC_PROTOCOL_HANDLER_H
 | 
			
		||||
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "net/net_utils_base.h"
 | 
			
		||||
#include "jsonrpc_structs.h"
 | 
			
		||||
#include "storages/portable_storage.h"
 | 
			
		||||
#include "storages/portable_storage_template_helper.h"
 | 
			
		||||
 | 
			
		||||
namespace epee
 | 
			
		||||
{
 | 
			
		||||
namespace net_utils
 | 
			
		||||
{
 | 
			
		||||
  namespace jsonrpc2
 | 
			
		||||
  {
 | 
			
		||||
  inline
 | 
			
		||||
  std::string& make_error_resp_json(int64_t code, const std::string& message,
 | 
			
		||||
                                    std::string& response_data,
 | 
			
		||||
                                    const epee::serialization::storage_entry& id = nullptr)
 | 
			
		||||
  {
 | 
			
		||||
    epee::json_rpc::error_response rsp;
 | 
			
		||||
    rsp.id = id;
 | 
			
		||||
    rsp.jsonrpc = "2.0";
 | 
			
		||||
    rsp.error.code = code;
 | 
			
		||||
    rsp.error.message = message;
 | 
			
		||||
    epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(rsp), response_data, 0, false);
 | 
			
		||||
    response_data += "\n";
 | 
			
		||||
    return response_data;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
    template<class t_connection_context>
 | 
			
		||||
    struct i_jsonrpc2_server_handler
 | 
			
		||||
    {
 | 
			
		||||
      virtual ~i_jsonrpc2_server_handler()
 | 
			
		||||
      {}
 | 
			
		||||
      virtual bool handle_rpc_request(const std::string& req_data,
 | 
			
		||||
                                      std::string& resp_data,
 | 
			
		||||
                                      t_connection_context& conn_context) = 0;
 | 
			
		||||
      virtual bool init_server_thread()
 | 
			
		||||
      { return true; }
 | 
			
		||||
      virtual bool deinit_server_thread()
 | 
			
		||||
      { return true; }
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    template<class t_connection_context>
 | 
			
		||||
    struct jsonrpc2_server_config
 | 
			
		||||
    {
 | 
			
		||||
      i_jsonrpc2_server_handler<t_connection_context>* m_phandler;
 | 
			
		||||
      critical_section m_lock;
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    template<class t_connection_context = net_utils::connection_context_base>
 | 
			
		||||
    class jsonrpc2_connection_handler
 | 
			
		||||
    {
 | 
			
		||||
    public:
 | 
			
		||||
      typedef t_connection_context connection_context;
 | 
			
		||||
      typedef jsonrpc2_server_config<t_connection_context> config_type;
 | 
			
		||||
 | 
			
		||||
      jsonrpc2_connection_handler(i_service_endpoint* psnd_hndlr,
 | 
			
		||||
                                  config_type& config,
 | 
			
		||||
                                  t_connection_context& conn_context)
 | 
			
		||||
        : m_psnd_hndlr(psnd_hndlr),
 | 
			
		||||
          m_config(config),
 | 
			
		||||
          m_conn_context(conn_context),
 | 
			
		||||
          m_is_stop_handling(false)
 | 
			
		||||
      {}
 | 
			
		||||
      virtual ~jsonrpc2_connection_handler()
 | 
			
		||||
      {}
 | 
			
		||||
 | 
			
		||||
      bool release_protocol()
 | 
			
		||||
      {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      virtual bool thread_init()
 | 
			
		||||
      {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      virtual bool thread_deinit()
 | 
			
		||||
      {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      void handle_qued_callback()   
 | 
			
		||||
      {}
 | 
			
		||||
      bool after_init_connection()
 | 
			
		||||
      {
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      virtual bool handle_recv(const void* ptr, size_t cb)
 | 
			
		||||
      {
 | 
			
		||||
        std::string buf((const char*)ptr, cb);
 | 
			
		||||
        LOG_PRINT_L0("JSONRPC2_RECV: " << ptr << "\r\n" << buf);
 | 
			
		||||
 | 
			
		||||
        bool res = handle_buff_in(buf);
 | 
			
		||||
        return res;
 | 
			
		||||
      }
 | 
			
		||||
    private:
 | 
			
		||||
      bool handle_buff_in(std::string& buf)
 | 
			
		||||
      {
 | 
			
		||||
        if(m_cache.size())
 | 
			
		||||
          m_cache += buf;
 | 
			
		||||
        else
 | 
			
		||||
          m_cache.swap(buf);
 | 
			
		||||
 | 
			
		||||
        m_is_stop_handling = false;
 | 
			
		||||
        while (!m_is_stop_handling) {
 | 
			
		||||
          std::string::size_type pos = match_end_of_request(m_cache);
 | 
			
		||||
          if (std::string::npos == pos) {
 | 
			
		||||
            m_is_stop_handling = true;
 | 
			
		||||
            if (m_cache.size() > 4096) {
 | 
			
		||||
              LOG_ERROR("jsonrpc2_connection_handler::handle_buff_in: Too long request");
 | 
			
		||||
              return false;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
          } else {
 | 
			
		||||
            extract_cached_request_and_handle(pos);
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
          if (!m_cache.size()) {
 | 
			
		||||
            m_is_stop_handling = true;
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
      }
 | 
			
		||||
      bool extract_cached_request_and_handle(std::string::size_type pos)
 | 
			
		||||
      {
 | 
			
		||||
        std::string request_data(m_cache.begin(), m_cache.begin() + pos);
 | 
			
		||||
        m_cache.erase(0, pos);
 | 
			
		||||
        return handle_request_and_send_response(request_data);
 | 
			
		||||
      }
 | 
			
		||||
      bool handle_request_and_send_response(const std::string& request_data)
 | 
			
		||||
      {
 | 
			
		||||
        CHECK_AND_ASSERT_MES(m_config.m_phandler, false, "m_config.m_phandler is NULL!!!!");
 | 
			
		||||
        std::string response_data;
 | 
			
		||||
 | 
			
		||||
        LOG_PRINT_L3("JSONRPC2_REQUEST: >> \r\n" << request_data);
 | 
			
		||||
        bool rpc_result = m_config.m_phandler->handle_rpc_request(request_data, response_data, m_conn_context);
 | 
			
		||||
        LOG_PRINT_L3("JSONRPC2_RESPONSE: << \r\n" << response_data);
 | 
			
		||||
 | 
			
		||||
        m_psnd_hndlr->do_send((void*)response_data.data(), response_data.size());
 | 
			
		||||
        return rpc_result;
 | 
			
		||||
      }
 | 
			
		||||
      std::string::size_type match_end_of_request(const std::string& buf)
 | 
			
		||||
      {
 | 
			
		||||
        std::string::size_type res = buf.find("\n");
 | 
			
		||||
        if(std::string::npos != res) {
 | 
			
		||||
          return res + 2;
 | 
			
		||||
        }
 | 
			
		||||
        return res;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
    protected:
 | 
			
		||||
      i_service_endpoint* m_psnd_hndlr;
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
      config_type& m_config;
 | 
			
		||||
      t_connection_context& m_conn_context;
 | 
			
		||||
      std::string m_cache;
 | 
			
		||||
      bool m_is_stop_handling;
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif	/* JSONRPC_PROTOCOL_HANDLER_H */
 | 
			
		||||
							
								
								
									
										86
									
								
								contrib/epee/include/net/jsonrpc_server_handlers_map.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								contrib/epee/include/net/jsonrpc_server_handlers_map.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,86 @@
 | 
			
		|||
#ifndef JSONRPC_SERVER_HANDLERS_MAP_H
 | 
			
		||||
#define	JSONRPC_SERVER_HANDLERS_MAP_H
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "serialization/keyvalue_serialization.h"
 | 
			
		||||
#include "storages/portable_storage_template_helper.h"
 | 
			
		||||
#include "storages/portable_storage_base.h"
 | 
			
		||||
#include "jsonrpc_structs.h"
 | 
			
		||||
#include "jsonrpc_protocol_handler.h"
 | 
			
		||||
 | 
			
		||||
#define BEGIN_JSONRPC2_MAP(t_connection_context) \
 | 
			
		||||
bool handle_rpc_request(const std::string& req_data, \
 | 
			
		||||
                        std::string& resp_data, \
 | 
			
		||||
                        t_connection_context& m_conn_context) \
 | 
			
		||||
{ \
 | 
			
		||||
  bool handled = false; \
 | 
			
		||||
  uint64_t ticks = epee::misc_utils::get_tick_count(); \
 | 
			
		||||
  epee::serialization::portable_storage ps; \
 | 
			
		||||
  if (!ps.load_from_json(req_data)) \
 | 
			
		||||
  { \
 | 
			
		||||
    epee::net_utils::jsonrpc2::make_error_resp_json(-32700, "Parse error", resp_data); \
 | 
			
		||||
    return true; \
 | 
			
		||||
  } \
 | 
			
		||||
  epee::serialization::storage_entry id_; \
 | 
			
		||||
  id_ = epee::serialization::storage_entry(std::string()); \
 | 
			
		||||
  if (!ps.get_value("id", id_, nullptr)) \
 | 
			
		||||
  { \
 | 
			
		||||
    epee::net_utils::jsonrpc2::make_error_resp_json(-32600, "Invalid Request", resp_data); \
 | 
			
		||||
    return true; \
 | 
			
		||||
  } \
 | 
			
		||||
  std::string callback_name; \
 | 
			
		||||
  if (!ps.get_value("method", callback_name, nullptr)) \
 | 
			
		||||
  { \
 | 
			
		||||
    epee::net_utils::jsonrpc2::make_error_resp_json(-32600, "Invalid Request", resp_data, id_); \
 | 
			
		||||
    return true; \
 | 
			
		||||
  } \
 | 
			
		||||
  if (false) return true; //just a stub to have "else if"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define PREPARE_JSONRPC2_OBJECTS_FROM_JSON(command_type) \
 | 
			
		||||
  handled = true; \
 | 
			
		||||
  boost::value_initialized<epee::json_rpc::request<command_type::request> > req_; \
 | 
			
		||||
  epee::json_rpc::request<command_type::request>& req = static_cast<epee::json_rpc::request<command_type::request>&>(req_);\
 | 
			
		||||
  if(!req.load(ps)) \
 | 
			
		||||
  { \
 | 
			
		||||
    epee::net_utils::jsonrpc2::make_error_resp_json(-32602, "Invalid params", resp_data, req.id); \
 | 
			
		||||
    return true; \
 | 
			
		||||
  } \
 | 
			
		||||
  uint64_t ticks1 = epee::misc_utils::get_tick_count(); \
 | 
			
		||||
  boost::value_initialized<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> > resp_; \
 | 
			
		||||
  epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error>& resp =  static_cast<epee::json_rpc::response<command_type::response, epee::json_rpc::dummy_error> &>(resp_); \
 | 
			
		||||
  resp.jsonrpc = "2.0"; \
 | 
			
		||||
  resp.id = req.id;
 | 
			
		||||
 | 
			
		||||
#define FINALIZE_JSONRPC2_OBJECTS_TO_JSON(method_name) \
 | 
			
		||||
  uint64_t ticks2 = epee::misc_utils::get_tick_count(); \
 | 
			
		||||
  epee::serialization::store_t_to_json(resp, resp_data, 0, false); \
 | 
			
		||||
  resp_data += "\n"; \
 | 
			
		||||
  uint64_t ticks3 = epee::misc_utils::get_tick_count(); \
 | 
			
		||||
  LOG_PRINT("[" << method_name << "] processed with " << ticks1-ticks << "/"<< ticks2-ticks1 << "/" << ticks3-ticks2 << "ms", LOG_LEVEL_2);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define MAP_JSONRPC2_WE(method_name, callback_f, command_type) \
 | 
			
		||||
  else if (callback_name == method_name) \
 | 
			
		||||
  { \
 | 
			
		||||
    PREPARE_JSONRPC2_OBJECTS_FROM_JSON(command_type) \
 | 
			
		||||
    epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \
 | 
			
		||||
    fail_resp.jsonrpc = "2.0"; \
 | 
			
		||||
    fail_resp.id = req.id; \
 | 
			
		||||
    if(!callback_f(req.params, resp.result, fail_resp.error, m_conn_context)) \
 | 
			
		||||
    { \
 | 
			
		||||
      epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), resp_data, 0, false); \
 | 
			
		||||
      resp_data += "\n"; \
 | 
			
		||||
      return true; \
 | 
			
		||||
    } \
 | 
			
		||||
    FINALIZE_JSONRPC2_OBJECTS_TO_JSON(method_name) \
 | 
			
		||||
    return true; \
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#define END_JSONRPC2_MAP() \
 | 
			
		||||
  epee::net_utils::jsonrpc2::make_error_resp_json(-32601, "Method not found", resp_data, id_); \
 | 
			
		||||
  return true; \
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif	/* JSONRPC_SERVER_HANDLERS_MAP_H */
 | 
			
		||||
							
								
								
									
										84
									
								
								contrib/epee/include/net/jsonrpc_server_impl_base.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										84
									
								
								contrib/epee/include/net/jsonrpc_server_impl_base.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,84 @@
 | 
			
		|||
#ifndef JSONRPC_SERVER_IMPL_BASE_H
 | 
			
		||||
#define	JSONRPC_SERVER_IMPL_BASE_H
 | 
			
		||||
 | 
			
		||||
#include <boost/thread.hpp>
 | 
			
		||||
#include <boost/bind.hpp> 
 | 
			
		||||
 | 
			
		||||
#include "net/jsonrpc_protocol_handler.h"
 | 
			
		||||
#include "net/jsonrpc_server_handlers_map.h"
 | 
			
		||||
#include "net/abstract_tcp_server2.h"
 | 
			
		||||
 | 
			
		||||
namespace epee
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
template<class t_child_class, class t_connection_context = epee::net_utils::connection_context_base>
 | 
			
		||||
  class jsonrpc_server_impl_base: public net_utils::jsonrpc2::i_jsonrpc2_server_handler<t_connection_context>
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
  public:
 | 
			
		||||
    jsonrpc_server_impl_base()
 | 
			
		||||
        : m_net_server()
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    explicit jsonrpc_server_impl_base(boost::asio::io_service& external_io_service)
 | 
			
		||||
        : m_net_server(external_io_service)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    bool init(const std::string& bind_port = "0", const std::string& bind_ip = "0.0.0.0")
 | 
			
		||||
    {
 | 
			
		||||
      //set self as callback handler
 | 
			
		||||
      m_net_server.get_config_object().m_phandler = static_cast<t_child_class*>(this);
 | 
			
		||||
 | 
			
		||||
      LOG_PRINT_L0("Binding on " << bind_ip << ":" << bind_port);
 | 
			
		||||
      bool res = m_net_server.init_server(bind_port, bind_ip);
 | 
			
		||||
      if (!res)
 | 
			
		||||
      {
 | 
			
		||||
        LOG_ERROR("Failed to bind server");
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool run(size_t threads_count, bool wait = true)
 | 
			
		||||
    {
 | 
			
		||||
      //go to loop
 | 
			
		||||
      LOG_PRINT("Run net_service loop( " << threads_count << " threads)...", LOG_LEVEL_0);
 | 
			
		||||
      if(!m_net_server.run_server(threads_count, wait))
 | 
			
		||||
      {
 | 
			
		||||
        LOG_ERROR("Failed to run net tcp server!");
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if(wait)
 | 
			
		||||
        LOG_PRINT("net_service loop stopped.", LOG_LEVEL_0);
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool deinit()
 | 
			
		||||
    {
 | 
			
		||||
      return m_net_server.deinit_server();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool timed_wait_server_stop(uint64_t ms)
 | 
			
		||||
    {
 | 
			
		||||
      return m_net_server.timed_wait_server_stop(ms);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool send_stop_signal()
 | 
			
		||||
    {
 | 
			
		||||
      m_net_server.send_stop_signal();
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int get_binded_port()
 | 
			
		||||
    {
 | 
			
		||||
      return m_net_server.get_binded_port();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  protected: 
 | 
			
		||||
    net_utils::boosted_tcp_server<net_utils::jsonrpc2::jsonrpc2_connection_handler<t_connection_context> > m_net_server;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif	/* JSONRPC_SERVER_IMPL_BASE_H */
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										96
									
								
								contrib/epee/include/net/jsonrpc_structs.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								contrib/epee/include/net/jsonrpc_structs.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,96 @@
 | 
			
		|||
#ifndef JSONRPC_STRUCTS_H
 | 
			
		||||
#define	JSONRPC_STRUCTS_H
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <cstdint>
 | 
			
		||||
#include "serialization/keyvalue_serialization.h"
 | 
			
		||||
#include "storages/portable_storage_base.h"
 | 
			
		||||
 | 
			
		||||
namespace epee 
 | 
			
		||||
{
 | 
			
		||||
  namespace json_rpc
 | 
			
		||||
  {
 | 
			
		||||
    template<typename t_param>
 | 
			
		||||
    struct request
 | 
			
		||||
    {
 | 
			
		||||
      std::string jsonrpc;
 | 
			
		||||
      std::string method;
 | 
			
		||||
      epee::serialization::storage_entry id;
 | 
			
		||||
      t_param     params;
 | 
			
		||||
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(jsonrpc)
 | 
			
		||||
        KV_SERIALIZE(id)
 | 
			
		||||
        KV_SERIALIZE(method)
 | 
			
		||||
        KV_SERIALIZE(params)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct error
 | 
			
		||||
    {
 | 
			
		||||
      int64_t code;
 | 
			
		||||
      std::string message;
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(code)
 | 
			
		||||
        KV_SERIALIZE(message)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
    
 | 
			
		||||
    struct dummy_error
 | 
			
		||||
    {
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    struct dummy_result
 | 
			
		||||
    {
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename t_param, typename t_error>
 | 
			
		||||
    struct response
 | 
			
		||||
    {
 | 
			
		||||
      std::string jsonrpc;
 | 
			
		||||
      t_param     result;
 | 
			
		||||
      epee::serialization::storage_entry id;
 | 
			
		||||
      t_error     error;
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(jsonrpc)
 | 
			
		||||
        KV_SERIALIZE(id)
 | 
			
		||||
        KV_SERIALIZE(result)
 | 
			
		||||
        KV_SERIALIZE(error)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename t_param>
 | 
			
		||||
    struct response<t_param, dummy_error>
 | 
			
		||||
    {
 | 
			
		||||
      std::string jsonrpc;
 | 
			
		||||
      t_param     result;
 | 
			
		||||
      epee::serialization::storage_entry id;
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(jsonrpc)
 | 
			
		||||
        KV_SERIALIZE(id)
 | 
			
		||||
        KV_SERIALIZE(result)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<typename t_error>
 | 
			
		||||
    struct response<dummy_result, t_error>
 | 
			
		||||
    {
 | 
			
		||||
      std::string jsonrpc;
 | 
			
		||||
      t_error     error;
 | 
			
		||||
      epee::serialization::storage_entry id;
 | 
			
		||||
      BEGIN_KV_SERIALIZE_MAP()
 | 
			
		||||
        KV_SERIALIZE(jsonrpc)
 | 
			
		||||
        KV_SERIALIZE(id)
 | 
			
		||||
        KV_SERIALIZE(error)
 | 
			
		||||
      END_KV_SERIALIZE_MAP()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    typedef response<dummy_result, error> error_response;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#endif	/* JSONRPC_STRUCTS_H */
 | 
			
		||||
| 
						 | 
				
			
			@ -47,8 +47,8 @@ namespace net_utils
 | 
			
		|||
	struct connection_context_base
 | 
			
		||||
	{
 | 
			
		||||
    const boost::uuids::uuid m_connection_id;
 | 
			
		||||
		const uint32_t m_remote_ip;
 | 
			
		||||
		const uint32_t m_remote_port;
 | 
			
		||||
    const uint32_t m_remote_ip;
 | 
			
		||||
    const uint32_t m_remote_port;
 | 
			
		||||
    const bool     m_is_income;
 | 
			
		||||
    const time_t   m_started;
 | 
			
		||||
    time_t   m_last_recv;
 | 
			
		||||
| 
						 | 
				
			
			@ -56,27 +56,30 @@ namespace net_utils
 | 
			
		|||
    uint64_t m_recv_cnt;
 | 
			
		||||
    uint64_t m_send_cnt;
 | 
			
		||||
 | 
			
		||||
    connection_context_base(boost::uuids::uuid connection_id, long remote_ip, int remote_port, bool is_income, time_t last_recv = 0, time_t last_send = 0, uint64_t recv_cnt = 0, uint64_t send_cnt = 0):
 | 
			
		||||
    connection_context_base(boost::uuids::uuid connection_id,
 | 
			
		||||
                            long remote_ip, int remote_port, bool is_income,
 | 
			
		||||
                            time_t last_recv = 0, time_t last_send = 0,
 | 
			
		||||
                            uint64_t recv_cnt = 0, uint64_t send_cnt = 0):
 | 
			
		||||
                                            m_connection_id(connection_id),
 | 
			
		||||
                                            m_remote_ip(remote_ip),
 | 
			
		||||
                                            m_remote_port(remote_port),
 | 
			
		||||
                                            m_is_income(is_income),
 | 
			
		||||
                                            m_started(time(NULL)),
 | 
			
		||||
                                            m_last_recv(last_recv),
 | 
			
		||||
                                            m_last_send(last_send),
 | 
			
		||||
                                            m_recv_cnt(recv_cnt),
 | 
			
		||||
                                            m_send_cnt(send_cnt),
 | 
			
		||||
                                            m_started(time(NULL))
 | 
			
		||||
                                            m_send_cnt(send_cnt)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    connection_context_base(): m_connection_id(),
 | 
			
		||||
                               m_remote_ip(0),
 | 
			
		||||
                               m_remote_port(0),
 | 
			
		||||
                               m_is_income(false),
 | 
			
		||||
                               m_started(time(NULL)),
 | 
			
		||||
                               m_last_recv(0),
 | 
			
		||||
                               m_last_send(0),
 | 
			
		||||
                               m_recv_cnt(0),
 | 
			
		||||
                               m_send_cnt(0),
 | 
			
		||||
                               m_started(time(NULL))
 | 
			
		||||
                               m_send_cnt(0)
 | 
			
		||||
    {}
 | 
			
		||||
 | 
			
		||||
    connection_context_base& operator=(const connection_context_base& a)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -51,13 +51,13 @@ namespace epee
 | 
			
		|||
#define PROFILE_FUNC_THIRD(immortal_ptr_str)
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define START_WAY_POINTS() uint64_t _____way_point_time = misc_utils::get_tick_count();
 | 
			
		||||
#define WAY_POINT(name) {uint64_t delta = misc_utils::get_tick_count()-_____way_point_time; LOG_PRINT("Way point " << name << ": " << delta, LOG_LEVEL_2);_____way_point_time = misc_utils::get_tick_count();}
 | 
			
		||||
#define WAY_POINT2(name, avrg_obj) {uint64_t delta = misc_utils::get_tick_count()-_____way_point_time; avrg_obj.push(delta); LOG_PRINT("Way point " << name << ": " << delta, LOG_LEVEL_2);_____way_point_time = misc_utils::get_tick_count();}
 | 
			
		||||
#define START_WAY_POINTS() uint64_t _____way_point_time = epee::misc_utils::get_tick_count();
 | 
			
		||||
#define WAY_POINT(name) {uint64_t delta = epee::misc_utils::get_tick_count()-_____way_point_time; LOG_PRINT("Way point " << name << ": " << delta, LOG_LEVEL_2);_____way_point_time = misc_utils::get_tick_count();}
 | 
			
		||||
#define WAY_POINT2(name, avrg_obj) {uint64_t delta = epee::misc_utils::get_tick_count()-_____way_point_time; avrg_obj.push(delta); LOG_PRINT("Way point " << name << ": " << delta, LOG_LEVEL_2);_____way_point_time = misc_utils::get_tick_count();}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define TIME_MEASURE_START(var_name)    uint64_t var_name = misc_utils::get_tick_count();
 | 
			
		||||
#define TIME_MEASURE_FINISH(var_name)   var_name = misc_utils::get_tick_count() - var_name;
 | 
			
		||||
#define TIME_MEASURE_START(var_name)    uint64_t var_name = epee::misc_utils::get_tick_count();
 | 
			
		||||
#define TIME_MEASURE_FINISH(var_name)   var_name = epee::misc_utils::get_tick_count() - var_name;
 | 
			
		||||
 | 
			
		||||
namespace profile_tools
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -31,6 +31,8 @@
 | 
			
		|||
#include "misc_log_ex.h"
 | 
			
		||||
#include "enableable.h"
 | 
			
		||||
#include "keyvalue_serialization_overloads.h"
 | 
			
		||||
#include "serialization/serialization.h"
 | 
			
		||||
 | 
			
		||||
namespace epee
 | 
			
		||||
{
 | 
			
		||||
  /************************************************************************/
 | 
			
		||||
| 
						 | 
				
			
			@ -41,12 +43,12 @@ public: \
 | 
			
		|||
  template<class t_storage> \
 | 
			
		||||
  bool store( t_storage& st, typename t_storage::hsection hparent_section = nullptr) const\
 | 
			
		||||
  {\
 | 
			
		||||
  return serialize_map<true>(*this, st, hparent_section);\
 | 
			
		||||
    return serialize_map<true>(*this, st, hparent_section);\
 | 
			
		||||
  }\
 | 
			
		||||
  template<class t_storage> \
 | 
			
		||||
  bool _load( t_storage& stg, typename t_storage::hsection hparent_section = nullptr)\
 | 
			
		||||
  {\
 | 
			
		||||
  return serialize_map<false>(*this, stg, hparent_section);\
 | 
			
		||||
    return serialize_map<false>(*this, stg, hparent_section);\
 | 
			
		||||
  }\
 | 
			
		||||
  template<class t_storage> \
 | 
			
		||||
  bool load( t_storage& stg, typename t_storage::hsection hparent_section = nullptr)\
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -83,7 +83,7 @@ namespace epee
 | 
			
		|||
      bool		load_from_binary(const binarybuffer& target);
 | 
			
		||||
      template<class trace_policy>
 | 
			
		||||
      bool		  dump_as_xml(std::string& targetObj, const std::string& root_name = "");
 | 
			
		||||
      bool		  dump_as_json(std::string& targetObj, size_t indent = 0);
 | 
			
		||||
      bool		  dump_as_json(std::string& targetObj, size_t indent = 0, bool insert_newlines = true);
 | 
			
		||||
      bool		  load_from_json(const std::string& source);
 | 
			
		||||
 | 
			
		||||
    private:
 | 
			
		||||
| 
						 | 
				
			
			@ -106,17 +106,17 @@ namespace epee
 | 
			
		|||
#pragma pack(pop)
 | 
			
		||||
    };
 | 
			
		||||
    inline
 | 
			
		||||
    bool		  portable_storage::dump_as_json(std::string& buff, size_t indent)
 | 
			
		||||
    bool portable_storage::dump_as_json(std::string& buff, size_t indent, bool insert_newlines)
 | 
			
		||||
    {
 | 
			
		||||
      TRY_ENTRY();
 | 
			
		||||
      std::stringstream ss;
 | 
			
		||||
      epee::serialization::dump_as_json(ss, m_root, indent);
 | 
			
		||||
      epee::serialization::dump_as_json(ss, m_root, indent, insert_newlines);
 | 
			
		||||
      buff = ss.str();
 | 
			
		||||
      return true;
 | 
			
		||||
      CATCH_ENTRY("portable_storage::dump_as_json", false)
 | 
			
		||||
    }
 | 
			
		||||
    inline
 | 
			
		||||
    bool		portable_storage::load_from_json(const std::string& source)
 | 
			
		||||
    bool portable_storage::load_from_json(const std::string& source)
 | 
			
		||||
    {
 | 
			
		||||
      TRY_ENTRY();
 | 
			
		||||
      return json::load_from_json(source, *this);
 | 
			
		||||
| 
						 | 
				
			
			@ -124,13 +124,13 @@ namespace epee
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    template<class trace_policy>
 | 
			
		||||
    bool		  portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name)
 | 
			
		||||
    bool portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name)
 | 
			
		||||
    {
 | 
			
		||||
      return false;//TODO: don't think i ever again will use xml - ambiguous and "overtagged" format
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    inline
 | 
			
		||||
    bool		portable_storage::store_to_binary(binarybuffer& target)
 | 
			
		||||
    bool portable_storage::store_to_binary(binarybuffer& target)
 | 
			
		||||
    {
 | 
			
		||||
      TRY_ENTRY();
 | 
			
		||||
      std::stringstream ss;
 | 
			
		||||
| 
						 | 
				
			
			@ -145,7 +145,7 @@ namespace epee
 | 
			
		|||
      CATCH_ENTRY("portable_storage::store_to_binary", false)
 | 
			
		||||
    }
 | 
			
		||||
    inline
 | 
			
		||||
    bool		portable_storage::load_from_binary(const binarybuffer& source)
 | 
			
		||||
    bool portable_storage::load_from_binary(const binarybuffer& source)
 | 
			
		||||
    {
 | 
			
		||||
      m_root.m_entries.clear();
 | 
			
		||||
      if(source.size() < sizeof(storage_block_header))
 | 
			
		||||
| 
						 | 
				
			
			@ -174,7 +174,7 @@ namespace epee
 | 
			
		|||
    }
 | 
			
		||||
    //---------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    inline
 | 
			
		||||
    hsection   portable_storage::open_section(const std::string& section_name,  hsection hparent_section, bool create_if_notexist)
 | 
			
		||||
    hsection portable_storage::open_section(const std::string& section_name,  hsection hparent_section, bool create_if_notexist)
 | 
			
		||||
    {
 | 
			
		||||
      TRY_ENTRY();
 | 
			
		||||
      hparent_section = hparent_section ? hparent_section:&m_root;
 | 
			
		||||
| 
						 | 
				
			
			@ -238,7 +238,7 @@ namespace epee
 | 
			
		|||
    }
 | 
			
		||||
    //---------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    template<class t_value>
 | 
			
		||||
    bool       portable_storage::set_value(const std::string& value_name, const t_value& v, hsection hparent_section)        
 | 
			
		||||
    bool portable_storage::set_value(const std::string& value_name, const t_value& v, hsection hparent_section)        
 | 
			
		||||
    {
 | 
			
		||||
      BOOST_MPL_ASSERT(( boost::mpl::contains<boost::mpl::push_front<storage_entry::types, storage_entry>::type, t_value> )); 
 | 
			
		||||
      TRY_ENTRY();
 | 
			
		||||
| 
						 | 
				
			
			@ -345,7 +345,7 @@ namespace epee
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    template<class t_value>
 | 
			
		||||
    bool          portable_storage::get_next_value(harray hval_array, t_value& target)
 | 
			
		||||
    bool portable_storage::get_next_value(harray hval_array, t_value& target)
 | 
			
		||||
    {
 | 
			
		||||
      BOOST_MPL_ASSERT(( boost::mpl::contains<storage_entry::types, t_value> )); 
 | 
			
		||||
      //TRY_ENTRY();
 | 
			
		||||
| 
						 | 
				
			
			@ -462,7 +462,7 @@ namespace epee
 | 
			
		|||
    }
 | 
			
		||||
    //---------------------------------------------------------------------------------------------------------------
 | 
			
		||||
    inline
 | 
			
		||||
    bool            portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
 | 
			
		||||
    bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
 | 
			
		||||
    {
 | 
			
		||||
      TRY_ENTRY();
 | 
			
		||||
      CHECK_AND_ASSERT(hsec_array, false);
 | 
			
		||||
| 
						 | 
				
			
			@ -476,4 +476,4 @@ namespace epee
 | 
			
		|||
    }
 | 
			
		||||
    //---------------------------------------------------------------------------------------------------------------
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,6 +25,9 @@
 | 
			
		|||
// 
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include "parserse_base_utils.h"
 | 
			
		||||
#include "portable_storage.h"
 | 
			
		||||
#include "file_io_utils.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -56,19 +59,19 @@ namespace epee
 | 
			
		|||
    }
 | 
			
		||||
    //-----------------------------------------------------------------------------------------------------------
 | 
			
		||||
    template<class t_struct>
 | 
			
		||||
    bool store_t_to_json(t_struct& str_in, std::string& json_buff, size_t indent = 0)
 | 
			
		||||
    bool store_t_to_json(t_struct& str_in, std::string& json_buff, size_t indent = 0, bool insert_newlines = true)
 | 
			
		||||
    {
 | 
			
		||||
      portable_storage ps;
 | 
			
		||||
      str_in.store(ps);
 | 
			
		||||
      ps.dump_as_json(json_buff, indent);
 | 
			
		||||
      ps.dump_as_json(json_buff, indent, insert_newlines);
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    //-----------------------------------------------------------------------------------------------------------
 | 
			
		||||
    template<class t_struct>
 | 
			
		||||
    std::string store_t_to_json(t_struct& str_in, size_t indent = 0)
 | 
			
		||||
    std::string store_t_to_json(t_struct& str_in, size_t indent = 0, bool insert_newlines = true)
 | 
			
		||||
    {
 | 
			
		||||
      std::string json_buff;
 | 
			
		||||
      store_t_to_json(str_in, json_buff, indent);
 | 
			
		||||
      store_t_to_json(str_in, json_buff, indent, insert_newlines);
 | 
			
		||||
      return std::move(json_buff);
 | 
			
		||||
    }
 | 
			
		||||
    //-----------------------------------------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,7 @@
 | 
			
		|||
 | 
			
		||||
#include "misc_language.h"
 | 
			
		||||
#include "portable_storage_base.h"
 | 
			
		||||
#include "parserse_base_utils.h"
 | 
			
		||||
 | 
			
		||||
namespace epee
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -37,21 +38,21 @@ namespace epee
 | 
			
		|||
  {
 | 
			
		||||
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent);
 | 
			
		||||
    void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent, bool insert_newlines);
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent);
 | 
			
		||||
    void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent, bool insert_newlines);
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const std::string& v, size_t indent);
 | 
			
		||||
    void dump_as_json(t_stream& strm, const std::string& v, size_t indent, bool insert_newlines);
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const int8_t& v, size_t indent);
 | 
			
		||||
    void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, bool insert_newlines);
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent);
 | 
			
		||||
    void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, bool insert_newlines);
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const bool& v, size_t indent);
 | 
			
		||||
    void dump_as_json(t_stream& strm, const bool& v, size_t indent, bool insert_newlines);
 | 
			
		||||
    template<class t_stream, class t_type>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const t_type& v, size_t indent);
 | 
			
		||||
    void dump_as_json(t_stream& strm, const t_type& v, size_t indent, bool insert_newlines);
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const section& sec, size_t indent);
 | 
			
		||||
    void dump_as_json(t_stream& strm, const section& sec, size_t indent, bool insert_newlines);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    inline std::string make_indent(size_t indent)
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +65,11 @@ namespace epee
 | 
			
		|||
    {
 | 
			
		||||
      t_stream& m_strm;
 | 
			
		||||
      size_t m_indent;
 | 
			
		||||
      array_entry_store_to_json_visitor(t_stream& strm, size_t indent):m_strm(strm), m_indent(indent){}
 | 
			
		||||
      bool m_insert_newlines;
 | 
			
		||||
      array_entry_store_to_json_visitor(t_stream& strm, size_t indent,
 | 
			
		||||
                                        bool insert_newlines = true)
 | 
			
		||||
        : m_strm(strm), m_indent(indent), m_insert_newlines(insert_newlines)
 | 
			
		||||
      {}
 | 
			
		||||
 | 
			
		||||
      template<class t_type>
 | 
			
		||||
      void operator()(const array_entry_t<t_type>& a)
 | 
			
		||||
| 
						 | 
				
			
			@ -75,7 +80,7 @@ namespace epee
 | 
			
		|||
          auto last_it = --a.m_array.end();
 | 
			
		||||
          for(auto it = a.m_array.begin(); it != a.m_array.end(); it++)
 | 
			
		||||
          {
 | 
			
		||||
            dump_as_json(m_strm, *it, m_indent);
 | 
			
		||||
            dump_as_json(m_strm, *it, m_indent, m_insert_newlines);
 | 
			
		||||
            if(it != last_it)
 | 
			
		||||
              m_strm << ",";
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -89,50 +94,53 @@ namespace epee
 | 
			
		|||
    {
 | 
			
		||||
      t_stream& m_strm;
 | 
			
		||||
      size_t m_indent;
 | 
			
		||||
      storage_entry_store_to_json_visitor(t_stream& strm, size_t indent):m_strm(strm), m_indent(indent)
 | 
			
		||||
      bool m_insert_newlines;
 | 
			
		||||
      storage_entry_store_to_json_visitor(t_stream& strm, size_t indent,
 | 
			
		||||
                                          bool insert_newlines = true)
 | 
			
		||||
          : m_strm(strm), m_indent(indent), m_insert_newlines(insert_newlines)
 | 
			
		||||
      {}
 | 
			
		||||
      //section, array_entry
 | 
			
		||||
      template<class visited_type>
 | 
			
		||||
      void operator()(const visited_type& v)
 | 
			
		||||
      { 
 | 
			
		||||
        dump_as_json(m_strm, v, m_indent);
 | 
			
		||||
        dump_as_json(m_strm, v, m_indent, m_insert_newlines);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent)
 | 
			
		||||
    void dump_as_json(t_stream& strm, const array_entry& ae, size_t indent, bool insert_newlines)
 | 
			
		||||
    {
 | 
			
		||||
      array_entry_store_to_json_visitor<t_stream> aesv(strm, indent);
 | 
			
		||||
      array_entry_store_to_json_visitor<t_stream> aesv(strm, indent, insert_newlines);
 | 
			
		||||
      boost::apply_visitor(aesv, ae);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent)
 | 
			
		||||
    void dump_as_json(t_stream& strm, const storage_entry& se, size_t indent, bool insert_newlines)
 | 
			
		||||
    {
 | 
			
		||||
      storage_entry_store_to_json_visitor<t_stream> sv(strm, indent);
 | 
			
		||||
      storage_entry_store_to_json_visitor<t_stream> sv(strm, indent, insert_newlines);
 | 
			
		||||
      boost::apply_visitor(sv, se);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const std::string& v, size_t indent)
 | 
			
		||||
    void dump_as_json(t_stream& strm, const std::string& v, size_t indent, bool insert_newlines)
 | 
			
		||||
    {
 | 
			
		||||
      strm << "\"" << misc_utils::parse::transform_to_escape_sequence(v) << "\"";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const int8_t& v, size_t indent)
 | 
			
		||||
    void dump_as_json(t_stream& strm, const int8_t& v, size_t indent, bool insert_newlines)
 | 
			
		||||
    {
 | 
			
		||||
      strm << static_cast<int32_t>(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent)
 | 
			
		||||
    void dump_as_json(t_stream& strm, const uint8_t& v, size_t indent, bool insert_newlines)
 | 
			
		||||
    {
 | 
			
		||||
      strm << static_cast<int32_t>(v);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const bool& v, size_t indent)
 | 
			
		||||
    void dump_as_json(t_stream& strm, const bool& v, size_t indent, bool insert_newlines)
 | 
			
		||||
    {
 | 
			
		||||
      if(v)
 | 
			
		||||
        strm << "true";
 | 
			
		||||
| 
						 | 
				
			
			@ -143,16 +151,17 @@ namespace epee
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    template<class t_stream, class t_type>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const t_type& v, size_t indent)
 | 
			
		||||
    void dump_as_json(t_stream& strm, const t_type& v, size_t indent, bool insert_newlines)
 | 
			
		||||
    {
 | 
			
		||||
      strm << v;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template<class t_stream>
 | 
			
		||||
    void dump_as_json(t_stream& strm, const section& sec, size_t indent)
 | 
			
		||||
    void dump_as_json(t_stream& strm, const section& sec, size_t indent, bool insert_newlines)
 | 
			
		||||
    {
 | 
			
		||||
      size_t local_indent = indent + 1;
 | 
			
		||||
      strm << "{\r\n";
 | 
			
		||||
      std::string newline = insert_newlines ? "\r\n" : "";
 | 
			
		||||
      strm << "{" << newline;
 | 
			
		||||
      std::string indent_str = make_indent(local_indent);
 | 
			
		||||
      if(sec.m_entries.size())
 | 
			
		||||
      {
 | 
			
		||||
| 
						 | 
				
			
			@ -160,10 +169,10 @@ namespace epee
 | 
			
		|||
        for(auto it = sec.m_entries.begin(); it!= sec.m_entries.end();it++)
 | 
			
		||||
        {
 | 
			
		||||
          strm << indent_str << "\"" << misc_utils::parse::transform_to_escape_sequence(it->first) << "\"" << ": ";
 | 
			
		||||
          dump_as_json(strm, it->second, local_indent);
 | 
			
		||||
          dump_as_json(strm, it->second, local_indent, insert_newlines);
 | 
			
		||||
          if(it_last != it)
 | 
			
		||||
            strm << ",";
 | 
			
		||||
          strm << "\r\n";
 | 
			
		||||
          strm << newline;
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      strm << make_indent(indent) <<  "}";
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@
 | 
			
		|||
//#include <objbase.h>
 | 
			
		||||
#include <locale>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <iomanip>
 | 
			
		||||
//#include <strsafe.h>
 | 
			
		||||
#include <boost/uuid/uuid.hpp>
 | 
			
		||||
#include <boost/uuid/uuid_io.hpp>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,7 +64,6 @@ static const char _NR[] = {
 | 
			
		|||
# define min(a,b) (((a)<(b)) ? (a) : (b))
 | 
			
		||||
#endif /* min */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// "OAES<8-bit header version><8-bit type><16-bit options><8-bit flags><56-bit reserved>"
 | 
			
		||||
static uint8_t oaes_header[OAES_BLOCK_SIZE] = {
 | 
			
		||||
	// 		0,    1,    2,    3,    4,    5,    6,    7,    8,    9,    a,    b,    c,    d,    e,    f,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@
 | 
			
		|||
#define _OAES_LIB_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus 
 | 
			
		||||
extern "C" {
 | 
			
		||||
| 
						 | 
				
			
			@ -101,15 +102,14 @@ typedef int ( * oaes_step_cb ) (
 | 
			
		|||
 | 
			
		||||
typedef uint16_t OAES_OPTION;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef struct _oaes_key
 | 
			
		||||
{
 | 
			
		||||
	size_t data_len;
 | 
			
		||||
	uint8_t *data;
 | 
			
		||||
	size_t exp_data_len;
 | 
			
		||||
	uint8_t *exp_data;
 | 
			
		||||
	size_t num_keys;
 | 
			
		||||
	size_t key_base;
 | 
			
		||||
  size_t data_len;
 | 
			
		||||
  uint8_t *data;
 | 
			
		||||
  size_t exp_data_len;
 | 
			
		||||
  uint8_t *exp_data;
 | 
			
		||||
  size_t num_keys;
 | 
			
		||||
  size_t key_base;
 | 
			
		||||
} oaes_key;
 | 
			
		||||
 | 
			
		||||
typedef struct _oaes_ctx
 | 
			
		||||
| 
						 | 
				
			
			@ -119,14 +119,13 @@ typedef struct _oaes_ctx
 | 
			
		|||
#endif // OAES_HAVE_ISAAC
 | 
			
		||||
 | 
			
		||||
#ifdef OAES_DEBUG
 | 
			
		||||
	oaes_step_cb step_cb;
 | 
			
		||||
  oaes_step_cb step_cb;
 | 
			
		||||
#endif // OAES_DEBUG
 | 
			
		||||
 | 
			
		||||
	oaes_key * key;
 | 
			
		||||
	OAES_OPTION options;
 | 
			
		||||
	uint8_t iv[OAES_BLOCK_SIZE];
 | 
			
		||||
  oaes_key * key;
 | 
			
		||||
  OAES_OPTION options;
 | 
			
		||||
  uint8_t iv[OAES_BLOCK_SIZE];
 | 
			
		||||
} oaes_ctx;
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * // usage:
 | 
			
		||||
 * 
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,7 @@
 | 
			
		|||
#define CRYPTONOTE_MAX_BLOCK_SIZE                       500000000  // block header blob limit, never used!
 | 
			
		||||
#define CRYPTONOTE_MAX_TX_SIZE                          1000000000
 | 
			
		||||
#define CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER          0
 | 
			
		||||
#define CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX         18 // addresses start with "2"
 | 
			
		||||
#define CRYPTONOTE_PUBLIC_ADDRESS_BASE58_PREFIX         18 // addresses start with "4"
 | 
			
		||||
#define CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW            60
 | 
			
		||||
#define CURRENT_TRANSACTION_VERSION                     1
 | 
			
		||||
#define CURRENT_BLOCK_MAJOR_VERSION                     1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -372,7 +372,7 @@ bool blockchain_storage::rollback_blockchain_switching(std::list<block>& origina
 | 
			
		|||
  return true;
 | 
			
		||||
}
 | 
			
		||||
//------------------------------------------------------------------
 | 
			
		||||
bool blockchain_storage::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain)
 | 
			
		||||
bool blockchain_storage::switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain, bool discard_disconnected_chain)
 | 
			
		||||
{
 | 
			
		||||
  CRITICAL_REGION_LOCAL(m_blockchain_lock);
 | 
			
		||||
  CHECK_AND_ASSERT_MES(alt_chain.size(), false, "switch_to_alternative_blockchain: empty chain passed");
 | 
			
		||||
| 
						 | 
				
			
			@ -414,16 +414,19 @@ bool blockchain_storage::switch_to_alternative_blockchain(std::list<blocks_ext_b
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //pushing old chain as alternative chain
 | 
			
		||||
  BOOST_FOREACH(auto& old_ch_ent, disconnected_chain)
 | 
			
		||||
  if(!discard_disconnected_chain)
 | 
			
		||||
  {
 | 
			
		||||
    block_verification_context bvc = boost::value_initialized<block_verification_context>();
 | 
			
		||||
    bool r = handle_alternative_block(old_ch_ent, get_block_hash(old_ch_ent), bvc);
 | 
			
		||||
    if(!r)
 | 
			
		||||
    //pushing old chain as alternative chain
 | 
			
		||||
    BOOST_FOREACH(auto& old_ch_ent, disconnected_chain)
 | 
			
		||||
    {
 | 
			
		||||
      LOG_ERROR("Failed to push ex-main chain blocks to alternative chain ");
 | 
			
		||||
      rollback_blockchain_switching(disconnected_chain, split_height);
 | 
			
		||||
      return false;
 | 
			
		||||
      block_verification_context bvc = boost::value_initialized<block_verification_context>();
 | 
			
		||||
      bool r = handle_alternative_block(old_ch_ent, get_block_hash(old_ch_ent), bvc);
 | 
			
		||||
      if(!r)
 | 
			
		||||
      {
 | 
			
		||||
        LOG_ERROR("Failed to push ex-main chain blocks to alternative chain ");
 | 
			
		||||
        rollback_blockchain_switching(disconnected_chain, split_height);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -701,6 +704,22 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
 | 
			
		|||
{
 | 
			
		||||
  CRITICAL_REGION_LOCAL(m_blockchain_lock);
 | 
			
		||||
 | 
			
		||||
  uint64_t block_height = get_block_height(b);
 | 
			
		||||
  if(0 == block_height)
 | 
			
		||||
  {
 | 
			
		||||
    LOG_ERROR("Block with id: " << string_tools::pod_to_hex(id) << " (as alternative) have wrong miner transaction");
 | 
			
		||||
    bvc.m_verifivation_failed = true;
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
  if (!m_checkpoints.is_alternative_block_allowed(get_current_blockchain_height(), block_height))
 | 
			
		||||
  {
 | 
			
		||||
    LOG_PRINT_RED_L0("Block with id: " << id
 | 
			
		||||
      << ENDL << " can't be accepted for alternative chain, block height: " << block_height
 | 
			
		||||
      << ENDL << " blockchain height: " << get_current_blockchain_height());
 | 
			
		||||
    bvc.m_verifivation_failed = true;
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //block is not related with head of main chain
 | 
			
		||||
  //first of all - look in alternative chains container
 | 
			
		||||
  auto it_main_prev = m_blocks_index.find(b.prev_id);
 | 
			
		||||
| 
						 | 
				
			
			@ -746,31 +765,28 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
 | 
			
		|||
    block_extended_info bei = boost::value_initialized<block_extended_info>();
 | 
			
		||||
    bei.bl = b;
 | 
			
		||||
    bei.height = alt_chain.size() ? it_prev->second.height + 1 : it_main_prev->second + 1;
 | 
			
		||||
 | 
			
		||||
    bool is_a_checkpoint;
 | 
			
		||||
    if(!m_checkpoints.check_block(bei.height, id, is_a_checkpoint))
 | 
			
		||||
    {
 | 
			
		||||
      LOG_ERROR("CHECKPOINT VALIDATION FAILED");
 | 
			
		||||
      bvc.m_verifivation_failed = true;
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Always check PoW for alternative blocks
 | 
			
		||||
    m_is_in_checkpoint_zone = false;
 | 
			
		||||
    difficulty_type current_diff = get_next_difficulty_for_alternative_chain(alt_chain, bei);
 | 
			
		||||
    CHECK_AND_ASSERT_MES(current_diff, false, "!!!!!!! DIFFICULTY OVERHEAD !!!!!!!");
 | 
			
		||||
    crypto::hash proof_of_work = null_hash;
 | 
			
		||||
    if(!m_checkpoints.is_in_checkpoint_zone(bei.height))
 | 
			
		||||
    get_block_longhash(bei.bl, proof_of_work, bei.height);
 | 
			
		||||
    if(!check_hash(proof_of_work, current_diff))
 | 
			
		||||
    {
 | 
			
		||||
      m_is_in_checkpoint_zone = false;
 | 
			
		||||
      get_block_longhash(bei.bl, proof_of_work, bei.height);
 | 
			
		||||
 | 
			
		||||
      if(!check_hash(proof_of_work, current_diff))
 | 
			
		||||
      {
 | 
			
		||||
        LOG_PRINT_RED_L0("Block with id: " << id
 | 
			
		||||
          << ENDL << " for alternative chain, have not enough proof of work: " << proof_of_work
 | 
			
		||||
          << ENDL << " expected difficulty: " << current_diff);
 | 
			
		||||
        bvc.m_verifivation_failed = true;
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
    }else
 | 
			
		||||
    {
 | 
			
		||||
      m_is_in_checkpoint_zone = true;
 | 
			
		||||
      if(!m_checkpoints.check_block(bei.height, id))
 | 
			
		||||
      {
 | 
			
		||||
        LOG_ERROR("CHECKPOINT VALIDATION FAILED");
 | 
			
		||||
        bvc.m_verifivation_failed = true;
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      LOG_PRINT_RED_L0("Block with id: " << id
 | 
			
		||||
        << ENDL << " for alternative chain, have not enough proof of work: " << proof_of_work
 | 
			
		||||
        << ENDL << " expected difficulty: " << current_diff);
 | 
			
		||||
      bvc.m_verifivation_failed = true;
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(!prevalidate_miner_transaction(b, bei.height))
 | 
			
		||||
| 
						 | 
				
			
			@ -792,22 +808,33 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
 | 
			
		|||
    auto i_res = m_alternative_chains.insert(blocks_ext_by_hash::value_type(id, bei));
 | 
			
		||||
    CHECK_AND_ASSERT_MES(i_res.second, false, "insertion of new alternative block returned as it already exist");
 | 
			
		||||
    alt_chain.push_back(i_res.first);
 | 
			
		||||
    //check if difficulty bigger then in main chain
 | 
			
		||||
    if(m_blocks.back().cumulative_difficulty < bei.cumulative_difficulty)
 | 
			
		||||
 | 
			
		||||
    if(is_a_checkpoint)
 | 
			
		||||
    {
 | 
			
		||||
      //do reorganize!
 | 
			
		||||
      LOG_PRINT_GREEN("###### REORGANIZE on height: " << alt_chain.front()->second.height << " of " << m_blocks.size() -1  << " with cum_difficulty " << m_blocks.back().cumulative_difficulty
 | 
			
		||||
        << ENDL << " alternative blockchain size: " << alt_chain.size() << " with cum_difficulty " << bei.cumulative_difficulty, LOG_LEVEL_0);
 | 
			
		||||
      bool r = switch_to_alternative_blockchain(alt_chain);
 | 
			
		||||
      LOG_PRINT_GREEN("###### REORGANIZE on height: " << alt_chain.front()->second.height << " of " << m_blocks.size() - 1 <<
 | 
			
		||||
        ", checkpoint is found in alternative chain on height " << bei.height, LOG_LEVEL_0);
 | 
			
		||||
      bool r = switch_to_alternative_blockchain(alt_chain, true);
 | 
			
		||||
      if(r) bvc.m_added_to_main_chain = true;
 | 
			
		||||
      else bvc.m_verifivation_failed = true;
 | 
			
		||||
      return r;
 | 
			
		||||
    }else if(m_blocks.back().cumulative_difficulty < bei.cumulative_difficulty) //check if difficulty bigger then in main chain
 | 
			
		||||
    {
 | 
			
		||||
      //do reorganize!
 | 
			
		||||
      LOG_PRINT_GREEN("###### REORGANIZE on height: " << alt_chain.front()->second.height << " of " << m_blocks.size() - 1 << " with cum_difficulty " << m_blocks.back().cumulative_difficulty
 | 
			
		||||
        << ENDL << " alternative blockchain size: " << alt_chain.size() << " with cum_difficulty " << bei.cumulative_difficulty, LOG_LEVEL_0);
 | 
			
		||||
      bool r = switch_to_alternative_blockchain(alt_chain, false);
 | 
			
		||||
      if(r) bvc.m_added_to_main_chain = true;
 | 
			
		||||
      else bvc.m_verifivation_failed = true;
 | 
			
		||||
      return r;
 | 
			
		||||
    }else
 | 
			
		||||
    {
 | 
			
		||||
      LOG_PRINT_BLUE("----- BLOCK ADDED AS ALTERNATIVE ON HEIGHT " << bei.height
 | 
			
		||||
        << ENDL << "id:\t" << id
 | 
			
		||||
        << ENDL << "PoW:\t" << proof_of_work
 | 
			
		||||
        << ENDL << "difficulty:\t" << current_diff, LOG_LEVEL_0);
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
    LOG_PRINT_BLUE("----- BLOCK ADDED AS ALTERNATIVE ON HEIGHT " << bei.height
 | 
			
		||||
      << ENDL << "id:\t" << id
 | 
			
		||||
      << ENDL << "PoW:\t" << proof_of_work
 | 
			
		||||
      << ENDL << "difficulty:\t" << current_diff, LOG_LEVEL_0);
 | 
			
		||||
    return true;
 | 
			
		||||
  }else
 | 
			
		||||
  {
 | 
			
		||||
    //block orphaned
 | 
			
		||||
| 
						 | 
				
			
			@ -815,7 +842,6 @@ bool blockchain_storage::handle_alternative_block(const block& b, const crypto::
 | 
			
		|||
    LOG_PRINT_RED_L0("Block recognized as orphaned and rejected, id = " << id);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  return true;
 | 
			
		||||
}
 | 
			
		||||
//------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -1480,19 +1506,27 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
 | 
			
		|||
  TIME_MEASURE_FINISH(target_calculating_time);
 | 
			
		||||
  TIME_MEASURE_START(longhash_calculating_time);
 | 
			
		||||
  crypto::hash proof_of_work = null_hash;
 | 
			
		||||
  if(!m_checkpoints.is_in_checkpoint_zone(get_current_blockchain_height()))
 | 
			
		||||
  {
 | 
			
		||||
    proof_of_work = get_block_longhash(bl, m_blocks.size());
 | 
			
		||||
 | 
			
		||||
    if(!check_hash(proof_of_work, current_diffic))
 | 
			
		||||
    {
 | 
			
		||||
      LOG_PRINT_L0("Block with id: " << id << ENDL
 | 
			
		||||
        << "have not enough proof of work: " << proof_of_work << ENDL
 | 
			
		||||
        << "nexpected difficulty: " << current_diffic );
 | 
			
		||||
      bvc.m_verifivation_failed = true;
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }else
 | 
			
		||||
  // Formerly the code below contained an if loop with the following condition
 | 
			
		||||
  // !m_checkpoints.is_in_checkpoint_zone(get_current_blockchain_height())
 | 
			
		||||
  // however, this caused the daemon to not bother checking PoW for blocks
 | 
			
		||||
  // before checkpoints, which is very dangerous behaviour. We moved the PoW
 | 
			
		||||
  // validation out of the next chunk of code to make sure that we correctly
 | 
			
		||||
  // check PoW now.
 | 
			
		||||
  proof_of_work = get_block_longhash(bl, m_blocks.size());
 | 
			
		||||
 | 
			
		||||
  if(!check_hash(proof_of_work, current_diffic))
 | 
			
		||||
  {
 | 
			
		||||
    LOG_PRINT_L0("Block with id: " << id << ENDL
 | 
			
		||||
      << "have not enough proof of work: " << proof_of_work << ENDL
 | 
			
		||||
      << "nexpected difficulty: " << current_diffic );
 | 
			
		||||
    bvc.m_verifivation_failed = true;
 | 
			
		||||
    return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // If we're at a checkpoint, ensure that our hardcoded checkpoint hash
 | 
			
		||||
  // is correct.
 | 
			
		||||
  if(m_checkpoints.is_in_checkpoint_zone(get_current_blockchain_height()))
 | 
			
		||||
  {
 | 
			
		||||
    if(!m_checkpoints.check_block(get_current_blockchain_height(), id))
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -1501,6 +1535,7 @@ bool blockchain_storage::handle_block_to_main_chain(const block& bl, const crypt
 | 
			
		|||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  TIME_MEASURE_FINISH(longhash_calculating_time);
 | 
			
		||||
 | 
			
		||||
  if(!prevalidate_miner_transaction(bl, m_blocks.size()))
 | 
			
		||||
| 
						 | 
				
			
			@ -1648,4 +1683,4 @@ bool blockchain_storage::add_new_block(const block& bl_, block_verification_cont
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  return handle_block_to_main_chain(bl, id, bvc);
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,6 +13,8 @@
 | 
			
		|||
#include <boost/foreach.hpp>
 | 
			
		||||
#include <atomic>
 | 
			
		||||
 | 
			
		||||
#include "syncobj.h"
 | 
			
		||||
#include "string_tools.h"
 | 
			
		||||
#include "tx_pool.h"
 | 
			
		||||
#include "cryptonote_basic.h"
 | 
			
		||||
#include "common/util.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -50,7 +52,7 @@ namespace cryptonote
 | 
			
		|||
      uint64_t already_generated_coins;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    blockchain_storage(tx_memory_pool& tx_pool):m_tx_pool(tx_pool), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false)
 | 
			
		||||
    blockchain_storage(tx_memory_pool& tx_pool):m_tx_pool(tx_pool), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false), m_is_blockchain_storing(false)
 | 
			
		||||
    {};
 | 
			
		||||
 | 
			
		||||
    bool init() { return init(tools::get_default_data_dir()); }
 | 
			
		||||
| 
						 | 
				
			
			@ -119,7 +121,7 @@ namespace cryptonote
 | 
			
		|||
          missed_bs.push_back(bl_id);
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
          CHECK_AND_ASSERT_MES(it->second < m_blocks.size(), false, "Internal error: bl_id=" << string_tools::pod_to_hex(bl_id)
 | 
			
		||||
          CHECK_AND_ASSERT_MES(it->second < m_blocks.size(), false, "Internal error: bl_id=" << epee::string_tools::pod_to_hex(bl_id)
 | 
			
		||||
            << " have index record with offset="<<it->second<< ", bigger then m_blocks.size()=" << m_blocks.size());
 | 
			
		||||
            blocks.push_back(m_blocks[it->second].bl);
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +165,7 @@ namespace cryptonote
 | 
			
		|||
    typedef std::map<uint64_t, std::vector<std::pair<crypto::hash, size_t>>> outputs_container; //crypto::hash - tx hash, size_t - index of out in transaction
 | 
			
		||||
 | 
			
		||||
    tx_memory_pool& m_tx_pool;
 | 
			
		||||
    critical_section m_blockchain_lock; // TODO: add here reader/writer lock
 | 
			
		||||
    epee::critical_section m_blockchain_lock; // TODO: add here reader/writer lock
 | 
			
		||||
 | 
			
		||||
    // main chain
 | 
			
		||||
    blocks_container m_blocks;               // height  -> block_extended_info
 | 
			
		||||
| 
						 | 
				
			
			@ -186,7 +188,7 @@ namespace cryptonote
 | 
			
		|||
    std::atomic<bool> m_is_in_checkpoint_zone;
 | 
			
		||||
    std::atomic<bool> m_is_blockchain_storing;
 | 
			
		||||
 | 
			
		||||
    bool switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain);
 | 
			
		||||
    bool switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain, bool discard_disconnected_chain);
 | 
			
		||||
    bool pop_block_from_blockchain();
 | 
			
		||||
    bool purge_block_data_from_blockchain(const block& b, size_t processed_tx_count);
 | 
			
		||||
    bool purge_transaction_from_blockchain(const crypto::hash& tx_id);
 | 
			
		||||
| 
						 | 
				
			
			@ -301,7 +303,7 @@ namespace cryptonote
 | 
			
		|||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      transactions_container::iterator tx_it = m_transactions.find(amount_outs_vec[i].first);
 | 
			
		||||
      CHECK_AND_ASSERT_MES(tx_it != m_transactions.end(), false, "Wrong transaction id in output indexes: " <<string_tools::pod_to_hex(amount_outs_vec[i].first));
 | 
			
		||||
      CHECK_AND_ASSERT_MES(tx_it != m_transactions.end(), false, "Wrong transaction id in output indexes: " << epee::string_tools::pod_to_hex(amount_outs_vec[i].first));
 | 
			
		||||
      CHECK_AND_ASSERT_MES(amount_outs_vec[i].second < tx_it->second.tx.vout.size(), false,
 | 
			
		||||
        "Wrong index in transaction outputs: " << amount_outs_vec[i].second << ", expected less then " << tx_it->second.tx.vout.size());
 | 
			
		||||
      if(!vis.handle_output(tx_it->second.tx, tx_it->second.tx.vout[amount_outs_vec[i].second]))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -29,10 +29,11 @@ namespace cryptonote
 | 
			
		|||
    return !m_points.empty() && (height <= (--m_points.end())->first);
 | 
			
		||||
  }
 | 
			
		||||
  //---------------------------------------------------------------------------
 | 
			
		||||
  bool checkpoints::check_block(uint64_t height, const crypto::hash& h) const
 | 
			
		||||
  bool checkpoints::check_block(uint64_t height, const crypto::hash& h, bool& is_a_checkpoint) const
 | 
			
		||||
  {
 | 
			
		||||
    auto it = m_points.find(height);
 | 
			
		||||
    if(it == m_points.end())
 | 
			
		||||
    is_a_checkpoint = it != m_points.end();
 | 
			
		||||
    if(!is_a_checkpoint)
 | 
			
		||||
      return true;
 | 
			
		||||
 | 
			
		||||
    if(it->second == h)
 | 
			
		||||
| 
						 | 
				
			
			@ -45,4 +46,25 @@ namespace cryptonote
 | 
			
		|||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  //---------------------------------------------------------------------------
 | 
			
		||||
  bool checkpoints::check_block(uint64_t height, const crypto::hash& h) const
 | 
			
		||||
  {
 | 
			
		||||
    bool ignored;
 | 
			
		||||
    return check_block(height, h, ignored);
 | 
			
		||||
  }
 | 
			
		||||
  //---------------------------------------------------------------------------
 | 
			
		||||
  bool checkpoints::is_alternative_block_allowed(uint64_t blockchain_height, uint64_t block_height) const
 | 
			
		||||
  {
 | 
			
		||||
    if (0 == block_height)
 | 
			
		||||
      return false;
 | 
			
		||||
 | 
			
		||||
    auto it = m_points.upper_bound(blockchain_height);
 | 
			
		||||
    // Is blockchain_height before the first checkpoint?
 | 
			
		||||
    if (it == m_points.begin())
 | 
			
		||||
      return true;
 | 
			
		||||
 | 
			
		||||
    --it;
 | 
			
		||||
    uint64_t checkpoint_height = it->first;
 | 
			
		||||
    return checkpoint_height < block_height;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,6 +16,9 @@ namespace cryptonote
 | 
			
		|||
    bool add_checkpoint(uint64_t height, const std::string& hash_str);
 | 
			
		||||
    bool is_in_checkpoint_zone(uint64_t height) const;
 | 
			
		||||
    bool check_block(uint64_t height, const crypto::hash& h) const;
 | 
			
		||||
    bool check_block(uint64_t height, const crypto::hash& h, bool& is_a_checkpoint) const;
 | 
			
		||||
    bool is_alternative_block_allowed(uint64_t blockchain_height, uint64_t block_height) const;
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    std::map<uint64_t, crypto::hash> m_points;
 | 
			
		||||
  };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -12,12 +12,9 @@
 | 
			
		|||
namespace cryptonote {
 | 
			
		||||
  inline bool create_checkpoints(cryptonote::checkpoints& checkpoints)
 | 
			
		||||
  {      
 | 
			
		||||
    // Checkpointing disabled until we can make the client not fast-sync
 | 
			
		||||
    // without checking PoW at some point. Otherwise we may be exposed
 | 
			
		||||
    // to blockchain corruption attacks. Need to investigate this further.
 | 
			
		||||
    // 8-5-14
 | 
			
		||||
    // ADD_CHECKPOINT(22231, "7cb10e29d67e1c069e6e11b17d30b809724255fee2f6868dc14cfc6ed44dfb25");
 | 
			
		||||
    // ADD_CHECKPOINT(29556, "53c484a8ed91e4da621bb2fa88106dbde426fe90d7ef07b9c1e5127fb6f3a7f6");
 | 
			
		||||
    ADD_CHECKPOINT(22231, "7cb10e29d67e1c069e6e11b17d30b809724255fee2f6868dc14cfc6ed44dfb25");
 | 
			
		||||
    ADD_CHECKPOINT(29556, "53c484a8ed91e4da621bb2fa88106dbde426fe90d7ef07b9c1e5127fb6f3a7f6");
 | 
			
		||||
    ADD_CHECKPOINT(50000, "0fe8758ab06a8b9cb35b7328fd4f757af530a5d37759f9d3e421023231f7b31c");
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -502,7 +502,7 @@ namespace cryptonote
 | 
			
		|||
      LOG_PRINT_L0(ENDL << "**********************************************************************" << ENDL 
 | 
			
		||||
        << "The daemon will start synchronizing with the network. It may take up to several hours." << ENDL 
 | 
			
		||||
        << ENDL
 | 
			
		||||
        << "You can set the level of process detailization by using command \"set_log <level>\", where <level> is either 0 (no details), 1 (current block height synchronized), or 2 (all details)." << ENDL
 | 
			
		||||
        << "You can set the level of process detailization* through \"set_log <level>\" command*, where <level> is between 0 (no details) and 4 (very verbose)." << ENDL
 | 
			
		||||
        << ENDL
 | 
			
		||||
        << "Use \"help\" command to see the list of available commands." << ENDL
 | 
			
		||||
        << ENDL
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -115,13 +115,13 @@ namespace cryptonote
 | 
			
		|||
     tx_memory_pool m_mempool;
 | 
			
		||||
     blockchain_storage m_blockchain_storage;
 | 
			
		||||
     i_cryptonote_protocol* m_pprotocol;
 | 
			
		||||
     critical_section m_incoming_tx_lock;
 | 
			
		||||
     epee::critical_section m_incoming_tx_lock;
 | 
			
		||||
     //m_miner and m_miner_addres are probably temporary here
 | 
			
		||||
     miner m_miner;
 | 
			
		||||
     account_public_address m_miner_address;
 | 
			
		||||
     std::string m_config_folder;
 | 
			
		||||
     cryptonote_protocol_stub m_protocol_stub;
 | 
			
		||||
     math_helper::once_a_time_seconds<60*60*12, false> m_store_blockchain_interval;
 | 
			
		||||
     epee::math_helper::once_a_time_seconds<60*60*12, false> m_store_blockchain_interval;
 | 
			
		||||
     friend class tx_validate_inputs;
 | 
			
		||||
     std::atomic<bool> m_starter_message_showed;
 | 
			
		||||
   };
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -239,8 +239,7 @@ namespace cryptonote
 | 
			
		|||
  crypto::public_key get_tx_pub_key_from_extra(const std::vector<uint8_t>& tx_extra)
 | 
			
		||||
  {
 | 
			
		||||
    std::vector<tx_extra_field> tx_extra_fields;
 | 
			
		||||
    if (!parse_tx_extra(tx_extra, tx_extra_fields))
 | 
			
		||||
      return null_pkey;
 | 
			
		||||
    parse_tx_extra(tx_extra, tx_extra_fields);
 | 
			
		||||
 | 
			
		||||
    tx_extra_pub_key pub_key_field;
 | 
			
		||||
    if(!find_tx_extra_field_by_type(tx_extra_fields, pub_key_field))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,6 @@
 | 
			
		|||
 | 
			
		||||
#pragma once 
 | 
			
		||||
 | 
			
		||||
#include <boost/atomic.hpp>
 | 
			
		||||
#include <boost/program_options.hpp>
 | 
			
		||||
#include <atomic>
 | 
			
		||||
#include "cryptonote_basic.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +63,7 @@ namespace cryptonote
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
    volatile uint32_t m_stop;
 | 
			
		||||
    ::critical_section m_template_lock;
 | 
			
		||||
    epee::critical_section m_template_lock;
 | 
			
		||||
    block m_template;
 | 
			
		||||
    std::atomic<uint32_t> m_template_no;
 | 
			
		||||
    std::atomic<uint32_t> m_starter_nonce;
 | 
			
		||||
| 
						 | 
				
			
			@ -73,21 +72,21 @@ namespace cryptonote
 | 
			
		|||
    volatile uint32_t m_thread_index; 
 | 
			
		||||
    volatile uint32_t m_threads_total;
 | 
			
		||||
    std::atomic<int32_t> m_pausers_count;
 | 
			
		||||
    ::critical_section m_miners_count_lock;
 | 
			
		||||
    epee::critical_section m_miners_count_lock;
 | 
			
		||||
 | 
			
		||||
    std::list<boost::thread> m_threads;
 | 
			
		||||
    ::critical_section m_threads_lock;
 | 
			
		||||
    epee::critical_section m_threads_lock;
 | 
			
		||||
    i_miner_handler* m_phandler;
 | 
			
		||||
    account_public_address m_mine_address;
 | 
			
		||||
    math_helper::once_a_time_seconds<5> m_update_block_template_interval;
 | 
			
		||||
    math_helper::once_a_time_seconds<2> m_update_merge_hr_interval;
 | 
			
		||||
    epee::math_helper::once_a_time_seconds<5> m_update_block_template_interval;
 | 
			
		||||
    epee::math_helper::once_a_time_seconds<2> m_update_merge_hr_interval;
 | 
			
		||||
    std::vector<blobdata> m_extra_messages;
 | 
			
		||||
    miner_config m_config;
 | 
			
		||||
    std::string m_config_folder_path;    
 | 
			
		||||
    std::atomic<uint64_t> m_last_hr_merge_time;
 | 
			
		||||
    std::atomic<uint64_t> m_hashes;
 | 
			
		||||
    std::atomic<uint64_t> m_current_hash_rate;
 | 
			
		||||
    critical_section m_last_hash_rates_lock;
 | 
			
		||||
    epee::critical_section m_last_hash_rates_lock;
 | 
			
		||||
    std::list<uint64_t> m_last_hash_rates;
 | 
			
		||||
    bool m_do_print_hashrate;
 | 
			
		||||
    bool m_do_mining;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -135,7 +135,6 @@ namespace cryptonote
 | 
			
		|||
  //   varint tag;
 | 
			
		||||
  //   varint size;
 | 
			
		||||
  //   varint data[];
 | 
			
		||||
  //typedef boost::variant<tx_extra_padding, tx_extra_pub_key, tx_extra_nonce> tx_extra_field;
 | 
			
		||||
  typedef boost::variant<tx_extra_padding, tx_extra_pub_key, tx_extra_nonce, tx_extra_merge_mining_tag> tx_extra_field;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -350,18 +350,69 @@ namespace cryptonote
 | 
			
		|||
  //---------------------------------------------------------------------------------
 | 
			
		||||
  bool tx_memory_pool::fill_block_template(block &bl, size_t median_size, uint64_t already_generated_coins, size_t &total_size, uint64_t &fee)
 | 
			
		||||
  {
 | 
			
		||||
    // Warning: This function takes already_generated_
 | 
			
		||||
    // coins as an argument and appears to do nothing
 | 
			
		||||
    // with it.
 | 
			
		||||
 | 
			
		||||
    CRITICAL_REGION_LOCAL(m_transactions_lock);
 | 
			
		||||
 | 
			
		||||
    total_size = 0;
 | 
			
		||||
    fee = 0;
 | 
			
		||||
 | 
			
		||||
    size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
 | 
			
		||||
    size_t max_total_size = 2 * median_size - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE; // Max block size
 | 
			
		||||
    std::unordered_set<crypto::key_image> k_images;
 | 
			
		||||
 | 
			
		||||
    // Tx size limit as in wallet2.h
 | 
			
		||||
    // tx_pool.cpp uses size_t for tx sizes, whereas
 | 
			
		||||
    // wallet2.h uses uint64_t; just use size_t here 
 | 
			
		||||
    // for now
 | 
			
		||||
    size_t upper_transaction_size_limit = ((CRYPTONOTE_BLOCK_GRANTED_FULL_REWARD_ZONE * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
 | 
			
		||||
 | 
			
		||||
    // Calculate size limit based on median too; useful
 | 
			
		||||
    // for when we actually fix wallet2.h's maximum
 | 
			
		||||
    // allowable tx size
 | 
			
		||||
    //
 | 
			
		||||
    // Can be removed when wallet2.h calculates max
 | 
			
		||||
    // tx size based on the median too; just use
 | 
			
		||||
    // upper_transaction_size_limit_median in all cases
 | 
			
		||||
    size_t upper_transaction_size_limit_median = ((median_size * 125) / 100) - CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE;
 | 
			
		||||
    if (upper_transaction_size_limit_median > upper_transaction_size_limit)
 | 
			
		||||
      upper_transaction_size_limit = upper_transaction_size_limit_median;
 | 
			
		||||
 | 
			
		||||
    BOOST_FOREACH(transactions_container::value_type& tx, m_transactions)
 | 
			
		||||
    {
 | 
			
		||||
      // Can not exceed maximum block size
 | 
			
		||||
      if (max_total_size < total_size + tx.second.blob_size)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      // Check to see if the minimum fee is included;
 | 
			
		||||
      // exclude tx missing minimum fee
 | 
			
		||||
      if (tx.second.fee < DEFAULT_FEE)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      // Skip transactions that are too large
 | 
			
		||||
      // TODO: Correct upper_transactions_size_limit
 | 
			
		||||
      // such that it is based on median block size;
 | 
			
		||||
      // We need to make a similar patch for
 | 
			
		||||
      // wallet2.h
 | 
			
		||||
      if (tx.second.blob_size > upper_transaction_size_limit)
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      // If adding this tx will make the block size
 | 
			
		||||
      // greater than 130% of the median, reject the
 | 
			
		||||
      // tx; this will keep down largely punitive tx
 | 
			
		||||
      // from being included
 | 
			
		||||
      if ( (total_size + tx.second.blob_size) > ((130 * median_size) / 100) )
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      // If we've exceeded the penalty free size,
 | 
			
		||||
      // stop including more tx
 | 
			
		||||
      if (total_size > median_size)
 | 
			
		||||
        break;      
 | 
			
		||||
 | 
			
		||||
      // Skip transactions that are not ready to be
 | 
			
		||||
      // included into the blockchain or that are
 | 
			
		||||
      // missing key images
 | 
			
		||||
      if (!is_transaction_ready_to_go(tx.second) || have_key_images(k_images, tx.second.tx))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,8 +4,6 @@
 | 
			
		|||
 | 
			
		||||
#pragma once
 | 
			
		||||
#include "include_base_utils.h"
 | 
			
		||||
using namespace epee;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#include <set>
 | 
			
		||||
#include <unordered_map>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ namespace cryptonote
 | 
			
		|||
    template<class t_parametr>
 | 
			
		||||
      bool post_notify(typename t_parametr::request& arg, cryptonote_connection_context& context)
 | 
			
		||||
      {
 | 
			
		||||
        LOG_PRINT_L2("[" << net_utils::print_connection_context_short(context) << "] post " << typeid(t_parametr).name() << " -->");
 | 
			
		||||
        LOG_PRINT_L2("[" << epee::net_utils::print_connection_context_short(context) << "] post " << typeid(t_parametr).name() << " -->");
 | 
			
		||||
        std::string blob;
 | 
			
		||||
        epee::serialization::store_t_to_binary(arg, blob);
 | 
			
		||||
        return m_p2p->invoke_notify_to_peer(t_parametr::ID, blob, context);
 | 
			
		||||
| 
						 | 
				
			
			@ -90,7 +90,7 @@ namespace cryptonote
 | 
			
		|||
      template<class t_parametr>
 | 
			
		||||
      bool relay_post_notify(typename t_parametr::request& arg, cryptonote_connection_context& exlude_context)
 | 
			
		||||
      {
 | 
			
		||||
        LOG_PRINT_L2("[" << net_utils::print_connection_context_short(exlude_context) << "] post relay " << typeid(t_parametr).name() << " -->");
 | 
			
		||||
        LOG_PRINT_L2("[" << epee::net_utils::print_connection_context_short(exlude_context) << "] post relay " << typeid(t_parametr).name() << " -->");
 | 
			
		||||
        std::string arg_buff;
 | 
			
		||||
        epee::serialization::store_t_to_binary(arg, arg_buff);
 | 
			
		||||
        return m_p2p->relay_notify_to_all(t_parametr::ID, arg_buff, exlude_context);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ namespace cryptonote
 | 
			
		|||
    m_p2p->for_each_connection([&](const connection_context& cntxt, nodetool::peerid_type peer_id)
 | 
			
		||||
    {
 | 
			
		||||
      ss << std::setw(25) << std::left << std::string(cntxt.m_is_income ? " [INC]":"[OUT]") + 
 | 
			
		||||
        string_tools::get_ip_string_from_int32(cntxt.m_remote_ip) + ":" + std::to_string(cntxt.m_remote_port) 
 | 
			
		||||
        epee::string_tools::get_ip_string_from_int32(cntxt.m_remote_ip) + ":" + std::to_string(cntxt.m_remote_port) 
 | 
			
		||||
        << std::setw(20) << std::hex << peer_id
 | 
			
		||||
        << std::setw(25) << std::to_string(cntxt.m_recv_cnt)+ "(" + std::to_string(time(NULL) - cntxt.m_last_recv) + ")" + "/" + std::to_string(cntxt.m_send_cnt) + "(" + std::to_string(time(NULL) - cntxt.m_last_send) + ")"
 | 
			
		||||
        << std::setw(25) << get_protocol_state_string(cntxt.m_state)
 | 
			
		||||
| 
						 | 
				
			
			@ -108,9 +108,12 @@ namespace cryptonote
 | 
			
		|||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    LOG_PRINT_CCONTEXT_YELLOW("Sync data returned unknown top block: " << m_core.get_current_blockchain_height() << "->" << hshd.current_height 
 | 
			
		||||
      << "[" << static_cast<int64_t>(hshd.current_height - m_core.get_current_blockchain_height()) << " blocks(" << (hshd.current_height - m_core.get_current_blockchain_height()) /1440 << " days) behind] " << ENDL 
 | 
			
		||||
      << "remote top: "  << hshd.top_id << "[" << hshd.current_height << "]" << ", set SYNCHRONIZATION mode", (is_inital ? LOG_LEVEL_0:LOG_LEVEL_1));
 | 
			
		||||
    int64_t diff = static_cast<int64_t>(hshd.current_height) - static_cast<int64_t>(m_core.get_current_blockchain_height());
 | 
			
		||||
    LOG_PRINT_CCONTEXT_YELLOW("Sync data returned unknown top block: " << m_core.get_current_blockchain_height() << " -> " << hshd.current_height
 | 
			
		||||
      << " [" << std::abs(diff) << " blocks (" << diff / (24 * 60 * 60 / DIFFICULTY_TARGET) << " days) "
 | 
			
		||||
      << (0 <= diff ? std::string("behind") : std::string("ahead"))
 | 
			
		||||
      << "] " << ENDL << "SYNCHRONIZATION started", (is_inital ? LOG_LEVEL_0:LOG_LEVEL_1));
 | 
			
		||||
    LOG_PRINT_L1("Remote top block height: " << hshd.current_height << ", id: " << hshd.top_id);
 | 
			
		||||
    context.m_state = cryptonote_connection_context::state_synchronizing;
 | 
			
		||||
    context.m_remote_blockchain_height = hshd.current_height;
 | 
			
		||||
    //let the socket to send response to handshake, but request callback, to let send request data after response
 | 
			
		||||
| 
						 | 
				
			
			@ -254,7 +257,7 @@ namespace cryptonote
 | 
			
		|||
      if(!parse_and_validate_block_from_blob(block_entry.block, b))
 | 
			
		||||
      {
 | 
			
		||||
        LOG_ERROR_CCONTEXT("sent wrong block: failed to parse and validate block: \r\n" 
 | 
			
		||||
          << string_tools::buff_to_hex_nodelimer(block_entry.block) << "\r\n dropping connection");
 | 
			
		||||
          << epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << "\r\n dropping connection");
 | 
			
		||||
        m_p2p->drop_connection(context);
 | 
			
		||||
        return 1;
 | 
			
		||||
      }      
 | 
			
		||||
| 
						 | 
				
			
			@ -274,14 +277,14 @@ namespace cryptonote
 | 
			
		|||
      auto req_it = context.m_requested_objects.find(get_block_hash(b));
 | 
			
		||||
      if(req_it == context.m_requested_objects.end())
 | 
			
		||||
      {
 | 
			
		||||
        LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << string_tools::pod_to_hex(get_blob_hash(block_entry.block)) 
 | 
			
		||||
        LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) 
 | 
			
		||||
          << " wasn't requested, dropping connection");
 | 
			
		||||
        m_p2p->drop_connection(context);
 | 
			
		||||
        return 1;
 | 
			
		||||
      }
 | 
			
		||||
      if(b.tx_hashes.size() != block_entry.txs.size()) 
 | 
			
		||||
      {
 | 
			
		||||
        LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << string_tools::pod_to_hex(get_blob_hash(block_entry.block)) 
 | 
			
		||||
        LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_OBJECTS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) 
 | 
			
		||||
          << ", tx_hashes.size()=" << b.tx_hashes.size() << " mismatch with block_complete_entry.m_txs.size()=" << block_entry.txs.size() << ", dropping connection");
 | 
			
		||||
        m_p2p->drop_connection(context);
 | 
			
		||||
        return 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -300,7 +303,7 @@ namespace cryptonote
 | 
			
		|||
 | 
			
		||||
    {
 | 
			
		||||
      m_core.pause_mine();
 | 
			
		||||
      misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler(
 | 
			
		||||
      epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler(
 | 
			
		||||
        boost::bind(&t_core::resume_mine, &m_core));
 | 
			
		||||
 | 
			
		||||
      BOOST_FOREACH(const block_complete_entry& block_entry, arg.blocks)
 | 
			
		||||
| 
						 | 
				
			
			@ -314,7 +317,7 @@ namespace cryptonote
 | 
			
		|||
          if(tvc.m_verifivation_failed)
 | 
			
		||||
          {
 | 
			
		||||
            LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_OBJECTS, \r\ntx_id = " 
 | 
			
		||||
              << string_tools::pod_to_hex(get_blob_hash(tx_blob)) << ", dropping connection");
 | 
			
		||||
              << epee::string_tools::pod_to_hex(get_blob_hash(tx_blob)) << ", dropping connection");
 | 
			
		||||
            m_p2p->drop_connection(context);
 | 
			
		||||
            return 1;
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			@ -408,7 +411,7 @@ namespace cryptonote
 | 
			
		|||
                           << "\r\nm_remote_blockchain_height=" << context.m_remote_blockchain_height
 | 
			
		||||
                           << "\r\nm_needed_objects.size()=" << context.m_needed_objects.size()
 | 
			
		||||
                           << "\r\nm_requested_objects.size()=" << context.m_requested_objects.size()
 | 
			
		||||
                           << "\r\non connection [" << net_utils::print_connection_context_short(context)<< "]");
 | 
			
		||||
                           << "\r\non connection [" << epee::net_utils::print_connection_context_short(context)<< "]");
 | 
			
		||||
      
 | 
			
		||||
      context.m_state = cryptonote_connection_context::state_normal;
 | 
			
		||||
      LOG_PRINT_CCONTEXT_GREEN(" SYNCHRONIZED OK", LOG_LEVEL_0);
 | 
			
		||||
| 
						 | 
				
			
			@ -464,7 +467,7 @@ namespace cryptonote
 | 
			
		|||
    if(!m_core.have_block(arg.m_block_ids.front()))
 | 
			
		||||
    {
 | 
			
		||||
      LOG_ERROR_CCONTEXT("sent m_block_ids starting from unknown id: "
 | 
			
		||||
                                              << string_tools::pod_to_hex(arg.m_block_ids.front()) << " , dropping connection");
 | 
			
		||||
                                              << epee::string_tools::pod_to_hex(arg.m_block_ids.front()) << " , dropping connection");
 | 
			
		||||
      m_p2p->drop_connection(context);
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@
 | 
			
		|||
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
 | 
			
		||||
#include "common/util.h"
 | 
			
		||||
#include "crypto/hash.h"
 | 
			
		||||
#include "version.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class daemon_cmmands_handler
 | 
			
		||||
| 
						 | 
				
			
			@ -34,6 +35,7 @@ public:
 | 
			
		|||
    m_cmd_binder.set_handler("show_hr", boost::bind(&daemon_cmmands_handler::show_hr, this, _1), "Start showing hash rate");
 | 
			
		||||
    m_cmd_binder.set_handler("hide_hr", boost::bind(&daemon_cmmands_handler::hide_hr, this, _1), "Stop showing hash rate");
 | 
			
		||||
    m_cmd_binder.set_handler("save", boost::bind(&daemon_cmmands_handler::save, this, _1), "Save blockchain");
 | 
			
		||||
    m_cmd_binder.set_handler("set_log", boost::bind(&daemon_cmmands_handler::set_log, this, _1), "set_log <level> - Change current log detalization level, <level> is a number 0-4");
 | 
			
		||||
    m_cmd_binder.set_handler("diff", boost::bind(&daemon_cmmands_handler::diff, this, _1), "Show difficulty");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -55,6 +57,7 @@ private:
 | 
			
		|||
  std::string get_commands_str()
 | 
			
		||||
  {
 | 
			
		||||
    std::stringstream ss;
 | 
			
		||||
    ss << CRYPTONOTE_NAME << " v" << PROJECT_VERSION_LONG << ENDL;
 | 
			
		||||
    ss << "Commands: " << ENDL;
 | 
			
		||||
    std::string usage = m_cmd_binder.get_usage();
 | 
			
		||||
    boost::replace_all(usage, "\n", "\n  ");
 | 
			
		||||
| 
						 | 
				
			
			@ -135,19 +138,34 @@ private:
 | 
			
		|||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    uint64_t start_index = 0;
 | 
			
		||||
    uint64_t end_index = 0;
 | 
			
		||||
    uint64_t end_block_parametr = m_srv.get_payload_object().get_core().get_current_blockchain_height();
 | 
			
		||||
    if(!string_tools::get_xtype_from_string(start_index, args[0]))
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "wrong starter block index parameter" << ENDL;
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    if(args.size() >1 && !string_tools::get_xtype_from_string(end_block_parametr, args[1]))
 | 
			
		||||
    if(args.size() >1 && !string_tools::get_xtype_from_string(end_index, args[1]))
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "wrong end block index parameter" << ENDL;
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (end_index == 0)
 | 
			
		||||
    {
 | 
			
		||||
      end_index = end_block_parametr;
 | 
			
		||||
    }
 | 
			
		||||
    if (end_index > end_block_parametr)
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "end block index parameter shouldn't be greater than " << end_block_parametr << ENDL;
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (end_index <= start_index)
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "end block index should be greater than starter block index" << ENDL;
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    m_srv.get_payload_object().get_core().print_blockchain(start_index, end_block_parametr);
 | 
			
		||||
    m_srv.get_payload_object().get_core().print_blockchain(start_index, end_index);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  //--------------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -156,6 +174,33 @@ private:
 | 
			
		|||
    m_srv.get_payload_object().get_core().print_blockchain_index();
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool set_log(const std::vector<std::string>& args)
 | 
			
		||||
  {
 | 
			
		||||
    if(args.size() != 1)
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "use: set_log <log_level_number_0-4>" << ENDL;
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint16_t l = 0;
 | 
			
		||||
    if(!string_tools::get_xtype_from_string(l, args[0]))
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "wrong number format, use: set_log <log_level_number_0-4>" << ENDL;
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(LOG_LEVEL_4 < l)
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "wrong number range, use: set_log <log_level_number_0-4>" << ENDL;
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    log_space::log_singletone::get_set_log_detalisation_level(true, l);
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //--------------------------------------------------------------------------------
 | 
			
		||||
  template <typename T>
 | 
			
		||||
  static bool print_as_json(T& obj)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,8 +24,7 @@
 | 
			
		|||
#include "p2p_networks.h"
 | 
			
		||||
#include "math_helper.h"
 | 
			
		||||
#include "net_node_common.h"
 | 
			
		||||
 | 
			
		||||
using namespace epee;
 | 
			
		||||
#include "common/command_line.h"
 | 
			
		||||
 | 
			
		||||
PUSH_WARNINGS
 | 
			
		||||
DISABLE_VS_WARNINGS(4355)
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +38,7 @@ namespace nodetool
 | 
			
		|||
  };
 | 
			
		||||
 | 
			
		||||
  template<class t_payload_net_handler>
 | 
			
		||||
  class node_server: public levin::levin_commands_handler<p2p_connection_context_t<typename t_payload_net_handler::connection_context> >,
 | 
			
		||||
  class node_server: public epee::levin::levin_commands_handler<p2p_connection_context_t<typename t_payload_net_handler::connection_context> >,
 | 
			
		||||
                     public i_p2p_endpoint<typename t_payload_net_handler::connection_context>
 | 
			
		||||
  {
 | 
			
		||||
    struct by_conn_id{};
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +125,7 @@ namespace nodetool
 | 
			
		|||
    bool parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr);
 | 
			
		||||
    bool handle_command_line(const boost::program_options::variables_map& vm);
 | 
			
		||||
    bool idle_worker();
 | 
			
		||||
    bool handle_remote_peerlist(const std::list<peerlist_entry>& peerlist, time_t local_time, const net_utils::connection_context_base& context);
 | 
			
		||||
    bool handle_remote_peerlist(const std::list<peerlist_entry>& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context);
 | 
			
		||||
    bool get_local_node_data(basic_node_data& node_data);
 | 
			
		||||
    //bool get_local_handshake_data(handshake_data& hshd);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -136,7 +135,7 @@ namespace nodetool
 | 
			
		|||
    bool connections_maker();
 | 
			
		||||
    bool peer_sync_idle_maker();
 | 
			
		||||
    bool do_handshake_with_peer(peerid_type& pi, p2p_connection_context& context, bool just_take_peerlist = false);
 | 
			
		||||
    bool do_peer_timed_sync(const net_utils::connection_context_base& context, peerid_type peer_id);
 | 
			
		||||
    bool do_peer_timed_sync(const epee::net_utils::connection_context_base& context, peerid_type peer_id);
 | 
			
		||||
 | 
			
		||||
    bool make_new_connection_from_peerlist(bool use_white_list);
 | 
			
		||||
    bool try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist = false, uint64_t last_seen_stamp = 0, bool white = true);
 | 
			
		||||
| 
						 | 
				
			
			@ -146,12 +145,19 @@ namespace nodetool
 | 
			
		|||
    template<class t_callback>
 | 
			
		||||
    bool try_ping(basic_node_data& node_data, p2p_connection_context& context, t_callback cb);
 | 
			
		||||
    bool make_expected_connections_count(bool white_list, size_t expected_connections);
 | 
			
		||||
    bool is_priority_node(const net_address& na);
 | 
			
		||||
 | 
			
		||||
    template <class Container>
 | 
			
		||||
    bool connect_to_peerlist(const Container& peers);
 | 
			
		||||
 | 
			
		||||
    template <class Container>
 | 
			
		||||
    bool parse_peers_and_add_to_container(const boost::program_options::variables_map& vm, const command_line::arg_descriptor<std::vector<std::string> > & arg, Container& container);
 | 
			
		||||
 | 
			
		||||
    //debug functions
 | 
			
		||||
    std::string print_connections_container();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    typedef net_utils::boosted_tcp_server<levin::async_protocol_handler<p2p_connection_context> > net_server;
 | 
			
		||||
    typedef epee::net_utils::boosted_tcp_server<epee::levin::async_protocol_handler<p2p_connection_context> > net_server;
 | 
			
		||||
 | 
			
		||||
    struct config
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -181,9 +187,9 @@ namespace nodetool
 | 
			
		|||
    t_payload_net_handler& m_payload_handler;
 | 
			
		||||
    peerlist_manager m_peerlist;
 | 
			
		||||
 | 
			
		||||
    math_helper::once_a_time_seconds<P2P_DEFAULT_HANDSHAKE_INTERVAL> m_peer_handshake_idle_maker_interval;
 | 
			
		||||
    math_helper::once_a_time_seconds<1> m_connections_maker_interval;
 | 
			
		||||
    math_helper::once_a_time_seconds<60*30, false> m_peerlist_store_interval;
 | 
			
		||||
    epee::math_helper::once_a_time_seconds<P2P_DEFAULT_HANDSHAKE_INTERVAL> m_peer_handshake_idle_maker_interval;
 | 
			
		||||
    epee::math_helper::once_a_time_seconds<1> m_connections_maker_interval;
 | 
			
		||||
    epee::math_helper::once_a_time_seconds<60*30, false> m_peerlist_store_interval;
 | 
			
		||||
 | 
			
		||||
    std::string m_bind_ip;
 | 
			
		||||
    std::string m_port;
 | 
			
		||||
| 
						 | 
				
			
			@ -191,6 +197,7 @@ namespace nodetool
 | 
			
		|||
    uint64_t m_last_stat_request_time;
 | 
			
		||||
#endif
 | 
			
		||||
    std::list<net_address>   m_priority_peers;
 | 
			
		||||
    std::vector<net_address> m_exclusive_peers;
 | 
			
		||||
    std::vector<net_address> m_seed_nodes;
 | 
			
		||||
    std::list<nodetool::peerlist_entry> m_command_line_peers;
 | 
			
		||||
    uint64_t m_peer_livetime;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,9 +4,10 @@
 | 
			
		|||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include "version.h"
 | 
			
		||||
#include "string_tools.h"
 | 
			
		||||
#include "common/command_line.h"
 | 
			
		||||
#include "common/util.h"
 | 
			
		||||
#include "net/net_helper.h"
 | 
			
		||||
#include "math_helper.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -31,8 +32,11 @@ namespace nodetool
 | 
			
		|||
    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<std::vector<std::string> > arg_p2p_add_exclusive_node   = {"add-exclusive-node", "Specify list of peers to connect to only."
 | 
			
		||||
                                                                                                  " If this option is given the options add-priority-node and seed-node are ignored"};
 | 
			
		||||
    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_hide_my_port   =    {"hide-my-port", "Do not announce yourself as peerlist candidate", false, true};
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
  template<class t_payload_net_handler>
 | 
			
		||||
| 
						 | 
				
			
			@ -44,6 +48,7 @@ namespace nodetool
 | 
			
		|||
    command_line::add_arg(desc, arg_p2p_allow_local_ip);
 | 
			
		||||
    command_line::add_arg(desc, arg_p2p_add_peer);
 | 
			
		||||
    command_line::add_arg(desc, arg_p2p_add_priority_node);
 | 
			
		||||
    command_line::add_arg(desc, arg_p2p_add_exclusive_node);
 | 
			
		||||
    command_line::add_arg(desc, arg_p2p_seed_node);    
 | 
			
		||||
    command_line::add_arg(desc, arg_p2p_hide_my_port);   }
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -96,7 +101,7 @@ namespace nodetool
 | 
			
		|||
  template<class t_payload_net_handler>
 | 
			
		||||
  bool node_server<t_payload_net_handler>::parse_peer_from_string(nodetool::net_address& pe, const std::string& node_addr)
 | 
			
		||||
  {
 | 
			
		||||
    return string_tools::parse_peer_from_string(pe.ip, pe.port, node_addr);
 | 
			
		||||
    return epee::string_tools::parse_peer_from_string(pe.ip, pe.port, node_addr);
 | 
			
		||||
  }
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
  template<class t_payload_net_handler>
 | 
			
		||||
| 
						 | 
				
			
			@ -120,30 +125,26 @@ namespace nodetool
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (command_line::has_arg(vm, arg_p2p_add_priority_node))
 | 
			
		||||
    {       
 | 
			
		||||
      std::vector<std::string> perrs = command_line::get_arg(vm, arg_p2p_add_priority_node);
 | 
			
		||||
      for(const std::string& pr_str: perrs)
 | 
			
		||||
      {
 | 
			
		||||
        nodetool::net_address na = AUTO_VAL_INIT(na);
 | 
			
		||||
        bool r = parse_peer_from_string(na, pr_str);
 | 
			
		||||
        CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str);
 | 
			
		||||
        m_priority_peers.push_back(na);
 | 
			
		||||
      }
 | 
			
		||||
    if (command_line::has_arg(vm,arg_p2p_add_exclusive_node))
 | 
			
		||||
    {
 | 
			
		||||
      if (!parse_peers_and_add_to_container(vm, arg_p2p_add_exclusive_node, m_exclusive_peers))
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    else if (command_line::has_arg(vm, arg_p2p_add_priority_node))
 | 
			
		||||
    {
 | 
			
		||||
      if (!parse_peers_and_add_to_container(vm, arg_p2p_add_priority_node, m_priority_peers))
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
    if (command_line::has_arg(vm, arg_p2p_seed_node))
 | 
			
		||||
    {
 | 
			
		||||
      std::vector<std::string> seed_perrs = command_line::get_arg(vm, arg_p2p_seed_node);
 | 
			
		||||
      for(const std::string& pr_str: seed_perrs)
 | 
			
		||||
      {
 | 
			
		||||
        nodetool::net_address na = AUTO_VAL_INIT(na);
 | 
			
		||||
        bool r = parse_peer_from_string(na, pr_str);
 | 
			
		||||
        CHECK_AND_ASSERT_MES(r, false, "Failed to parse seed address from string: " << pr_str);
 | 
			
		||||
        m_seed_nodes.push_back(na);
 | 
			
		||||
      }
 | 
			
		||||
      if (!parse_peers_and_add_to_container(vm, arg_p2p_seed_node, m_seed_nodes))
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(command_line::has_arg(vm, arg_p2p_hide_my_port))
 | 
			
		||||
      m_hide_my_port = true;    return true;
 | 
			
		||||
      m_hide_my_port = true;
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
  namespace
 | 
			
		||||
| 
						 | 
				
			
			@ -353,23 +354,23 @@ namespace nodetool
 | 
			
		|||
    get_local_node_data(arg.node_data);
 | 
			
		||||
    m_payload_handler.get_payload_sync_data(arg.payload_data);
 | 
			
		||||
    
 | 
			
		||||
    simple_event ev;
 | 
			
		||||
    epee::simple_event ev;
 | 
			
		||||
    std::atomic<bool> hsh_result(false);
 | 
			
		||||
    
 | 
			
		||||
    bool r = net_utils::async_invoke_remote_command2<typename COMMAND_HANDSHAKE::response>(context_.m_connection_id, COMMAND_HANDSHAKE::ID, arg, m_net_server.get_config_object(), 
 | 
			
		||||
    bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_HANDSHAKE::response>(context_.m_connection_id, COMMAND_HANDSHAKE::ID, arg, m_net_server.get_config_object(), 
 | 
			
		||||
      [this, &pi, &ev, &hsh_result, &just_take_peerlist](int code, const typename COMMAND_HANDSHAKE::response& rsp, p2p_connection_context& context)
 | 
			
		||||
    {
 | 
			
		||||
      misc_utils::auto_scope_leave_caller scope_exit_handler = misc_utils::create_scope_leave_handler([&](){ev.raise();});
 | 
			
		||||
      epee::misc_utils::auto_scope_leave_caller scope_exit_handler = epee::misc_utils::create_scope_leave_handler([&](){ev.raise();});
 | 
			
		||||
 | 
			
		||||
      if(code < 0)
 | 
			
		||||
      {
 | 
			
		||||
        LOG_PRINT_CC_RED(context, "COMMAND_HANDSHAKE invoke failed. (" << code <<  ", " << levin::get_err_descr(code) << ")", LOG_LEVEL_1);
 | 
			
		||||
        LOG_PRINT_CC_RED(context, "COMMAND_HANDSHAKE invoke failed. (" << code <<  ", " << epee::levin::get_err_descr(code) << ")", LOG_LEVEL_1);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if(rsp.node_data.network_id != BYTECOIN_NETWORK)
 | 
			
		||||
      {
 | 
			
		||||
        LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong network!  (" << string_tools::get_str_from_guid_a(rsp.node_data.network_id) << "), closing connection.");
 | 
			
		||||
        LOG_ERROR_CCONTEXT("COMMAND_HANDSHAKE Failed, wrong network!  (" << epee::string_tools::get_str_from_guid_a(rsp.node_data.network_id) << "), closing connection.");
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -397,10 +398,10 @@ namespace nodetool
 | 
			
		|||
          hsh_result = false;
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        LOG_PRINT_CCONTEXT_L0(" COMMAND_HANDSHAKE INVOKED OK");
 | 
			
		||||
        LOG_PRINT_CCONTEXT_L1(" COMMAND_HANDSHAKE INVOKED OK");
 | 
			
		||||
      }else
 | 
			
		||||
      {
 | 
			
		||||
        LOG_PRINT_CCONTEXT_L0(" COMMAND_HANDSHAKE(AND CLOSE) INVOKED OK");
 | 
			
		||||
        LOG_PRINT_CCONTEXT_L1(" COMMAND_HANDSHAKE(AND CLOSE) INVOKED OK");
 | 
			
		||||
      }
 | 
			
		||||
    }, P2P_DEFAULT_HANDSHAKE_INVOKE_TIMEOUT);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -411,7 +412,7 @@ namespace nodetool
 | 
			
		|||
 | 
			
		||||
    if(!hsh_result)
 | 
			
		||||
    {
 | 
			
		||||
      LOG_PRINT_CC_L0(context_, "COMMAND_HANDSHAKE Failed");
 | 
			
		||||
      LOG_PRINT_CC_L1(context_, "COMMAND_HANDSHAKE Failed");
 | 
			
		||||
      m_net_server.get_config_object().close(context_.m_connection_id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -419,17 +420,17 @@ namespace nodetool
 | 
			
		|||
  }
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
  template<class t_payload_net_handler>
 | 
			
		||||
  bool node_server<t_payload_net_handler>::do_peer_timed_sync(const net_utils::connection_context_base& context_, peerid_type peer_id)
 | 
			
		||||
  bool node_server<t_payload_net_handler>::do_peer_timed_sync(const epee::net_utils::connection_context_base& context_, peerid_type peer_id)
 | 
			
		||||
  {
 | 
			
		||||
    typename COMMAND_TIMED_SYNC::request arg = AUTO_VAL_INIT(arg);
 | 
			
		||||
    m_payload_handler.get_payload_sync_data(arg.payload_data);
 | 
			
		||||
 | 
			
		||||
    bool r = net_utils::async_invoke_remote_command2<typename COMMAND_TIMED_SYNC::response>(context_.m_connection_id, COMMAND_TIMED_SYNC::ID, arg, m_net_server.get_config_object(), 
 | 
			
		||||
    bool r = epee::net_utils::async_invoke_remote_command2<typename COMMAND_TIMED_SYNC::response>(context_.m_connection_id, COMMAND_TIMED_SYNC::ID, arg, m_net_server.get_config_object(), 
 | 
			
		||||
      [this](int code, const typename COMMAND_TIMED_SYNC::response& rsp, p2p_connection_context& context)
 | 
			
		||||
    {
 | 
			
		||||
      if(code < 0)
 | 
			
		||||
      {
 | 
			
		||||
        LOG_PRINT_CC_RED(context, "COMMAND_TIMED_SYNC invoke failed. (" << code <<  ", " << levin::get_err_descr(code) << ")", LOG_LEVEL_1);
 | 
			
		||||
        LOG_PRINT_CC_RED(context, "COMMAND_TIMED_SYNC invoke failed. (" << code <<  ", " << epee::levin::get_err_descr(code) << ")", LOG_LEVEL_1);
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -502,36 +503,53 @@ namespace nodetool
 | 
			
		|||
    return connected;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
#define LOG_PRINT_CC_PRIORITY_NODE(priority, con, msg) \
 | 
			
		||||
  do { \
 | 
			
		||||
    if (priority) {\
 | 
			
		||||
      LOG_PRINT_CC_L0(con, msg); \
 | 
			
		||||
    } else {\
 | 
			
		||||
      LOG_PRINT_CC_L1(con, msg); \
 | 
			
		||||
    } \
 | 
			
		||||
  } while(0)
 | 
			
		||||
 | 
			
		||||
  template<class t_payload_net_handler>
 | 
			
		||||
  bool node_server<t_payload_net_handler>::try_to_connect_and_handshake_with_new_peer(const net_address& na, bool just_take_peerlist, uint64_t last_seen_stamp, bool white)
 | 
			
		||||
  {
 | 
			
		||||
    LOG_PRINT_L0("Connecting to " << string_tools::get_ip_string_from_int32(na.ip)  << ":" << string_tools::num_to_string_fast(na.port) << "(white=" << white << ", last_seen: " << (last_seen_stamp?misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never" ) << ")...");
 | 
			
		||||
    LOG_PRINT_L1("Connecting to " << epee::string_tools::get_ip_string_from_int32(na.ip)  << ":"
 | 
			
		||||
        << epee::string_tools::num_to_string_fast(na.port) << "(white=" << white << ", last_seen: "
 | 
			
		||||
        << (last_seen_stamp ? epee::misc_utils::get_time_interval_string(time(NULL) - last_seen_stamp):"never")
 | 
			
		||||
        << ")...");
 | 
			
		||||
 | 
			
		||||
    typename net_server::t_connection_context con = AUTO_VAL_INIT(con);
 | 
			
		||||
    bool res = m_net_server.connect(string_tools::get_ip_string_from_int32(na.ip),
 | 
			
		||||
      string_tools::num_to_string_fast(na.port),
 | 
			
		||||
    bool res = m_net_server.connect(epee::string_tools::get_ip_string_from_int32(na.ip),
 | 
			
		||||
      epee::string_tools::num_to_string_fast(na.port),
 | 
			
		||||
      m_config.m_net_config.connection_timeout,
 | 
			
		||||
      con);
 | 
			
		||||
 | 
			
		||||
    if(!res)
 | 
			
		||||
    {
 | 
			
		||||
      LOG_PRINT_L0("Connect failed to "
 | 
			
		||||
        << string_tools::get_ip_string_from_int32(na.ip)
 | 
			
		||||
        << ":" << string_tools::num_to_string_fast(na.port)
 | 
			
		||||
      bool is_priority = is_priority_node(na);
 | 
			
		||||
      LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Connect failed to "
 | 
			
		||||
        << epee::string_tools::get_ip_string_from_int32(na.ip)
 | 
			
		||||
        << ":" << epee::string_tools::num_to_string_fast(na.port)
 | 
			
		||||
        /*<< ", try " << try_count*/);
 | 
			
		||||
      //m_peerlist.set_peer_unreachable(pe);
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    peerid_type pi = AUTO_VAL_INIT(pi);
 | 
			
		||||
    res = do_handshake_with_peer(pi, con, just_take_peerlist);
 | 
			
		||||
 | 
			
		||||
    if(!res)
 | 
			
		||||
    {
 | 
			
		||||
      LOG_PRINT_CC_L0(con, "Failed to HANDSHAKE with peer "
 | 
			
		||||
        << string_tools::get_ip_string_from_int32(na.ip)
 | 
			
		||||
        << ":" << string_tools::num_to_string_fast(na.port)
 | 
			
		||||
      bool is_priority = is_priority_node(na);
 | 
			
		||||
      LOG_PRINT_CC_PRIORITY_NODE(is_priority, con, "Failed to HANDSHAKE with peer "
 | 
			
		||||
        << epee::string_tools::get_ip_string_from_int32(na.ip)
 | 
			
		||||
        << ":" << epee::string_tools::num_to_string_fast(na.port)
 | 
			
		||||
        /*<< ", try " << try_count*/);
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if(just_take_peerlist)
 | 
			
		||||
    {
 | 
			
		||||
      m_net_server.get_config_object().close(con.m_connection_id);
 | 
			
		||||
| 
						 | 
				
			
			@ -549,6 +567,9 @@ namespace nodetool
 | 
			
		|||
    LOG_PRINT_CC_GREEN(con, "CONNECTION HANDSHAKED OK.", LOG_LEVEL_2);
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#undef LOG_PRINT_CC_PRIORITY_NODE
 | 
			
		||||
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
  template<class t_payload_net_handler>
 | 
			
		||||
  bool node_server<t_payload_net_handler>::make_new_connection_from_peerlist(bool use_white_list)
 | 
			
		||||
| 
						 | 
				
			
			@ -582,7 +603,10 @@ namespace nodetool
 | 
			
		|||
      if(is_peer_used(pe))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      LOG_PRINT_L1("Selected peer: " << pe.id << " " << string_tools::get_ip_string_from_int32(pe.adr.ip) << ":" << boost::lexical_cast<std::string>(pe.adr.port) << "[white=" << use_white_list << "] last_seen: " << (pe.last_seen ? misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never"));
 | 
			
		||||
      LOG_PRINT_L1("Selected peer: " << pe.id << " " << epee::string_tools::get_ip_string_from_int32(pe.adr.ip)
 | 
			
		||||
                    << ":" << boost::lexical_cast<std::string>(pe.adr.port)
 | 
			
		||||
                    << "[white=" << use_white_list
 | 
			
		||||
                    << "] last_seen: " << (pe.last_seen ? epee::misc_utils::get_time_interval_string(time(NULL) - pe.last_seen) : "never"));
 | 
			
		||||
      
 | 
			
		||||
      if(!try_to_connect_and_handshake_with_new_peer(pe.adr, false, pe.last_seen, use_white_list))
 | 
			
		||||
        continue;
 | 
			
		||||
| 
						 | 
				
			
			@ -595,6 +619,10 @@ namespace nodetool
 | 
			
		|||
  template<class t_payload_net_handler>
 | 
			
		||||
  bool node_server<t_payload_net_handler>::connections_maker()
 | 
			
		||||
  {
 | 
			
		||||
    if (!connect_to_peerlist(m_exclusive_peers)) return false;
 | 
			
		||||
 | 
			
		||||
    if (!m_exclusive_peers.empty()) return true;
 | 
			
		||||
 | 
			
		||||
    if(!m_peerlist.get_white_peers_count() && m_seed_nodes.size())
 | 
			
		||||
    {
 | 
			
		||||
      size_t try_count = 0;
 | 
			
		||||
| 
						 | 
				
			
			@ -616,15 +644,7 @@ namespace nodetool
 | 
			
		|||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(const net_address& na: m_priority_peers)
 | 
			
		||||
    {
 | 
			
		||||
      if(m_net_server.is_stop_signal_sent())
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
      if(is_addr_connected(na))
 | 
			
		||||
        continue;
 | 
			
		||||
      try_to_connect_and_handshake_with_new_peer(na);
 | 
			
		||||
    }
 | 
			
		||||
    if (!connect_to_peerlist(m_priority_peers)) return false;
 | 
			
		||||
 | 
			
		||||
    size_t expected_white_connections = (m_config.m_net_config.connections_count*P2P_DEFAULT_WHITELIST_CONNECTIONS_PERCENT)/100;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -698,7 +718,7 @@ namespace nodetool
 | 
			
		|||
  bool node_server<t_payload_net_handler>::peer_sync_idle_maker()
 | 
			
		||||
  {
 | 
			
		||||
    LOG_PRINT_L2("STARTED PEERLIST IDLE HANDSHAKE");
 | 
			
		||||
    typedef std::list<std::pair<net_utils::connection_context_base, peerid_type> > local_connects_type;
 | 
			
		||||
    typedef std::list<std::pair<epee::net_utils::connection_context_base, peerid_type> > local_connects_type;
 | 
			
		||||
    local_connects_type cncts;
 | 
			
		||||
    m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -725,7 +745,7 @@ namespace nodetool
 | 
			
		|||
    {
 | 
			
		||||
      if(be.last_seen > local_time)
 | 
			
		||||
      {
 | 
			
		||||
        LOG_PRINT_RED_L0("FOUND FUTURE peerlist for entry " << string_tools::get_ip_string_from_int32(be.adr.ip) << ":" << be.adr.port << " last_seen: " << be.last_seen << ", local_time(on remote node):" << local_time);
 | 
			
		||||
        LOG_PRINT_RED_L0("FOUND FUTURE peerlist for entry " << epee::string_tools::get_ip_string_from_int32(be.adr.ip) << ":" << be.adr.port << " last_seen: " << be.last_seen << ", local_time(on remote node):" << local_time);
 | 
			
		||||
        return false;
 | 
			
		||||
      }
 | 
			
		||||
      be.last_seen += delta;
 | 
			
		||||
| 
						 | 
				
			
			@ -734,7 +754,7 @@ namespace nodetool
 | 
			
		|||
  }
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
  template<class t_payload_net_handler>
 | 
			
		||||
  bool node_server<t_payload_net_handler>::handle_remote_peerlist(const std::list<peerlist_entry>& peerlist, time_t local_time, const net_utils::connection_context_base& context)
 | 
			
		||||
  bool node_server<t_payload_net_handler>::handle_remote_peerlist(const std::list<peerlist_entry>& peerlist, time_t local_time, const epee::net_utils::connection_context_base& context)
 | 
			
		||||
  {
 | 
			
		||||
    int64_t delta = 0;
 | 
			
		||||
    std::list<peerlist_entry> peerlist_ = peerlist;
 | 
			
		||||
| 
						 | 
				
			
			@ -782,7 +802,7 @@ namespace nodetool
 | 
			
		|||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    crypto::public_key pk = AUTO_VAL_INIT(pk);
 | 
			
		||||
    string_tools::hex_to_pod(P2P_STAT_TRUSTED_PUB_KEY, pk);
 | 
			
		||||
    epee::string_tools::hex_to_pod(P2P_STAT_TRUSTED_PUB_KEY, pk);
 | 
			
		||||
    crypto::hash h = tools::get_proof_of_trust_hash(tr);
 | 
			
		||||
    if(!crypto::check_signature(h, pk, tr.sign))
 | 
			
		||||
    {
 | 
			
		||||
| 
						 | 
				
			
			@ -903,8 +923,8 @@ namespace nodetool
 | 
			
		|||
    uint32_t actual_ip =  context.m_remote_ip;
 | 
			
		||||
    if(!m_peerlist.is_ip_allowed(actual_ip))
 | 
			
		||||
      return false;
 | 
			
		||||
    std::string ip = string_tools::get_ip_string_from_int32(actual_ip);
 | 
			
		||||
    std::string port = string_tools::num_to_string_fast(node_data.my_port);
 | 
			
		||||
    std::string ip = epee::string_tools::get_ip_string_from_int32(actual_ip);
 | 
			
		||||
    std::string port = epee::string_tools::num_to_string_fast(node_data.my_port);
 | 
			
		||||
    peerid_type pr = node_data.peer_id;
 | 
			
		||||
    bool r = m_net_server.connect_async(ip, port, m_config.m_net_config.ping_connection_timeout, [cb, /*context,*/ ip, port, pr, this](
 | 
			
		||||
      const typename net_server::t_connection_context& ping_context,
 | 
			
		||||
| 
						 | 
				
			
			@ -922,12 +942,12 @@ namespace nodetool
 | 
			
		|||
      std::string port_=port;
 | 
			
		||||
      peerid_type pr_ = pr;
 | 
			
		||||
      auto cb_ = cb;*/
 | 
			
		||||
      bool inv_call_res = net_utils::async_invoke_remote_command2<COMMAND_PING::response>(ping_context.m_connection_id, COMMAND_PING::ID, req, m_net_server.get_config_object(),
 | 
			
		||||
      bool inv_call_res = epee::net_utils::async_invoke_remote_command2<COMMAND_PING::response>(ping_context.m_connection_id, COMMAND_PING::ID, req, m_net_server.get_config_object(),
 | 
			
		||||
        [=](int code, const COMMAND_PING::response& rsp, p2p_connection_context& context)
 | 
			
		||||
      {
 | 
			
		||||
        if(code <= 0)
 | 
			
		||||
        {
 | 
			
		||||
          LOG_PRINT_CC_L2(ping_context, "Failed to invoke COMMAND_PING to " << ip << ":" << port << "(" << code <<  ", " << levin::get_err_descr(code) << ")");
 | 
			
		||||
          LOG_PRINT_CC_L2(ping_context, "Failed to invoke COMMAND_PING to " << ip << ":" << port << "(" << code <<  ", " << epee::levin::get_err_descr(code) << ")");
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -979,7 +999,7 @@ namespace nodetool
 | 
			
		|||
    if(arg.node_data.network_id != BYTECOIN_NETWORK)
 | 
			
		||||
    {
 | 
			
		||||
 | 
			
		||||
      LOG_PRINT_CCONTEXT_L0("WRONG NETWORK AGENT CONNECTED! id=" << string_tools::get_str_from_guid_a(arg.node_data.network_id));
 | 
			
		||||
      LOG_PRINT_CCONTEXT_L0("WRONG NETWORK AGENT CONNECTED! id=" << epee::string_tools::get_str_from_guid_a(arg.node_data.network_id));
 | 
			
		||||
      drop_connection(context);
 | 
			
		||||
      return 1;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			@ -1021,7 +1041,7 @@ namespace nodetool
 | 
			
		|||
        time(&pe.last_seen);
 | 
			
		||||
        pe.id = peer_id_l;
 | 
			
		||||
        this->m_peerlist.append_with_peer_white(pe);
 | 
			
		||||
        LOG_PRINT_CCONTEXT_L2("PING SUCCESS " << string_tools::get_ip_string_from_int32(context.m_remote_ip) << ":" << port_l);
 | 
			
		||||
        LOG_PRINT_CCONTEXT_L2("PING SUCCESS " << epee::string_tools::get_ip_string_from_int32(context.m_remote_ip) << ":" << port_l);
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -1066,9 +1086,9 @@ namespace nodetool
 | 
			
		|||
    std::stringstream ss;
 | 
			
		||||
    m_net_server.get_config_object().foreach_connection([&](const p2p_connection_context& cntxt)
 | 
			
		||||
    {
 | 
			
		||||
      ss << string_tools::get_ip_string_from_int32(cntxt.m_remote_ip) << ":" << cntxt.m_remote_port
 | 
			
		||||
      ss << epee::string_tools::get_ip_string_from_int32(cntxt.m_remote_ip) << ":" << cntxt.m_remote_port
 | 
			
		||||
        << " \t\tpeer_id " << cntxt.peer_id
 | 
			
		||||
        << " \t\tconn_id " << string_tools::get_str_from_guid_a(cntxt.m_connection_id) << (cntxt.m_is_income ? " INC":" OUT")
 | 
			
		||||
        << " \t\tconn_id " << epee::string_tools::get_str_from_guid_a(cntxt.m_connection_id) << (cntxt.m_is_income ? " INC":" OUT")
 | 
			
		||||
        << std::endl;
 | 
			
		||||
      return true;
 | 
			
		||||
    });
 | 
			
		||||
| 
						 | 
				
			
			@ -1079,13 +1099,51 @@ namespace nodetool
 | 
			
		|||
  template<class t_payload_net_handler>
 | 
			
		||||
  void node_server<t_payload_net_handler>::on_connection_new(p2p_connection_context& context)
 | 
			
		||||
  {
 | 
			
		||||
    LOG_PRINT_L2("["<< net_utils::print_connection_context(context) << "] NEW CONNECTION");
 | 
			
		||||
    LOG_PRINT_L2("["<< epee::net_utils::print_connection_context(context) << "] NEW CONNECTION");
 | 
			
		||||
  }
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
  template<class t_payload_net_handler>
 | 
			
		||||
  void node_server<t_payload_net_handler>::on_connection_close(p2p_connection_context& context)
 | 
			
		||||
  {
 | 
			
		||||
    LOG_PRINT_L2("["<< net_utils::print_connection_context(context) << "] CLOSE CONNECTION");
 | 
			
		||||
    LOG_PRINT_L2("["<< epee::net_utils::print_connection_context(context) << "] CLOSE CONNECTION");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<class t_payload_net_handler>
 | 
			
		||||
  bool node_server<t_payload_net_handler>::is_priority_node(const net_address& na)
 | 
			
		||||
  {
 | 
			
		||||
    return (std::find(m_priority_peers.begin(), m_priority_peers.end(), na) != m_priority_peers.end()) || (std::find(m_exclusive_peers.begin(), m_exclusive_peers.end(), na) != m_exclusive_peers.end());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<class t_payload_net_handler> template <class Container>
 | 
			
		||||
  bool node_server<t_payload_net_handler>::connect_to_peerlist(const Container& peers)
 | 
			
		||||
  {
 | 
			
		||||
    for(const net_address& na: peers)
 | 
			
		||||
    {
 | 
			
		||||
      if(m_net_server.is_stop_signal_sent())
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
      if(is_addr_connected(na))
 | 
			
		||||
        continue;
 | 
			
		||||
 | 
			
		||||
      try_to_connect_and_handshake_with_new_peer(na);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template<class t_payload_net_handler> template <class Container>
 | 
			
		||||
  bool node_server<t_payload_net_handler>::parse_peers_and_add_to_container(const boost::program_options::variables_map& vm, const command_line::arg_descriptor<std::vector<std::string> > & arg, Container& container)
 | 
			
		||||
  {
 | 
			
		||||
    std::vector<std::string> perrs = command_line::get_arg(vm, arg);
 | 
			
		||||
 | 
			
		||||
    for(const std::string& pr_str: perrs)
 | 
			
		||||
    {
 | 
			
		||||
      nodetool::net_address na = AUTO_VAL_INIT(na);
 | 
			
		||||
      bool r = parse_peer_from_string(na, pr_str);
 | 
			
		||||
      CHECK_AND_ASSERT_MES(r, false, "Failed to parse address from string: " << pr_str);
 | 
			
		||||
      container.push_back(na);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  //-----------------------------------------------------------------------------------
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -395,7 +395,7 @@ namespace cryptonote
 | 
			
		|||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob);
 | 
			
		||||
 | 
			
		||||
    res.status = CORE_RPC_STATUS_OK;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  //------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -423,7 +423,7 @@ namespace cryptonote
 | 
			
		|||
      error_resp.message = "Block not accepted";
 | 
			
		||||
      return false;
 | 
			
		||||
    }
 | 
			
		||||
    res.status = "OK";
 | 
			
		||||
    res.status = CORE_RPC_STATUS_OK;
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  //------------------------------------------------------------------------------------------------------------------------------
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,8 @@
 | 
			
		|||
// Distributed under the MIT/X11 software license, see the accompanying
 | 
			
		||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
#include "serialization.h"
 | 
			
		||||
#include "debug_archive.h"
 | 
			
		||||
#include "crypto/chacha8.h"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,6 +10,7 @@
 | 
			
		|||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <boost/type_traits/is_integral.hpp>
 | 
			
		||||
#include <boost/type_traits/integral_constant.hpp>
 | 
			
		||||
 | 
			
		||||
template <class T>
 | 
			
		||||
struct is_blob_type { typedef boost::false_type type; };
 | 
			
		||||
| 
						 | 
				
			
			@ -79,8 +80,10 @@ inline bool do_serialize(Archive &ar, T &v)
 | 
			
		|||
    if (!r || !ar.stream().good()) return false; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
#define FIELDS(f) \
 | 
			
		||||
  do { \
 | 
			
		||||
    bool r = ::do_serialize(ar, f); \
 | 
			
		||||
    if (!r || !ar.stream().good()) return false;
 | 
			
		||||
    if (!r || !ar.stream().good()) return false; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
#define FIELD(f) \
 | 
			
		||||
  do { \
 | 
			
		||||
    ar.tag(#f); \
 | 
			
		||||
| 
						 | 
				
			
			@ -99,6 +102,7 @@ inline bool do_serialize(Archive &ar, T &v)
 | 
			
		|||
    ar.serialize_varint(f); \
 | 
			
		||||
    if (!ar.stream().good()) return false; \
 | 
			
		||||
  } while(0);
 | 
			
		||||
 | 
			
		||||
namespace serialization {
 | 
			
		||||
  namespace detail
 | 
			
		||||
  {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -202,7 +202,7 @@ bool simple_wallet::set_log(const std::vector<std::string> &args)
 | 
			
		|||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
  uint16_t l = 0;
 | 
			
		||||
  if(!string_tools::get_xtype_from_string(l, args[0]))
 | 
			
		||||
  if(!epee::string_tools::get_xtype_from_string(l, args[0]))
 | 
			
		||||
  {
 | 
			
		||||
    fail_msg_writer() << "wrong number format, use: set_log <log_level_number_0-4>";
 | 
			
		||||
    return true;
 | 
			
		||||
| 
						 | 
				
			
			@ -229,8 +229,8 @@ bool simple_wallet::ask_wallet_create_if_needed()
 | 
			
		|||
  wallet_path = string_tools::trim(wallet_path);
 | 
			
		||||
 | 
			
		||||
  bool keys_file_exists;
 | 
			
		||||
  bool wallet_file_exitst;
 | 
			
		||||
  tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exitst);
 | 
			
		||||
  bool wallet_file_exists;
 | 
			
		||||
  tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exists);
 | 
			
		||||
 | 
			
		||||
  bool r;
 | 
			
		||||
  if(keys_file_exists)
 | 
			
		||||
| 
						 | 
				
			
			@ -239,7 +239,7 @@ bool simple_wallet::ask_wallet_create_if_needed()
 | 
			
		|||
    r = true;
 | 
			
		||||
  }else
 | 
			
		||||
  {
 | 
			
		||||
    if(!wallet_file_exitst)
 | 
			
		||||
    if(!wallet_file_exists)
 | 
			
		||||
    {
 | 
			
		||||
      std::cout << "The wallet doesn't exist, generating new one" << std::endl;
 | 
			
		||||
      m_generate_new = wallet_path;
 | 
			
		||||
| 
						 | 
				
			
			@ -749,7 +749,7 @@ bool simple_wallet::transfer(const std::vector<std::string> &args_)
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  size_t fake_outs_count;
 | 
			
		||||
  if(!string_tools::get_xtype_from_string(fake_outs_count, local_args[0]))
 | 
			
		||||
  if(!epee::string_tools::get_xtype_from_string(fake_outs_count, local_args[0]))
 | 
			
		||||
  {
 | 
			
		||||
    fail_msg_writer() << "mixin_count should be non-negative integer, got " << local_args[0];
 | 
			
		||||
    return true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ namespace cryptonote
 | 
			
		|||
    epee::console_handlers_binder m_cmd_binder;
 | 
			
		||||
 | 
			
		||||
    std::unique_ptr<tools::wallet2> m_wallet;
 | 
			
		||||
    net_utils::http::http_simple_client m_http_client;
 | 
			
		||||
    epee::net_utils::http::http_simple_client m_http_client;
 | 
			
		||||
    refresh_progress_reporter_t m_refresh_progress_reporter;
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
#define BUILD_COMMIT_ID "@VERSION@"
 | 
			
		||||
#define PROJECT_VERSION "0.8.8.2"
 | 
			
		||||
#define PROJECT_VERSION "0.8.8"
 | 
			
		||||
#define PROJECT_VERSION_BUILD_NO "1"
 | 
			
		||||
#define PROJECT_VERSION_LONG PROJECT_VERSION "." PROJECT_VERSION_BUILD_NO "(" BUILD_COMMIT_ID ")"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -455,14 +455,14 @@ void wallet2::generate(const std::string& wallet_, const std::string& password)
 | 
			
		|||
  store();
 | 
			
		||||
}
 | 
			
		||||
//----------------------------------------------------------------------------------------------------
 | 
			
		||||
void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exitst)
 | 
			
		||||
void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists)
 | 
			
		||||
{
 | 
			
		||||
  std::string keys_file, wallet_file;
 | 
			
		||||
  do_prepare_file_names(file_path, keys_file, wallet_file);
 | 
			
		||||
 | 
			
		||||
  boost::system::error_code ignore;
 | 
			
		||||
  keys_file_exists = boost::filesystem::exists(keys_file, ignore);
 | 
			
		||||
  wallet_file_exitst = boost::filesystem::exists(wallet_file, ignore);
 | 
			
		||||
  wallet_file_exists = boost::filesystem::exists(wallet_file, ignore);
 | 
			
		||||
}
 | 
			
		||||
//----------------------------------------------------------------------------------------------------
 | 
			
		||||
bool wallet2::prepare_file_names(const std::string& file_path)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -149,7 +149,7 @@ namespace tools
 | 
			
		|||
      a & m_payments;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    static void wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exitst);
 | 
			
		||||
    static void wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists);
 | 
			
		||||
 | 
			
		||||
  private:
 | 
			
		||||
    bool store_keys(const std::string& keys_file_name, const std::string& password);
 | 
			
		||||
| 
						 | 
				
			
			@ -331,7 +331,7 @@ namespace tools
 | 
			
		|||
        req.amounts.push_back(it->amount());
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      bool r = net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/getrandom_outs.bin", req, daemon_resp, m_http_client, 200000);
 | 
			
		||||
      bool r = epee::net_utils::invoke_http_bin_remote_command2(m_daemon_address + "/getrandom_outs.bin", req, daemon_resp, m_http_client, 200000);
 | 
			
		||||
      THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "getrandom_outs.bin");
 | 
			
		||||
      THROW_WALLET_EXCEPTION_IF(daemon_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "getrandom_outs.bin");
 | 
			
		||||
      THROW_WALLET_EXCEPTION_IF(daemon_resp.status != CORE_RPC_STATUS_OK, error::get_random_outs_error, daemon_resp.status);
 | 
			
		||||
| 
						 | 
				
			
			@ -426,7 +426,7 @@ namespace tools
 | 
			
		|||
    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;
 | 
			
		||||
    r = net_utils::invoke_http_json_remote_command2(m_daemon_address + "/sendrawtransaction", req, daemon_send_resp, m_http_client, 200000);
 | 
			
		||||
    r = epee::net_utils::invoke_http_json_remote_command2(m_daemon_address + "/sendrawtransaction", req, daemon_send_resp, m_http_client, 200000);
 | 
			
		||||
    THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "sendrawtransaction");
 | 
			
		||||
    THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status == CORE_RPC_STATUS_BUSY, error::daemon_busy, "sendrawtransaction");
 | 
			
		||||
    THROW_WALLET_EXCEPTION_IF(daemon_send_resp.status != CORE_RPC_STATUS_OK, error::tx_rejected, tx, daemon_send_resp.status);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,15 +21,15 @@ namespace
 | 
			
		|||
int main(int argc, char* argv[])
 | 
			
		||||
{
 | 
			
		||||
  TRY_ENTRY();
 | 
			
		||||
  string_tools::set_module_name_and_folder(argv[0]);
 | 
			
		||||
  epee::string_tools::set_module_name_and_folder(argv[0]);
 | 
			
		||||
 | 
			
		||||
  //set up logging options
 | 
			
		||||
  log_space::get_set_log_detalisation_level(true, LOG_LEVEL_3);
 | 
			
		||||
  log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2);
 | 
			
		||||
  epee::log_space::get_set_log_detalisation_level(true, LOG_LEVEL_3);
 | 
			
		||||
  epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL, LOG_LEVEL_2);
 | 
			
		||||
  
 | 
			
		||||
  log_space::log_singletone::add_logger(LOGGER_FILE, 
 | 
			
		||||
    log_space::log_singletone::get_default_log_file().c_str(), 
 | 
			
		||||
    log_space::log_singletone::get_default_log_folder().c_str());
 | 
			
		||||
  epee::log_space::log_singletone::add_logger(LOGGER_FILE, 
 | 
			
		||||
    epee::log_space::log_singletone::get_default_log_file().c_str(), 
 | 
			
		||||
    epee::log_space::log_singletone::get_default_log_folder().c_str());
 | 
			
		||||
 | 
			
		||||
  po::options_description desc_options("Allowed options");
 | 
			
		||||
  command_line::add_arg(desc_options, command_line::arg_help);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										45
									
								
								tests/performance_tests/cn_slow_hash.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								tests/performance_tests/cn_slow_hash.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,45 @@
 | 
			
		|||
// Copyright (c) 2012-2013 The Cryptonote developers
 | 
			
		||||
// Distributed under the MIT/X11 software license, see the accompanying
 | 
			
		||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include "crypto/crypto.h"
 | 
			
		||||
#include "cryptonote_core/cryptonote_basic.h"
 | 
			
		||||
 | 
			
		||||
class test_cn_slow_hash
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
  static const size_t loop_count = 10;
 | 
			
		||||
 | 
			
		||||
#pragma pack(push, 1)
 | 
			
		||||
  struct data_t
 | 
			
		||||
  {
 | 
			
		||||
    char data[13];
 | 
			
		||||
  };
 | 
			
		||||
#pragma pack(pop)
 | 
			
		||||
 | 
			
		||||
  static_assert(13 == sizeof(data_t), "Invalid structure size");
 | 
			
		||||
 | 
			
		||||
  bool init()
 | 
			
		||||
  {
 | 
			
		||||
    if (!epee::string_tools::hex_to_pod("63617665617420656d70746f72", m_data))
 | 
			
		||||
      return false;
 | 
			
		||||
 | 
			
		||||
    if (!epee::string_tools::hex_to_pod("bbec2cacf69866a8e740380fe7b818fc78f8571221742d729d9d02d7f8989b87", m_expected_hash))
 | 
			
		||||
      return false;
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  bool test()
 | 
			
		||||
  {
 | 
			
		||||
    crypto::hash hash;
 | 
			
		||||
    crypto::cn_slow_hash(&m_data, sizeof(m_data), hash);
 | 
			
		||||
    return hash == m_expected_hash;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
  data_t m_data;
 | 
			
		||||
  crypto::hash m_expected_hash;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -8,6 +8,7 @@
 | 
			
		|||
// tests
 | 
			
		||||
#include "construct_tx.h"
 | 
			
		||||
#include "check_ring_signature.h"
 | 
			
		||||
#include "cn_slow_hash.h"
 | 
			
		||||
#include "derive_public_key.h"
 | 
			
		||||
#include "derive_secret_key.h"
 | 
			
		||||
#include "generate_key_derivation.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -56,6 +57,8 @@ int main(int argc, char** argv)
 | 
			
		|||
  TEST_PERFORMANCE0(test_derive_public_key);
 | 
			
		||||
  TEST_PERFORMANCE0(test_derive_secret_key);
 | 
			
		||||
 | 
			
		||||
  TEST_PERFORMANCE0(test_cn_slow_hash);
 | 
			
		||||
 | 
			
		||||
  std::cout << "Tests finished. Elapsed time: " << timer.elapsed_ms() / 1000 << " sec" << std::endl;
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										140
									
								
								tests/unit_tests/checkpoints.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										140
									
								
								tests/unit_tests/checkpoints.cpp
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,140 @@
 | 
			
		|||
// Copyright (c) 2012-2013 The Cryptonote developers
 | 
			
		||||
// Distributed under the MIT/X11 software license, see the accompanying
 | 
			
		||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
 | 
			
		||||
 | 
			
		||||
#include "gtest/gtest.h"
 | 
			
		||||
 | 
			
		||||
#include "cryptonote_core/checkpoints.cpp"
 | 
			
		||||
 | 
			
		||||
using namespace cryptonote;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
TEST(checkpoints_is_alternative_block_allowed, handles_empty_checkpoins)
 | 
			
		||||
{
 | 
			
		||||
  checkpoints cp;
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(0, 0));
 | 
			
		||||
 | 
			
		||||
  ASSERT_TRUE(cp.is_alternative_block_allowed(1, 1));
 | 
			
		||||
  ASSERT_TRUE(cp.is_alternative_block_allowed(1, 9));
 | 
			
		||||
  ASSERT_TRUE(cp.is_alternative_block_allowed(9, 1));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(checkpoints_is_alternative_block_allowed, handles_one_checkpoint)
 | 
			
		||||
{
 | 
			
		||||
  checkpoints cp;
 | 
			
		||||
  cp.add_checkpoint(5, "0000000000000000000000000000000000000000000000000000000000000000");
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(0, 0));
 | 
			
		||||
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 1));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 4));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 9));
 | 
			
		||||
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 1));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 4));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 9));
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(5, 1));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(5, 4));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(5, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(5, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(5, 9));
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(6, 1));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(6, 4));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(6, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(6, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(6, 9));
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(9, 1));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(9, 4));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(9, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(9, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(9, 9));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
TEST(checkpoints_is_alternative_block_allowed, handles_two_and_more_checkpoints)
 | 
			
		||||
{
 | 
			
		||||
  checkpoints cp;
 | 
			
		||||
  cp.add_checkpoint(5, "0000000000000000000000000000000000000000000000000000000000000000");
 | 
			
		||||
  cp.add_checkpoint(9, "0000000000000000000000000000000000000000000000000000000000000000");
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(0, 0));
 | 
			
		||||
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 1));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 4));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 8));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 9));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 10));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(1, 11));
 | 
			
		||||
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 1));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 4));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 8));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 9));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 10));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(4, 11));
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(5, 1));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(5, 4));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(5, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(5, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(5, 8));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(5, 9));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(5, 10));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(5, 11));
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(6, 1));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(6, 4));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(6, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(6, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(6, 8));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(6, 9));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(6, 10));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(6, 11));
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(8, 1));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(8, 4));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(8, 5));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(8, 6));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(8, 8));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(8, 9));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(8, 10));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(8, 11));
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(9, 1));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(9, 4));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(9, 5));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(9, 6));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(9, 8));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(9, 9));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(9, 10));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(9, 11));
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(10, 1));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(10, 4));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(10, 5));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(10, 6));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(10, 8));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(10, 9));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(10, 10));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(10, 11));
 | 
			
		||||
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(11, 1));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(11, 4));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(11, 5));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(11, 6));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(11, 8));
 | 
			
		||||
  ASSERT_FALSE(cp.is_alternative_block_allowed(11, 9));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(11, 10));
 | 
			
		||||
  ASSERT_TRUE (cp.is_alternative_block_allowed(11, 11));
 | 
			
		||||
}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue