未验证 提交 4b3660f2 编写于 作者: M Matt Witherspoon 提交者: GitHub

Merge pull request #2771 from EOSIO/cleos-pretty-get-account-3

cleos get account pretty print, system newaccount
...@@ -57,6 +57,15 @@ ...@@ -57,6 +57,15 @@
{"name":"cpu_weight", "type":"uint64"}, {"name":"cpu_weight", "type":"uint64"},
{"name":"storage_bytes", "type":"uint64"} {"name":"storage_bytes", "type":"uint64"}
] ]
},{
"name": "user_resources",
"base": "",
"fields": [
{"name":"owner", "type":"account_name"},
{"name":"net_weight", "type":"asset"},
{"name":"cpu_weight", "type":"asset"},
{"name":"storage_bytes", "type":"uint64"}
]
},{ },{
"name": "total_resources", "name": "total_resources",
"base": "", "base": "",
...@@ -257,6 +266,12 @@ ...@@ -257,6 +266,12 @@
"index_type": "i64", "index_type": "i64",
"key_names" : ["owner"], "key_names" : ["owner"],
"key_types" : ["account_name"] "key_types" : ["account_name"]
},{
"name": "userres",
"type": "user_resources",
"index_type": "i64",
"key_names" : ["owner"],
"key_types" : ["uint64"]
},{ },{
"name": "totalband", "name": "totalband",
"type": "total_resources", "type": "total_resources",
......
...@@ -99,6 +99,17 @@ namespace eosio { namespace chain { ...@@ -99,6 +99,17 @@ namespace eosio { namespace chain {
} } // eosio::chain } } // eosio::chain
namespace std {
template<> struct hash<eosio::chain::name> : private hash<uint64_t> {
typedef eosio::chain::name argument_type;
typedef typename hash<uint64_t>::result_type result_type;
result_type operator()(const argument_type& name) const noexcept
{
return hash<uint64_t>::operator()(name.value);
}
};
};
namespace fc { namespace fc {
class variant; class variant;
void to_variant(const eosio::chain::name& c, fc::variant& v); void to_variant(const eosio::chain::name& c, fc::variant& v);
......
...@@ -26,6 +26,12 @@ namespace eosio { namespace chain { namespace resource_limits { ...@@ -26,6 +26,12 @@ namespace eosio { namespace chain { namespace resource_limits {
void validate()const; // throws if the parameters do not satisfy basic sanity checks void validate()const; // throws if the parameters do not satisfy basic sanity checks
}; };
struct account_resource_limit {
int64_t current_per_block = 0;
int64_t max_per_block = 0;
int64_t guaranteed_per_day = 0;
};
class resource_limits_manager { class resource_limits_manager {
public: public:
explicit resource_limits_manager(chainbase::database& db) explicit resource_limits_manager(chainbase::database& db)
...@@ -59,9 +65,15 @@ namespace eosio { namespace chain { namespace resource_limits { ...@@ -59,9 +65,15 @@ namespace eosio { namespace chain { namespace resource_limits {
int64_t get_account_cpu_limit( const account_name& name ) const; int64_t get_account_cpu_limit( const account_name& name ) const;
int64_t get_account_net_limit( const account_name& name ) const; int64_t get_account_net_limit( const account_name& name ) const;
account_resource_limit get_account_cpu_limit_ex( const account_name& name ) const;
account_resource_limit get_account_net_limit_ex( const account_name& name ) const;
int64_t get_account_ram_usage( const account_name& name ) const; int64_t get_account_ram_usage( const account_name& name ) const;
private: private:
chainbase::database& _db; chainbase::database& _db;
}; };
} } } /// eosio::chain } } } /// eosio::chain
FC_REFLECT( eosio::chain::resource_limits::account_resource_limit, (current_per_block)(max_per_block)(guaranteed_per_day) )
...@@ -325,6 +325,7 @@ int64_t resource_limits_manager::get_account_cpu_limit( const account_name& name ...@@ -325,6 +325,7 @@ int64_t resource_limits_manager::get_account_cpu_limit( const account_name& name
uint128_t consumed_ex = (uint128_t)usage.cpu_usage.consumed * (uint128_t)config::rate_limiting_precision; uint128_t consumed_ex = (uint128_t)usage.cpu_usage.consumed * (uint128_t)config::rate_limiting_precision;
uint128_t virtual_capacity_ex = (uint128_t)state.virtual_cpu_limit * (uint128_t)config::rate_limiting_precision; uint128_t virtual_capacity_ex = (uint128_t)state.virtual_cpu_limit * (uint128_t)config::rate_limiting_precision;
uint128_t usable_capacity_ex = (uint128_t)(virtual_capacity_ex * limits.cpu_weight) / (uint128_t)total_cpu_weight; uint128_t usable_capacity_ex = (uint128_t)(virtual_capacity_ex * limits.cpu_weight) / (uint128_t)total_cpu_weight;
if (usable_capacity_ex < consumed_ex) { if (usable_capacity_ex < consumed_ex) {
...@@ -334,6 +335,37 @@ int64_t resource_limits_manager::get_account_cpu_limit( const account_name& name ...@@ -334,6 +335,37 @@ int64_t resource_limits_manager::get_account_cpu_limit( const account_name& name
return (int64_t)((usable_capacity_ex - consumed_ex) / (uint128_t)config::rate_limiting_precision); return (int64_t)((usable_capacity_ex - consumed_ex) / (uint128_t)config::rate_limiting_precision);
} }
account_resource_limit resource_limits_manager::get_account_cpu_limit_ex( const account_name& name ) const {
const auto& cfg = _db.get<resource_limits_config_object>();
const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name);
const auto& limits = _db.get<resource_limits_object, by_owner>(boost::make_tuple(false, name));
if (limits.cpu_weight < 0) {
return { -1, -1, -1 };
}
auto total_cpu_weight = state.total_cpu_weight;
if( total_cpu_weight == 0 ) total_cpu_weight = 1;
uint128_t consumed_ex = (uint128_t)usage.cpu_usage.consumed * (uint128_t)config::rate_limiting_precision;
uint128_t virtual_capacity_ex = (uint128_t)state.virtual_cpu_limit * (uint128_t)config::rate_limiting_precision;
uint128_t usable_capacity_ex = (uint128_t)(virtual_capacity_ex * limits.cpu_weight) / (uint128_t)total_cpu_weight;
uint128_t real_capacity_ex = (uint128_t)cfg.cpu_limit_parameters.target * (uint128_t)config::rate_limiting_precision;
uint128_t guaranteed_capacity_ex = (uint128_t)(real_capacity_ex * limits.cpu_weight) / (uint128_t)total_cpu_weight;
uint128_t blocks_per_day = 86400 * 1000 / config::block_interval_ms;
if (usable_capacity_ex < consumed_ex) {
consumed_ex = usable_capacity_ex;
}
return { (int64_t)(std::min(usable_capacity_ex - consumed_ex, real_capacity_ex) / (uint128_t)config::rate_limiting_precision),
(int64_t)(std::min(usable_capacity_ex, real_capacity_ex) / (uint128_t)config::rate_limiting_precision),
(int64_t)(guaranteed_capacity_ex * blocks_per_day / cfg.cpu_limit_parameters.periods / (uint128_t)config::rate_limiting_precision)
};
}
int64_t resource_limits_manager::get_account_net_limit( const account_name& name ) const { int64_t resource_limits_manager::get_account_net_limit( const account_name& name ) const {
const auto& state = _db.get<resource_limits_state_object>(); const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name); const auto& usage = _db.get<resource_usage_object, by_owner>(name);
...@@ -348,7 +380,7 @@ int64_t resource_limits_manager::get_account_net_limit( const account_name& name ...@@ -348,7 +380,7 @@ int64_t resource_limits_manager::get_account_net_limit( const account_name& name
auto total_net_weight = state.total_net_weight; auto total_net_weight = state.total_net_weight;
if( total_net_weight == 0 ) total_net_weight = 1; if( total_net_weight == 0 ) total_net_weight = 1;
uint128_t usable_capacity_ex = (uint128_t)(virtual_capacity_ex * limits.net_weight) / (uint128_t)total_net_weight; uint128_t usable_capacity_ex = (uint128_t)(virtual_capacity_ex * limits.net_weight) / (uint128_t)total_net_weight; // max
if (usable_capacity_ex < consumed_ex) { if (usable_capacity_ex < consumed_ex) {
return 0; return 0;
...@@ -358,5 +390,36 @@ int64_t resource_limits_manager::get_account_net_limit( const account_name& name ...@@ -358,5 +390,36 @@ int64_t resource_limits_manager::get_account_net_limit( const account_name& name
} }
account_resource_limit resource_limits_manager::get_account_net_limit_ex( const account_name& name ) const {
const auto& cfg = _db.get<resource_limits_config_object>();
const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name);
const auto& limits = _db.get<resource_limits_object, by_owner>(boost::make_tuple(false, name));
if (limits.net_weight < 0) {
return { -1, -1, -1 };
}
auto total_net_weight = state.total_net_weight;
if( total_net_weight == 0 ) total_net_weight = 1;
uint128_t consumed_ex = (uint128_t)usage.net_usage.consumed * (uint128_t)config::rate_limiting_precision;
uint128_t virtual_capacity_ex = (uint128_t)state.virtual_net_limit * (uint128_t)config::rate_limiting_precision;
uint128_t usable_capacity_ex = (uint128_t)(virtual_capacity_ex * limits.net_weight) / (uint128_t)total_net_weight; // max
uint128_t real_capacity_ex = (uint128_t)cfg.net_limit_parameters.target * (uint128_t)config::rate_limiting_precision;
uint128_t guaranteed_capacity_ex = (uint128_t)(real_capacity_ex * limits.net_weight) / (uint128_t)total_net_weight;
uint128_t blocks_per_day = 86400 * 1000 / config::block_interval_ms;
if (usable_capacity_ex < consumed_ex) {
consumed_ex = usable_capacity_ex;
}
return { (int64_t)(std::min(usable_capacity_ex - consumed_ex, real_capacity_ex) / (uint128_t)config::rate_limiting_precision),
(int64_t)(std::min(usable_capacity_ex, real_capacity_ex) / (uint128_t)config::rate_limiting_precision),
(int64_t)(guaranteed_capacity_ex * blocks_per_day / cfg.net_limit_parameters.periods / (uint128_t)config::rate_limiting_precision)
};
}
} } } /// eosio::chain::resource_limits } } } /// eosio::chain::resource_limits
...@@ -515,8 +515,8 @@ read_only::get_account_results read_only::get_account( const get_account_params& ...@@ -515,8 +515,8 @@ read_only::get_account_results read_only::get_account( const get_account_params&
result.last_code_update = a.last_code_update; result.last_code_update = a.last_code_update;
result.created = a.creation_date; result.created = a.creation_date;
result.net_limit = rm.get_account_net_limit( result.account_name ); result.net_limit = rm.get_account_net_limit_ex( result.account_name );
result.cpu_limit = rm.get_account_cpu_limit( result.account_name ); result.cpu_limit = rm.get_account_cpu_limit_ex( result.account_name );
result.ram_usage = rm.get_account_ram_usage( result.account_name ); result.ram_usage = rm.get_account_ram_usage( result.account_name );
const auto& permissions = d.get_index<permission_index,by_owner>(); const auto& permissions = d.get_index<permission_index,by_owner>();
...@@ -538,7 +538,45 @@ read_only::get_account_results read_only::get_account( const get_account_params& ...@@ -538,7 +538,45 @@ read_only::get_account_results read_only::get_account( const get_account_params&
++perm; ++perm;
} }
const auto& code_account = db.db().get<account_object,by_name>( N(eosio) );
//const abi_def abi = get_abi( db, N(eosio) );
abi_def abi;
if( abi_serializer::to_abi(code_account.abi, abi) ) {
abi_serializer abis( abi );
//get_table_rows_ex<key_value_index, by_scope_primary>(p,abi);
const auto* t_id = d.find<chain::table_id_object, chain::by_code_scope_table>(boost::make_tuple( config::system_account_name, params.account_name, N(userres) ));
if (t_id != nullptr) {
const auto &idx = d.get_index<key_value_index, by_scope_primary>();
auto it = idx.lower_bound(boost::make_tuple( t_id->id, params.account_name ));
if ( it != idx.end() ) {
vector<char> data;
copy_inline_row(*it, data);
result.total_resources = abis.binary_to_variant( "user_resources", data );
}
}
t_id = d.find<chain::table_id_object, chain::by_code_scope_table>(boost::make_tuple( config::system_account_name, params.account_name, N(delband) ));
if (t_id != nullptr) {
const auto &idx = d.get_index<key_value_index, by_scope_primary>();
auto it = idx.lower_bound(boost::make_tuple( t_id->id, params.account_name ));
if ( it != idx.end() ) {
vector<char> data;
copy_inline_row(*it, data);
result.delegated_bandwidth = abis.binary_to_variant( "delegated_bandwidth", data );
}
}
t_id = d.find<chain::table_id_object, chain::by_code_scope_table>(boost::make_tuple( config::system_account_name, config::system_account_name, N(voters) ));
if (t_id != nullptr) {
const auto &idx = d.get_index<key_value_index, by_scope_primary>();
auto it = idx.lower_bound(boost::make_tuple( t_id->id, params.account_name ));
if ( it != idx.end() ) {
vector<char> data;
copy_inline_row(*it, data);
result.voter_info = abis.binary_to_variant( "voter_info", data );
}
}
}
return result; return result;
} }
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include <eosio/chain/block.hpp> #include <eosio/chain/block.hpp>
#include <eosio/chain/controller.hpp> #include <eosio/chain/controller.hpp>
#include <eosio/chain/contract_table_objects.hpp> #include <eosio/chain/contract_table_objects.hpp>
#include <eosio/chain/resource_limits.hpp>
#include <eosio/chain/transaction.hpp> #include <eosio/chain/transaction.hpp>
#include <eosio/chain/abi_serializer.hpp> #include <eosio/chain/abi_serializer.hpp>
...@@ -80,6 +81,7 @@ public: ...@@ -80,6 +81,7 @@ public:
name producer_name; name producer_name;
}; };
using account_resource_limit = chain::resource_limits::account_resource_limit;
struct get_account_results { struct get_account_results {
name account_name; name account_name;
...@@ -91,11 +93,15 @@ public: ...@@ -91,11 +93,15 @@ public:
int64_t net_weight = 0; int64_t net_weight = 0;
int64_t cpu_weight = 0; int64_t cpu_weight = 0;
int64_t net_limit = 0; account_resource_limit net_limit;
int64_t cpu_limit = 0; account_resource_limit cpu_limit;
int64_t ram_usage = 0; int64_t ram_usage = 0;
vector<permission> permissions; vector<permission> permissions;
fc::variant total_resources;
fc::variant delegated_bandwidth;
fc::variant voter_info;
}; };
struct get_account_params { struct get_account_params {
...@@ -365,7 +371,7 @@ private: ...@@ -365,7 +371,7 @@ private:
FC_REFLECT( eosio::chain_apis::permission, (perm_name)(parent)(required_auth) ) FC_REFLECT( eosio::chain_apis::permission, (perm_name)(parent)(required_auth) )
FC_REFLECT(eosio::chain_apis::empty, ) FC_REFLECT(eosio::chain_apis::empty, )
FC_REFLECT(eosio::chain_apis::read_only::get_info_results, FC_REFLECT(eosio::chain_apis::read_only::get_info_results,
(server_version)(head_block_num)(last_irreversible_block_num)(last_irreversible_block_id)(head_block_id)(head_block_time)(head_block_producer)(virtual_block_cpu_limit)(virtual_block_net_limit)(block_cpu_limit)(block_net_limit) ) (server_version)(head_block_num)(last_irreversible_block_num)(last_irreversible_block_id)(head_block_id)(head_block_time)(head_block_producer)(virtual_block_cpu_limit)(virtual_block_net_limit)(block_cpu_limit)(block_net_limit) )
FC_REFLECT(eosio::chain_apis::read_only::get_block_params, (block_num_or_id)) FC_REFLECT(eosio::chain_apis::read_only::get_block_params, (block_num_or_id))
FC_REFLECT( eosio::chain_apis::read_write::push_transaction_results, (transaction_id)(processed) ) FC_REFLECT( eosio::chain_apis::read_write::push_transaction_results, (transaction_id)(processed) )
...@@ -377,7 +383,7 @@ FC_REFLECT( eosio::chain_apis::read_only::get_currency_balance_params, (code)(ac ...@@ -377,7 +383,7 @@ FC_REFLECT( eosio::chain_apis::read_only::get_currency_balance_params, (code)(ac
FC_REFLECT( eosio::chain_apis::read_only::get_currency_stats_params, (code)(symbol)); FC_REFLECT( eosio::chain_apis::read_only::get_currency_stats_params, (code)(symbol));
FC_REFLECT( eosio::chain_apis::read_only::get_currency_stats_result, (supply)(max_supply)(issuer)); FC_REFLECT( eosio::chain_apis::read_only::get_currency_stats_result, (supply)(max_supply)(issuer));
FC_REFLECT( eosio::chain_apis::read_only::get_account_results, (account_name)(privileged)(last_code_update)(created)(ram_quota)(net_weight)(cpu_weight)(net_limit)(cpu_limit)(ram_usage)(permissions) ) FC_REFLECT( eosio::chain_apis::read_only::get_account_results, (account_name)(privileged)(last_code_update)(created)(ram_quota)(net_weight)(cpu_weight)(net_limit)(cpu_limit)(ram_usage)(permissions)(total_resources)(delegated_bandwidth)(voter_info) )
FC_REFLECT( eosio::chain_apis::read_only::get_code_results, (account_name)(code_hash)(wast)(abi) ) FC_REFLECT( eosio::chain_apis::read_only::get_code_results, (account_name)(code_hash)(wast)(abi) )
FC_REFLECT( eosio::chain_apis::read_only::get_account_params, (account_name) ) FC_REFLECT( eosio::chain_apis::read_only::get_account_params, (account_name) )
FC_REFLECT( eosio::chain_apis::read_only::get_code_params, (account_name) ) FC_REFLECT( eosio::chain_apis::read_only::get_code_params, (account_name) )
......
...@@ -408,6 +408,16 @@ chain::action create_buyrambytes(const name& creator, const name& newaccount, ui ...@@ -408,6 +408,16 @@ chain::action create_buyrambytes(const name& creator, const name& newaccount, ui
config::system_account_name, N(buyrambytes), act_payload); config::system_account_name, N(buyrambytes), act_payload);
} }
chain::action create_delegate(const name& from, const name& receiver, const asset& net, const asset& cpu) {
fc::variant act_payload = fc::mutable_variant_object()
("from", from.to_string())
("receiver", receiver.to_string())
("stake_net_quantity", net.to_string())
("stake_cpu_quantity", cpu.to_string());
return create_action(tx_permission.empty() ? vector<chain::permission_level>{{from,config::active_name}} : get_account_permissions(tx_permission),
config::system_account_name, N(delegatebw), act_payload);
}
fc::variant regproducer_variant(const account_name& producer, fc::variant regproducer_variant(const account_name& producer,
public_key_type key, public_key_type key,
string url) { string url) {
...@@ -656,6 +666,58 @@ struct register_producer_subcommand { ...@@ -656,6 +666,58 @@ struct register_producer_subcommand {
} }
}; };
struct create_account_subcommand {
string creator;
string account_name;
string owner_key_str;
string active_key_str;
string stake_net;
string stake_cpu;
uint32_t buy_ram_bytes_in_kbytes = 8;
string buy_ram_eos;
bool simple;
create_account_subcommand(CLI::App* actionRoot, bool s) : simple(s) {
auto createAccount = actionRoot->add_subcommand( (simple ? "account" : "newaccount"), localized("Create an account, buy ram, stake for bandwidth for the account"));
createAccount->add_option("creator", creator, localized("The name of the account creating the new account"))->required();
createAccount->add_option("name", account_name, localized("The name of the new account"))->required();
createAccount->add_option("OwnerKey", owner_key_str, localized("The owner public key for the new account"))->required();
createAccount->add_option("ActiveKey", active_key_str, localized("The active public key for the new account"))->required();
if (!simple) {
createAccount->add_option("--stake-net", stake_net,
(localized("The amount of EOS delegated for net bandwidth")))->required();
createAccount->add_option("--stake-cpu", stake_cpu,
(localized("The amount of EOS delegated for CPU bandwidth")))->required();
createAccount->add_option("--buy-ram-bytes", buy_ram_bytes_in_kbytes,
(localized("The amount of RAM bytes to purchase for the new account in kilobytes KiB, default is 8 KiB")));
createAccount->add_option("--buy-ram-EOS", buy_ram_eos,
(localized("The amount of RAM bytes to purchase for the new account in EOS")));
}
add_standard_transaction_options(createAccount);
createAccount->set_callback([this] {
public_key_type owner_key, active_key;
try {
owner_key = public_key_type(owner_key_str);
} EOS_RETHROW_EXCEPTIONS(public_key_type_exception, "Invalid owner public key: ${public_key}", ("public_key", owner_key_str));
try {
active_key = public_key_type(active_key_str);
} EOS_RETHROW_EXCEPTIONS(public_key_type_exception, "Invalid active public key: ${public_key}", ("public_key", active_key_str));
auto create = create_newaccount(creator, account_name, owner_key, active_key);
if (!simple) {
action buyram = !buy_ram_eos.empty() ? create_buyram(creator, account_name, asset::from_string(buy_ram_eos))
: create_buyrambytes(creator, account_name, buy_ram_bytes_in_kbytes * 1024);
action delegate = create_delegate( creator, account_name, asset::from_string(stake_net), asset::from_string(stake_cpu) );
send_actions( { create, buyram, delegate } );
} else {
send_actions( { create } );
}
});
}
};
struct unregister_producer_subcommand { struct unregister_producer_subcommand {
string producer_str; string producer_str;
...@@ -729,7 +791,6 @@ struct delegate_bandwidth_subcommand { ...@@ -729,7 +791,6 @@ struct delegate_bandwidth_subcommand {
delegate_bandwidth->add_option("receiver", receiver_str, localized("The account to receive the delegated bandwidth"))->required(); delegate_bandwidth->add_option("receiver", receiver_str, localized("The account to receive the delegated bandwidth"))->required();
delegate_bandwidth->add_option("stake_net_quantity", stake_net_amount, localized("The amount of EOS to stake for network bandwidth"))->required(); delegate_bandwidth->add_option("stake_net_quantity", stake_net_amount, localized("The amount of EOS to stake for network bandwidth"))->required();
delegate_bandwidth->add_option("stake_cpu_quantity", stake_cpu_amount, localized("The amount of EOS to stake for CPU bandwidth"))->required(); delegate_bandwidth->add_option("stake_cpu_quantity", stake_cpu_amount, localized("The amount of EOS to stake for CPU bandwidth"))->required();
delegate_bandwidth->add_option("stake_storage_quantity", stake_storage_amount, localized("The amount of EOS to stake for storage"))->required();
add_standard_transaction_options(delegate_bandwidth); add_standard_transaction_options(delegate_bandwidth);
delegate_bandwidth->set_callback([this] { delegate_bandwidth->set_callback([this] {
...@@ -737,8 +798,7 @@ struct delegate_bandwidth_subcommand { ...@@ -737,8 +798,7 @@ struct delegate_bandwidth_subcommand {
("from", from_str) ("from", from_str)
("receiver", receiver_str) ("receiver", receiver_str)
("stake_net_quantity", stake_net_amount + " EOS") ("stake_net_quantity", stake_net_amount + " EOS")
("stake_cpu_quantity", stake_cpu_amount + " EOS") ("stake_cpu_quantity", stake_cpu_amount + " EOS");
("stake_storage_quantity", stake_storage_amount + " EOS");
wdump((act_payload)); wdump((act_payload));
send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(delegatebw), act_payload)}); send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(delegatebw), act_payload)});
}); });
...@@ -758,7 +818,6 @@ struct undelegate_bandwidth_subcommand { ...@@ -758,7 +818,6 @@ struct undelegate_bandwidth_subcommand {
undelegate_bandwidth->add_option("receiver", receiver_str, localized("The account to undelegate bandwidth from"))->required(); undelegate_bandwidth->add_option("receiver", receiver_str, localized("The account to undelegate bandwidth from"))->required();
undelegate_bandwidth->add_option("unstake_net_quantity", unstake_net_amount, localized("The amount of EOS to undelegate for network bandwidth"))->required(); undelegate_bandwidth->add_option("unstake_net_quantity", unstake_net_amount, localized("The amount of EOS to undelegate for network bandwidth"))->required();
undelegate_bandwidth->add_option("unstake_cpu_quantity", unstake_cpu_amount, localized("The amount of EOS to undelegate for CPU bandwidth"))->required(); undelegate_bandwidth->add_option("unstake_cpu_quantity", unstake_cpu_amount, localized("The amount of EOS to undelegate for CPU bandwidth"))->required();
undelegate_bandwidth->add_option("unstake_storage_bytes", unstake_storage_bytes, localized("The amount of byte storage to undelegate"))->required();
add_standard_transaction_options(undelegate_bandwidth); add_standard_transaction_options(undelegate_bandwidth);
undelegate_bandwidth->set_callback([this] { undelegate_bandwidth->set_callback([this] {
...@@ -766,13 +825,53 @@ struct undelegate_bandwidth_subcommand { ...@@ -766,13 +825,53 @@ struct undelegate_bandwidth_subcommand {
("from", from_str) ("from", from_str)
("receiver", receiver_str) ("receiver", receiver_str)
("unstake_net_quantity", unstake_net_amount + " EOS") ("unstake_net_quantity", unstake_net_amount + " EOS")
("unstake_cpu_quantity", unstake_cpu_amount + " EOS") ("unstake_cpu_quantity", unstake_cpu_amount + " EOS");
("unstake_storage_bytes", unstake_storage_bytes);
send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(undelegatebw), act_payload)}); send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(undelegatebw), act_payload)});
}); });
} }
}; };
struct buyram_subcommand {
string from_str;
string receiver_str;
string amount;
buyram_subcommand(CLI::App* actionRoot) {
auto buyram = actionRoot->add_subcommand("buyram", localized("Buy RAM"));
buyram->add_option("payer", from_str, localized("The account paying for RAM"))->required();
buyram->add_option("receiver", receiver_str, localized("The account receiving bought RAM"))->required();
buyram->add_option("tokens", amount, localized("The amount of EOS to pay for RAM"))->required();
add_standard_transaction_options(buyram);
buyram->set_callback([this] {
fc::variant act_payload = fc::mutable_variant_object()
("payer", from_str)
("receiver", receiver_str)
("quant", asset::from_string(amount));
send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(buyram), act_payload)});
});
}
};
struct sellram_subcommand {
string from_str;
string receiver_str;
uint64_t amount;
sellram_subcommand(CLI::App* actionRoot) {
auto sellram = actionRoot->add_subcommand("sellram", localized("Sell RAM"));
sellram->add_option("account", receiver_str, localized("The account to receive EOS for sold RAM"))->required();
sellram->add_option("bytes", amount, localized("Number of RAM bytes to sell"))->required();
add_standard_transaction_options(sellram);
sellram->set_callback([this] {
fc::variant act_payload = fc::mutable_variant_object()
("account", receiver_str)
("bytes", amount);
send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(sellram), act_payload)});
});
}
};
struct claimrewards_subcommand { struct claimrewards_subcommand {
string owner; string owner;
...@@ -882,6 +981,124 @@ struct canceldelay_subcommand { ...@@ -882,6 +981,124 @@ struct canceldelay_subcommand {
} }
}; };
void get_account( const string& accountName, bool json_format ) {
auto json = call(get_account_func, fc::mutable_variant_object("account_name", accountName));
auto res = json.as<eosio::chain_apis::read_only::get_account_results>();
if (!json_format) {
std::cout << "privileged: " << ( res.privileged ? "true" : "false") << std::endl;
constexpr size_t indent_size = 5;
const string indent(indent_size, ' ');
std::cout << "permissions: " << std::endl;
unordered_map<name, vector<name>/*children*/> tree;
vector<name> roots; //we don't have multiple roots, but we can easily handle them here, so let's do it just in case
unordered_map<name, eosio::chain_apis::permission> cache;
for ( auto& perm : res.permissions ) {
if ( perm.parent ) {
tree[perm.parent].push_back( perm.perm_name );
} else {
roots.push_back( perm.perm_name );
}
auto name = perm.perm_name; //keep copy before moving `perm`, since thirst argument of emplace can be evaluated first
// looks a little crazy, but should be efficient
cache.insert( std::make_pair(name, std::move(perm)) );
}
std::function<void (account_name, int)> dfs_print = [&]( account_name name, int depth ) -> void {
auto& p = cache.at(name);
std::cout << indent << std::string(depth*3, ' ') << name << ' ' << std::setw(5) << p.required_auth.threshold << ": ";
for ( auto it = p.required_auth.keys.begin(); it != p.required_auth.keys.end(); ++it ) {
if ( it != p.required_auth.keys.begin() ) {
std::cout << ", ";
}
std::cout << it->weight << ' ' << string(it->key);
}
for ( auto& acc : p.required_auth.accounts ) {
std::cout << acc.weight << ' ' << string(acc.permission.actor) << '@' << string(acc.permission.permission) << ", ";
}
std::cout << std::endl;
auto it = tree.find( name );
if (it != tree.end()) {
auto& children = it->second;
sort( children.begin(), children.end() );
for ( auto& n : children ) {
// we have a tree, not a graph, so no need to check for already visited nodes
dfs_print( n, depth+1 );
}
} // else it's a leaf node
};
std::sort(roots.begin(), roots.end());
for ( auto r : roots ) {
dfs_print( r, 0 );
}
std::cout << "memory: " << std::endl
<< indent << "quota: " << std::setw(15) << res.ram_quota << " bytes used: " << std::setw(15) << res.ram_usage << " bytes" << std::endl << std::endl;
std::cout << "net bandwidth:" << std::endl;
if ( res.total_resources.is_object() && res.delegated_bandwidth.is_object() ) {
asset net_own( stoll( res.delegated_bandwidth.get_object()["net_weight"].as_string() ) );
auto net_others = asset::from_string(res.total_resources.get_object()["net_weight"].as_string()) - net_own;
std::cout << indent << "staked:" << std::setw(20) << net_own
<< std::string(11, ' ') << "(total stake delegated from account to self)" << std::endl
<< indent << "delegated:" << std::setw(17) << net_others
<< std::string(11, ' ') << "(total staked delegated to account from others)" << std::endl;
}
std::cout << indent << "current:" << std::setw(15) << ("~"+std::to_string(res.net_limit.current_per_block)) << " bytes/block"
<< std::string(3, ' ') << "(assuming current congestion and current usage)" << std::endl
<< indent << "max:" << std::setw(19) << ("~"+std::to_string(res.net_limit.max_per_block)) << " bytes/block"
<< std::string(3, ' ') << "(assuming current congestion and 0 usage in current window)" << std::endl
<< indent << "guaranteed: " << std::setw(11) << res.net_limit.guaranteed_per_day << " bytes/day"
<< std::string(5, ' ') << "(assuming 100% congestion and 0 usage in current window)" << std::endl
<< std::endl;
std::cout << "cpu bandwidth:" << std::endl;
if ( res.total_resources.is_object() && res.delegated_bandwidth.is_object() ) {
asset cpu_own( stoll( res.delegated_bandwidth.get_object()["cpu_weight"].as_string() ) );
auto cpu_others = asset::from_string(res.total_resources.get_object()["cpu_weight"].as_string()) - cpu_own;
std::cout << indent << "staked:" << std::setw(20) << cpu_own
<< std::string(11, ' ') << "(total stake delegated from account to self)" << std::endl
<< indent << "delegated:" << std::setw(17) << cpu_others
<< std::string(11, ' ') << "(total staked delegated to account from others)" << std::endl;
}
std::cout << indent << "current:" << std::setw(15) << ("~"+std::to_string(res.cpu_limit.current_per_block/1024)) << " kcycle/block"
<< std::string(2, ' ') << "(assuming current congestion and current usage)" << std::endl
<< indent << "max:" << std::setw(19) << ("~"+std::to_string(res.cpu_limit.max_per_block/1024)) << " kcycle/block"
<< std::string(2, ' ') << "(assuming current congestion and 0 usage in current window)" << std::endl
<< indent << "guaranteed:" << std::setw(12) << res.cpu_limit.guaranteed_per_day/1024 << " kcycle/day"
<< std::string(4, ' ') << "(assuming 100% congestion and 0 usage in current window)" << std::endl
<< std::endl;
if ( res.voter_info.is_object() ) {
auto& obj = res.voter_info.get_object();
string proxy = obj["proxy"].as_string();
if ( proxy.empty() ) {
auto& prods = obj["producers"].get_array();
std::cout << "producers:";
if ( !prods.empty() ) {
for ( int i = 0; i < prods.size(); ++i ) {
if ( i%3 == 0 ) {
std::cout << std::endl << indent;
}
std::cout << std::setw(16) << std::left << prods[i].as_string();
}
std::cout << std::endl;
} else {
std::cout << indent << "<not voted>" << std::endl;
}
} else {
std::cout << "proxy:" << indent << proxy << std::endl;
}
}
std::cout << std::endl;
} else {
std::cout << fc::json::to_pretty_string(json) << std::endl;
}
}
int main( int argc, char** argv ) { int main( int argc, char** argv ) {
fc::path binPath = argv[0]; fc::path binPath = argv[0];
if (binPath.is_relative()) { if (binPath.is_relative()) {
...@@ -926,41 +1143,7 @@ int main( int argc, char** argv ) { ...@@ -926,41 +1143,7 @@ int main( int argc, char** argv ) {
}); });
// create account // create account
string creator; auto createAccount = create_account_subcommand( create, true /*simple*/ );
string account_name;
string owner_key_str;
string active_key_str;
uint32_t buy_ram_bytes_in_kbytes = 8;
string buy_ram_eos;
auto createAccount = create->add_subcommand("account", localized("Create a new account on the blockchain"), false);
createAccount->add_option("creator", creator, localized("The name of the account creating the new account"))->required();
createAccount->add_option("name", account_name, localized("The name of the new account"))->required();
createAccount->add_option("OwnerKey", owner_key_str, localized("The owner public key for the new account"))->required();
createAccount->add_option("ActiveKey", active_key_str, localized("The active public key for the new account"))->required();
createAccount->add_option("--buy-ram-bytes", buy_ram_bytes_in_kbytes,
(localized("The amount of RAM bytes to purchase for the new account in kilobytes KiB, default is 8 KiB")));
createAccount->add_option("--buy-ram-EOS", buy_ram_eos,
(localized("The amount of RAM bytes to purchase for the new account in EOS")));
add_standard_transaction_options(createAccount, "creator@active");
createAccount->set_callback([&] {
public_key_type owner_key, active_key;
try {
owner_key = public_key_type(owner_key_str);
} EOS_RETHROW_EXCEPTIONS(public_key_type_exception, "Invalid owner public key: ${public_key}", ("public_key", owner_key_str))
try {
active_key = public_key_type(active_key_str);
} EOS_RETHROW_EXCEPTIONS(public_key_type_exception, "Invalid active public key: ${public_key}", ("public_key", active_key_str))
if( !buy_ram_eos.empty() ) {
action buyact = create_buyram(creator, account_name, asset::from_string(buy_ram_eos));
send_actions({create_newaccount(creator, account_name, owner_key, active_key), buyact});
} else if( buy_ram_bytes_in_kbytes > 0 ){
action buyact = create_buyrambytes(creator, account_name, buy_ram_bytes_in_kbytes * 1024 * 1024);
send_actions({create_newaccount(creator, account_name, owner_key, active_key), buyact});
} else {
send_actions({create_newaccount(creator, account_name, owner_key, active_key)});
}
});
// Get subcommand // Get subcommand
auto get = app.add_subcommand("get", localized("Retrieve various items and information from the blockchain"), false); auto get = app.add_subcommand("get", localized("Retrieve various items and information from the blockchain"), false);
...@@ -982,13 +1165,11 @@ int main( int argc, char** argv ) { ...@@ -982,13 +1165,11 @@ int main( int argc, char** argv ) {
// get account // get account
string accountName; string accountName;
bool print_json;
auto getAccount = get->add_subcommand("account", localized("Retrieve an account from the blockchain"), false); auto getAccount = get->add_subcommand("account", localized("Retrieve an account from the blockchain"), false);
getAccount->add_option("name", accountName, localized("The name of the account to retrieve"))->required(); getAccount->add_option("name", accountName, localized("The name of the account to retrieve"))->required();
getAccount->set_callback([&] { getAccount->add_flag("--json,-j", print_json, localized("Output in JSON format") );
std::cout << fc::json::to_pretty_string(call(get_account_func, getAccount->set_callback([&]() { get_account(accountName, print_json); });
fc::mutable_variant_object("account_name", accountName)))
<< std::endl;
});
// get code // get code
string codeFilename; string codeFilename;
...@@ -1124,6 +1305,7 @@ int main( int argc, char** argv ) { ...@@ -1124,6 +1305,7 @@ int main( int argc, char** argv ) {
}); });
// get actions // get actions
string account_name;
string skip_seq_str; string skip_seq_str;
string num_seq_str; string num_seq_str;
bool printjson = false; bool printjson = false;
...@@ -1867,6 +2049,7 @@ int main( int argc, char** argv ) { ...@@ -1867,6 +2049,7 @@ int main( int argc, char** argv ) {
auto system = app.add_subcommand("system", localized("Send eosio.system contract action to the blockchain."), false); auto system = app.add_subcommand("system", localized("Send eosio.system contract action to the blockchain."), false);
system->require_subcommand(); system->require_subcommand();
auto createAccountSystem = create_account_subcommand( system, false /*simple*/ );
auto registerProducer = register_producer_subcommand(system); auto registerProducer = register_producer_subcommand(system);
auto unregisterProducer = unregister_producer_subcommand(system); auto unregisterProducer = unregister_producer_subcommand(system);
...@@ -1878,6 +2061,9 @@ int main( int argc, char** argv ) { ...@@ -1878,6 +2061,9 @@ int main( int argc, char** argv ) {
auto delegateBandWidth = delegate_bandwidth_subcommand(system); auto delegateBandWidth = delegate_bandwidth_subcommand(system);
auto undelegateBandWidth = undelegate_bandwidth_subcommand(system); auto undelegateBandWidth = undelegate_bandwidth_subcommand(system);
auto biyram = buyram_subcommand(system);
auto sellram = sellram_subcommand(system);
auto claimRewards = claimrewards_subcommand(system); auto claimRewards = claimrewards_subcommand(system);
auto regProxy = regproxy_subcommand(system); auto regProxy = regproxy_subcommand(system);
......
...@@ -488,7 +488,7 @@ class Node(object): ...@@ -488,7 +488,7 @@ class Node(object):
# Create account and return creation transactions. Return transaction json object # Create account and return creation transactions. Return transaction json object
# waitForTransBlock: wait on creation transaction id to appear in a block # waitForTransBlock: wait on creation transaction id to appear in a block
def createAccount(self, account, creatorAccount, stakedDeposit=1000, waitForTransBlock=False): def createAccount(self, account, creatorAccount, stakedDeposit=1000, waitForTransBlock=False):
cmd="%s %s create account -j --buy-ram-bytes 0 %s %s %s %s" % ( cmd="%s %s create account -j %s %s %s %s" % (
Utils.EosClientPath, self.endpointArgs, creatorAccount.name, account.name, Utils.EosClientPath, self.endpointArgs, creatorAccount.name, account.name,
account.ownerPublicKey, account.activePublicKey) account.ownerPublicKey, account.activePublicKey)
...@@ -513,7 +513,7 @@ class Node(object): ...@@ -513,7 +513,7 @@ class Node(object):
return trans return trans
def getEosAccount(self, name): def getEosAccount(self, name):
cmd="%s %s get account %s" % (Utils.EosClientPath, self.endpointArgs, name) cmd="%s %s get account -j %s" % (Utils.EosClientPath, self.endpointArgs, name)
Utils.Debug and Utils.Print("cmd: %s" % (cmd)) Utils.Debug and Utils.Print("cmd: %s" % (cmd))
try: try:
trans=Node.runCmdReturnJson(cmd) trans=Node.runCmdReturnJson(cmd)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册