Compare commits
31 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de1636183e | ||
|
|
00240b8b3a | ||
|
|
156b0c4e41 | ||
|
|
eba31d8361 | ||
|
|
2e5f550ddb | ||
|
|
e7369949be | ||
|
|
a409f944d0 | ||
|
|
2aeba6b6a5 | ||
|
|
711b04fb4f | ||
|
|
07eaa68334 | ||
|
|
a08adc37de | ||
|
|
98e27b8b85 | ||
|
|
6171e973c7 | ||
|
|
a36e6e71be | ||
|
|
1cc740598f | ||
|
|
e433b42e65 | ||
|
|
86b77c6eb4 | ||
|
|
8363f00715 | ||
|
|
4888839219 | ||
|
|
29d2f72b24 | ||
|
|
0e9259486c | ||
|
|
d8429b8376 | ||
|
|
5e5c6c91df | ||
|
|
3f4a4468e0 | ||
|
|
fb27454cdf | ||
|
|
917e4d348b | ||
|
|
8dd2fbe1b6 | ||
|
|
b99585ca69 | ||
|
|
c1e362a8dd | ||
|
|
13b7cfaec7 | ||
|
|
0cf6f461b6 |
65 changed files with 757 additions and 1166 deletions
44
.gitlab-ci.yml
Normal file
44
.gitlab-ci.yml
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
include:
|
||||
- template: Jobs/Code-Quality.gitlab-ci.yml
|
||||
|
||||
stages:
|
||||
- build
|
||||
- test
|
||||
- trigger_build_peerplays
|
||||
|
||||
build:
|
||||
stage: build
|
||||
script:
|
||||
- rm -rf .git/modules/vendor ./vendor
|
||||
- git submodule sync
|
||||
- git submodule update --init --recursive
|
||||
- rm -rf build
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_BUILD_TYPE=Release ..
|
||||
- make -j$(nproc)
|
||||
artifacts:
|
||||
untracked: true
|
||||
paths:
|
||||
- build/tests/
|
||||
tags:
|
||||
- builder-fc
|
||||
|
||||
test:
|
||||
stage: test
|
||||
dependencies:
|
||||
- build
|
||||
script:
|
||||
- ./build/tests/all_test
|
||||
tags:
|
||||
- builder-fc
|
||||
when:
|
||||
- manual
|
||||
|
||||
trigger_build_peerplays:
|
||||
stage: trigger_build_peerplays
|
||||
dependencies:
|
||||
- test
|
||||
script:
|
||||
- "curl -X POST -F token=$CI_JOB_TOKEN -F ref=$REF_NAME https://gitlab.com/api/v4/projects/10735589/trigger/pipeline"
|
||||
|
||||
9
.gitmodules
vendored
9
.gitmodules
vendored
|
|
@ -1,3 +1,6 @@
|
|||
[submodule "vendor/secp256k1-zkp"]
|
||||
path = vendor/secp256k1-zkp
|
||||
url = https://github.com/bitshares/secp256k1-zkp.git
|
||||
[submodule "vendor/editline"]
|
||||
path = vendor/editline
|
||||
url = https://github.com/troglobit/editline.git
|
||||
[submodule "vendor/secp256k1"]
|
||||
path = vendor/secp256k1
|
||||
url = https://github.com/libbitcoin/secp256k1.git
|
||||
|
|
|
|||
110
CMakeLists.txt
110
CMakeLists.txt
|
|
@ -40,7 +40,7 @@ endif()
|
|||
SET (ORIGINAL_LIB_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
|
||||
SET(BOOST_COMPONENTS)
|
||||
LIST(APPEND BOOST_COMPONENTS thread date_time filesystem system program_options signals serialization chrono unit_test_framework context locale iostreams)
|
||||
LIST(APPEND BOOST_COMPONENTS thread date_time filesystem system program_options serialization chrono unit_test_framework context locale iostreams)
|
||||
SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
|
||||
|
||||
IF( ECC_IMPL STREQUAL openssl )
|
||||
|
|
@ -54,10 +54,10 @@ ELSE( ECC_IMPL STREQUAL openssl )
|
|||
ENDIF( ECC_IMPL STREQUAL mixed )
|
||||
ENDIF( ECC_IMPL STREQUAL openssl )
|
||||
|
||||
# Configure secp256k1-zkp
|
||||
# Configure secp256k1
|
||||
if ( MSVC )
|
||||
# autoconf won't work here, hard code the defines
|
||||
set( SECP256K1_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp" )
|
||||
set( SECP256K1_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1" )
|
||||
|
||||
file( GLOB SECP256K1_SOURCES "${SECP256K1_DIR}/src/secp256k1.c" )
|
||||
add_library( secp256k1 ${SECP256K1_SOURCES} )
|
||||
|
|
@ -75,26 +75,26 @@ else ( MSVC )
|
|||
include(ExternalProject)
|
||||
if ( MINGW )
|
||||
ExternalProject_Add( project_secp256k1
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp --with-bignum=no --host=x86_64-w64-mingw32
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1 --with-bignum=no --host=x86_64-w64-mingw32 --enable-module-recovery
|
||||
BUILD_COMMAND make
|
||||
INSTALL_COMMAND true
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp/src/project_secp256k1-build/.libs/libsecp256k1.a
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1/src/project_secp256k1-build/.libs/libsecp256k1.a
|
||||
)
|
||||
else ( MINGW )
|
||||
ExternalProject_Add( project_secp256k1
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp --with-bignum=no
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1 --with-bignum=no --enable-module-recovery
|
||||
BUILD_COMMAND make
|
||||
INSTALL_COMMAND true
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1-zkp/src/project_secp256k1-build/.libs/libsecp256k1.a
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/secp256k1/src/project_secp256k1-build/.libs/libsecp256k1.a
|
||||
)
|
||||
endif ( MINGW )
|
||||
ExternalProject_Add_Step(project_secp256k1 autogen
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp/autogen.sh
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1/autogen.sh
|
||||
DEPENDERS configure
|
||||
)
|
||||
|
||||
|
|
@ -102,11 +102,59 @@ else ( MSVC )
|
|||
|
||||
add_library(secp256k1 STATIC IMPORTED)
|
||||
set_property(TARGET secp256k1 PROPERTY IMPORTED_LOCATION ${binary_dir}/.libs/libsecp256k1${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
set_property(TARGET secp256k1 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp/include)
|
||||
set_property(TARGET secp256k1 PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1/include)
|
||||
add_dependencies(secp256k1 project_secp256k1)
|
||||
install( FILES ${binary_dir}/.libs/libsecp256k1${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib/cryptonomex )
|
||||
endif ( MSVC )
|
||||
# End configure secp256k1-zkp
|
||||
# End configure secp256k1
|
||||
|
||||
# Configure editline
|
||||
if ( MSVC )
|
||||
# autoconf won't work here, hard code the defines
|
||||
set( EDITLINE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline" )
|
||||
|
||||
file( GLOB EDITLINE_SOURCES "${EDITLINE_DIR}/src/editline.c" )
|
||||
add_library( editline ${EDITLINE_SOURCES} )
|
||||
|
||||
target_include_directories( editline PRIVATE "${EDITLINE_DIR}" PUBLIC "${EDITLINE_DIR}/include" )
|
||||
|
||||
set_target_properties( editline PROPERTIES COMPILE_DEFINITIONS LINKER_LANGUAGE C )
|
||||
else ( MSVC )
|
||||
include(ExternalProject)
|
||||
if ( MINGW )
|
||||
ExternalProject_Add( project_editline
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/editline --host=x86_64-w64-mingw32
|
||||
BUILD_COMMAND make
|
||||
INSTALL_COMMAND true
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline/src/project_editline-build/.libs/libeditline.a
|
||||
)
|
||||
else ( MINGW )
|
||||
ExternalProject_Add( project_editline
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline
|
||||
CONFIGURE_COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/configure --prefix=${CMAKE_CURRENT_BINARY_DIR}/vendor/editline
|
||||
BUILD_COMMAND make
|
||||
INSTALL_COMMAND true
|
||||
BUILD_BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/vendor/editline/src/project_editline-build/.libs/libeditline.a
|
||||
)
|
||||
endif ( MINGW )
|
||||
ExternalProject_Add_Step(project_editline autogen
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline
|
||||
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/autogen.sh
|
||||
DEPENDERS configure
|
||||
)
|
||||
|
||||
ExternalProject_Get_Property(project_editline binary_dir)
|
||||
|
||||
add_library(editline STATIC IMPORTED)
|
||||
set_property(TARGET editline PROPERTY IMPORTED_LOCATION ${binary_dir}/src/.libs/libeditline${CMAKE_STATIC_LIBRARY_SUFFIX})
|
||||
set_property(TARGET editline PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/vendor/editline/include)
|
||||
add_dependencies(editline project_editline)
|
||||
install( FILES ${binary_dir}/src/.libs/libeditline${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib/cryptonomex )
|
||||
endif ( MSVC )
|
||||
# End configure editline
|
||||
|
||||
IF( WIN32 )
|
||||
MESSAGE(STATUS "Configuring fc to build on Win32")
|
||||
|
|
@ -168,6 +216,7 @@ set( fc_sources
|
|||
src/variant.cpp
|
||||
src/exception.cpp
|
||||
src/variant_object.cpp
|
||||
src/static_variant.cpp
|
||||
src/thread/thread.cpp
|
||||
src/thread/thread_specific.cpp
|
||||
src/thread/future.cpp
|
||||
|
|
@ -228,7 +277,6 @@ set( fc_sources
|
|||
src/crypto/elliptic_common.cpp
|
||||
${ECC_REST}
|
||||
src/crypto/elliptic_${ECC_IMPL}.cpp
|
||||
src/crypto/rand.cpp
|
||||
src/network/tcp_socket.cpp
|
||||
src/network/udp_socket.cpp
|
||||
src/network/http/http_connection.cpp
|
||||
|
|
@ -258,27 +306,17 @@ add_subdirectory( vendor/websocketpp EXCLUDE_FROM_ALL )
|
|||
setup_library( fc SOURCES ${sources} LIBRARY_TYPE STATIC )
|
||||
install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/" DESTINATION include )
|
||||
|
||||
# begin readline stuff
|
||||
find_package(Curses)
|
||||
find_package(Readline)
|
||||
|
||||
file(GLOB HEADERS "include/bts/cli/*.hpp")
|
||||
|
||||
if (READLINE_FOUND)
|
||||
target_compile_definitions (fc PRIVATE HAVE_READLINE)
|
||||
set(readline_libraries ${Readline_LIBRARY})
|
||||
if (CURSES_FOUND)
|
||||
list(APPEND readline_libraries ${CURSES_LIBRARY})
|
||||
endif()
|
||||
set(readline_includes ${Readline_INCLUDE_DIR})
|
||||
endif()
|
||||
# begin editline stuff
|
||||
if(WIN32)
|
||||
target_compile_definitions( fc PRIVATE _CRT_NONSTDC_NO_DEPRECATE )
|
||||
else(WIN32)
|
||||
target_compile_definitions( fc PRIVATE HAVE_EDITLINE )
|
||||
set( editline_libraries editline )
|
||||
endif(WIN32)
|
||||
# end readline stuff
|
||||
# end editline stuff
|
||||
|
||||
if( NOT CPP_STANDARD )
|
||||
set( CPP_STANDARD, "-std=c++11" )
|
||||
set( CPP_STANDARD "-std=c++11" )
|
||||
endif()
|
||||
|
||||
IF(WIN32)
|
||||
|
|
@ -360,24 +398,23 @@ target_include_directories(fc
|
|||
${OPENSSL_INCLUDE_DIR}
|
||||
"vendor/diff-match-patch-cpp-stl"
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vendor/websocketpp
|
||||
"${readline_includes}"
|
||||
|
||||
PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1-zkp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/vendor/secp256k1
|
||||
)
|
||||
|
||||
#target_link_libraries( fc PUBLIC ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${BZIP2_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${ECC_LIB} )
|
||||
IF(NOT WIN32)
|
||||
set(LINK_USR_LOCAL_LIB -L/usr/local/lib)
|
||||
ENDIF()
|
||||
target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${readline_libraries} ${ECC_LIB} )
|
||||
target_link_libraries( fc PUBLIC ${LINK_USR_LOCAL_LIB} ${Boost_LIBRARIES} ${OPENSSL_LIBRARIES} ${ZLIB_LIBRARIES} ${PLATFORM_SPECIFIC_LIBS} ${RPCRT4} ${CMAKE_DL_LIBS} ${rt_library} ${editline_libraries} ${ECC_LIB} )
|
||||
|
||||
if(MSVC)
|
||||
set_source_files_properties( src/network/http/websocket.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )
|
||||
endif(MSVC)
|
||||
|
||||
|
||||
IF(NOT Boost_UNIT_TEST_FRAMEWORK_LIBRARY MATCHES "\\.(a|lib)$")
|
||||
IF(Boost_UNIT_TEST_FRAMEWORK_LIBRARY MATCHES "\\.(so|dll)$" OR FC_BUILD_DYNAMIC_LIBRARIES)
|
||||
IF(MSVC)
|
||||
add_definitions(/DBOOST_TEST_DYN_LINK)
|
||||
ELSE(MSVC)
|
||||
|
|
@ -495,3 +532,4 @@ ADD_CUSTOM_COMMAND(TARGET fc POST_BUILD ${POST_BUILD_STEP_COMMANDS}
|
|||
)
|
||||
|
||||
MESSAGE(STATUS "Finished fc module configuration...")
|
||||
|
||||
|
|
|
|||
|
|
@ -1,47 +0,0 @@
|
|||
# - Try to find readline include dirs and libraries
|
||||
#
|
||||
# Usage of this module as follows:
|
||||
#
|
||||
# find_package(Readline)
|
||||
#
|
||||
# Variables used by this module, they can change the default behaviour and need
|
||||
# to be set before calling find_package:
|
||||
#
|
||||
# Readline_ROOT_DIR Set this variable to the root installation of
|
||||
# readline if the module has problems finding the
|
||||
# proper installation path.
|
||||
#
|
||||
# Variables defined by this module:
|
||||
#
|
||||
# READLINE_FOUND System has readline, include and lib dirs found
|
||||
# Readline_INCLUDE_DIR The readline include directories.
|
||||
# Readline_LIBRARY The readline library.
|
||||
|
||||
find_path(Readline_ROOT_DIR
|
||||
NAMES include/readline/readline.h
|
||||
)
|
||||
|
||||
find_path(Readline_INCLUDE_DIR
|
||||
NAMES readline/readline.h
|
||||
HINTS ${Readline_ROOT_DIR}/include
|
||||
)
|
||||
|
||||
find_library(Readline_LIBRARY
|
||||
NAMES readline
|
||||
HINTS ${Readline_ROOT_DIR}/lib
|
||||
)
|
||||
|
||||
if(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
|
||||
set(READLINE_FOUND TRUE)
|
||||
else(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
|
||||
FIND_LIBRARY(Readline_LIBRARY NAMES readline)
|
||||
include(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Readline DEFAULT_MSG Readline_INCLUDE_DIR Readline_LIBRARY )
|
||||
MARK_AS_ADVANCED(Readline_INCLUDE_DIR Readline_LIBRARY)
|
||||
endif(Readline_INCLUDE_DIR AND Readline_LIBRARY AND Ncurses_LIBRARY)
|
||||
|
||||
mark_as_advanced(
|
||||
Readline_ROOT_DIR
|
||||
Readline_INCLUDE_DIR
|
||||
Readline_LIBRARY
|
||||
)
|
||||
|
|
@ -115,7 +115,9 @@ namespace fc {
|
|||
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
else
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
for (size_t i = 0; i < bi.size(); i++) {
|
||||
bi.data[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,12 @@
|
|||
#define FC_PACK_MAX_DEPTH 1000
|
||||
#endif
|
||||
|
||||
#ifndef FC_MAX_STRING_OBJECT_DEPTH
|
||||
// how many levels of nested objects are proceed for string functions
|
||||
#define FC_MAX_STRING_OBJECT_DEPTH 200
|
||||
#endif
|
||||
|
||||
#ifndef FC_MAX_LOG_OBJECT_DEPTH
|
||||
// how many levels of nested objects are displayed in log messages
|
||||
#define FC_MAX_LOG_OBJECT_DEPTH 200
|
||||
#define FC_MAX_LOG_OBJECT_DEPTH 1000
|
||||
#endif
|
||||
|
|
@ -202,33 +202,6 @@ namespace fc {
|
|||
uint64_t max_value;
|
||||
};
|
||||
|
||||
commitment_type blind( const blind_factor_type& blind, uint64_t value );
|
||||
blind_factor_type blind_sum( const std::vector<blind_factor_type>& blinds, uint32_t non_neg );
|
||||
/** verifies taht commnits + neg_commits + excess == 0 */
|
||||
bool verify_sum( const std::vector<commitment_type>& commits, const std::vector<commitment_type>& neg_commits, int64_t excess );
|
||||
bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const range_proof_type& proof );
|
||||
|
||||
range_proof_type range_proof_sign( uint64_t min_value,
|
||||
const commitment_type& commit,
|
||||
const blind_factor_type& commit_blind,
|
||||
const blind_factor_type& nonce,
|
||||
int8_t base10_exp,
|
||||
uint8_t min_bits,
|
||||
uint64_t actual_value
|
||||
);
|
||||
|
||||
bool verify_range_proof_rewind( blind_factor_type& blind_out,
|
||||
uint64_t& value_out,
|
||||
string& message_out,
|
||||
const blind_factor_type& nonce,
|
||||
uint64_t& min_val,
|
||||
uint64_t& max_val,
|
||||
commitment_type commit,
|
||||
const range_proof_type& proof );
|
||||
range_proof_info range_get_info( const range_proof_type& proof );
|
||||
|
||||
|
||||
|
||||
} // namespace ecc
|
||||
void to_variant( const ecc::private_key& var, variant& vo, uint32_t max_depth );
|
||||
void from_variant( const variant& var, ecc::private_key& vo, uint32_t max_depth );
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@
|
|||
#include <openssl/ecdh.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/obj_mac.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
/**
|
||||
* @file openssl.hpp
|
||||
|
|
|
|||
|
|
@ -1,8 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
namespace fc {
|
||||
|
||||
/* provides access to the OpenSSL random number generator */
|
||||
void rand_bytes(char* buf, int count);
|
||||
void rand_pseudo_bytes(char* buf, int count);
|
||||
} // namespace fc
|
||||
|
|
@ -15,7 +15,7 @@ namespace fc
|
|||
{
|
||||
string endpoint = "127.0.0.1:12201";
|
||||
string host = "fc"; // the name of the host, source or application that sent this message (just passed through to GELF server)
|
||||
uint32_t max_object_depth;
|
||||
uint32_t max_object_depth = FC_MAX_LOG_OBJECT_DEPTH;
|
||||
};
|
||||
|
||||
gelf_appender(const variant& args);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <fc/any.hpp>
|
||||
#include <boost/any.hpp>
|
||||
#include <fc/network/ip.hpp>
|
||||
#include <fc/signals.hpp>
|
||||
|
||||
|
|
@ -26,14 +26,14 @@ namespace fc { namespace http {
|
|||
void on_message_handler( const std::function<void(const std::string&)>& h ) { _on_message = h; }
|
||||
void on_http_handler( const std::function<std::string(const std::string&)>& h ) { _on_http = h; }
|
||||
|
||||
void set_session_data( fc::any d ){ _session_data = std::move(d); }
|
||||
fc::any& get_session_data() { return _session_data; }
|
||||
void set_session_data( boost::any d ){ _session_data = std::move(d); }
|
||||
boost::any& get_session_data() { return _session_data; }
|
||||
|
||||
virtual std::string get_request_header(const std::string& key) = 0;
|
||||
|
||||
fc::signal<void()> closed;
|
||||
private:
|
||||
fc::any _session_data;
|
||||
boost::any _session_data;
|
||||
std::function<void(const std::string&)> _on_message;
|
||||
std::function<string(const std::string&)> _on_http;
|
||||
};
|
||||
|
|
@ -53,6 +53,8 @@ namespace fc { namespace http {
|
|||
uint16_t get_listening_port();
|
||||
void start_accept();
|
||||
|
||||
void stop_listening();
|
||||
void close();
|
||||
private:
|
||||
friend class detail::websocket_server_impl;
|
||||
std::unique_ptr<detail::websocket_server_impl> my;
|
||||
|
|
@ -84,6 +86,10 @@ namespace fc { namespace http {
|
|||
|
||||
websocket_connection_ptr connect( const std::string& uri );
|
||||
websocket_connection_ptr secure_connect( const std::string& uri );
|
||||
|
||||
void close();
|
||||
void synchronous_close();
|
||||
|
||||
private:
|
||||
std::unique_ptr<detail::websocket_client_impl> my;
|
||||
std::unique_ptr<detail::websocket_tls_client_impl> smy;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
#include <fc/utility.hpp>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
namespace fc {
|
||||
|
|
@ -23,12 +24,13 @@ namespace fc {
|
|||
public:
|
||||
typedef T value_type;
|
||||
|
||||
optional():_valid(false){}
|
||||
optional():_valid(false){ memset(_value, 0, sizeof(_value)); }
|
||||
~optional(){ reset(); }
|
||||
|
||||
optional( optional& o )
|
||||
:_valid(false)
|
||||
{
|
||||
memset(_value, 0, sizeof(_value));
|
||||
if( o._valid ) new (ptr()) T( *o );
|
||||
_valid = o._valid;
|
||||
}
|
||||
|
|
@ -36,6 +38,7 @@ namespace fc {
|
|||
optional( const optional& o )
|
||||
:_valid(false)
|
||||
{
|
||||
memset(_value, 0, sizeof(_value));
|
||||
if( o._valid ) new (ptr()) T( *o );
|
||||
_valid = o._valid;
|
||||
}
|
||||
|
|
@ -43,6 +46,7 @@ namespace fc {
|
|||
optional( optional&& o )
|
||||
:_valid(false)
|
||||
{
|
||||
memset(_value, 0, sizeof(_value));
|
||||
if( o._valid ) new (ptr()) T( fc::move(*o) );
|
||||
_valid = o._valid;
|
||||
o.reset();
|
||||
|
|
@ -52,6 +56,7 @@ namespace fc {
|
|||
optional( const optional<U>& o )
|
||||
:_valid(false)
|
||||
{
|
||||
memset(_value, 0, sizeof(_value));
|
||||
if( o._valid ) new (ptr()) T( *o );
|
||||
_valid = o._valid;
|
||||
}
|
||||
|
|
@ -60,6 +65,7 @@ namespace fc {
|
|||
optional( optional<U>& o )
|
||||
:_valid(false)
|
||||
{
|
||||
memset(_value, 0, sizeof(_value));
|
||||
if( o._valid )
|
||||
{
|
||||
new (ptr()) T( *o );
|
||||
|
|
@ -71,6 +77,7 @@ namespace fc {
|
|||
optional( optional<U>&& o )
|
||||
:_valid(false)
|
||||
{
|
||||
memset(_value, 0, sizeof(_value));
|
||||
if( o._valid ) new (ptr()) T( fc::move(*o) );
|
||||
_valid = o._valid;
|
||||
o.reset();
|
||||
|
|
@ -80,6 +87,7 @@ namespace fc {
|
|||
optional( U&& u )
|
||||
:_valid(true)
|
||||
{
|
||||
memset(_value, 0, sizeof(_value));
|
||||
new ((char*)ptr()) T( fc::forward<U>(u) );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace fc { namespace rpc {
|
|||
class websocket_api_connection : public api_connection
|
||||
{
|
||||
public:
|
||||
websocket_api_connection( fc::http::websocket_connection& c, uint32_t max_conversion_depth );
|
||||
websocket_api_connection(const std::shared_ptr<fc::http::websocket_connection> &c, uint32_t max_conversion_depth );
|
||||
~websocket_api_connection();
|
||||
|
||||
virtual variant send_call(
|
||||
|
|
@ -29,7 +29,7 @@ namespace fc { namespace rpc {
|
|||
const std::string& message,
|
||||
bool send_message = true );
|
||||
|
||||
fc::http::websocket_connection& _connection;
|
||||
std::shared_ptr<fc::http::websocket_connection> _connection;
|
||||
fc::rpc::state _rpc_state;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
/** This source adapted from https://github.com/kmicklas/variadic-static_variant
|
||||
|
||||
/** This source adapted from https://github.com/kmicklas/variadic-static_variant Now available at https://github.com/kmicklas/variadic-variant.
|
||||
*
|
||||
* Copyright (C) 2013 Kenneth Micklas
|
||||
*
|
||||
|
|
@ -13,21 +14,15 @@
|
|||
#include <stdexcept>
|
||||
#include <typeinfo>
|
||||
#include <fc/exception/exception.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
// Implementation details, the user should not import this:
|
||||
namespace impl {
|
||||
|
||||
template<int N, typename... Ts>
|
||||
struct storage_ops;
|
||||
|
||||
template<typename X, typename... Ts>
|
||||
struct position;
|
||||
|
||||
template<typename... Ts>
|
||||
struct type_info;
|
||||
|
||||
template<typename StaticVariant>
|
||||
struct copy_construct
|
||||
{
|
||||
|
|
@ -40,7 +35,6 @@ struct copy_construct
|
|||
sv.init(v);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename StaticVariant>
|
||||
struct move_construct
|
||||
{
|
||||
|
|
@ -53,25 +47,19 @@ struct move_construct
|
|||
sv.init( std::move(v) );
|
||||
}
|
||||
};
|
||||
|
||||
template<int N, typename T, typename... Ts>
|
||||
struct storage_ops<N, T&, Ts...> {
|
||||
static void del(int n, void *data) {}
|
||||
static void con(int n, void *data) {}
|
||||
|
||||
template<typename visitor>
|
||||
static typename visitor::result_type apply(int n, void *data, visitor& v) {}
|
||||
|
||||
template<typename visitor>
|
||||
static typename visitor::result_type apply(int n, void *data, const visitor& v) {}
|
||||
|
||||
template<typename visitor>
|
||||
static typename visitor::result_type apply(int n, const void *data, visitor& v) {}
|
||||
|
||||
template<typename visitor>
|
||||
static typename visitor::result_type apply(int n, const void *data, const visitor& v) {}
|
||||
};
|
||||
|
||||
template<int N, typename T, typename... Ts>
|
||||
struct storage_ops<N, T, Ts...> {
|
||||
static void del(int n, void *data) {
|
||||
|
|
@ -82,32 +70,27 @@ struct storage_ops<N, T, Ts...> {
|
|||
if(n == N) new(reinterpret_cast<T*>(data)) T();
|
||||
else storage_ops<N + 1, Ts...>::con(n, data);
|
||||
}
|
||||
|
||||
template<typename visitor>
|
||||
static typename visitor::result_type apply(int n, void *data, visitor& v) {
|
||||
if(n == N) return v(*reinterpret_cast<T*>(data));
|
||||
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
||||
}
|
||||
|
||||
template<typename visitor>
|
||||
static typename visitor::result_type apply(int n, void *data, const visitor& v) {
|
||||
if(n == N) return v(*reinterpret_cast<T*>(data));
|
||||
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
||||
}
|
||||
|
||||
template<typename visitor>
|
||||
static typename visitor::result_type apply(int n, const void *data, visitor& v) {
|
||||
if(n == N) return v(*reinterpret_cast<const T*>(data));
|
||||
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
||||
}
|
||||
|
||||
template<typename visitor>
|
||||
static typename visitor::result_type apply(int n, const void *data, const visitor& v) {
|
||||
if(n == N) return v(*reinterpret_cast<const T*>(data));
|
||||
else return storage_ops<N + 1, Ts...>::apply(n, data, v);
|
||||
}
|
||||
};
|
||||
|
||||
template<int N>
|
||||
struct storage_ops<N> {
|
||||
static void del(int n, void *data) {
|
||||
|
|
@ -116,7 +99,6 @@ struct storage_ops<N> {
|
|||
static void con(int n, void *data) {
|
||||
FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." );
|
||||
}
|
||||
|
||||
template<typename visitor>
|
||||
static typename visitor::result_type apply(int n, void *data, visitor& v) {
|
||||
FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." );
|
||||
|
|
@ -134,22 +116,18 @@ struct storage_ops<N> {
|
|||
FC_THROW_EXCEPTION( fc::assert_exception, "Internal error: static_variant tag is invalid." );
|
||||
}
|
||||
};
|
||||
|
||||
template<typename X>
|
||||
struct position<X> {
|
||||
static const int pos = -1;
|
||||
};
|
||||
|
||||
template<typename X, typename... Ts>
|
||||
struct position<X, X, Ts...> {
|
||||
static const int pos = 0;
|
||||
};
|
||||
|
||||
template<typename X, typename T, typename... Ts>
|
||||
struct position<X, T, Ts...> {
|
||||
static const int pos = position<X, Ts...>::pos != -1 ? position<X, Ts...>::pos + 1 : -1;
|
||||
};
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
struct type_info<T&, Ts...> {
|
||||
static const bool no_reference_types = false;
|
||||
|
|
@ -157,7 +135,6 @@ struct type_info<T&, Ts...> {
|
|||
static const size_t size = type_info<Ts...>::size > sizeof(T&) ? type_info<Ts...>::size : sizeof(T&);
|
||||
static const size_t count = 1 + type_info<Ts...>::count;
|
||||
};
|
||||
|
||||
template<typename T, typename... Ts>
|
||||
struct type_info<T, Ts...> {
|
||||
static const bool no_reference_types = type_info<Ts...>::no_reference_types;
|
||||
|
|
@ -165,7 +142,6 @@ struct type_info<T, Ts...> {
|
|||
static const size_t size = type_info<Ts...>::size > sizeof(T) ? type_info<Ts...>::size : sizeof(T&);
|
||||
static const size_t count = 1 + type_info<Ts...>::count;
|
||||
};
|
||||
|
||||
template<>
|
||||
struct type_info<> {
|
||||
static const bool no_reference_types = true;
|
||||
|
|
@ -174,48 +150,94 @@ struct type_info<> {
|
|||
static const size_t size = 0;
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
template<typename TTag>
|
||||
size_t size( TTag )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename TTag, typename A, typename...Ts>
|
||||
size_t size( TTag tag )
|
||||
{
|
||||
if (tag <= 0)
|
||||
{
|
||||
return sizeof(A);
|
||||
}
|
||||
|
||||
return size<TTag, Ts...>( --tag );
|
||||
}
|
||||
|
||||
|
||||
class dynamic_storage
|
||||
{
|
||||
char* storage;
|
||||
public:
|
||||
dynamic_storage();
|
||||
|
||||
~dynamic_storage();
|
||||
|
||||
void* data() const;
|
||||
|
||||
void alloc( size_t size );
|
||||
|
||||
void release();
|
||||
};
|
||||
|
||||
} // namespace impl
|
||||
template<typename... Types>
|
||||
class static_variant {
|
||||
using tag_type = int64_t;
|
||||
|
||||
static_assert(impl::type_info<Types...>::no_reference_types, "Reference types are not permitted in static_variant.");
|
||||
static_assert(impl::type_info<Types...>::no_duplicates, "static_variant type arguments contain duplicate types.");
|
||||
|
||||
int _tag;
|
||||
char storage[impl::type_info<Types...>::size];
|
||||
|
||||
template<typename X>
|
||||
using type_in_typelist = typename std::enable_if<impl::position<X, Types...>::pos != -1, X>::type; // type is in typelist of static_variant.
|
||||
|
||||
|
||||
int _tag;
|
||||
impl::dynamic_storage storage;
|
||||
template<typename X, typename = type_in_typelist<X>>
|
||||
void init(const X& x) {
|
||||
_tag = impl::position<X, Types...>::pos;
|
||||
new(storage) X(x);
|
||||
storage.alloc( sizeof(X) );
|
||||
new(storage.data()) X(x);
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
template<typename X, typename = type_in_typelist<X>>
|
||||
void init(X&& x) {
|
||||
_tag = impl::position<X, Types...>::pos;
|
||||
new(storage) X( std::move(x) );
|
||||
storage.alloc( sizeof(X) );
|
||||
new(storage.data()) X( std::move(x) );
|
||||
}
|
||||
|
||||
void init(tag_type tag)
|
||||
{
|
||||
FC_ASSERT( tag >= 0 );
|
||||
FC_ASSERT( tag < count() );
|
||||
_tag = tag;
|
||||
storage.alloc( impl::size<tag_type, Types...>( tag ) );
|
||||
impl::storage_ops<0, Types...>::con(_tag, storage.data());
|
||||
}
|
||||
|
||||
void clean()
|
||||
{
|
||||
impl::storage_ops<0, Types...>::del(_tag, storage.data() );
|
||||
storage.release();
|
||||
}
|
||||
template<typename StaticVariant>
|
||||
friend struct impl::copy_construct;
|
||||
template<typename StaticVariant>
|
||||
friend struct impl::move_construct;
|
||||
public:
|
||||
template<typename X>
|
||||
template<typename X, typename = type_in_typelist<X>>
|
||||
struct tag
|
||||
{
|
||||
static_assert(
|
||||
impl::position<X, Types...>::pos != -1,
|
||||
"Type not in static_variant."
|
||||
);
|
||||
static const int value = impl::position<X, Types...>::pos;
|
||||
};
|
||||
static_variant()
|
||||
{
|
||||
_tag = 0;
|
||||
impl::storage_ops<0, Types...>::con(0, storage);
|
||||
}
|
||||
|
||||
init(0);
|
||||
}
|
||||
template<typename... Other>
|
||||
static_variant( const static_variant<Other...>& cpy )
|
||||
{
|
||||
|
|
@ -225,46 +247,34 @@ public:
|
|||
{
|
||||
cpy.visit( impl::copy_construct<static_variant>(*this) );
|
||||
}
|
||||
|
||||
static_variant( static_variant&& mv )
|
||||
{
|
||||
mv.visit( impl::move_construct<static_variant>(*this) );
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
template<typename X, typename = type_in_typelist<X>>
|
||||
static_variant(const X& v) {
|
||||
static_assert(
|
||||
impl::position<X, Types...>::pos != -1,
|
||||
"Type not in static_variant."
|
||||
);
|
||||
init(v);
|
||||
}
|
||||
~static_variant() {
|
||||
impl::storage_ops<0, Types...>::del(_tag, storage);
|
||||
clean();
|
||||
}
|
||||
|
||||
|
||||
template<typename X>
|
||||
template<typename X, typename = type_in_typelist<X>>
|
||||
static_variant& operator=(const X& v) {
|
||||
static_assert(
|
||||
impl::position<X, Types...>::pos != -1,
|
||||
"Type not in static_variant."
|
||||
);
|
||||
this->~static_variant();
|
||||
clean();
|
||||
init(v);
|
||||
return *this;
|
||||
}
|
||||
static_variant& operator=( const static_variant& v )
|
||||
{
|
||||
if( this == &v ) return *this;
|
||||
this->~static_variant();
|
||||
clean();
|
||||
v.visit( impl::copy_construct<static_variant>(*this) );
|
||||
return *this;
|
||||
}
|
||||
static_variant& operator=( static_variant&& v )
|
||||
{
|
||||
if( this == &v ) return *this;
|
||||
this->~static_variant();
|
||||
clean();
|
||||
v.visit( impl::move_construct<static_variant>(*this) );
|
||||
return *this;
|
||||
}
|
||||
|
|
@ -276,98 +286,73 @@ public:
|
|||
{
|
||||
return a.which() < b.which();
|
||||
}
|
||||
|
||||
template<typename X>
|
||||
template<typename X, typename = type_in_typelist<X>>
|
||||
X& get() {
|
||||
static_assert(
|
||||
impl::position<X, Types...>::pos != -1,
|
||||
"Type not in static_variant."
|
||||
);
|
||||
if(_tag == impl::position<X, Types...>::pos) {
|
||||
void* tmp(storage);
|
||||
return *reinterpret_cast<X*>(tmp);
|
||||
return *reinterpret_cast<X*>(storage.data());
|
||||
} else {
|
||||
FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename<X>::name()) );
|
||||
// std::string("static_variant does not contain value of type ") + typeid(X).name()
|
||||
// );
|
||||
}
|
||||
}
|
||||
template<typename X>
|
||||
template<typename X, typename = type_in_typelist<X>>
|
||||
const X& get() const {
|
||||
static_assert(
|
||||
impl::position<X, Types...>::pos != -1,
|
||||
"Type not in static_variant."
|
||||
);
|
||||
if(_tag == impl::position<X, Types...>::pos) {
|
||||
const void* tmp(storage);
|
||||
return *reinterpret_cast<const X*>(tmp);
|
||||
return *reinterpret_cast<const X*>(storage.data());
|
||||
} else {
|
||||
FC_THROW_EXCEPTION( fc::assert_exception, "static_variant does not contain a value of type ${t}", ("t",fc::get_typename<X>::name()) );
|
||||
}
|
||||
}
|
||||
template<typename visitor>
|
||||
typename visitor::result_type visit(visitor& v) {
|
||||
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
|
||||
return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v);
|
||||
}
|
||||
|
||||
template<typename visitor>
|
||||
typename visitor::result_type visit(const visitor& v) {
|
||||
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
|
||||
return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v);
|
||||
}
|
||||
|
||||
template<typename visitor>
|
||||
typename visitor::result_type visit(visitor& v)const {
|
||||
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
|
||||
return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v);
|
||||
}
|
||||
|
||||
template<typename visitor>
|
||||
typename visitor::result_type visit(const visitor& v)const {
|
||||
return impl::storage_ops<0, Types...>::apply(_tag, storage, v);
|
||||
return impl::storage_ops<0, Types...>::apply(_tag, storage.data(), v);
|
||||
}
|
||||
|
||||
static int count() { return impl::type_info<Types...>::count; }
|
||||
void set_which( int w ) {
|
||||
FC_ASSERT( w >= 0 );
|
||||
FC_ASSERT( w < count() );
|
||||
this->~static_variant();
|
||||
_tag = w;
|
||||
impl::storage_ops<0, Types...>::con(_tag, storage);
|
||||
clean();
|
||||
init(w);
|
||||
}
|
||||
|
||||
int which() const {return _tag;}
|
||||
};
|
||||
|
||||
template<typename Result>
|
||||
struct visitor {
|
||||
typedef Result result_type;
|
||||
};
|
||||
|
||||
struct from_static_variant
|
||||
{
|
||||
variant& var;
|
||||
const uint32_t _max_depth;
|
||||
from_static_variant( variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){}
|
||||
|
||||
typedef void result_type;
|
||||
template<typename T> void operator()( const T& v )const
|
||||
{
|
||||
to_variant( v, var, _max_depth );
|
||||
}
|
||||
};
|
||||
|
||||
struct to_static_variant
|
||||
{
|
||||
const variant& var;
|
||||
const uint32_t _max_depth;
|
||||
to_static_variant( const variant& dv, uint32_t max_depth ):var(dv),_max_depth(max_depth){}
|
||||
|
||||
typedef void result_type;
|
||||
template<typename T> void operator()( T& v )const
|
||||
{
|
||||
from_variant( var, v, _max_depth );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template<typename... T> void to_variant( const fc::static_variant<T...>& s, fc::variant& v, uint32_t max_depth )
|
||||
{
|
||||
FC_ASSERT( max_depth > 0 );
|
||||
|
|
@ -384,6 +369,5 @@ struct visitor {
|
|||
s.set_which( ar[0].as_uint64() );
|
||||
s.visit( to_static_variant(ar[1], max_depth - 1) );
|
||||
}
|
||||
|
||||
template<typename... T> struct get_typename { static const char* name() { return typeid(static_variant<T...>).name(); } };
|
||||
} // namespace fc
|
||||
} // namespace fc
|
||||
|
|
@ -2,6 +2,7 @@
|
|||
#include <fc/utility.hpp>
|
||||
#include <fc/fwd.hpp>
|
||||
#include <fc/optional.hpp>
|
||||
#include <fc/config.hpp>
|
||||
|
||||
#ifndef USE_FC_STRING
|
||||
#include <string>
|
||||
|
|
@ -25,7 +26,7 @@ namespace fc
|
|||
|
||||
typedef fc::optional<fc::string> ostring;
|
||||
class variant_object;
|
||||
fc::string format_string( const fc::string&, const variant_object&, uint32_t max_object_depth = 200 );
|
||||
fc::string format_string( const fc::string&, const variant_object&, uint32_t max_object_depth = FC_MAX_STRING_OBJECT_DEPTH );
|
||||
fc::string trim( const fc::string& );
|
||||
fc::string to_lower( const fc::string& );
|
||||
string trim_and_normalize_spaces( const string& s );
|
||||
|
|
|
|||
|
|
@ -1497,7 +1497,10 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
|
|||
{
|
||||
mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
|
||||
r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
|
||||
for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
|
||||
for ( i = 0; i <= 143; ++i) *p++ = 8;
|
||||
for ( ; i <= 255; ++i) *p++ = 9;
|
||||
for ( ; i <= 279; ++i) *p++ = 7;
|
||||
for ( ; i <= 287; ++i) *p++ = 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -2281,7 +2284,11 @@ static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahe
|
|||
if (TDEFL_READ_UNALIGNED_WORD(&d->m_dict[probe_pos + match_len - 1]) == c01) break;
|
||||
TDEFL_PROBE; TDEFL_PROBE; TDEFL_PROBE;
|
||||
}
|
||||
if (!dist) break; q = (const mz_uint16*)(d->m_dict + probe_pos); if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue; p = s; probe_len = 32;
|
||||
if (!dist) break;
|
||||
q = (const mz_uint16*)(d->m_dict + probe_pos);
|
||||
if (TDEFL_READ_UNALIGNED_WORD(q) != s01) continue;
|
||||
p = s;
|
||||
probe_len = 32;
|
||||
do { } while ( (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) &&
|
||||
(TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (TDEFL_READ_UNALIGNED_WORD(++p) == TDEFL_READ_UNALIGNED_WORD(++q)) && (--probe_len > 0) );
|
||||
if (!probe_len)
|
||||
|
|
@ -2848,7 +2855,7 @@ void *tdefl_write_image_to_png_file_in_memory(const void *pImage, int w, int h,
|
|||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#if defined(_MSC_VER)
|
||||
static FILE *mz_fopen(const char *pFilename, const char *pMode)
|
||||
{
|
||||
FILE* pFile = NULL;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
namespace fc { namespace ecc { namespace detail {
|
||||
|
||||
|
||||
const secp256k1_context_t* _get_context();
|
||||
const secp256k1_context* _get_context();
|
||||
void _init_lib();
|
||||
|
||||
class private_key_impl
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ struct aes_encoder::impl
|
|||
aes_encoder::aes_encoder()
|
||||
{
|
||||
static int init = init_openssl();
|
||||
(void)init;
|
||||
}
|
||||
|
||||
aes_encoder::~aes_encoder()
|
||||
|
|
@ -70,7 +71,9 @@ uint32_t aes_encoder::encode( const char* plaintxt, uint32_t plaintext_len, char
|
|||
FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc encryption update",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
FC_ASSERT( ciphertext_len == plaintext_len, "", ("ciphertext_len",ciphertext_len)("plaintext_len",plaintext_len) );
|
||||
int64_t ciphertext_len_i64 = ciphertext_len;
|
||||
int64_t plaintext_len_i64 = plaintext_len;
|
||||
FC_ASSERT( ciphertext_len_i64 == plaintext_len_i64, "", ("ciphertext_len",ciphertext_len)("plaintext_len",plaintext_len) );
|
||||
return ciphertext_len;
|
||||
}
|
||||
#if 0
|
||||
|
|
@ -98,6 +101,7 @@ struct aes_decoder::impl
|
|||
aes_decoder::aes_decoder()
|
||||
{
|
||||
static int init = init_openssl();
|
||||
(void)init;
|
||||
}
|
||||
|
||||
void aes_decoder::init( const fc::sha256& key, const fc::uint128& init_value )
|
||||
|
|
@ -137,7 +141,9 @@ uint32_t aes_decoder::decode( const char* ciphertxt, uint32_t ciphertxt_len, cha
|
|||
FC_THROW_EXCEPTION( aes_exception, "error during aes 256 cbc decryption update",
|
||||
("s", ERR_error_string( ERR_get_error(), nullptr) ) );
|
||||
}
|
||||
FC_ASSERT( ciphertxt_len == plaintext_len, "", ("ciphertxt_len",ciphertxt_len)("plaintext_len",plaintext_len) );
|
||||
int64_t ciphertxt_len_i64 = ciphertxt_len;
|
||||
int64_t plaintext_len_i64 = plaintext_len;
|
||||
FC_ASSERT( ciphertxt_len_i64 == plaintext_len_i64, "", ("ciphertxt_len",ciphertxt_len)("plaintext_len",plaintext_len) );
|
||||
return plaintext_len;
|
||||
}
|
||||
#if 0
|
||||
|
|
@ -377,63 +383,4 @@ std::vector<char> aes_load( const fc::path& file, const fc::sha512& key )
|
|||
return aes_decrypt( key, cipher );
|
||||
} FC_RETHROW_EXCEPTIONS( warn, "", ("file",file) ) }
|
||||
|
||||
/* This stuff has to go somewhere, I guess this is as good a place as any...
|
||||
OpenSSL isn't thread-safe unless you give it access to some mutexes,
|
||||
so the CRYPTO_set_id_callback() function needs to be called before there's any
|
||||
chance of OpenSSL being accessed from multiple threads.
|
||||
*/
|
||||
struct openssl_thread_config
|
||||
{
|
||||
static boost::mutex* openssl_mutexes;
|
||||
static unsigned long get_thread_id();
|
||||
static void locking_callback(int mode, int type, const char *file, int line);
|
||||
openssl_thread_config();
|
||||
~openssl_thread_config();
|
||||
};
|
||||
openssl_thread_config openssl_thread_config_manager;
|
||||
|
||||
boost::mutex* openssl_thread_config::openssl_mutexes = nullptr;
|
||||
|
||||
unsigned long openssl_thread_config::get_thread_id()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (unsigned long)::GetCurrentThreadId();
|
||||
#else
|
||||
return (unsigned long)(&fc::thread::current()); // TODO: should expose boost thread id
|
||||
#endif
|
||||
}
|
||||
|
||||
void openssl_thread_config::locking_callback(int mode, int type, const char *file, int line)
|
||||
{
|
||||
if (mode & CRYPTO_LOCK)
|
||||
openssl_mutexes[type].lock();
|
||||
else
|
||||
openssl_mutexes[type].unlock();
|
||||
}
|
||||
|
||||
// Warning: Things get complicated if third-party libraries also try to install their their own
|
||||
// OpenSSL thread functions. Right now, we don't install our own handlers if another library has
|
||||
// installed them before us which is a partial solution, but you'd really need to evaluate
|
||||
// each library that does this to make sure they will play nice.
|
||||
openssl_thread_config::openssl_thread_config()
|
||||
{
|
||||
if (CRYPTO_get_id_callback() == NULL &&
|
||||
CRYPTO_get_locking_callback() == NULL)
|
||||
{
|
||||
openssl_mutexes = new boost::mutex[CRYPTO_num_locks()];
|
||||
CRYPTO_set_id_callback(&get_thread_id);
|
||||
CRYPTO_set_locking_callback(&locking_callback);
|
||||
}
|
||||
}
|
||||
openssl_thread_config::~openssl_thread_config()
|
||||
{
|
||||
if (CRYPTO_get_id_callback() == &get_thread_id)
|
||||
{
|
||||
CRYPTO_set_id_callback(NULL);
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
delete[] openssl_mutexes;
|
||||
openssl_mutexes = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
|
|
|||
|
|
@ -85,8 +85,10 @@ namespace fc { namespace ecc {
|
|||
ssl_bignum order;
|
||||
FC_ASSERT( EC_GROUP_get_order( group, order, ctx ) );
|
||||
private_key_secret bin;
|
||||
FC_ASSERT( BN_num_bytes( order ) == bin.data_size() );
|
||||
FC_ASSERT( BN_bn2bin( order, (unsigned char*) bin.data() ) == bin.data_size() );
|
||||
size_t order_BN_num_bytes = BN_num_bytes( order );
|
||||
FC_ASSERT( order_BN_num_bytes == bin.data_size() );
|
||||
size_t order_BN_bn2bin = BN_bn2bin( order, (unsigned char*) bin.data() );
|
||||
FC_ASSERT( order_BN_bn2bin == bin.data_size() );
|
||||
return bin;
|
||||
}
|
||||
|
||||
|
|
@ -104,8 +106,10 @@ namespace fc { namespace ecc {
|
|||
FC_ASSERT( EC_GROUP_get_order( group, order, ctx ) );
|
||||
BN_rshift1( order, order );
|
||||
private_key_secret bin;
|
||||
FC_ASSERT( BN_num_bytes( order ) == bin.data_size() );
|
||||
FC_ASSERT( BN_bn2bin( order, (unsigned char*) bin.data() ) == bin.data_size() );
|
||||
size_t order_BN_num_bytes = BN_num_bytes( order );
|
||||
FC_ASSERT( order_BN_num_bytes == bin.data_size() );
|
||||
size_t order_BN_bn2bin = BN_bn2bin( order, (unsigned char*) bin.data() );
|
||||
FC_ASSERT( order_BN_bn2bin == bin.data_size() );
|
||||
return bin;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include <fc/fwd_impl.hpp>
|
||||
|
||||
#include <secp256k1.h>
|
||||
#include <secp256k1_recovery.h>
|
||||
|
||||
#include "_elliptic_impl_priv.hpp"
|
||||
|
||||
|
|
@ -71,29 +72,35 @@ namespace fc { namespace ecc {
|
|||
{
|
||||
FC_ASSERT( my->_key != empty_priv );
|
||||
public_key_data pub;
|
||||
unsigned int pk_len;
|
||||
FC_ASSERT( secp256k1_ec_pubkey_create( detail::_get_context(), (unsigned char*) pub.begin(), (int*) &pk_len, (unsigned char*) my->_key.data(), 1 ) );
|
||||
secp256k1_pubkey pub_key;
|
||||
FC_ASSERT( secp256k1_ec_pubkey_create( detail::_get_context(), &pub_key, (const unsigned char*) my->_key.data() ) );
|
||||
|
||||
size_t pk_len = pub.size();
|
||||
FC_ASSERT( secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char *) pub.data, (size_t*) &pk_len, &pub_key, SECP256K1_EC_COMPRESSED ) );
|
||||
FC_ASSERT( pk_len == pub.size() );
|
||||
|
||||
return public_key(pub);
|
||||
}
|
||||
|
||||
static int extended_nonce_function( unsigned char *nonce32, const unsigned char *msg32,
|
||||
const unsigned char *key32, unsigned int attempt,
|
||||
const void *data ) {
|
||||
const unsigned char *key32, const unsigned char *algo16,
|
||||
void *data, unsigned int ) {
|
||||
unsigned int* extra = (unsigned int*) data;
|
||||
(*extra)++;
|
||||
return secp256k1_nonce_function_default( nonce32, msg32, key32, *extra, nullptr );
|
||||
return secp256k1_nonce_function_default( nonce32, msg32, key32, algo16, nullptr, *extra );
|
||||
}
|
||||
|
||||
compact_signature private_key::sign_compact( const fc::sha256& digest, bool require_canonical )const
|
||||
{
|
||||
FC_ASSERT( my->_key != empty_priv );
|
||||
compact_signature result;
|
||||
int recid;
|
||||
int recid = 0;
|
||||
unsigned int counter = 0;
|
||||
do
|
||||
{
|
||||
FC_ASSERT( secp256k1_ecdsa_sign_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) result.begin() + 1, (unsigned char*) my->_key.data(), extended_nonce_function, &counter, &recid ));
|
||||
secp256k1_ecdsa_recoverable_signature sig;
|
||||
FC_ASSERT( secp256k1_ecdsa_sign_recoverable( detail::_get_context(), &sig, (const unsigned char*) digest.data(), (const unsigned char*) my->_key.data(), extended_nonce_function, &counter ));
|
||||
FC_ASSERT( secp256k1_ecdsa_recoverable_signature_serialize_compact( detail::_get_context(), (unsigned char*) result.begin() + 1, &recid, &sig));
|
||||
} while( require_canonical && !public_key::is_canonical( result ) );
|
||||
result.begin()[0] = 27 + 4 + recid;
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -16,13 +16,13 @@
|
|||
namespace fc { namespace ecc {
|
||||
namespace detail
|
||||
{
|
||||
const secp256k1_context_t* _get_context() {
|
||||
static secp256k1_context_t* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
|
||||
const secp256k1_context* _get_context() {
|
||||
static secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void _init_lib() {
|
||||
static const secp256k1_context_t* ctx = _get_context();
|
||||
static const secp256k1_context* ctx = _get_context();
|
||||
static int init_o = init_openssl();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <secp256k1.h>
|
||||
#include <secp256k1_recovery.h>
|
||||
|
||||
#if _WIN32
|
||||
# include <malloc.h>
|
||||
|
|
@ -23,15 +24,16 @@
|
|||
namespace fc { namespace ecc {
|
||||
namespace detail
|
||||
{
|
||||
const secp256k1_context_t* _get_context() {
|
||||
static secp256k1_context_t* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN | SECP256K1_CONTEXT_RANGEPROOF | SECP256K1_CONTEXT_COMMIT );
|
||||
const secp256k1_context* _get_context() {
|
||||
static secp256k1_context* ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY | SECP256K1_CONTEXT_SIGN );
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void _init_lib() {
|
||||
static const secp256k1_context_t* ctx = _get_context();
|
||||
static const secp256k1_context* ctx = _get_context();
|
||||
static int init_o = init_openssl();
|
||||
(void)ctx;
|
||||
(void)init_o;
|
||||
}
|
||||
|
||||
class public_key_impl
|
||||
|
|
@ -68,7 +70,16 @@ namespace fc { namespace ecc {
|
|||
FC_ASSERT( my->_key != empty_priv );
|
||||
FC_ASSERT( other.my->_key != empty_pub );
|
||||
public_key_data pub(other.my->_key);
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( detail::_get_context(), (unsigned char*) pub.begin(), pub.size(), (unsigned char*) my->_key.data() ) );
|
||||
|
||||
secp256k1_pubkey pub_key;
|
||||
FC_ASSERT( secp256k1_ec_pubkey_parse( detail::_get_context(), &pub_key, (const unsigned char*) pub.data, pub.size() ) );
|
||||
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_mul( detail::_get_context(), &pub_key, (const unsigned char*) my->_key.data() ) );
|
||||
|
||||
size_t pk_len = pub.size();
|
||||
FC_ASSERT( secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char *) pub.data, (size_t*) &pk_len, &pub_key, SECP256K1_EC_COMPRESSED ) );
|
||||
FC_ASSERT( pk_len == pub.size() );
|
||||
|
||||
return fc::sha512::hash( pub.begin() + 1, pub.size() - 1 );
|
||||
}
|
||||
|
||||
|
|
@ -103,7 +114,16 @@ namespace fc { namespace ecc {
|
|||
FC_ASSERT( my->_key != empty_pub );
|
||||
public_key_data new_key;
|
||||
memcpy( new_key.begin(), my->_key.begin(), new_key.size() );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), (unsigned char*) new_key.begin(), new_key.size(), (unsigned char*) digest.data() ) );
|
||||
|
||||
secp256k1_pubkey pub_key;
|
||||
FC_ASSERT( secp256k1_ec_pubkey_parse( detail::_get_context(), &pub_key, (const unsigned char*) new_key.data, new_key.size() ) );
|
||||
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), &pub_key, (unsigned char*) digest.data() ) );
|
||||
|
||||
size_t pk_len = new_key.size();
|
||||
FC_ASSERT( secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char *) new_key.data, (size_t*) &pk_len, &pub_key, SECP256K1_EC_COMPRESSED ) );
|
||||
FC_ASSERT( pk_len == new_key.size() );
|
||||
|
||||
return public_key( new_key );
|
||||
}
|
||||
|
||||
|
|
@ -123,9 +143,10 @@ namespace fc { namespace ecc {
|
|||
{
|
||||
FC_ASSERT( my->_key != empty_pub );
|
||||
public_key_point_data dat;
|
||||
unsigned int pk_len = my->_key.size();
|
||||
memcpy( dat.begin(), my->_key.begin(), pk_len );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_decompress( detail::_get_context(), (unsigned char *) dat.begin(), (int*) &pk_len ) );
|
||||
secp256k1_pubkey pubkey;
|
||||
FC_ASSERT( secp256k1_ec_pubkey_parse( detail::_get_context(), &pubkey, (const unsigned char *) my->_key.data, my->_key.size() ) );
|
||||
size_t pk_len = dat.size();
|
||||
FC_ASSERT( secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char *) dat.begin(), (size_t*) &pk_len, &pubkey, SECP256K1_EC_UNCOMPRESSED ) );
|
||||
FC_ASSERT( pk_len == dat.size() );
|
||||
return dat;
|
||||
}
|
||||
|
|
@ -162,8 +183,14 @@ namespace fc { namespace ecc {
|
|||
FC_ASSERT( is_canonical( c ), "signature is not canonical" );
|
||||
}
|
||||
|
||||
unsigned int pk_len;
|
||||
FC_ASSERT( secp256k1_ecdsa_recover_compact( detail::_get_context(), (unsigned char*) digest.data(), (unsigned char*) c.begin() + 1, (unsigned char*) my->_key.begin(), (int*) &pk_len, 1, (*c.begin() - 27) & 3 ) );
|
||||
secp256k1_ecdsa_recoverable_signature sig;
|
||||
FC_ASSERT( secp256k1_ecdsa_recoverable_signature_parse_compact( detail::_get_context(), &sig, (const unsigned char*) c.begin() + 1, (*c.begin() - 27) & 3 ) );
|
||||
|
||||
secp256k1_pubkey pubkey;
|
||||
FC_ASSERT( secp256k1_ecdsa_recover( detail::_get_context(), &pubkey, &sig, (const unsigned char*) digest.data() ) );
|
||||
|
||||
size_t pk_len = my->_key.size();
|
||||
FC_ASSERT( secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char *) my->_key.data, (size_t*) &pk_len, &pubkey, SECP256K1_EC_COMPRESSED ) );
|
||||
FC_ASSERT( pk_len == my->_key.size() );
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +206,16 @@ namespace fc { namespace ecc {
|
|||
fc::sha512 l = mac.digest( c.data(), c.data_size(), data.begin(), data.size() );
|
||||
fc::sha256 left = detail::_left(l);
|
||||
FC_ASSERT( left < detail::get_curve_order() );
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), (unsigned char*) key.begin(), key.size(), (unsigned char*) left.data() ) > 0 );
|
||||
|
||||
secp256k1_pubkey pub_key;
|
||||
FC_ASSERT( secp256k1_ec_pubkey_parse( detail::_get_context(), &pub_key, (const unsigned char*) key.data, key.size() ) );
|
||||
|
||||
FC_ASSERT( secp256k1_ec_pubkey_tweak_add( detail::_get_context(), &pub_key, (unsigned char*) left.data() ) );
|
||||
|
||||
size_t pk_len = key.size();
|
||||
FC_ASSERT( secp256k1_ec_pubkey_serialize( detail::_get_context(), (unsigned char *) key.data, (size_t*) &pk_len, &pub_key, SECP256K1_EC_COMPRESSED ) );
|
||||
FC_ASSERT( pk_len == key.size() );
|
||||
|
||||
// FIXME: check validity - if left + key == infinity then invalid
|
||||
extended_public_key result( key, detail::_right(l), i, fingerprint(), depth + 1 );
|
||||
return result;
|
||||
|
|
@ -200,102 +236,4 @@ namespace fc { namespace ecc {
|
|||
return result;
|
||||
}
|
||||
|
||||
commitment_type blind( const blind_factor_type& blind, uint64_t value )
|
||||
{
|
||||
commitment_type result;
|
||||
FC_ASSERT( secp256k1_pedersen_commit( detail::_get_context(), (unsigned char*)&result, (unsigned char*)&blind, value ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
blind_factor_type blind_sum( const std::vector<blind_factor_type>& blinds_in, uint32_t non_neg )
|
||||
{
|
||||
blind_factor_type result;
|
||||
std::vector<const unsigned char*> blinds(blinds_in.size());
|
||||
for( uint32_t i = 0; i < blinds_in.size(); ++i ) blinds[i] = (const unsigned char*)&blinds_in[i];
|
||||
FC_ASSERT( secp256k1_pedersen_blind_sum( detail::_get_context(), (unsigned char*)&result, blinds.data(), blinds_in.size(), non_neg ) );
|
||||
return result;
|
||||
}
|
||||
|
||||
/** verifies taht commnits + neg_commits + excess == 0 */
|
||||
bool verify_sum( const std::vector<commitment_type>& commits_in, const std::vector<commitment_type>& neg_commits_in, int64_t excess )
|
||||
{
|
||||
std::vector<const unsigned char*> commits(commits_in.size());
|
||||
for( uint32_t i = 0; i < commits_in.size(); ++i ) commits[i] = (const unsigned char*)&commits_in[i];
|
||||
std::vector<const unsigned char*> neg_commits(neg_commits_in.size());
|
||||
for( uint32_t i = 0; i < neg_commits_in.size(); ++i ) neg_commits[i] = (const unsigned char*)&neg_commits_in[i];
|
||||
|
||||
return secp256k1_pedersen_verify_tally( detail::_get_context(), commits.data(), commits.size(), neg_commits.data(), neg_commits.size(), excess );
|
||||
}
|
||||
|
||||
bool verify_range( uint64_t& min_val, uint64_t& max_val, const commitment_type& commit, const std::vector<char>& proof )
|
||||
{
|
||||
return secp256k1_rangeproof_verify( detail::_get_context(), &min_val, &max_val, (const unsigned char*)&commit, (const unsigned char*)proof.data(), proof.size() );
|
||||
}
|
||||
|
||||
std::vector<char> range_proof_sign( uint64_t min_value,
|
||||
const commitment_type& commit,
|
||||
const blind_factor_type& commit_blind,
|
||||
const blind_factor_type& nonce,
|
||||
int8_t base10_exp,
|
||||
uint8_t min_bits,
|
||||
uint64_t actual_value
|
||||
)
|
||||
{
|
||||
int proof_len = 5134;
|
||||
std::vector<char> proof(proof_len);
|
||||
|
||||
FC_ASSERT( secp256k1_rangeproof_sign( detail::_get_context(),
|
||||
(unsigned char*)proof.data(),
|
||||
&proof_len, min_value,
|
||||
(const unsigned char*)&commit,
|
||||
(const unsigned char*)&commit_blind,
|
||||
(const unsigned char*)&nonce,
|
||||
base10_exp, min_bits, actual_value ) );
|
||||
proof.resize(proof_len);
|
||||
return proof;
|
||||
}
|
||||
|
||||
|
||||
bool verify_range_proof_rewind( blind_factor_type& blind_out,
|
||||
uint64_t& value_out,
|
||||
string& message_out,
|
||||
const blind_factor_type& nonce,
|
||||
uint64_t& min_val,
|
||||
uint64_t& max_val,
|
||||
commitment_type commit,
|
||||
const std::vector<char>& proof )
|
||||
{
|
||||
char msg[4096];
|
||||
int mlen = 0;
|
||||
FC_ASSERT( secp256k1_rangeproof_rewind( detail::_get_context(),
|
||||
(unsigned char*)&blind_out,
|
||||
&value_out,
|
||||
(unsigned char*)msg,
|
||||
&mlen,
|
||||
(const unsigned char*)&nonce,
|
||||
&min_val,
|
||||
&max_val,
|
||||
(const unsigned char*)&commit,
|
||||
(const unsigned char*)proof.data(),
|
||||
proof.size() ) );
|
||||
|
||||
message_out = std::string( msg, mlen );
|
||||
return true;
|
||||
}
|
||||
|
||||
range_proof_info range_get_info( const std::vector<char>& proof )
|
||||
{
|
||||
range_proof_info result;
|
||||
FC_ASSERT( secp256k1_rangeproof_info( detail::_get_context(),
|
||||
(int*)&result.exp,
|
||||
(int*)&result.mantissa,
|
||||
(uint64_t*)&result.min_value,
|
||||
(uint64_t*)&result.max_value,
|
||||
(const unsigned char*)proof.data(),
|
||||
(int)proof.size() ) );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -91,6 +91,8 @@ namespace fc {
|
|||
if( ve.size() )
|
||||
memcpy(&bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
else
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
for (size_t i = 0; i < bi.data_size(); i++) {
|
||||
bi.data()[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
#include <string>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <fc/log/logger.hpp>
|
||||
|
||||
namespace fc
|
||||
{
|
||||
struct openssl_scope
|
||||
|
|
@ -15,9 +17,6 @@ namespace fc
|
|||
static path _configurationFilePath;
|
||||
openssl_scope()
|
||||
{
|
||||
ERR_load_crypto_strings();
|
||||
OpenSSL_add_all_algorithms();
|
||||
|
||||
const boost::filesystem::path& boostPath = _configurationFilePath;
|
||||
if(boostPath.empty() == false)
|
||||
{
|
||||
|
|
@ -30,13 +29,16 @@ namespace fc
|
|||
#endif
|
||||
}
|
||||
|
||||
OPENSSL_config(nullptr);
|
||||
if (CONF_modules_load_file(_configurationFilePath.string().c_str(), "fc", CONF_MFLAGS_IGNORE_MISSING_FILE) <= 0) {
|
||||
elog("FATAL: error loading configuration file\n");
|
||||
ERR_print_errors_fp(stderr);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
~openssl_scope()
|
||||
{
|
||||
EVP_cleanup();
|
||||
ERR_free_strings();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
#include <openssl/rand.h>
|
||||
#include <fc/crypto/openssl.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
#include <fc/fwd_impl.hpp>
|
||||
|
||||
|
||||
namespace fc {
|
||||
|
||||
void rand_bytes(char* buf, int count)
|
||||
{
|
||||
static int init = init_openssl();
|
||||
|
||||
int result = RAND_bytes((unsigned char*)buf, count);
|
||||
if (result != 1)
|
||||
FC_THROW("Error calling OpenSSL's RAND_bytes(): ${code}", ("code", (uint32_t)ERR_get_error()));
|
||||
}
|
||||
|
||||
void rand_pseudo_bytes(char* buf, int count)
|
||||
{
|
||||
static int init = init_openssl();
|
||||
|
||||
int result = RAND_pseudo_bytes((unsigned char*)buf, count);
|
||||
if (result == -1)
|
||||
FC_THROW("Error calling OpenSSL's RAND_pseudo_bytes(): ${code}", ("code", (uint32_t)ERR_get_error()));
|
||||
}
|
||||
|
||||
} // namespace fc
|
||||
|
|
@ -106,7 +106,9 @@ bool operator == ( const ripemd160& h1, const ripemd160& h2 ) {
|
|||
void from_variant( const variant& v, ripemd160& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
for (size_t i = 0; i < bi.data_size(); i++) {
|
||||
bi.data()[i] = 0;
|
||||
}
|
||||
if( ve.size() )
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,7 +90,9 @@ bool operator == ( const sha1& h1, const sha1& h2 ) {
|
|||
void from_variant( const variant& v, sha1& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
for (size_t i = 0; i < bi.data_size(); i++) {
|
||||
bi.data()[i] = 0;
|
||||
}
|
||||
if( ve.size() )
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,9 @@ namespace fc {
|
|||
void from_variant( const variant& v, sha224& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
for (size_t i = 0; i < bi.data_size(); i++) {
|
||||
bi.data()[i] = 0;
|
||||
}
|
||||
if( ve.size() )
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -200,7 +200,9 @@ namespace fc {
|
|||
void from_variant( const variant& v, sha256& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
for (size_t i = 0; i < bi.data_size(); i++) {
|
||||
bi.data()[i] = 0;
|
||||
}
|
||||
if( ve.size() )
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,9 @@ namespace fc {
|
|||
void from_variant( const variant& v, sha512& bi, uint32_t max_depth )
|
||||
{
|
||||
std::vector<char> ve = v.as< std::vector<char> >( max_depth );
|
||||
memset( &bi, char(0), sizeof(bi) );
|
||||
for (size_t i = 0; i < bi.data_size(); i++) {
|
||||
bi.data()[i] = 0;
|
||||
}
|
||||
if( ve.size() )
|
||||
memcpy( &bi, ve.data(), fc::min<size_t>(ve.size(),sizeof(bi)) );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -168,7 +168,8 @@ namespace fc {
|
|||
filename(p),
|
||||
flush(true),
|
||||
rotate(false),
|
||||
rotation_compression(false)
|
||||
rotation_compression(false),
|
||||
max_object_depth(FC_MAX_LOG_OBJECT_DEPTH)
|
||||
{}
|
||||
|
||||
file_appender::file_appender( const variant& args ) :
|
||||
|
|
|
|||
|
|
@ -132,14 +132,10 @@ namespace fc { namespace http {
|
|||
typedef websocketpp::transport::asio::tls_socket::endpoint socket_type;
|
||||
};
|
||||
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config>
|
||||
transport_type;
|
||||
typedef websocketpp::transport::asio::endpoint<transport_config> transport_type;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
using websocketpp::connection_hdl;
|
||||
typedef websocketpp::server<asio_with_stub_log> websocket_server_type;
|
||||
typedef websocketpp::server<asio_tls_stub_log> websocket_tls_server_type;
|
||||
|
|
@ -152,7 +148,7 @@ namespace fc { namespace http {
|
|||
:_ws_connection(con){
|
||||
}
|
||||
|
||||
~websocket_connection_impl()
|
||||
virtual ~websocket_connection_impl()
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -306,7 +302,7 @@ namespace fc { namespace http {
|
|||
context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
|
||||
try {
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
/*boost::asio::ssl::context::no_sslv2 |*/
|
||||
boost::asio::ssl::context::no_sslv3 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
ctx->set_password_callback([=](std::size_t max_length, boost::asio::ssl::context::password_purpose){ return ssl_password;});
|
||||
|
|
@ -399,35 +395,26 @@ namespace fc { namespace http {
|
|||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
typedef websocketpp::client<asio_with_stub_log> websocket_client_type;
|
||||
typedef websocketpp::client<asio_tls_stub_log> websocket_tls_client_type;
|
||||
|
||||
typedef websocket_client_type::connection_ptr websocket_client_connection_type;
|
||||
typedef websocket_tls_client_type::connection_ptr websocket_tls_client_connection_type;
|
||||
|
||||
class websocket_client_impl
|
||||
using websocketpp::connection_hdl;
|
||||
|
||||
template<typename T>
|
||||
class generic_websocket_client_impl
|
||||
{
|
||||
public:
|
||||
typedef websocket_client_type::message_ptr message_ptr;
|
||||
|
||||
websocket_client_impl()
|
||||
generic_websocket_client_impl()
|
||||
:_client_thread( fc::thread::current() )
|
||||
{
|
||||
_client.clear_access_channels( websocketpp::log::alevel::all );
|
||||
_client.set_message_handler( [&]( connection_hdl hdl, message_ptr msg ){
|
||||
_client.set_message_handler( [&]( connection_hdl hdl,
|
||||
typename websocketpp::client<T>::message_ptr msg ){
|
||||
_client_thread.async( [&](){
|
||||
idump((msg->get_payload()));
|
||||
wdump((msg->get_payload()));
|
||||
//std::cerr<<"recv: "<<msg->get_payload()<<"\n";
|
||||
auto received = msg->get_payload();
|
||||
fc::async( [=](){
|
||||
|
|
@ -447,79 +434,47 @@ namespace fc { namespace http {
|
|||
_client_thread.async( [&](){ if( _connection ) _connection->closed(); _connection.reset(); } ).wait();
|
||||
if( _connected && !_connected->ready() )
|
||||
_connected->set_exception( exception_ptr( new FC_EXCEPTION( exception, "${message}", ("message",message)) ) );
|
||||
if( _closed )
|
||||
_closed->set_value();
|
||||
//if( _closed && !_closed->ready() )
|
||||
// _closed->set_value();
|
||||
_failed = true;
|
||||
});
|
||||
|
||||
_client.init_asio( &fc::asio::default_io_service() );
|
||||
}
|
||||
~websocket_client_impl()
|
||||
virtual ~generic_websocket_client_impl()
|
||||
{
|
||||
if(_connection )
|
||||
if( _connection )
|
||||
{
|
||||
_connection->close(0, "client closed");
|
||||
_connection.reset();
|
||||
_closed->wait();
|
||||
}
|
||||
if( _closed && !_failed)
|
||||
_closed->wait();
|
||||
}
|
||||
|
||||
bool _failed = false;
|
||||
fc::promise<void>::ptr _connected;
|
||||
fc::promise<void>::ptr _closed;
|
||||
fc::thread& _client_thread;
|
||||
websocket_client_type _client;
|
||||
websocketpp::client<T> _client;
|
||||
websocket_connection_ptr _connection;
|
||||
std::string _uri;
|
||||
fc::optional<connection_hdl> _hdl;
|
||||
};
|
||||
|
||||
class websocket_client_impl : public generic_websocket_client_impl<asio_with_stub_log>
|
||||
{};
|
||||
|
||||
|
||||
class websocket_tls_client_impl
|
||||
class websocket_tls_client_impl : public generic_websocket_client_impl<asio_tls_stub_log>
|
||||
{
|
||||
public:
|
||||
typedef websocket_tls_client_type::message_ptr message_ptr;
|
||||
|
||||
websocket_tls_client_impl( const std::string& ca_filename )
|
||||
:_client_thread( fc::thread::current() )
|
||||
: generic_websocket_client_impl()
|
||||
{
|
||||
// ca_filename has special values:
|
||||
// "_none" disables cert checking (potentially insecure!)
|
||||
// "_default" uses default CA's provided by OS
|
||||
|
||||
_client.clear_access_channels( websocketpp::log::alevel::all );
|
||||
_client.set_message_handler( [&]( connection_hdl hdl, message_ptr msg ){
|
||||
_client_thread.async( [&](){
|
||||
idump((msg->get_payload()));
|
||||
_connection->on_message( msg->get_payload() );
|
||||
}).wait();
|
||||
});
|
||||
_client.set_close_handler( [=]( connection_hdl hdl ){
|
||||
if( _connection )
|
||||
{
|
||||
try {
|
||||
_client_thread.async( [&](){
|
||||
ilog(". ${p}", ("p",uint64_t(_connection.get())));
|
||||
if( !_shutting_down && !_closed && _connection )
|
||||
_connection->closed();
|
||||
_connection.reset();
|
||||
} ).wait();
|
||||
} catch ( const fc::exception& e )
|
||||
{
|
||||
if( _closed ) _closed->set_exception( e.dynamic_copy_exception() );
|
||||
}
|
||||
if( _closed ) _closed->set_value();
|
||||
}
|
||||
});
|
||||
_client.set_fail_handler( [=]( connection_hdl hdl ){
|
||||
elog( "." );
|
||||
auto con = _client.get_con_from_hdl(hdl);
|
||||
auto message = con->get_ec().message();
|
||||
if( _connection )
|
||||
_client_thread.async( [&](){ if( _connection ) _connection->closed(); _connection.reset(); } ).wait();
|
||||
if( _connected && !_connected->ready() )
|
||||
_connected->set_exception( exception_ptr( new FC_EXCEPTION( exception, "${message}", ("message",message)) ) );
|
||||
if( _closed )
|
||||
_closed->set_value();
|
||||
});
|
||||
|
||||
//
|
||||
// We need ca_filename to be copied into the closure, as the referenced object might be destroyed by the caller by the time
|
||||
// tls_init_handler() is called. According to [1], capture-by-value results in the desired behavior (i.e. creation of
|
||||
|
|
@ -540,7 +495,7 @@ namespace fc { namespace http {
|
|||
context_ptr ctx = websocketpp::lib::make_shared<boost::asio::ssl::context>(boost::asio::ssl::context::tlsv1);
|
||||
try {
|
||||
ctx->set_options(boost::asio::ssl::context::default_workarounds |
|
||||
boost::asio::ssl::context::no_sslv2 |
|
||||
/*boost::asio::ssl::context::no_sslv2 |*/
|
||||
boost::asio::ssl::context::no_sslv3 |
|
||||
boost::asio::ssl::context::single_dh_use);
|
||||
|
||||
|
|
@ -552,18 +507,8 @@ namespace fc { namespace http {
|
|||
return ctx;
|
||||
});
|
||||
|
||||
_client.init_asio( &fc::asio::default_io_service() );
|
||||
}
|
||||
~websocket_tls_client_impl()
|
||||
{
|
||||
if(_connection )
|
||||
{
|
||||
ilog(".");
|
||||
_shutting_down = true;
|
||||
_connection->close(0, "client closed");
|
||||
_closed->wait();
|
||||
}
|
||||
}
|
||||
virtual ~websocket_tls_client_impl() {}
|
||||
|
||||
std::string get_host()const
|
||||
{
|
||||
|
|
@ -576,20 +521,19 @@ namespace fc { namespace http {
|
|||
return;
|
||||
ctx->set_verify_mode( boost::asio::ssl::verify_peer );
|
||||
if( ca_filename == "_default" )
|
||||
{
|
||||
#if WIN32
|
||||
add_windows_root_certs( *ctx );
|
||||
#else
|
||||
ctx->set_default_verify_paths();
|
||||
#endif
|
||||
}
|
||||
else
|
||||
ctx->load_verify_file( ca_filename );
|
||||
ctx->set_verify_depth(10);
|
||||
ctx->set_verify_callback( boost::asio::ssl::rfc2818_verification( get_host() ) );
|
||||
}
|
||||
|
||||
bool _shutting_down = false;
|
||||
fc::promise<void>::ptr _connected;
|
||||
fc::promise<void>::ptr _closed;
|
||||
fc::thread& _client_thread;
|
||||
websocket_tls_client_type _client;
|
||||
websocket_connection_ptr _connection;
|
||||
std::string _uri;
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -622,8 +566,16 @@ namespace fc { namespace http {
|
|||
my->_server.start_accept();
|
||||
}
|
||||
|
||||
void websocket_server::stop_listening()
|
||||
{
|
||||
my->_server.stop_listening();
|
||||
}
|
||||
|
||||
|
||||
void websocket_server::close()
|
||||
{
|
||||
for (auto& connection : my->_connections)
|
||||
my->_server.close(connection.first, websocketpp::close::status::normal, "Goodbye");
|
||||
}
|
||||
|
||||
websocket_tls_server::websocket_tls_server( const string& server_pem, const string& ssl_password ):my( new detail::websocket_tls_server_impl(server_pem, ssl_password) ) {}
|
||||
websocket_tls_server::~websocket_tls_server(){}
|
||||
|
|
@ -646,7 +598,6 @@ namespace fc { namespace http {
|
|||
my->_server.start_accept();
|
||||
}
|
||||
|
||||
|
||||
websocket_tls_client::websocket_tls_client( const std::string& ca_filename ):my( new detail::websocket_tls_client_impl( ca_filename ) ) {}
|
||||
websocket_tls_client::~websocket_tls_client(){ }
|
||||
|
||||
|
|
@ -659,7 +610,7 @@ namespace fc { namespace http {
|
|||
{ try {
|
||||
if( uri.substr(0,4) == "wss:" )
|
||||
return secure_connect(uri);
|
||||
FC_ASSERT( uri.substr(0,3) == "ws:" );
|
||||
FC_ASSERT( uri.substr(0,4) == "wss:" || uri.substr(0,3) == "ws:", "Unsupported protocol" );
|
||||
|
||||
// wlog( "connecting to ${uri}", ("uri",uri));
|
||||
websocketpp::lib::error_code ec;
|
||||
|
|
@ -687,7 +638,8 @@ namespace fc { namespace http {
|
|||
{ try {
|
||||
if( uri.substr(0,3) == "ws:" )
|
||||
return connect(uri);
|
||||
FC_ASSERT( uri.substr(0,4) == "wss:" );
|
||||
FC_ASSERT( uri.substr(0,4) == "wss:" || uri.substr(0,3) == "ws:", "Unsupported protocol" );
|
||||
|
||||
// wlog( "connecting to ${uri}", ("uri",uri));
|
||||
websocketpp::lib::error_code ec;
|
||||
|
||||
|
|
@ -709,6 +661,19 @@ namespace fc { namespace http {
|
|||
return smy->_connection;
|
||||
} FC_CAPTURE_AND_RETHROW( (uri) ) }
|
||||
|
||||
void websocket_client::close()
|
||||
{
|
||||
if (my->_hdl)
|
||||
my->_client.close(*my->_hdl, websocketpp::close::status::normal, "Goodbye");
|
||||
}
|
||||
|
||||
void websocket_client::synchronous_close()
|
||||
{
|
||||
close();
|
||||
if (my->_closed)
|
||||
my->_closed->wait();
|
||||
}
|
||||
|
||||
websocket_connection_ptr websocket_tls_client::connect( const std::string& uri )
|
||||
{ try {
|
||||
// wlog( "connecting to ${uri}", ("uri",uri));
|
||||
|
|
|
|||
|
|
@ -182,7 +182,7 @@ namespace fc
|
|||
}
|
||||
}
|
||||
} // try
|
||||
catch (fc::canceled_exception)
|
||||
catch (fc::canceled_exception&)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
|
|
|||
158
src/rpc/cli.cpp
158
src/rpc/cli.cpp
|
|
@ -7,22 +7,8 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
// I don't know exactly what version of readline we need. I know the 4.2 version that ships on some macs is
|
||||
// missing some functions we require. We're developing against 6.3, but probably anything in the 6.x
|
||||
// series is fine
|
||||
# if RL_VERSION_MAJOR < 6
|
||||
# ifdef _MSC_VER
|
||||
# pragma message("You have an old version of readline installed that might not support some of the features we need")
|
||||
# pragma message("Readline support will not be compiled in")
|
||||
# else
|
||||
# warning "You have an old version of readline installed that might not support some of the features we need"
|
||||
# warning "Readline support will not be compiled in"
|
||||
# endif
|
||||
# undef HAVE_READLINE
|
||||
# endif
|
||||
#ifdef HAVE_EDITLINE
|
||||
# include "editline.h"
|
||||
# ifdef WIN32
|
||||
# include <io.h>
|
||||
# endif
|
||||
|
|
@ -131,61 +117,107 @@ void cli::run()
|
|||
}
|
||||
|
||||
|
||||
char * dupstr (const char* s) {
|
||||
char *r;
|
||||
|
||||
r = (char*) malloc ((strlen (s) + 1));
|
||||
strcpy (r, s);
|
||||
return (r);
|
||||
}
|
||||
|
||||
char* my_generator(const char* text, int state)
|
||||
/****
|
||||
* @brief loop through list of commands, attempting to find a match
|
||||
* @param token what the user typed
|
||||
* @param match sets to 1 if only 1 match was found
|
||||
* @returns the remaining letters of the name of the command or NULL if 1 match not found
|
||||
*/
|
||||
static char *my_rl_complete(char *token, int *match)
|
||||
{
|
||||
static int list_index, len;
|
||||
const char *name;
|
||||
|
||||
if (!state) {
|
||||
list_index = 0;
|
||||
len = strlen (text);
|
||||
}
|
||||
const auto& cmds = cli_commands();
|
||||
const size_t partlen = strlen (token); /* Part of token */
|
||||
|
||||
auto& cmd = cli_commands();
|
||||
|
||||
while( list_index < cmd.size() )
|
||||
std::vector<std::reference_wrapper<const std::string>> matched_cmds;
|
||||
for( const std::string& it : cmds )
|
||||
{
|
||||
name = cmd[list_index].c_str();
|
||||
list_index++;
|
||||
|
||||
if (strncmp (name, text, len) == 0)
|
||||
return (dupstr(name));
|
||||
if( it.compare(0, partlen, token) == 0 )
|
||||
{
|
||||
matched_cmds.push_back( it );
|
||||
}
|
||||
}
|
||||
|
||||
/* If no names matched, then return NULL. */
|
||||
return ((char *)NULL);
|
||||
if( matched_cmds.size() == 0 )
|
||||
return NULL;
|
||||
|
||||
const std::string& first_matched_cmd = matched_cmds[0];
|
||||
if( matched_cmds.size() == 1 )
|
||||
{
|
||||
*match = 1;
|
||||
std::string matched_cmd = first_matched_cmd + " ";
|
||||
return strdup( matched_cmd.c_str() + partlen );
|
||||
}
|
||||
|
||||
size_t first_cmd_len = first_matched_cmd.size();
|
||||
size_t matched_len = partlen;
|
||||
for( ; matched_len < first_cmd_len; ++matched_len )
|
||||
{
|
||||
char next_char = first_matched_cmd[matched_len];
|
||||
bool end = false;
|
||||
for( const std::string& s : matched_cmds )
|
||||
{
|
||||
if( s.size() <= matched_len || s[matched_len] != next_char )
|
||||
{
|
||||
end = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( end )
|
||||
break;
|
||||
}
|
||||
|
||||
if( matched_len == partlen )
|
||||
return NULL;
|
||||
|
||||
std::string matched_cmd_part = first_matched_cmd.substr( partlen, matched_len - partlen );
|
||||
return strdup( matched_cmd_part.c_str() );
|
||||
}
|
||||
|
||||
|
||||
static char** cli_completion( const char * text , int start, int end)
|
||||
/***
|
||||
* @brief return an array of matching commands
|
||||
* @param token the incoming text
|
||||
* @param array the resultant array of possible matches
|
||||
* @returns the number of matches
|
||||
*/
|
||||
static int cli_completion(char *token, char ***array)
|
||||
{
|
||||
char **matches;
|
||||
matches = (char **)NULL;
|
||||
auto& cmd = cli_commands();
|
||||
int num_commands = cmd.size();
|
||||
|
||||
#ifdef HAVE_READLINE
|
||||
if (start == 0)
|
||||
matches = rl_completion_matches ((char*)text, &my_generator);
|
||||
else
|
||||
rl_bind_key('\t',rl_abort);
|
||||
#endif
|
||||
char **copy = (char **) malloc (num_commands * sizeof(char *));
|
||||
if (copy == NULL)
|
||||
{
|
||||
// possible out of memory
|
||||
return 0;
|
||||
}
|
||||
int total_matches = 0;
|
||||
|
||||
return (matches);
|
||||
int partlen = strlen(token);
|
||||
|
||||
for (const std::string& it : cmd)
|
||||
{
|
||||
if ( it.compare(0, partlen, token) == 0)
|
||||
{
|
||||
copy[total_matches] = strdup ( it.c_str() );
|
||||
++total_matches;
|
||||
}
|
||||
}
|
||||
*array = copy;
|
||||
|
||||
return total_matches;
|
||||
}
|
||||
|
||||
|
||||
/***
|
||||
* @brief Read input from the user
|
||||
* @param prompt the prompt to display
|
||||
* @param line what the user typed
|
||||
*/
|
||||
void cli::getline( const fc::string& prompt, fc::string& line)
|
||||
{
|
||||
// getting file descriptor for C++ streams is near impossible
|
||||
// so we just assume it's the same as the C stream...
|
||||
#ifdef HAVE_READLINE
|
||||
#ifdef HAVE_EDITLINE
|
||||
#ifndef WIN32
|
||||
if( isatty( fileno( stdin ) ) )
|
||||
#else
|
||||
|
|
@ -197,8 +229,9 @@ void cli::getline( const fc::string& prompt, fc::string& line)
|
|||
if( _isatty( _fileno( stdin ) ) )
|
||||
#endif
|
||||
{
|
||||
rl_attempted_completion_function = cli_completion;
|
||||
|
||||
el_hist_size = 256;
|
||||
rl_set_complete_func(my_rl_complete);
|
||||
rl_set_list_possib_func(cli_completion);
|
||||
static fc::thread getline_thread("getline");
|
||||
getline_thread.async( [&](){
|
||||
char* line_read = nullptr;
|
||||
|
|
@ -206,10 +239,17 @@ void cli::getline( const fc::string& prompt, fc::string& line)
|
|||
line_read = readline(prompt.c_str());
|
||||
if( line_read == nullptr )
|
||||
FC_THROW_EXCEPTION( fc::eof_exception, "" );
|
||||
rl_bind_key( '\t', rl_complete );
|
||||
if( *line_read )
|
||||
add_history(line_read);
|
||||
line = line_read;
|
||||
try
|
||||
{
|
||||
if (*line_read)
|
||||
add_history(line_read);
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
free(line_read);
|
||||
throw;
|
||||
}
|
||||
free(line_read);
|
||||
}).wait();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ websocket_api_connection::~websocket_api_connection()
|
|||
{
|
||||
}
|
||||
|
||||
websocket_api_connection::websocket_api_connection( fc::http::websocket_connection& c, uint32_t max_depth )
|
||||
websocket_api_connection::websocket_api_connection(const std::shared_ptr<fc::http::websocket_connection>& c, uint32_t max_depth )
|
||||
: api_connection(max_depth),_connection(c)
|
||||
{
|
||||
_rpc_state.add_method( "call", [this]( const variants& args ) -> variant
|
||||
|
|
@ -47,9 +47,12 @@ websocket_api_connection::websocket_api_connection( fc::http::websocket_connecti
|
|||
return this->receive_call( 0, method_name, args );
|
||||
} );
|
||||
|
||||
_connection.on_message_handler( [&]( const std::string& msg ){ on_message(msg,true); } );
|
||||
_connection.on_http_handler( [&]( const std::string& msg ){ return on_message(msg,false); } );
|
||||
_connection.closed.connect( [this](){ closed(); } );
|
||||
_connection->on_message_handler( [&]( const std::string& msg ){ on_message(msg,true); } );
|
||||
_connection->on_http_handler( [&]( const std::string& msg ){ return on_message(msg,false); } );
|
||||
_connection->closed.connect( [this](){
|
||||
closed();
|
||||
_connection = nullptr;
|
||||
} );
|
||||
}
|
||||
|
||||
variant websocket_api_connection::send_call(
|
||||
|
|
@ -58,7 +61,7 @@ variant websocket_api_connection::send_call(
|
|||
variants args /* = variants() */ )
|
||||
{
|
||||
auto request = _rpc_state.start_remote_call( "call", {api_id, std::move(method_name), std::move(args) } );
|
||||
_connection.send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth),
|
||||
_connection->send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ) );
|
||||
return _rpc_state.wait_for_response( *request.id );
|
||||
}
|
||||
|
|
@ -68,7 +71,7 @@ variant websocket_api_connection::send_callback(
|
|||
variants args /* = variants() */ )
|
||||
{
|
||||
auto request = _rpc_state.start_remote_call( "callback", {callback_id, std::move(args) } );
|
||||
_connection.send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth),
|
||||
_connection->send_message( fc::json::to_string(fc::variant(request, _max_conversion_depth),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ) );
|
||||
return _rpc_state.wait_for_response( *request.id );
|
||||
}
|
||||
|
|
@ -78,7 +81,7 @@ void websocket_api_connection::send_notice(
|
|||
variants args /* = variants() */ )
|
||||
{
|
||||
fc::rpc::request req{ optional<uint64_t>(), "notice", {callback_id, std::move(args)}};
|
||||
_connection.send_message( fc::json::to_string(fc::variant(req, _max_conversion_depth),
|
||||
_connection->send_message( fc::json::to_string(fc::variant(req, _max_conversion_depth),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth ) );
|
||||
}
|
||||
|
||||
|
|
@ -118,7 +121,7 @@ std::string websocket_api_connection::on_message(
|
|||
{
|
||||
auto reply = fc::json::to_string( response( *call.id, result, "2.0" ), fc::json::stringify_large_ints_and_doubles, _max_conversion_depth );
|
||||
if( send_message )
|
||||
_connection.send_message( reply );
|
||||
_connection->send_message( reply );
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
|
|
@ -136,7 +139,7 @@ std::string websocket_api_connection::on_message(
|
|||
auto reply = fc::json::to_string( variant(response( *call.id, error_object{ 1, optexcept->to_string(), fc::variant(*optexcept, _max_conversion_depth)}, "2.0" ), _max_conversion_depth ),
|
||||
fc::json::stringify_large_ints_and_doubles, _max_conversion_depth );
|
||||
if( send_message )
|
||||
_connection.send_message( reply );
|
||||
_connection->send_message( reply );
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
|
|
|||
31
src/static_variant.cpp
Normal file
31
src/static_variant.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#include <fc/static_variant.hpp>
|
||||
|
||||
|
||||
namespace fc { namespace impl {
|
||||
|
||||
dynamic_storage::dynamic_storage() : storage(nullptr) {};
|
||||
|
||||
dynamic_storage::~dynamic_storage()
|
||||
{
|
||||
release();
|
||||
}
|
||||
|
||||
void* dynamic_storage::data() const
|
||||
{
|
||||
FC_ASSERT( storage != nullptr );
|
||||
return (void*)storage;
|
||||
}
|
||||
|
||||
void dynamic_storage::alloc( size_t size )
|
||||
{
|
||||
release();
|
||||
storage = new char[size];
|
||||
}
|
||||
|
||||
void dynamic_storage::release()
|
||||
{
|
||||
delete [] storage;
|
||||
storage = nullptr;
|
||||
}
|
||||
|
||||
}}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
#include <fc/thread/thread.hpp>
|
||||
#include <boost/context/all.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
#include <vector>
|
||||
|
||||
|
|
@ -9,6 +8,12 @@
|
|||
#define BOOST_COROUTINES_NO_DEPRECATION_WARNING // Boost 1.61
|
||||
#define BOOST_COROUTINE_NO_DEPRECATION_WARNING // Boost 1.62
|
||||
|
||||
#if BOOST_VERSION >= 106800
|
||||
#include <boost/context/continuation_fcontext.hpp>
|
||||
#else
|
||||
#include <boost/context/all.hpp>
|
||||
#endif
|
||||
|
||||
#if BOOST_VERSION >= 106100
|
||||
#include <boost/coroutine/stack_allocator.hpp>
|
||||
namespace bc = boost::context::detail;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ namespace fc {
|
|||
}
|
||||
|
||||
void promise_base::cancel(const char* reason /* = nullptr */){
|
||||
synchronized(_spin_yield)
|
||||
// wlog("${desc} canceled!", ("desc", _desc? _desc : ""));
|
||||
_canceled = true;
|
||||
#ifndef NDEBUG
|
||||
|
|
|
|||
|
|
@ -13,18 +13,18 @@ namespace fc {
|
|||
{}
|
||||
|
||||
mutex::~mutex() {
|
||||
if( m_blist )
|
||||
{
|
||||
context* c = m_blist;
|
||||
fc::thread::current().debug("~mutex");
|
||||
#if 0
|
||||
while( c ) {
|
||||
// elog( "still blocking on context %p (%s)", m_blist, (m_blist->cur_task ? m_blist->cur_task->get_desc() : "no current task") );
|
||||
c = c->next_blocked_mutex;
|
||||
}
|
||||
#endif
|
||||
BOOST_ASSERT( false && "Attempt to free mutex while others are blocking on lock." );
|
||||
}
|
||||
// if( m_blist )
|
||||
// {
|
||||
// context* c = m_blist;
|
||||
// fc::thread::current().debug("~mutex");
|
||||
//#if 0
|
||||
// while( c ) {
|
||||
// // elog( "still blocking on context %p (%s)", m_blist, (m_blist->cur_task ? m_blist->cur_task->get_desc() : "no current task") );
|
||||
// c = c->next_blocked_mutex;
|
||||
// }
|
||||
//#endif
|
||||
// BOOST_ASSERT( false && "Attempt to free mutex while others are blocking on lock." );
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -596,7 +596,12 @@ namespace fc {
|
|||
else if( timeout_time != time_point::min() )
|
||||
{
|
||||
// there may be tasks that have been canceled we should filter them out now
|
||||
// rather than waiting...
|
||||
// rather than waiting...
|
||||
//
|
||||
|
||||
if (current->canceled){
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* This bit is kind of sloppy -- this wait was originally implemented as a wait
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ namespace fc {
|
|||
|
||||
bool is_utf8( const std::string& str )
|
||||
{
|
||||
auto itr = utf8::find_invalid(str.begin(), str.end());
|
||||
//auto itr = utf8::find_invalid(str.begin(), str.end());
|
||||
return utf8::is_valid( str.begin(), str.end() );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,11 +5,6 @@ target_link_libraries( bip_lock fc )
|
|||
add_executable( api api.cpp )
|
||||
target_link_libraries( api fc )
|
||||
|
||||
if( ECC_IMPL STREQUAL secp256k1 )
|
||||
add_executable( blind all_tests.cpp crypto/blind.cpp )
|
||||
target_link_libraries( blind fc )
|
||||
endif()
|
||||
|
||||
add_executable( task_cancel_test all_tests.cpp thread/task_cancel.cpp )
|
||||
target_link_libraries( task_cancel_test fc )
|
||||
|
||||
|
|
@ -41,10 +36,8 @@ add_executable( all_tests all_tests.cpp
|
|||
crypto/aes_test.cpp
|
||||
crypto/base_n_tests.cpp
|
||||
crypto/bigint_test.cpp
|
||||
crypto/blind.cpp
|
||||
crypto/blowfish_test.cpp
|
||||
crypto/dh_test.cpp
|
||||
crypto/rand_test.cpp
|
||||
crypto/sha_tests.cpp
|
||||
io/json_tests.cpp
|
||||
io/stream_tests.cpp
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ int main( int argc, char** argv )
|
|||
|
||||
fc::http::websocket_server server;
|
||||
server.on_connection([&]( const websocket_connection_ptr& c ){
|
||||
auto wsc = std::make_shared<websocket_api_connection>(*c, MAX_DEPTH);
|
||||
auto wsc = std::make_shared<websocket_api_connection>(c, MAX_DEPTH);
|
||||
auto login = std::make_shared<login_api>();
|
||||
login->calc = calc_api;
|
||||
wsc->register_api(fc::api<login_api>(login));
|
||||
|
|
@ -76,7 +76,7 @@ int main( int argc, char** argv )
|
|||
try {
|
||||
fc::http::websocket_client client;
|
||||
auto con = client.connect( "ws://localhost:8090" );
|
||||
auto apic = std::make_shared<websocket_api_connection>(*con, MAX_DEPTH);
|
||||
auto apic = std::make_shared<websocket_api_connection>(con, MAX_DEPTH);
|
||||
auto remote_login_api = apic->get_remote_api<login_api>();
|
||||
auto remote_calc = remote_login_api->get_calc();
|
||||
remote_calc->on_result( []( uint32_t r ) { elog( "callback result ${r}", ("r",r) ); } );
|
||||
|
|
|
|||
|
|
@ -1,305 +0,0 @@
|
|||
#define BOOST_TEST_MODULE BlindingTest
|
||||
#include <boost/test/unit_test.hpp>
|
||||
#include <fc/array.hpp>
|
||||
#include <fc/crypto/base58.hpp>
|
||||
#include <fc/crypto/hex.hpp>
|
||||
#include <fc/crypto/elliptic.hpp>
|
||||
#include <fc/crypto/openssl.hpp>
|
||||
#include <fc/exception/exception.hpp>
|
||||
|
||||
// See https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#Test_Vectors
|
||||
|
||||
static fc::string TEST1_SEED = "000102030405060708090a0b0c0d0e0f";
|
||||
static fc::string TEST1_M_PUB = "xpub661MyMwAqRbcFtXgS5sYJABqqG9YLmC4Q1Rdap9gSE8NqtwybGhePY2gZ29ESFjqJoCu1Rupje8YtGqsefD265TMg7usUDFdp6W1EGMcet8";
|
||||
static fc::string TEST1_M_PRIV = "xprv9s21ZrQH143K3QTDL4LXw2F7HEK3wJUD2nW2nRk4stbPy6cq3jPPqjiChkVvvNKmPGJxWUtg6LnF5kejMRNNU3TGtRBeJgk33yuGBxrMPHi";
|
||||
static fc::string TEST1_M_0H_PUB = "xpub68Gmy5EdvgibQVfPdqkBBCHxA5htiqg55crXYuXoQRKfDBFA1WEjWgP6LHhwBZeNK1VTsfTFUHCdrfp1bgwQ9xv5ski8PX9rL2dZXvgGDnw";
|
||||
static fc::string TEST1_M_0H_PRIV = "xprv9uHRZZhk6KAJC1avXpDAp4MDc3sQKNxDiPvvkX8Br5ngLNv1TxvUxt4cV1rGL5hj6KCesnDYUhd7oWgT11eZG7XnxHrnYeSvkzY7d2bhkJ7";
|
||||
static fc::string TEST1_M_0H_1_PUB = "xpub6ASuArnXKPbfEwhqN6e3mwBcDTgzisQN1wXN9BJcM47sSikHjJf3UFHKkNAWbWMiGj7Wf5uMash7SyYq527Hqck2AxYysAA7xmALppuCkwQ";
|
||||
static fc::string TEST1_M_0H_1_PRIV = "xprv9wTYmMFdV23N2TdNG573QoEsfRrWKQgWeibmLntzniatZvR9BmLnvSxqu53Kw1UmYPxLgboyZQaXwTCg8MSY3H2EU4pWcQDnRnrVA1xe8fs";
|
||||
static fc::string TEST1_M_0H_1_2H_PUB = "xpub6D4BDPcP2GT577Vvch3R8wDkScZWzQzMMUm3PWbmWvVJrZwQY4VUNgqFJPMM3No2dFDFGTsxxpG5uJh7n7epu4trkrX7x7DogT5Uv6fcLW5";
|
||||
static fc::string TEST1_M_0H_1_2H_PRIV = "xprv9z4pot5VBttmtdRTWfWQmoH1taj2axGVzFqSb8C9xaxKymcFzXBDptWmT7FwuEzG3ryjH4ktypQSAewRiNMjANTtpgP4mLTj34bhnZX7UiM";
|
||||
static fc::string TEST1_M_0H_1_2H_2_PUB = "xpub6FHa3pjLCk84BayeJxFW2SP4XRrFd1JYnxeLeU8EqN3vDfZmbqBqaGJAyiLjTAwm6ZLRQUMv1ZACTj37sR62cfN7fe5JnJ7dh8zL4fiyLHV";
|
||||
static fc::string TEST1_M_0H_1_2H_2_PRIV = "xprvA2JDeKCSNNZky6uBCviVfJSKyQ1mDYahRjijr5idH2WwLsEd4Hsb2Tyh8RfQMuPh7f7RtyzTtdrbdqqsunu5Mm3wDvUAKRHSC34sJ7in334";
|
||||
static fc::string TEST1_M_0H_1_2H_2_1g_PUB = "xpub6H1LXWLaKsWFhvm6RVpEL9P4KfRZSW7abD2ttkWP3SSQvnyA8FSVqNTEcYFgJS2UaFcxupHiYkro49S8yGasTvXEYBVPamhGW6cFJodrTHy";
|
||||
static fc::string TEST1_M_0H_1_2H_2_1g_PRIV = "xprvA41z7zogVVwxVSgdKUHDy1SKmdb533PjDz7J6N6mV6uS3ze1ai8FHa8kmHScGpWmj4WggLyQjgPie1rFSruoUihUZREPSL39UNdE3BBDu76";
|
||||
|
||||
static fc::string TEST2_SEED = "fffcf9f6f3f0edeae7e4e1dedbd8d5d2cfccc9c6c3c0bdbab7b4b1aeaba8a5a29f9c999693908d8a8784817e7b7875726f6c696663605d5a5754514e4b484542";
|
||||
static fc::string TEST2_M_PUB = "xpub661MyMwAqRbcFW31YEwpkMuc5THy2PSt5bDMsktWQcFF8syAmRUapSCGu8ED9W6oDMSgv6Zz8idoc4a6mr8BDzTJY47LJhkJ8UB7WEGuduB";
|
||||
static fc::string TEST2_M_PRIV = "xprv9s21ZrQH143K31xYSDQpPDxsXRTUcvj2iNHm5NUtrGiGG5e2DtALGdso3pGz6ssrdK4PFmM8NSpSBHNqPqm55Qn3LqFtT2emdEXVYsCzC2U";
|
||||
static fc::string TEST2_M_0_PUB = "xpub69H7F5d8KSRgmmdJg2KhpAK8SR3DjMwAdkxj3ZuxV27CprR9LgpeyGmXUbC6wb7ERfvrnKZjXoUmmDznezpbZb7ap6r1D3tgFxHmwMkQTPH";
|
||||
static fc::string TEST2_M_0_PRIV = "xprv9vHkqa6EV4sPZHYqZznhT2NPtPCjKuDKGY38FBWLvgaDx45zo9WQRUT3dKYnjwih2yJD9mkrocEZXo1ex8G81dwSM1fwqWpWkeS3v86pgKt";
|
||||
static fc::string TEST2_M_0_m1_PUB = "xpub6ASAVgeehLbnwdqV6UKMHVzgqAG8Gr6riv3Fxxpj8ksbH9ebxaEyBLZ85ySDhKiLDBrQSARLq1uNRts8RuJiHjaDMBU4Zn9h8LZNnBC5y4a";
|
||||
static fc::string TEST2_M_0_m1_PRIV = "xprv9wSp6B7kry3Vj9m1zSnLvN3xH8RdsPP1Mh7fAaR7aRLcQMKTR2vidYEeEg2mUCTAwCd6vnxVrcjfy2kRgVsFawNzmjuHc2YmYRmagcEPdU9";
|
||||
static fc::string TEST2_M_0_m1_1_PUB = "xpub6DF8uhdarytz3FWdA8TvFSvvAh8dP3283MY7p2V4SeE2wyWmG5mg5EwVvmdMVCQcoNJxGoWaU9DCWh89LojfZ537wTfunKau47EL2dhHKon";
|
||||
static fc::string TEST2_M_0_m1_1_PRIV = "xprv9zFnWC6h2cLgpmSA46vutJzBcfJ8yaJGg8cX1e5StJh45BBciYTRXSd25UEPVuesF9yog62tGAQtHjXajPPdbRCHuWS6T8XA2ECKADdw4Ef";
|
||||
static fc::string TEST2_M_0_m1_1_m2_PUB = "xpub6ERApfZwUNrhLCkDtcHTcxd75RbzS1ed54G1LkBUHQVHQKqhMkhgbmJbZRkrgZw4koxb5JaHWkY4ALHY2grBGRjaDMzQLcgJvLJuZZvRcEL";
|
||||
static fc::string TEST2_M_0_m1_1_m2_PRIV = "xprvA1RpRA33e1JQ7ifknakTFpgNXPmW2YvmhqLQYMmrj4xJXXWYpDPS3xz7iAxn8L39njGVyuoseXzU6rcxFLJ8HFsTjSyQbLYnMpCqE2VbFWc";
|
||||
static fc::string TEST2_M_0_m1_1_m2_2_PUB = "xpub6FnCn6nSzZAw5Tw7cgR9bi15UV96gLZhjDstkXXxvCLsUXBGXPdSnLFbdpq8p9HmGsApME5hQTZ3emM2rnY5agb9rXpVGyy3bdW6EEgAtqt";
|
||||
static fc::string TEST2_M_0_m1_1_m2_2_PRIV = "xprvA2nrNbFZABcdryreWet9Ea4LvTJcGsqrMzxHx98MMrotbir7yrKCEXw7nadnHM8Dq38EGfSh6dqA9QWTyefMLEcBYJUuekgW4BYPJcr9E7j";
|
||||
|
||||
static fc::string BLIND_K_X = "08be5c5076f8cbd1283cf98e74bff873032b9bc79a0769962bf3900f33c2df6e";
|
||||
static fc::string BLIND_T_X = "80deff382af8a8e4a5f297588e44d5bf858f30a524f74b13efcefeb54f4b3f47";
|
||||
static fc::string BLINDED_HASH = "7196e80cdafdfdfb7496323ad24bf47dda8447febd7426e444facc04940c7309";
|
||||
static fc::string BLIND_SIG = "40d6a477d849cc860df8ad159481f2ffc5b4dc3131b86a799d7d10460824dd53";
|
||||
static fc::string UNBLINDED = "700092a72a05e33509f9b068aa1d7c5336d8b5692b4157da199d7ec1e10fd7c0";
|
||||
/*
|
||||
BOOST_AUTO_TEST_CASE(test_extended_keys_1)
|
||||
{
|
||||
char seed[16];
|
||||
fc::from_hex( TEST1_SEED, seed, sizeof(seed) );
|
||||
fc::ecc::extended_private_key master = fc::ecc::extended_private_key::generate_master( seed, sizeof(seed) );
|
||||
BOOST_CHECK_EQUAL( master.str(), TEST1_M_PRIV );
|
||||
BOOST_CHECK_EQUAL( master.get_extended_public_key().str(), TEST1_M_PUB );
|
||||
|
||||
BOOST_CHECK_EQUAL( fc::ecc::extended_private_key::from_base58(TEST1_M_PRIV).str(), TEST1_M_PRIV );
|
||||
BOOST_CHECK_EQUAL( fc::ecc::extended_public_key::from_base58(TEST1_M_PUB).str(), TEST1_M_PUB );
|
||||
BOOST_CHECK_EQUAL( fc::ecc::extended_private_key::from_base58(TEST1_M_0H_PRIV).str(), TEST1_M_0H_PRIV );
|
||||
BOOST_CHECK_EQUAL( fc::ecc::extended_public_key::from_base58(TEST1_M_0H_PUB).str(), TEST1_M_0H_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0 = master.derive_child(0x80000000);
|
||||
BOOST_CHECK_EQUAL( m_0.str(), TEST1_M_0H_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0.get_extended_public_key().str(), TEST1_M_0H_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0_1 = m_0.derive_child(1);
|
||||
BOOST_CHECK_EQUAL( m_0_1.str(), TEST1_M_0H_1_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0_1.get_extended_public_key().str(), TEST1_M_0H_1_PUB );
|
||||
BOOST_CHECK_EQUAL( m_0.get_extended_public_key().derive_child(1).str(), TEST1_M_0H_1_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0_1_2 = m_0_1.derive_child(0x80000002);
|
||||
BOOST_CHECK_EQUAL( m_0_1_2.str(), TEST1_M_0H_1_2H_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0_1_2.get_extended_public_key().str(), TEST1_M_0H_1_2H_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0_1_2_2 = m_0_1_2.derive_child(2);
|
||||
BOOST_CHECK_EQUAL( m_0_1_2_2.str(), TEST1_M_0H_1_2H_2_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0_1_2_2.get_extended_public_key().str(), TEST1_M_0H_1_2H_2_PUB );
|
||||
BOOST_CHECK_EQUAL( m_0_1_2.get_extended_public_key().derive_child(2).str(), TEST1_M_0H_1_2H_2_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0_1_2_2_1g = m_0_1_2_2.derive_child(1000000000);
|
||||
BOOST_CHECK_EQUAL( m_0_1_2_2_1g.str(), TEST1_M_0H_1_2H_2_1g_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0_1_2_2_1g.get_extended_public_key().str(), TEST1_M_0H_1_2H_2_1g_PUB );
|
||||
BOOST_CHECK_EQUAL( m_0_1_2_2.get_extended_public_key().derive_child(1000000000).str(), TEST1_M_0H_1_2H_2_1g_PUB );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_extended_keys_2)
|
||||
{
|
||||
char seed[64];
|
||||
fc::from_hex( TEST2_SEED, seed, sizeof(seed) );
|
||||
fc::ecc::extended_private_key master = fc::ecc::extended_private_key::generate_master( seed, sizeof(seed) );
|
||||
BOOST_CHECK_EQUAL( master.str(), TEST2_M_PRIV );
|
||||
BOOST_CHECK_EQUAL( master.get_extended_public_key().str(), TEST2_M_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0 = master.derive_child(0);
|
||||
BOOST_CHECK_EQUAL( m_0.str(), TEST2_M_0_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0.get_extended_public_key().str(), TEST2_M_0_PUB );
|
||||
BOOST_CHECK_EQUAL( master.get_extended_public_key().derive_child(0).str(), TEST2_M_0_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0_m1 = m_0.derive_child(-1);
|
||||
BOOST_CHECK_EQUAL( m_0_m1.str(), TEST2_M_0_m1_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0_m1.get_extended_public_key().str(), TEST2_M_0_m1_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0_m1_1 = m_0_m1.derive_child(1);
|
||||
BOOST_CHECK_EQUAL( m_0_m1_1.str(), TEST2_M_0_m1_1_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0_m1_1.get_extended_public_key().str(), TEST2_M_0_m1_1_PUB );
|
||||
BOOST_CHECK_EQUAL( m_0_m1.get_extended_public_key().derive_child(1).str(), TEST2_M_0_m1_1_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0_m1_1_m2 = m_0_m1_1.derive_child(-2);
|
||||
BOOST_CHECK_EQUAL( m_0_m1_1_m2.str(), TEST2_M_0_m1_1_m2_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0_m1_1_m2.get_extended_public_key().str(), TEST2_M_0_m1_1_m2_PUB );
|
||||
|
||||
fc::ecc::extended_private_key m_0_m1_1_m2_2 = m_0_m1_1_m2.derive_child(2);
|
||||
BOOST_CHECK_EQUAL( m_0_m1_1_m2_2.str(), TEST2_M_0_m1_1_m2_2_PRIV );
|
||||
BOOST_CHECK_EQUAL( m_0_m1_1_m2_2.get_extended_public_key().str(), TEST2_M_0_m1_1_m2_2_PUB );
|
||||
BOOST_CHECK_EQUAL( m_0_m1_1_m2.get_extended_public_key().derive_child(2).str(), TEST2_M_0_m1_1_m2_2_PUB );
|
||||
}
|
||||
|
||||
//static void print(const unsigned char* data, int len) {
|
||||
// for (int i = 0; i < len; i++) {
|
||||
// printf("%02x", *data++);
|
||||
// }
|
||||
//}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_blinding_1)
|
||||
{
|
||||
char buffer[7] = "test_";
|
||||
fc::ecc::extended_private_key alice = fc::ecc::extended_private_key::generate_master( "master" );
|
||||
fc::ecc::extended_private_key bob = fc::ecc::extended_private_key::generate_master( "puppet" );
|
||||
|
||||
for ( int i = 0; i < 30; i++ )
|
||||
{
|
||||
buffer[5] = '0' + i;
|
||||
fc::ecc::extended_public_key bob_pub = bob.get_extended_public_key();
|
||||
fc::sha256 hash = fc::sha256::hash( buffer, sizeof(buffer) );
|
||||
fc::ecc::public_key t = alice.blind_public_key( bob_pub, i );
|
||||
fc::ecc::blinded_hash blinded = alice.blind_hash( hash, i );
|
||||
fc::ecc::blind_signature blind_sig = bob.blind_sign( blinded, i );
|
||||
try {
|
||||
fc::ecc::compact_signature sig = alice.unblind_signature( bob_pub, blind_sig, hash, i );
|
||||
fc::ecc::public_key validate( sig, hash );
|
||||
// printf("Validated: "); print((unsigned char*) validate.serialize().begin(), 33);
|
||||
// printf("\nT: "); print((unsigned char*) t.serialize().begin(), 33); printf("\n");
|
||||
BOOST_CHECK( validate.serialize() == t.serialize() );
|
||||
} catch (const fc::exception& e) {
|
||||
printf( "Test %d: %s\n", i, e.to_string().c_str() );
|
||||
}
|
||||
alice = alice.derive_child( i );
|
||||
bob = bob.derive_child( i | 0x80000000 );
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(test_blinding_2)
|
||||
{
|
||||
char message[7] = "test_0";
|
||||
fc::ecc::extended_private_key alice = fc::ecc::extended_private_key::generate_master( "master" );
|
||||
fc::ecc::extended_private_key bob = fc::ecc::extended_private_key::generate_master( "puppet" );
|
||||
fc::ecc::extended_public_key bob_pub = bob.get_extended_public_key();
|
||||
fc::sha256 hash = fc::sha256::hash( message, sizeof(message) );
|
||||
|
||||
fc::ecc::public_key t = alice.blind_public_key( bob_pub, 0 );
|
||||
fc::ecc::public_key_data pub = t.serialize();
|
||||
char buffer[32];
|
||||
fc::from_hex( BLIND_T_X, buffer, sizeof(buffer) );
|
||||
BOOST_CHECK( !memcmp( pub.begin() + 1, buffer, sizeof(buffer) ) );
|
||||
|
||||
fc::ecc::blinded_hash blinded = alice.blind_hash( hash, 0 );
|
||||
fc::from_hex( BLINDED_HASH, buffer, sizeof(buffer) );
|
||||
BOOST_CHECK( !memcmp( blinded.data(), buffer, sizeof(buffer) ) );
|
||||
|
||||
fc::ecc::blind_signature blind_sig = bob.blind_sign( blinded, 0 );
|
||||
fc::from_hex( BLIND_SIG, buffer, sizeof(buffer) );
|
||||
BOOST_CHECK( !memcmp( blind_sig.data(), buffer, sizeof(buffer) ) );
|
||||
|
||||
fc::ecc::compact_signature sig = alice.unblind_signature( bob_pub, blind_sig, hash, 0 );
|
||||
fc::from_hex( BLIND_K_X, buffer, sizeof(buffer) );
|
||||
BOOST_CHECK( !memcmp( sig.begin() + 1, buffer, sizeof(buffer) ) );
|
||||
fc::from_hex( UNBLINDED, buffer, sizeof(buffer) );
|
||||
BOOST_CHECK( !memcmp( sig.begin() + 33, buffer, sizeof(buffer) ) );
|
||||
}
|
||||
|
||||
static void to_bignum(const char* data32, fc::ssl_bignum& out) {
|
||||
unsigned char dummy[33]; dummy[0] = 0;
|
||||
memcpy(dummy, data32, 32);
|
||||
BN_bin2bn((unsigned char*) data32, 32, out);
|
||||
}
|
||||
|
||||
//static void print(const fc::sha256 hash) {
|
||||
// print((unsigned char*) hash.data(), hash.data_size());
|
||||
//}
|
||||
//
|
||||
//static void print(const BIGNUM* bn) {
|
||||
// unsigned char buffer[64];
|
||||
// int len = BN_num_bytes(bn);
|
||||
// if (len > sizeof(buffer)) {
|
||||
// printf("BN too long - %d bytes?!", len);
|
||||
// return;
|
||||
// }
|
||||
// BN_bn2bin(bn, buffer);
|
||||
// print(buffer, len);
|
||||
//}
|
||||
//
|
||||
//static void print(const fc::ec_group& curve, const fc::ec_point& p, fc::bn_ctx& ctx) {
|
||||
// fc::ssl_bignum x;
|
||||
// fc::ssl_bignum y;
|
||||
// EC_POINT_get_affine_coordinates_GFp(curve, p, x, y, ctx);
|
||||
// printf("(");
|
||||
// print(x);
|
||||
// printf(", ");
|
||||
// print(y);
|
||||
// printf(")");
|
||||
//}
|
||||
|
||||
namespace fc {
|
||||
SSL_TYPE(ec_key, EC_KEY, EC_KEY_free)
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(openssl_blinding)
|
||||
{
|
||||
// Needed this "test" for producing data for debugging my libsecp256k1 implementation
|
||||
|
||||
char buffer[7] = "test_0";
|
||||
fc::ecc::extended_private_key alice = fc::ecc::extended_private_key::generate_master( "master" );
|
||||
fc::ecc::extended_private_key bob = fc::ecc::extended_private_key::generate_master( "puppet" );
|
||||
fc::ec_group curve(EC_GROUP_new_by_curve_name(NID_secp256k1));
|
||||
fc::bn_ctx ctx(BN_CTX_new());
|
||||
fc::ssl_bignum n;
|
||||
EC_GROUP_get_order(curve, n, ctx);
|
||||
fc::ssl_bignum n_half;
|
||||
BN_rshift1(n_half, n);
|
||||
fc::ssl_bignum zero; BN_zero(zero);
|
||||
|
||||
fc::sha256 hash_ = fc::sha256::hash( buffer, sizeof(buffer) );
|
||||
fc::ssl_bignum hash; to_bignum(hash_.data(), hash);
|
||||
fc::ssl_bignum a; to_bignum(alice.derive_hardened_child(0).get_secret().data(), a);
|
||||
fc::ssl_bignum b; to_bignum(alice.derive_hardened_child(1).get_secret().data(), b);
|
||||
fc::ssl_bignum c; to_bignum(alice.derive_hardened_child(2).get_secret().data(), c);
|
||||
fc::ssl_bignum d; to_bignum(alice.derive_hardened_child(3).get_secret().data(), d);
|
||||
|
||||
fc::ec_point P(EC_POINT_new(curve));
|
||||
fc::ecc::public_key_data Pd = bob.get_extended_public_key().derive_child(0).serialize();
|
||||
fc::ssl_bignum Px; to_bignum(Pd.begin() + 1, Px);
|
||||
EC_POINT_set_compressed_coordinates_GFp(curve, P, Px, (*Pd.begin()) & 1, ctx);
|
||||
|
||||
fc::ec_point Q(EC_POINT_new(curve));
|
||||
fc::ecc::public_key_data Qd = bob.get_extended_public_key().derive_child(1).serialize();
|
||||
fc::ssl_bignum Qx; to_bignum(Qd.begin() + 1, Qx);
|
||||
EC_POINT_set_compressed_coordinates_GFp(curve, Q, Qx, (*Qd.begin()) & 1, ctx);
|
||||
|
||||
// Alice computes K = (c·a)^-1·P and public key T = (a·Kx)^-1·(b·G + Q + d·c^-1·P).
|
||||
fc::ec_point K(EC_POINT_new(curve));
|
||||
fc::ssl_bignum tmp;
|
||||
BN_mod_mul(tmp, a, c, n, ctx);
|
||||
BN_mod_inverse(tmp, tmp, n, ctx);
|
||||
EC_POINT_mul(curve, K, zero, P, tmp, ctx);
|
||||
|
||||
fc::ec_point T(EC_POINT_new(curve));
|
||||
BN_mod_inverse(tmp, c, n, ctx);
|
||||
BN_mod_mul(tmp, d, tmp, n, ctx);
|
||||
EC_POINT_mul(curve, T, b, P, tmp, ctx);
|
||||
EC_POINT_add(curve, T, T, Q, ctx);
|
||||
fc::ssl_bignum Kx;
|
||||
fc::ssl_bignum Ky;
|
||||
EC_POINT_get_affine_coordinates_GFp(curve, K, Kx, Ky, ctx);
|
||||
BN_mod_mul(tmp, a, Kx, n, ctx);
|
||||
BN_mod_inverse(tmp, tmp, n, ctx);
|
||||
EC_POINT_mul(curve, T, zero, T, tmp, ctx);
|
||||
|
||||
fc::ssl_bignum blinded;
|
||||
BN_mod_mul(blinded, a, hash, n, ctx);
|
||||
BN_mod_add(blinded, blinded, b, n, ctx);
|
||||
|
||||
fc::ssl_bignum p; to_bignum(bob.derive_normal_child(0).get_secret().data(), p);
|
||||
fc::ssl_bignum q; to_bignum(bob.derive_normal_child(1).get_secret().data(), q);
|
||||
BN_mod_inverse(p, p, n, ctx);
|
||||
BN_mod_mul(q, q, p, n, ctx);
|
||||
fc::ssl_bignum blind_sig;
|
||||
BN_mod_mul(blind_sig, p, blinded, n, ctx);
|
||||
BN_mod_add(blind_sig, blind_sig, q, n, ctx);
|
||||
|
||||
fc::ecdsa_sig sig(ECDSA_SIG_new());
|
||||
BN_copy(sig->r, Kx);
|
||||
BN_mod_mul(sig->s, c, blind_sig, n, ctx);
|
||||
BN_mod_add(sig->s, sig->s, d, n, ctx);
|
||||
|
||||
if (BN_cmp(sig->s, n_half) > 0) {
|
||||
BN_sub(sig->s, n, sig->s);
|
||||
}
|
||||
|
||||
fc::ec_key verify(EC_KEY_new());
|
||||
EC_KEY_set_public_key(verify, T);
|
||||
BOOST_CHECK( ECDSA_do_verify( (unsigned char*) hash_.data(), hash_.data_size(), sig, verify ) );
|
||||
// printf("a: "); print(a);
|
||||
// printf("\nb: "); print(b);
|
||||
// printf("\nc: "); print(c);
|
||||
// printf("\nd: "); print(d);
|
||||
// printf("\nP: "); print(curve, P, ctx);
|
||||
// printf("\nQ: "); print(curve, Q, ctx);
|
||||
// printf("\nK: "); print(curve, K, ctx);
|
||||
// printf("\nT: "); print(curve, T, ctx);
|
||||
// printf("\np: "); print(p);
|
||||
// printf("\nq: "); print(q);
|
||||
// printf("\nhash: "); print(hash_);
|
||||
// printf("\nblinded: "); print(blinded);
|
||||
// printf("\nblind_sig: "); print(blind_sig);
|
||||
// printf("\nunblinded: "); print(sig->s);
|
||||
// printf("\n");
|
||||
}
|
||||
*/
|
||||
|
|
@ -86,7 +86,7 @@ static void test_58( const std::string& test, const std::string& expected )
|
|||
try {
|
||||
len = fc::from_base58( enc1, buffer, 10 );
|
||||
BOOST_CHECK( len <= 10 );
|
||||
} catch ( fc::exception expected ) {}
|
||||
} catch ( fc::exception& expected ) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <fc/crypto/elliptic.hpp>
|
||||
#include <fc/log/logger.hpp>
|
||||
#include <fc/io/raw.hpp>
|
||||
#include <fc/variant.hpp>
|
||||
#include <fc/reflect/variant.hpp>
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(fc_crypto)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(blind_test)
|
||||
{
|
||||
try {
|
||||
auto InB1 = fc::sha256::hash("InB1");
|
||||
auto InB2 = fc::sha256::hash("InB2");
|
||||
auto OutB1 = fc::sha256::hash("OutB1");
|
||||
|
||||
|
||||
auto InC1 = fc::ecc::blind(InB1,25);
|
||||
auto InC2 = fc::ecc::blind(InB2,75);
|
||||
|
||||
auto OutC1 = fc::ecc::blind(OutB1,40);
|
||||
|
||||
auto OutB2 = fc::ecc::blind_sum( {InB1,InB2,OutB1}, 2 );
|
||||
auto OutC2 = fc::ecc::blind( OutB2, 60 );
|
||||
|
||||
/*
|
||||
FC_ASSERT( fc::ecc::verify_sum( {},{InC1,InC2}, 100 ) );
|
||||
FC_ASSERT( fc::ecc::verify_sum( {InC1,InC2}, {}, -100 ) );
|
||||
*/
|
||||
|
||||
//FC_ASSERT( fc::ecc::verify_sum( {InC1,InC2}, {OutC1}, -60 ) );
|
||||
|
||||
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {InC1,InC2}, {OutC1,OutC2}, 0 ) );
|
||||
auto nonce = fc::sha256::hash("nonce");
|
||||
|
||||
auto proof = fc::ecc::range_proof_sign( 0, OutC1, OutB1, nonce, 0, 0, 40 );
|
||||
// wdump( (proof.size()));
|
||||
|
||||
auto result = fc::ecc::range_get_info( proof );
|
||||
// wdump((result));
|
||||
BOOST_CHECK( result.max_value >= 60 );
|
||||
BOOST_CHECK( result.min_value >= 0 );
|
||||
|
||||
|
||||
auto B1 = fc::sha256::hash("B1");
|
||||
auto B2 = fc::sha256::hash("B2");
|
||||
auto b3 = fc::sha256::hash("b3");
|
||||
auto B4 = fc::sha256::hash("B4");
|
||||
auto C1 = fc::ecc::blind( B1, 1 );
|
||||
auto C2 = fc::ecc::blind( B2, 2 );
|
||||
/*auto c3 = */fc::ecc::blind( b3, 3 );
|
||||
/*auto C4 = */fc::ecc::blind( B4, -1 );
|
||||
|
||||
auto B3 = fc::ecc::blind_sum( {B1,B2}, 2 );
|
||||
auto C3 = fc::ecc::blind( B3, 3 );
|
||||
|
||||
|
||||
auto B2m1 = fc::ecc::blind_sum( {B2,B1}, 1 );
|
||||
/*auto C2m1 = */fc::ecc::blind( B2m1, 1 );
|
||||
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C1,C2}, {C3}, 0 ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C1,C2}, {C3}, 0 ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C3}, {C1,C2}, 0 ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C3}, {C1,C2}, 0 ) );
|
||||
|
||||
|
||||
{
|
||||
auto B1 = fc::sha256::hash("B1");
|
||||
/*auto B2 = */fc::sha256::hash("B2");
|
||||
/*auto B3 = */fc::sha256::hash("B3");
|
||||
/*auto B4 = */fc::sha256::hash("B4");
|
||||
|
||||
//secp256k1_scalar_get_b32((unsigned char*)&B1, (const secp256k1_scalar_t*)&B2);
|
||||
//B1 = fc::variant("b2e5da56ef9f2a34d3e22fd12634bc99261e95c87b9960bf94ed3d27b30").as<fc::sha256>();
|
||||
|
||||
auto C1 = fc::ecc::blind( B1, INT64_MAX );
|
||||
auto C2 = fc::ecc::blind( B1, 0 );
|
||||
auto C3 = fc::ecc::blind( B1, 1 );
|
||||
/*auto C4 = */fc::ecc::blind( B1, 2 );
|
||||
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C2}, {C3}, -1 ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C1}, {C1}, 0 ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C2}, {C2}, 0 ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C3}, {C2}, 1 ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C1}, {C2}, INT64_MAX ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C1}, {C2}, INT64_MAX ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {C2}, {C1}, -INT64_MAX ) );
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
auto Out1 = fc::sha256::hash("B1");
|
||||
auto Out2 = fc::sha256::hash("B2");
|
||||
auto OutC1 = fc::ecc::blind( Out1, 250 );
|
||||
auto OutC2 = fc::ecc::blind( Out2, 750 );
|
||||
auto InBlind = fc::ecc::blind_sum( {Out1,Out2}, 2 );
|
||||
auto InC = fc::ecc::blind( InBlind, 1000 );
|
||||
auto In0 = fc::ecc::blind( InBlind, 0 );
|
||||
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {InC}, {OutC1,OutC2}, 0 ) );
|
||||
BOOST_CHECK( fc::ecc::verify_sum( {InC}, {In0}, 1000 ) );
|
||||
|
||||
}
|
||||
}
|
||||
catch ( const fc::exception& e )
|
||||
{
|
||||
edump((e.to_detail_string()));
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
@ -139,31 +139,36 @@ BOOST_AUTO_TEST_CASE(blowfish_chain_test)
|
|||
BOOST_CHECK_EQUAL( 32, fc::from_hex( chain_test_cbc.c_str(), (char*) cipher, sizeof(cipher) ) );
|
||||
fc::blowfish fish;
|
||||
fish.start( key, sizeof(key), fc::sblock( from_bytes( iv ), from_bytes( iv + 4 ) ) );
|
||||
fish.encrypt( (unsigned char*) chain_test_plain.c_str(), out, sizeof(out), fc::blowfish::CBC );
|
||||
|
||||
char buffer[32];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
memcpy(buffer, chain_test_plain.c_str(), std::min(sizeof(buffer), chain_test_plain.size()));
|
||||
|
||||
fish.encrypt( (unsigned char*) buffer, out, sizeof(out), fc::blowfish::CBC );
|
||||
BOOST_CHECK( !memcmp( cipher, out, sizeof(cipher) ) );
|
||||
fish.reset_chain();
|
||||
fish.decrypt( out, sizeof(out), fc::blowfish::CBC );
|
||||
BOOST_CHECK( !memcmp( chain_test_plain.c_str(), out, 29 ) );
|
||||
BOOST_CHECK( !memcmp( buffer, out, 29 ) );
|
||||
fish.reset_chain();
|
||||
fish.encrypt( out, sizeof(out), fc::blowfish::CBC );
|
||||
BOOST_CHECK( !memcmp( cipher, out, sizeof(cipher) ) );
|
||||
fish.reset_chain();
|
||||
fish.decrypt( cipher, out, sizeof(cipher), fc::blowfish::CBC );
|
||||
BOOST_CHECK( !memcmp( chain_test_plain.c_str(), out, 29 ) );
|
||||
BOOST_CHECK( !memcmp( buffer, out, 29 ) );
|
||||
|
||||
BOOST_CHECK_EQUAL( 29, fc::from_hex( chain_test_cfb.c_str(), (char*) cipher, sizeof(cipher) ) );
|
||||
fish.reset_chain();
|
||||
fish.encrypt( (unsigned char*) chain_test_plain.c_str(), out, sizeof(out), fc::blowfish::CFB );
|
||||
fish.encrypt( (unsigned char*) buffer, out, sizeof(out), fc::blowfish::CFB );
|
||||
BOOST_CHECK( !memcmp( cipher, out, 29 ) );
|
||||
fish.reset_chain(); memset( out + 29, 0, 3 );
|
||||
fish.decrypt( out, sizeof(out), fc::blowfish::CFB );
|
||||
BOOST_CHECK( !memcmp( chain_test_plain.c_str(), out, 29 ) );
|
||||
BOOST_CHECK( !memcmp( buffer, out, 29 ) );
|
||||
fish.reset_chain(); memset( out + 29, 0, 3 );
|
||||
fish.encrypt( out, sizeof(out), fc::blowfish::CFB );
|
||||
BOOST_CHECK( !memcmp( cipher, out, 29 ) );
|
||||
fish.reset_chain(); memset( out + 29, 0, 3 );
|
||||
fish.decrypt( cipher, out, sizeof(cipher), fc::blowfish::CFB );
|
||||
BOOST_CHECK( !memcmp( chain_test_plain.c_str(), out, 29 ) );
|
||||
BOOST_CHECK( !memcmp( buffer, out, 29 ) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ BOOST_AUTO_TEST_CASE(dh_test)
|
|||
alice.p.clear(); alice.p.push_back(100); alice.p.push_back(2);
|
||||
BOOST_CHECK( !alice.validate() );
|
||||
alice.p = bob.p;
|
||||
alice.g = 9;
|
||||
alice.g = 1;
|
||||
BOOST_CHECK( !alice.validate() );
|
||||
|
||||
// It ain't easy...
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#include <fc/crypto/rand.hpp>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
static void check_randomness( const char* buffer, size_t len ) {
|
||||
if (len == 0) { return; }
|
||||
// count bit runs and 0's / 1's
|
||||
unsigned int zc = 0, oc = 0, rc = 0, last = 2;
|
||||
for (size_t k = len; k; k--) {
|
||||
char c = *buffer++;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
unsigned int bit = c & 1;
|
||||
c >>= 1;
|
||||
if (bit) { oc++; } else { zc++; }
|
||||
if (bit != last) { rc++; last = bit; }
|
||||
}
|
||||
}
|
||||
BOOST_CHECK_EQUAL( 8*len, zc + oc );
|
||||
double E = 1 + (zc + oc) / 2.0;
|
||||
double variance = (E - 1) * (E - 2) / (oc + zc - 1);
|
||||
double sigma = sqrt(variance);
|
||||
BOOST_CHECK( rc < E + sigma );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE(fc_crypto)
|
||||
|
||||
BOOST_AUTO_TEST_CASE(rand_test)
|
||||
{
|
||||
char buffer[128];
|
||||
fc::rand_bytes( buffer, sizeof(buffer) );
|
||||
check_randomness( buffer, sizeof(buffer) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(pseudo_rand_test)
|
||||
{
|
||||
char buffer[10013];
|
||||
fc::rand_pseudo_bytes( buffer, sizeof(buffer) );
|
||||
check_randomness( buffer, sizeof(buffer) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
@ -335,7 +335,7 @@ BOOST_AUTO_TEST_CASE(recursion_test)
|
|||
BOOST_AUTO_TEST_CASE(rethrow_test)
|
||||
{
|
||||
fc::variants biggie;
|
||||
for( int i = 0; i < 250; i++ )
|
||||
for( int i = 0; i < 1010; i++ )
|
||||
{
|
||||
fc::variant tmp( std::move(biggie) );
|
||||
biggie.reserve(1);
|
||||
|
|
|
|||
|
|
@ -47,9 +47,9 @@ BOOST_AUTO_TEST_CASE(real128_test)
|
|||
|
||||
BOOST_CHECK_EQUAL( real128(uint64_t(-1)).to_uint64(), uint64_t(-1) );
|
||||
|
||||
wdump( (ten)(two)(twenty) );
|
||||
wdump((real128("12345.6789")) );
|
||||
wdump( (ten/3*3) );
|
||||
//wdump( (ten)(two)(twenty) );
|
||||
//wdump((real128("12345.6789")) );
|
||||
//wdump( (ten/3*3) );
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
|
|
|||
|
|
@ -51,12 +51,12 @@ BOOST_AUTO_TEST_CASE( nested_objects_test )
|
|||
|
||||
auto create_nested_object = []( uint32_t level )
|
||||
{
|
||||
ilog( "Creating nested object with ${lv} level(s)", ("lv",level) );
|
||||
//ilog( "Creating nested object with ${lv} level(s)", ("lv",level) );
|
||||
fc::test::item nested;
|
||||
for( uint32_t i = 1; i <= level; i++ )
|
||||
{
|
||||
if( i % 100 == 0 )
|
||||
ilog( "Creating level ${lv}", ("lv",i) );
|
||||
//if( i % 100 == 0 )
|
||||
// ilog( "Creating level ${lv}", ("lv",i) );
|
||||
fc::test::item_wrapper wp( std::move(nested) );
|
||||
nested = fc::test::item( std::move(wp), i );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -191,11 +191,8 @@ BOOST_AUTO_TEST_CASE( cleanup_cancelled_task )
|
|||
{
|
||||
fc::usleep(fc::seconds(5));
|
||||
BOOST_TEST_MESSAGE("Finsihed usleep in async task, leaving the task's functor");
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
BOOST_TEST_MESSAGE("Caught exception in async task, leaving the task's functor");
|
||||
}
|
||||
} FC_CAPTURE_AND_LOG( (some_string) );
|
||||
|
||||
}, "test_task");
|
||||
std::weak_ptr<std::string> weak_string_ptr(some_string);
|
||||
some_string.reset();
|
||||
|
|
|
|||
1
vendor/editline
vendored
Submodule
1
vendor/editline
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 62bba782585c6c18d7a2b27beeb60a45db9abb43
|
||||
1
vendor/secp256k1
vendored
Submodule
1
vendor/secp256k1
vendored
Submodule
|
|
@ -0,0 +1 @@
|
|||
Subproject commit 1c3616f9f6f8ec4cd88eaccbae08b8cbb04ea326
|
||||
1
vendor/secp256k1-zkp
vendored
1
vendor/secp256k1-zkp
vendored
|
|
@ -1 +0,0 @@
|
|||
Subproject commit bd067945ead3b514fba884abd0de95fc4b5db9ae
|
||||
3
vendor/websocketpp/changelog.md
vendored
3
vendor/websocketpp/changelog.md
vendored
|
|
@ -1,4 +1,7 @@
|
|||
HEAD
|
||||
- Bug: Change default listen backlog from 0 to socket_base::max_connections.
|
||||
#549. Thank you derwassi and zwelab for reporting and na1pir for providing
|
||||
access to hardware to debug the issue.
|
||||
|
||||
0.7.0 - 2016-02-22
|
||||
- MINOR BREAKING SOCKET POLICY CHANGE: Asio transport socket policy method
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@
|
|||
|
||||
#include "connection_tu2.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
// Include special debugging transport
|
||||
//#include <websocketpp/config/minimal_client.hpp>
|
||||
#include <websocketpp/transport/debug/endpoint.hpp>
|
||||
|
|
@ -172,6 +174,20 @@ void http_func(server* s, websocketpp::connection_hdl hdl) {
|
|||
BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok));
|
||||
}
|
||||
|
||||
void http_func_with_move(server* s, websocketpp::connection_hdl hdl) {
|
||||
using namespace websocketpp::http;
|
||||
|
||||
server::connection_ptr con = s->get_con_from_hdl(hdl);
|
||||
|
||||
std::string res = con->get_resource();
|
||||
|
||||
con->set_body( std::move(res) );
|
||||
con->set_status(status_code::ok);
|
||||
|
||||
BOOST_CHECK_EQUAL(con->get_response_code(), status_code::ok);
|
||||
BOOST_CHECK_EQUAL(con->get_response_msg(), status_code::get_string(status_code::ok));
|
||||
}
|
||||
|
||||
void defer_http_func(server* s, bool * deferred, websocketpp::connection_hdl hdl) {
|
||||
*deferred = true;
|
||||
|
||||
|
|
@ -237,6 +253,18 @@ BOOST_AUTO_TEST_CASE( http_request ) {
|
|||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( http_request_with_move ) {
|
||||
std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: ";
|
||||
output+=websocketpp::user_agent;
|
||||
output+="\r\n\r\n/foo/bar";
|
||||
|
||||
server s;
|
||||
s.set_http_handler(bind(&http_func_with_move,&s,::_1));
|
||||
|
||||
BOOST_CHECK_EQUAL(run_server_test(s,input), output);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( deferred_http_request ) {
|
||||
std::string input = "GET /foo/bar HTTP/1.1\r\nHost: www.example.com\r\nOrigin: http://www.example.com\r\n\r\n";
|
||||
std::string output = "HTTP/1.1 200 OK\r\nContent-Length: 8\r\nServer: ";
|
||||
|
|
|
|||
|
|
@ -1041,6 +1041,7 @@ public:
|
|||
* @see websocketpp::http::response::set_body
|
||||
*/
|
||||
void set_body(std::string const & value);
|
||||
void set_body( std::string&& value );
|
||||
|
||||
/// Append a header
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
#include <websocketpp/common/cpp11.hpp>
|
||||
#include <websocketpp/common/memory.hpp>
|
||||
#include <websocketpp/common/platforms.hpp>
|
||||
#include <websocketpp/common/stdint.hpp>
|
||||
#include <websocketpp/common/system_error.hpp>
|
||||
#include <websocketpp/error.hpp>
|
||||
|
||||
|
|
@ -46,7 +47,7 @@
|
|||
namespace websocketpp {
|
||||
namespace extensions {
|
||||
|
||||
/// Implementation of the draft permessage-deflate WebSocket extension
|
||||
/// Implementation of RFC 7692, the permessage-deflate WebSocket extension
|
||||
/**
|
||||
* ### permessage-deflate interface
|
||||
*
|
||||
|
|
@ -174,18 +175,30 @@ namespace websocketpp {
|
|||
namespace extensions {
|
||||
namespace permessage_deflate {
|
||||
|
||||
/// Default value for server_max_window_bits as defined by draft 17
|
||||
/// Default value for server_max_window_bits as defined by RFC 7692
|
||||
static uint8_t const default_server_max_window_bits = 15;
|
||||
/// Minimum value for server_max_window_bits as defined by draft 17
|
||||
/// Minimum value for server_max_window_bits as defined by RFC 7692
|
||||
/**
|
||||
* NOTE: A value of 8 is not actually supported by zlib, the deflate
|
||||
* library that WebSocket++ uses. To preserve backwards compatibility
|
||||
* with RFC 7692 and previous versions of the library a value of 8
|
||||
* is accepted by the library but will always be negotiated as 9.
|
||||
*/
|
||||
static uint8_t const min_server_max_window_bits = 8;
|
||||
/// Maximum value for server_max_window_bits as defined by draft 17
|
||||
/// Maximum value for server_max_window_bits as defined by RFC 7692
|
||||
static uint8_t const max_server_max_window_bits = 15;
|
||||
|
||||
/// Default value for client_max_window_bits as defined by draft 17
|
||||
/// Default value for client_max_window_bits as defined by RFC 7692
|
||||
static uint8_t const default_client_max_window_bits = 15;
|
||||
/// Minimum value for client_max_window_bits as defined by draft 17
|
||||
/// Minimum value for client_max_window_bits as defined by RFC 7692
|
||||
/**
|
||||
* NOTE: A value of 8 is not actually supported by zlib, the deflate
|
||||
* library that WebSocket++ uses. To preserve backwards compatibility
|
||||
* with RFC 7692 and previous versions of the library a value of 8
|
||||
* is accepted by the library but will always be negotiated as 9.
|
||||
*/
|
||||
static uint8_t const min_client_max_window_bits = 8;
|
||||
/// Maximum value for client_max_window_bits as defined by draft 17
|
||||
/// Maximum value for client_max_window_bits as defined by RFC 7692
|
||||
static uint8_t const max_client_max_window_bits = 15;
|
||||
|
||||
namespace mode {
|
||||
|
|
@ -213,7 +226,7 @@ public:
|
|||
, m_server_max_window_bits_mode(mode::accept)
|
||||
, m_client_max_window_bits_mode(mode::accept)
|
||||
, m_initialized(false)
|
||||
, m_compress_buffer_size(16384)
|
||||
, m_compress_buffer_size(8192)
|
||||
{
|
||||
m_dstate.zalloc = Z_NULL;
|
||||
m_dstate.zfree = Z_NULL;
|
||||
|
|
@ -292,6 +305,7 @@ public:
|
|||
}
|
||||
|
||||
m_compress_buffer.reset(new unsigned char[m_compress_buffer_size]);
|
||||
m_decompress_buffer.reset(new unsigned char[m_compress_buffer_size]);
|
||||
if ((m_server_no_context_takeover && is_server) ||
|
||||
(m_client_no_context_takeover && !is_server))
|
||||
{
|
||||
|
|
@ -372,7 +386,7 @@ public:
|
|||
/**
|
||||
* The bits setting is the base 2 logarithm of the maximum window size that
|
||||
* the server must use to compress outgoing messages. The permitted range
|
||||
* is 8 to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB
|
||||
* is 9 to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB
|
||||
* window. The default setting is 15.
|
||||
*
|
||||
* Mode Options:
|
||||
|
|
@ -386,6 +400,14 @@ public:
|
|||
* adjusted by the server. A server may unilaterally set this value without
|
||||
* client support.
|
||||
*
|
||||
* NOTE: The permessage-deflate spec specifies that a value of 8 is allowed.
|
||||
* Prior to version 0.8.0 a value of 8 was also allowed by this library.
|
||||
* zlib, the deflate compression library that WebSocket++ uses has always
|
||||
* silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9
|
||||
* and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0
|
||||
* continues to perform the 8->9 conversion for backwards compatibility
|
||||
* purposes but this should be considered deprecated functionality.
|
||||
*
|
||||
* @param bits The size to request for the outgoing window size
|
||||
* @param mode The mode to use for negotiating this parameter
|
||||
* @return A status code
|
||||
|
|
@ -394,6 +416,12 @@ public:
|
|||
if (bits < min_server_max_window_bits || bits > max_server_max_window_bits) {
|
||||
return error::make_error_code(error::invalid_max_window_bits);
|
||||
}
|
||||
|
||||
// See note in doc comment above about what is happening here
|
||||
if (bits == 8) {
|
||||
bits = 9;
|
||||
}
|
||||
|
||||
m_server_max_window_bits = bits;
|
||||
m_server_max_window_bits_mode = mode;
|
||||
|
||||
|
|
@ -403,8 +431,8 @@ public:
|
|||
/// Limit client LZ77 sliding window size
|
||||
/**
|
||||
* The bits setting is the base 2 logarithm of the window size that the
|
||||
* client must use to compress outgoing messages. The permitted range is 8
|
||||
* to 15 inclusive. 8 represents a 256 byte window and 15 a 32KiB window.
|
||||
* client must use to compress outgoing messages. The permitted range is 9
|
||||
* to 15 inclusive. 9 represents a 512 byte window and 15 a 32KiB window.
|
||||
* The default setting is 15.
|
||||
*
|
||||
* Mode Options:
|
||||
|
|
@ -417,6 +445,14 @@ public:
|
|||
* outgoing window size unilaterally. A server may only limit the client's
|
||||
* window size if the remote client supports that feature.
|
||||
*
|
||||
* NOTE: The permessage-deflate spec specifies that a value of 8 is allowed.
|
||||
* Prior to version 0.8.0 a value of 8 was also allowed by this library.
|
||||
* zlib, the deflate compression library that WebSocket++ uses has always
|
||||
* silently adjusted a value of 8 to 9. In recent versions of zlib (1.2.9
|
||||
* and greater) a value of 8 is now explicitly rejected. WebSocket++ 0.8.0
|
||||
* continues to perform the 8->9 conversion for backwards compatibility
|
||||
* purposes but this should be considered deprecated functionality.
|
||||
*
|
||||
* @param bits The size to request for the outgoing window size
|
||||
* @param mode The mode to use for negotiating this parameter
|
||||
* @return A status code
|
||||
|
|
@ -425,6 +461,12 @@ public:
|
|||
if (bits < min_client_max_window_bits || bits > max_client_max_window_bits) {
|
||||
return error::make_error_code(error::invalid_max_window_bits);
|
||||
}
|
||||
|
||||
// See note in doc comment above about what is happening here
|
||||
if (bits == 8) {
|
||||
bits = 9;
|
||||
}
|
||||
|
||||
m_client_max_window_bits = bits;
|
||||
m_client_max_window_bits_mode = mode;
|
||||
|
||||
|
|
@ -555,7 +597,7 @@ public:
|
|||
|
||||
do {
|
||||
m_istate.avail_out = m_compress_buffer_size;
|
||||
m_istate.next_out = m_compress_buffer.get();
|
||||
m_istate.next_out = m_decompress_buffer.get();
|
||||
|
||||
ret = inflate(&m_istate, Z_SYNC_FLUSH);
|
||||
|
||||
|
|
@ -564,7 +606,7 @@ public:
|
|||
}
|
||||
|
||||
out.append(
|
||||
reinterpret_cast<char *>(m_compress_buffer.get()),
|
||||
reinterpret_cast<char *>(m_decompress_buffer.get()),
|
||||
m_compress_buffer_size - m_istate.avail_out
|
||||
);
|
||||
} while (m_istate.avail_out == 0);
|
||||
|
|
@ -642,11 +684,17 @@ private:
|
|||
* client requested that we use.
|
||||
*
|
||||
* options:
|
||||
* - decline (refuse to use the attribute)
|
||||
* - accept (use whatever the client says)
|
||||
* - largest (use largest possible value)
|
||||
* - decline (ignore value, offer our default instead)
|
||||
* - accept (use the value requested by the client)
|
||||
* - largest (use largest value acceptable to both)
|
||||
* - smallest (use smallest possible value)
|
||||
*
|
||||
* NOTE: As a value of 8 is no longer explicitly supported by zlib but might
|
||||
* be requested for negotiation by an older client/server, if the result of
|
||||
* the negotiation would be to send a value of 8, a value of 9 is offered
|
||||
* instead. This ensures that WebSocket++ will only ever negotiate connections
|
||||
* with compression settings explicitly supported by zlib.
|
||||
*
|
||||
* @param [in] value The value of the attribute from the offer
|
||||
* @param [out] ec A reference to the error code to return errors via
|
||||
*/
|
||||
|
|
@ -678,6 +726,11 @@ private:
|
|||
ec = make_error_code(error::invalid_mode);
|
||||
m_server_max_window_bits = default_server_max_window_bits;
|
||||
}
|
||||
|
||||
// See note in doc comment
|
||||
if (m_server_max_window_bits == 8) {
|
||||
m_server_max_window_bits = 9;
|
||||
}
|
||||
}
|
||||
|
||||
/// Negotiate client_max_window_bits attribute
|
||||
|
|
@ -687,11 +740,17 @@ private:
|
|||
* negotiation mode.
|
||||
*
|
||||
* options:
|
||||
* - decline (refuse to use the attribute)
|
||||
* - accept (use whatever the client says)
|
||||
* - largest (use largest possible value)
|
||||
* - decline (ignore value, offer our default instead)
|
||||
* - accept (use the value requested by the client)
|
||||
* - largest (use largest value acceptable to both)
|
||||
* - smallest (use smallest possible value)
|
||||
*
|
||||
* NOTE: As a value of 8 is no longer explicitly supported by zlib but might
|
||||
* be requested for negotiation by an older client/server, if the result of
|
||||
* the negotiation would be to send a value of 8, a value of 9 is offered
|
||||
* instead. This ensures that WebSocket++ will only ever negotiate connections
|
||||
* with compression settings explicitly supported by zlib.
|
||||
*
|
||||
* @param [in] value The value of the attribute from the offer
|
||||
* @param [out] ec A reference to the error code to return errors via
|
||||
*/
|
||||
|
|
@ -727,6 +786,11 @@ private:
|
|||
ec = make_error_code(error::invalid_mode);
|
||||
m_client_max_window_bits = default_client_max_window_bits;
|
||||
}
|
||||
|
||||
// See note in doc comment
|
||||
if (m_client_max_window_bits == 8) {
|
||||
m_client_max_window_bits = 9;
|
||||
}
|
||||
}
|
||||
|
||||
bool m_enabled;
|
||||
|
|
@ -741,6 +805,7 @@ private:
|
|||
int m_flush;
|
||||
size_t m_compress_buffer_size;
|
||||
lib::unique_ptr_uchar_array m_compress_buffer;
|
||||
lib::unique_ptr_uchar_array m_decompress_buffer;
|
||||
z_stream m_dstate;
|
||||
z_stream m_istate;
|
||||
};
|
||||
|
|
@ -750,3 +815,4 @@ private:
|
|||
} // namespace websocketpp
|
||||
|
||||
#endif // WEBSOCKETPP_PROCESSOR_EXTENSION_PERMESSAGEDEFLATE_HPP
|
||||
|
||||
|
|
|
|||
|
|
@ -575,6 +575,17 @@ void connection<config>::set_body(std::string const & value) {
|
|||
m_response.set_body(value);
|
||||
}
|
||||
|
||||
template <typename config>
|
||||
void connection<config>::set_body( std::string&& value )
|
||||
{
|
||||
if (m_internal_state != istate::PROCESS_HTTP_REQUEST) {
|
||||
throw exception("Call to set_status from invalid state",
|
||||
error::make_error_code(error::invalid_state));
|
||||
}
|
||||
|
||||
m_response.set_body(std::move(value));
|
||||
}
|
||||
|
||||
// TODO: EXCEPTION_FREE
|
||||
template <typename config>
|
||||
void connection<config>::append_header(std::string const & key,
|
||||
|
|
|
|||
|
|
@ -311,10 +311,10 @@ public:
|
|||
* needed.
|
||||
*/
|
||||
timer_ptr set_timer(long duration, timer_handler callback) {
|
||||
timer_ptr new_timer = lib::make_shared<lib::asio::steady_timer>(
|
||||
lib::ref(*m_io_service),
|
||||
lib::asio::milliseconds(duration)
|
||||
);
|
||||
timer_ptr new_timer(
|
||||
new lib::asio::steady_timer(
|
||||
*m_io_service,
|
||||
lib::asio::milliseconds(duration)));
|
||||
|
||||
if (config::enable_multithreading) {
|
||||
new_timer->async_wait(m_strand->wrap(lib::bind(
|
||||
|
|
@ -461,8 +461,7 @@ protected:
|
|||
m_io_service = io_service;
|
||||
|
||||
if (config::enable_multithreading) {
|
||||
m_strand = lib::make_shared<lib::asio::io_service::strand>(
|
||||
lib::ref(*io_service));
|
||||
m_strand.reset(new lib::asio::io_service::strand(*io_service));
|
||||
}
|
||||
|
||||
lib::error_code ec = socket_con_type::init_asio(io_service, m_strand,
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include <websocketpp/uri.hpp>
|
||||
#include <websocketpp/logger/levels.hpp>
|
||||
|
||||
#include <websocketpp/common/asio.hpp>
|
||||
#include <websocketpp/common/functional.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
|
@ -191,8 +192,7 @@ public:
|
|||
|
||||
m_io_service = ptr;
|
||||
m_external_io_service = true;
|
||||
m_acceptor = lib::make_shared<lib::asio::ip::tcp::acceptor>(
|
||||
lib::ref(*m_io_service));
|
||||
m_acceptor.reset(new lib::asio::ip::tcp::acceptor(*m_io_service));
|
||||
|
||||
m_state = READY;
|
||||
ec = lib::error_code();
|
||||
|
|
@ -314,8 +314,10 @@ public:
|
|||
*
|
||||
* New values affect future calls to listen only.
|
||||
*
|
||||
* A value of zero will use the operating system default. This is the
|
||||
* default value.
|
||||
* The default value is specified as *::asio::socket_base::max_connections
|
||||
* which uses the operating system defined maximum queue length. Your OS
|
||||
* may restrict or silently lower this value. A value of zero may cause
|
||||
* all connections to be rejected.
|
||||
*
|
||||
* @since 0.3.0
|
||||
*
|
||||
|
|
@ -660,9 +662,7 @@ public:
|
|||
* @since 0.3.0
|
||||
*/
|
||||
void start_perpetual() {
|
||||
m_work = lib::make_shared<lib::asio::io_service::work>(
|
||||
lib::ref(*m_io_service)
|
||||
);
|
||||
m_work.reset(new lib::asio::io_service::work(*m_io_service));
|
||||
}
|
||||
|
||||
/// Clears the endpoint's perpetual flag, allowing it to exit when empty
|
||||
|
|
@ -826,8 +826,7 @@ protected:
|
|||
|
||||
// Create a resolver
|
||||
if (!m_resolver) {
|
||||
m_resolver = lib::make_shared<lib::asio::ip::tcp::resolver>(
|
||||
lib::ref(*m_io_service));
|
||||
m_resolver.reset(new lib::asio::ip::tcp::resolver(*m_io_service));
|
||||
}
|
||||
|
||||
tcon->set_uri(u);
|
||||
|
|
|
|||
|
|
@ -168,8 +168,7 @@ protected:
|
|||
return socket::make_error_code(socket::error::invalid_state);
|
||||
}
|
||||
|
||||
m_socket = lib::make_shared<lib::asio::ip::tcp::socket>(
|
||||
lib::ref(*service));
|
||||
m_socket.reset(new lib::asio::ip::tcp::socket(*service));
|
||||
|
||||
m_state = READY;
|
||||
|
||||
|
|
|
|||
|
|
@ -193,8 +193,7 @@ protected:
|
|||
if (!m_context) {
|
||||
return socket::make_error_code(socket::error::invalid_tls_context);
|
||||
}
|
||||
m_socket = lib::make_shared<socket_type>(
|
||||
_WEBSOCKETPP_REF(*service),lib::ref(*m_context));
|
||||
m_socket.reset(new socket_type(*service, *m_context));
|
||||
|
||||
m_io_service = service;
|
||||
m_strand = strand;
|
||||
|
|
|
|||
Loading…
Reference in a new issue