提交 44548f35 编写于 作者: N Nathan Hourt

Improvements circa Types

- Move types into eos::types namespace
- Fix lots of bugs in types
- Add tests of types (one still failing)
上级 5599ace3
......@@ -545,7 +545,7 @@ void database::validate_referenced_accounts(const signed_transaction& trx)const
for(const auto& msg : trx.messages) {
get_account(msg.sender);
get_account(msg.recipient);
const account_name* previous_notify_account = nullptr;
const AccountName* previous_notify_account = nullptr;
for(const auto& current_notify_account : msg.notify) {
get_account(current_notify_account);
if(previous_notify_account) {
......@@ -798,10 +798,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
create<account_object>([&](account_object& a) {
a.name = "sys";
});
register_type<eos::Transfer>("sys");
register_type<eos::CreateAccount>("sys");
register_type<eos::DefineStruct>("sys");
register_type<eos::SetMessageHandler>("sys");
register_type<types::Transfer>("sys");
register_type<types::CreateAccount>("sys");
register_type<types::DefineStruct>("sys");
register_type<types::SetMessageHandler>("sys");
// Create initial accounts
for (const auto& acct : genesis_state.initial_accounts) {
......@@ -1129,17 +1129,17 @@ void database::update_producer_schedule()
{
}
void database::set_validate_handler( const account_name& contract, const account_name& scope, const message_type& action, message_validate_handler v ) {
void database::set_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, message_validate_handler v ) {
message_validate_handlers[contract][std::make_pair(scope,action)] = v;
}
void database::set_precondition_validate_handler( const account_name& contract, const account_name& scope, const message_type& action, precondition_validate_handler v ) {
void database::set_precondition_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, precondition_validate_handler v ) {
precondition_validate_handlers[contract][std::make_pair(scope,action)] = v;
}
void database::set_apply_handler( const account_name& contract, const account_name& scope, const message_type& action, apply_handler v ) {
void database::set_apply_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, apply_handler v ) {
apply_handlers[contract][std::make_pair(scope,action)] = v;
}
const account_object& database::get_account( const account_name& name )const {
const account_object& database::get_account( const AccountName& name )const {
try {
return get<account_object,by_name>(name);
} FC_CAPTURE_AND_RETHROW( (name) ) }
......
......@@ -51,9 +51,9 @@ namespace eos { namespace chain {
return *this;
}
UInt32 threshold = 0;
shared_vector<AccountPermissionWeight> accounts;
shared_vector<KeyPermissionWeight> keys;
UInt32 threshold = 0;
shared_vector<types::AccountPermissionWeight> accounts;
shared_vector<types::KeyPermissionWeight> keys;
};
class account_object : public chainbase::object<account_object_type, account_object>
......@@ -84,7 +84,7 @@ namespace eos { namespace chain {
id_type id;
account_id_type owner; ///< the account this permission belongs to
id_type parent; ///< parent permission
permission_name name;
PermissionName name;
shared_authority auth; ///< TODO
};
......@@ -105,11 +105,11 @@ namespace eos { namespace chain {
ordered_unique<tag<by_owner>,
composite_key< permission_object,
member<permission_object, account_object::id_type, &permission_object::owner>,
member<permission_object, permission_name, &permission_object::name>,
member<permission_object, PermissionName, &permission_object::name>,
member<permission_object, permission_object::id_type, &permission_object::id>
>
>,
ordered_unique<tag<by_name>, member<permission_object, permission_name, &permission_object::name> >
ordered_unique<tag<by_name>, member<permission_object, PermissionName, &permission_object::name> >
>
>;
......
......@@ -3,20 +3,20 @@
#include <eos/types/generated.hpp>
namespace eos {
inline bool operator < ( const AccountPermission& a, const AccountPermission& b ) {
inline bool operator < ( const types::AccountPermission& a, const types::AccountPermission& b ) {
return std::tie( a.account, a.permission ) < std::tie( b.account, b.permission );
}
/**
* Makes sure all keys are unique and sorted and all account permissions are unique and sorted
*/
inline bool validate( eos::Authority& auth ) {
const KeyPermissionWeight* prev = nullptr;
inline bool validate( types::Authority& auth ) {
const types::KeyPermissionWeight* prev = nullptr;
for( const auto& k : auth.keys ) {
if( !prev ) prev = &k;
else if( prev->key < k.key ) return false;
}
const AccountPermissionWeight* pa = nullptr;
const types::AccountPermissionWeight* pa = nullptr;
for( const auto& a : auth.accounts ) {
if( !pa ) pa = &a;
else if( pa->permission < a.permission ) return false;
......
......@@ -56,17 +56,17 @@ namespace eos { namespace chain {
class precondition_validate_context : public message_validate_context {
public:
precondition_validate_context( const database& d, const transaction& t, const message& m, const account_name& r )
precondition_validate_context( const database& d, const transaction& t, const message& m, const AccountName& r )
:message_validate_context(t,m),recipient(r),db(d){}
const account_name& recipient;
const AccountName& recipient;
const database& db;
};
class apply_context : public precondition_validate_context {
public:
apply_context( database& d, const transaction& t, const message& m, const account_name& recipient )
apply_context( database& d, const transaction& t, const message& m, const AccountName& recipient )
:precondition_validate_context(d,t,m,recipient),mutable_db(d){}
String get( String key )const;
......@@ -108,8 +108,8 @@ namespace eos { namespace chain {
fc::signal<void(const signed_transaction&)> on_pending_transaction;
template<typename T>
void register_type( account_name scope ) {
auto stru = eos::GetStruct<T>::type();
void register_type( AccountName scope ) {
auto stru = eos::types::GetStruct<T>::type();
create<type_object>([&](type_object& o) {
o.scope = scope;
o.name = stru.name;
......@@ -126,9 +126,9 @@ namespace eos { namespace chain {
* The database can override any script handler with native code.
*/
///@{
void set_validate_handler( const account_name& contract, const account_name& scope, const message_type& action, message_validate_handler v );
void set_precondition_validate_handler( const account_name& contract, const account_name& scope, const message_type& action, precondition_validate_handler v );
void set_apply_handler( const account_name& contract, const account_name& scope, const message_type& action, apply_handler v );
void set_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, message_validate_handler v );
void set_precondition_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, precondition_validate_handler v );
void set_apply_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, apply_handler v );
//@}
enum validation_steps
......@@ -193,7 +193,7 @@ namespace eos { namespace chain {
const signed_transaction& get_recent_transaction( const transaction_id_type& trx_id )const;
std::vector<block_id_type> get_block_ids_on_fork(block_id_type head_of_fork) const;
const account_object& get_account( const account_name& name )const;
const account_object& get_account( const AccountName& name )const;
/**
* Calculate the percent of block production slots that were missed in the
......@@ -383,10 +383,10 @@ namespace eos { namespace chain {
node_property_object _node_property_object;
typedef pair<account_name,message_type> handler_key;
map< account_name, map<handler_key, message_validate_handler> > message_validate_handlers;
map< account_name, map<handler_key, precondition_validate_handler> > precondition_validate_handlers;
map< account_name, map<handler_key, apply_handler> > apply_handlers;
typedef pair<AccountName,TypeName> handler_key;
map< AccountName, map<handler_key, message_validate_handler> > message_validate_handlers;
map< AccountName, map<handler_key, precondition_validate_handler> > precondition_validate_handlers;
map< AccountName, map<handler_key, apply_handler> > apply_handlers;
};
} }
......@@ -25,45 +25,7 @@
#include <fc/exception/exception.hpp>
#include <eos/chain/protocol.hpp>
#define EOS_ASSERT( expr, exc_type, FORMAT, ... ) \
FC_MULTILINE_MACRO_BEGIN \
if( !(expr) ) \
FC_THROW_EXCEPTION( exc_type, FORMAT, __VA_ARGS__ ); \
FC_MULTILINE_MACRO_END
#define EOS_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _validate_exception, \
eos::chain::message_validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value, \
#op_name "_operation validation exception" \
) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _evaluate_exception, \
eos::chain::message_evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value, \
#op_name "_operation evaluation exception" \
)
#define EOS_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _ ## exc_name, \
eos::chain::op_name ## _validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value \
+ seqnum, \
msg \
)
#define EOS_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _ ## exc_name, \
eos::chain::op_name ## _evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value \
+ seqnum, \
msg \
)
#include <eos/utilities/exception_macros.hpp>
namespace eos { namespace chain {
......
......@@ -32,7 +32,7 @@ namespace eos { namespace chain {
OBJECT_CTOR(key_value_object, (key)(value))
id_type id;
account_name scope;
AccountName scope;
shared_string key;
shared_string value;
};
......@@ -44,10 +44,10 @@ namespace eos { namespace chain {
ordered_unique<tag<by_id>, member<key_value_object, key_value_object::id_type, &key_value_object::id>>,
ordered_unique<tag<by_scope_key>,
composite_key< key_value_object,
member<key_value_object, account_name, &key_value_object::scope>,
member<key_value_object, AccountName, &key_value_object::scope>,
member<key_value_object, shared_string, &key_value_object::key>
>,
composite_key_compare< std::less<account_name>, chainbase::strcmp_less >
composite_key_compare< std::less<AccountName>, chainbase::strcmp_less >
>
>
>;
......
......@@ -20,26 +20,26 @@ namespace eos { namespace chain {
*/
struct message {
/// The account which sent the message
account_name sender;
AccountName sender;
/// The account to receive the message
account_name recipient;
AccountName recipient;
/// Other accounts to notify about this message
vector<account_name> notify;
vector<AccountName> notify;
/**
* Every contract defines the set of types that it accepts, these types are
* scoped according to the recipient. This means two contracts can can define
* two different types with the same name.
*/
TypeName type;
types::TypeName type;
/// The message contents
vector<char> data;
template<typename T>
void set( const message_type& t, const T& value ) {
void set( const TypeName& t, const T& value ) {
type = t;
data = fc::raw::pack( value );
}
......@@ -47,7 +47,7 @@ struct message {
T as()const {
return fc::raw::unpack<T>(data);
}
bool has_notify( const account_name& n )const {
bool has_notify( const AccountName& n )const {
for( const auto& no : notify )
if( no == n ) return true;
return false;
......
......@@ -133,9 +133,9 @@ namespace eos { namespace chain {
*/
struct authorization {
/// The account authorizing the transaction
account_name authorizing_account;
AccountName authorizing_account;
/// The privileges being invoked to authorize the transaction
permission_name privileges;
PermissionName privileges;
};
/**
......
......@@ -32,9 +32,9 @@ namespace eos { namespace chain {
OBJECT_CTOR(type_object, (fields))
id_type id;
account_name scope;
AccountName scope;
TypeName name;
account_name base_scope;
AccountName base_scope;
TypeName base;
shared_vector<Field> fields;
};
......@@ -46,8 +46,8 @@ namespace eos { namespace chain {
ordered_unique<tag<by_id>, member<type_object, type_object::id_type, &type_object::id>>,
ordered_unique<tag<by_scope_name>,
composite_key< type_object,
member<type_object, account_name, &type_object::scope>,
member<type_object, message_type, &type_object::name>
member<type_object, AccountName, &type_object::scope>,
member<type_object, TypeName, &type_object::name>
>
>
>
......
......@@ -107,13 +107,27 @@ namespace eos { namespace chain {
using chain_id_type = fc::sha256;
using eos::AccountName;
using account_name = eos::AccountName;
using eos::PermissionName;
using permission_name = eos::PermissionName;
using message_name = eos::TypeName;
using message_type = message_name;
using eos::types::AccountName;
using eos::types::PermissionName;
using eos::types::Asset;
using eos::types::Authority;
using eos::types::PermissionName;
using eos::types::TypeName;
using eos::types::Time;
using eos::types::Field;
using eos::types::String;
using eos::types::UInt8;
using eos::types::UInt16;
using eos::types::UInt32;
using eos::types::UInt64;
using eos::types::UInt128;
using eos::types::UInt256;
using eos::types::Int8;
using eos::types::Int16;
using eos::types::Int32;
using eos::types::Int64;
using eos::types::Int128;
using eos::types::Int256;
/**
* List all object types from all namespaces here so they can
......@@ -154,7 +168,7 @@ namespace eos { namespace chain {
using signature_type = fc::ecc::compact_signature;
using weight_type = uint16_t;
using public_key_type = eos::PublicKey;
using public_key_type = eos::types::PublicKey;
} } // eos::chain
......
......@@ -3,7 +3,7 @@
#include <boost/multiprecision/cpp_int.hpp>
#include <fc/reflect/variant.hpp>
namespace eos {
namespace eos { namespace types {
typedef boost::multiprecision::int128_t int128_t;
uint8_t Asset::decimals()const {
......@@ -159,4 +159,4 @@ namespace eos {
} FC_CAPTURE_AND_RETHROW( (base)(quote) ) }
} // eos
}} // eos::types
......@@ -8,14 +8,14 @@ add_library( eos_types
${HEADERS}
)
target_include_directories( eos_types PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )
target_link_libraries( eos_types fc )
target_link_libraries( eos_types eos_utilities fc )
add_executable( type_generator type_generator.cpp )
target_link_libraries( type_generator fc eos_types ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} )
add_custom_command( OUTPUT include/eos/types/generated.hpp
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/type_generator ${CMAKE_CURRENT_SOURCE_DIR}/types.eos ${CMAKE_CURRENT_SOURCE_DIR}/include/eos/types/generated.hpp
DEPENDS types.eos type_generator )
DEPENDS types.eos type_generator type_generator.cpp )
add_executable( types_test test.cpp include/eos/types/generated.hpp )
target_link_libraries( types_test eos_types fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} )
......
......@@ -6,7 +6,7 @@
#define KEY_PREFIX "EOS"
namespace eos {
namespace eos { namespace types {
PublicKey::PublicKey():key_data(){};
......@@ -70,19 +70,19 @@ namespace eos {
return p1.key_data < p2.key_data;
};
} // eos
}} // eos::types
namespace fc
{
using namespace std;
void to_variant(const eos::PublicKey& var, fc::variant& vo)
void to_variant(const eos::types::PublicKey& var, fc::variant& vo)
{
vo = std::string(var);
}
void from_variant(const fc::variant& var, eos::PublicKey& vo)
void from_variant(const fc::variant& var, eos::types::PublicKey& vo)
{
vo = eos::PublicKey(var.as_string());
vo = eos::types::PublicKey(var.as_string());
}
} // fc
#include <eos/types/TypeParser.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/algorithm/cxx11/all_of.hpp>
#include <boost/range.hpp>
#include <algorithm>
#include <iostream>
namespace eos {
void AbstractSymbolTable::parse( std::istream& in ) {
vector<string> line_tokens;
bool in_struct = false;
Struct current;
auto finishStruct = [&](){
FC_ASSERT( current.fields.size() > 0, "A struct must specify at least one field" );
this->addType( current );
current.fields.clear();
current.base = TypeName();
in_struct = false;
};
int linenum = -1;
for( string line; std::getline(in, line); ) {
++linenum;
if( !line.size() ) continue;
line = line.substr( 0, line.find( '#' ) );
line = fc::trim(line);
if( !line.size() ) continue;
std::cerr << line << "\n";
line_tokens.clear();
split( line_tokens, line, boost::is_any_of( " \t" ), boost::token_compress_on );
if( !line_tokens.size() ) continue;
if( line_tokens[0] == "struct" ) {
if( in_struct ) finishStruct();
in_struct = true;
FC_ASSERT( line_tokens.size() >= 2, "Expected a struct name" );
current.name = line_tokens[1];
if( line_tokens.size() > 2 ) {
FC_ASSERT( line_tokens.size() == 4, "Expected a struct name" );
FC_ASSERT( line_tokens[2] == "inherits" );
current.base = line_tokens[3];
}
} else if( line_tokens[0] == "typedef" ) {
if( in_struct ) finishStruct();
FC_ASSERT( line_tokens.size() == 3, "Expected a struct name" );
this->addTypeDef( line_tokens[1], line_tokens[2] );
} else if( in_struct ) { // parse field
idump((line_tokens));
FC_ASSERT( line_tokens.size() == 2, "a field must be two tokens long" );
const auto& name = line_tokens[0];
const auto& type = line_tokens[1];
FC_ASSERT( name.size() > 0 );
current.fields.emplace_back( Field{name,type} );
namespace eos { namespace types {
namespace alg = boost::algorithm;
bool AbstractSymbolTable::isValidTypeName(const TypeName& name, bool allowArray) {
std::string mutable_name = name;
if (name.size() == 0 || !std::isupper(mutable_name[0])) return false;
// If appropriate, remove trailing []
if (allowArray && alg::ends_with(mutable_name, "[]"))
mutable_name.resize(mutable_name.size() - 2);
return alg::all_of(mutable_name, alg::is_alnum());
}
void AbstractSymbolTable::parse(std::istream& in) {
vector<string> line_tokens;
bool in_struct = false;
Struct current;
auto finishStruct = [&](){
FC_ASSERT(current.fields.size() > 0, "A struct must specify at least one field");
this->addType(current);
current.fields.clear();
current.base = TypeName();
in_struct = false;
};
int linenum = -1;
for(string line; std::getline(in, line);) {
++linenum;
if(!line.size()) continue;
line = line.substr(0, line.find('#'));
line = fc::trim(line);
if(!line.size()) continue;
std::cerr << line << "\n";
line_tokens.clear();
split(line_tokens, line, boost::is_any_of(" \t"), boost::token_compress_on);
if(!line_tokens.size()) continue;
if(line_tokens[0] == "struct") {
if(in_struct) finishStruct();
in_struct = true;
FC_ASSERT(line_tokens.size() >= 2, "Expected a struct name");
current.name = line_tokens[1];
if(line_tokens.size() > 2) {
FC_ASSERT(line_tokens.size() == 4, "Expected a struct name");
FC_ASSERT(line_tokens[2] == "inherits");
current.base = line_tokens[3];
}
else
FC_ASSERT( false, "Invalid token ${t} on line ${n}", ("t",line_tokens[0])("n",linenum) );
} else if(line_tokens[0] == "typedef") {
if(in_struct) finishStruct();
FC_ASSERT(line_tokens.size() == 3, "Expected a struct name");
this->addTypeDef(line_tokens[1], line_tokens[2]);
} else if(in_struct) { // parse field
idump((line_tokens));
FC_ASSERT(line_tokens.size() == 2, "a field must be two tokens long");
const auto& name = line_tokens[0];
const auto& type = line_tokens[1];
FC_ASSERT(name.size() > 0);
current.fields.emplace_back(Field{name,type});
}
else
FC_ASSERT(false, "Invalid token ${t} on line ${n}", ("t",line_tokens[0])("n",linenum));
}
}
void SimpleSymbolTable::addType(const Struct& s) { try {
EOS_ASSERT(isValidTypeName(s.name), invalid_type_name_exception,
"Invalid type name: ${name}", ("name", s.name));
EOS_ASSERT(!isKnownType(s.name), duplicate_type_exception,
"Duplicate type name: ${name}", ("name", s.name));
EOS_ASSERT(s.base.size() == 0 || isKnownType(s.base), unknown_type_exception,
"Unknown base type name: ${name}", ("name", s.base));
for(const auto& f : s.fields) {
EOS_ASSERT(isKnownType(f.type), unknown_type_exception,
"No such type found: ${type}", ("type",f.type));
}
structs[s.name] = s;
order.push_back(s.name);
} FC_CAPTURE_AND_RETHROW((s)) }
void SimpleSymbolTable::addTypeDef(const TypeName& from, const TypeName& to) { try {
EOS_ASSERT(isValidTypeName(to), invalid_type_name_exception,
"Invalid type name: ${name}", ("name", to));
EOS_ASSERT(!isKnownType(to), duplicate_type_exception,
"Duplicate type name: ${name}", ("name", to));
EOS_ASSERT(isKnownType(from), unknown_type_exception,
"No such type found: ${type}", ("type", from));
typedefs[to] = from;
order.push_back(to);
} FC_CAPTURE_AND_RETHROW((from)(to)) }
bool SimpleSymbolTable::isKnownType(const TypeName& n) { try {
String name(n);
EOS_ASSERT(!name.empty(), invalid_type_name_exception, "Type name cannot be empty");
if(name.size() > 2 && name.back() == ']') {
FC_ASSERT(name[name.size()-2] == '[');
return isKnownType(name.substr(0, name.size()-2));
}
return known.find(n) != known.end() ||
typedefs.find(n) != typedefs.end() ||
structs.find(n) != structs.end();
} FC_CAPTURE_AND_RETHROW((n)) }
Struct eos::types::SimpleSymbolTable::getType(TypeName name) const {
name = resolveTypedef(name);
auto itr = structs.find(name);
if(itr != structs.end())
return itr->second;
if(known.find(name) != known.end())
FC_ASSERT(false, "type is a built in type");
FC_ASSERT(false, "unknown type: ${n}", ("n", name));
}
TypeName SimpleSymbolTable::resolveTypedef(TypeName name) const {
auto tdef = typedefs.find(name);
while(tdef != typedefs.end()) {
name = tdef->second;
tdef = typedefs.find(name);
}
return name;
}
} // namespace eos
}} // namespace eos::types
......@@ -3,19 +3,19 @@
#include <eos/types/native.hpp>
/// eos with 8 digits of precision
#define EOS_SYMBOL (uint64_t(8) | (uint64_t('E') << 8) | (uint64_t('O') << 16) | (uint64_t('S') << 24) )
#define EOS_SYMBOL (int64_t(8) | (uint64_t('E') << 8) | (uint64_t('O') << 16) | (uint64_t('S') << 24))
/// Defined to be largest power of 10 that fits in 53 bits of precision
#define EOS_MAX_SHARE_SUPPLY int64_t(1000000000000000ll)
namespace eos {
namespace eos { namespace types {
using AssetSymbol = uint64_t;
using ShareType = Int64;
struct Asset
{
Asset( ShareType a = 0, AssetSymbol id = EOS_SYMBOL )
Asset(ShareType a = 0, AssetSymbol id = EOS_SYMBOL)
:amount(a),symbol(id){}
ShareType amount;
......@@ -28,49 +28,49 @@ namespace eos {
int64_t precision()const;
void set_decimals(uint8_t d);
static Asset fromString( const String& from );
static Asset fromString(const String& from);
String toString()const;
Asset& operator += ( const Asset& o )
Asset& operator += (const Asset& o)
{
FC_ASSERT( symbol == o.symbol );
FC_ASSERT(symbol == o.symbol);
amount += o.amount;
return *this;
}
Asset& operator -= ( const Asset& o )
Asset& operator -= (const Asset& o)
{
FC_ASSERT( symbol == o.symbol );
FC_ASSERT(symbol == o.symbol);
amount -= o.amount;
return *this;
}
Asset operator -()const { return Asset( -amount, symbol ); }
Asset operator -()const { return Asset(-amount, symbol); }
friend bool operator == ( const Asset& a, const Asset& b )
friend bool operator == (const Asset& a, const Asset& b)
{
return std::tie( a.symbol, a.amount ) == std::tie( b.symbol, b.amount );
return std::tie(a.symbol, a.amount) == std::tie(b.symbol, b.amount);
}
friend bool operator < ( const Asset& a, const Asset& b )
friend bool operator < (const Asset& a, const Asset& b)
{
FC_ASSERT( a.symbol == b.symbol );
FC_ASSERT(a.symbol == b.symbol);
return std::tie(a.amount,a.symbol) < std::tie(b.amount,b.symbol);
}
friend bool operator <= ( const Asset& a, const Asset& b ) { return (a == b) || (a < b); }
friend bool operator != ( const Asset& a, const Asset& b ) { return !(a == b); }
friend bool operator > ( const Asset& a, const Asset& b ) { return !(a <= b); }
friend bool operator >= ( const Asset& a, const Asset& b ) { return !(a < b); }
friend Asset operator - ( const Asset& a, const Asset& b ) {
FC_ASSERT( a.symbol == b.symbol );
return Asset( a.amount - b.amount, a.symbol );
friend bool operator <= (const Asset& a, const Asset& b) { return (a == b) || (a < b); }
friend bool operator != (const Asset& a, const Asset& b) { return !(a == b); }
friend bool operator > (const Asset& a, const Asset& b) { return !(a <= b); }
friend bool operator >= (const Asset& a, const Asset& b) { return !(a < b); }
friend Asset operator - (const Asset& a, const Asset& b) {
FC_ASSERT(a.symbol == b.symbol);
return Asset(a.amount - b.amount, a.symbol);
}
friend Asset operator + ( const Asset& a, const Asset& b ) {
FC_ASSERT( a.symbol == b.symbol );
return Asset( a.amount + b.amount, a.symbol );
friend Asset operator + (const Asset& a, const Asset& b) {
FC_ASSERT(a.symbol == b.symbol);
return Asset(a.amount + b.amount, a.symbol);
}
friend std::ostream& operator << ( std::ostream& out, const Asset& a ) { return out << a.toString(); }
friend std::ostream& operator << (std::ostream& out, const Asset& a) { return out << a.toString(); }
};
......@@ -82,11 +82,11 @@ namespace eos {
Price(const Asset& base = Asset(), const Asset quote = Asset())
:base(base),quote(quote){}
static Price max(AssetSymbol base, AssetSymbol quote );
static Price min(AssetSymbol base, AssetSymbol quote );
static Price max(AssetSymbol base, AssetSymbol quote);
static Price min(AssetSymbol base, AssetSymbol quote);
Price max()const { return Price::max( base.symbol, quote.symbol ); }
Price min()const { return Price::min( base.symbol, quote.symbol ); }
Price max()const { return Price::max(base.symbol, quote.symbol); }
Price min()const { return Price::min(base.symbol, quote.symbol); }
double to_real()const { return base.to_real() / quote.to_real(); }
......@@ -94,26 +94,28 @@ namespace eos {
void validate()const;
};
Price operator / ( const Asset& base, const Asset& quote );
inline Price operator~( const Price& p ) { return Price{p.quote,p.base}; }
Price operator / (const Asset& base, const Asset& quote);
inline Price operator~(const Price& p) { return Price{p.quote,p.base}; }
bool operator < ( const Asset& a, const Asset& b );
bool operator <= ( const Asset& a, const Asset& b );
bool operator < ( const Price& a, const Price& b );
bool operator <= ( const Price& a, const Price& b );
bool operator > ( const Price& a, const Price& b );
bool operator >= ( const Price& a, const Price& b );
bool operator == ( const Price& a, const Price& b );
bool operator != ( const Price& a, const Price& b );
Asset operator * ( const Asset& a, const Price& b );
bool operator < (const Asset& a, const Asset& b);
bool operator <= (const Asset& a, const Asset& b);
bool operator < (const Price& a, const Price& b);
bool operator <= (const Price& a, const Price& b);
bool operator > (const Price& a, const Price& b);
bool operator >= (const Price& a, const Price& b);
bool operator == (const Price& a, const Price& b);
bool operator != (const Price& a, const Price& b);
Asset operator * (const Asset& a, const Price& b);
} // namespace eos
}} // namespace eos::types
namespace fc {
inline void to_variant( const eos::Asset& var, fc::variant& vo ) { vo = var.toString(); }
inline void from_variant( const fc::variant& var, eos::Asset& vo ) { vo = eos::Asset::fromString( var.get_string() ); }
inline void to_variant(const eos::types::Asset& var, fc::variant& vo) { vo = var.toString(); }
inline void from_variant(const fc::variant& var, eos::types::Asset& vo) {
vo = eos::types::Asset::fromString(var.get_string());
}
}
FC_REFLECT( eos::Asset, (amount)(symbol) )
FC_REFLECT( eos::Price, (base)(quote) )
FC_REFLECT(eos::types::Asset, (amount)(symbol))
FC_REFLECT(eos::types::Price, (base)(quote))
......@@ -3,7 +3,7 @@
#include <fc/reflect/reflect.hpp>
#include <fc/reflect/variant.hpp>
namespace eos {
namespace eos { namespace types {
struct PublicKey
{
struct BinaryKey
......@@ -14,9 +14,9 @@ namespace eos {
};
fc::ecc::public_key_data key_data;
PublicKey();
PublicKey( const fc::ecc::public_key_data& data );
PublicKey( const fc::ecc::public_key& pubkey );
explicit PublicKey( const std::string& base58str );
PublicKey(const fc::ecc::public_key_data& data);
PublicKey(const fc::ecc::public_key& pubkey);
explicit PublicKey(const std::string& base58str);
operator fc::ecc::public_key_data() const;
operator fc::ecc::public_key() const;
explicit operator std::string() const;
......@@ -24,15 +24,15 @@ namespace eos {
friend bool operator == ( const PublicKey& p1, const PublicKey& p2);
friend bool operator != ( const PublicKey& p1, const PublicKey& p2);
friend bool operator < ( const PublicKey& p1, const PublicKey& p2);
bool is_valid_v1( const std::string& base58str );
bool is_valid_v1(const std::string& base58str);
};
}
}} // namespace eos::types
namespace fc
{
void to_variant( const eos::PublicKey& var, fc::variant& vo );
void from_variant( const fc::variant& var, eos::PublicKey& vo );
void to_variant(const eos::types::PublicKey& var, fc::variant& vo);
void from_variant(const fc::variant& var, eos::types::PublicKey& vo);
}
FC_REFLECT( eos::PublicKey, (key_data) )
FC_REFLECT( eos::PublicKey::BinaryKey, (data)(check) )
FC_REFLECT(eos::types::PublicKey, (key_data))
FC_REFLECT(eos::types::PublicKey::BinaryKey, (data)(check))
......@@ -9,103 +9,60 @@
#include <fc/reflect/variant.hpp>
#include <eos/types/native.hpp>
namespace eos {
using std::map;
using std::set;
using std::string;
using std::vector;
class AbstractSymbolTable {
public:
virtual ~AbstractSymbolTable(){};
virtual void addType( const Struct& s ) =0;
virtual void addTypeDef( const TypeName& from, const TypeName& to ) = 0;
virtual bool isKnownType( const TypeName& name ) = 0;
virtual TypeName resolveTypedef( TypeName name )const = 0;
virtual Struct getType( TypeName name )const = 0;
/**
* Parses the input stream and populatse the symbol table, the table may be pre-populated
*/
void parse( std::istream& in );
string binaryToJson( const TypeName& type, const Bytes& binary );
Bytes jsonToBinary( const TypeName& type, const string& json );
};
class SimpleSymbolTable : public AbstractSymbolTable {
public:
SimpleSymbolTable():
known( { "Field", "Struct", "Asset", "FixedString16", "FixedString32",
"UInt8", "UInt16", "UInt32", "UInt64",
"UInt128", "Checksum", "UInt256", "UInt512",
"Int8", "Int16", "Int32", "Int64",
"Int128", "Int224", "Int256", "Int512",
"Bytes", "PublicKey", "Signature", "String", "Time" } )
{
}
virtual void addType( const Struct& s ) override { try {
FC_ASSERT( !isKnownType( s.name ) );
for( const auto& f : s.fields ) {
FC_ASSERT( isKnownType( f.type ), "", ("type",f.type) );
}
structs[s.name] = s;
order.push_back(s.name);
// wdump((s.name)(s.base)(s.fields));
} FC_CAPTURE_AND_RETHROW( (s) ) }
virtual void addTypeDef( const TypeName& from, const TypeName& to ) override { try {
FC_ASSERT( !isKnownType( to ) );
FC_ASSERT( isKnownType( from ) );
typedefs[to] = from;
order.push_back(to);
} FC_CAPTURE_AND_RETHROW( (from)(to) ) }
virtual bool isKnownType( const TypeName& n ) override { try {
String name(n);
FC_ASSERT( name.size() > 0 );
if( name.size() > 2 && name.back() == ']' ) {
FC_ASSERT( name[name.size()-2] == '[' );
return isKnownType( name.substr( 0, name.size()-2 ) );
}
return known.find(n) != known.end() ||
typedefs.find(n) != typedefs.end() ||
structs.find(n) != structs.end();
} FC_CAPTURE_AND_RETHROW( (n) ) }
virtual Struct getType( TypeName name )const override {
name = resolveTypedef( name );
auto itr = structs.find( name );
if( itr != structs.end() )
return itr->second;
if( known.find(name) != known.end() )
FC_ASSERT( false, "type is a built in type" );
FC_ASSERT( false, "unknown type: ${n}", ("n", name) );
}
virtual TypeName resolveTypedef( TypeName name )const override {
auto tdef = typedefs.find( name );
while( tdef != typedefs.end() ) {
name = tdef->second;
tdef = typedefs.find( name );
}
return name;
}
// private:
set<TypeName> known;
vector<TypeName> order;
map<TypeName, TypeName> typedefs;
map<TypeName, Struct> structs;
};
} // namespace eos
FC_REFLECT( eos::SimpleSymbolTable, (typedefs)(structs) )
#include <eos/types/exceptions.hpp>
namespace eos { namespace types {
using std::map;
using std::set;
using std::string;
using std::vector;
class AbstractSymbolTable {
public:
virtual ~AbstractSymbolTable(){}
virtual void addType(const Struct& s) =0;
virtual void addTypeDef(const TypeName& from, const TypeName& to) = 0;
virtual bool isKnownType(const TypeName& name) = 0;
virtual bool isValidTypeName(const TypeName& name, bool allowArray = false);
virtual TypeName resolveTypedef(TypeName name)const = 0;
virtual Struct getType(TypeName name)const = 0;
/**
* Parses the input stream and populatse the symbol table, the table may be pre-populated
*/
void parse(std::istream& in);
string binaryToJson(const TypeName& type, const Bytes& binary);
Bytes jsonToBinary(const TypeName& type, const string& json);
};
class SimpleSymbolTable : public AbstractSymbolTable {
public:
SimpleSymbolTable():
known({ "Field", "Struct", "Asset", "FixedString16", "FixedString32",
"UInt8", "UInt16", "UInt32", "UInt64",
"UInt128", "Checksum", "UInt256", "UInt512",
"Int8", "Int16", "Int32", "Int64",
"Int128", "Int224", "Int256", "Int512",
"Bytes", "PublicKey", "Signature", "String", "Time" })
{}
virtual void addType(const Struct& s) override;
virtual void addTypeDef(const TypeName& from, const TypeName& to) override;
virtual bool isKnownType(const TypeName& n) override;
virtual Struct getType(TypeName name)const override;
virtual TypeName resolveTypedef(TypeName name)const override;
// private:
set<TypeName> known;
vector<TypeName> order;
map<TypeName, TypeName> typedefs;
map<TypeName, Struct> structs;
};
}} // namespace eos::types
FC_REFLECT(eos::types::SimpleSymbolTable, (typedefs)(structs))
#pragma once
#include <fc/io/datastream.hpp>
namespace EOS {
namespace eos { namespace types {
using fc::datastream;
struct InputDatastream {
......@@ -78,4 +78,4 @@ namespace EOS {
uint32_t tellp()const { return ds.tellp(); }
};
} // namespace EOS
}} // namespace eos::types
#pragma once
#include <eos/types/native.hpp>
namespace EOS {
namespace eos { namespace types {
class InputDatastream;
class OutputDatastream;
......@@ -66,4 +66,4 @@ namespace EOS {
};
} /// namespace EOS
}} /// namespace eos::types
/*
* Copyright (c) 2017, Respective Authors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include <fc/exception/exception.hpp>
#include <eos/utilities/exception_macros.hpp>
namespace eos { namespace types {
FC_DECLARE_EXCEPTION(type_exception, 4000000, "type exception")
FC_DECLARE_DERIVED_EXCEPTION(unknown_type_exception, type_exception,
4010000, "Could not find requested type")
FC_DECLARE_DERIVED_EXCEPTION(duplicate_type_exception, type_exception,
4020000, "Requested type already exists")
FC_DECLARE_DERIVED_EXCEPTION(invalid_type_name_exception, type_exception,
4030000, "Requested type name is invalid")
} } // eos::chain
......@@ -17,7 +17,7 @@
#include <fc/reflect/reflect.hpp>
namespace eos {
namespace eos { namespace types {
using namespace boost::multiprecision;
template<typename... T>
......@@ -95,26 +95,26 @@ namespace eos {
/// TODO: make sure this works with FC raw
template<typename Stream, typename Number>
void fromBinary( Stream& st, boost::multiprecision::number<Number>& value ) {
void fromBinary(Stream& st, boost::multiprecision::number<Number>& value) {
unsigned char data[(std::numeric_limits<decltype(value)>::digits+1)/8];
st.read( (char*)data, sizeof(data) );
boost::multiprecision::import_bits( value, data, data + sizeof(data), 1 );
st.read((char*)data, sizeof(data));
boost::multiprecision::import_bits(value, data, data + sizeof(data), 1);
}
template<typename Stream, typename Number>
void toBinary( Stream& st, const boost::multiprecision::number<Number>& value ) {
void toBinary(Stream& st, const boost::multiprecision::number<Number>& value) {
unsigned char data[(std::numeric_limits<decltype(value)>::digits+1)/8];
boost::multiprecision::export_bits( value, data, 1 );
st.write( (const char*)data, sizeof(data) );
boost::multiprecision::export_bits(value, data, 1);
st.write((const char*)data, sizeof(data));
}
} // namespace eos
}} // namespace eos::types
namespace fc {
void to_variant( const std::vector<eos::Field>& c, fc::variant& v );
void from_variant( const fc::variant& v, std::vector<eos::Field>& check );
void to_variant( const std::map<std::string,eos::Struct>& c, fc::variant& v );
void from_variant( const fc::variant& v, std::map<std::string,eos::Struct>& check );
void to_variant(const std::vector<eos::types::Field>& c, fc::variant& v);
void from_variant(const fc::variant& v, std::vector<eos::types::Field>& check);
void to_variant(const std::map<std::string,eos::types::Struct>& c, fc::variant& v);
void from_variant(const fc::variant& v, std::map<std::string,eos::types::Struct>& check);
}
FC_REFLECT( eos::Field, (name)(type) )
FC_REFLECT( eos::Struct, (name)(base)(fields) )
FC_REFLECT(eos::types::Field, (name)(type))
FC_REFLECT(eos::types::Struct, (name)(base)(fields))
#pragma once
namespace EOS {
namespace eos { namespace types {
template<typename T>
fc::variant toVariant( const vector<T>& a ) {
vector<fc::variant> result;
......@@ -41,4 +41,4 @@ namespace EOS {
EOS::fromBinary( ds, result );
return result;
}
}
}} // namespace eos::types
......@@ -6,39 +6,39 @@
#include <fc/reflect/variant.hpp>
namespace fc {
void to_variant( const std::vector<eos::Field>& c, fc::variant& v ) {
fc::mutable_variant_object mvo; mvo.reserve( c.size() );
for( const auto& f : c ) {
mvo.set( f.name, eos::String(f.type) );
void to_variant(const std::vector<eos::types::Field>& c, fc::variant& v) {
fc::mutable_variant_object mvo; mvo.reserve(c.size());
for(const auto& f : c) {
mvo.set(f.name, eos::types::String(f.type));
}
v = std::move(mvo);
}
void from_variant( const fc::variant& v, std::vector<eos::Field>& fields ) {
void from_variant(const fc::variant& v, std::vector<eos::types::Field>& fields) {
const auto& obj = v.get_object();
fields.reserve( obj.size() );
for( const auto& f : obj )
fields.emplace_back( eos::Field{ f.key(), f.value().get_string() } );
fields.reserve(obj.size());
for(const auto& f : obj)
fields.emplace_back(eos::types::Field{ f.key(), f.value().get_string() });
}
void to_variant( const std::map<std::string,eos::Struct>& c, fc::variant& v )
void to_variant(const std::map<std::string,eos::types::Struct>& c, fc::variant& v)
{
fc::mutable_variant_object mvo; mvo.reserve( c.size() );
for( const auto& item : c ) {
if( item.second.base.size() )
mvo.set( item.first, fc::mutable_variant_object("base",item.second.base)("fields",item.second.fields) );
fc::mutable_variant_object mvo; mvo.reserve(c.size());
for(const auto& item : c) {
if(item.second.base.size())
mvo.set(item.first, fc::mutable_variant_object("base",item.second.base)("fields",item.second.fields));
else
mvo.set( item.first, fc::mutable_variant_object("fields",item.second.fields) );
mvo.set(item.first, fc::mutable_variant_object("fields",item.second.fields));
}
v = std::move(mvo);
}
void from_variant( const fc::variant& v, std::map<std::string,eos::Struct>& structs ) {
void from_variant(const fc::variant& v, std::map<std::string,eos::types::Struct>& structs) {
const auto& obj = v.get_object();
structs.clear();
for( const auto& f : obj ) {
for(const auto& f : obj) {
auto& stru = structs[f.key()];
if( f.value().get_object().contains( "fields" ) )
fc::from_variant( f.value().get_object()["fields"], stru.fields );
if( f.value().get_object().contains( "base" ) )
fc::from_variant( f.value().get_object()["base"], stru.base );
if(f.value().get_object().contains("fields"))
fc::from_variant(f.value().get_object()["fields"], stru.fields);
if(f.value().get_object().contains("base"))
fc::from_variant(f.value().get_object()["base"], stru.base);
stru.name = f.key();
}
}
......
......@@ -11,13 +11,13 @@
int main( int argc, char** argv ) {
try {
eos::Message m;
m.sender = eos::AccountName( "ned" );
m.recipient = eos::AccountName( "dan" );
eos::types::Message m;
m.sender = eos::types::AccountName( "ned" );
m.recipient = eos::types::AccountName( "dan" );
idump( (m) );
eos::Transfer t;
eos::types::Transfer t;
t.from = m.sender;
t.to = "other";
......
......@@ -4,6 +4,7 @@
#include <fc/io/json.hpp>
using std::string;
namespace eos { using types::SimpleSymbolTable; }
bool isVector( const string& type ) {
......@@ -60,7 +61,7 @@ string call_type_constructor( const string& type ) {
return "Vector[" + getWrenType(type) + "]";
return getWrenType(type) + ".new()";
}
string generate_wren( const eos::Struct& s, eos::SimpleSymbolTable& symbols ) {
string generate_wren( const eos::types::Struct& s, eos::types::SimpleSymbolTable& symbols ) {
std::stringstream ss;
ss << "class " << s.name;
......@@ -98,15 +99,15 @@ string generate_wren( const eos::Struct& s, eos::SimpleSymbolTable& symbols ) {
return ss.str();
}
void generate_wren( eos::SimpleSymbolTable& ss, const char* outfile ) {
void generate_wren( eos::types::SimpleSymbolTable& ss, const char* outfile ) {
//for( const auto& s : ss.order )
}
void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) {
void generate_hpp( eos::types::SimpleSymbolTable& ss, const char* outfile ) {
wdump((outfile));
std::ofstream out(outfile);
out << "#pragma once\n";
out << "namespace eos { \n";
out << "namespace eos { namespace types {\n";
for( const auto& s : ss.order ) {
if( ss.typedefs.find( s ) != ss.typedefs.end() ) {
const auto& td = ss.typedefs[s];
......@@ -141,7 +142,7 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) {
}
out << "} // namespace eos \n";
out << "}} // namespace eos::types\n";
for( const auto& s : ss.order ) {
if( ss.typedefs.find( s ) != ss.typedefs.end() ) {
......@@ -150,9 +151,9 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) {
const auto& st = ss.structs[s];
if( st.base.size() ) {
out << "FC_REFLECT_DERIVED( eos::" << s << ", (eos::" << st.base <<"), ";
out << "FC_REFLECT_DERIVED( eos::types::" << s << ", (eos::types::" << st.base <<"), ";
} else {
out << "FC_REFLECT( eos::" << std::setw(33) << s << ", ";
out << "FC_REFLECT( eos::types::" << std::setw(33) << s << ", ";
}
for( const auto& f : st.fields ) {
out <<"("<<f.name<<")";
......@@ -162,7 +163,7 @@ void generate_hpp( eos::SimpleSymbolTable& ss, const char* outfile ) {
}
int count_fields( eos::SimpleSymbolTable& ss, const eos::Struct& st ) {
int count_fields( eos::types::SimpleSymbolTable& ss, const eos::types::Struct& st ) {
if( st.base.size() )
return st.fields.size() + count_fields( ss, ss.getType( st.base ) );
return st.fields.size();
......@@ -173,7 +174,7 @@ int main( int argc, char** argv ) {
FC_ASSERT( argc > 2, "Usage: ${program} input path/to/out.hpp", ("program",string(argv[0])) );
std::ifstream in(argv[1]);
eos::SimpleSymbolTable ss;
eos::types::SimpleSymbolTable ss;
ss.parse(in);
auto as_json = fc::json::to_pretty_string( ss );
......
#define EOS_ASSERT( expr, exc_type, FORMAT, ... ) \
FC_MULTILINE_MACRO_BEGIN \
if( !(expr) ) \
FC_THROW_EXCEPTION( exc_type, FORMAT, __VA_ARGS__ ); \
FC_MULTILINE_MACRO_END
#define EOS_DECLARE_OP_BASE_EXCEPTIONS( op_name ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _validate_exception, \
eos::chain::message_validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value, \
#op_name "_operation validation exception" \
) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _evaluate_exception, \
eos::chain::message_evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value, \
#op_name "_operation evaluation exception" \
)
#define EOS_DECLARE_OP_VALIDATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _ ## exc_name, \
eos::chain::op_name ## _validate_exception, \
3040000 + 100 * operation::tag< op_name ## _operation >::value \
+ seqnum, \
msg \
)
#define EOS_DECLARE_OP_EVALUATE_EXCEPTION( exc_name, op_name, seqnum, msg ) \
FC_DECLARE_DERIVED_EXCEPTION( \
op_name ## _ ## exc_name, \
eos::chain::op_name ## _evaluate_exception, \
3050000 + 100 * operation::tag< op_name ## _operation >::value \
+ seqnum, \
msg \
)
#define EOS_RECODE_EXC( cause_type, effect_type ) \
catch( const cause_type& e ) \
{ throw( effect_type( e.what(), e.get_log() ) ); }
......@@ -7,6 +7,7 @@
namespace eos {
using namespace chain;
using namespace types;
class native_system_contract_plugin_impl {
public:
......
......@@ -39,6 +39,7 @@
using namespace eos;
using namespace chain;
using namespace types;
BOOST_AUTO_TEST_SUITE(block_tests)
......@@ -154,7 +155,7 @@ BOOST_FIXTURE_TEST_CASE(create_script, testing_fixture)
const auto& processor = db.get<account_object,by_name>("init1");
const auto& recipient = db.get<account_object,by_name>("sys");
const auto& world = db.get<key_value_object,by_scope_key>( boost::make_tuple( AccountName("init1"), eos::String("hello") ) );
const auto& world = db.get<key_value_object,by_scope_key>(boost::make_tuple(AccountName("init1"), String("hello")));
BOOST_CHECK_EQUAL( string(world.value.c_str()), "world" );
} FC_LOG_AND_RETHROW() }
......
#include <eos/types/TypeParser.hpp>
#include <boost/test/unit_test.hpp>
namespace eos { namespace types {
BOOST_AUTO_TEST_SUITE(types_tests)
/// Put the SimpleSymbolTable through its paces
BOOST_AUTO_TEST_CASE(basic_simple_symbol_table_test)
{ try {
SimpleSymbolTable table;
BOOST_CHECK_THROW(table.addType({"testtype", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"test type", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Testtype[]", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Testtype]", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Testtype[", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Test[]type", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Test]type", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Test[type", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Test!type", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"!Testtype", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"!testtype", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Testtype!", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"_Testtype", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Testtype_", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"Test_type", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"0Testtype", "", {{"f1", "String"}}}), invalid_type_name_exception);
BOOST_CHECK_THROW(table.addType({"0testtype", "", {{"f1", "String"}}}), invalid_type_name_exception);
table.addType({"Testtype", "", {{"f1", "String"}}});
table.addType({"Testtype1", "", {{"f1", "String"}}});
table.addType({"Test2type", "", {{"f1", "String"}}});
BOOST_CHECK_THROW(table.addType({"Testtype", "", {{"f1", "String"}}}), duplicate_type_exception);
BOOST_CHECK_THROW(table.addTypeDef("Testtype", "Testtype"), duplicate_type_exception);
BOOST_CHECK_THROW(table.addTypeDef("Testtype5", "NewType"), unknown_type_exception);
table.addTypeDef("Testtype", "TestType");
BOOST_CHECK_THROW(table.addTypeDef("Testtype", "TestType"), duplicate_type_exception);
table.addTypeDef("Testtype[]", "TestTypeArray");
BOOST_CHECK_THROW(table.addTypeDef("Testtype", "NewType[]"), invalid_type_name_exception);
BOOST_CHECK(table.isKnownType("Testtype"));
BOOST_CHECK(table.isKnownType("Testtype1"));
BOOST_CHECK(table.isKnownType("Test2type"));
BOOST_CHECK(table.isKnownType("TestType"));
BOOST_CHECK(table.isKnownType("Testtype[]"));
BOOST_CHECK(table.isKnownType("TestTypeArray"));
BOOST_CHECK(!table.isKnownType("Testtype5"));
BOOST_CHECK(!table.isKnownType("NewType"));
BOOST_CHECK(!table.isKnownType("NewType[]"));
BOOST_CHECK_THROW(table.addType({"Foo", "Bar", {{"f1", "String"}}}), unknown_type_exception);
BOOST_CHECK_THROW(table.addType({"Foo", "Foo", {{"f1", "String"}}}), unknown_type_exception);
BOOST_CHECK_THROW(table.addType({"Foo", "", {{"f1", "Bar"}}}), unknown_type_exception);
BOOST_CHECK_THROW(table.addType({"Foo", "", {{"f1", "Foo"}}}), unknown_type_exception);
table.addType({"Foo", "", {{"f1", "String"}}});
table.addType({"FooBar", "Foo", {{"f2", "Int32"}}});
BOOST_CHECK(table.isKnownType("Foo"));
BOOST_CHECK(table.isKnownType("FooBar"));
BOOST_CHECK_THROW(table.addType({"Bar", "", {{"f1", "Struct"}}}), unknown_type_exception);
} FC_LOG_AND_RETHROW() }
BOOST_AUTO_TEST_SUITE_END()
}} // namespace eos::types
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册