Wire Sysio Wire Sysion 1.0.0
Loading...
Searching...
No Matches
sysio::producer_plugin Class Reference

#include <producer_plugin.hpp>

Inheritance diagram for sysio::producer_plugin:
Collaboration diagram for sysio::producer_plugin:

Classes

struct  get_account_ram_corrections_params
 
struct  get_account_ram_corrections_result
 
struct  get_supported_protocol_features_params
 
struct  greylist_params
 
struct  integrity_hash_information
 
struct  scheduled_protocol_feature_activations
 
struct  snapshot_information
 
struct  whitelist_blacklist
 

Public Types

template<typename T >
using next_function = std::function<void(const std::variant<fc::exception_ptr, T>&)>
 
- Public Types inherited from appbase::abstract_plugin
enum  state { registered , initialized , started , stopped }
 

Public Member Functions

 APPBASE_PLUGIN_REQUIRES ((chain_plugin)(http_client_plugin)) struct runtime_options
 
 producer_plugin ()
 
virtual ~producer_plugin ()
 
virtual void set_program_options (boost::program_options::options_description &command_line_options, boost::program_options::options_description &config_file_options) override
 
bool is_producer_key (const chain::public_key_type &key) const
 
chain::signature_type sign_compact (const chain::public_key_type &key, const fc::sha256 &digest) const
 
int64_t get_subjective_bill (const account_name &first_auth, const fc::time_point &now) const
 
virtual void plugin_initialize (const boost::program_options::variables_map &options)
 
virtual void plugin_startup ()
 
virtual void plugin_shutdown ()
 
void handle_sighup () override
 
void pause ()
 
void resume ()
 
bool paused () const
 
void update_runtime_options (const runtime_options &options)
 
runtime_options get_runtime_options () const
 
void add_greylist_accounts (const greylist_params &params)
 
void remove_greylist_accounts (const greylist_params &params)
 
greylist_params get_greylist () const
 
whitelist_blacklist get_whitelist_blacklist () const
 
void set_whitelist_blacklist (const whitelist_blacklist &params)
 
integrity_hash_information get_integrity_hash () const
 
void create_snapshot (next_function< snapshot_information > next)
 
scheduled_protocol_feature_activations get_scheduled_protocol_feature_activations () const
 
void schedule_protocol_feature_activations (const scheduled_protocol_feature_activations &schedule)
 
fc::variants get_supported_protocol_features (const get_supported_protocol_features_params &params) const
 
get_account_ram_corrections_result get_account_ram_corrections (const get_account_ram_corrections_params &params) const
 
void log_failed_transaction (const transaction_id_type &trx_id, const chain::packed_transaction_ptr &packed_trx_ptr, const char *reason) const
 
void received_block ()
 
- Public Member Functions inherited from appbase::plugin< producer_plugin >
 plugin ()
 
virtual ~plugin ()
 
virtual state get_state () const override
 
virtual const std::string & name () const override
 
virtual void register_dependencies ()
 
virtual void initialize (const variables_map &options) override
 
virtual void startup () override
 
virtual void shutdown () override
 
- Public Member Functions inherited from appbase::abstract_plugin
virtual ~abstract_plugin ()
 
virtual void set_program_options (options_description &cli, options_description &cfg)=0
 

Additional Inherited Members

- Protected Member Functions inherited from appbase::plugin< producer_plugin >
 plugin (const string &name)
 

Detailed Description

Definition at line 12 of file producer_plugin.hpp.

Member Typedef Documentation

◆ next_function

template<typename T >
using sysio::producer_plugin::next_function = std::function<void(const std::variant<fc::exception_ptr, T>&)>

Definition at line 75 of file producer_plugin.hpp.

Constructor & Destructor Documentation

◆ producer_plugin()

sysio::producer_plugin::producer_plugin ( )

Definition at line 825 of file producer_plugin.cpp.

826 : my(new producer_plugin_impl(app().get_io_service())){
827 }
application & app()
Here is the call graph for this function:

◆ ~producer_plugin()

sysio::producer_plugin::~producer_plugin ( )
virtual

Definition at line 829 of file producer_plugin.cpp.

829{}

Member Function Documentation

◆ add_greylist_accounts()

void sysio::producer_plugin::add_greylist_accounts ( const greylist_params & params)

Definition at line 1329 of file producer_plugin.cpp.

1329 {
1330 SYS_ASSERT(params.accounts.size() > 0, chain::invalid_http_request, "At least one account is required");
1331
1332 chain::controller& chain = my->chain_plug->chain();
1333 for (auto &acc : params.accounts) {
1334 chain.add_resource_greylist(acc);
1335 }
1336}
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
account_query_db::get_accounts_by_authorizers_params params
Here is the call graph for this function:
Here is the caller graph for this function:

◆ APPBASE_PLUGIN_REQUIRES()

sysio::producer_plugin::APPBASE_PLUGIN_REQUIRES ( (chain_plugin)(http_client_plugin) )
inline

Definition at line 14 of file producer_plugin.hpp.

16 {
17 std::optional<int32_t> max_transaction_time;
18 std::optional<int32_t> max_irreversible_block_age;
19 std::optional<int32_t> produce_time_offset_us;
20 std::optional<int32_t> last_block_time_offset_us;
21 std::optional<int32_t> max_scheduled_transaction_time_per_block_ms;
22 std::optional<int32_t> subjective_cpu_leeway_us;
23 std::optional<double> incoming_defer_ratio;
24 std::optional<uint32_t> greylist_limit;
25 };

◆ create_snapshot()

void sysio::producer_plugin::create_snapshot ( next_function< snapshot_information > next)

Definition at line 1402 of file producer_plugin.cpp.

1402 {
1403 chain::controller& chain = my->chain_plug->chain();
1404
1405 auto head_id = chain.head_block_id();
1406 const auto head_block_num = chain.head_block_num();
1407 const auto head_block_time = chain.head_block_time();
1408 const auto& snapshot_path = pending_snapshot::get_final_path(head_id, my->_snapshots_dir);
1409 const auto& temp_path = pending_snapshot::get_temp_path(head_id, my->_snapshots_dir);
1410
1411 // maintain legacy exception if the snapshot exists
1412 if( fc::is_regular_file(snapshot_path) ) {
1413 auto ex = snapshot_exists_exception( FC_LOG_MESSAGE( error, "snapshot named ${name} already exists", ("name", snapshot_path.generic_string()) ) );
1414 next(ex.dynamic_copy_exception());
1415 return;
1416 }
1417
1418 auto write_snapshot = [&]( const bfs::path& p ) -> void {
1419 auto reschedule = fc::make_scoped_exit([this](){
1420 my->schedule_production_loop();
1421 });
1422
1423 if (chain.is_building_block()) {
1424 // abort the pending block
1425 my->abort_block();
1426 } else {
1427 reschedule.cancel();
1428 }
1429
1430 bfs::create_directory( p.parent_path() );
1431
1432 // create the snapshot
1433 auto snap_out = std::ofstream(p.generic_string(), (std::ios::out | std::ios::binary));
1434 auto writer = std::make_shared<ostream_snapshot_writer>(snap_out);
1435 chain.write_snapshot(writer);
1436 writer->finalize();
1437 snap_out.flush();
1438 snap_out.close();
1439 };
1440
1441 // If in irreversible mode, create snapshot and return path to snapshot immediately.
1442 if( chain.get_read_mode() == db_read_mode::IRREVERSIBLE ) {
1443 try {
1444 write_snapshot( temp_path );
1445
1446 boost::system::error_code ec;
1447 bfs::rename(temp_path, snapshot_path, ec);
1448 SYS_ASSERT(!ec, snapshot_finalization_exception,
1449 "Unable to finalize valid snapshot of block number ${bn}: [code: ${ec}] ${message}",
1450 ("bn", head_block_num)
1451 ("ec", ec.value())
1452 ("message", ec.message()));
1453
1454 next( producer_plugin::snapshot_information{head_id, head_block_num, head_block_time, chain_snapshot_header::current_version, snapshot_path.generic_string()} );
1455 } CATCH_AND_CALL (next);
1456 return;
1457 }
1458
1459 // Otherwise, the result will be returned when the snapshot becomes irreversible.
1460
1461 // determine if this snapshot is already in-flight
1462 auto& pending_by_id = my->_pending_snapshot_index.get<by_id>();
1463 auto existing = pending_by_id.find(head_id);
1464 if( existing != pending_by_id.end() ) {
1465 // if a snapshot at this block is already pending, attach this requests handler to it
1466 pending_by_id.modify(existing, [&next]( auto& entry ){
1467 entry.next = [prev = entry.next, next](const std::variant<fc::exception_ptr, producer_plugin::snapshot_information>& res){
1468 prev(res);
1469 next(res);
1470 };
1471 });
1472 } else {
1473 const auto& pending_path = pending_snapshot::get_pending_path(head_id, my->_snapshots_dir);
1474
1475 try {
1476 write_snapshot( temp_path ); // create a new pending snapshot
1477
1478 boost::system::error_code ec;
1479 bfs::rename(temp_path, pending_path, ec);
1480 SYS_ASSERT(!ec, snapshot_finalization_exception,
1481 "Unable to promote temp snapshot to pending for block number ${bn}: [code: ${ec}] ${message}",
1482 ("bn", head_block_num)
1483 ("ec", ec.value())
1484 ("message", ec.message()));
1485
1486 my->_pending_snapshot_index.emplace(head_id, next, pending_path.generic_string(), snapshot_path.generic_string());
1487 } CATCH_AND_CALL (next);
1488 }
1489}
const mie::Vuint & p
Definition bn.cpp:27
#define CATCH_AND_CALL(NEXT)
static bfs::path get_pending_path(const block_id_type &block_id, const bfs::path &snapshots_dir)
static bfs::path get_temp_path(const block_id_type &block_id, const bfs::path &snapshots_dir)
static bfs::path get_final_path(const block_id_type &block_id, const bfs::path &snapshots_dir)
#define FC_LOG_MESSAGE(LOG_LEVEL, FORMAT,...)
A helper method for generating log messages.
scoped_exit< Callback > make_scoped_exit(Callback &&c)
bool is_regular_file(const path &p)
uint32_t next(octet_iterator &it, octet_iterator end)
Definition checked.h:137
static constexpr uint32_t current_version
Here is the call graph for this function:

◆ get_account_ram_corrections()

producer_plugin::get_account_ram_corrections_result sysio::producer_plugin::get_account_ram_corrections ( const get_account_ram_corrections_params & params) const

Definition at line 1553 of file producer_plugin.cpp.

1553 {
1554 get_account_ram_corrections_result result;
1555 const auto& db = my->chain_plug->chain().db();
1556
1557 const auto& idx = db.get_index<chain::account_ram_correction_index, chain::by_name>();
1558 account_name lower_bound_value{ std::numeric_limits<uint64_t>::lowest() };
1559 account_name upper_bound_value{ std::numeric_limits<uint64_t>::max() };
1560
1561 if( params.lower_bound ) {
1562 lower_bound_value = *params.lower_bound;
1563 }
1564
1565 if( params.upper_bound ) {
1566 upper_bound_value = *params.upper_bound;
1567 }
1568
1569 if( upper_bound_value < lower_bound_value )
1570 return result;
1571
1572 auto walk_range = [&]( auto itr, auto end_itr ) {
1573 for( unsigned int count = 0;
1574 count < params.limit && itr != end_itr;
1575 ++itr )
1576 {
1577 result.rows.push_back( fc::variant( *itr ) );
1578 ++count;
1579 }
1580 if( itr != end_itr ) {
1581 result.more = itr->name;
1582 }
1583 };
1584
1585 auto lower = idx.lower_bound( lower_bound_value );
1586 auto upper = idx.upper_bound( upper_bound_value );
1587 if( params.reverse ) {
1588 walk_range( boost::make_reverse_iterator(upper), boost::make_reverse_iterator(lower) );
1589 } else {
1590 walk_range( lower, upper );
1591 }
1592
1593 return result;
1594}
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
int * count
chainbase::shared_multi_index_container< account_ram_correction_object, indexed_by< ordered_unique< tag< by_id >, member< account_ram_correction_object, account_ram_correction_object::id_type, &account_ram_correction_object::id > >, ordered_unique< tag< by_name >, member< account_ram_correction_object, account_name, &account_ram_correction_object::name > > > > account_ram_correction_index
name account_name
Definition types.hpp:120

◆ get_greylist()

producer_plugin::greylist_params sysio::producer_plugin::get_greylist ( ) const

Definition at line 1347 of file producer_plugin.cpp.

1347 {
1348 chain::controller& chain = my->chain_plug->chain();
1349 greylist_params result;
1350 const auto& list = chain.get_resource_greylist();
1351 result.accounts.reserve(list.size());
1352 for (auto &acc: list) {
1353 result.accounts.push_back(acc);
1354 }
1355 return result;
1356}
Here is the call graph for this function:

◆ get_integrity_hash()

producer_plugin::integrity_hash_information sysio::producer_plugin::get_integrity_hash ( ) const

Definition at line 1385 of file producer_plugin.cpp.

1385 {
1386 chain::controller& chain = my->chain_plug->chain();
1387
1388 auto reschedule = fc::make_scoped_exit([this](){
1389 my->schedule_production_loop();
1390 });
1391
1392 if (chain.is_building_block()) {
1393 // abort the pending block
1394 my->abort_block();
1395 } else {
1396 reschedule.cancel();
1397 }
1398
1399 return {chain.head_block_id(), chain.calculate_integrity_hash()};
1400}
Here is the call graph for this function:

◆ get_runtime_options()

producer_plugin::runtime_options sysio::producer_plugin::get_runtime_options ( ) const

Definition at line 1314 of file producer_plugin.cpp.

1314 {
1315 return {
1316 my->_max_transaction_time_ms,
1317 my->_max_irreversible_block_age_us.count() < 0 ? -1 : my->_max_irreversible_block_age_us.count() / 1'000'000,
1318 my->_produce_time_offset_us,
1319 my->_last_block_time_offset_us,
1320 my->_max_scheduled_transaction_time_per_block_ms,
1321 my->chain_plug->chain().get_subjective_cpu_leeway() ?
1322 my->chain_plug->chain().get_subjective_cpu_leeway()->count() :
1323 std::optional<int32_t>(),
1324 my->_incoming_defer_ratio,
1325 my->chain_plug->chain().get_greylist_limit()
1326 };
1327}

◆ get_scheduled_protocol_feature_activations()

producer_plugin::scheduled_protocol_feature_activations sysio::producer_plugin::get_scheduled_protocol_feature_activations ( ) const

Definition at line 1492 of file producer_plugin.cpp.

1492 {
1493 return {my->_protocol_features_to_activate};
1494}

◆ get_subjective_bill()

int64_t sysio::producer_plugin::get_subjective_bill ( const account_name & first_auth,
const fc::time_point & now ) const

Definition at line 917 of file producer_plugin.cpp.

918{
919 return my->_subjective_billing.get_subjective_bill( first_auth, now );
920}

◆ get_supported_protocol_features()

fc::variants sysio::producer_plugin::get_supported_protocol_features ( const get_supported_protocol_features_params & params) const

Definition at line 1514 of file producer_plugin.cpp.

1514 {
1516 const chain::controller& chain = my->chain_plug->chain();
1517 const auto& pfs = chain.get_protocol_feature_manager().get_protocol_feature_set();
1518 const auto next_block_time = chain.head_block_time() + fc::milliseconds(config::block_interval_ms);
1519
1520 flat_map<digest_type, bool> visited_protocol_features;
1521 visited_protocol_features.reserve( pfs.size() );
1522
1523 std::function<bool(const protocol_feature&)> add_feature =
1524 [&results, &pfs, &params, next_block_time, &visited_protocol_features, &add_feature]
1525 ( const protocol_feature& pf ) -> bool {
1526 if( ( params.exclude_disabled || params.exclude_unactivatable ) && !pf.enabled ) return false;
1527 if( params.exclude_unactivatable && ( next_block_time < pf.earliest_allowed_activation_time ) ) return false;
1528
1529 auto res = visited_protocol_features.emplace( pf.feature_digest, false );
1530 if( !res.second ) return res.first->second;
1531
1532 const auto original_size = results.size();
1533 for( const auto& dependency : pf.dependencies ) {
1534 if( !add_feature( pfs.get_protocol_feature( dependency ) ) ) {
1535 results.resize( original_size );
1536 return false;
1537 }
1538 }
1539
1540 res.first->second = true;
1541 results.emplace_back( pf.to_variant(true) );
1542 return true;
1543 };
1544
1545 for( const auto& pf : pfs ) {
1546 add_feature( pf );
1547 }
1548
1549 return results;
1550}
sysio::chain_apis::account_query_db::get_accounts_by_authorizers_params params
constexpr microseconds milliseconds(int64_t s)
Definition time.hpp:33
std::vector< fc::variant > variants
Definition variant.hpp:173
account_query_db::get_accounts_by_authorizers_result results
Here is the call graph for this function:

◆ get_whitelist_blacklist()

producer_plugin::whitelist_blacklist sysio::producer_plugin::get_whitelist_blacklist ( ) const

Definition at line 1358 of file producer_plugin.cpp.

1358 {
1359 chain::controller& chain = my->chain_plug->chain();
1360 return {
1361 chain.get_actor_whitelist(),
1362 chain.get_actor_blacklist(),
1363 chain.get_contract_whitelist(),
1364 chain.get_contract_blacklist(),
1365 chain.get_action_blacklist(),
1366 chain.get_key_blacklist()
1367 };
1368}
Here is the call graph for this function:

◆ handle_sighup()

void sysio::producer_plugin::handle_sighup ( )
overridevirtual

Reimplemented from appbase::plugin< producer_plugin >.

Definition at line 1239 of file producer_plugin.cpp.

1239 {
1246}
static void update(const fc::string &name, logger &log)
Definition logger.cpp:92
const fc::string logger_name("net_plugin_impl")
const std::string trx_trace_failure_logger_name("transaction_trace_failure")
const std::string trx_failed_trace_logger_name("transaction_failure_tracing")
fc::logger _trx_log
fc::logger _trx_trace_success_log
fc::logger _trx_trace_failure_log
const std::string trx_successful_trace_logger_name("transaction_success_tracing")
fc::logger _log
const std::string trx_trace_success_logger_name("transaction_trace_success")
fc::logger _trx_failed_trace_log
fc::logger _trx_successful_trace_log
const std::string trx_logger_name("transaction")
Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_producer_key()

bool sysio::producer_plugin::is_producer_key ( const chain::public_key_type & key) const

Definition at line 909 of file producer_plugin.cpp.

910{
911 auto private_key_itr = my->_signature_providers.find(key);
912 if(private_key_itr != my->_signature_providers.end())
913 return true;
914 return false;
915}
Here is the caller graph for this function:

◆ log_failed_transaction()

void sysio::producer_plugin::log_failed_transaction ( const transaction_id_type & trx_id,
const chain::packed_transaction_ptr & packed_trx_ptr,
const char * reason ) const

Definition at line 2494 of file producer_plugin.cpp.

2494 {
2495 fc_dlog(_trx_failed_trace_log, "[TRX_TRACE] Speculative execution is REJECTING tx: ${txid} : ${why}",
2496 ("txid", trx_id)("why", reason));
2497 fc_dlog(_trx_log, "[TRX_TRACE] Speculative execution is REJECTING tx: ${trx}",
2498 ("entire_trx", packed_trx_ptr ? my->chain_plug->get_log_trx(packed_trx_ptr->get_transaction()) : fc::variant{trx_id}));
2499 fc_dlog(_trx_trace_failure_log, "[TRX_TRACE] Speculative execution is REJECTING tx: ${entire_trx}",
2500 ("entire_trx", packed_trx_ptr ? my->chain_plug->get_log_trx(packed_trx_ptr->get_transaction()) : fc::variant{trx_id}));
2501}
#define fc_dlog(LOGGER, FORMAT,...)
Definition logger.hpp:77

◆ pause()

void sysio::producer_plugin::pause ( )

Definition at line 1248 of file producer_plugin.cpp.

1248 {
1249 fc_ilog(_log, "Producer paused.");
1250 my->_pause_production = true;
1251}
#define fc_ilog(LOGGER, FORMAT,...)
Definition logger.hpp:83

◆ paused()

bool sysio::producer_plugin::paused ( ) const

Definition at line 1267 of file producer_plugin.cpp.

1267 {
1268 return my->_pause_production;
1269}

◆ plugin_initialize()

void sysio::producer_plugin::plugin_initialize ( const boost::program_options::variables_map & options)
virtual

Definition at line 979 of file producer_plugin.cpp.

980{ try {
981 my->chain_plug = app().find_plugin<chain_plugin>();
982 SYS_ASSERT( my->chain_plug, plugin_config_exception, "chain_plugin not found" );
983 my->_options = &options;
984 LOAD_VALUE_SET(options, "producer-name", my->_producers)
985
986 chain::controller& chain = my->chain_plug->chain();
987
988 if( options.count("private-key") )
989 {
990 const std::vector<std::string> key_id_to_wif_pair_strings = options["private-key"].as<std::vector<std::string>>();
991 for (const std::string& key_id_to_wif_pair_string : key_id_to_wif_pair_strings)
992 {
993 try {
994 auto key_id_to_wif_pair = dejsonify<std::pair<public_key_type, private_key_type>>(key_id_to_wif_pair_string);
995 my->_signature_providers[key_id_to_wif_pair.first] = make_key_signature_provider(key_id_to_wif_pair.second);
996 auto blanked_privkey = std::string(key_id_to_wif_pair.second.to_string().size(), '*' );
997 wlog("\"private-key\" is DEPRECATED, use \"signature-provider=${pub}=KEY:${priv}\"", ("pub",key_id_to_wif_pair.first)("priv", blanked_privkey));
998 } catch ( const std::exception& e ) {
999 elog("Malformed private key pair");
1000 }
1001 }
1002 }
1003
1004 if( options.count("signature-provider") ) {
1005 const std::vector<std::string> key_spec_pairs = options["signature-provider"].as<std::vector<std::string>>();
1006 for (const auto& key_spec_pair : key_spec_pairs) {
1007 try {
1008 auto delim = key_spec_pair.find("=");
1009 SYS_ASSERT(delim != std::string::npos, plugin_config_exception, "Missing \"=\" in the key spec pair");
1010 auto pub_key_str = key_spec_pair.substr(0, delim);
1011 auto spec_str = key_spec_pair.substr(delim + 1);
1012
1013 auto spec_delim = spec_str.find(":");
1014 SYS_ASSERT(spec_delim != std::string::npos, plugin_config_exception, "Missing \":\" in the key spec pair");
1015 auto spec_type_str = spec_str.substr(0, spec_delim);
1016 auto spec_data = spec_str.substr(spec_delim + 1);
1017
1018 auto pubkey = public_key_type(pub_key_str);
1019
1020 if (spec_type_str == "KEY") {
1021 my->_signature_providers[pubkey] = make_key_signature_provider(private_key_type(spec_data));
1022 } else if (spec_type_str == "KSYSD") {
1023 my->_signature_providers[pubkey] = make_kiod_signature_provider(my, spec_data, pubkey);
1024 }
1025
1026 } catch (...) {
1027 elog("Malformed signature provider: \"${val}\", ignoring!", ("val", key_spec_pair));
1028 }
1029 }
1030 }
1031
1032 my->_kiod_provider_timeout_us = fc::milliseconds(options.at("kiod-provider-timeout").as<int32_t>());
1033
1034 my->_account_fails.set_max_failures_per_account( options.at("subjective-account-max-failures").as<uint32_t>() );
1035
1036 my->_produce_time_offset_us = options.at("produce-time-offset-us").as<int32_t>();
1037 SYS_ASSERT( my->_produce_time_offset_us <= 0 && my->_produce_time_offset_us >= -config::block_interval_us, plugin_config_exception,
1038 "produce-time-offset-us ${o} must be 0 .. -${bi}", ("bi", config::block_interval_us)("o", my->_produce_time_offset_us) );
1039
1040 my->_last_block_time_offset_us = options.at("last-block-time-offset-us").as<int32_t>();
1041 SYS_ASSERT( my->_last_block_time_offset_us <= 0 && my->_last_block_time_offset_us >= -config::block_interval_us, plugin_config_exception,
1042 "last-block-time-offset-us ${o} must be 0 .. -${bi}", ("bi", config::block_interval_us)("o", my->_last_block_time_offset_us) );
1043
1044 uint32_t cpu_effort_pct = options.at("cpu-effort-percent").as<uint32_t>();
1045 SYS_ASSERT( cpu_effort_pct >= 0 && cpu_effort_pct <= 100, plugin_config_exception,
1046 "cpu-effort-percent ${pct} must be 0 - 100", ("pct", cpu_effort_pct) );
1047 cpu_effort_pct *= config::percent_1;
1048 int32_t cpu_effort_offset_us =
1049 -SYS_PERCENT( config::block_interval_us, chain::config::percent_100 - cpu_effort_pct );
1050
1051 uint32_t last_block_cpu_effort_pct = options.at("last-block-cpu-effort-percent").as<uint32_t>();
1052 SYS_ASSERT( last_block_cpu_effort_pct >= 0 && last_block_cpu_effort_pct <= 100, plugin_config_exception,
1053 "last-block-cpu-effort-percent ${pct} must be 0 - 100", ("pct", last_block_cpu_effort_pct) );
1054 last_block_cpu_effort_pct *= config::percent_1;
1055 int32_t last_block_cpu_effort_offset_us =
1056 -SYS_PERCENT( config::block_interval_us, chain::config::percent_100 - last_block_cpu_effort_pct );
1057
1058 my->_produce_time_offset_us = std::min( my->_produce_time_offset_us, cpu_effort_offset_us );
1059 my->_last_block_time_offset_us = std::min( my->_last_block_time_offset_us, last_block_cpu_effort_offset_us );
1060
1061 my->_max_block_cpu_usage_threshold_us = options.at( "max-block-cpu-usage-threshold-us" ).as<uint32_t>();
1062 SYS_ASSERT( my->_max_block_cpu_usage_threshold_us < config::block_interval_us, plugin_config_exception,
1063 "max-block-cpu-usage-threshold-us ${t} must be 0 .. ${bi}", ("bi", config::block_interval_us)("t", my->_max_block_cpu_usage_threshold_us) );
1064
1065 my->_max_block_net_usage_threshold_bytes = options.at( "max-block-net-usage-threshold-bytes" ).as<uint32_t>();
1066
1067 my->_max_scheduled_transaction_time_per_block_ms = options.at("max-scheduled-transaction-time-per-block-ms").as<int32_t>();
1068
1069 if( options.at( "subjective-cpu-leeway-us" ).as<int32_t>() != config::default_subjective_cpu_leeway_us ) {
1070 chain.set_subjective_cpu_leeway( fc::microseconds( options.at( "subjective-cpu-leeway-us" ).as<int32_t>() ) );
1071 }
1072
1073 fc::microseconds subjective_account_decay_time = fc::minutes(options.at( "subjective-account-decay-time-minutes" ).as<uint32_t>());
1074 SYS_ASSERT( subjective_account_decay_time.count() > 0, plugin_config_exception,
1075 "subjective-account-decay-time-minutes ${dt} must be greater than 0", ("dt", subjective_account_decay_time.to_seconds() / 60));
1076 my->_subjective_billing.set_expired_accumulator_average_window( subjective_account_decay_time );
1077
1078 my->_max_transaction_time_ms = options.at("max-transaction-time").as<int32_t>();
1079
1080 my->_max_irreversible_block_age_us = fc::seconds(options.at("max-irreversible-block-age").as<int32_t>());
1081
1082 auto max_incoming_transaction_queue_size = options.at("incoming-transaction-queue-size-mb").as<uint16_t>() * 1024*1024;
1083
1084 SYS_ASSERT( max_incoming_transaction_queue_size > 0, plugin_config_exception,
1085 "incoming-transaction-queue-size-mb ${mb} must be greater than 0", ("mb", max_incoming_transaction_queue_size) );
1086
1087 my->_unapplied_transactions.set_max_transaction_queue_size( max_incoming_transaction_queue_size );
1088
1089 my->_incoming_defer_ratio = options.at("incoming-defer-ratio").as<double>();
1090
1091 my->_disable_persist_until_expired = options.at("disable-api-persisted-trx").as<bool>();
1092 bool disable_subjective_billing = options.at("disable-subjective-billing").as<bool>();
1093 my->_disable_subjective_p2p_billing = options.at("disable-subjective-p2p-billing").as<bool>();
1094 my->_disable_subjective_api_billing = options.at("disable-subjective-api-billing").as<bool>();
1095 dlog( "disable-subjective-billing: ${s}, disable-subjective-p2p-billing: ${p2p}, disable-subjective-api-billing: ${api}",
1096 ("s", disable_subjective_billing)("p2p", my->_disable_subjective_p2p_billing)("api", my->_disable_subjective_api_billing) );
1097 if( !disable_subjective_billing ) {
1098 my->_disable_subjective_p2p_billing = my->_disable_subjective_api_billing = false;
1099 } else if( !my->_disable_subjective_p2p_billing || !my->_disable_subjective_api_billing ) {
1100 disable_subjective_billing = false;
1101 }
1102 if( disable_subjective_billing ) {
1103 my->_subjective_billing.disable();
1104 ilog( "Subjective CPU billing disabled" );
1105 } else if( !my->_disable_subjective_p2p_billing && !my->_disable_subjective_api_billing ) {
1106 ilog( "Subjective CPU billing enabled" );
1107 } else {
1108 if( my->_disable_subjective_p2p_billing ) ilog( "Subjective CPU billing of P2P trxs disabled " );
1109 if( my->_disable_subjective_api_billing ) ilog( "Subjective CPU billing of API trxs disabled " );
1110 }
1111
1112 auto thread_pool_size = options.at( "producer-threads" ).as<uint16_t>();
1113 SYS_ASSERT( thread_pool_size > 0, plugin_config_exception,
1114 "producer-threads ${num} must be greater than 0", ("num", thread_pool_size));
1115 my->_thread_pool.emplace( "prod", thread_pool_size );
1116
1117 if( options.count( "snapshots-dir" )) {
1118 auto sd = options.at( "snapshots-dir" ).as<bfs::path>();
1119 if( sd.is_relative()) {
1120 my->_snapshots_dir = app().data_dir() / sd;
1121 if (!fc::exists(my->_snapshots_dir)) {
1122 fc::create_directories(my->_snapshots_dir);
1123 }
1124 } else {
1125 my->_snapshots_dir = sd;
1126 }
1127
1128 SYS_ASSERT( fc::is_directory(my->_snapshots_dir), snapshot_directory_not_found_exception,
1129 "No such directory '${dir}'", ("dir", my->_snapshots_dir.generic_string()) );
1130
1131 if (auto resmon_plugin = app().find_plugin<resource_monitor_plugin>()) {
1132 resmon_plugin->monitor_directory(my->_snapshots_dir);
1133 }
1134 }
1135
1136 my->_incoming_block_sync_provider = app().get_method<incoming::methods::block_sync>().register_provider(
1137 [this](const signed_block_ptr& block, const std::optional<block_id_type>& block_id, const block_state_ptr& bsp) {
1138 return my->on_incoming_block(block, block_id, bsp);
1139 });
1140
1141 my->_incoming_transaction_async_provider = app().get_method<incoming::methods::transaction_async>().register_provider(
1142 [this](const packed_transaction_ptr& trx, bool persist_until_expired, bool read_only, bool return_failure_traces, next_function<transaction_trace_ptr> next) -> void {
1143 return my->on_incoming_transaction_async(trx, persist_until_expired, read_only, return_failure_traces, next );
1144 });
1145
1146 if (options.count("greylist-account")) {
1147 std::vector<std::string> greylist = options["greylist-account"].as<std::vector<std::string>>();
1148 greylist_params param;
1149 for (auto &a : greylist) {
1150 param.accounts.push_back(account_name(a));
1151 }
1152 add_greylist_accounts(param);
1153 }
1154
1155 {
1156 uint32_t greylist_limit = options.at("greylist-limit").as<uint32_t>();
1157 chain.set_greylist_limit( greylist_limit );
1158 }
1159
1160 if( options.count("disable-subjective-account-billing") ) {
1161 std::vector<std::string> accounts = options["disable-subjective-account-billing"].as<std::vector<std::string>>();
1162 for( const auto& a : accounts ) {
1163 my->_subjective_billing.disable_account( account_name(a) );
1164 }
1165 }
1166
constexpr uint64_t SYS_PERCENT(uint64_t value, uint32_t percentage)
Definition config.hpp:152
#define LOAD_VALUE_SET(options, op_name, container)
abstract_plugin * find_plugin(const string &name) const
bfs::path data_dir() const
Get data directory.
auto get_method() -> std::enable_if_t< is_method_decl< MethodDecl >::value, typename MethodDecl::method_type & >
constexpr int64_t to_seconds() const
Definition time.hpp:27
constexpr int64_t count() const
Definition time.hpp:26
void add_greylist_accounts(const greylist_params &params)
std::function< void(const std::variant< fc::exception_ptr, T > &)> next_function
#define FC_LOG_AND_RETHROW()
#define wlog(FORMAT,...)
Definition logger.hpp:124
#define dlog(FORMAT,...)
Definition logger.hpp:101
#define ilog(FORMAT,...)
Definition logger.hpp:118
#define elog(FORMAT,...)
Definition logger.hpp:130
@ read_only
bool exists(const path &p)
void create_directories(const path &p)
constexpr microseconds seconds(int64_t s)
Definition time.hpp:32
constexpr microseconds minutes(int64_t m)
Definition time.hpp:34
bool is_directory(const path &p)
method_decl< chain_plugin_interface, void(const packed_transaction_ptr &, bool, bool, bool, next_function< transaction_trace_ptr >), first_provider_policy > transaction_async
method_decl< chain_plugin_interface, bool(const signed_block_ptr &, const std::optional< block_id_type > &, const block_state_ptr &), first_provider_policy > block_sync
fc::crypto::public_key public_key_type
Definition types.hpp:76
std::shared_ptr< const packed_transaction > packed_transaction_ptr
std::shared_ptr< signed_block > signed_block_ptr
Definition block.hpp:105
std::shared_ptr< block_state > block_state_ptr
fc::crypto::private_key private_key_type
Definition types.hpp:77
T dejsonify(const string &s)
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
unsigned short uint16_t
Definition stdint.h:125
unsigned int uint32_t
Definition stdint.h:126
signed int int32_t
Definition stdint.h:123
if(ppFunctionList==NULL)
CK_BYTE_PTR pubkey
Here is the call graph for this function:

◆ plugin_shutdown()

void sysio::producer_plugin::plugin_shutdown ( )
virtual

Definition at line 1218 of file producer_plugin.cpp.

1218 {
1219 try {
1220 my->_timer.cancel();
1221 } catch ( const std::bad_alloc& ) {
1223 } catch ( const boost::interprocess::bad_alloc& ) {
1225 } catch(const fc::exception& e) {
1226 edump((e.to_detail_string()));
1227 } catch(const std::exception& e) {
1229 }
1230
1231 if( my->_thread_pool ) {
1232 my->_thread_pool->stop();
1233 }
1234
1235 app().post( 0, [me = my](){} ); // keep my pointer alive until queue is drained
1236 fc_ilog(_log, "exit shutdown");
1237}
auto post(int priority, Func &&func)
Used to generate a useful error report when an exception is thrown.
Definition exception.hpp:58
std::string to_detail_string(log_level ll=log_level::all) const
static std_exception_wrapper from_current_exception(const std::exception &e)
static void handle_bad_alloc()
#define edump(SEQ)
Definition logger.hpp:162
Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugin_startup()

void sysio::producer_plugin::plugin_startup ( )
virtual

Definition at line 1169 of file producer_plugin.cpp.

1170{ try {
1171 handle_sighup(); // Sets loggers
1172
1173 try {
1174 ilog("producer plugin: plugin_startup() begin");
1175
1176 chain::controller& chain = my->chain_plug->chain();
1177 SYS_ASSERT( my->_producers.empty() || chain.get_read_mode() == chain::db_read_mode::SPECULATIVE, plugin_config_exception,
1178 "node cannot have any producer-name configured because block production is impossible when read_mode is not \"speculative\"" );
1179
1180 SYS_ASSERT( my->_producers.empty() || chain.get_validation_mode() == chain::validation_mode::FULL, plugin_config_exception,
1181 "node cannot have any producer-name configured because block production is not safe when validation_mode is not \"full\"" );
1182
1183 SYS_ASSERT( my->_producers.empty() || my->chain_plug->accept_transactions(), plugin_config_exception,
1184 "node cannot have any producer-name configured because no block production is possible with no [api|p2p]-accepted-transactions" );
1185
1186 my->_accepted_block_connection.emplace(chain.accepted_block.connect( [this]( const auto& bsp ){ my->on_block( bsp ); } ));
1187 my->_accepted_block_header_connection.emplace(chain.accepted_block_header.connect( [this]( const auto& bsp ){ my->on_block_header( bsp ); } ));
1188 my->_irreversible_block_connection.emplace(chain.irreversible_block.connect( [this]( const auto& bsp ){ my->on_irreversible_block( bsp->block ); } ));
1189
1190 const auto lib_num = chain.last_irreversible_block_num();
1191 const auto lib = chain.fetch_block_by_number(lib_num);
1192 if (lib) {
1193 my->on_irreversible_block(lib);
1194 } else {
1195 my->_irreversible_block_time = fc::time_point::maximum();
1196 }
1197
1198 if (!my->_producers.empty()) {
1199 ilog("Launching block production for ${n} producers at ${time}.", ("n", my->_producers.size())("time",fc::time_point::now()));
1200
1201 if (my->_production_enabled) {
1202 if (chain.head_block_num() == 0) {
1203 new_chain_banner(chain);
1204 }
1205 }
1206 }
1207
1208 my->schedule_production_loop();
1209
1210 ilog("producer plugin: plugin_startup() end");
1211 } catch( ... ) {
1212 // always call plugin_shutdown, even on exception
1214 throw;
1215 }
static time_point now()
Definition time.cpp:14
static constexpr time_point maximum()
Definition time.hpp:46
#define FC_CAPTURE_AND_RETHROW(...)
void new_chain_banner(const sysio::chain::controller &db)
Here is the call graph for this function:

◆ received_block()

void sysio::producer_plugin::received_block ( )

Definition at line 2490 of file producer_plugin.cpp.

2490 {
2491 my->_received_block = true;
2492}
Here is the caller graph for this function:

◆ remove_greylist_accounts()

void sysio::producer_plugin::remove_greylist_accounts ( const greylist_params & params)

Definition at line 1338 of file producer_plugin.cpp.

1338 {
1339 SYS_ASSERT(params.accounts.size() > 0, chain::invalid_http_request, "At least one account is required");
1340
1341 chain::controller& chain = my->chain_plug->chain();
1342 for (auto &acc : params.accounts) {
1343 chain.remove_resource_greylist(acc);
1344 }
1345}
Here is the call graph for this function:

◆ resume()

void sysio::producer_plugin::resume ( )

Definition at line 1253 of file producer_plugin.cpp.

1253 {
1254 my->_pause_production = false;
1255 // it is possible that we are only speculating because of this policy which we have now changed
1256 // re-evaluate that now
1257 //
1258 if (my->_pending_block_mode == pending_block_mode::speculating) {
1259 my->abort_block();
1260 fc_ilog(_log, "Producer resumed. Scheduling production.");
1261 my->schedule_production_loop();
1262 } else {
1263 fc_ilog(_log, "Producer resumed.");
1264 }
1265}

◆ schedule_protocol_feature_activations()

void sysio::producer_plugin::schedule_protocol_feature_activations ( const scheduled_protocol_feature_activations & schedule)

Definition at line 1496 of file producer_plugin.cpp.

1496 {
1497 const chain::controller& chain = my->chain_plug->chain();
1498 std::set<digest_type> set_of_features_to_activate( schedule.protocol_features_to_activate.begin(),
1499 schedule.protocol_features_to_activate.end() );
1500 SYS_ASSERT( set_of_features_to_activate.size() == schedule.protocol_features_to_activate.size(),
1501 invalid_protocol_features_to_activate, "duplicate digests" );
1502 chain.validate_protocol_features( schedule.protocol_features_to_activate );
1503 const auto& pfs = chain.get_protocol_feature_manager().get_protocol_feature_set();
1504 for (auto &feature_digest : set_of_features_to_activate) {
1505 const auto& pf = pfs.get_protocol_feature(feature_digest);
1506 SYS_ASSERT( !pf.preactivation_required, protocol_feature_exception,
1507 "protocol feature requires preactivation: ${digest}",
1508 ("digest", feature_digest));
1509 }
1510 my->_protocol_features_to_activate = schedule.protocol_features_to_activate;
1511 my->_protocol_features_signaled = false;
1512}
Here is the call graph for this function:

◆ set_program_options()

void sysio::producer_plugin::set_program_options ( boost::program_options::options_description & command_line_options,
boost::program_options::options_description & config_file_options )
overridevirtual

Definition at line 831 of file producer_plugin.cpp.

834{
835 auto default_priv_key = private_key_type::regenerate<fc::ecc::private_key_shim>(fc::sha256::hash(std::string("nathan")));
836 auto private_key_default = std::make_pair(default_priv_key.get_public_key(), default_priv_key );
837
838 boost::program_options::options_description producer_options;
839
840 producer_options.add_options()
841 ("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.")
842 ("pause-on-startup,x", boost::program_options::bool_switch()->notifier([this](bool p){my->_pause_production = p;}), "Start this node in a state where production is paused")
843 ("max-transaction-time", bpo::value<int32_t>()->default_value(30),
844 "Limits the maximum time (in milliseconds) that is allowed a pushed transaction's code to execute before being considered invalid")
845 ("max-irreversible-block-age", bpo::value<int32_t>()->default_value( -1 ),
846 "Limits the maximum age (in seconds) of the DPOS Irreversible Block for a chain this node will produce blocks on (use negative value to indicate unlimited)")
847 ("producer-name,p", boost::program_options::value<vector<string>>()->composing()->multitoken(),
848 "ID of producer controlled by this node (e.g. inita; may specify multiple times)")
849 ("private-key", boost::program_options::value<vector<string>>()->composing()->multitoken(),
850 "(DEPRECATED - Use signature-provider instead) Tuple of [public key, WIF private key] (may specify multiple times)")
851 ("signature-provider", boost::program_options::value<vector<string>>()->composing()->multitoken()->default_value(
852 {default_priv_key.get_public_key().to_string() + "=KEY:" + default_priv_key.to_string()},
853 default_priv_key.get_public_key().to_string() + "=KEY:" + default_priv_key.to_string()),
854 "Key=Value pairs in the form <public-key>=<provider-spec>\n"
855 "Where:\n"
856 " <public-key> \tis a string form of a vaild SYSIO public key\n\n"
857 " <provider-spec> \tis a string in the form <provider-type>:<data>\n\n"
858 " <provider-type> \tis KEY, or KSYSD\n\n"
859 " KEY:<data> \tis a string form of a valid SYSIO private key which maps to the provided public key\n\n"
860 " KSYSD:<data> \tis the URL where kiod is available and the approptiate wallet(s) are unlocked")
861 ("kiod-provider-timeout", boost::program_options::value<int32_t>()->default_value(5),
862 "Limits the maximum time (in milliseconds) that is allowed for sending blocks to a kiod provider for signing")
863 ("greylist-account", boost::program_options::value<vector<string>>()->composing()->multitoken(),
864 "account that can not access to extended CPU/NET virtual resources")
865 ("greylist-limit", boost::program_options::value<uint32_t>()->default_value(1000),
866 "Limit (between 1 and 1000) on the multiple that CPU/NET virtual resources can extend during low usage (only enforced subjectively; use 1000 to not enforce any limit)")
867 ("produce-time-offset-us", boost::program_options::value<int32_t>()->default_value(0),
868 "Offset of non last block producing time in microseconds. Valid range 0 .. -block_time_interval.")
869 ("last-block-time-offset-us", boost::program_options::value<int32_t>()->default_value(-200000),
870 "Offset of last block producing time in microseconds. Valid range 0 .. -block_time_interval.")
871 ("cpu-effort-percent", bpo::value<uint32_t>()->default_value(config::default_block_cpu_effort_pct / config::percent_1),
872 "Percentage of cpu block production time used to produce block. Whole number percentages, e.g. 80 for 80%")
873 ("last-block-cpu-effort-percent", bpo::value<uint32_t>()->default_value(config::default_block_cpu_effort_pct / config::percent_1),
874 "Percentage of cpu block production time used to produce last block. Whole number percentages, e.g. 80 for 80%")
875 ("max-block-cpu-usage-threshold-us", bpo::value<uint32_t>()->default_value( 5000 ),
876 "Threshold of CPU block production to consider block full; when within threshold of max-block-cpu-usage block can be produced immediately")
877 ("max-block-net-usage-threshold-bytes", bpo::value<uint32_t>()->default_value( 1024 ),
878 "Threshold of NET block production to consider block full; when within threshold of max-block-net-usage block can be produced immediately")
879 ("max-scheduled-transaction-time-per-block-ms", boost::program_options::value<int32_t>()->default_value(100),
880 "Maximum wall-clock time, in milliseconds, spent retiring scheduled transactions in any block before returning to normal transaction processing.")
881 ("subjective-cpu-leeway-us", boost::program_options::value<int32_t>()->default_value( config::default_subjective_cpu_leeway_us ),
882 "Time in microseconds allowed for a transaction that starts with insufficient CPU quota to complete and cover its CPU usage.")
883 ("subjective-account-max-failures", boost::program_options::value<uint32_t>()->default_value(3),
884 "Sets the maximum amount of failures that are allowed for a given account per block.")
885 ("subjective-account-decay-time-minutes", bpo::value<uint32_t>()->default_value( config::account_cpu_usage_average_window_ms / 1000 / 60 ),
886 "Sets the time to return full subjective cpu for accounts")
887 ("incoming-defer-ratio", bpo::value<double>()->default_value(1.0),
888 "ratio between incoming transactions and deferred transactions when both are queued for execution")
889 ("incoming-transaction-queue-size-mb", bpo::value<uint16_t>()->default_value( 1024 ),
890 "Maximum size (in MiB) of the incoming transaction queue. Exceeding this value will subjectively drop transaction with resource exhaustion.")
891 ("disable-api-persisted-trx", bpo::bool_switch()->default_value(false),
892 "Disable the re-apply of API transactions.")
893 ("disable-subjective-billing", bpo::value<bool>()->default_value(true),
894 "Disable subjective CPU billing for API/P2P transactions")
895 ("disable-subjective-account-billing", boost::program_options::value<vector<string>>()->composing()->multitoken(),
896 "Account which is excluded from subjective CPU billing")
897 ("disable-subjective-p2p-billing", bpo::value<bool>()->default_value(true),
898 "Disable subjective CPU billing for P2P transactions")
899 ("disable-subjective-api-billing", bpo::value<bool>()->default_value(true),
900 "Disable subjective CPU billing for API transactions")
901 ("producer-threads", bpo::value<uint16_t>()->default_value(config::default_controller_thread_pool_size),
902 "Number of worker threads in producer thread pool")
903 ("snapshots-dir", bpo::value<bfs::path>()->default_value("snapshots"),
904 "the location of the snapshots directory (absolute path or relative to application data dir)")
905 ;
906 config_file_options.add(producer_options);
907}
static private_key regenerate(const typename KeyType::data_type &data)
static sha256 hash(const char *d, uint32_t dlen)
Definition sha256.cpp:44
fc::string to_string(double)
Definition string.cpp:131
Here is the call graph for this function:

◆ set_whitelist_blacklist()

void sysio::producer_plugin::set_whitelist_blacklist ( const whitelist_blacklist & params)

Definition at line 1370 of file producer_plugin.cpp.

1370 {
1371 SYS_ASSERT(params.actor_whitelist || params.actor_blacklist || params.contract_whitelist || params.contract_blacklist || params.action_blacklist || params.key_blacklist,
1372 chain::invalid_http_request,
1373 "At least one of actor_whitelist, actor_blacklist, contract_whitelist, contract_blacklist, action_blacklist, and key_blacklist is required"
1374 );
1375
1376 chain::controller& chain = my->chain_plug->chain();
1377 if(params.actor_whitelist) chain.set_actor_whitelist(*params.actor_whitelist);
1378 if(params.actor_blacklist) chain.set_actor_blacklist(*params.actor_blacklist);
1379 if(params.contract_whitelist) chain.set_contract_whitelist(*params.contract_whitelist);
1380 if(params.contract_blacklist) chain.set_contract_blacklist(*params.contract_blacklist);
1381 if(params.action_blacklist) chain.set_action_blacklist(*params.action_blacklist);
1382 if(params.key_blacklist) chain.set_key_blacklist(*params.key_blacklist);
1383}
Here is the call graph for this function:

◆ sign_compact()

chain::signature_type sysio::producer_plugin::sign_compact ( const chain::public_key_type & key,
const fc::sha256 & digest ) const

Definition at line 922 of file producer_plugin.cpp.

923{
924 if(key != chain::public_key_type()) {
925 auto private_key_itr = my->_signature_providers.find(key);
926 SYS_ASSERT(private_key_itr != my->_signature_providers.end(), producer_priv_key_not_found, "Local producer has no private key in config.ini corresponding to public key ${key}", ("key", key));
927
928 return private_key_itr->second(digest);
929 }
930 else {
931 return chain::signature_type();
932 }
933}
fc::sha256 digest(const T &value)
Definition digest.hpp:9
fc::crypto::signature signature_type
Definition types.hpp:78
Here is the call graph for this function:
Here is the caller graph for this function:

◆ update_runtime_options()

void sysio::producer_plugin::update_runtime_options ( const runtime_options & options)

Definition at line 1271 of file producer_plugin.cpp.

1271 {
1272 chain::controller& chain = my->chain_plug->chain();
1273 bool check_speculating = false;
1274
1275 if (options.max_transaction_time) {
1276 my->_max_transaction_time_ms = *options.max_transaction_time;
1277 }
1278
1279 if (options.max_irreversible_block_age) {
1280 my->_max_irreversible_block_age_us = fc::seconds(*options.max_irreversible_block_age);
1281 check_speculating = true;
1282 }
1283
1284 if (options.produce_time_offset_us) {
1285 my->_produce_time_offset_us = *options.produce_time_offset_us;
1286 }
1287
1288 if (options.last_block_time_offset_us) {
1289 my->_last_block_time_offset_us = *options.last_block_time_offset_us;
1290 }
1291
1292 if (options.max_scheduled_transaction_time_per_block_ms) {
1293 my->_max_scheduled_transaction_time_per_block_ms = *options.max_scheduled_transaction_time_per_block_ms;
1294 }
1295
1296 if (options.incoming_defer_ratio) {
1297 my->_incoming_defer_ratio = *options.incoming_defer_ratio;
1298 }
1299
1300 if (check_speculating && my->_pending_block_mode == pending_block_mode::speculating) {
1301 my->abort_block();
1302 my->schedule_production_loop();
1303 }
1304
1305 if (options.subjective_cpu_leeway_us) {
1306 chain.set_subjective_cpu_leeway(fc::microseconds(*options.subjective_cpu_leeway_us));
1307 }
1308
1309 if (options.greylist_limit) {
1310 chain.set_greylist_limit(*options.greylist_limit);
1311 }
1312}
Here is the call graph for this function:

The documentation for this class was generated from the following files: