Merge branch 'cryptonomex_master'
# Conflicts: # src/network/http/websocket.cpp
This commit is contained in:
commit
fa2b8fd4d2
19 changed files with 299 additions and 181 deletions
|
|
@ -37,7 +37,6 @@ SET(BOOST_COMPONENTS)
|
||||||
LIST(APPEND BOOST_COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework context locale iostreams)
|
LIST(APPEND BOOST_COMPONENTS thread date_time system filesystem program_options signals serialization chrono unit_test_framework context locale iostreams)
|
||||||
SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
|
SET( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" )
|
||||||
|
|
||||||
|
|
||||||
IF( ECC_IMPL STREQUAL openssl )
|
IF( ECC_IMPL STREQUAL openssl )
|
||||||
SET( ECC_REST src/crypto/elliptic_impl_pub.cpp )
|
SET( ECC_REST src/crypto/elliptic_impl_pub.cpp )
|
||||||
ELSE( ECC_IMPL STREQUAL openssl )
|
ELSE( ECC_IMPL STREQUAL openssl )
|
||||||
|
|
@ -290,6 +289,11 @@ ELSE()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
|
# This will become unnecessary once we update to websocketpp which fixes upstream issue #395
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWEBSOCKETPP_STRICT_MASKING")
|
||||||
|
|
||||||
|
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DBOOST_ASIO_HAS_STD_CHRONO")
|
||||||
|
|
||||||
target_include_directories(fc
|
target_include_directories(fc
|
||||||
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
${Boost_INCLUDE_DIR}
|
${Boost_INCLUDE_DIR}
|
||||||
|
|
|
||||||
|
|
@ -1,49 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <fc/io/raw.hpp>
|
||||||
|
|
||||||
namespace fc {
|
namespace fc {
|
||||||
namespace raw {
|
namespace raw {
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
|
||||||
inline void pack( Stream& s, const std::deque<T>& value ) {
|
|
||||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
|
||||||
auto itr = value.begin();
|
|
||||||
auto end = value.end();
|
|
||||||
while( itr != end ) {
|
|
||||||
fc::raw::pack( s, *itr );
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
|
||||||
inline void unpack( Stream& s, std::deque<T>& value ) {
|
|
||||||
unsigned_int size; unpack( s, size );
|
|
||||||
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
|
|
||||||
value.resize(size.value);
|
|
||||||
auto itr = value.begin();
|
|
||||||
auto end = value.end();
|
|
||||||
while( itr != end ) {
|
|
||||||
fc::raw::unpack( s, *itr );
|
|
||||||
++itr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace raw
|
} // namespace raw
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void to_variant( const std::deque<T>& var, variant& vo )
|
|
||||||
{
|
|
||||||
std::vector<variant> vars;
|
|
||||||
vars.reserve(var.size());
|
|
||||||
std::transform(var.begin(), var.end(), std::back_inserter(vars), [](const T& t) { return variant(t); });
|
|
||||||
vo = vars;
|
|
||||||
}
|
|
||||||
template<typename T>
|
|
||||||
void from_variant( const variant& var, std::deque<T>& vo )
|
|
||||||
{
|
|
||||||
const variants& vars = var.get_array();
|
|
||||||
vo.clear();
|
|
||||||
std::transform(vars.begin(), vars.end(), std::back_inserter(vo), [](const variant& t) { return t.template as<T>(); });
|
|
||||||
}
|
|
||||||
} // namespace fc
|
} // namespace fc
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,9 @@
|
||||||
|
|
||||||
namespace fc {
|
namespace fc {
|
||||||
|
|
||||||
class uint128;
|
|
||||||
template<typename T, size_t N>
|
template<typename T, size_t N>
|
||||||
class array;
|
class array;
|
||||||
|
class uint128;
|
||||||
|
|
||||||
// Hash function for a byte array.
|
// Hash function for a byte array.
|
||||||
uint64_t city_hash64(const char *buf, size_t len);
|
uint64_t city_hash64(const char *buf, size_t len);
|
||||||
|
|
@ -72,4 +72,5 @@ uint64_t city_hash_crc_64(const char *buf, size_t len);
|
||||||
uint128 city_hash_crc_128(const char *s, size_t len);
|
uint128 city_hash_crc_128(const char *s, size_t len);
|
||||||
array<uint64_t,4> city_hash_crc_256(const char *s, size_t len);
|
array<uint64_t,4> city_hash_crc_256(const char *s, size_t len);
|
||||||
|
|
||||||
|
|
||||||
} // namespace fc
|
} // namespace fc
|
||||||
|
|
|
||||||
|
|
@ -60,6 +60,7 @@ class sha256
|
||||||
return ds;
|
return ds;
|
||||||
}
|
}
|
||||||
friend sha256 operator << ( const sha256& h1, uint32_t i );
|
friend sha256 operator << ( const sha256& h1, uint32_t i );
|
||||||
|
friend sha256 operator >> ( const sha256& h1, uint32_t i );
|
||||||
friend bool operator == ( const sha256& h1, const sha256& h2 );
|
friend bool operator == ( const sha256& h1, const sha256& h2 );
|
||||||
friend bool operator != ( const sha256& h1, const sha256& h2 );
|
friend bool operator != ( const sha256& h1, const sha256& h2 );
|
||||||
friend sha256 operator ^ ( const sha256& h1, const sha256& h2 );
|
friend sha256 operator ^ ( const sha256& h1, const sha256& h2 );
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ namespace fc {
|
||||||
istream& read( char* buf, size_t len );
|
istream& read( char* buf, size_t len );
|
||||||
istream& read( const std::shared_ptr<char>& buf, size_t len, size_t offset = 0 );
|
istream& read( const std::shared_ptr<char>& buf, size_t len, size_t offset = 0 );
|
||||||
virtual char get();
|
virtual char get();
|
||||||
|
void get( char& c ) { c = get(); }
|
||||||
};
|
};
|
||||||
typedef std::shared_ptr<istream> istream_ptr;
|
typedef std::shared_ptr<istream> istream_ptr;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
#include <fc/safe.hpp>
|
#include <fc/safe.hpp>
|
||||||
#include <fc/io/raw_fwd.hpp>
|
#include <fc/io/raw_fwd.hpp>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <deque>
|
||||||
|
|
||||||
namespace fc {
|
namespace fc {
|
||||||
namespace raw {
|
namespace raw {
|
||||||
|
|
@ -116,12 +117,25 @@ namespace fc {
|
||||||
s.write((const char*)&v.data[0],N*sizeof(T));
|
s.write((const char*)&v.data[0],N*sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename T>
|
||||||
|
inline void pack( Stream& s, const std::shared_ptr<T>& v)
|
||||||
|
{
|
||||||
|
fc::raw::pack( s, *v );
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Stream, typename T, size_t N>
|
template<typename Stream, typename T, size_t N>
|
||||||
inline void unpack( Stream& s, fc::array<T,N>& v)
|
inline void unpack( Stream& s, fc::array<T,N>& v)
|
||||||
{ try {
|
{ try {
|
||||||
s.read((char*)&v.data[0],N*sizeof(T));
|
s.read((char*)&v.data[0],N*sizeof(T));
|
||||||
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<type,length>", ("type",fc::get_typename<T>::name())("length",N) ) }
|
} FC_RETHROW_EXCEPTIONS( warn, "fc::array<type,length>", ("type",fc::get_typename<T>::name())("length",N) ) }
|
||||||
|
|
||||||
|
template<typename Stream, typename T>
|
||||||
|
inline void unpack( Stream& s, std::shared_ptr<T>& v)
|
||||||
|
{ try {
|
||||||
|
v = std::make_shared<T>();
|
||||||
|
fc::raw::unpack( s, *v );
|
||||||
|
} FC_RETHROW_EXCEPTIONS( warn, "std::shared_ptr<T>", ("type",fc::get_typename<T>::name()) ) }
|
||||||
|
|
||||||
template<typename Stream> inline void pack( Stream& s, const signed_int& v ) {
|
template<typename Stream> inline void pack( Stream& s, const signed_int& v ) {
|
||||||
uint32_t val = (v.value<<1) ^ (v.value>>31);
|
uint32_t val = (v.value<<1) ^ (v.value>>31);
|
||||||
do {
|
do {
|
||||||
|
|
@ -166,55 +180,55 @@ namespace fc {
|
||||||
template<typename Stream, typename T> inline void unpack( Stream& s, const T& vi )
|
template<typename Stream, typename T> inline void unpack( Stream& s, const T& vi )
|
||||||
{
|
{
|
||||||
T tmp;
|
T tmp;
|
||||||
unpack( s, tmp );
|
fc::raw::unpack( s, tmp );
|
||||||
FC_ASSERT( vi == tmp );
|
FC_ASSERT( vi == tmp );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream> inline void pack( Stream& s, const char* v ) { pack( s, fc::string(v) ); }
|
template<typename Stream> inline void pack( Stream& s, const char* v ) { fc::raw::pack( s, fc::string(v) ); }
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
void pack( Stream& s, const safe<T>& v ) { pack( s, v.value ); }
|
void pack( Stream& s, const safe<T>& v ) { fc::raw::pack( s, v.value ); }
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
void unpack( Stream& s, fc::safe<T>& v ) { unpack( s, v.value ); }
|
void unpack( Stream& s, fc::safe<T>& v ) { fc::raw::unpack( s, v.value ); }
|
||||||
|
|
||||||
template<typename Stream, typename T, unsigned int S, typename Align>
|
template<typename Stream, typename T, unsigned int S, typename Align>
|
||||||
void pack( Stream& s, const fc::fwd<T,S,Align>& v ) {
|
void pack( Stream& s, const fc::fwd<T,S,Align>& v ) {
|
||||||
pack( *v );
|
fc::raw::pack( *v );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream, typename T, unsigned int S, typename Align>
|
template<typename Stream, typename T, unsigned int S, typename Align>
|
||||||
void unpack( Stream& s, fc::fwd<T,S,Align>& v ) {
|
void unpack( Stream& s, fc::fwd<T,S,Align>& v ) {
|
||||||
unpack( *v );
|
fc::raw::unpack( *v );
|
||||||
}
|
}
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
void pack( Stream& s, const fc::smart_ref<T>& v ) { pack( s, *v ); }
|
void pack( Stream& s, const fc::smart_ref<T>& v ) { fc::raw::pack( s, *v ); }
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
void unpack( Stream& s, fc::smart_ref<T>& v ) { unpack( s, *v ); }
|
void unpack( Stream& s, fc::smart_ref<T>& v ) { fc::raw::unpack( s, *v ); }
|
||||||
|
|
||||||
// optional
|
// optional
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
void pack( Stream& s, const fc::optional<T>& v ) {
|
void pack( Stream& s, const fc::optional<T>& v ) {
|
||||||
pack( s, bool(!!v) );
|
fc::raw::pack( s, bool(!!v) );
|
||||||
if( !!v ) pack( s, *v );
|
if( !!v ) fc::raw::pack( s, *v );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
void unpack( Stream& s, fc::optional<T>& v )
|
void unpack( Stream& s, fc::optional<T>& v )
|
||||||
{ try {
|
{ try {
|
||||||
bool b; unpack( s, b );
|
bool b; fc::raw::unpack( s, b );
|
||||||
if( b ) { v = T(); unpack( s, *v ); }
|
if( b ) { v = T(); fc::raw::unpack( s, *v ); }
|
||||||
} FC_RETHROW_EXCEPTIONS( warn, "optional<${type}>", ("type",fc::get_typename<T>::name() ) ) }
|
} FC_RETHROW_EXCEPTIONS( warn, "optional<${type}>", ("type",fc::get_typename<T>::name() ) ) }
|
||||||
|
|
||||||
// std::vector<char>
|
// std::vector<char>
|
||||||
template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value ) {
|
template<typename Stream> inline void pack( Stream& s, const std::vector<char>& value ) {
|
||||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||||
if( value.size() )
|
if( value.size() )
|
||||||
s.write( &value.front(), (uint32_t)value.size() );
|
s.write( &value.front(), (uint32_t)value.size() );
|
||||||
}
|
}
|
||||||
template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value ) {
|
template<typename Stream> inline void unpack( Stream& s, std::vector<char>& value ) {
|
||||||
unsigned_int size; unpack( s, size );
|
unsigned_int size; fc::raw::unpack( s, size );
|
||||||
FC_ASSERT( size.value < MAX_ARRAY_ALLOC_SIZE );
|
FC_ASSERT( size.value < MAX_ARRAY_ALLOC_SIZE );
|
||||||
value.resize(size.value);
|
value.resize(size.value);
|
||||||
if( value.size() )
|
if( value.size() )
|
||||||
|
|
@ -223,20 +237,26 @@ namespace fc {
|
||||||
|
|
||||||
// fc::string
|
// fc::string
|
||||||
template<typename Stream> inline void pack( Stream& s, const fc::string& v ) {
|
template<typename Stream> inline void pack( Stream& s, const fc::string& v ) {
|
||||||
pack( s, unsigned_int((uint32_t)v.size()));
|
fc::raw::pack( s, unsigned_int((uint32_t)v.size()));
|
||||||
if( v.size() ) s.write( v.c_str(), v.size() );
|
if( v.size() ) s.write( v.c_str(), v.size() );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream> inline void unpack( Stream& s, fc::string& v ) {
|
template<typename Stream> inline void unpack( Stream& s, fc::string& v ) {
|
||||||
std::vector<char> tmp; unpack(s,tmp);
|
std::vector<char> tmp; fc::raw::unpack(s,tmp);
|
||||||
if( tmp.size() )
|
if( tmp.size() )
|
||||||
v = fc::string(tmp.data(),tmp.data()+tmp.size());
|
v = fc::string(tmp.data(),tmp.data()+tmp.size());
|
||||||
else v = fc::string();
|
else v = fc::string();
|
||||||
}
|
}
|
||||||
|
|
||||||
// bool
|
// bool
|
||||||
template<typename Stream> inline void pack( Stream& s, const bool& v ) { pack( s, uint8_t(v) ); }
|
template<typename Stream> inline void pack( Stream& s, const bool& v ) { fc::raw::pack( s, uint8_t(v) ); }
|
||||||
template<typename Stream> inline void unpack( Stream& s, bool& v ) { uint8_t b; unpack( s, b ); v=(b!=0); }
|
template<typename Stream> inline void unpack( Stream& s, bool& v )
|
||||||
|
{
|
||||||
|
uint8_t b;
|
||||||
|
fc::raw::unpack( s, b );
|
||||||
|
FC_ASSERT( (b & ~1) == 0 );
|
||||||
|
v=(b!=0);
|
||||||
|
}
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
|
|
@ -247,7 +267,7 @@ namespace fc {
|
||||||
|
|
||||||
template<typename T, typename C, T(C::*p)>
|
template<typename T, typename C, T(C::*p)>
|
||||||
void operator()( const char* name )const {
|
void operator()( const char* name )const {
|
||||||
raw::pack( s, c.*p );
|
fc::raw::pack( s, c.*p );
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
const Class& c;
|
const Class& c;
|
||||||
|
|
@ -262,7 +282,7 @@ namespace fc {
|
||||||
template<typename T, typename C, T(C::*p)>
|
template<typename T, typename C, T(C::*p)>
|
||||||
inline void operator()( const char* name )const
|
inline void operator()( const char* name )const
|
||||||
{ try {
|
{ try {
|
||||||
raw::unpack( s, c.*p );
|
fc::raw::unpack( s, c.*p );
|
||||||
} FC_RETHROW_EXCEPTIONS( warn, "Error unpacking field ${field}", ("field",name) ) }
|
} FC_RETHROW_EXCEPTIONS( warn, "Error unpacking field ${field}", ("field",name) ) }
|
||||||
private:
|
private:
|
||||||
Class& c;
|
Class& c;
|
||||||
|
|
@ -341,7 +361,7 @@ namespace fc {
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
inline void pack( Stream& s, const std::unordered_set<T>& value ) {
|
inline void pack( Stream& s, const std::unordered_set<T>& value ) {
|
||||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||||
auto itr = value.begin();
|
auto itr = value.begin();
|
||||||
auto end = value.end();
|
auto end = value.end();
|
||||||
while( itr != end ) {
|
while( itr != end ) {
|
||||||
|
|
@ -351,7 +371,7 @@ namespace fc {
|
||||||
}
|
}
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
inline void unpack( Stream& s, std::unordered_set<T>& value ) {
|
inline void unpack( Stream& s, std::unordered_set<T>& value ) {
|
||||||
unsigned_int size; unpack( s, size );
|
unsigned_int size; fc::raw::unpack( s, size );
|
||||||
value.clear();
|
value.clear();
|
||||||
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
|
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
|
||||||
value.reserve(size.value);
|
value.reserve(size.value);
|
||||||
|
|
@ -366,19 +386,19 @@ namespace fc {
|
||||||
|
|
||||||
template<typename Stream, typename K, typename V>
|
template<typename Stream, typename K, typename V>
|
||||||
inline void pack( Stream& s, const std::pair<K,V>& value ) {
|
inline void pack( Stream& s, const std::pair<K,V>& value ) {
|
||||||
pack( s, value.first );
|
fc::raw::pack( s, value.first );
|
||||||
pack( s, value.second );
|
fc::raw::pack( s, value.second );
|
||||||
}
|
}
|
||||||
template<typename Stream, typename K, typename V>
|
template<typename Stream, typename K, typename V>
|
||||||
inline void unpack( Stream& s, std::pair<K,V>& value )
|
inline void unpack( Stream& s, std::pair<K,V>& value )
|
||||||
{
|
{
|
||||||
unpack( s, value.first );
|
fc::raw::unpack( s, value.first );
|
||||||
unpack( s, value.second );
|
fc::raw::unpack( s, value.second );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream, typename K, typename V>
|
template<typename Stream, typename K, typename V>
|
||||||
inline void pack( Stream& s, const std::unordered_map<K,V>& value ) {
|
inline void pack( Stream& s, const std::unordered_map<K,V>& value ) {
|
||||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||||
auto itr = value.begin();
|
auto itr = value.begin();
|
||||||
auto end = value.end();
|
auto end = value.end();
|
||||||
while( itr != end ) {
|
while( itr != end ) {
|
||||||
|
|
@ -389,7 +409,7 @@ namespace fc {
|
||||||
template<typename Stream, typename K, typename V>
|
template<typename Stream, typename K, typename V>
|
||||||
inline void unpack( Stream& s, std::unordered_map<K,V>& value )
|
inline void unpack( Stream& s, std::unordered_map<K,V>& value )
|
||||||
{
|
{
|
||||||
unsigned_int size; unpack( s, size );
|
unsigned_int size; fc::raw::unpack( s, size );
|
||||||
value.clear();
|
value.clear();
|
||||||
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
|
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
|
||||||
value.reserve(size.value);
|
value.reserve(size.value);
|
||||||
|
|
@ -402,7 +422,7 @@ namespace fc {
|
||||||
}
|
}
|
||||||
template<typename Stream, typename K, typename V>
|
template<typename Stream, typename K, typename V>
|
||||||
inline void pack( Stream& s, const std::map<K,V>& value ) {
|
inline void pack( Stream& s, const std::map<K,V>& value ) {
|
||||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||||
auto itr = value.begin();
|
auto itr = value.begin();
|
||||||
auto end = value.end();
|
auto end = value.end();
|
||||||
while( itr != end ) {
|
while( itr != end ) {
|
||||||
|
|
@ -413,7 +433,7 @@ namespace fc {
|
||||||
template<typename Stream, typename K, typename V>
|
template<typename Stream, typename K, typename V>
|
||||||
inline void unpack( Stream& s, std::map<K,V>& value )
|
inline void unpack( Stream& s, std::map<K,V>& value )
|
||||||
{
|
{
|
||||||
unsigned_int size; unpack( s, size );
|
unsigned_int size; fc::raw::unpack( s, size );
|
||||||
value.clear();
|
value.clear();
|
||||||
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
|
FC_ASSERT( size.value*(sizeof(K)+sizeof(V)) < MAX_ARRAY_ALLOC_SIZE );
|
||||||
for( uint32_t i = 0; i < size.value; ++i )
|
for( uint32_t i = 0; i < size.value; ++i )
|
||||||
|
|
@ -424,10 +444,33 @@ namespace fc {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename T>
|
||||||
|
inline void pack( Stream& s, const std::deque<T>& value ) {
|
||||||
|
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||||
|
auto itr = value.begin();
|
||||||
|
auto end = value.end();
|
||||||
|
while( itr != end ) {
|
||||||
|
fc::raw::pack( s, *itr );
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename Stream, typename T>
|
||||||
|
inline void unpack( Stream& s, std::deque<T>& value ) {
|
||||||
|
unsigned_int size; fc::raw::unpack( s, size );
|
||||||
|
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
|
||||||
|
value.resize(size.value);
|
||||||
|
auto itr = value.begin();
|
||||||
|
auto end = value.end();
|
||||||
|
while( itr != end ) {
|
||||||
|
fc::raw::unpack( s, *itr );
|
||||||
|
++itr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
inline void pack( Stream& s, const std::vector<T>& value ) {
|
inline void pack( Stream& s, const std::vector<T>& value ) {
|
||||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||||
auto itr = value.begin();
|
auto itr = value.begin();
|
||||||
auto end = value.end();
|
auto end = value.end();
|
||||||
while( itr != end ) {
|
while( itr != end ) {
|
||||||
|
|
@ -438,7 +481,7 @@ namespace fc {
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
inline void unpack( Stream& s, std::vector<T>& value ) {
|
inline void unpack( Stream& s, std::vector<T>& value ) {
|
||||||
unsigned_int size; unpack( s, size );
|
unsigned_int size; fc::raw::unpack( s, size );
|
||||||
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
|
FC_ASSERT( size.value*sizeof(T) < MAX_ARRAY_ALLOC_SIZE );
|
||||||
value.resize(size.value);
|
value.resize(size.value);
|
||||||
auto itr = value.begin();
|
auto itr = value.begin();
|
||||||
|
|
@ -451,7 +494,7 @@ namespace fc {
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
inline void pack( Stream& s, const std::set<T>& value ) {
|
inline void pack( Stream& s, const std::set<T>& value ) {
|
||||||
pack( s, unsigned_int((uint32_t)value.size()) );
|
fc::raw::pack( s, unsigned_int((uint32_t)value.size()) );
|
||||||
auto itr = value.begin();
|
auto itr = value.begin();
|
||||||
auto end = value.end();
|
auto end = value.end();
|
||||||
while( itr != end ) {
|
while( itr != end ) {
|
||||||
|
|
@ -462,11 +505,11 @@ namespace fc {
|
||||||
|
|
||||||
template<typename Stream, typename T>
|
template<typename Stream, typename T>
|
||||||
inline void unpack( Stream& s, std::set<T>& value ) {
|
inline void unpack( Stream& s, std::set<T>& value ) {
|
||||||
unsigned_int size; unpack( s, size );
|
unsigned_int size; fc::raw::unpack( s, size );
|
||||||
for( uint64_t i = 0; i < size.value; ++i )
|
for( uint64_t i = 0; i < size.value; ++i )
|
||||||
{
|
{
|
||||||
T tmp;
|
T tmp;
|
||||||
unpack( s, tmp );
|
fc::raw::unpack( s, tmp );
|
||||||
value.insert( std::move(tmp) );
|
value.insert( std::move(tmp) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -487,19 +530,19 @@ namespace fc {
|
||||||
inline size_t pack_size( const T& v )
|
inline size_t pack_size( const T& v )
|
||||||
{
|
{
|
||||||
datastream<size_t> ps;
|
datastream<size_t> ps;
|
||||||
raw::pack(ps,v );
|
fc::raw::pack(ps,v );
|
||||||
return ps.tellp();
|
return ps.tellp();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline std::vector<char> pack( const T& v ) {
|
inline std::vector<char> pack( const T& v ) {
|
||||||
datastream<size_t> ps;
|
datastream<size_t> ps;
|
||||||
raw::pack(ps,v );
|
fc::raw::pack(ps,v );
|
||||||
std::vector<char> vec(ps.tellp());
|
std::vector<char> vec(ps.tellp());
|
||||||
|
|
||||||
if( vec.size() ) {
|
if( vec.size() ) {
|
||||||
datastream<char*> ds( vec.data(), size_t(vec.size()) );
|
datastream<char*> ds( vec.data(), size_t(vec.size()) );
|
||||||
raw::pack(ds,v);
|
fc::raw::pack(ds,v);
|
||||||
}
|
}
|
||||||
return vec;
|
return vec;
|
||||||
}
|
}
|
||||||
|
|
@ -510,7 +553,7 @@ namespace fc {
|
||||||
T tmp;
|
T tmp;
|
||||||
if( s.size() ) {
|
if( s.size() ) {
|
||||||
datastream<const char*> ds( s.data(), size_t(s.size()) );
|
datastream<const char*> ds( s.data(), size_t(s.size()) );
|
||||||
raw::unpack(ds,tmp);
|
fc::raw::unpack(ds,tmp);
|
||||||
}
|
}
|
||||||
return tmp;
|
return tmp;
|
||||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||||
|
|
@ -520,14 +563,14 @@ namespace fc {
|
||||||
{ try {
|
{ try {
|
||||||
if( s.size() ) {
|
if( s.size() ) {
|
||||||
datastream<const char*> ds( s.data(), size_t(s.size()) );
|
datastream<const char*> ds( s.data(), size_t(s.size()) );
|
||||||
raw::unpack(ds,tmp);
|
fc::raw::unpack(ds,tmp);
|
||||||
}
|
}
|
||||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
inline void pack( char* d, uint32_t s, const T& v ) {
|
inline void pack( char* d, uint32_t s, const T& v ) {
|
||||||
datastream<char*> ds(d,s);
|
datastream<char*> ds(d,s);
|
||||||
raw::pack(ds,v );
|
fc::raw::pack(ds,v );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
@ -535,7 +578,7 @@ namespace fc {
|
||||||
{ try {
|
{ try {
|
||||||
T v;
|
T v;
|
||||||
datastream<const char*> ds( d, s );
|
datastream<const char*> ds( d, s );
|
||||||
raw::unpack(ds,v);
|
fc::raw::unpack(ds,v);
|
||||||
return v;
|
return v;
|
||||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||||
|
|
||||||
|
|
@ -543,7 +586,7 @@ namespace fc {
|
||||||
inline void unpack( const char* d, uint32_t s, T& v )
|
inline void unpack( const char* d, uint32_t s, T& v )
|
||||||
{ try {
|
{ try {
|
||||||
datastream<const char*> ds( d, s );
|
datastream<const char*> ds( d, s );
|
||||||
raw::unpack(ds,v);
|
fc::raw::unpack(ds,v);
|
||||||
return v;
|
return v;
|
||||||
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
} FC_RETHROW_EXCEPTIONS( warn, "error unpacking ${type}", ("type",fc::get_typename<T>::name() ) ) }
|
||||||
|
|
||||||
|
|
@ -556,7 +599,7 @@ namespace fc {
|
||||||
typedef void result_type;
|
typedef void result_type;
|
||||||
template<typename T> void operator()( const T& v )const
|
template<typename T> void operator()( const T& v )const
|
||||||
{
|
{
|
||||||
pack( stream, v );
|
fc::raw::pack( stream, v );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -569,7 +612,7 @@ namespace fc {
|
||||||
typedef void result_type;
|
typedef void result_type;
|
||||||
template<typename T> void operator()( T& v )const
|
template<typename T> void operator()( T& v )const
|
||||||
{
|
{
|
||||||
unpack( stream, v );
|
fc::raw::unpack( stream, v );
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -577,14 +620,14 @@ namespace fc {
|
||||||
template<typename Stream, typename... T>
|
template<typename Stream, typename... T>
|
||||||
void pack( Stream& s, const static_variant<T...>& sv )
|
void pack( Stream& s, const static_variant<T...>& sv )
|
||||||
{
|
{
|
||||||
pack( s, unsigned_int(sv.which()) );
|
fc::raw::pack( s, unsigned_int(sv.which()) );
|
||||||
sv.visit( pack_static_variant<Stream>(s) );
|
sv.visit( pack_static_variant<Stream>(s) );
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv )
|
template<typename Stream, typename... T> void unpack( Stream& s, static_variant<T...>& sv )
|
||||||
{
|
{
|
||||||
unsigned_int w;
|
unsigned_int w;
|
||||||
unpack( s, w );
|
fc::raw::unpack( s, w );
|
||||||
sv.set_which(w.value);
|
sv.set_which(w.value);
|
||||||
sv.visit( unpack_static_variant<Stream>(s) );
|
sv.visit( unpack_static_variant<Stream>(s) );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,11 @@ namespace fc
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void from_variant( const variant& var, std::unordered_set<T>& vo );
|
void from_variant( const variant& var, std::unordered_set<T>& vo );
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void to_variant( const std::deque<T>& var, variant& vo );
|
||||||
|
template<typename T>
|
||||||
|
void from_variant( const variant& var, std::deque<T>& vo );
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void to_variant( const fc::flat_set<T>& var, variant& vo );
|
void to_variant( const fc::flat_set<T>& var, variant& vo );
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|
@ -454,6 +459,27 @@ namespace fc
|
||||||
vo.insert( itr->as<T>() );
|
vo.insert( itr->as<T>() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @ingroup Serializable */
|
||||||
|
template<typename T>
|
||||||
|
void from_variant( const variant& var, std::deque<T>& tmp )
|
||||||
|
{
|
||||||
|
const variants& vars = var.get_array();
|
||||||
|
tmp.clear();
|
||||||
|
for( auto itr = vars.begin(); itr != vars.end(); ++itr )
|
||||||
|
tmp.push_back( itr->as<T>() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @ingroup Serializable */
|
||||||
|
template<typename T>
|
||||||
|
void to_variant( const std::deque<T>& t, variant& v )
|
||||||
|
{
|
||||||
|
std::vector<variant> vars(t.size());
|
||||||
|
for( size_t i = 0; i < t.size(); ++i )
|
||||||
|
vars[i] = variant(t[i]);
|
||||||
|
v = std::move(vars);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @ingroup Serializable */
|
/** @ingroup Serializable */
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void from_variant( const variant& var, std::vector<T>& tmp )
|
void from_variant( const variant& var, std::vector<T>& tmp )
|
||||||
|
|
@ -474,6 +500,8 @@ namespace fc
|
||||||
vars[i] = variant(t[i]);
|
vars[i] = variant(t[i]);
|
||||||
v = std::move(vars);
|
v = std::move(vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @ingroup Serializable */
|
/** @ingroup Serializable */
|
||||||
template<typename A, typename B>
|
template<typename A, typename B>
|
||||||
void to_variant( const std::pair<A,B>& t, variant& v )
|
void to_variant( const std::pair<A,B>& t, variant& v )
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ namespace fc { namespace detail {
|
||||||
uint8_t* out8 = (uint8_t*) out;
|
uint8_t* out8 = (uint8_t*) out;
|
||||||
|
|
||||||
if (i >= 8) {
|
if (i >= 8) {
|
||||||
shift_l( in8, out8, n, i >> 3 );
|
shift_l( in8, out8, n, i / 8 );
|
||||||
i &= 7;
|
i &= 7;
|
||||||
in8 = out8;
|
in8 = out8;
|
||||||
}
|
}
|
||||||
|
|
@ -26,4 +26,28 @@ namespace fc { namespace detail {
|
||||||
out8[p] = (in8[p] << i) | (in8[p+1]>>(8-i));
|
out8[p] = (in8[p] << i) | (in8[p+1]>>(8-i));
|
||||||
out8[p] = in8[p] << i;
|
out8[p] = in8[p] << i;
|
||||||
}
|
}
|
||||||
|
static void shift_r( const uint8_t* in, uint8_t* out, std::size_t n, unsigned int i) {
|
||||||
|
if (i < n) {
|
||||||
|
memcpy( out+i, in, n-i );
|
||||||
|
} else {
|
||||||
|
i = n;
|
||||||
|
}
|
||||||
|
memset( out, 0, i );
|
||||||
|
}
|
||||||
|
|
||||||
|
void shift_r( const char* in, char* out, std::size_t n, unsigned int i) {
|
||||||
|
const uint8_t* in8 = (uint8_t*) in;
|
||||||
|
uint8_t* out8 = (uint8_t*) out;
|
||||||
|
|
||||||
|
if (i >= 8) {
|
||||||
|
shift_r( in8, out8, n, i / 8 );
|
||||||
|
i &= 7;
|
||||||
|
in8 = out8;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t p;
|
||||||
|
for( p = n-1; p > 0; --p )
|
||||||
|
out8[p] = (in8[p] >> i) | (in8[p-1]<<(8-i));
|
||||||
|
out8[p] = in8[p] >> i;
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,5 @@
|
||||||
*/
|
*/
|
||||||
namespace fc { namespace detail {
|
namespace fc { namespace detail {
|
||||||
void shift_l( const char* in, char* out, std::size_t n, unsigned int i);
|
void shift_l( const char* in, char* out, std::size_t n, unsigned int i);
|
||||||
|
void shift_r( const char* in, char* out, std::size_t n, unsigned int i);
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -270,6 +270,11 @@ namespace fc { namespace ecc {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extended_public_key extended_public_key::deserialize( const extended_key_data& data )
|
||||||
|
{
|
||||||
|
return from_base58( _to_base58( data ) );
|
||||||
|
}
|
||||||
|
|
||||||
fc::string extended_public_key::str() const
|
fc::string extended_public_key::str() const
|
||||||
{
|
{
|
||||||
return _to_base58( serialize_extended() );
|
return _to_base58( serialize_extended() );
|
||||||
|
|
@ -336,6 +341,11 @@ namespace fc { namespace ecc {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extended_private_key extended_private_key::deserialize( const extended_key_data& data )
|
||||||
|
{
|
||||||
|
return from_base58( _to_base58( data ) );
|
||||||
|
}
|
||||||
|
|
||||||
private_key extended_private_key::generate_a(int i) const { return derive_hardened_child(4*i + 0); }
|
private_key extended_private_key::generate_a(int i) const { return derive_hardened_child(4*i + 0); }
|
||||||
private_key extended_private_key::generate_b(int i) const { return derive_hardened_child(4*i + 1); }
|
private_key extended_private_key::generate_b(int i) const { return derive_hardened_child(4*i + 1); }
|
||||||
private_key extended_private_key::generate_c(int i) const { return derive_hardened_child(4*i + 2); }
|
private_key extended_private_key::generate_c(int i) const { return derive_hardened_child(4*i + 2); }
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,11 @@ namespace fc {
|
||||||
fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i );
|
fc::detail::shift_l( h1.data(), result.data(), result.data_size(), i );
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
sha256 operator >> ( const sha256& h1, uint32_t i ) {
|
||||||
|
sha256 result;
|
||||||
|
fc::detail::shift_r( h1.data(), result.data(), result.data_size(), i );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
sha256 operator ^ ( const sha256& h1, const sha256& h2 ) {
|
sha256 operator ^ ( const sha256& h1, const sha256& h2 ) {
|
||||||
sha256 result;
|
sha256 result;
|
||||||
result._hash[0] = h1._hash[0] ^ h2._hash[0];
|
result._hash[0] = h1._hash[0] ^ h2._hash[0];
|
||||||
|
|
|
||||||
|
|
@ -199,25 +199,28 @@ namespace fc { namespace http {
|
||||||
std::shared_ptr<websocket_connection> con = current_con->second;
|
std::shared_ptr<websocket_connection> con = current_con->second;
|
||||||
++_pending_messages;
|
++_pending_messages;
|
||||||
auto f = fc::async([this,con,payload](){ if( _pending_messages ) --_pending_messages; con->on_message( payload ); });
|
auto f = fc::async([this,con,payload](){ if( _pending_messages ) --_pending_messages; con->on_message( payload ); });
|
||||||
if( _pending_messages > 100 ) f.wait();
|
if( _pending_messages > 100 )
|
||||||
|
f.wait();
|
||||||
}).wait();
|
}).wait();
|
||||||
});
|
});
|
||||||
|
|
||||||
_server.set_http_handler( [&]( connection_hdl hdl ){
|
_server.set_http_handler( [&]( connection_hdl hdl ){
|
||||||
_server_thread.async( [&](){
|
_server_thread.async( [&](){
|
||||||
|
|
||||||
auto current_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
|
auto current_con = std::make_shared<websocket_connection_impl<websocket_server_type::connection_ptr>>( _server.get_con_from_hdl(hdl) );
|
||||||
_on_connection( current_con );
|
_on_connection( current_con );
|
||||||
|
|
||||||
auto con = _server.get_con_from_hdl(hdl);
|
auto con = _server.get_con_from_hdl(hdl);
|
||||||
idump(("server")(con->get_request_body()));
|
con->defer_http_response();
|
||||||
auto response = current_con->on_http( con->get_request_body() );
|
std::string request_body = con->get_request_body();
|
||||||
|
wdump(("server")(request_body));
|
||||||
|
|
||||||
|
fc::async([current_con, request_body, con] {
|
||||||
|
std::string response = current_con->on_http(request_body);
|
||||||
con->set_body( response );
|
con->set_body( response );
|
||||||
con->set_status( websocketpp::http::status_code::ok );
|
con->set_status( websocketpp::http::status_code::ok );
|
||||||
|
con->send_http_response();
|
||||||
current_con->closed();
|
current_con->closed();
|
||||||
|
}, "call on_http");
|
||||||
}).wait();
|
}).wait();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ namespace fc { namespace rpc {
|
||||||
void handle_message( const variant_object& obj )
|
void handle_message( const variant_object& obj )
|
||||||
{
|
{
|
||||||
wlog( "recv: ${msg}", ("msg", obj) );
|
wlog( "recv: ${msg}", ("msg", obj) );
|
||||||
|
fc::exception_ptr eptr;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto m = obj.find("method");
|
auto m = obj.find("method");
|
||||||
|
|
@ -158,6 +159,7 @@ namespace fc { namespace rpc {
|
||||||
}
|
}
|
||||||
else if( e != obj.end() ) //if error response
|
else if( e != obj.end() ) //if error response
|
||||||
{
|
{
|
||||||
|
fc::exception_ptr eptr;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto err = e->value().get_object();
|
auto err = e->value().get_object();
|
||||||
|
|
@ -173,8 +175,9 @@ namespace fc { namespace rpc {
|
||||||
catch ( fc::exception& e )
|
catch ( fc::exception& e )
|
||||||
{
|
{
|
||||||
elog( "Error parsing exception: ${e}", ("e", e.to_detail_string() ) );
|
elog( "Error parsing exception: ${e}", ("e", e.to_detail_string() ) );
|
||||||
await->second->set_exception( e.dynamic_copy_exception() );
|
eptr = e.dynamic_copy_exception();
|
||||||
}
|
}
|
||||||
|
if( eptr ) await->second->set_exception( eptr );
|
||||||
}
|
}
|
||||||
else // id found without error, result, nor method field
|
else // id found without error, result, nor method field
|
||||||
{
|
{
|
||||||
|
|
@ -191,12 +194,14 @@ namespace fc { namespace rpc {
|
||||||
{
|
{
|
||||||
fc_elog( _logger, "json rpc exception: ${exception}", ("exception",e ));
|
fc_elog( _logger, "json rpc exception: ${exception}", ("exception",e ));
|
||||||
elog( "json rpc exception: ${exception}", ("exception",e ));
|
elog( "json rpc exception: ${exception}", ("exception",e ));
|
||||||
close(e.dynamic_copy_exception());
|
eptr = e.dynamic_copy_exception();
|
||||||
}
|
}
|
||||||
|
if( eptr ) { close(eptr); }
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_loop()
|
void read_loop()
|
||||||
{
|
{
|
||||||
|
fc::exception_ptr eptr;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fc::string line;
|
fc::string line;
|
||||||
|
|
@ -211,16 +216,17 @@ namespace fc { namespace rpc {
|
||||||
catch ( eof_exception& eof )
|
catch ( eof_exception& eof )
|
||||||
{
|
{
|
||||||
_eof = true;
|
_eof = true;
|
||||||
close( eof.dynamic_copy_exception() );
|
eptr = eof.dynamic_copy_exception();
|
||||||
}
|
}
|
||||||
catch ( exception& e )
|
catch ( exception& e )
|
||||||
{
|
{
|
||||||
close( e.dynamic_copy_exception() );
|
eptr = e.dynamic_copy_exception();
|
||||||
}
|
}
|
||||||
catch ( ... )
|
catch ( ... )
|
||||||
{
|
{
|
||||||
close( fc::exception_ptr(new FC_EXCEPTION( unhandled_exception, "json connection read error" )) );
|
eptr = fc::exception_ptr(new FC_EXCEPTION( unhandled_exception, "json connection read error" ));
|
||||||
}
|
}
|
||||||
|
if( eptr ) close( eptr );
|
||||||
}
|
}
|
||||||
|
|
||||||
void close( fc::exception_ptr e )
|
void close( fc::exception_ptr e )
|
||||||
|
|
|
||||||
|
|
@ -62,16 +62,38 @@ namespace fc {
|
||||||
}
|
}
|
||||||
_enqueue_thread();
|
_enqueue_thread();
|
||||||
}
|
}
|
||||||
|
std::exception_ptr e;
|
||||||
|
|
||||||
|
//
|
||||||
|
// Create shared_ptr to take ownership of this; i.e. this will
|
||||||
|
// be deleted when p_this goes out of scope. Consequently,
|
||||||
|
// it would be Very Bad to let p_this go out of scope
|
||||||
|
// before we're done reading/writing instance variables!
|
||||||
|
// See https://github.com/cryptonomex/graphene/issues/597
|
||||||
|
//
|
||||||
|
|
||||||
|
ptr p_this = ptr( this, true );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
thread::current().wait_until( ptr(this,true), timeout_us );
|
//
|
||||||
}
|
// We clone p_this here because the wait_until() API requires us
|
||||||
catch (...)
|
// to use std::move(). I.e. wait_until() takes ownership of any
|
||||||
{
|
// pointer passed to it. Since we want to keep ownership ourselves,
|
||||||
_dequeue_thread();
|
// we need to have two shared_ptr's to this:
|
||||||
throw;
|
//
|
||||||
|
// - p_this to keep this alive until the end of the current function
|
||||||
|
// - p_this2 to be owned by wait_until() as the wait_until() API requires
|
||||||
|
//
|
||||||
|
ptr p_this2 = p_this;
|
||||||
|
thread::current().wait_until( std::move( p_this2 ), timeout_us );
|
||||||
}
|
}
|
||||||
|
catch (...) { e = std::current_exception(); }
|
||||||
|
|
||||||
_dequeue_thread();
|
_dequeue_thread();
|
||||||
|
|
||||||
|
if( e ) std::rethrow_exception(e);
|
||||||
|
|
||||||
if( _ready )
|
if( _ready )
|
||||||
{
|
{
|
||||||
if( _exceptp )
|
if( _exceptp )
|
||||||
|
|
|
||||||
|
|
@ -118,13 +118,18 @@ namespace fc {
|
||||||
cc->next_blocked_mutex = m_blist;
|
cc->next_blocked_mutex = m_blist;
|
||||||
m_blist = cc;
|
m_blist = cc;
|
||||||
} // end lock scope
|
} // end lock scope
|
||||||
|
|
||||||
|
|
||||||
|
std::exception_ptr e;
|
||||||
try {
|
try {
|
||||||
fc::thread::current().my->yield_until( abs_time, false );
|
fc::thread::current().my->yield_until( abs_time, false );
|
||||||
return( 0 == cc->next_blocked_mutex );
|
return( 0 == cc->next_blocked_mutex );
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
cleanup( *this, m_blist_lock, m_blist, cc);
|
e = std::current_exception();
|
||||||
throw;
|
|
||||||
}
|
}
|
||||||
|
assert(e);
|
||||||
|
cleanup( *this, m_blist_lock, m_blist, cc);
|
||||||
|
std::rethrow_exception(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mutex::lock() {
|
void mutex::lock() {
|
||||||
|
|
@ -166,6 +171,7 @@ namespace fc {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::exception_ptr e; // cleanup calls yield so we need to move the exception outside of the catch block
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
fc::thread::current().yield(false);
|
fc::thread::current().yield(false);
|
||||||
|
|
@ -174,17 +180,13 @@ namespace fc {
|
||||||
assert(recursive_lock_count == 0);
|
assert(recursive_lock_count == 0);
|
||||||
recursive_lock_count = 1;
|
recursive_lock_count = 1;
|
||||||
}
|
}
|
||||||
catch ( exception& e )
|
|
||||||
{
|
|
||||||
wlog( "lock threw: ${e}", ("e", e));
|
|
||||||
cleanup( *this, m_blist_lock, m_blist, current_context);
|
|
||||||
FC_RETHROW_EXCEPTION(e, warn, "lock threw: ${e}", ("e", e));
|
|
||||||
}
|
|
||||||
catch ( ... )
|
catch ( ... )
|
||||||
{
|
{
|
||||||
wlog( "lock threw unexpected exception" );
|
e = std::current_exception();
|
||||||
|
}
|
||||||
|
if( e ) {
|
||||||
cleanup( *this, m_blist_lock, m_blist, current_context);
|
cleanup( *this, m_blist_lock, m_blist, current_context);
|
||||||
throw;
|
std::rethrow_exception(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ namespace fc {
|
||||||
}
|
}
|
||||||
catch ( ... )
|
catch ( ... )
|
||||||
{
|
{
|
||||||
set_exception( std::make_shared<unhandled_exception>( FC_LOG_MESSAGE( warn, "unhandled exception: ${diagnostic}", ("diagnostic",boost::current_exception_diagnostic_information()) ) ) );
|
set_exception( std::make_shared<unhandled_exception>( FC_LOG_MESSAGE( warn, "unhandled exception: ${diagnostic}", ("diagnostic",boost::current_exception_diagnostic_information()) ) ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -112,7 +112,7 @@ namespace fc {
|
||||||
//wlog( "my ${n}", ("n",name()) );
|
//wlog( "my ${n}", ("n",name()) );
|
||||||
if( my )
|
if( my )
|
||||||
{
|
{
|
||||||
wlog( "calling quit() on ${n}",("n",my->name) );
|
// wlog( "calling quit() on ${n}",("n",my->name) );
|
||||||
quit(); // deletes `my`
|
quit(); // deletes `my`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +157,7 @@ namespace fc {
|
||||||
async( [=](){quit();}, "thread::quit" );//.wait();
|
async( [=](){quit();}, "thread::quit" );//.wait();
|
||||||
if( my->boost_thread )
|
if( my->boost_thread )
|
||||||
{
|
{
|
||||||
wlog("destroying boost thread ${tid}",("tid",(uintptr_t)my->boost_thread->native_handle()));
|
//wlog("destroying boost thread ${tid}",("tid",(uintptr_t)my->boost_thread->native_handle()));
|
||||||
my->boost_thread->join();
|
my->boost_thread->join();
|
||||||
delete my;
|
delete my;
|
||||||
my = nullptr;
|
my = nullptr;
|
||||||
|
|
@ -243,7 +243,7 @@ namespace fc {
|
||||||
}
|
}
|
||||||
catch( canceled_exception& e )
|
catch( canceled_exception& e )
|
||||||
{
|
{
|
||||||
wlog( "thread canceled: ${e}", ("e", e.to_detail_string()) );
|
dlog( "thread canceled: ${e}", ("e", e.to_detail_string()) );
|
||||||
}
|
}
|
||||||
delete my->current;
|
delete my->current;
|
||||||
my->current = 0;
|
my->current = 0;
|
||||||
|
|
|
||||||
|
|
@ -474,10 +474,7 @@ namespace fc {
|
||||||
{
|
{
|
||||||
self->process_tasks();
|
self->process_tasks();
|
||||||
}
|
}
|
||||||
catch ( canceled_exception& )
|
catch ( canceled_exception& ) { /* allowed exception */ }
|
||||||
{
|
|
||||||
// allowed exception...
|
|
||||||
}
|
|
||||||
catch ( ... )
|
catch ( ... )
|
||||||
{
|
{
|
||||||
elog( "fiber ${name} exited with uncaught exception: ${e}", ("e",fc::except_str())("name", self->name) );
|
elog( "fiber ${name} exited with uncaught exception: ${e}", ("e",fc::except_str())("name", self->name) );
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,14 @@ bool variant::as_bool()const
|
||||||
switch( get_type() )
|
switch( get_type() )
|
||||||
{
|
{
|
||||||
case string_type:
|
case string_type:
|
||||||
return **reinterpret_cast<const const_string_ptr*>(this) == "true";
|
{
|
||||||
|
const string& s = **reinterpret_cast<const const_string_ptr*>(this);
|
||||||
|
if( s == "true" )
|
||||||
|
return true;
|
||||||
|
if( s == "false" )
|
||||||
|
return false;
|
||||||
|
FC_THROW_EXCEPTION( bad_cast_exception, "Cannot convert string to bool (only \"true\" or \"false\" can be converted)" );
|
||||||
|
}
|
||||||
case double_type:
|
case double_type:
|
||||||
return *reinterpret_cast<const double*>(this) != 0.0;
|
return *reinterpret_cast<const double*>(this) != 0.0;
|
||||||
case int64_type:
|
case int64_type:
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue