提交 fb4ed919 编写于 作者: A arhag

generalize sending inline actions through templates and macros

上级 e875e360
......@@ -39,7 +39,7 @@ namespace eosiosystem {
account_name owner;
asset net_weight;
asset cpu_weight;
asset storage_stake;
asset storage_stake;
uint64_t storage_bytes = 0;
uint64_t primary_key()const { return owner; }
......@@ -183,9 +183,9 @@ namespace eosiosystem {
}
//set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity );
eosio::inline_transfer(eosio::permission_level{del.from,N(active)}, N(eosio.token),
{ del.from, N(eosio), total_stake, std::string("stake bandwidth") } );
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {del.from,N(active)},
{ del.from, N(eosio), total_stake, std::string("stake bandwidth") } );
if ( asset(0) < del.stake_net_quantity + del.stake_cpu_quantity ) {
voting<SystemAccount>::increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity );
......@@ -282,8 +282,8 @@ namespace eosiosystem {
// allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many
// consecutive missed blocks.
eosio::inline_transfer( eosio::permission_level{N(eosio),N(active)}, N(eosio.token),
{ N(eosio), req->owner, req->amount, std::string("unstake") });
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)},
{ N(eosio), req->owner, req->amount, std::string("unstake") } );
refunds_tbl.erase( req );
}
......
......@@ -29,8 +29,8 @@ namespace eosiosystem {
template<account_name SystemAccount>
class contract : eosio::contract, public delegate_bandwidth<SystemAccount>, public native<SystemAccount> {
public:
contract(account_name self = SystemAccount):
contract(account_name self = SystemAccount):
eosio::contract(self)
{
}
......@@ -164,8 +164,8 @@ namespace eosiosystem {
p.per_block_payments.amount = 0;
});
eosio::inline_transfer(eosio::permission_level{N(eosio),N(active)}, N(eosio.token),
{ N(eosio), cr.owner, rewards, std::string("producer claiming rewards") } );
INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)},
{ N(eosio), cr.owner, rewards, std::string("producer claiming rewards") } );
}
static void apply( account_name receiver, account_name code, action_name act ) {
......
......@@ -376,8 +376,8 @@ namespace eosiosystem {
}
auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket);
eosio::inline_issue(eosio::permission_level{N(eosio),N(active)}, N(eosio.token),
{ N(eosio), issue_quantity, std::string("producer pay") });
INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}},
{N(eosio), issue_quantity, std::string("producer pay")} );
set_blockchain_parameters(parameters);
global_state_singleton::set(parameters);
......
......@@ -10,8 +10,8 @@ namespace eosio {
void token::create( account_name issuer,
asset maximum_supply,
uint8_t issuer_can_freeze,
uint8_t issuer_can_recall,
uint8_t issuer_can_whitelist )
uint8_t issuer_can_recall,
uint8_t issuer_can_whitelist )
{
require_auth( _self );
......@@ -35,7 +35,7 @@ void token::create( account_name issuer,
}
void token::issue( account_name to, asset quantity, string memo )
void token::issue( account_name to, asset quantity, string memo )
{
print( "issue" );
auto sym = quantity.symbol.name();
......@@ -55,14 +55,14 @@ void token::issue( account_name to, asset quantity, string memo )
if( to != st.issuer )
{
dispatch_inline( permission_level{st.issuer,N(active)}, _self, N(transfer), &token::transfer, { st.issuer, to, quantity, memo } );
SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} );
}
}
void token::transfer( account_name from,
void token::transfer( account_name from,
account_name to,
asset quantity,
string /*memo*/ )
string /*memo*/ )
{
print( "transfer" );
require_auth( from );
......
......@@ -74,18 +74,4 @@ namespace eosio {
account_name ram_payer );
};
typedef std::tuple<account_name, account_name, asset, string> transfer_args;
void inline_transfer( permission_level permissions, account_name code, transfer_args args )
{
action act( permissions, code, N(transfer), args );
act.send();
}
typedef std::tuple<account_name, asset, string> issue_args;
void inline_issue( permission_level permissions, account_name code, issue_args args )
{
action act( permissions, code, N(issue), args );
act.send();
}
} /// namespace eosio
......@@ -7,6 +7,11 @@
#include <eosiolib/datastream.hpp>
#include <eosiolib/serialize.hpp>
#include <boost/preprocessor/variadic/size.hpp>
#include <boost/preprocessor/variadic/to_tuple.hpp>
#include <boost/preprocessor/tuple/enum.hpp>
#include <boost/preprocessor/facilities/overload.hpp>
namespace eosio {
/**
......@@ -24,7 +29,7 @@ namespace eosio {
* This method unpacks the current action at type T.
*
* @brief Interpret the action body as type T
*
*
* Example:
* @code
* struct dummy_action {
......@@ -134,16 +139,26 @@ namespace eosio {
}
/**
* @tparam Action - a type derived from action_meta<Scope,Name>
* @tparam T - the type of the action data
* @param auth - a single permission_level to be used as the authorization of the action
* @param a - name of the contract account
* @param n - name of the action
* @param value - will be serialized via pack into data
*/
template<typename Action>
action( const permission_level& auth, account_name a, action_name n, const Action& value )
:authorization(1,auth) {
account = a;
name = n;
data = pack(value);
}
template<typename T>
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))) {}
/**
* @tparam T - the type of the action data
* @param auths - vector permission_levels defining the authorizations of the action
* @param a - name of the contract account
* @param n - name of the action
* @param value - will be serialized via pack into data
*/
template<typename T>
action( vector<permission_level> auths, account_name a, action_name n, T&& value )
:account(a), name(n), authorization(std::move(auths)), data(pack(std::forward<T>(value))) {}
EOSLIB_SERIALIZE( action, (account)(name)(authorization)(data) )
......@@ -178,18 +193,41 @@ namespace eosio {
static uint64_t get_name() { return Name; }
};
template<typename T, typename... Args>
void dispatch_inline( permission_level perm,
account_name code, action_name act,
void (T::*)(Args...), std::tuple<Args...> args ) {
action( perm, code, act, args ).send();
template<typename... Args>
void dispatch_inline( account_name code, action_name act,
vector<permission_level> perms,
std::tuple<Args...> args ) {
action( perms, code, act, std::move(args) ).send();
}
template<typename, uint64_t>
struct inline_dispatcher;
template<typename T, uint64_t Name, typename... Args>
struct inline_dispatcher<void(T::*)(Args...), Name> {
static void call(account_name code, const permission_level& perm, std::tuple<Args...> args) {
dispatch_inline(code, Name, vector<permission_level>(1, perm), std::move(args));
}
static void call(account_name code, vector<permission_level> perms, std::tuple<Args...> args) {
dispatch_inline(code, Name, std::move(perms), std::move(args));
}
};
///@} actioncpp api
} // namespace eosio
#define INLINE_ACTION_SENDER3( CONTRACT_CLASS, FUNCTION_NAME, ACTION_NAME )\
::eosio::inline_dispatcher<decltype(&CONTRACT_CLASS::FUNCTION_NAME), ACTION_NAME>::call
#define INLINE_ACTION_SENDER2( CONTRACT_CLASS, NAME )\
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 SEND_INLINE_ACTION( CONTRACT, NAME, ... )\
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__)) );
#define ACTION( CODE, NAME ) struct NAME : ::eosio::action_meta<CODE, ::eosio::string_to_name(#NAME) >
......@@ -2,9 +2,14 @@
namespace eosio {
struct contract {
contract( account_name n ):_self(n){}
account_name _self;
class contract {
public:
contract( account_name n ):_self(n){}
inline account_name get_self()const { return _self; }
protected:
account_name _self;
};
} /// namespace eosio
......@@ -466,6 +466,44 @@ bytes pack( const T& value ) {
return result;
}
template<typename T>
size_t _pack_size( T&& a ) {
return pack_size(std::forward<T>(a));
}
template<typename Arg, typename... Args>
size_t _pack_size( Arg&& a, Args&&... args ) {
return pack_size(std::forward<Arg>(a)) + _pack_size(std::forward<Args>(args)...);
}
template<typename T>
size_t __pack( char* result, size_t size, const T& a ) {
datastream<char*> ds( result, size );
auto start = ds.tellp();
ds << a;
return ds.tellp() - start;
}
template<typename Arg>
void _pack( char* result, size_t size, Arg&& a ) {
__pack(result, size, std::forward<Arg>(a));
}
template<typename Arg, typename... Args>
void _pack( char* result, size_t size, Arg&& a, Args&&... args ) {
auto size_of_a = __pack(result, size, std::forward<Arg>(a));
_pack(result + size_of_a, size, std::forward<Args>(args)...);
}
template<typename... Args>
bytes pack( Args&&... args ) {
bytes result;
auto size = _pack_size(std::forward<Args>(args)...);
result.resize(size);
_pack(result.data(), size, std::forward<Args>(args)...);
return result;
}
template<typename Stream>
inline datastream<Stream>& operator<<(datastream<Stream>& ds, const checksum160& cs) {
ds.write((const char*)&cs, sizeof(cs));
......
......@@ -14,7 +14,9 @@ namespace eosio {
void forward( action_name reqauth, account_name forward_code, account_name forward_auth ) {
require_auth( reqauth );
dispatch_inline( permission_level{forward_auth,N(active)}, forward_code, N(reqauth), &testinline::reqauth, { forward_auth } );
INLINE_ACTION_SENDER(testinline, reqauth)( forward_code, {forward_auth,N(active)}, {forward_auth} );
//SEND_INLINE_ACTION( testinline(forward_code), reqauth, {forward_auth,N(active)}, {forward_auth} );
//eosio::dispatch_inline<account_name>( N(forward_code), N(reqauth), {{forward_auth, N(active)}}, {forward_auth} );
}
};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册