Skip to content

Commit

Permalink
Merge branch 'master' into feature/3161-producer-loop-to-expiration
Browse files Browse the repository at this point in the history
  • Loading branch information
b1bart authored May 22, 2018
2 parents a36bdd3 + 2d1844c commit 691041e
Show file tree
Hide file tree
Showing 25 changed files with 329 additions and 202 deletions.
9 changes: 4 additions & 5 deletions libraries/chain/include/eosio/chain/abi_serializer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,12 +461,12 @@ namespace impl {
* @tparam Reslover - callable with the signature (const name& code_account) -> optional<abi_def>
*/
template<typename T, typename Resolver>
class abi_from_variant_visitor
class abi_from_variant_visitor : reflector_verifier_visitor<T>
{
public:
abi_from_variant_visitor( const variant_object& _vo, T& v, Resolver _resolver )
:_vo(_vo)
,_val(v)
: reflector_verifier_visitor<T>(v)
,_vo(_vo)
,_resolver(_resolver)
{}

Expand All @@ -482,12 +482,11 @@ namespace impl {
{
auto itr = _vo.find(name);
if( itr != _vo.end() )
abi_from_variant::extract( itr->value(), _val.*member, _resolver );
abi_from_variant::extract( itr->value(), this->obj.*member, _resolver );
}

private:
const variant_object& _vo;
T& _val;
Resolver _resolver;
};

Expand Down
15 changes: 12 additions & 3 deletions libraries/chain/include/eosio/chain/asset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,6 @@ struct asset
EOS_ASSERT( sym.valid(), asset_type_exception, "invalid symbol" );
}

share_type amount;
symbol sym;

bool is_amount_within_range()const { return -max_amount <= amount && amount <= max_amount; }
bool is_valid()const { return is_amount_within_range() && sym.valid(); }

Expand All @@ -39,6 +36,7 @@ struct asset
string symbol_name()const;
int64_t precision()const;
const symbol& get_symbol() const { return sym; }
share_type get_amount()const { return amount; }

static asset from_string(const string& from);
string to_string()const;
Expand Down Expand Up @@ -84,6 +82,17 @@ struct asset

friend std::ostream& operator << (std::ostream& out, const asset& a) { return out << a.to_string(); }

friend struct fc::reflector<asset>;

void reflector_verify()const {
EOS_ASSERT( is_amount_within_range(), asset_type_exception, "magnitude of asset amount must be less than 2^62" );
EOS_ASSERT( sym.valid(), asset_type_exception, "invalid symbol" );
}

private:
share_type amount;
symbol sym;

};

struct extended_asset {
Expand Down
8 changes: 7 additions & 1 deletion libraries/chain/include/eosio/chain/symbol.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ namespace eosio {
auto prec_part = s.substr(0, comma_pos);
uint8_t p = fc::to_int64(prec_part);
string name_part = s.substr(comma_pos + 1);
FC_ASSERT( p <= max_precision, "precision should be <= 18");
FC_ASSERT( p <= max_precision, "precision ${p} should be <= 18", ("p", p));
return symbol(string_to_symbol(p, name_part.c_str()));
} FC_CAPTURE_LOG_AND_RETHROW((from))
}
Expand All @@ -97,6 +97,7 @@ namespace eosio {
uint8_t decimals() const { return m_value & 0xFF; }
uint64_t precision() const
{
FC_ASSERT( decimals() <= max_precision, "precision ${p} should be <= 18", ("p", decimals()) );
uint64_t p10 = 1;
uint64_t p = decimals();
while( p > 0 ) {
Expand Down Expand Up @@ -136,6 +137,11 @@ namespace eosio {
return ds << s.to_string();
}

void reflector_verify()const {
FC_ASSERT( decimals() <= max_precision, "precision ${p} should be <= 18", ("p", decimals()) );
FC_ASSERT( valid_name(name()), "invalid symbol: ${name}", ("name",name()));
}

private:
uint64_t m_value;
friend struct fc::reflector<symbol>;
Expand Down
8 changes: 4 additions & 4 deletions libraries/fc/include/fc/io/raw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,17 +350,17 @@ namespace fc {
};

template<typename Stream, typename Class>
struct unpack_object_visitor {
struct unpack_object_visitor : fc::reflector_verifier_visitor<Class> {
unpack_object_visitor(Class& _c, Stream& _s)
:c(_c),s(_s){}
: fc::reflector_verifier_visitor<Class>(_c), s(_s){}

template<typename T, typename C, T(C::*p)>
inline void operator()( const char* name )const
{ try {
fc::raw::unpack( s, c.*p );
fc::raw::unpack( s, this->obj.*p );
} FC_RETHROW_EXCEPTIONS( warn, "Error unpacking field ${field}", ("field",name) ) }

private:
Class& c;
Stream& s;
};

Expand Down
67 changes: 67 additions & 0 deletions libraries/fc/include/fc/reflect/reflect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ struct reflector{
* };
* @endcode
*
* If reflection requires a verification (what a constructor might normally assert) then
* derive your Visitor from reflector_verifier_visitor and implement a reflector_verify()
* on your reflected type.
*
* @code
* template<typename Class>
* struct functor : reflector_verifier_visitor<Class> {
* functor(Class& _c)
* : fc::reflector_verifier_visitor<Class>(_c) {}
*
* template<typename Member, class Class, Member (Class::*member)>
* void operator()( const char* name )const;
* };
* @endcode
*
* If T is an enum then the functor has the following form:
* @code
* struct functor {
Expand All @@ -65,6 +80,37 @@ struct reflector{

void throw_bad_enum_cast( int64_t i, const char* e );
void throw_bad_enum_cast( const char* k, const char* e );

template <typename Class>
struct reflector_verifier_visitor {
explicit reflector_verifier_visitor( Class& c )
: obj(c) {}

void reflector_verify() {
reflect_verify( obj );
}

private:

// int matches 0 if reflector_verify exists SFINAE
template<class T>
auto verify_imp(const T& t, int) -> decltype(t.reflector_verify(), void()) {
t.reflector_verify();
}

// if no reflector_verify method exists (SFINAE), 0 matches long
template<class T>
auto verify_imp(const T& t, long) -> decltype(t, void()) {}

template<typename T>
auto reflect_verify(const T& t) -> decltype(verify_imp(t, 0), void()) {
verify_imp(t, 0);
}

protected:
Class& obj;
};

} // namespace fc


Expand Down Expand Up @@ -99,6 +145,7 @@ template<typename Visitor>\
static inline void visit( const Visitor& v ) { \
BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_VISIT_BASE, v, INHERITS ) \
BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_VISIT_MEMBER, v, MEMBERS ) \
verify( v ); \
}

#define FC_REFLECT_DERIVED_IMPL_EXT( TYPE, INHERITS, MEMBERS ) \
Expand Down Expand Up @@ -206,6 +253,16 @@ template<> struct reflector<TYPE> {\
typedef TYPE type; \
typedef fc::true_type is_defined; \
typedef fc::false_type is_enum; \
template<typename Visitor> \
static auto verify_imp(const Visitor& v, int) -> decltype(v.reflector_verify(), void()) { \
v.reflector_verify(); \
} \
template<typename Visitor> \
static auto verify_imp(const Visitor& v, long) -> decltype(v, void()) {} \
template<typename Visitor> \
static auto verify(const Visitor& v) -> decltype(verify_imp(v, 0), void()) { \
verify_imp(v, 0); \
} \
enum member_count_enum { \
local_member_count = 0 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_MEMBER_COUNT, +, MEMBERS ),\
total_member_count = local_member_count BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_BASE_MEMBER_COUNT, +, INHERITS )\
Expand All @@ -219,6 +276,16 @@ template<BOOST_PP_SEQ_ENUM(TEMPLATE_ARGS)> struct reflector<TYPE> {\
typedef TYPE type; \
typedef fc::true_type is_defined; \
typedef fc::false_type is_enum; \
template<typename Visitor> \
static auto verify_imp(const Visitor& v, int) -> decltype(v.reflector_verify(), void()) { \
v.reflector_verify(); \
} \
template<typename Visitor> \
static auto verify_imp(const Visitor& v, long) -> decltype(v, void()) {} \
template<typename Visitor> \
static auto verify(const Visitor& v) -> decltype(verify_imp(v, 0), void()) { \
verify_imp(v, 0); \
} \
enum member_count_enum { \
local_member_count = 0 BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_MEMBER_COUNT, +, MEMBERS ),\
total_member_count = local_member_count BOOST_PP_SEQ_FOR_EACH( FC_REFLECT_BASE_MEMBER_COUNT, +, INHERITS )\
Expand Down
8 changes: 4 additions & 4 deletions libraries/fc/include/fc/reflect/variant.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,22 @@ namespace fc
};

template<typename T>
class from_variant_visitor
class from_variant_visitor : reflector_verifier_visitor<T>
{
public:
from_variant_visitor( const variant_object& _vo, T& v )
:vo(_vo),val(v){}
:reflector_verifier_visitor<T>(v)
,vo(_vo){}

template<typename Member, class Class, Member (Class::*member)>
void operator()( const char* name )const
{
auto itr = vo.find(name);
if( itr != vo.end() )
from_variant( itr->value(), val.*member );
from_variant( itr->value(), this->obj.*member );
}

const variant_object& vo;
T& val;
};

template<typename IsReflected=fc::false_type>
Expand Down
64 changes: 50 additions & 14 deletions libraries/fc/src/exception.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,14 +158,32 @@ namespace fc
string exception::to_detail_string( log_level ll )const
{
std::stringstream ss;
ss << variant(my->_code).as_string() <<" " << my->_name << ": " <<my->_what<<"\n";
for( auto itr = my->_elog.begin(); itr != my->_elog.end(); )
{
ss << itr->get_message() <<"\n"; //fc::format_string( itr->get_format(), itr->get_data() ) <<"\n";
ss << " " << json::to_string( itr->get_data() ) <<"\n";
ss << " " << itr->get_context().to_string();
++itr;
if( itr != my->_elog.end() ) ss<<"\n";
try {
try {
ss << variant( my->_code ).as_string();
} catch( std::bad_alloc& ) {
throw;
} catch( ... ) {
ss << "<- exception in to_detail_string.";
}
ss << " " << my->_name << ": " << my->_what << "\n";
for( auto itr = my->_elog.begin(); itr != my->_elog.end(); ) {
try {
ss << itr->get_message() << "\n"; //fc::format_string( itr->get_format(), itr->get_data() ) <<"\n";
ss << " " << json::to_string( itr->get_data()) << "\n";
ss << " " << itr->get_context().to_string();
++itr;
} catch( std::bad_alloc& ) {
throw;
} catch( ... ) {
ss << "<- exception in to_detail_string.";
}
if( itr != my->_elog.end()) ss << "\n";
}
} catch( std::bad_alloc& ) {
throw;
} catch( ... ) {
ss << "<- exception in to_detail_string.\n";
}
return ss.str();
}
Expand All @@ -176,13 +194,31 @@ namespace fc
string exception::to_string( log_level ll )const
{
std::stringstream ss;
ss << what() << " (" << variant(my->_code).as_string() <<")\n";
for( auto itr = my->_elog.begin(); itr != my->_elog.end(); ++itr )
{
ss << fc::format_string( itr->get_format(), itr->get_data() ) <<"\n";
// ss << " " << itr->get_context().to_string() <<"\n";
try {
ss << my->_what;
try {
ss << " (" << variant( my->_code ).as_string() << ")\n";
} catch( std::bad_alloc& ) {
throw;
} catch( ... ) {
ss << "<- exception in to_string.\n";
}
for( auto itr = my->_elog.begin(); itr != my->_elog.end(); ++itr ) {
try {
ss << fc::format_string( itr->get_format(), itr->get_data()) << "\n";
// ss << " " << itr->get_context().to_string() <<"\n";
} catch( std::bad_alloc& ) {
throw;
} catch( ... ) {
ss << "<- exception in to_string.\n";
}
}
return ss.str();
} catch( std::bad_alloc& ) {
throw;
} catch( ... ) {
ss << "<- exception in to_string.\n";
}
return ss.str();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,8 @@ void account_history_api_plugin::plugin_initialize(const variables_map&) {}
if (body.empty()) body = "{}"; \
auto result = api_handle.call_name(fc::json::from_string(body).as<api_namespace::call_name ## _params>()); \
cb(200, fc::json::to_string(result)); \
} catch (fc::eof_exception& e) { \
error_results results{400, "Bad Request", e}; \
cb(400, fc::json::to_string(results)); \
elog("Unable to parse arguments: ${args}", ("args", body)); \
} catch (fc::exception& e) { \
error_results results{500, "Internal Service Error", e}; \
cb(500, fc::json::to_string(results)); \
elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \
} catch (...) { \
http_plugin::handle_exception(#api_name, #call_name, body, cb); \
} \
}}

Expand Down
19 changes: 2 additions & 17 deletions plugins/chain_api_plugin/chain_api_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,8 @@ void chain_api_plugin::plugin_initialize(const variables_map&) {}
if (body.empty()) body = "{}"; \
auto result = api_handle.call_name(fc::json::from_string(body).as<api_namespace::call_name ## _params>()); \
cb(http_response_code, fc::json::to_string(result)); \
} catch (chain::unsatisfied_authorization& e) { \
error_results results{401, "UnAuthorized", e}; \
cb(401, fc::json::to_string(results)); \
} catch (chain::tx_duplicate& e) { \
error_results results{409, "Conflict", e}; \
cb(409, fc::json::to_string(results)); \
} catch (chain::transaction_exception& e) { \
error_results results{400, "Bad Request", e}; \
cb(400, fc::json::to_string(results)); \
} catch (fc::eof_exception& e) { \
error_results results{400, "Bad Request", e}; \
cb(400, fc::json::to_string(results)); \
elog("Unable to parse arguments: ${args}", ("args", body)); \
} catch (fc::exception& e) { \
error_results results{500, "Internal Service Error", e}; \
cb(500, fc::json::to_string(results)); \
elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e.to_detail_string())); \
} catch (...) { \
http_plugin::handle_exception(#api_name, #call_name, body, cb); \
} \
}}

Expand Down
10 changes: 2 additions & 8 deletions plugins/db_size_api_plugin/db_size_api_plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,8 @@ using namespace eosio;
if (body.empty()) body = "{}"; \
INVOKE \
cb(http_response_code, fc::json::to_string(result)); \
} catch (fc::eof_exception& e) { \
error_results results{400, "Bad Request", e}; \
cb(400, fc::json::to_string(results)); \
elog("Unable to parse arguments: ${args}", ("args", body)); \
} catch (fc::exception& e) { \
error_results results{500, "Internal Service Error", e}; \
cb(500, fc::json::to_string(results)); \
elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \
} catch (...) { \
http_plugin::handle_exception(#api_name, #call_name, body, cb); \
} \
}}

Expand Down
Loading

0 comments on commit 691041e

Please sign in to comment.