未验证 提交 bbcc2d9b 编写于 作者: D Daniel Larimer 提交者: GitHub

Merge pull request #2010 from EOSIO/usability

Usability Enhancements of Cleos
......@@ -285,18 +285,39 @@ namespace eosio { namespace chain { namespace contracts {
}
} else {
const auto& st = get_struct(rtype);
const auto& vo = var.get_object();
if( st.base != type_name() ) {
variant_to_binary(resolve_type(st.base), var, ds);
}
for( const auto& field : st.fields ) {
if( vo.contains( string(field.name).c_str() ) ) {
variant_to_binary(field.type, vo[field.name], ds);
if( var.is_object() ) {
const auto& vo = var.get_object();
if( st.base != type_name() ) {
variant_to_binary(resolve_type(st.base), var, ds);
}
for( const auto& field : st.fields ) {
if( vo.contains( string(field.name).c_str() ) ) {
variant_to_binary(field.type, vo[field.name], ds);
}
else {
variant_to_binary(field.type, fc::variant(), ds);
/// TODO: default construct field and write it out
FC_THROW( "Missing '${f}' in variant object", ("f",field.name) );
}
}
} else if( var.is_array() ) {
const auto& va = var.get_array();
FC_ASSERT( st.base == type_name(), "support for base class as array not yet implemented" );
/*if( st.base != type_name() ) {
variant_to_binary(resolve_type(st.base), var, ds);
}
else {
/// TODO: default construct field and write it out
FC_THROW( "Missing '${f}' in variant object", ("f",field.name) );
*/
uint32_t i = 0;
for( const auto& field : st.fields ) {
idump((field.type)(va[i])(i));
if( va.size() > i )
variant_to_binary(field.type, va[i], ds);
else
variant_to_binary(field.type, fc::variant(), ds);
++i;
}
}
}
......
......@@ -36,8 +36,8 @@ struct genesis_state_type {
.max_generated_transaction_count = config::default_max_gen_trx_count
};
time_point initial_timestamp;
public_key_type initial_key;
time_point initial_timestamp = fc::time_point::from_iso_string( "2018-03-01T12:00:00" );;
public_key_type initial_key = fc::variant("EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV").as<public_key_type>();
/**
* Temporary, will be moved elsewhere.
......
......@@ -232,6 +232,7 @@ namespace eosio { namespace chain {
};
struct deferred_reference {
deferred_reference(){}
deferred_reference( const account_name& sender, uint128_t sender_id)
:sender(sender),sender_id(sender_id)
{}
......
......@@ -487,7 +487,7 @@ namespace fc {
return fc::path(std::wstring(app_data_dir));
}();
#else
static fc::path appdir = home_path();
static fc::path appdir = home_path() / ".local/share";
#endif
return appdir;
}
......
......@@ -56,6 +56,17 @@ public:
int64_t transactions_time_limit = DEFAULT_TRANSACTION_TIME_LIMIT;
std::set<account_name> filter_on;
bool init_db = false;
void check_init_db() {
if( !init_db ) {
init_db = true;
auto& db = chain_plug->chain().get_mutable_database();
db.add_index<account_control_history_multi_index>();
db.add_index<account_transaction_history_multi_index>();
db.add_index<public_key_history_multi_index>();
db.add_index<transaction_history_multi_index>();
}
}
private:
struct block_comp
{
......@@ -464,11 +475,19 @@ void account_history_plugin::plugin_initialize(const variables_map& options)
for(auto filter_account : foa)
my->filter_on.emplace(filter_account);
}
my->chain_plug = app().find_plugin<chain_plugin>();
my->chain_plug->chain_config().applied_block_callbacks.emplace_back(
[&impl = my](const chain::block_trace& trace) {
impl->check_init_db();
impl->applied_block(trace);
});
}
void account_history_plugin::plugin_startup()
{
my->chain_plug = app().find_plugin<chain_plugin>();
/*
auto& db = my->chain_plug->chain().get_mutable_database();
db.add_index<account_control_history_multi_index>();
db.add_index<account_transaction_history_multi_index>();
......@@ -478,6 +497,7 @@ void account_history_plugin::plugin_startup()
my->chain_plug->chain().applied_block.connect ([&impl = my](const chain::block_trace& trace) {
impl->applied_block(trace);
});
*/
}
void account_history_plugin::plugin_shutdown()
......
......@@ -166,13 +166,6 @@ void chain_plugin::plugin_initialize(const variables_map& options) {
if(options.count("wasm-runtime"))
my->wasm_runtime = options.at("wasm-runtime").as<vm_type>();
#warning TODO: Rate Limits
/*my->rate_limits.per_auth_account_time_frame_sec = fc::time_point_sec(options.at("per-authorized-account-transaction-msg-rate-limit-time-frame-sec").as<uint32_t>());
my->rate_limits.per_auth_account = options.at("per-authorized-account-transaction-msg-rate-limit").as<uint32_t>();
my->rate_limits.per_code_account_time_frame_sec = fc::time_point_sec(options.at("per-code-account-transaction-msg-rate-limit-time-frame-sec").as<uint32_t>());
my->rate_limits.per_code_account = options.at("per-code-account-transaction-msg-rate-limit").as<uint32_t>();*/
}
void chain_plugin::plugin_startup()
......@@ -319,7 +312,7 @@ read_only::get_table_rows_result read_only::get_table_rows( const read_only::get
vector<asset> read_only::get_currency_balance( const read_only::get_currency_balance_params& p )const {
vector<asset> results;
walk_table<contracts::key_value_index, contracts::by_scope_primary>(p.code, p.account, N(account), [&](const contracts::key_value_object& obj){
walk_table<contracts::key_value_index, contracts::by_scope_primary>(p.code, p.account, N(accounts), [&](const contracts::key_value_object& obj){
share_type balance;
fc::datastream<const char *> ds(obj.value.data(), obj.value.size());
fc::raw::unpack(ds, balance);
......
......@@ -82,7 +82,7 @@ void producer_plugin::set_program_options(
boost::program_options::options_description producer_options;
producer_options.add_options()
("enable-stale-production", boost::program_options::bool_switch()->notifier([this](bool e){my->_production_enabled = e;}), "Enable block production, even if the chain is stale.")
("enable-stale-production,e", boost::program_options::bool_switch()->notifier([this](bool e){my->_production_enabled = e;}), "Enable block production, even if the chain is stale.")
("required-participation", boost::program_options::value<uint32_t>()
->default_value(uint32_t(config::required_producer_participation/config::percent_1))
->notifier([this](uint32_t e) {
......
......@@ -141,7 +141,7 @@ namespace eosio { namespace client { namespace http {
}
FC_ASSERT( !"unable to connect" );
} FC_RETHROW_EXCEPTIONS( error, "Request Path: ${server}:${port}${path}\nRequest Post Data: ${postdata}" ,
("server", server)("port", port)("path", path)("postdata", postdata) )
} FC_CAPTURE_AND_RETHROW() // error, "Request Path: ${server}:${port}${path}\nRequest Post Data: ${postdata}" ,
// ("server", server)("port", port)("path", path)("postdata", postdata) )
}
}}}
\ No newline at end of file
}}}
......@@ -82,7 +82,9 @@ Options:
#include <eosio/chain/config.hpp>
#include <eosio/chain/wast_to_wasm.hpp>
#include <eosio/chain/transaction_trace.hpp>
#include <eosio/chain_plugin/chain_plugin.hpp>
#include <boost/range/algorithm/find_if.hpp>
#include <boost/range/algorithm/sort.hpp>
#include <boost/range/adaptor/transformed.hpp>
......@@ -141,6 +143,7 @@ auto tx_expiration = fc::seconds(30);
bool tx_force_unique = false;
bool tx_dont_broadcast = false;
bool tx_skip_sign = false;
bool tx_print_json = false;
uint32_t tx_cf_cpu_usage = 0;
uint32_t tx_net_usage = 0;
......@@ -161,6 +164,7 @@ void add_standard_transaction_options(CLI::App* cmd, string default_permission =
cmd->add_option("-x,--expiration", parse_exipration, localized("set the time in seconds before a transaction expires, defaults to 30s"));
cmd->add_flag("-f,--force-unique", tx_force_unique, localized("force the transaction to be unique. this will consume extra bandwidth and remove any protections against accidently issuing the same transaction multiple times"));
cmd->add_flag("-s,--skip-sign", tx_skip_sign, localized("Specify if unlocked wallet keys should be used to sign transaction"));
cmd->add_flag("-j,--json", tx_print_json, localized("print result as json"));
cmd->add_flag("-d,--dont-broadcast", tx_dont_broadcast, localized("don't broadcast transaction to the network (just print to stdout)"));
string msg = "An account and permission level to authorize, as in 'account@permission'";
......@@ -284,12 +288,62 @@ fc::variant push_actions(std::vector<chain::action>&& actions, int32_t extra_kcp
return push_transaction(trx, extra_kcpu, compression);
}
void print_result( const fc::variant& result ) {
const auto& processed = result["processed"];
const auto& transaction_id = processed["id"].as_string();
const auto& status = processed["status"].as_string() ;
auto net = processed["net_usage"].as_int64();
auto cpu = processed["cpu_usage"].as_int64();
cout << status << " transaction: " << transaction_id << " " << net << " bytes " << cpu << " cycles\n";
const auto& actions = processed["action_traces"].get_array();
for( const auto& at : actions ) {
auto receiver = at["receiver"].as_string();
const auto& act = at["act"].get_object();
auto code = act["account"].as_string();
auto func = act["name"].as_string();
auto args = fc::json::to_string( act["data"] );
auto console = at["console"].as_string();
/*
if( code == "eosio" && func == "setcode" )
args = args.substr(40)+"...";
if( name(code) == config::system_account_name && func == "setabi" )
args = args.substr(40)+"...";
*/
if( args.size() > 100 ) args = args.substr(0,100) + "...";
cout << "#" << std::setw(14) << right << receiver << " <= " << std::setw(28) << std::left << (code +"::" + func) << " " << args << "\n";
if( console.size() ) {
std::stringstream ss(console);
string line;
std::getline( ss, line );
cout << ">> " << line << "\n";
}
}
}
using std::cout;
void send_actions(std::vector<chain::action>&& actions, int32_t extra_kcpu = 1000, packed_transaction::compression_type compression = packed_transaction::none ) {
std::cout << fc::json::to_pretty_string(push_actions(std::forward<decltype(actions)>(actions), extra_kcpu, compression)) << std::endl;
auto result = push_actions( move(actions), extra_kcpu, compression);
if( tx_print_json ) {
cout << fc::json::to_pretty_string( result );
} else {
print_result( result );
}
}
void send_transaction( signed_transaction& trx, int32_t extra_kcpu, packed_transaction::compression_type compression = packed_transaction::none ) {
std::cout << fc::json::to_pretty_string(push_transaction(trx, extra_kcpu, compression)) << std::endl;
auto result = push_transaction(trx, extra_kcpu, compression);
if( tx_print_json ) {
cout << fc::json::to_pretty_string( result );
} else {
auto trace = result["processed"].as<eosio::chain::transaction_trace>();
print_result( result );
}
}
chain::action create_newaccount(const name& creator, const name& newaccount, public_key_type owner, public_key_type active) {
......@@ -634,15 +688,21 @@ int main( int argc, char** argv ) {
auto result = call(get_currency_balance_func, fc::mutable_variant_object("json", false)
("account", accountName)
("code", code)
("symbol", symbol)
("symbol", symbol=="*" ? fc::variant(symbol) : fc::variant() )
);
const auto& rows = result.get_array();
if (symbol.empty()) {
for( const auto& r : rows ) {
std::cout << r.as_string()
<< std::endl;
}
/*
std::cout << fc::json::to_pretty_string(rows)
<< std::endl;
*/
} else if ( rows.size() > 0 ){
std::cout << fc::json::to_pretty_string(rows[0])
std::cout << rows[0].as_string()
<< std::endl;
}
});
......@@ -705,10 +765,12 @@ int main( int argc, char** argv ) {
// get transactions
string skip_seq_str;
string num_seq_str;
bool printjson = false;
auto getTransactions = get->add_subcommand("transactions", localized("Retrieve all transactions with specific account name referenced in their scope"), false);
getTransactions->add_option("account_name", account_name, localized("name of account to query on"))->required();
getTransactions->add_option("skip_seq", skip_seq_str, localized("Number of most recent transactions to skip (0 would start at most recent transaction)"));
getTransactions->add_option("num_seq", num_seq_str, localized("Number of transactions to return"));
getTransactions->add_flag("--json,-j", printjson, localized("print full json"));
getTransactions->set_callback([&] {
fc::mutable_variant_object arg;
if (skip_seq_str.empty()) {
......@@ -729,19 +791,30 @@ int main( int argc, char** argv ) {
}
}
auto result = call(get_transactions_func, arg);
std::cout << fc::json::to_pretty_string(call(get_transactions_func, arg)) << std::endl;
const auto& trxs = result.get_object()["transactions"].get_array();
for( const auto& t : trxs ) {
const auto& tobj = t.get_object();
int64_t seq_num = tobj["seq_num"].as<int64_t>();
string id = tobj["transaction_id"].as_string();
const auto& trx = tobj["transaction"].get_object();
const auto& data = trx["data"].get_object();
const auto& exp = data["expiration"].as<fc::time_point_sec>();
const auto& msgs = data["actions"].get_array();
std::cout << tobj["seq_num"].as_string() <<"] " << id << " " << data["expiration"].as_string() << std::endl;
if( printjson ) {
std::cout << fc::json::to_pretty_string(call(get_transactions_func, arg)) << std::endl;
}
else {
const auto& trxs = result.get_object()["transactions"].get_array();
for( const auto& t : trxs ) {
const auto& tobj = t.get_object();
const auto& trx = tobj["transaction"].get_object();
const auto& data = trx["data"].get_object();
const auto& msgs = data["actions"].get_array();
for( const auto& msg : msgs ) {
int64_t seq_num = tobj["seq_num"].as<int64_t>();
string id = tobj["transaction_id"].as_string();
const auto& exp = data["expiration"].as<fc::time_point_sec>();
std::cout << tobj["seq_num"].as_string() <<"] " << id.substr(0,8) << "... " << data["expiration"].as_string() << " ";
auto code = msg["account"].as_string();
auto func = msg["name"].as_string();
auto args = fc::json::to_string( msg["data"] );
std::cout << setw(26) << left << (code + "::" + func) << " " << args;
std::cout << std::endl;
}
}
}
});
......@@ -752,19 +825,37 @@ int main( int argc, char** argv ) {
// set contract subcommand
string account;
string contractPath;
string wastPath;
string abiPath;
auto contractSubcommand = setSubcommand->add_subcommand("contract", localized("Create or update the contract on an account"));
contractSubcommand->add_option("account", account, localized("The account to publish a contract for"))->required();
contractSubcommand->add_option("wast-file", wastPath, localized("The file containing the contract WAST or WASM"))->required()
->check(CLI::ExistingFile);
auto abi = contractSubcommand->add_option("abi-file,-a,--abi", abiPath, localized("The ABI for the contract"))
->check(CLI::ExistingFile);
contractSubcommand->add_option("account", account, localized("The account to publish a contract for"))
->required();
contractSubcommand->add_option("contract-dir", contractPath, localized("The the path containing the .wast and .abi"))
->required();
contractSubcommand->add_option("wast-file", wastPath, localized("The file containing the contract WAST or WASM relative to contract-dir"));
// ->check(CLI::ExistingFile);
auto abi = contractSubcommand->add_option("abi-file,-a,--abi", abiPath, localized("The ABI for the contract relative to contract-dir"));
// ->check(CLI::ExistingFile);
add_standard_transaction_options(contractSubcommand, "account@active");
contractSubcommand->set_callback([&] {
std::string wast;
std::cout << localized("Reading WAST...") << std::endl;
fc::path cpath(contractPath);
if( cpath.filename().generic_string() == "." ) cpath = cpath.parent_path();
if( wastPath == string() )
{
wastPath = (cpath / (cpath.filename().generic_string()+".wast")).generic_string();
}
if( abiPath == string() )
{
abiPath = (cpath / (cpath.filename().generic_string()+".abi")).generic_string();
}
fc::read_file_contents(wastPath, wast);
vector<uint8_t> wasm;
......@@ -781,14 +872,21 @@ int main( int argc, char** argv ) {
std::vector<chain::action> actions;
actions.emplace_back( create_setcode(account, bytes(wasm.begin(), wasm.end()) ) );
if (abi->count()) {
try {
actions.emplace_back( create_setabi(account, fc::json::from_file(abiPath).as<contracts::abi_def>()) );
} EOS_RETHROW_EXCEPTIONS(abi_type_exception, "Fail to parse ABI JSON")
}
FC_ASSERT( fc::exists( abiPath ), "no abi file found ${f}", ("f", abiPath) );
try {
actions.emplace_back( create_setabi(account, fc::json::from_file(abiPath).as<contracts::abi_def>()) );
} EOS_RETHROW_EXCEPTIONS(abi_type_exception, "Fail to parse ABI JSON")
std::cout << localized("Publishing contract...") << std::endl;
send_actions(std::move(actions), 10000, packed_transaction::zlib);
/*
auto result = push_actions(std::move(actions), 10000, packed_transaction::zlib);
if( tx_dont_broadcast ) {
std::cout << fc::json::to_pretty_string(result) << "\n";
}
*/
});
// set account
......@@ -1012,10 +1110,9 @@ int main( int argc, char** argv ) {
add_standard_transaction_options(actionsSubcommand);
actionsSubcommand->set_callback([&] {
ilog("Converting argument to binary...");
fc::variant action_args_var;
try {
action_args_var = fc::json::from_string(data);
action_args_var = fc::json::from_string(data, fc::json::relaxed_parser);
} EOS_RETHROW_EXCEPTIONS(action_type_exception, "Fail to parse action JSON")
auto arg= fc::mutable_variant_object
......
......@@ -7,6 +7,7 @@
#include <eosio/chain_plugin/chain_plugin.hpp>
#include <eosio/http_plugin/http_plugin.hpp>
#include <eosio/net_plugin/net_plugin.hpp>
#include <eosio/producer_plugin/producer_plugin.hpp>
#include <eosio/txn_test_gen_plugin/txn_test_gen_plugin.hpp>
#include <fc/log/logger_config.hpp>
......@@ -77,35 +78,14 @@ void initialize_logging()
logging_conf_loop();
}
bfs::path determine_root_directory()
{
bfs::path root;
char* path = std::getenv("EOSIO_ROOT");
if(path != nullptr)
root = bfs::path(path);
else {
bfs::path p = boost::dll::program_location();
while(p != p.root_directory()) {
p = p.parent_path();
if(exists(p / "etc")) {
root = p;
break;
}
}
if(p == p.root_directory())
root = p;
}
return root;
}
int main(int argc, char** argv)
{
try {
app().set_version(eosio::nodeos::config::version);
bfs::path root = determine_root_directory();
app().set_default_data_dir(root / "var/lib/eosio/node_00");
app().set_default_config_dir(root / "etc/eosio/node_00");
if(!app().initialize<chain_plugin, http_plugin, net_plugin, txn_test_gen_plugin>(argc, argv))
auto root = fc::app_path();
app().set_default_data_dir(root / "eosio/nodeos/data" );
app().set_default_config_dir(root / "eosio/nodeos/config" );
if(!app().initialize<chain_plugin, http_plugin, net_plugin, txn_test_gen_plugin, producer_plugin>(argc, argv))
return -1;
initialize_logging();
ilog("nodeos version ${ver}", ("ver", eosio::nodeos::config::itoh(static_cast<uint32_t>(app().version()))));
......
......@@ -47,7 +47,7 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/consensus-validation-malicious-produc
#To run chain_test with all log from blockchain displayed, put --verbose after --, i.e. chain_test -- --verbose
add_test(NAME chain_test_binaryen COMMAND chain_test --report_level=detailed --color_output -- --binaryen)
add_test(NAME chain_test_wavm COMMAND chain_test --report_level=detailed --color_output -- --wavm)
add_test(NAME nodeos_run_test COMMAND tests/nodeos_run_test.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
#add_test(NAME nodeos_run_test COMMAND tests/nodeos_run_test.py -v --dump-error-detail WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
# add_test(NAME nodeos_run_remote_test COMMAND tests/nodeos_run_remote_test.py --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})
if(BUILD_MONGO_DB_PLUGIN)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册