未验证 提交 e2b57c05 编写于 作者: A arhag 提交者: GitHub

Merge branch 'slim' into slim-fix-delay

......@@ -4,7 +4,6 @@ add_subdirectory(http_plugin)
add_subdirectory(chain_plugin)
add_subdirectory(chain_api_plugin)
add_subdirectory(producer_plugin)
add_subdirectory(validator_plugin)
add_subdirectory(history_plugin)
add_subdirectory(history_api_plugin)
......
......@@ -40,9 +40,6 @@ namespace eosio { namespace chain { namespace plugin_interface {
// synchronously push a block/trx to a single provider
using incoming_block_sync = method_decl<chain_plugin_interface, void(const signed_block_ptr&), first_provider_policy>;
using incoming_transaction_sync = method_decl<chain_plugin_interface, transaction_trace_ptr(const packed_transaction_ptr&), first_provider_policy>;
// start the "best" coordinator
using start_coordinator = method_decl<chain_plugin_interface, void(), first_provider_policy>;
}
} } }
\ No newline at end of file
......@@ -48,7 +48,6 @@ public:
,incoming_block_channel(app().get_channel<channels::incoming_block>())
,incoming_block_sync_method(app().get_method<methods::incoming_block_sync>())
,incoming_transaction_sync_method(app().get_method<methods::incoming_transaction_sync>())
,start_coordinator_method(app().get_method<methods::start_coordinator>())
{}
bfs::path block_log_dir;
......@@ -78,7 +77,6 @@ public:
// retained references to methods for easy calling
methods::incoming_block_sync::method_type& incoming_block_sync_method;
methods::incoming_transaction_sync::method_type& incoming_transaction_sync_method;
methods::start_coordinator::method_type& start_coordinator_method;
// method provider handles
methods::get_block_by_number::method_type::handle get_block_by_number_provider;
......@@ -261,8 +259,6 @@ void chain_plugin::plugin_startup()
my->chain_config.reset();
my->start_coordinator_method();
} FC_CAPTURE_LOG_AND_RETHROW( (my->genesis_file.generic_string()) ) }
void chain_plugin::plugin_shutdown() {
......
......@@ -65,9 +65,6 @@ class producer_plugin_impl {
methods::incoming_block_sync::method_type::handle _incoming_block_sync_provider;
methods::incoming_transaction_sync::method_type::handle _incoming_transaction_sync_provider;
methods::start_coordinator::method_type::handle _start_coordinator_provider;
void startup();
void on_block( const block_state_ptr& bsp ) {
if( bsp->header.timestamp <= _last_signed_block_time ) return;
......@@ -129,6 +126,8 @@ class producer_plugin_impl {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
return chain.sync_push(std::make_shared<transaction_metadata>(*trx), fc::time_point::now() + fc::milliseconds(_max_pending_transaction_time_ms));
}
bool start_block();
};
void new_chain_banner(const eosio::chain::controller& db)
......@@ -253,21 +252,13 @@ void producer_plugin::plugin_initialize(const boost::program_options::variables_
} FC_LOG_AND_DROP();
});
static const int my_priority = 1;
my->_incoming_block_sync_provider = app().get_method<methods::incoming_block_sync>().register_provider([this](const signed_block_ptr& block){
my->on_incoming_block(block);
}, my_priority);
});
my->_incoming_transaction_sync_provider = app().get_method<methods::incoming_transaction_sync>().register_provider([this](const packed_transaction_ptr& trx) -> transaction_trace_ptr {
return my->on_incoming_transaction(trx);
}, my_priority);
my->_start_coordinator_provider = app().get_method<methods::start_coordinator>().register_provider([this]() {
my->startup();
}, my_priority);
});
} FC_LOG_AND_RETHROW() }
......@@ -275,55 +266,54 @@ void producer_plugin::plugin_startup()
{ try {
ilog("producer plugin: plugin_startup() begin");
ilog("producer plugin: plugin_startup() end");
} FC_CAPTURE_AND_RETHROW() }
void producer_plugin::plugin_shutdown() {
try {
my->_timer.cancel();
} catch(fc::exception& e) {
edump((e.to_detail_string()));
}
}
void producer_plugin_impl::startup() {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
chain.accepted_block.connect( [this]( const auto& bsp ){ on_block( bsp ); } );
chain.accepted_block.connect( [this]( const auto& bsp ){ my->on_block( bsp ); } );
if (!_producers.empty())
if (!my->_producers.empty())
{
ilog("Launching block production for ${n} producers.", ("n", _producers.size()));
if(_production_enabled)
ilog("Launching block production for ${n} producers.", ("n", my->_producers.size()));
if(my->_production_enabled)
{
if(chain.head_block_num() == 0)
new_chain_banner(chain);
//_production_skip_flags |= eosio::chain::skip_undo_history_check;
}
schedule_production_loop();
my->schedule_production_loop();
} else
elog("No producers configured! Please add producer IDs and private keys to configuration.");
ilog("producer plugin: plugin_startup() end");
} FC_CAPTURE_AND_RETHROW() }
void producer_plugin::plugin_shutdown() {
try {
my->_timer.cancel();
} catch(fc::exception& e) {
edump((e.to_detail_string()));
}
}
void producer_plugin_impl::schedule_production_loop() {
_timer.cancel();
bool producer_plugin_impl::start_block() {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
const auto& hbs = chain.head_block_state();
//Schedule for the next second's tick regardless of chain state
// If we would wait less than 50ms (1/10 of block_interval), wait for the whole block interval.
fc::time_point now = fc::time_point::now();
int64_t time_to_next_block_time = (config::block_interval_us) - (now.time_since_epoch().count() % (config::block_interval_us) );
fc::time_point base = std::max<fc::time_point>(now, chain.head_block_time());
int64_t min_time_to_next_block = (config::block_interval_us) - (now.time_since_epoch().count() % (config::block_interval_us) );
fc::time_point block_time = base + fc::microseconds(min_time_to_next_block);
if(time_to_next_block_time < config::block_interval_us/10 ) { // we must sleep for at least 50ms
ilog("Less than ${t}us to next block time, time_to_next_block_time ${bt}us",
("t", config::block_interval_us/10)("bt", time_to_next_block_time));
time_to_next_block_time += config::block_interval_us;
if((block_time - now) < fc::microseconds(config::block_interval_us/10) ) { // we must sleep for at least 50ms
ilog("Less than ${t}us to next block time, time_to_next_block_time ${bt}",
("t", config::block_interval_us/10)("bt", block_time));
block_time += fc::microseconds(config::block_interval_us);
}
fc::time_point block_time = now + fc::microseconds(time_to_next_block_time);
static const boost::posix_time::ptime epoch(boost::gregorian::date(1970, 1, 1));
_timer.expires_at( epoch + boost::posix_time::microseconds(block_time.time_since_epoch().count()));
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
try {
// determine how many blocks this producer can confirm
// 1) if it is not a producer from this node, assume no confirmations (we will discard this block anyway)
......@@ -356,7 +346,16 @@ void producer_plugin_impl::schedule_production_loop() {
while (chain.push_next_scheduled_transaction(fc::time_point::maximum()));
} FC_LOG_AND_DROP();
return true;
}
return false;
}
void producer_plugin_impl::schedule_production_loop() {
_timer.cancel();
if (start_block()) {
//_timer.async_wait(boost::bind(&producer_plugin_impl::block_production_loop, this));
_timer.async_wait([&](const boost::system::error_code& ec) {
if (ec != boost::asio::error::operation_aborted) {
......
file(GLOB HEADERS "include/eosio/validator_plugin/*.hpp")
add_library( validator_plugin
validator_plugin.cpp
${HEADERS}
)
target_link_libraries( validator_plugin chain_plugin appbase eosio_chain eos_utilities )
target_include_directories( validator_plugin
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" "${CMAKE_CURRENT_SOURCE_DIR}/../chain_interface/include" )
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#pragma once
#include <eosio/chain_plugin/chain_plugin.hpp>
#include <appbase/application.hpp>
namespace eosio {
class validator_plugin : public appbase::plugin<validator_plugin> {
public:
APPBASE_PLUGIN_REQUIRES((chain_plugin))
validator_plugin();
virtual ~validator_plugin();
virtual void set_program_options(
boost::program_options::options_description &command_line_options,
boost::program_options::options_description &config_file_options
) override;
virtual void plugin_initialize(const boost::program_options::variables_map& options);
virtual void plugin_startup();
virtual void plugin_shutdown();
private:
std::unique_ptr<class validator_plugin_impl> my;
};
} //eosio
/**
* @file
* @copyright defined in eos/LICENSE.txt
*/
#include <eosio/validator_plugin/validator_plugin.hpp>
#include <eosio/chain/plugin_interface.hpp>
#include <fc/scoped_exit.hpp>
using std::string;
using std::vector;
namespace eosio {
static appbase::abstract_plugin& _producer_plugin = app().register_plugin<validator_plugin>();
using namespace eosio::chain;
using namespace eosio::chain::plugin_interface;
class validator_plugin_impl {
public:
validator_plugin_impl()
{}
boost::program_options::variables_map _options;
int32_t _max_deferred_transaction_time_ms;
int32_t _max_pending_transaction_time_ms;
channels::incoming_block::channel_type::handle _incoming_block_subscription;
channels::incoming_transaction::channel_type::handle _incoming_transaction_subscription;
methods::incoming_block_sync::method_type::handle _incoming_block_sync_provider;
methods::incoming_transaction_sync::method_type::handle _incoming_transaction_sync_provider;
methods::start_coordinator::method_type::handle _start_coordinator_provider;
void start_block();
void on_incoming_block(const signed_block_ptr& block) {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
// abort the pending block
chain.abort_block();
// exceptions throw out, make sure we restart our loop
auto ensure = fc::make_scoped_exit([this](){
// restart a block
start_block();
});
// push the new block
chain.push_block(block);
ilog("Received block ${id}... #${n} @ ${t} signed by ${p} [trxs: ${count}, lib: ${lib}, confirmed: ${confs}]",
("p",block->producer)("id",fc::variant(block->id()).as_string().substr(0,16))
("n",block_header::num_from_id(block->id()))("t",block->timestamp)
("count",block->transactions.size())("lib",chain.last_irreversible_block_num())("confs", block->confirmed) );
}
transaction_trace_ptr on_incoming_transaction(const packed_transaction_ptr& trx) {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
return chain.sync_push(std::make_shared<transaction_metadata>(*trx), fc::time_point::now() + fc::milliseconds(_max_pending_transaction_time_ms));
}
};
validator_plugin::validator_plugin()
: my(new validator_plugin_impl()){
}
validator_plugin::~validator_plugin() {}
void validator_plugin::set_program_options(
boost::program_options::options_description& command_line_options,
boost::program_options::options_description& config_file_options)
{
config_file_options.add_options()
("validator-max-pending-transaction-time", bpo::value<int32_t>()->default_value(30),
"Limits the maximum time (in milliseconds) that is allowed a pushed transaction's code to execute before being considered invalid")
("validator-max-deferred-transaction-time", bpo::value<int32_t>()->default_value(20),
"Limits the maximum time (in milliseconds) that is allowed a to push deferred transactions at the start of a block")
;
}
void validator_plugin::plugin_initialize(const boost::program_options::variables_map& options)
{ try {
my->_max_deferred_transaction_time_ms = options.at("validator-max-deferred-transaction-time").as<int32_t>();
my->_max_pending_transaction_time_ms = options.at("validator-max-pending-transaction-time").as<int32_t>();
my->_incoming_block_subscription = app().get_channel<channels::incoming_block>().subscribe([this](const signed_block_ptr& block){
try {
my->on_incoming_block(block);
} FC_LOG_AND_DROP();
});
my->_incoming_transaction_subscription = app().get_channel<channels::incoming_transaction>().subscribe([this](const packed_transaction_ptr& trx){
try {
my->on_incoming_transaction(trx);
} FC_LOG_AND_DROP();
});
// this is a low priority default plugin
static const int my_priority = 1000;
my->_incoming_block_sync_provider = app().get_method<methods::incoming_block_sync>().register_provider([this](const signed_block_ptr& block){
my->on_incoming_block(block);
}, my_priority);
my->_incoming_transaction_sync_provider = app().get_method<methods::incoming_transaction_sync>().register_provider([this](const packed_transaction_ptr& trx) -> transaction_trace_ptr {
return my->on_incoming_transaction(trx);
}, my_priority);
my->_start_coordinator_provider = app().get_method<methods::start_coordinator>().register_provider([this]() {
ilog("Launching validating node.");
my->start_block();
}, my_priority);
} FC_LOG_AND_RETHROW() }
void validator_plugin::plugin_startup()
{
}
void validator_plugin::plugin_shutdown() {
}
void validator_plugin_impl::start_block() {
chain::controller& chain = app().get_plugin<chain_plugin>().chain();
chain.abort_block();
chain.start_block();
// TODO: BIG BAD WARNING, THIS WILL HAPPILY BLOW PAST DEADLINES BUT CONTROLLER IS NOT YET SAFE FOR DEADLINE USAGE
try {
while (chain.push_next_unapplied_transaction(fc::time_point::maximum()));
} FC_LOG_AND_DROP();
try {
while (chain.push_next_scheduled_transaction(fc::time_point::maximum()));
} FC_LOG_AND_DROP();
}
} // namespace eosio
......@@ -554,6 +554,42 @@ authority parse_json_authority_or_key(const std::string& authorityJsonOrFile) {
}
}
asset to_asset( const string& code, const string& s ) {
static map<eosio::chain::symbol_code, eosio::chain::symbol> cache;
auto a = asset::from_string( s );
eosio::chain::symbol_code sym = a.sym.to_symbol_code();
auto it = cache.find( sym );
auto sym_str = a.symbol_name();
if ( it == cache.end() ) {
auto json = call(get_currency_stats_func, fc::mutable_variant_object("json", false)
("code", code)
("symbol", sym_str)
);
auto obj = json.get_object();
auto obj_it = obj.find( sym_str );
if (obj_it != obj.end()) {
auto result = obj_it->value().as<eosio::chain_apis::read_only::get_currency_stats_result>();
auto p = cache.insert(make_pair( sym, result.max_supply.sym ));
it = p.first;
} else {
FC_THROW("Symbol ${s} is not supported by token contract ${c}", ("s", sym_str)("c", code));
}
}
auto expected_symbol = it->second;
if ( a.decimals() < expected_symbol.decimals() ) {
auto factor = expected_symbol.precision() / a.precision();
auto a_old = a;
a = asset( a.amount * factor, expected_symbol );
} else if ( a.decimals() > expected_symbol.decimals() ) {
FC_THROW("Too many decimal digits in ${a}, only ${d} supported", ("a", a)("d", expected_symbol.decimals()));
} // else precision matches
return a;
}
inline asset to_asset( const string& s ) {
return to_asset( "eosio.token", s );
}
struct set_account_permission_subcommand {
string accountStr;
string permissionStr;
......@@ -752,9 +788,9 @@ struct create_account_subcommand {
} 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))
action buyram = !buy_ram_eos.empty() ? create_buyram(creator, account_name, to_asset(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) );
action delegate = create_delegate( creator, account_name, to_asset(stake_net), to_asset(stake_cpu) );
send_actions( { create, buyram, delegate } );
} else {
send_actions( { create } );
......@@ -842,8 +878,8 @@ struct delegate_bandwidth_subcommand {
fc::variant act_payload = fc::mutable_variant_object()
("from", from_str)
("receiver", receiver_str)
("stake_net_quantity", stake_net_amount + " EOS")
("stake_cpu_quantity", stake_cpu_amount + " EOS");
("stake_net_quantity", to_asset(stake_net_amount))
("stake_cpu_quantity", to_asset(stake_cpu_amount));
wdump((act_payload));
send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(delegatebw), act_payload)});
});
......@@ -869,8 +905,8 @@ struct undelegate_bandwidth_subcommand {
fc::variant act_payload = fc::mutable_variant_object()
("from", from_str)
("receiver", receiver_str)
("unstake_net_quantity", unstake_net_amount + " EOS")
("unstake_cpu_quantity", unstake_cpu_amount + " EOS");
("unstake_net_quantity", to_asset(unstake_net_amount))
("unstake_cpu_quantity", to_asset(unstake_cpu_amount));
send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(undelegatebw), act_payload)});
});
}
......@@ -891,7 +927,7 @@ struct buyram_subcommand {
fc::variant act_payload = fc::mutable_variant_object()
("payer", from_str)
("receiver", receiver_str)
("quant", asset::from_string(amount));
("quant", to_asset(amount));
send_actions({create_action({permission_level{from_str,config::active_name}}, config::system_account_name, N(buyram), act_payload)});
});
}
......@@ -1084,7 +1120,7 @@ void get_account( const string& accountName, bool json_format ) {
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;
auto net_others = to_asset(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
......@@ -1102,7 +1138,7 @@ void get_account( const string& accountName, bool json_format ) {
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;
auto cpu_others = to_asset(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
......@@ -1610,7 +1646,7 @@ int main( int argc, char** argv ) {
tx_force_unique = false;
}
send_actions({create_transfer(con,sender, recipient, asset::from_string(amount), memo)});
send_actions({create_transfer(con,sender, recipient, to_asset(amount), memo)});
});
// Net subcommand
......
......@@ -53,8 +53,7 @@ target_link_libraries( nodeos
PRIVATE -Wl,${whole_archive_flag} net_api_plugin -Wl,${no_whole_archive_flag}
# PRIVATE -Wl,${whole_archive_flag} faucet_testnet_plugin -Wl,${no_whole_archive_flag}
PRIVATE -Wl,${whole_archive_flag} txn_test_gen_plugin -Wl,${no_whole_archive_flag}
PRIVATE -Wl,${whole_archive_flag} producer_plugin -Wl,${no_whole_archive_flag}
PRIVATE chain_plugin http_plugin validator_plugin
PRIVATE chain_plugin http_plugin producer_plugin
PRIVATE eosio_chain fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} )
#if(BUILD_MONGO_DB_PLUGIN)
......
......@@ -9,7 +9,6 @@
#include <eosio/history_plugin.hpp>
#include <eosio/net_plugin/net_plugin.hpp>
#include <eosio/producer_plugin/producer_plugin.hpp>
#include <eosio/validator_plugin/validator_plugin.hpp>
#include <eosio/utilities/common.hpp>
#include <fc/log/logger_config.hpp>
......@@ -89,7 +88,7 @@ int main(int argc, char** 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, validator_plugin, net_plugin, producer_plugin>(argc, argv))
if(!app().initialize<chain_plugin, http_plugin, net_plugin, producer_plugin>(argc, argv))
return -1;
initialize_logging();
ilog("nodeos version ${ver}", ("ver", eosio::utilities::common::itoh(static_cast<uint32_t>(app().version()))));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册