提交 914cb0fc 编写于 作者: A Anton Perkov

Merge branch 'cleos-msig-propose-transaction' of github.com:EOSIO/eos into...

Merge branch 'cleos-msig-propose-transaction' of github.com:EOSIO/eos into cleos-msig-propose-transaction
...@@ -60,7 +60,7 @@ RUN git clone --depth 1 https://github.com/cryptonomex/secp256k1-zkp \ ...@@ -60,7 +60,7 @@ RUN git clone --depth 1 https://github.com/cryptonomex/secp256k1-zkp \
&& make -j$(nproc) install \ && make -j$(nproc) install \
&& cd .. && rm -rf secp256k1-zkp && cd .. && rm -rf secp256k1-zkp
RUN git clone --depth 1 -b releases/stable https://github.com/mongodb/mongo-cxx-driver \ RUN git clone --depth 1 -b releases/v3.2 https://github.com/mongodb/mongo-cxx-driver \
&& cd mongo-cxx-driver \ && cd mongo-cxx-driver \
&& cmake -H. -Bbuild -G Ninja -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local\ && cmake -H. -Bbuild -G Ninja -DBUILD_SHARED_LIBS=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local\
&& cmake --build build --target install \ && cmake --build build --target install \
......
...@@ -9,14 +9,14 @@ extern "C" { ...@@ -9,14 +9,14 @@ extern "C" {
/** /**
* @defgroup actionapi Action API * @defgroup actionapi Action API
* @ingroup contractdev * @ingroup contractdev
* @brief Define API for querying action properties * @brief Defines API for for querying action and sending action
* *
*/ */
/** /**
* @defgroup actioncapi Action C API * @defgroup actioncapi Action C API
* @ingroup actionapi * @ingroup actionapi
* @brief Define API for querying action properties * @brief Defines API for querying action and sending action
* *
* *
* A EOS.IO action has the following abstract structure: * A EOS.IO action has the following abstract structure:
...@@ -68,16 +68,19 @@ extern "C" { ...@@ -68,16 +68,19 @@ extern "C" {
/** /**
* Copy up to @ref len bytes of current action data to the specified location * Copy up to @ref len bytes of current action data to the specified location
*
* @brief Copy current action data to the specified location * @brief Copy current action data to the specified location
* @param msg - a pointer where up to @ref len bytes of the current action data will be copied * @param msg - a pointer where up to @ref len bytes of the current action data will be copied
* @param len - len of the current action data to be copied, 0 to report required size * @param len - len of the current action data to be copied, 0 to report required size
* @return the number of bytes copied to msg, or number of bytes that can be copied if len==0 passed * @return the number of bytes copied to msg, or number of bytes that can be copied if len==0 passed
* @pre `msg` is a valid pointer to a range of memory at least `len` bytes long
* @post `msg` is filled with packed action data
*/ */
uint32_t read_action_data( void* msg, uint32_t len ); uint32_t read_action_data( void* msg, uint32_t len );
/** /**
* Get the length of the current action's data field * Get the length of the current action's data field. This method is useful for dynamically sized actions
* This method is useful for dynamically sized actions *
* @brief Get the length of current action's data field * @brief Get the length of current action's data field
* @return the length of the current action's data field * @return the length of the current action's data field
*/ */
...@@ -85,21 +88,31 @@ extern "C" { ...@@ -85,21 +88,31 @@ extern "C" {
/** /**
* Add the specified account to set of accounts to be notified * Add the specified account to set of accounts to be notified
*
* @brief Add the specified account to set of accounts to be notified * @brief Add the specified account to set of accounts to be notified
* @param name - name of the account to be verified * @param name - name of the account to be verified
*/ */
void require_recipient( account_name name ); void require_recipient( account_name name );
/** /**
* Verifies that @ref name exists in the set of provided auths on a action. Throws if not found * Verifies that @ref name exists in the set of provided auths on a action. Throws if not found.
*
* @brief Verify specified account exists in the set of provided auths * @brief Verify specified account exists in the set of provided auths
* @param name - name of the account to be verified * @param name - name of the account to be verified
*/ */
void require_auth( account_name name ); void require_auth( account_name name );
/**
* Verifies that @ref name has auth.
*
* @brief Verifies that @ref name has auth.
* @param name - name of the account to be verified
*/
bool has_auth( account_name name ); bool has_auth( account_name name );
/** /**
* Verifies that @ref name exists in the set of provided auths on a action. Throws if not found * Verifies that @ref name exists in the set of provided auths on a action. Throws if not found.
*
* @brief Verify specified account exists in the set of provided auths * @brief Verify specified account exists in the set of provided auths
* @param name - name of the account to be verified * @param name - name of the account to be verified
* @param permission - permission level to be verified * @param permission - permission level to be verified
...@@ -110,15 +123,19 @@ extern "C" { ...@@ -110,15 +123,19 @@ extern "C" {
/** /**
* Send an inline action in the context of this action's parent transaction * Send an inline action in the context of this action's parent transaction
*
* @param serialized_action - serialized action * @param serialized_action - serialized action
* @param size - size of serialized action in bytes * @param size - size of serialized action in bytes
* @pre `serialized_action` is a valid pointer to an array at least `size` bytes long
*/ */
void send_inline(char *serialized_action, size_t size); void send_inline(char *serialized_action, size_t size);
/** /**
* Send an inline context free action in the context of this action's parent transaction * Send an inline context free action in the context of this action's parent transaction
*
* @param serialized_action - serialized action * @param serialized_action - serialized action
* @param size - size of serialized action in bytes * @param size - size of serialized action in bytes
* @pre `serialized_action` is a valid pointer to an array at least `size` bytes long
*/ */
void send_context_free_inline(char *serialized_action, size_t size); void send_context_free_inline(char *serialized_action, size_t size);
......
...@@ -17,7 +17,7 @@ namespace eosio { ...@@ -17,7 +17,7 @@ namespace eosio {
/** /**
* @defgroup actioncppapi Action C++ API * @defgroup actioncppapi Action C++ API
* @ingroup actionapi * @ingroup actionapi
* @brief Type-safe C++ wrapers for Action C API * @brief Defines type-safe C++ wrapers for querying action and sending action
* *
* @note There are some methods from the @ref actioncapi that can be used directly from C++ * @note There are some methods from the @ref actioncapi that can be used directly from C++
* *
...@@ -28,9 +28,11 @@ namespace eosio { ...@@ -28,9 +28,11 @@ namespace eosio {
* *
* This method unpacks the current action at type T. * This method unpacks the current action at type T.
* *
* @brief Interpret the action body as type T * @brief Interpret the action body as type T.
* @return Unpacked action data casted as T.
* *
* Example: * Example:
*
* @code * @code
* struct dummy_action { * struct dummy_action {
* char a; //1 * char a; //1
...@@ -62,9 +64,12 @@ namespace eosio { ...@@ -62,9 +64,12 @@ namespace eosio {
* *
* @note action.code is also considered as part of the set of notified accounts * @note action.code is also considered as part of the set of notified accounts
* *
* @brief Verify specified accounts exist in the set of notified accounts * @brief Notify an account for this action
* @param name account to be notified
* @param remaining_accounts accounts to be notified
* *
* Example: * Example:
*
* @code * @code
* require_recipient(N(Account1), N(Account2), N(Account3)); // throws exception if any of them not in set. * require_recipient(N(Account1), N(Account2), N(Account3)); // throws exception if any of them not in set.
* @endcode * @endcode
...@@ -75,13 +80,50 @@ namespace eosio { ...@@ -75,13 +80,50 @@ namespace eosio {
require_recipient( remaining_accounts... ); require_recipient( remaining_accounts... );
} }
/**
* Packed representation of a permission level (Authorization)
*
* @brief Packed representation of a permission level (Authorization)
*/
struct permission_level { struct permission_level {
/**
* Construct a new permission level object with actor name and permission name
*
* @brief Construct a new permission level object
* @param a - Name of the account who owns this authorization
* @param p - Name of the permission
*/
permission_level( account_name a, permission_name p ):actor(a),permission(p){} permission_level( account_name a, permission_name p ):actor(a),permission(p){}
/**
* Default Constructor
*
* @brief Construct a new permission level object
*/
permission_level(){} permission_level(){}
/**
* Name of the account who owns this permission
*
* @brief Name of the account who owns this permission
*/
account_name actor; account_name actor;
/**
* Name of the permission
*
* @brief Name of the permission
*/
permission_name permission; permission_name permission;
/**
* Check equality of two permissions
*
* @brief Check equality of two permissions
* @param a - first permission to compare
* @param b - second permission to compare
* @return true if equal
* @return false if unequal
*/
friend bool operator == ( const permission_level& a, const permission_level& b ) { friend bool operator == ( const permission_level& a, const permission_level& b ) {
return std::tie( a.actor, a.permission ) == std::tie( b.actor, b.permission ); return std::tie( a.actor, a.permission ) == std::tie( b.actor, b.permission );
} }
...@@ -89,6 +131,13 @@ namespace eosio { ...@@ -89,6 +131,13 @@ namespace eosio {
EOSLIB_SERIALIZE( permission_level, (actor)(permission) ) EOSLIB_SERIALIZE( permission_level, (actor)(permission) )
}; };
/**
* Require the specified authorization for this action. If this action doesn't contain the specified auth, it will fail.
*
* @brief Require the specified authorization for this action
*
* @param level - Authorization to be required
*/
void require_auth(const permission_level& level) { void require_auth(const permission_level& level) {
require_auth2( level.actor, level.permission ); require_auth2( level.actor, level.permission );
} }
...@@ -96,18 +145,52 @@ namespace eosio { ...@@ -96,18 +145,52 @@ namespace eosio {
/** /**
* This is the packed representation of an action along with * This is the packed representation of an action along with
* meta-data about the authorization levels. * meta-data about the authorization levels.
*
* @brief Packed representation of an action
*/ */
struct action { struct action {
/**
* Name of the account the action is intended for
*
* @brief Name of the account the action is intended for
*/
account_name account; account_name account;
/**
* Name of the action
*
* @brief Name of the action
*/
action_name name; action_name name;
/**
* List of permissions that authorize this action
*
* @brief List of permissions that authorize this action
*/
vector<permission_level> authorization; vector<permission_level> authorization;
/**
* Payload data
*
* @brief Payload data
*/
bytes data; bytes data;
/**
* Default Constructor
*
* @brief Construct a new action object
*/
action() = default; action() = default;
/** /**
* @tparam Action - a type derived from action_meta<Scope,Name> * Construct a new action object with the given permission and action struct
* @param value - will be serialized via pack into data *
* @brief Construct a new action object with the given permission and action struct
* @tparam Action - Type of action struct
* @param auth - The permission that authorizes this action
* @param value - The action struct that will be serialized via pack into data
*/ */
template<typename Action> template<typename Action>
action( vector<permission_level>&& auth, const Action& value ) { action( vector<permission_level>&& auth, const Action& value ) {
...@@ -118,8 +201,12 @@ namespace eosio { ...@@ -118,8 +201,12 @@ namespace eosio {
} }
/** /**
* @tparam Action - a type derived from action_meta<Scope,Name> * Construct a new action object with the given list of permissions and action struct
* @param value - will be serialized via pack into data *
* @brief Construct a new action object with the given list of permissions and action struct
* @tparam Action - Type of action struct
* @param auth - The list of permissions that authorizes this action
* @param value - The action struct that will be serialized via pack into data
*/ */
template<typename Action> template<typename Action>
action( const permission_level& auth, const Action& value ) action( const permission_level& auth, const Action& value )
...@@ -129,9 +216,13 @@ namespace eosio { ...@@ -129,9 +216,13 @@ namespace eosio {
data = pack(value); data = pack(value);
} }
/** /**
* @tparam Action - a type derived from action_meta<Scope,Name> * Construct a new action object with the given action struct
* @param value - will be serialized via pack into data *
* @brief Construct a new action object with the given action struct
* @tparam Action - Type of action struct
* @param value - The action struct that will be serialized via pack into data
*/ */
template<typename Action> template<typename Action>
action( const Action& value ) { action( const Action& value ) {
...@@ -141,22 +232,28 @@ namespace eosio { ...@@ -141,22 +232,28 @@ namespace eosio {
} }
/** /**
* @tparam T - the type of the action data * Construct a new action object with the given action struct
* @param auth - a single permission_level to be used as the authorization of the action *
* @param a - name of the contract account * @brief Construct a new action object with the given permission, action receiver, action name, action struct
* @param n - name of the action * @tparam T - Type of action struct
* @param value - will be serialized via pack into data * @param auth - The permissions that authorizes this action
* @param a - The name of the account this action is intended for (action receiver)
* @param n - The name of the action
* @param value - The action struct that will be serialized via pack into data
*/ */
template<typename T> template<typename T>
action( const permission_level& auth, account_name a, action_name n, T&& value ) action( const permission_level& auth, account_name a, action_name n, T&& value )
:account(a), name(n), authorization(1,auth), data(pack(std::forward<T>(value))) {} :account(a), name(n), authorization(1,auth), data(pack(std::forward<T>(value))) {}
/** /**
* @tparam T - the type of the action data * Construct a new action object with the given action struct
* @param auths - vector permission_levels defining the authorizations of the action *
* @param a - name of the contract account * @brief Construct a new action object with the given list of permissions, action receiver, action name, action struct
* @param n - name of the action * @tparam T - Type of action struct
* @param value - will be serialized via pack into data * @param auths - The list of permissions that authorize this action
* @param a - The name of the account this action is intended for (action receiver)
* @param n - The name of the action
* @param value - The action struct that will be serialized via pack into data
*/ */
template<typename T> template<typename T>
action( vector<permission_level> auths, account_name a, action_name n, T&& value ) action( vector<permission_level> auths, account_name a, action_name n, T&& value )
...@@ -164,11 +261,22 @@ namespace eosio { ...@@ -164,11 +261,22 @@ namespace eosio {
EOSLIB_SERIALIZE( action, (account)(name)(authorization)(data) ) EOSLIB_SERIALIZE( action, (account)(name)(authorization)(data) )
/**
* Send the action as inline action
*
* @brief Send the action as inline action
*/
void send() const { void send() const {
auto serialize = pack(*this); auto serialize = pack(*this);
::send_inline(serialize.data(), serialize.size()); ::send_inline(serialize.data(), serialize.size());
} }
/**
* Send the action as inline context free action
*
* @brief Send the action as inline context free action
* @pre This action should not contain any authorizations
*/
void send_context_free() const { void send_context_free() const {
eosio_assert( authorization.size() == 0, "context free actions cannot have authorizations"); eosio_assert( authorization.size() == 0, "context free actions cannot have authorizations");
auto serialize = pack(*this); auto serialize = pack(*this);
...@@ -177,6 +285,8 @@ namespace eosio { ...@@ -177,6 +285,8 @@ namespace eosio {
/** /**
* Retrieve the unpacked data as T * Retrieve the unpacked data as T
*
* @brief Retrieve the unpacked data as T
* @tparam T expected type of data * @tparam T expected type of data
* @return the action data * @return the action data
*/ */
...@@ -189,12 +299,33 @@ namespace eosio { ...@@ -189,12 +299,33 @@ namespace eosio {
}; };
/**
* Base class to derive a new defined action from so it can take advantage of the dispatcher
*
* @brief Base class to derive a new defined action from
* @tparam Account - The account this action is intended for
* @tparam Name - The name of the action
*/
template<uint64_t Account, uint64_t Name> template<uint64_t Account, uint64_t Name>
struct action_meta { struct action_meta {
/**
* Get the account this action is intended for
*
* @brief Get the account this action is intended for
* @return uint64_t The account this action is intended for
*/
static uint64_t get_account() { return Account; } static uint64_t get_account() { return Account; }
/**
* Get the name of this action
*
* @brief Get the name of this action
* @return uint64_t Name of the action
*/
static uint64_t get_name() { return Name; } static uint64_t get_name() { return Name; }
}; };
///@} actioncpp api
template<typename... Args> template<typename... Args>
void dispatch_inline( account_name code, action_name act, void dispatch_inline( account_name code, action_name act,
vector<permission_level> perms, vector<permission_level> perms,
...@@ -202,9 +333,11 @@ namespace eosio { ...@@ -202,9 +333,11 @@ namespace eosio {
action( perms, code, act, std::move(args) ).send(); action( perms, code, act, std::move(args) ).send();
} }
template<typename, uint64_t> template<typename, uint64_t>
struct inline_dispatcher; struct inline_dispatcher;
template<typename T, uint64_t Name, typename... Args> template<typename T, uint64_t Name, typename... Args>
struct inline_dispatcher<void(T::*)(Args...), Name> { struct inline_dispatcher<void(T::*)(Args...), Name> {
static void call(account_name code, const permission_level& perm, std::tuple<Args...> args) { static void call(account_name code, const permission_level& perm, std::tuple<Args...> args) {
...@@ -215,7 +348,6 @@ namespace eosio { ...@@ -215,7 +348,6 @@ namespace eosio {
} }
}; };
///@} actioncpp api
} // namespace eosio } // namespace eosio
...@@ -227,9 +359,31 @@ INLINE_ACTION_SENDER3( CONTRACT_CLASS, NAME, ::eosio::string_to_name(#NAME) ) ...@@ -227,9 +359,31 @@ INLINE_ACTION_SENDER3( CONTRACT_CLASS, NAME, ::eosio::string_to_name(#NAME) )
#define INLINE_ACTION_SENDER(...) BOOST_PP_OVERLOAD(INLINE_ACTION_SENDER,__VA_ARGS__)(__VA_ARGS__) #define INLINE_ACTION_SENDER(...) BOOST_PP_OVERLOAD(INLINE_ACTION_SENDER,__VA_ARGS__)(__VA_ARGS__)
/**
* @addtogroup actioncppapi
* Additional documentation for group
* @{
*/
/**
* Send inline action
*
* @brief Send inline action
* @param CONTRACT - The account this action is intended for
* @param NAME - The name of the action
* @param ... - The member of the action specified as ("action_member1_name", action_member1_value)("action_member2_name", action_member2_value)
*/
#define SEND_INLINE_ACTION( CONTRACT, NAME, ... )\ #define SEND_INLINE_ACTION( CONTRACT, NAME, ... )\
INLINE_ACTION_SENDER(std::decay_t<decltype(CONTRACT)>, NAME)( (CONTRACT).get_self(),\ INLINE_ACTION_SENDER(std::decay_t<decltype(CONTRACT)>, NAME)( (CONTRACT).get_self(),\
BOOST_PP_TUPLE_ENUM(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__)) ); BOOST_PP_TUPLE_ENUM(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), BOOST_PP_VARIADIC_TO_TUPLE(__VA_ARGS__)) );
/**
* Extend a new defined action with theaction meta, so it can work with the dispatcher
*
* @brief Extend a new defined action with the action meta
* @param CODE - The account this action is intended for
* @param NAME - The name of the action
*/
#define ACTION( CODE, NAME ) struct NAME : ::eosio::action_meta<CODE, ::eosio::string_to_name(#NAME) > #define ACTION( CODE, NAME ) struct NAME : ::eosio::action_meta<CODE, ::eosio::string_to_name(#NAME) >
/// @}
...@@ -8,12 +8,54 @@ ...@@ -8,12 +8,54 @@
namespace eosio { namespace eosio {
/**
* @defgroup assetapi Asset API
* @brief Defines API for managing assets
* @ingroup contractdev
*/
/**
* @defgroup assetcppapi Asset CPP API
* @brief Defines %CPP API for managing assets
* @ingroup assetapi
* @{
*/
/**
* \struct Stores information for owner of asset
*
* @brief Stores information for owner of asset
*/
struct asset { struct asset {
/**
* The amount of the asset
*
* @brief The amount of the asset
*/
int64_t amount; int64_t amount;
/**
* The symbol name of the asset
*
* @brief The symbol name of the asset
*/
symbol_type symbol; symbol_type symbol;
/**
* Maximum amount possible for this asset. It's capped to 2^62 - 1
*
* @brief Maximum amount possible for this asset
*/
static constexpr int64_t max_amount = (1LL << 62) - 1; static constexpr int64_t max_amount = (1LL << 62) - 1;
/**
* Construct a new asset given the symbol name and the amount
*
* @brief Construct a new asset object
* @param a - The amount of the asset
* @param s - THe name of the symbol, default to CORE_SYMBOL
*/
explicit asset( int64_t a = 0, symbol_type s = CORE_SYMBOL ) explicit asset( int64_t a = 0, symbol_type s = CORE_SYMBOL )
:amount(a),symbol{s} :amount(a),symbol{s}
{ {
...@@ -21,20 +63,55 @@ namespace eosio { ...@@ -21,20 +63,55 @@ namespace eosio {
eosio_assert( symbol.is_valid(), "invalid symbol name" ); eosio_assert( symbol.is_valid(), "invalid symbol name" );
} }
/**
* Check if the amount doesn't exceed the max amount
*
* @brief Check if the amount doesn't exceed the max amount
* @return true - if the amount doesn't exceed the max amount
* @return false - otherwise
*/
bool is_amount_within_range()const { return -max_amount <= amount && amount <= max_amount; } bool is_amount_within_range()const { return -max_amount <= amount && amount <= max_amount; }
/**
* Check if the asset is valid. %A valid asset has its amount <= max_amount and its symbol name valid
*
* @brief Check if the asset is valid
* @return true - if the asset is valid
* @return false - otherwise
*/
bool is_valid()const { return is_amount_within_range() && symbol.is_valid(); } bool is_valid()const { return is_amount_within_range() && symbol.is_valid(); }
/**
* Set the amount of the asset
*
* @brief Set the amount of the asset
* @param a - New amount for the asset
*/
void set_amount( int64_t a ) { void set_amount( int64_t a ) {
amount = a; amount = a;
eosio_assert( is_amount_within_range(), "magnitude of asset amount must be less than 2^62" ); eosio_assert( is_amount_within_range(), "magnitude of asset amount must be less than 2^62" );
} }
/**
* Unary minus operator
*
* @brief Unary minus operator
* @return asset - New asset with its amount is the negative amount of this asset
*/
asset operator-()const { asset operator-()const {
asset r = *this; asset r = *this;
r.amount = -r.amount; r.amount = -r.amount;
return r; return r;
} }
/**
* Subtraction assignment operator
*
* @brief Subtraction assignment operator
* @param a - Another asset to subtract this asset with
* @return asset& - Reference to this asset
* @post The amount of this asset is subtracted by the amount of asset a
*/
asset& operator-=( const asset& a ) { asset& operator-=( const asset& a ) {
eosio_assert( a.symbol == symbol, "attempt to subtract asset with different symbol" ); eosio_assert( a.symbol == symbol, "attempt to subtract asset with different symbol" );
amount -= a.amount; amount -= a.amount;
...@@ -43,6 +120,14 @@ namespace eosio { ...@@ -43,6 +120,14 @@ namespace eosio {
return *this; return *this;
} }
/**
* Addition Assignment operator
*
* @brief Addition Assignment operator
* @param a - Another asset to subtract this asset with
* @return asset& - Reference to this asset
* @post The amount of this asset is added with the amount of asset a
*/
asset& operator+=( const asset& a ) { asset& operator+=( const asset& a ) {
eosio_assert( a.symbol == symbol, "attempt to add asset with different symbol" ); eosio_assert( a.symbol == symbol, "attempt to add asset with different symbol" );
amount += a.amount; amount += a.amount;
...@@ -51,18 +136,42 @@ namespace eosio { ...@@ -51,18 +136,42 @@ namespace eosio {
return *this; return *this;
} }
/**
* Addition operator
*
* @brief Addition operator
* @param a - The first asset to be added
* @param b - The second asset to be added
* @return asset - New asset as the result of addition
*/
inline friend asset operator+( const asset& a, const asset& b ) { inline friend asset operator+( const asset& a, const asset& b ) {
asset result = a; asset result = a;
result += b; result += b;
return result; return result;
} }
/**
* Subtraction operator
*
* @brief Subtraction operator
* @param a - The asset to be subtracted
* @param b - The asset used to subtract
* @return asset - New asset as the result of subtraction of a with b
*/
inline friend asset operator-( const asset& a, const asset& b ) { inline friend asset operator-( const asset& a, const asset& b ) {
asset result = a; asset result = a;
result -= b; result -= b;
return result; return result;
} }
/**
* Multiplication assignment operator. Multiply the amount of this asset with a number and then assign the value to itself.
*
* @brief Multiplication assignment operator, with a number
* @param a - The multiplier for the asset's amount
* @return asset - Reference to this asset
* @post The amount of this asset is multiplied by a
*/
asset& operator*=( int64_t a ) { asset& operator*=( int64_t a ) {
eosio_assert( a == 0 || (amount * a) / a == amount, "multiplication overflow or underflow" ); eosio_assert( a == 0 || (amount * a) / a == amount, "multiplication overflow or underflow" );
eosio_assert( -max_amount <= amount, "multiplication underflow" ); eosio_assert( -max_amount <= amount, "multiplication underflow" );
...@@ -71,63 +180,170 @@ namespace eosio { ...@@ -71,63 +180,170 @@ namespace eosio {
return *this; return *this;
} }
/**
* Multiplication operator, with a number proceeding
*
* @brief Multiplication operator, with a number proceeding
* @param a - The asset to be multiplied
* @param b - The multiplier for the asset's amount
* @return asset - New asset as the result of multiplication
*/
friend asset operator*( const asset& a, int64_t b ) { friend asset operator*( const asset& a, int64_t b ) {
asset result = a; asset result = a;
result *= b; result *= b;
return result; return result;
} }
/**
* Multiplication operator, with a number preceeding
*
* @brief Multiplication operator, with a number preceeding
* @param a - The multiplier for the asset's amount
* @param b - The asset to be multiplied
* @return asset - New asset as the result of multiplication
*/
friend asset operator*( int64_t b, const asset& a ) { friend asset operator*( int64_t b, const asset& a ) {
asset result = a; asset result = a;
result *= b; result *= b;
return result; return result;
} }
/**
* Division assignment operator. Divide the amount of this asset with a number and then assign the value to itself.
*
* @brief Division assignment operator, with a number
* @param a - The divisor for the asset's amount
* @return asset - Reference to this asset
* @post The amount of this asset is divided by a
*/
asset& operator/=( int64_t a ) { asset& operator/=( int64_t a ) {
amount /= a; amount /= a;
return *this; return *this;
} }
/**
* Division operator, with a number proceeding
*
* @brief Division operator, with a number proceeding
* @param a - The asset to be divided
* @param b - The divisor for the asset's amount
* @return asset - New asset as the result of division
*/
friend asset operator/( const asset& a, int64_t b ) { friend asset operator/( const asset& a, int64_t b ) {
asset result = a; asset result = a;
result /= b; result /= b;
return result; return result;
} }
/**
* Division operator, with another asset
*
* @brief Division operator, with another asset
* @param a - The asset which amount acts as the dividend
* @param b - The asset which amount acts as the divisor
* @return int64_t - the resulted amount after the division
* @pre Both asset must have the same symbol
*/
friend int64_t operator/( const asset& a, const asset& b ) { friend int64_t operator/( const asset& a, const asset& b ) {
eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" ); eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" );
return a.amount / b.amount; return a.amount / b.amount;
} }
/**
* Equality operator
*
* @brief Equality operator
* @param a - The first asset to be compared
* @param b - The second asset to be compared
* @return true - if both asset has the same amount
* @return false - otherwise
* @pre Both asset must have the same symbol
*/
friend bool operator==( const asset& a, const asset& b ) { friend bool operator==( const asset& a, const asset& b ) {
eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" ); eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" );
return a.amount == b.amount; return a.amount == b.amount;
} }
/**
* Inequality operator
*
* @brief Inequality operator
* @param a - The first asset to be compared
* @param b - The second asset to be compared
* @return true - if both asset doesn't have the same amount
* @return false - otherwise
* @pre Both asset must have the same symbol
*/
friend bool operator!=( const asset& a, const asset& b ) { friend bool operator!=( const asset& a, const asset& b ) {
return !( a == b); return !( a == b);
} }
/**
* Less than operator
*
* @brief Less than operator
* @param a - The first asset to be compared
* @param b - The second asset to be compared
* @return true - if the first asset's amount is less than the second asset amount
* @return false - otherwise
* @pre Both asset must have the same symbol
*/
friend bool operator<( const asset& a, const asset& b ) { friend bool operator<( const asset& a, const asset& b ) {
eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" ); eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" );
return a.amount < b.amount; return a.amount < b.amount;
} }
/**
* Less or equal to operator
*
* @brief Less or equal to operator
* @param a - The first asset to be compared
* @param b - The second asset to be compared
* @return true - if the first asset's amount is less or equal to the second asset amount
* @return false - otherwise
* @pre Both asset must have the same symbol
*/
friend bool operator<=( const asset& a, const asset& b ) { friend bool operator<=( const asset& a, const asset& b ) {
eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" ); eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" );
return a.amount <= b.amount; return a.amount <= b.amount;
} }
/**
* Greater than operator
*
* @brief Greater than operator
* @param a - The first asset to be compared
* @param b - The second asset to be compared
* @return true - if the first asset's amount is greater than the second asset amount
* @return false - otherwise
* @pre Both asset must have the same symbol
*/
friend bool operator>( const asset& a, const asset& b ) { friend bool operator>( const asset& a, const asset& b ) {
eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" ); eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" );
return a.amount > b.amount; return a.amount > b.amount;
} }
/**
* Greater or equal to operator
*
* @brief Greater or equal to operator
* @param a - The first asset to be compared
* @param b - The second asset to be compared
* @return true - if the first asset's amount is greater or equal to the second asset amount
* @return false - otherwise
* @pre Both asset must have the same symbol
*/
friend bool operator>=( const asset& a, const asset& b ) { friend bool operator>=( const asset& a, const asset& b ) {
eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" ); eosio_assert( a.symbol == b.symbol, "comparison of assets with different symbols is not allowed" );
return a.amount >= b.amount; return a.amount >= b.amount;
} }
/**
* %Print the asset
*
* @brief %Print the asset
*/
void print()const { void print()const {
int64_t p = (int64_t)symbol.precision(); int64_t p = (int64_t)symbol.precision();
int64_t p10 = 1; int64_t p10 = 1;
...@@ -154,30 +370,93 @@ namespace eosio { ...@@ -154,30 +370,93 @@ namespace eosio {
EOSLIB_SERIALIZE( asset, (amount)(symbol) ) EOSLIB_SERIALIZE( asset, (amount)(symbol) )
}; };
/**
* \struct Extended asset which stores the information of the owner of the asset
*
* @brief Extended asset which stores the information of the owner of the asset
*/
struct extended_asset : public asset { struct extended_asset : public asset {
/**
* The owner of the asset
*
* @brief The owner of the asset
*/
account_name contract; account_name contract;
/**
* Get the extended symbol of the asset
*
* @brief Get the extended symbol of the asset
* @return extended_symbol - The extended symbol of the asset
*/
extended_symbol get_extended_symbol()const { return extended_symbol( symbol, contract ); } extended_symbol get_extended_symbol()const { return extended_symbol( symbol, contract ); }
/**
* Default constructor
*
* @brief Construct a new extended asset object
*/
extended_asset() = default; extended_asset() = default;
/**
* Construct a new extended asset given the amount and extended symbol
*
* @brief Construct a new extended asset object
*/
extended_asset( int64_t v, extended_symbol s ):asset(v,s),contract(s.contract){} extended_asset( int64_t v, extended_symbol s ):asset(v,s),contract(s.contract){}
/**
* Construct a new extended asset given the asset and owner name
*
* @brief Construct a new extended asset object
*/
extended_asset( asset a, account_name c ):asset(a),contract(c){} extended_asset( asset a, account_name c ):asset(a),contract(c){}
/**
* %Print the extended asset
*
* @brief %Print the extended asset
*/
void print()const { void print()const {
asset::print(); asset::print();
prints("@"); prints("@");
printn(contract); printn(contract);
} }
/**
* Unary minus operator
*
* @brief Unary minus operator
* @return extended_asset - New extended asset with its amount is the negative amount of this extended asset
*/
extended_asset operator-()const { extended_asset operator-()const {
asset r = this->asset::operator-(); asset r = this->asset::operator-();
return {r, contract}; return {r, contract};
} }
/**
* Subtraction operator. This subtracts the amount of the extended asset.
*
* @brief Subtraction operator
* @param a - The extended asset to be subtracted
* @param b - The extended asset used to subtract
* @return extended_asset - New extended asset as the result of subtraction
* @pre The owner of both extended asset need to be the same
*/
friend extended_asset operator - ( const extended_asset& a, const extended_asset& b ) { friend extended_asset operator - ( const extended_asset& a, const extended_asset& b ) {
eosio_assert( a.contract == b.contract, "type mismatch" ); eosio_assert( a.contract == b.contract, "type mismatch" );
asset r = static_cast<const asset&>(a) - static_cast<const asset&>(b); asset r = static_cast<const asset&>(a) - static_cast<const asset&>(b);
return {r, a.contract}; return {r, a.contract};
} }
/**
* Addition operator. This adds the amount of the extended asset.
*
* @brief Addition operator
* @param a - The extended asset to be added
* @param b - The extended asset to be added
* @return extended_asset - New extended asset as the result of addition
* @pre The owner of both extended asset need to be the same
*/
friend extended_asset operator + ( const extended_asset& a, const extended_asset& b ) { friend extended_asset operator + ( const extended_asset& a, const extended_asset& b ) {
eosio_assert( a.contract == b.contract, "type mismatch" ); eosio_assert( a.contract == b.contract, "type mismatch" );
asset r = static_cast<const asset&>(a) + static_cast<const asset&>(b); asset r = static_cast<const asset&>(a) + static_cast<const asset&>(b);
...@@ -187,5 +466,5 @@ namespace eosio { ...@@ -187,5 +466,5 @@ namespace eosio {
EOSLIB_SERIALIZE( extended_asset, (amount)(symbol)(contract) ) EOSLIB_SERIALIZE( extended_asset, (amount)(symbol)(contract) )
}; };
/// @} asset type
} /// namespace eosio } /// namespace eosio
...@@ -8,25 +8,31 @@ ...@@ -8,25 +8,31 @@
/** /**
* @defgroup chainapi Chain API * @defgroup chainapi Chain API
* @brief Define API for querying internal chain state * @brief Defines API for querying internal chain state
* @ingroup contractdev * @ingroup contractdev
*/ */
/** /**
* @defgroup chaincapi Chain C API * @defgroup chaincapi Chain C API
* @brief C API for querying internal chain state * @brief Defines %C API for querying internal chain state
* @ingroup chainapi * @ingroup chainapi
* @{ * @{
*/ */
extern "C" { extern "C" {
/** /**
* Return the set of active producers * Gets the set of active producers.
* @param producers - a pointer to an buffer of account_names * @brief Gets the set of active producers.
* @param datalen - byte length of buffer, 0 to report required size *
* @return the number of bytes actually populated, or number of bytes that can be copied if datalen==0 passed * @param producers - Pointer to a buffer of account names
* @param datalen - Byte length of buffer
*
* @return uint32_t - Number of bytes actually populated
* @pre `producers` is a pointer to a range of memory at least `datalen` bytes long
* @post the passed in `producers` pointer gets the array of active producers.
* *
* Example: * Example:
*
* @code * @code
* account_name producers[21]; * account_name producers[21];
* uint32_t bytes_populated = get_active_producers(producers, sizeof(account_name)*21); * uint32_t bytes_populated = get_active_producers(producers, sizeof(account_name)*21);
......
...@@ -8,65 +8,424 @@ ...@@ -8,65 +8,424 @@
extern "C" { extern "C" {
/** /**
* @defgroup compiler builtins API * @defgroup compilerbuiltinsapi Compiler Builtins API
* @ingroup mathapi
* @brief Declares int128 helper builtins generated by the toolchain. * @brief Declares int128 helper builtins generated by the toolchain.
* @ingroup compilerbuiltinsapi
* *
* @{ * @{
*/ */
/** /**
* Multiply two 128 bit integers split as two unsigned 64 bit integers and assign the value to the first parameter. * Multiply two 128 bit integers split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Multiply two 128 unsigned bit integers (which are represented as two 64 bit unsigned integers. * @brief Multiply two 128 unsigned bit integers (which are represented as two 64 bit unsigned integers.
* @param res It will be replaced with the result product. * @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor. * @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor. * @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor. * @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor. * @param hb High 64 bits of the second 128 bit factor.
* @post `res` is replaced with the result of multiplication
* Example: * Example:
* @code * @code
* __int128 res = 0; * __int128 res = 0;
* __int128 a = 100; * __int128 a = 100;
* __int128 b = 100; * __int128 b = 100;
* __multi3(res, a, (a >> 64), b, (b >> 64)); * __multi3(res, a, (a >> 64), b, (b >> 64));
* printi128(res); // Output: 10000 * printi128(&res); // Output: 10000
* @endcode * @endcode
*/ */
void __multi3(__int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb); void __multi3(__int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
/**
* Divide two 128 bit integers split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Divide two 128 bit integers (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @post `res` is replaced with the result of division
* Example:
* @code
* __int128 res = 0;
* __int128 a = 100;
* __int128 b = 100;
* __divti3(res, a, (a >> 64), b, (b >> 64));
* printi128(&res); // Output: 1
* @endcode
*/
void __divti3(__int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb); void __divti3(__int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
/**
* Divide two 128 bit unsigned integers split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Divide two 128 unsigned bit integers (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* Example:
* @code
* unsigned __int128 res = 0;
* unsigned __int128 a = 100;
* unsigned __int128 b = 100;
* __udivti3(res, a, (a >> 64), b, (b >> 64));
* printi128(&res); // Output: 1
* @endcode
*/
void __udivti3(unsigned __int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb); void __udivti3(unsigned __int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
/**
* Perform modular arithmetic on two 128 bit integers split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Perform modular arithmetic on two 128 bit integers (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @post `res` is replaced with the result of modulus
* Example:
* @code
* __int128 res = 0;
* __int128 a = 100;
* __int128 b = 3;
* __modti3(res, a, (a >> 64), b, (b >> 64));
* printi128(&res); // Output: 1
* @endcode
*/
void __modti3(__int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb); void __modti3(__int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
/**
* Perform modular arithmetic on two 128 unsigned bit integers split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Perform modular arithmetic on two 128 unsigned bit integers (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @post `res` is replaced with the result of modulus
* Example:
* @code
* unsigned __int128 res = 0;
* unsigned __int128 a = 100;
* unsigned __int128 b = 3;
* __umodti3(res, a, (a >> 64), b, (b >> 64));
* printi128(&res); // Output: 1
* @endcode
*/
void __umodti3(unsigned __int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb); void __umodti3(unsigned __int128& res, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb);
/**
* Perform logical shift left on a 128 bit integer split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Perform logical shift left on a 128 bit integer (which is represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param lo Low 64 bits of the 128 bit factor.
* @param hi High 64 bits of the 128 bit factor.
* @param shift Number of bits to shift.
* @post `res` is replaced with the result of the operation
* Example:
* @code
* __int128 res = 0;
* __int128 a = 8;
* __lshlti3(res, a, (a >> 64), 1);
* printi128(&res); // Output: 16
* @endcode
*/
void __lshlti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift); void __lshlti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift);
/**
* Perform logical shift right on a 128 bit integer split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Perform logical shift right on a 128 bit integer (which is represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param lo Low 64 bits of the 128 bit factor.
* @param hi High 64 bits of the 128 bit factor.
* @param shift Number of bits to shift.
* @post `res` is replaced with the result of the operation
* Example:
* @code
* __int128 res = 0;
* __int128 a = 8;
* __lshrti3(res, a, (a >> 64), 1);
* printi128(&res); // Output: 4
* @endcode
*/
void __lshrti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift); void __lshrti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift);
/**
* Perform arithmetic shift left on a 128 bit integer split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Perform arithmetic shift left on a 128 bit integer (which is represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param lo Low 64 bits of the 128 bit factor.
* @param hi High 64 bits of the 128 bit factor.
* @param shift Number of bits to shift.
* @post `res` is replaced with the result of the operation
* Example:
* @code
* __int128 res = 0;
* __int128 a = 8;
* __ashlti3(res, a, (a >> 64), 1);
* printi128(&res); // Output: 16
* @endcode
*/
void __ashlti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift); void __ashlti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift);
/**
* Perform arithmetic shift right on a 128 bit integer split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Perform arithmetic shift right on a 128 bit integer (which is represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param lo Low 64 bits of the 128 bit factor.
* @param hi High 64 bits of the 128 bit factor.
* @param shift Number of bits to shift.
* @post `res` is replaced with the result of the operation
* Example:
* @code
* __int128 res = 0;
* __int128 a = -8;
* __ashrti3(res, a, (a >> 64), 1);
* printi128(&res); // Output: -4
* @endcode
*/
void __ashrti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift); void __ashrti3(__int128& res, uint64_t lo, uint64_t hi, uint32_t shift);
/**
* Add two long doubles split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Add two long doubles (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @post `ret` is replaced with the result of the operation
*/
void __addtf3( long double& ret, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); void __addtf3( long double& ret, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Subtract two long doubles split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Subtract two long doubles (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @post `ret` is replaced with the result of the operation
*/
void __subtf3( long double& ret, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); void __subtf3( long double& ret, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Multiply two long doubles split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Multiply two long doubles (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @post `ret` is replaced with the result of the operation
*/
void __multf3( long double& ret, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); void __multf3( long double& ret, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Divide two long doubles split as two 64 bit unsigned integers and assign the value to the first parameter.
* @brief Divide two long doubles (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @post `ret` is replaced with the result of the operation
*/
void __divtf3( long double& ret, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); void __divtf3( long double& ret, uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Check equality between two doubles split as two 64 bit unsigned integers
* @brief Check equality between two doubles (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @return 1 if a greater than b
* @return 0 if a equal to b
* @return -1 if a less than b
* @return 1 if either a or b is NaN
*/
int __eqtf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); int __eqtf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Check inequality between two doubles split as two 64 bit unsigned integers
* @brief Check inequality between two doubles (which are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @return 1 if a greater than b
* @return 0 if a equal to b
* @return -1 if a less than b
* @return1 if either a or b is NaN
*/
int __netf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); int __netf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Check if the first double is greater or equal to the second double, the doubles are split as two 64 bit unsigned integers
* @brief Check if the first double is greater or equal to the second double, (the doubles are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @return 1 if a greater than b
* @return 0 if a equal to b
* @return -1 if a less than b
* @return -1 if either a or b is NaN
*/
int __getf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); int __getf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Check if the first double is greater than the second double, the doubles are split as two 64 bit unsigned integers
* @brief Check if the first double is greater than the second double, (the doubles are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @return 1 if a greater than b
* @return 0 if a equal to b
* @return -1 if a less than b
* @return 0 if either a or b is NaN
*/
int __gttf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); int __gttf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Check if the first double is less or equal to the second double, the doubles are split as two 64 bit unsigned integers
* @brief Check if the first double is less or equal to the second double, (the doubles are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @return 1 if a greater than b
* @return 0 if a equal to b
* @return -1 if a less than b
* @return 1 if either a or b is NaN
*/
int __letf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); int __letf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Check if the first double is less than the second double, the doubles are split as two 64 bit unsigned integers
* @brief Check if the first double is less than the second double, (the doubles are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @return 1 if a greater than b
* @return 0 if a equal to b
* @return -1 if a less than b
* @return 0 if either a or b is NaN
*/
int __lttf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); int __lttf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Compare two doubles which are split as two 64 bit unsigned integers
* @brief Compare two doubles (the doubles are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @return 1 if a greater than b
* @return 0 if a equal to b
* @return -1 if a less than b
* @return 1 if either a or b is NaN
*/
int __cmptf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); int __cmptf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Check if either of the doubles is NaN, the doubles are split as two 64 bit unsigned integers
* @brief Check if either of the doubles is NaN, (the doubles are represented as two 64 bit unsigned integers)
* @param res It will be replaced with the result product.
* @param la Low 64 bits of the first 128 bit factor.
* @param ha High 64 bits of the first 128 bit factor.
* @param lb Low 64 bits of the second 128 bit factor.
* @param hb High 64 bits of the second 128 bit factor.
* @return 1 if either a or b is NaN
* @return 0 if either a or b is not NaN
*/
int __unordtf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb ); int __unordtf2( uint64_t la, uint64_t ha, uint64_t lb, uint64_t hb );
/**
* Extend float to long double
* @brief Extend float to long double
* @param ret It will be replaced with the result product.
* @param f Input float to be extended
* @post `ret` is replaced with the extended float
*/
void __extendsftf2( long double& ret, float f ); void __extendsftf2( long double& ret, float f );
/**
* Extend double to long double
* @brief Extend float to long double
* @param ret It will be replaced with the result product.
* @param f Input float to be extended
* @post `ret` is replaced with the extended float
*/
void __extenddftf2( long double& ret, double f ); void __extenddftf2( long double& ret, double f );
/**
* Convert long double (which are split as two 64 bit unsigned integers) into 64 bit integer
* @brief Convert long double (which are split as two 64 bit unsigned integers) into 64 bit integer
* @param l Low 64 bits of the first 128 bit factor.
* @param h High 64 bits of the first 128 bit factor.
* @return the converted 64 bit integer.
*/
int64_t __fixtfdi( uint64_t l, uint64_t h ); int64_t __fixtfdi( uint64_t l, uint64_t h );
/**
* Convert long double (which are split as two 64 bit unsigned integers) into 32 bit integer
* @brief Convert long double (which are split as two 64 bit unsigned integers) into 32 bit integer
* @param l Low 64 bits of the first 128 bit factor.
* @param h High 64 bits of the first 128 bit factor.
* @return the converted 32 bit integer.
*/
int32_t __fixtfsi( uint64_t l, uint64_t h ); int32_t __fixtfsi( uint64_t l, uint64_t h );
/**
* Convert long double (which are split as two 64 bit unsigned integers) into 64 bit unsigned integer
* @brief Convert long double (which are split as two 64 bit unsigned integers) into 64 bit unsigned integer
* @param l Low 64 bits of the first 128 bit factor.
* @param h High 64 bits of the first 128 bit factor.
* @return the converted 64 bit unsigned integer.
*/
uint64_t __fixunstfdi( uint64_t l, uint64_t h ); uint64_t __fixunstfdi( uint64_t l, uint64_t h );
/**
* Convert long double (which are split as two 64 bit unsigned integers) into 32 bit unsigned integer
* @brief Convert long double (which are split as two 64 bit unsigned integers) into 32 bit unsigned integer
* @param l Low 64 bits of the first 128 bit factor.
* @param h High 64 bits of the first 128 bit factor.
* @return the converted 32 bit unsigned integer.
*/
uint32_t __fixunstfsi( uint64_t l, uint64_t h ); uint32_t __fixunstfsi( uint64_t l, uint64_t h );
/**
* Truncate long double (which are split as two 64 bit unsigned integers) into double
* @brief Convert long double (which are split as two 64 bit unsigned integers) into double
* @param l Low 64 bits of the first 128 bit factor.
* @param h High 64 bits of the first 128 bit factor.
* @return the converted double
*/
double __trunctfdf2( uint64_t l, uint64_t h ); double __trunctfdf2( uint64_t l, uint64_t h );
/**
* Truncate long double (which are split as two 64 bit unsigned integers) into float
* @brief Convert long double (which are split as two 64 bit unsigned integers) into float
* @param l Low 64 bits of the first 128 bit factor.
* @param h High 64 bits of the first 128 bit factor.
* @return the converted float
*/
float __trunctfsf2( uint64_t l, uint64_t h ); float __trunctfsf2( uint64_t l, uint64_t h );
void __break_point(); void __break_point();
/// @}
} // extern "C" } // extern "C"
...@@ -2,14 +2,46 @@ ...@@ -2,14 +2,46 @@
namespace eosio { namespace eosio {
/**
* @defgroup contracttype Contract Type
* @ingroup types
* @brief Defines contract type which is %base class for every EOSIO contract
*
* @{
*
*/
/**
* @brief %Base class for EOSIO contract.
* @details %Base class for EOSIO contract. %A new contract should derive from this class, so it can make use of EOSIO_ABI macro.
*/
class contract { class contract {
public: public:
/**
* Construct a new contract given the contract name
*
* @brief Construct a new contract object.
* @param n - The name of this contract
*/
contract( account_name n ):_self(n){} contract( account_name n ):_self(n){}
/**
*
* Get this contract name
*
* @brief Get this contract name.
* @return account_name - The name of this contract
*/
inline account_name get_self()const { return _self; } inline account_name get_self()const { return _self; }
protected: protected:
/**
* The name of this contract
*
* @brief The name of this contract.
*/
account_name _self; account_name _self;
}; };
/// @} contracttype
} /// namespace eosio } /// namespace eosio
...@@ -5,85 +5,236 @@ ...@@ -5,85 +5,236 @@
#pragma once #pragma once
#include <eosiolib/types.h> #include <eosiolib/types.h>
extern "C" { extern "C" {
/**
* @defgroup cryptoapi Chain API
* @brief Defines API for calculating and checking hash
* @ingroup contractdev
*/
/**
* @defgroup cryptocapi Chain C API
* @brief Defines %C API for calculating and checking hash
* @ingroup chainapi
* @{
*/
/** /**
* This method is implemented as: * Tests if the sha256 hash generated from data matches the provided checksum.
* This method is optimized to a NO-OP when in fast evaluation mode.
* @brief Tests if the sha256 hash generated from data matches the provided checksum.
* *
* checksum calc_hash; * @param data - Data you want to hash
* sha256( data, length, &calc_hash ); * @param length - Data length
* eosio_assert( calc_hash == hash, "invalid hash" ); * @param hash - `checksum256*` hash to compare to
* *
* This method is optimized to a NO-OP when in fast evaluation mode * @pre **assert256 hash** of `data` equals provided `hash` parameter.
* @post Executes next statement. If was not `true`, hard return.
*
* Example:
*
* @code
* checksum hash;
* char data;
* uint32_t length;
* assert_sha256( data, length, hash )
* //If the sha256 hash generated from data does not equal provided hash, anything below will never fire.
* eosio::print("sha256 hash generated from data equals provided hash");
* @endcode
*/ */
void assert_sha256( char* data, uint32_t length, const checksum256* hash ); void assert_sha256( char* data, uint32_t length, const checksum256* hash );
/** /**
* This method is implemented as: * Tests if the sha1 hash generated from data matches the provided checksum.
* This method is optimized to a NO-OP when in fast evaluation mode.
* @brief Tests if the sha1 hash generated from data matches the provided checksum.
* *
* checksum calc_hash; * @param data - Data you want to hash
* sha1( data, length, &calc_hash ); * @param length - Data length
* eos_assert( calc_hash == hash, "invalid hash" ); * @param hash - `checksum160*` hash to compare to
*
* @pre **sha1 hash** of `data` equals provided `hash` parameter.
* @post Executes next statement. If was not `true`, hard return.
* *
* This method is optimized to a NO-OP when in fast evaluation mode * Example:
*
* @code
* checksum hash;
* char data;
* uint32_t length;
* assert_sha1( data, length, hash )
* //If the sha1 hash generated from data does not equal provided hash, anything below will never fire.
* eosio::print("sha1 hash generated from data equals provided hash");
* @endcode
*/ */
void assert_sha1( char* data, uint32_t length, const checksum160* hash ); void assert_sha1( char* data, uint32_t length, const checksum160* hash );
/** /**
* This method is implemented as: * Tests if the sha512 hash generated from data matches the provided checksum.
* This method is optimized to a NO-OP when in fast evaluation mode.
* @brief Tests if the sha512 hash generated from data matches the provided checksum.
* *
* checksum calc_hash; * @param data - Data you want to hash
* sha512( data, length, &calc_hash ); * @param length - Data length
* eos_assert( calc_hash == hash, "invalid hash" ); * @param hash - `checksum512*` hash to compare to
*
* @pre **assert512 hash** of `data` equals provided `hash` parameter.
* @post Executes next statement. If was not `true`, hard return.
* *
* This method is optimized to a NO-OP when in fast evaluation mode * Example:
*
* @code
* checksum hash;
* char data;
* uint32_t length;
* assert_sha512( data, length, hash )
* //If the sha512 hash generated from data does not equal provided hash, anything below will never fire.
* eosio::print("sha512 hash generated from data equals provided hash");
* @endcode
*/ */
void assert_sha512( char* data, uint32_t length, const checksum512* hash ); void assert_sha512( char* data, uint32_t length, const checksum512* hash );
/** /**
* This method is implemented as: * Tests if the ripemod160 hash generated from data matches the provided checksum.
* @brief Tests if the ripemod160 hash generated from data matches the provided checksum.
* *
* checksum calc_hash; * @param data - Data you want to hash
* ripemd160( data, length, &calc_hash ); * @param length - Data length
* eos_assert( calc_hash == hash, "invalid hash" ); * @param hash - `checksum160*` hash to compare to
*
* @pre **assert160 hash** of `data` equals provided `hash` parameter.
* @post Executes next statement. If was not `true`, hard return.
* *
* This method is optimized to a NO-OP when in fast evaluation mode * Example:
*
* @code
* checksum hash;
* char data;
* uint32_t length;
* assert_ripemod160( data, length, hash )
* //If the ripemod160 hash generated from data does not equal provided hash, anything below will never fire.
* eosio::print("ripemod160 hash generated from data equals provided hash");
* @endcode
*/ */
void assert_ripemd160( char* data, uint32_t length, const checksum160* hash ); void assert_ripemd160( char* data, uint32_t length, const checksum160* hash );
/** /**
* Calculates sha256( data,length) and stores result in memory pointed to by hash * Hashes `data` using `sha256` and stores result in memory pointed to by hash.
* `hash` should be checksum<256> * @brief Hashes `data` using `sha256` and stores result in memory pointed to by hash.
*
* @param data - Data you want to hash
* @param length - Data length
* @param hash - Hash pointer
*
* Example:
*
* @code
* checksum calc_hash;
* sha256( data, length, &calc_hash );
* eos_assert( calc_hash == hash, "invalid hash" );
* @endcode
*/ */
void sha256( char* data, uint32_t length, checksum256* hash ); void sha256( char* data, uint32_t length, checksum256* hash );
/** /**
* Calculates sha1( data,length) and stores result in memory pointed to by hash * Hashes `data` using `sha1` and stores result in memory pointed to by hash.
* `hash` should be checksum<160> * @brief Hashes `data` using `sha1` and stores result in memory pointed to by hash.
*
* @param data - Data you want to hash
* @param length - Data length
* @param hash - Hash pointer
*
* Example:
*
* @code
* checksum calc_hash;
* sha1( data, length, &calc_hash );
* eos_assert( calc_hash == hash, "invalid hash" );
* @endcode
*/ */
void sha1( char* data, uint32_t length, checksum160* hash ); void sha1( char* data, uint32_t length, checksum160* hash );
/** /**
* Calculates sha512( data,length) and stores result in memory pointed to by hash * Hashes `data` using `sha512` and stores result in memory pointed to by hash.
* `hash` should be checksum<512> * @brief Hashes `data` using `sha512` and stores result in memory pointed to by hash.
*
* @param data - Data you want to hash
* @param length - Data length
* @param hash - Hash pointer
*
* Example:
*
* @code
* checksum calc_hash;
* sha512( data, length, &calc_hash );
* eos_assert( calc_hash == hash, "invalid hash" );
* @endcode
*/ */
void sha512( char* data, uint32_t length, checksum512* hash ); void sha512( char* data, uint32_t length, checksum512* hash );
/** /**
* Calculates ripemd160( data,length) and stores result in memory pointed to by hash * Hashes `data` using `ripemod160` and stores result in memory pointed to by hash.
* `hash` should be checksum<160> * @brief Hashes `data` using `ripemod160` and stores result in memory pointed to by hash.
*
* @param data - Data you want to hash
* @param length - Data length
* @param hash - Hash pointer
*
* Example:
*
* @code
* checksum calc_hash;
* ripemod160( data, length, &calc_hash );
* eos_assert( calc_hash == hash, "invalid hash" );
* @endcode
*/ */
void ripemd160( char* data, uint32_t length, checksum160* hash ); void ripemd160( char* data, uint32_t length, checksum160* hash );
/** /**
* Calculates the public key used for a given signature and hash used to create a message and places it in `pub` * Calculates the public key used for a given signature and hash used to create a message.
* returns the number of bytes read into pub * @brief Calculates the public key used for a given signature and hash used to create a message.
* `digest` should be checksum<256> *
* @param digest - Hash used to create a message
* @param sig - Signature
* @param siglen - Signature length
* @param pub - Public key
* @param publen - Public key length
*
* Example:
*
* @code
* @endcode
*/ */
int recover_key( const checksum256* digest, const char* sig, size_t siglen, char* pub, size_t publen ); int recover_key( const checksum256* digest, const char* sig, size_t siglen, char* pub, size_t publen );
/** /**
* Tests a given public key with the generated key from digest and the signature * Tests a given public key with the generated key from digest and the signature.
* `digest` should be checksum<256> * @brief Tests a given public key with the generated key from digest and the signature.
*
* @param digest - What the key will be generated from
* @param sig - Signature
* @param siglen - Signature length
* @param pub - Public key
* @param publen - Public key length
*
* @pre **assert recovery key** of `pub` equals the key generated from the `digest` parameter
* @post Executes next statement. If was not `true`, hard return.
*
* Example:
*
* @code
* checksum digest;
* char sig;
* size_t siglen;
* char pub;
* size_t publen;
* assert_recover_key( digest, sig, siglen, pub, publen )
* // If the given public key does not match with the generated key from digest and the signature, anything below will never fire.
* eosio::print("pub key matches the pub key generated from digest");
* @endcode
*/ */
void assert_recover_key( const checksum256* digest, const char* sig, size_t siglen, const char* pub, size_t publen ); void assert_recover_key( const checksum256* digest, const char* sig, size_t siglen, const char* pub, size_t publen );
/// }@cryptocapi
} }
...@@ -9,7 +9,7 @@ namespace eosio { ...@@ -9,7 +9,7 @@ namespace eosio {
/** /**
* This contract enables the creation, issuance, and transfering of many different tokens. * This contract enables the creation, issuance, and transfering of many different tokens.
* * @deprecated This class is deprecated in favor of eosio.token in Dawn 3.0
*/ */
class currency { class currency {
public: public:
......
此差异已折叠。
此差异已折叠。
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <boost/mp11/tuple.hpp> #include <boost/mp11/tuple.hpp>
#define N(X) ::eosio::string_to_name(#X) #define N(X) ::eosio::string_to_name(#X)
namespace eosio { namespace eosio {
template<typename Contract, typename FirstAction> template<typename Contract, typename FirstAction>
bool dispatch( uint64_t code, uint64_t act ) { bool dispatch( uint64_t code, uint64_t act ) {
if( code == FirstAction::get_account() && FirstAction::get_name() == act ) { if( code == FirstAction::get_account() && FirstAction::get_name() == act ) {
...@@ -25,7 +26,7 @@ namespace eosio { ...@@ -25,7 +26,7 @@ namespace eosio {
* static Contract::on( ActionType ) * static Contract::on( ActionType )
* ``` * ```
* *
* For this to work the Actions must be dervied from the * For this to work the Actions must be derived from eosio::contract
* *
*/ */
template<typename Contract, typename FirstAction, typename SecondAction, typename... Actions> template<typename Contract, typename FirstAction, typename SecondAction, typename... Actions>
...@@ -37,6 +38,30 @@ namespace eosio { ...@@ -37,6 +38,30 @@ namespace eosio {
return eosio::dispatch<Contract,SecondAction,Actions...>( code, act ); return eosio::dispatch<Contract,SecondAction,Actions...>( code, act );
} }
/**
* @defgroup dispatcher Dispatcher API
* @brief Defines functions to dispatch action to proper action handler inside a contract
* @ingroup contractdev
*/
/**
* @defgroup dispatchercpp Dispatcher C++ API
* @brief Defines C++ functions to dispatch action to proper action handler inside a contract
* @ingroup dispatcher
* @{
*/
/**
* Unpack the received action and execute the correponding action handler
*
* @brief Unpack the received action and execute the correponding action handler
* @tparam T - The contract class that has the correponding action handler, this contract should be derived from eosio::contract
* @tparam Q - The namespace of the action handler function
* @tparam Args - The arguments that the action handler accepts, i.e. members of the action
* @param obj - The contract object that has the correponding action handler
* @param func - The action handler
* @return true
*/
template<typename T, typename Q, typename... Args> template<typename T, typename Q, typename... Args>
bool execute_action( T* obj, void (Q::*func)(Args...) ) { bool execute_action( T* obj, void (Q::*func)(Args...) ) {
size_t size = action_data_size(); size_t size = action_data_size();
...@@ -62,15 +87,36 @@ namespace eosio { ...@@ -62,15 +87,36 @@ namespace eosio {
boost::mp11::tuple_apply( f2, args ); boost::mp11::tuple_apply( f2, args );
return true; return true;
} }
/// @} dispatcher
// Helper macro for EOSIO_API
#define EOSIO_API_CALL( r, OP, elem ) \ #define EOSIO_API_CALL( r, OP, elem ) \
case ::eosio::string_to_name( BOOST_PP_STRINGIZE(elem) ): \ case ::eosio::string_to_name( BOOST_PP_STRINGIZE(elem) ): \
eosio::execute_action( &thiscontract, &OP::elem ); \ eosio::execute_action( &thiscontract, &OP::elem ); \
break; break;
// Helper macro for EOSIO_ABI
#define EOSIO_API( TYPE, MEMBERS ) \ #define EOSIO_API( TYPE, MEMBERS ) \
BOOST_PP_SEQ_FOR_EACH( EOSIO_API_CALL, TYPE, MEMBERS ) BOOST_PP_SEQ_FOR_EACH( EOSIO_API_CALL, TYPE, MEMBERS )
/**
* @addtogroup dispatcher
* @{
*/
/**
* Convenient macro to create contract apply handler
* To be able to use this macro, the contract needs to be derived from eosio::contract
*
* @brief Convenient macro to create contract apply handler
* @param TYPE - The class name of the contract
* @param MEMBERS - The sequence of available actions supported by this contract
*
* Example:
* @code
* EOSIO_ABI( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(reqauth) )
* @endcode
*/
#define EOSIO_ABI( TYPE, MEMBERS ) \ #define EOSIO_ABI( TYPE, MEMBERS ) \
extern "C" { \ extern "C" { \
void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \ void apply( uint64_t receiver, uint64_t code, uint64_t action ) { \
...@@ -88,6 +134,7 @@ extern "C" { \ ...@@ -88,6 +134,7 @@ extern "C" { \
} \ } \
} \ } \
} \ } \
/// @} dispatcher
/* /*
......
...@@ -58,13 +58,7 @@ namespace eosio { ...@@ -58,13 +58,7 @@ namespace eosio {
using ::memset; using ::memset;
using ::memcpy; using ::memcpy;
/**
* @defgroup memorycppapi Memory C++ API
* @brief Defines common memory functions
* @ingroup memoryapi
*
* @{
*/
class memory_manager // NOTE: Should never allocate another instance of memory_manager class memory_manager // NOTE: Should never allocate another instance of memory_manager
{ {
......
...@@ -28,10 +28,19 @@ namespace eosio { ...@@ -28,10 +28,19 @@ namespace eosio {
bool operator<(const fixed_key<Size> &c1, const fixed_key<Size> &c2); bool operator<(const fixed_key<Size> &c1, const fixed_key<Size> &c2);
/** /**
* @defgroup fixed_key fixed size key sorted lexicographically * @defgroup fixed_key Fixed Size Key
* @brief Fixed size key sorted lexicographically for Multi Index Table
* @ingroup types * @ingroup types
* @{ * @{
*/ */
/**
* Fixed size key sorted lexicographically for Multi Index Table
*
* @brief Fixed size key sorted lexicographically for Multi Index Table
* @tparam Size - Size of the fixed_key object
* @ingroup types
*/
template<size_t Size> template<size_t Size>
class fixed_key { class fixed_key {
private: private:
...@@ -75,7 +84,20 @@ namespace eosio { ...@@ -75,7 +84,20 @@ namespace eosio {
typedef uint128_t word_t; typedef uint128_t word_t;
/**
* Get number of words contained in this fixed_key object. A word is defined to be 16 bytes in size
*
* @brief Get number of words contained in this fixed_key object
*/
static constexpr size_t num_words() { return (Size + sizeof(word_t) - 1) / sizeof(word_t); } static constexpr size_t num_words() { return (Size + sizeof(word_t) - 1) / sizeof(word_t); }
/**
* Get number of padded bytes contained in this fixed_key object. Padded bytes are the remaining bytes
* inside the fixed_key object after all the words are allocated
*
* @brief Get number of padded bytes contained in this fixed_key object
*/
static constexpr size_t padded_bytes() { return num_words() * sizeof(word_t) - Size; } static constexpr size_t padded_bytes() { return num_words() * sizeof(word_t) - Size; }
/** /**
...@@ -96,6 +118,12 @@ namespace eosio { ...@@ -96,6 +118,12 @@ namespace eosio {
std::copy(arr.begin(), arr.end(), _data.begin()); std::copy(arr.begin(), arr.end(), _data.begin());
} }
/**
* @brief Constructor to fixed_key object from std::array of num_words() words
*
* @details Constructor to fixed_key object from std::array of num_words() words
* @param arr - Source data
*/
template<typename Word, size_t NumWords, template<typename Word, size_t NumWords,
typename Enable = typename std::enable_if<std::is_integral<Word>::value && typename Enable = typename std::enable_if<std::is_integral<Word>::value &&
!std::is_same<Word, bool>::value && !std::is_same<Word, bool>::value &&
...@@ -109,6 +137,15 @@ namespace eosio { ...@@ -109,6 +137,15 @@ namespace eosio {
set_from_word_sequence(arr, *this); set_from_word_sequence(arr, *this);
} }
/**
* @brief Create a new fixed_key object from a sequence of words
*
* @details Create a new fixed_key object from a sequence of words
* @tparam FirstWord - The type of the first word in the sequence
* @tparam Rest - THe type of the remaining words in the sequence
* @param first_word - The first word in the sequence
* @param rest - The remaining words in the sequence
*/
template<typename FirstWord, typename... Rest> template<typename FirstWord, typename... Rest>
static static
fixed_key<Size> fixed_key<Size>
...@@ -128,13 +165,36 @@ namespace eosio { ...@@ -128,13 +165,36 @@ namespace eosio {
return key; return key;
} }
/**
* Get the contained std::array
* @brief Get the contained std::array
*/
const auto& get_array()const { return _data; } const auto& get_array()const { return _data; }
/**
* Get the underlying data of the contained std::array
* @brief Get the underlying data of the contained std::array
*/
auto data() { return _data.data(); } auto data() { return _data.data(); }
/**
* Get the underlying data of the contained std::array
* @brief Get the underlying data of the contained std::array
*/
auto data()const { return _data.data(); } auto data()const { return _data.data(); }
/**
* Get the size of the contained std::array
* @brief Get the size of the contained std::array
*/
auto size()const { return _data.size(); } auto size()const { return _data.size(); }
/**
* Extract the contained data as an array of bytes
* @brief Extract the contained data as an array of bytes
* @return - the extracted data as array of bytes
*/
std::array<uint8_t, Size> extract_as_byte_array()const { std::array<uint8_t, Size> extract_as_byte_array()const {
std::array<uint8_t, Size> arr; std::array<uint8_t, Size> arr;
...@@ -178,6 +238,8 @@ namespace eosio { ...@@ -178,6 +238,8 @@ namespace eosio {
* @brief Compares two fixed_key variables c1 and c2 * @brief Compares two fixed_key variables c1 and c2
* *
* @details Lexicographically compares two fixed_key variables c1 and c2 * @details Lexicographically compares two fixed_key variables c1 and c2
* @param c1 - First fixed_key object to compare
* @param c2 - Second fixed_key object to compare
* @return if c1 == c2, return true, otherwise false * @return if c1 == c2, return true, otherwise false
*/ */
template<size_t Size> template<size_t Size>
...@@ -189,6 +251,8 @@ namespace eosio { ...@@ -189,6 +251,8 @@ namespace eosio {
* @brief Compares two fixed_key variables c1 and c2 * @brief Compares two fixed_key variables c1 and c2
* *
* @details Lexicographically compares two fixed_key variables c1 and c2 * @details Lexicographically compares two fixed_key variables c1 and c2
* @param c1 - First fixed_key object to compare
* @param c2 - Second fixed_key object to compare
* @return if c1 != c2, return true, otherwise false * @return if c1 != c2, return true, otherwise false
*/ */
template<size_t Size> template<size_t Size>
...@@ -200,6 +264,8 @@ namespace eosio { ...@@ -200,6 +264,8 @@ namespace eosio {
* @brief Compares two fixed_key variables c1 and c2 * @brief Compares two fixed_key variables c1 and c2
* *
* @details Lexicographically compares two fixed_key variables c1 and c2 * @details Lexicographically compares two fixed_key variables c1 and c2
* @param c1 - First fixed_key object to compare
* @param c2 - Second fixed_key object to compare
* @return if c1 > c2, return true, otherwise false * @return if c1 > c2, return true, otherwise false
*/ */
template<size_t Size> template<size_t Size>
...@@ -211,6 +277,8 @@ namespace eosio { ...@@ -211,6 +277,8 @@ namespace eosio {
* @brief Compares two fixed_key variables c1 and c2 * @brief Compares two fixed_key variables c1 and c2
* *
* @details Lexicographically compares two fixed_key variables c1 and c2 * @details Lexicographically compares two fixed_key variables c1 and c2
* @param c1 - First fixed_key object to compare
* @param c2 - Second fixed_key object to compare
* @return if c1 < c2, return true, otherwise false * @return if c1 < c2, return true, otherwise false
*/ */
template<size_t Size> template<size_t Size>
......
...@@ -7,7 +7,7 @@ namespace eosio ...@@ -7,7 +7,7 @@ namespace eosio
/** /**
* @defgroup fixedpoint Fixed Point * @defgroup fixedpoint Fixed Point
* @ingroup mathcppapi * @ingroup mathcppapi
* @brief 32,64,128,256 bits version of Fixed Point variables * @brief 32,64,128,256 bits version of fixed point variables
* *
* Floating point operations are indeterministic, hence is prevented in smart contract. * Floating point operations are indeterministic, hence is prevented in smart contract.
* The smart contract developers should use the appropriate Fixed_Point template class * The smart contract developers should use the appropriate Fixed_Point template class
...@@ -85,9 +85,10 @@ namespace eosio ...@@ -85,9 +85,10 @@ namespace eosio
#endif #endif
/** /**
* The template param Q represents the Q Factor i.e number of decimals
*
* @brief 128 bits representation of Fixed Point class. * @brief 128 bits representation of Fixed Point class.
* *
* The template param Q represents the Q Factor i.e number of decimals
* Example: * Example:
* @code * @code
* fixed_point128<6> a(123232.455667233) * fixed_point128<6> a(123232.455667233)
...@@ -101,26 +102,63 @@ namespace eosio ...@@ -101,26 +102,63 @@ namespace eosio
struct fixed_point128 struct fixed_point128
{ {
static_assert(Q < 128, "Maximum number of decimals supported in fixed_point128 is 128 decimals"); static_assert(Q < 128, "Maximum number of decimals supported in fixed_point128 is 128 decimals");
/**
* @brief Value of the fixed point represented as int128_t
*
* Value of the fixed point represented as int128_t
*/
int128_t val; int128_t val;
/** /**
* Various constructors for fixed_point128 * Various constructors for fixed_point128. Can create fixed_point128 instance from an int128_t, fixed_point128,64,32 instance
* @brief Can create fixed_point128 instance from an int128_t, fixed_point128,64,32 instance
* *
* @brief Various constructors for fixed_point128
* *
* Example: * Example:
* @code * @code
* fixed_point64<18> a(1234.455667); * fixed_point64<18> a(1234.455667);
ope * fixed_point128<3> b(a); * fixed_point128<3> b(a);
* fixed_point32<6> b(13324.32323); * fixed_point32<6> b(13324.32323);
* fixed_point128<5> c(a); * fixed_point128<5> c(a);
* @endcode * @endcode
*/ */
/**
* Construct a new fixed point128 object from int128_t
*
* @brief Construct a new fixed point128 object
* @param v - int128_t representation of the fixed point value
*/
fixed_point128(int128_t v=0) : val(v) {} fixed_point128(int128_t v=0) : val(v) {}
/**
* Construct a new fixed point128 object from another fixed_point128
*
* @brief Construct a new fixed point128 object from another fixed_point128
* @param r - Another fixed_point128 as source
*/
template <uint8_t qr> fixed_point128(const fixed_point128<qr> &r); template <uint8_t qr> fixed_point128(const fixed_point128<qr> &r);
/**
* Construct a new fixed point128 object from another fixed_point64
*
* @brief Construct a new fixed point128 object from another fixed_point64
* @param r -fixed_point64 as source
*/
template <uint8_t qr> fixed_point128(const fixed_point64<qr> &r); template <uint8_t qr> fixed_point128(const fixed_point64<qr> &r);
/**
* Construct a new fixed point128 object from another fixed_point32
*
* @brief Construct a new fixed point128 object from another fixed_point32
* @param r -fixed_point32 as source
*/
template <uint8_t qr> fixed_point128(const fixed_point32<qr> &r); template <uint8_t qr> fixed_point128(const fixed_point32<qr> &r);
/** /**
* Get the integer part of the 64 bit fixed number * Get the integer part of the 64 bit fixed number
*
* @brief To get the integer part of the fixed number * @brief To get the integer part of the fixed number
* @return Returns integer part of the fixed number * @return Returns integer part of the fixed number
* *
...@@ -136,6 +174,7 @@ ope * fixed_point128<3> b(a); ...@@ -136,6 +174,7 @@ ope * fixed_point128<3> b(a);
/** /**
* Get the decimal part of the 64 bit fixed number * Get the decimal part of the 64 bit fixed number
*
* @brief To get the decimal part of the fixed number * @brief To get the decimal part of the fixed number
* @return Returns decimal part of the fixed number * @return Returns decimal part of the fixed number
* *
...@@ -150,6 +189,11 @@ ope * fixed_point128<3> b(a); ...@@ -150,6 +189,11 @@ ope * fixed_point128<3> b(a);
return uint128_t(val << (32-Q)); return uint128_t(val << (32-Q));
} }
/**
* Prints the fixed point value
*
* @brief Prints the fixed point value
*/
void print() const { void print() const {
uint128_t ip((uint128_t)int_part()); uint128_t ip((uint128_t)int_part());
uint128_t fp(frac_part()); uint128_t fp(frac_part());
...@@ -159,12 +203,66 @@ ope * fixed_point128<3> b(a); ...@@ -159,12 +203,66 @@ ope * fixed_point128<3> b(a);
} }
// Various assignment operators // Various assignment operators
/**
* Assignment operator. Assign fixed_point32 to fixed_point128
*
* @brief Assignment operator
* @tparam qr - Precision of the source
* @param r - Source
* @return fixed_point128& - Reference to this object
*/
template <uint8_t qr> fixed_point128 &operator=(const fixed_point32<qr> &r); template <uint8_t qr> fixed_point128 &operator=(const fixed_point32<qr> &r);
/**
* Assignment operator. Assign fixed_point32 to fixed_point64
*
* @brief Assignment operator
* @tparam qr - Precision of the source
* @param r - Source
* @return fixed_point128& - Reference to this object
*/
template <uint8_t qr> fixed_point128 &operator=(const fixed_point64<qr> &r); template <uint8_t qr> fixed_point128 &operator=(const fixed_point64<qr> &r);
/**
* Assignment operator. Assign fixed_point32 to fixed_point32
*
* @brief Assignment operator
* @tparam qr - Precision of the source
* @param r - Source
* @return fixed_point128& - Reference to this object
*/
template <uint8_t qr> fixed_point128 &operator=(const fixed_point128<qr> &r); template <uint8_t qr> fixed_point128 &operator=(const fixed_point128<qr> &r);
// Comparison functions // Comparison functions
/**
* Equality operator
*
* @brief Equality operator
* @tparam qr - Precision of the source
* @param r - Source
* @return true - if equal
* @return false - otherwise
*/
template <uint8_t qr> bool operator==(const fixed_point128<qr> &r) { return (val == r.val);} template <uint8_t qr> bool operator==(const fixed_point128<qr> &r) { return (val == r.val);}
/**
* Greater than operator
*
* @brief Greater than operator
* @tparam qr - Precision of the source
* @param r - Source
* @return true - if equal
* @return false - otherwise
*/
template <uint8_t qr> bool operator>(const fixed_point128<qr> &r) { return (val > r.val);} template <uint8_t qr> bool operator>(const fixed_point128<qr> &r) { return (val > r.val);}
/**
* Less than operator
*
* @brief Less than operator
* @tparam qr - Precision of the source
* @param r - Source
* @return true - if equal
* @return false - otherwise
*/
template <uint8_t qr> bool operator<(const fixed_point128<qr> &r) { return (val < r.val);} template <uint8_t qr> bool operator<(const fixed_point128<qr> &r) { return (val < r.val);}
}; };
...@@ -185,23 +283,38 @@ ope * fixed_point128<3> b(a); ...@@ -185,23 +283,38 @@ ope * fixed_point128<3> b(a);
struct fixed_point64 struct fixed_point64
{ {
static_assert(Q < 128, "Maximum number of decimals supported in fixed_point64 is 128 decimals"); static_assert(Q < 128, "Maximum number of decimals supported in fixed_point64 is 128 decimals");
/**
* @brief Value of the fixed point represented as int64_t
*
* Value of the fixed point represented as int64_t
*/
int64_t val; int64_t val;
fixed_point64(int64_t v=0) : val(v) {}
/** /**
* Various constructors for fixed_point64 * Construct a new fixed point64 object from int64_t
* @brief Can create fixed_point64 instance from int64_t, fixed_point64,32 instances
* *
* @brief Construct a new fixed point64 object
* @param v - int64_t representation of the fixed point value
*/
fixed_point64(int64_t v=0) : val(v) {}
/**
* Construct a new fixed point64 object from another fixed_point64
* *
* Example: * @brief Construct a new fixed point64 object from another fixed_point64
* @code * @param r - Another fixed_point64 as source
* fixed_point32<18> a(1234.455667);
* fixed_point64<3> b(a);
* fixed_point64<6> b(13324.32323);
* fixed_point64<5> c(a);
* @endcode
*/ */
template <uint8_t QR> fixed_point64(const fixed_point64<QR> &r); template <uint8_t QR> fixed_point64(const fixed_point64<QR> &r);
/**
* Construct a new fixed point64 object from another fixed_point32
*
* @brief Construct a new fixed point64 object from another fixed_point32
* @param r - fixed_point64 as source
*/
template <uint8_t QR> fixed_point64(const fixed_point32<QR> &r); template <uint8_t QR> fixed_point64(const fixed_point32<QR> &r);
/** /**
* Get the integer part of the 64 bit fixed number * Get the integer part of the 64 bit fixed number
* @brief To get the integer part of the fixed number * @brief To get the integer part of the fixed number
...@@ -233,6 +346,11 @@ ope * fixed_point128<3> b(a); ...@@ -233,6 +346,11 @@ ope * fixed_point128<3> b(a);
return uint64_t(val << (32-Q)); return uint64_t(val << (32-Q));
} }
/**
* Prints the fixed point value
*
* @brief Prints the fixed point value
*/
void print() const { void print() const {
printi(int_part()); printi(int_part());
prints("."); prints(".");
...@@ -240,19 +358,101 @@ ope * fixed_point128<3> b(a); ...@@ -240,19 +358,101 @@ ope * fixed_point128<3> b(a);
} }
// Various assignment operators // Various assignment operators
/**
* Assignment operator. Assign fixed_point32 to fixed_point64
*
* @brief Assignment operator
* @tparam qr - Precision of the source
* @param r - Source
* @return fixed_point64& - Reference to this object
*/
template <uint8_t QR> fixed_point64 &operator=(const fixed_point32<QR> &r); template <uint8_t QR> fixed_point64 &operator=(const fixed_point32<QR> &r);
/**
* Assignment operator. Assign fixed_point64 to fixed_point64
*
* @brief Assignment operator
* @tparam qr - Precision of the source
* @param r - Source
* @return fixed_point64& - Reference to this object
*/
template <uint8_t QR> fixed_point64 &operator=(const fixed_point64<QR> &r); template <uint8_t QR> fixed_point64 &operator=(const fixed_point64<QR> &r);
// Arithmetic operations // Arithmetic operations
/**
* Addition operator
*
* @brief Addition operator
* @tparam QR - Precision of the second addend
* @param r - Second addend
* @return - The result of addition
*/
template <uint8_t QR> fixed_point64< (Q>QR)?Q:QR > operator+(const fixed_point64<QR> &r) const; template <uint8_t QR> fixed_point64< (Q>QR)?Q:QR > operator+(const fixed_point64<QR> &r) const;
/**
* Subtraction operator
*
* @brief Subtraction operator
* @tparam QR - Precision of the minuend
* @param r - Minuend
* @return - The result of subtraction
*/
template <uint8_t QR> fixed_point64< (Q>QR)?Q:QR > operator-(const fixed_point64<QR> &r) const; template <uint8_t QR> fixed_point64< (Q>QR)?Q:QR > operator-(const fixed_point64<QR> &r) const;
// product and division of two fixed_point64 instances will be fixed_point128 // product and division of two fixed_point64 instances will be fixed_point128
// The total number of decimals will be the max // The total number of decimals will be the max
/**
* Multiplication operator
*
* @brief Multiplication operator
* @tparam QR - Precision of the multiplier
* @param r - Multiplier
* @return - The result of multiplication
*/
template <uint8_t QR> fixed_point128<Q+QR> operator*(const fixed_point64<QR> &r) const; template <uint8_t QR> fixed_point128<Q+QR> operator*(const fixed_point64<QR> &r) const;
/**
* Division operator
*
* @brief Division operator
* @tparam QR - Precision of the divisor
* @param r - Divisor
* @return - The result of division
*/
template <uint8_t QR> fixed_point128<Q+64-QR> operator/(const fixed_point64<QR> &r) const; template <uint8_t QR> fixed_point128<Q+64-QR> operator/(const fixed_point64<QR> &r) const;
// Comparison functions // Comparison functions
/**
* Equality operator
*
* @brief Equality operator
* @tparam qr - Precision of the source
* @param r - Source
* @return true - if equal
* @return false - otherwise
*/
template <uint8_t QR> bool operator==(const fixed_point64<QR> &r) { return (val == r.val);} template <uint8_t QR> bool operator==(const fixed_point64<QR> &r) { return (val == r.val);}
/**
* Greater than operator
*
* @brief Greater than operator
* @tparam qr - Precision of the source
* @param r - Source
* @return true - if equal
* @return false - otherwise
*/
template <uint8_t QR> bool operator>(const fixed_point64<QR> &r) { return (val > r.val);} template <uint8_t QR> bool operator>(const fixed_point64<QR> &r) { return (val > r.val);}
/**
* Less than operator
*
* @brief Less than operator
* @tparam qr - Precision of the source
* @param r - Source
* @return true - if equal
* @return false - otherwise
*/
template <uint8_t QR> bool operator<(const fixed_point64<QR> &r) { return (val < r.val);} template <uint8_t QR> bool operator<(const fixed_point64<QR> &r) { return (val < r.val);}
}; };
...@@ -277,12 +477,40 @@ ope * fixed_point128<3> b(a); ...@@ -277,12 +477,40 @@ ope * fixed_point128<3> b(a);
struct fixed_point32 struct fixed_point32
{ {
static_assert(Q < 128, "Maximum number of decimals supported in fixed_point32 is 128 decimals"); static_assert(Q < 128, "Maximum number of decimals supported in fixed_point32 is 128 decimals");
// translates given double variable to the int32 based on the scale factor
/**
* @brief Value of the fixed point represented as int32_t
*
* Value of the fixed point represented as int32_t
*/
int32_t val; int32_t val;
/**
* Construct a new fixed point32 object from another fixed_point32
*
* @brief Construct a new fixed point32 object from another fixed_point32
* @param r - Another fixed_point32 as source
*/
template <uint8_t QR> fixed_point32(const fixed_point32<QR> &r); template <uint8_t QR> fixed_point32(const fixed_point32<QR> &r);
/**
* Construct a new fixed point32 object from another fixed_point64. It will be truncated.
*
* @brief Construct a new fixed point32 object from another fixed_point64
* @param r - Another fixed_point32 as source
*/
template <uint8_t QR> fixed_point32(const fixed_point64<QR> &r); template <uint8_t QR> fixed_point32(const fixed_point64<QR> &r);
/**
* Construct a new fixed point32 object from int32_t
*
* @brief Construct a new fixed point32 object
* @param v - int32_t representation of the fixed point value
*/
fixed_point32(int32_t param=0) : val(param) {} fixed_point32(int32_t param=0) : val(param) {}
// translates given double variable to the int32 based on the scale factor
// fixed_point32(double d=0) : val(d * (1<<q) ) { } // fixed_point32(double d=0) : val(d * (1<<q) ) { }
/* /*
double to_double() const { double to_double() const {
...@@ -309,6 +537,11 @@ ope * fixed_point128<3> b(a); ...@@ -309,6 +537,11 @@ ope * fixed_point128<3> b(a);
return uint32_t(val << (32-Q)); return uint32_t(val << (32-Q));
} }
/**
* Prints the fixed point value
*
* @brief Prints the fixed point value
*/
void print() const { void print() const {
printi(int_part()); printi(int_part());
prints("."); prints(".");
...@@ -316,20 +549,105 @@ ope * fixed_point128<3> b(a); ...@@ -316,20 +549,105 @@ ope * fixed_point128<3> b(a);
} }
// Various assignment operators // Various assignment operators
/**
* Assignment operator. Assign fixed_point32 to fixed_point32
*
* @brief Assignment operator
* @tparam qr - Precision of the source
* @param r - Source
* @return fixed_point32& - Reference to this object
*/
template <uint8_t QR> fixed_point32 &operator=(const fixed_point32<QR> &r); template <uint8_t QR> fixed_point32 &operator=(const fixed_point32<QR> &r);
/**
* Assignment operator. Assign fixed_point64 to fixed_point32
*
* @brief Assignment operator
* @tparam qr - Precision of the source
* @param r - Source
* @return fixed_point32& - Reference to this object
*/
template <uint8_t QR> fixed_point32 &operator=(const fixed_point64<QR> &r); template <uint8_t QR> fixed_point32 &operator=(const fixed_point64<QR> &r);
/**
* Addition operator
*
* @brief Addition operator
* @tparam QR - Precision of the second addend
* @param r - Second addend
* @return - The result of addition
*/
template <uint8_t QR> fixed_point32< (Q>QR)?Q:QR > operator+(const fixed_point32<QR> &r) const; template <uint8_t QR> fixed_point32< (Q>QR)?Q:QR > operator+(const fixed_point32<QR> &r) const;
/**
* Subtraction operator
*
* @brief Subtraction operator
* @tparam QR - Precision of the minuend
* @param r - Minuend
* @return - The result of subtraction
*/
template <uint8_t QR> fixed_point32< (Q>QR)?Q:QR > operator-(const fixed_point32<QR> &r) const; template <uint8_t QR> fixed_point32< (Q>QR)?Q:QR > operator-(const fixed_point32<QR> &r) const;
// productd of to fixed_point32 instances will be fixed_point64 // productd of to fixed_point32 instances will be fixed_point64
/**
* Multiplication operator
*
* @brief Multiplication operator
* @tparam QR - Precision of the multiplier
* @param r - Multiplier
* @return - The result of multiplication
*/
template <uint8_t QR> fixed_point64<Q+QR> operator*(const fixed_point32<QR> &r) const; template <uint8_t QR> fixed_point64<Q+QR> operator*(const fixed_point32<QR> &r) const;
/**
* Division operator
*
* @brief Division operator
* @tparam QR - Precision of the divisor
* @param r - Divisor
* @return - The result of division
*/
template <uint8_t QR> fixed_point64<Q+32-QR> operator/(const fixed_point32<QR> &r) const; template <uint8_t QR> fixed_point64<Q+32-QR> operator/(const fixed_point32<QR> &r) const;
// Comparison functions // Comparison functions
/**
* Equality operator
*
* @brief Equality operator
* @tparam qr - Precision of the source
* @param r - Source
* @return true - if equal
* @return false - otherwise
*/
template <uint8_t QR> bool operator==(const fixed_point32<QR> &r) { return (val == r.val);} template <uint8_t QR> bool operator==(const fixed_point32<QR> &r) { return (val == r.val);}
/**
* Greater than operator
*
* @brief Greater than operator
* @tparam qr - Precision of the source
* @param r - Source
* @return true - if equal
* @return false - otherwise
*/
template <uint8_t QR> bool operator>(const fixed_point32<QR> &r) { return (val > r.val);} template <uint8_t QR> bool operator>(const fixed_point32<QR> &r) { return (val > r.val);}
/**
* Less than operator
*
* @brief Less than operator
* @tparam qr - Precision of the source
* @param r - Source
* @return true - if equal
* @return false - otherwise
*/
template <uint8_t QR> bool operator<(const fixed_point32<QR> &r) { return (val < r.val);} template <uint8_t QR> bool operator<(const fixed_point32<QR> &r) { return (val < r.val);}
}; };
/// @} fixedpoint
// Helper functions // Helper functions
template<typename T> template<typename T>
T assignHelper(T rhs_val, uint8_t q, uint8_t qr) T assignHelper(T rhs_val, uint8_t q, uint8_t qr)
...@@ -338,6 +656,7 @@ ope * fixed_point128<3> b(a); ...@@ -338,6 +656,7 @@ ope * fixed_point128<3> b(a);
return result; return result;
} }
#if 0 #if 0
// fixed_point256 methods // fixed_point256 methods
template<uint32_t q> template<uint32_t qr> template<uint32_t q> template<uint32_t qr>
...@@ -599,5 +918,5 @@ ope * fixed_point128<3> b(a); ...@@ -599,5 +918,5 @@ ope * fixed_point128<3> b(a);
return fixed_point128<Q>(result); return fixed_point128<Q>(result);
} }
/// @} fixedpoint
}; };
...@@ -9,14 +9,60 @@ ...@@ -9,14 +9,60 @@
void* sbrk(size_t num_bytes); void* sbrk(size_t num_bytes);
/**
* @defgroup memoryapi Memory API
* @brief Defines common memory functions
* @ingroup contractdev
*/
/**
* @defgroup memorycppapi Memory C++ API
* @brief Defines common memory functions
* @ingroup memoryapi
*
* @{
*/
extern "C" { extern "C" {
/**
* Allocate additional memory
*
* @brief Allocate additional memory
* @param size - Number of additional bytes to be allocated
* @return void* - Pointer to start of the new allocated memory
*/
void* malloc(size_t size); void* malloc(size_t size);
/**
* Allocate a block of memory for an array of **count** elements, each of them **size** bytes long, and initializes all bits with 0
*
* @brief Allocate a block of memory for an array of **count** elements, each of them **size** bytes long, and initializes all bits with 0
* @param count - Number of elements to allocate
* @param size - Size of each element
* @return void* - Pointer to start of the new allocated memory
*/
void* calloc(size_t count, size_t size); void* calloc(size_t count, size_t size);
/**
* Reallocate the given area of memory, which is allocated by malloc(), calloc(), or realloc() previously
*
* @brief Reallocate the given area of memory
* @param ptr - Pointer to the memory area to be reallocated
* @param size - New size of the memory
* @return void* - Pointer to the new reallocated memory
*/
void* realloc(void* ptr, size_t size); void* realloc(void* ptr, size_t size);
/**
*
* Deallocates the given area of memory which is previously allocated by malloc(), calloc(), or realloc()
* @brief Deallocates the given area of memory
*
* @param ptr - Pointer to the memory to be deallocated
*/
void free(void* ptr); void free(void* ptr);
} }
/// @}memorycppapi
此差异已折叠。
...@@ -3,16 +3,43 @@ ...@@ -3,16 +3,43 @@
#include <utility> #include <utility>
namespace eosio { namespace eosio {
/**
* @defgroup optionaltype Optional Type
* @brief Defines otional type which is similar to boost::optional
* @ingroup types
* @{
*/
/**
* Provides stack-based nullable value similar to boost::optional
*
* @brief Provides stack-based nullable value similar to boost::optional
*/
template<typename T> template<typename T>
class optional { class optional {
public: public:
typedef T value_type; typedef T value_type;
typedef typename std::aligned_storage<sizeof(T), alignof(T)>::type storage_type; typedef typename std::aligned_storage<sizeof(T), alignof(T)>::type storage_type;
/**
* Default constructor
*
* @brief Construct a new optional object
*/
optional():_valid(false){} optional():_valid(false){}
/**
* Destructor
*
* @brief Destroy the optional object
*/
~optional(){ reset(); } ~optional(){ reset(); }
/**
* Construct a new optional object from another optional object
*
* @brief Construct a new optional object
*/
optional( optional& o ) optional( optional& o )
:_valid(false) :_valid(false)
{ {
...@@ -20,6 +47,11 @@ namespace eosio { ...@@ -20,6 +47,11 @@ namespace eosio {
_valid = o._valid; _valid = o._valid;
} }
/**
* Copy constructor
*
* @brief Construct a new optional object
*/
optional( const optional& o ) optional( const optional& o )
:_valid(false) :_valid(false)
{ {
...@@ -27,6 +59,11 @@ namespace eosio { ...@@ -27,6 +59,11 @@ namespace eosio {
_valid = o._valid; _valid = o._valid;
} }
/**
* Move constructor
*
* @brief Construct a new optional object
*/
optional( optional&& o ) optional( optional&& o )
:_valid(false) :_valid(false)
{ {
...@@ -35,6 +72,11 @@ namespace eosio { ...@@ -35,6 +72,11 @@ namespace eosio {
o.reset(); o.reset();
} }
/**
* Construct a new optional object from another type of optional object
*
* @brief Construct a new optional object from another type of optional object
*/
template<typename U> template<typename U>
optional( const optional<U>& o ) optional( const optional<U>& o )
:_valid(false) :_valid(false)
...@@ -43,6 +85,11 @@ namespace eosio { ...@@ -43,6 +85,11 @@ namespace eosio {
_valid = o._valid; _valid = o._valid;
} }
/**
* Construct a new optional object from another type of optional object
*
* @brief Construct a new optional object from another type of optional object
*/
template<typename U> template<typename U>
optional( optional<U>& o ) optional( optional<U>& o )
:_valid(false) :_valid(false)
...@@ -54,6 +101,11 @@ namespace eosio { ...@@ -54,6 +101,11 @@ namespace eosio {
_valid = o._valid; _valid = o._valid;
} }
/**
* Construct a new optional object from another type of optional object
*
* @brief Construct a new optional object from another type of optional object
*/
template<typename U> template<typename U>
optional( optional<U>&& o ) optional( optional<U>&& o )
:_valid(false) :_valid(false)
...@@ -63,6 +115,11 @@ namespace eosio { ...@@ -63,6 +115,11 @@ namespace eosio {
o.reset(); o.reset();
} }
/**
* Construct a new optional object from another object
*
* @brief Construct a new optional object from another object
*/
template<typename U> template<typename U>
optional( U&& u ) optional( U&& u )
:_valid(true) :_valid(true)
...@@ -70,6 +127,11 @@ namespace eosio { ...@@ -70,6 +127,11 @@ namespace eosio {
new ((char*)ptr()) T( std::forward<U>(u) ); new ((char*)ptr()) T( std::forward<U>(u) );
} }
/**
* Construct a new optional object from another object
*
* @brief Construct a new optional object from another object
*/
template<typename U> template<typename U>
optional& operator=( U&& u ) optional& operator=( U&& u )
{ {
...@@ -79,6 +141,13 @@ namespace eosio { ...@@ -79,6 +141,13 @@ namespace eosio {
return *this; return *this;
} }
/**
* Construct the contained value in place
*
* @brief Construct the contained value in place
* @tparam Args - Type of the contained value
* @param args - The value to be assigned as contained value
*/
template<typename ...Args> template<typename ...Args>
void emplace(Args&& ... args) { void emplace(Args&& ... args) {
if (_valid) { if (_valid) {
...@@ -89,6 +158,14 @@ namespace eosio { ...@@ -89,6 +158,14 @@ namespace eosio {
_valid = true; _valid = true;
} }
/**
* Assignment Operator
*
* @brief Assignment Operator
* @tparam U - Type of the contained value of the optional object to be assigned from
* @param o - The other optional object to be assigned from
* @return optional& - The reference to this object
*/
template<typename U> template<typename U>
optional& operator=( optional<U>& o ) { optional& operator=( optional<U>& o ) {
if (this != &o) { if (this != &o) {
...@@ -104,6 +181,14 @@ namespace eosio { ...@@ -104,6 +181,14 @@ namespace eosio {
return *this; return *this;
} }
/**
* Assignment Operator
*
* @brief Assignment Operator
* @tparam U - Type of the contained value of the optional object to be assigned from
* @param o - The other optional object to be assigned from
* @return optional& - The reference to this object
*/
template<typename U> template<typename U>
optional& operator=( const optional<U>& o ) { optional& operator=( const optional<U>& o ) {
if (this != &o) { if (this != &o) {
...@@ -119,6 +204,13 @@ namespace eosio { ...@@ -119,6 +204,13 @@ namespace eosio {
return *this; return *this;
} }
/**
* Assignment Operator
*
* @brief Assignment Operator
* @param o - The other optional object to be assigned from
* @return optional& - The reference to this object
*/
optional& operator=( optional& o ) { optional& operator=( optional& o ) {
if (this != &o) { if (this != &o) {
if( _valid && o._valid ) { if( _valid && o._valid ) {
...@@ -133,6 +225,13 @@ namespace eosio { ...@@ -133,6 +225,13 @@ namespace eosio {
return *this; return *this;
} }
/**
* Assignment Operator
*
* @brief Assignment Operator
* @param o - The other optional object to be assigned from
* @return optional& - The reference to this object
*/
optional& operator=( const optional& o ) { optional& operator=( const optional& o ) {
if (this != &o) { if (this != &o) {
if( _valid && o._valid ) { if( _valid && o._valid ) {
...@@ -147,6 +246,14 @@ namespace eosio { ...@@ -147,6 +246,14 @@ namespace eosio {
return *this; return *this;
} }
/**
* Assignment Operator
*
* @brief Assignment Operator
* @tparam U - Type of the contained value of the optional object to be assigned from
* @param o - The other optional object to be assigned from
* @return optional& - The reference to this object
*/
template<typename U> template<typename U>
optional& operator=( optional<U>&& o ) optional& operator=( optional<U>&& o )
{ {
...@@ -165,6 +272,13 @@ namespace eosio { ...@@ -165,6 +272,13 @@ namespace eosio {
return *this; return *this;
} }
/**
* Assignment Operator
*
* @brief Assignment Operator
* @param o - The other optional object to be assigned from
* @return optional& - The reference to this object
*/
optional& operator=( optional&& o ) optional& operator=( optional&& o )
{ {
if (this != &o) if (this != &o)
...@@ -182,33 +296,91 @@ namespace eosio { ...@@ -182,33 +296,91 @@ namespace eosio {
return *this; return *this;
} }
/**
* Check if this optional has valid contained value
*
* @brief Check if this optional has valid contained value
* @return true - if this optional has valid contained value
* @return false - otherwise
*/
bool valid()const { return _valid; } bool valid()const { return _valid; }
/**
* Logical Negation operator
*
* @brief Logical Negation Operator
* @return true - if this optional has invalid contained value
* @return false - otherwise
*/
bool operator!()const { return !_valid; } bool operator!()const { return !_valid; }
// this operation is not safe and can result in unintential /**
// casts and comparisons, use valid() or !! * Similar to valid(). However, this operation is not safe and can result in unintential
* casts and comparisons, use valid() or !!
*
* @brief Check if this optional has valid contained value
* @return true - if this optional has valid contained value
* @return false - otherwise
*/
explicit operator bool()const { return _valid; } explicit operator bool()const { return _valid; }
/**
* Get contained value of this optional
*
* @brief Pointer Dereference operator
* @return T& - Contained value
*/
T& operator*() { eosio_assert(_valid, "dereference of empty optional"); return ref(); } T& operator*() { eosio_assert(_valid, "dereference of empty optional"); return ref(); }
/**
* Get contained value of this optional
*
* @brief Pointer Dereference operator
* @return T& - Contained value
*/
const T& operator*()const { eosio_assert(_valid, "dereference of empty optional"); return ref(); } const T& operator*()const { eosio_assert(_valid, "dereference of empty optional"); return ref(); }
/**
* Get pointer to the contained value
*
* @brief Member Access Through Pointer Operator
* @return T& - The pointer to the contained value
*/
T* operator->() T* operator->()
{ {
eosio_assert(_valid, "dereference of empty optional"); eosio_assert(_valid, "dereference of empty optional");
return ptr(); return ptr();
} }
/**
* Get pointer to the contained value
*
* @brief Member Access Through Pointer Operator
* @return T& - The pointer to the contained value
*/
const T* operator->()const const T* operator->()const
{ {
eosio_assert(_valid, "dereference of empty optional"); eosio_assert(_valid, "dereference of empty optional");
return ptr(); return ptr();
} }
/**
* Assignment Operator with nullptr
*
* @brief Assignment Operator with nullptr
* @return optional& - The reference to this object
*/
optional& operator=(std::nullptr_t) optional& operator=(std::nullptr_t)
{ {
reset(); reset();
return *this; return *this;
} }
/**
* Call the destructor fot he contained value and mark this optional as valid
*
* @brief Reset the optional object
*/
void reset() void reset()
{ {
if( _valid ) { if( _valid ) {
...@@ -217,17 +389,45 @@ namespace eosio { ...@@ -217,17 +389,45 @@ namespace eosio {
_valid = false; _valid = false;
} }
/**
* Check if a contained value is less than b contained value
*
* @brief Less than operator
* @param a - First object to compare
* @param b - Second object to compare
* @return true - if a contained value is less than b contained value
* @return false - otherwise
*/
friend bool operator < ( const optional a, optional b ) friend bool operator < ( const optional a, optional b )
{ {
if( a.valid() && b.valid() ) return *a < *b; if( a.valid() && b.valid() ) return *a < *b;
return a.valid() < b.valid(); return a.valid() < b.valid();
} }
/**
* Check if a contained value is equal to b contained value
*
* @brief Equality operator
* @param a - First object to compare
* @param b - Second object to compare
* @return true - if contained value is equal to b contained value
* @return false - otherwise
*/
friend bool operator == ( const optional a, optional b ) friend bool operator == ( const optional a, optional b )
{ {
if( a.valid() && b.valid() ) return *a == *b; if( a.valid() && b.valid() ) return *a == *b;
return a.valid() == b.valid(); return a.valid() == b.valid();
} }
/**
* Serialize an optional object
*
* @brief Serialize an optional object
* @param ds - The stream to write
* @param op - The value to serialize
* @tparam Stream - Type of datastream
* @return eosio::datastream<Stream>& - Reference to the datastream
*/
template<typename Stream> template<typename Stream>
friend inline eosio::datastream<Stream>& operator>> (eosio::datastream<Stream>& ds, optional& op) friend inline eosio::datastream<Stream>& operator>> (eosio::datastream<Stream>& ds, optional& op)
{ {
...@@ -240,6 +440,15 @@ namespace eosio { ...@@ -240,6 +440,15 @@ namespace eosio {
return ds; return ds;
} }
/**
* Deserialize an optional object
*
* @brief Deserialize an optional object
* @param ds - The stream to read
* @param op - The destination for deserialized value
* @tparam Stream - Type of datastream
* @return eosio::datastream<Stream>& - Reference to the datastream
*/
template<typename Stream> template<typename Stream>
friend inline eosio::datastream<Stream>& operator<< (eosio::datastream<Stream>& ds, const optional& op) friend inline eosio::datastream<Stream>& operator<< (eosio::datastream<Stream>& ds, const optional& op)
{ {
...@@ -261,21 +470,66 @@ namespace eosio { ...@@ -261,21 +470,66 @@ namespace eosio {
}; };
/**
* Check equality between two optional object that shares same type of contained value
*
* @brief Equality Operator
* @tparam T - Type of contained value of the optional objects
* @param left - First object to be compared
* @param right - Second object to be compared
* @return true - if both optional objects are equal
* @return false
*/
template<typename T> template<typename T>
bool operator == ( const optional<T>& left, const optional<T>& right ) { bool operator == ( const optional<T>& left, const optional<T>& right ) {
return (!left == !right) || (!!left && *left == *right); return (!left == !right) || (!!left && *left == *right);
} }
/**
* Check equality between an optional object with another object
*
* @brief Equality Operator
* @tparam T - Type of contained value of the optional object
* @tparam U - Type of the other object to be compared
* @param left - First object to be compared
* @param u - Second object to be compared
* @return true - if the optional objects contained value is equal with the compared object
* @return false
*/
template<typename T, typename U> template<typename T, typename U>
bool operator == ( const optional<T>& left, const U& u ) { bool operator == ( const optional<T>& left, const U& u ) {
return !!left && *left == u; return !!left && *left == u;
} }
/**
* Check inequality between two optional object that shares same type of contained value
*
* @brief Inquality Operator
* @tparam T - Type of contained value of the optional objects
* @param left - First object to be compared
* @param right - Second object to be compared
* @return true - if both optional objects are unequal
* @return false
*/
template<typename T> template<typename T>
bool operator != ( const optional<T>& left, const optional<T>& right ) { bool operator != ( const optional<T>& left, const optional<T>& right ) {
return (!left != !right) || (!!left && *left != *right); return (!left != !right) || (!!left && *left != *right);
} }
/**
* Check inequality between an optional object with another object
*
* @brief Inqquality Operator
* @tparam T - Type of contained value of the optional object
* @tparam U - Type of the other object to be compared
* @param left - First object to be compared
* @param u - Second object to be compared
* @return true - if the optional objects contained value is unequal with the compared object
* @return false
*/
template<typename T, typename U> template<typename T, typename U>
bool operator != ( const optional<T>& left, const U& u ) { bool operator != ( const optional<T>& left, const U& u ) {
return !left || *left != u; return !left || *left != u;
} }
///@} optional
} // namespace eosio } // namespace eosio
...@@ -11,14 +11,14 @@ extern "C" { ...@@ -11,14 +11,14 @@ extern "C" {
#endif #endif
/** /**
* @defgroup consoleapi Console API * @defgroup consoleapi Console API
* @brief Enables applications to log/print text messages * @brief Defines APIs to log/print text messages
* @ingroup contractdev * @ingroup contractdev
* *
*/ */
/** /**
* @defgroup consolecapi Console C API * @defgroup consolecapi Console C API
* @brief C API to log/print text messages * @brief Defnes %C API to log/print text messages
* @ingroup consoleapi * @ingroup consoleapi
* @{ * @{
*/ */
...@@ -29,6 +29,7 @@ extern "C" { ...@@ -29,6 +29,7 @@ extern "C" {
* @param cstr - a null terminated string * @param cstr - a null terminated string
* *
* Example: * Example:
*
* @code * @code
* prints("Hello World!"); // Output: Hello World! * prints("Hello World!"); // Output: Hello World!
* @endcode * @endcode
...@@ -42,6 +43,7 @@ extern "C" { ...@@ -42,6 +43,7 @@ extern "C" {
* @param len - len of string to be printed * @param len - len of string to be printed
* *
* Example: * Example:
*
* @code * @code
* prints_l("Hello World!", 5); // Output: Hello * prints_l("Hello World!", 5); // Output: Hello
* @endcode * @endcode
...@@ -54,6 +56,7 @@ extern "C" { ...@@ -54,6 +56,7 @@ extern "C" {
* @param value of 64 bit signed integer to be printed * @param value of 64 bit signed integer to be printed
* *
* Example: * Example:
*
* @code * @code
* printi(-1e+18); // Output: -1000000000000000000 * printi(-1e+18); // Output: -1000000000000000000
* @endcode * @endcode
...@@ -66,6 +69,7 @@ extern "C" { ...@@ -66,6 +69,7 @@ extern "C" {
* @param value of 64 bit unsigned integer to be printed * @param value of 64 bit unsigned integer to be printed
* *
* Example: * Example:
*
* @code * @code
* printui(1e+18); // Output: 1000000000000000000 * printui(1e+18); // Output: 1000000000000000000
* @endcode * @endcode
...@@ -78,6 +82,7 @@ extern "C" { ...@@ -78,6 +82,7 @@ extern "C" {
* @param value is a pointer to the 128 bit signed integer to be printed * @param value is a pointer to the 128 bit signed integer to be printed
* *
* Example: * Example:
*
* @code * @code
* int128_t large_int(-87654323456); * int128_t large_int(-87654323456);
* printi128(&large_int); // Output: -87654323456 * printi128(&large_int); // Output: -87654323456
...@@ -91,6 +96,7 @@ extern "C" { ...@@ -91,6 +96,7 @@ extern "C" {
* @param value is a pointer to the 128 bit unsigned integer to be printed * @param value is a pointer to the 128 bit unsigned integer to be printed
* *
* Example: * Example:
*
* @code * @code
* uint128_t large_int(87654323456); * uint128_t large_int(87654323456);
* printui128(&large_int); // Output: 87654323456 * printui128(&large_int); // Output: 87654323456
...@@ -104,6 +110,7 @@ extern "C" { ...@@ -104,6 +110,7 @@ extern "C" {
* @param value of float to be printed * @param value of float to be printed
* *
* Example: * Example:
*
* @code * @code
* float value = 5.0 / 10.0; * float value = 5.0 / 10.0;
* printsf(value); // Output: 0.5 * printsf(value); // Output: 0.5
...@@ -117,6 +124,7 @@ extern "C" { ...@@ -117,6 +124,7 @@ extern "C" {
* @param value of double to be printed * @param value of double to be printed
* *
* Example: * Example:
*
* @code * @code
* double value = 5.0 / 10.0; * double value = 5.0 / 10.0;
* printdf(value); // Output: 0.5 * printdf(value); // Output: 0.5
...@@ -130,6 +138,7 @@ extern "C" { ...@@ -130,6 +138,7 @@ extern "C" {
* @param value is a pointer to the long double to be printed * @param value is a pointer to the long double to be printed
* *
* Example: * Example:
*
* @code * @code
* long double value = 5.0 / 10.0; * long double value = 5.0 / 10.0;
* printqf(value); // Output: 0.5 * printqf(value); // Output: 0.5
......
此差异已折叠。
...@@ -13,11 +13,19 @@ extern "C" { ...@@ -13,11 +13,19 @@ extern "C" {
/** /**
* @defgroup privilegedcapi Privileged C API * @defgroup privilegedcapi Privileged C API
* @ingroup privilegedapi * @ingroup privilegedapi
* @brief Define C Privileged API * @brief Defines %C Privileged API
* *
* @{ * @{
*/ */
/**
* @brief Set the resource limit of an account
* Set the resource limit of an account
* @param account - name of the account whose resource limit to be set
* @param ram_bytes - ram limit
* @param net_weight - net limit
* @param cpu_weight - cput limit
*/
void set_resource_limits( account_name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); void set_resource_limits( account_name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight );
/** /**
...@@ -29,19 +37,56 @@ extern "C" { ...@@ -29,19 +37,56 @@ extern "C" {
*/ */
int64_t set_proposed_producers( char *producer_data, uint32_t producer_data_size ); int64_t set_proposed_producers( char *producer_data, uint32_t producer_data_size );
/**
* @brief Set new active producers
* Set new active producers. Producers will only be activated once the block which starts the next round is irrreversible
* @param producer_data - pointer to producer schedule packed as bytes
* @param producer_data_size - size of the packed producer schedule
* @pre `producer_data` is a valid pointer to a range of memory at least `producer_data_size` bytes long that contains serialized produced schedule data
*/
void set_active_producers( char *producer_data, uint32_t producer_data_size );
/**
* @brief Check if an account is privileged
* Check if an account is privileged
* @param account - name of the account to be checked
* @return true if the account is privileged
* @return false if the account is not privileged
*/
bool is_privileged( account_name account ); bool is_privileged( account_name account );
/**
* @brief Set the privileged status of an account
* Set the privileged status of an account
* @param account - name of the account whose privileged account to be set
* @param is_priv - privileged status
*/
void set_privileged( account_name account, bool is_priv ); void set_privileged( account_name account, bool is_priv );
/**
* @brief Set the blockchain parameters
* Set the blockchain parameters
* @param data - pointer to blockchain parameters packed as bytes
* @param datalen - size of the packed blockchain parameters
* @pre `data` is a valid pointer to a range of memory at least `datalen` bytes long that contains packed blockchain params data
*/
void set_blockchain_parameters_packed(char* data, uint32_t datalen); void set_blockchain_parameters_packed(char* data, uint32_t datalen);
/** /**
* @brief Retrieve the blolckchain parameters
* Retrieve the blolckchain parameters * Retrieve the blolckchain parameters
* @param data - output buffer of the blockchain parameters, only retrieved if sufficent size to hold packed data. * @param data - output buffer of the blockchain parameters, only retrieved if sufficent size to hold packed data.
* @param datalen - size of the data buffer, 0 to report required size. * @param datalen - size of the data buffer, 0 to report required size.
* @return size of the blockchain parameters
* @pre `data` is a valid pointer to a range of memory at least `datalen` bytes long
* @post `data` is filled with packed blockchain parameters
*/ */
uint32_t get_blockchain_parameters_packed(char* data, uint32_t datalen); uint32_t get_blockchain_parameters_packed(char* data, uint32_t datalen);
/**
* @brief Activate new feature
* Activate new feature
* @param f - name (identifier) of the feature to be activated
*/
void activate_feature( int64_t f ); void activate_feature( int64_t f );
///@ } privilegedcapi ///@ } privilegedcapi
......
此差异已折叠。
...@@ -4,11 +4,27 @@ ...@@ -4,11 +4,27 @@
#include <vector> #include <vector>
namespace eosio { namespace eosio {
/** /**
* Defines both the order, account name, and signing keys of the active set of producers. * Defines both the order, account name, and signing keys of the active set of producers.
*
* @brief Defines both the order, account name, and signing keys of the active set of producers.
*/ */
struct producer_schedule { struct producer_schedule {
uint32_t version; ///< sequentially incrementing version number /**
* Version number of the schedule. It is sequentially incrementing version number
*
* @brief Version number of the schedule
*/
uint32_t version;
/**
* List of producers for this schedule, including its signing key
*
* @brief List of producers for this schedule, including its signing key
*/
std::vector<producer_key> producers; std::vector<producer_key> producers;
}; };
/// @} producertype
} /// namespace eosio } /// namespace eosio
...@@ -3,8 +3,31 @@ ...@@ -3,8 +3,31 @@
#include <eosiolib/serialize.hpp> #include <eosiolib/serialize.hpp>
namespace eosio { namespace eosio {
/**
* @defgroup publickeytype Public Key Type
* @ingroup types
* @brief Specifies public key type
*
* @{
*/
/**
* EOSIO Public Key
* @brief EOSIO Public Key
*/
struct public_key { struct public_key {
/**
* Type of the public key, could be either K1 or R1
* @brief Type of the public key
*/
unsigned_int type; unsigned_int type;
/**
* Bytes of the public key
*
* @brief Bytes of the public key
*/
std::array<char,33> data; std::array<char,33> data;
friend bool operator == ( const public_key& a, const public_key& b ) { friend bool operator == ( const public_key& a, const public_key& b ) {
...@@ -15,4 +38,7 @@ namespace eosio { ...@@ -15,4 +38,7 @@ namespace eosio {
} }
EOSLIB_SERIALIZE( public_key, (type)(data) ) EOSLIB_SERIALIZE( public_key, (type)(data) )
}; };
} }
/// @} publickeytype
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -54,6 +54,12 @@ namespace eosio { ...@@ -54,6 +54,12 @@ namespace eosio {
EOSLIB_SERIALIZE_DERIVED( transaction, transaction_header, (context_free_actions)(actions)(transaction_extensions) ) EOSLIB_SERIALIZE_DERIVED( transaction, transaction_header, (context_free_actions)(actions)(transaction_extensions) )
}; };
/**
*
*
*
*
*/
struct onerror { struct onerror {
uint128_t sender_id; uint128_t sender_id;
bytes sent_trx; bytes sent_trx;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -42,6 +42,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/validate-dirty-db.py ${CMAKE_CURRENT_ ...@@ -42,6 +42,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/validate-dirty-db.py ${CMAKE_CURRENT_
#To run plugin_test with all log from blockchain displayed, put --verbose after --, i.e. plugin_test -- --verbose #To run plugin_test with all log from blockchain displayed, put --verbose after --, i.e. plugin_test -- --verbose
add_test(NAME plugin_test COMMAND plugin_test --report_level=detailed --color_output) add_test(NAME plugin_test COMMAND plugin_test --report_level=detailed --color_output)
add_test(NAME nodeos_sanity_test COMMAND tests/nodeos_run_test.py -v --sanity-test --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_test(NAME nodeos_run_test COMMAND tests/nodeos_run_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME nodeos_run_test COMMAND tests/nodeos_run_test.py -v --clean-run --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
add_test(NAME p2p_dawn515_test COMMAND tests/p2p_tests/dawn_515/test.sh WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) add_test(NAME p2p_dawn515_test COMMAND tests/p2p_tests/dawn_515/test.sh WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
......
此差异已折叠。
此差异已折叠。
...@@ -181,7 +181,7 @@ class WalletMgr(object): ...@@ -181,7 +181,7 @@ class WalletMgr(object):
def killall(self, allInstances=False): def killall(self, allInstances=False):
"""Kill keos instances. allInstances will kill all keos instances running on the system.""" """Kill keos instances. allInstances will kill all keos instances running on the system."""
if self.__walletPid: if self.__walletPid:
Utils.Print("Killing wallet manager process %d:" % (self.__walletPid)) Utils.Print("Killing wallet manager process %d" % (self.__walletPid))
os.kill(self.__walletPid, signal.SIGKILL) os.kill(self.__walletPid, signal.SIGKILL)
if allInstances: if allInstances:
......
...@@ -54,7 +54,7 @@ cluster=Cluster() ...@@ -54,7 +54,7 @@ cluster=Cluster()
(fd, nodesFile) = tempfile.mkstemp() (fd, nodesFile) = tempfile.mkstemp()
try: try:
Print("BEGIN") TestHelper.printSystemInfo("BEGIN")
cluster.killall(allInstances=killAll) cluster.killall(allInstances=killAll)
cluster.cleanup() cluster.cleanup()
......
此差异已折叠。
...@@ -56,6 +56,8 @@ cluster=Cluster(walletd=True) ...@@ -56,6 +56,8 @@ cluster=Cluster(walletd=True)
walletMgr=WalletMgr(True) walletMgr=WalletMgr(True)
try: try:
TestHelper.printSystemInfo("BEGIN")
cluster.setChainStrategy(chainSyncStrategyStr) cluster.setChainStrategy(chainSyncStrategyStr)
cluster.setWalletMgr(walletMgr) cluster.setWalletMgr(walletMgr)
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册