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

#include <chain_plugin.hpp>

Inheritance diagram for sysio::chain_plugin:
Collaboration diagram for sysio::chain_plugin:

Public Member Functions

 chain_plugin ()
 
virtual ~chain_plugin ()
 
virtual void set_program_options (options_description &cli, options_description &cfg) override
 
void plugin_initialize (const variables_map &options)
 
void plugin_startup ()
 
void plugin_shutdown ()
 
void handle_sighup () override
 
chain_apis::read_write get_read_write_api ()
 
chain_apis::read_only get_read_only_api () const
 
bool accept_block (const chain::signed_block_ptr &block, const chain::block_id_type &id, const chain::block_state_ptr &bsp)
 
void accept_transaction (const chain::packed_transaction_ptr &trx, chain::plugin_interface::next_function< chain::transaction_trace_ptr > next)
 
controllerchain ()
 
const controllerchain () const
 
chain::chain_id_type get_chain_id () const
 
fc::microseconds get_abi_serializer_max_time () const
 
bool api_accept_transactions () const
 
bool accept_transactions () const
 
void enable_accept_transactions ()
 
void do_hard_replay (const variables_map &options)
 
bool account_queries_enabled () const
 
bool transaction_finality_status_enabled () const
 
fc::variant get_log_trx_trace (const chain::transaction_trace_ptr &trx_trace) const
 
fc::variant get_log_trx (const transaction &trx) const
 
- Public Member Functions inherited from appbase::plugin< chain_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 ()
 

Static Public Member Functions

static void handle_guard_exception (const chain::guard_exception &e)
 
static void handle_db_exhaustion ()
 
static void handle_bad_alloc ()
 

Additional Inherited Members

- Public Types inherited from appbase::abstract_plugin
enum  state { registered , initialized , started , stopped }
 
- Protected Member Functions inherited from appbase::plugin< chain_plugin >
 plugin (const string &name)
 

Detailed Description

Definition at line 763 of file chain_plugin.hpp.

Constructor & Destructor Documentation

◆ chain_plugin()

◆ ~chain_plugin()

chain_plugin::~chain_plugin ( )
virtual

Definition at line 207 of file chain_plugin.cpp.

207{}

Member Function Documentation

◆ accept_block()

bool chain_plugin::accept_block ( const chain::signed_block_ptr & block,
const chain::block_id_type & id,
const chain::block_state_ptr & bsp )

Definition at line 1334 of file chain_plugin.cpp.

1334 {
1335 return my->incoming_block_sync_method(block, id, bsp);
1336}
Here is the caller graph for this function:

◆ accept_transaction()

void chain_plugin::accept_transaction ( const chain::packed_transaction_ptr & trx,
chain::plugin_interface::next_function< chain::transaction_trace_ptr > next )

Definition at line 1338 of file chain_plugin.cpp.

1338 {
1339 my->incoming_transaction_async_method(trx, false, false, false, std::move(next));
1340}
Here is the caller graph for this function:

◆ accept_transactions()

bool chain_plugin::accept_transactions ( ) const

Definition at line 1357 of file chain_plugin.cpp.

1357 {
1358 return my->accept_transactions;
1359}
Here is the caller graph for this function:

◆ account_queries_enabled()

bool chain_plugin::account_queries_enabled ( ) const

Definition at line 1395 of file chain_plugin.cpp.

1395 {
1396 return my->account_queries_enabled;
1397}

◆ api_accept_transactions()

bool chain_plugin::api_accept_transactions ( ) const

Definition at line 1353 of file chain_plugin.cpp.

1353 {
1354 return my->api_accept_transactions;
1355}

◆ chain() [1/2]

controller & chain_plugin::chain ( )

Definition at line 1342 of file chain_plugin.cpp.

1342{ return *my->chain; }
Here is the caller graph for this function:

◆ chain() [2/2]

const controller & chain_plugin::chain ( ) const

Definition at line 1343 of file chain_plugin.cpp.

1343{ return *my->chain; }

◆ do_hard_replay()

void chain_plugin::do_hard_replay ( const variables_map & options)

Definition at line 648 of file chain_plugin.cpp.

648 {
649 ilog( "Hard replay requested: deleting state database" );
650 clear_directory_contents( my->chain_config->state_dir );
651 auto backup_dir = block_log::repair_log( my->blocks_dir, options.at( "truncate-at-block" ).as<uint32_t>(), config::reversible_blocks_dir_name);
652}
static fc::path repair_log(const fc::path &data_dir, uint32_t truncate_at_block=0, const char *reversible_block_dir_name="")
#define ilog(FORMAT,...)
Definition logger.hpp:118
void clear_directory_contents(const fc::path &p)
unsigned int uint32_t
Definition stdint.h:126
Here is the call graph for this function:
Here is the caller graph for this function:

◆ enable_accept_transactions()

void chain_plugin::enable_accept_transactions ( )

Definition at line 1361 of file chain_plugin.cpp.

1361 {
1362 my->accept_transactions = true;
1363}
Here is the caller graph for this function:

◆ get_abi_serializer_max_time()

fc::microseconds chain_plugin::get_abi_serializer_max_time ( ) const

Definition at line 1349 of file chain_plugin.cpp.

1349 {
1350 return my->abi_serializer_max_time_us;
1351}
Here is the caller graph for this function:

◆ get_chain_id()

chain::chain_id_type chain_plugin::get_chain_id ( ) const

Definition at line 1345 of file chain_plugin.cpp.

1345 {
1346 return my->chain->get_chain_id();
1347}

◆ get_log_trx()

fc::variant chain_plugin::get_log_trx ( const transaction & trx) const

Definition at line 2747 of file chain_plugin.cpp.

2747 {
2748 fc::variant pretty_output;
2749 try {
2750 abi_serializer::to_log_variant(trx, pretty_output,
2753 } catch (...) {
2754 pretty_output = trx;
2755 }
2756 return pretty_output;
2757}
stores null, int64, uint64, double, bool, string, std::vector<variant>, and variant_object's.
Definition variant.hpp:191
fc::microseconds get_abi_serializer_max_time() const
auto make_resolver(const controller &control, abi_serializer::yield_function_t yield)
static yield_function_t create_yield_function(const fc::microseconds &max_serialization_time)
static void to_log_variant(const T &o, fc::variant &vo, Resolver resolver, const yield_function_t &yield)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_log_trx_trace()

fc::variant chain_plugin::get_log_trx_trace ( const chain::transaction_trace_ptr & trx_trace) const

Definition at line 2735 of file chain_plugin.cpp.

2735 {
2736 fc::variant pretty_output;
2737 try {
2738 abi_serializer::to_log_variant(trx_trace, pretty_output,
2741 } catch (...) {
2742 pretty_output = trx_trace;
2743 }
2744 return pretty_output;
2745}
Here is the call graph for this function:

◆ get_read_only_api()

chain_apis::read_only chain_plugin::get_read_only_api ( ) const

Definition at line 1329 of file chain_plugin.cpp.

1329 {
1330 return chain_apis::read_only(chain(), my->_account_query_db, get_abi_serializer_max_time(), my->producer_plug, my->_trx_finality_status_processing.get());
1331}
Here is the caller graph for this function:

◆ get_read_write_api()

chain_apis::read_write chain_plugin::get_read_write_api ( )

Definition at line 1325 of file chain_plugin.cpp.

1325 {
1326 return chain_apis::read_write(chain(), my->_trx_retry_db, get_abi_serializer_max_time(), api_accept_transactions());
1327}
bool api_accept_transactions() const

◆ handle_bad_alloc()

void chain_plugin::handle_bad_alloc ( )
static

Definition at line 1389 of file chain_plugin.cpp.

1389 {
1390 elog("std::bad_alloc - memory exhausted");
1391 //return -2 -- it's what programs/nodeop/main.cpp reports for std::exception
1392 std::_Exit(-2);
1393}
#define elog(FORMAT,...)
Definition logger.hpp:130
Here is the caller graph for this function:

◆ handle_db_exhaustion()

void chain_plugin::handle_db_exhaustion ( )
static

Definition at line 1383 of file chain_plugin.cpp.

1383 {
1384 elog("database memory exhausted: increase chain-state-db-size-mb");
1385 //return 1 -- it's what programs/nodeop/main.cpp considers "BAD_ALLOC"
1386 std::_Exit(1);
1387}
Here is the caller graph for this function:

◆ handle_guard_exception()

void chain_plugin::handle_guard_exception ( const chain::guard_exception & e)
static

Definition at line 1375 of file chain_plugin.cpp.

1375 {
1376 log_guard_exception(e);
1377
1378 elog("database chain::guard_exception, quitting..."); // log string searched for in: tests/nodeop_under_min_avail_ram.py
1379 // quit the app
1380 app().quit();
1381}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handle_sighup()

void chain_plugin::handle_sighup ( )
overridevirtual

Reimplemented from appbase::plugin< chain_plugin >.

Definition at line 1308 of file chain_plugin.cpp.

1308 {
1309 _deep_mind_log.update_logger( deep_mind_logger_name );
1310}
FC_REFLECT_ENUM(chainbase::environment::os_t,(OS_LINUX)(OS_MACOS)(OS_WINDOWS)(OS_OTHER)) FC_REFLECT_ENUM(chainbase sysio::chain::deep_mind_handler _deep_mind_log
void update_logger(const std::string &logger_name)
Definition deep_mind.cpp:34
Here is the call graph for this function:
Here is the caller graph for this function:

◆ plugin_initialize()

void chain_plugin::plugin_initialize ( const variables_map & options)

Definition at line 654 of file chain_plugin.cpp.

654 {
655 ilog("initializing chain plugin");
656
657 try {
658 try {
659 genesis_state gs; // Check if SYSIO_ROOT_KEY is bad
660 } catch ( const std::exception& ) {
661 elog( "SYSIO_ROOT_KEY ('${root_key}') is invalid. Recompile with a valid public key.",
662 ("root_key", genesis_state::sysio_root_key));
663 throw;
664 }
665
666 my->chain_config = controller::config();
667
668 if( options.at( "print-build-info" ).as<bool>() || options.count( "extract-build-info") ) {
669 if( options.at( "print-build-info" ).as<bool>() ) {
670 ilog( "Build environment JSON:\n${e}", ("e", json::to_pretty_string( chainbase::environment() )) );
671 }
672 if( options.count( "extract-build-info") ) {
673 auto p = options.at( "extract-build-info" ).as<bfs::path>();
674
675 if( p.is_relative()) {
676 p = bfs::current_path() / p;
677 }
678
679 SYS_ASSERT( fc::json::save_to_file( chainbase::environment(), p, true ), misc_exception,
680 "Error occurred while writing build info JSON to '${path}'",
681 ("path", p.generic_string())
682 );
683
684 ilog( "Saved build info JSON to '${path}'", ("path", p.generic_string()) );
685 }
686
687 SYS_THROW( node_management_success, "reported build environment information" );
688 }
689
690 LOAD_VALUE_SET( options, "sender-bypass-whiteblacklist", my->chain_config->sender_bypass_whiteblacklist );
691 LOAD_VALUE_SET( options, "actor-whitelist", my->chain_config->actor_whitelist );
692 LOAD_VALUE_SET( options, "actor-blacklist", my->chain_config->actor_blacklist );
693 LOAD_VALUE_SET( options, "contract-whitelist", my->chain_config->contract_whitelist );
694 LOAD_VALUE_SET( options, "contract-blacklist", my->chain_config->contract_blacklist );
695
696 LOAD_VALUE_SET( options, "trusted-producer", my->chain_config->trusted_producers );
697
698 if( options.count( "action-blacklist" )) {
699 const std::vector<std::string>& acts = options["action-blacklist"].as<std::vector<std::string>>();
700 auto& list = my->chain_config->action_blacklist;
701 for( const auto& a : acts ) {
702 auto pos = a.find( "::" );
703 SYS_ASSERT( pos != std::string::npos, plugin_config_exception, "Invalid entry in action-blacklist: '${a}'", ("a", a));
704 account_name code( a.substr( 0, pos ));
705 action_name act( a.substr( pos + 2 ));
706 list.emplace( code, act );
707 }
708 }
709
710 if( options.count( "key-blacklist" )) {
711 const std::vector<std::string>& keys = options["key-blacklist"].as<std::vector<std::string>>();
712 auto& list = my->chain_config->key_blacklist;
713 for( const auto& key_str : keys ) {
714 list.emplace( key_str );
715 }
716 }
717
718 if( options.count( "blocks-dir" )) {
719 auto bld = options.at( "blocks-dir" ).as<bfs::path>();
720 if( bld.is_relative())
721 my->blocks_dir = app().data_dir() / bld;
722 else
723 my->blocks_dir = bld;
724 }
725
726 protocol_feature_set pfs;
727 {
728 fc::path protocol_features_dir;
729 auto pfd = options.at( "protocol-features-dir" ).as<bfs::path>();
730 if( pfd.is_relative())
731 protocol_features_dir = app().config_dir() / pfd;
732 else
733 protocol_features_dir = pfd;
734
735 pfs = initialize_protocol_features( protocol_features_dir );
736 }
737
738 if( options.count("checkpoint") ) {
739 auto cps = options.at("checkpoint").as<vector<string>>();
740 my->loaded_checkpoints.reserve(cps.size());
741 for( const auto& cp : cps ) {
742 auto item = fc::json::from_string(cp).as<std::pair<uint32_t,block_id_type>>();
743 auto itr = my->loaded_checkpoints.find(item.first);
744 if( itr != my->loaded_checkpoints.end() ) {
745 SYS_ASSERT( itr->second == item.second,
746 plugin_config_exception,
747 "redefining existing checkpoint at block number ${num}: original: ${orig} new: ${new}",
748 ("num", item.first)("orig", itr->second)("new", item.second)
749 );
750 } else {
751 my->loaded_checkpoints[item.first] = item.second;
752 }
753 }
754 }
755
756 if( options.count( "wasm-runtime" ))
757 my->wasm_runtime = options.at( "wasm-runtime" ).as<vm_type>();
758
759 LOAD_VALUE_SET( options, "profile-account", my->chain_config->profile_accounts );
760
761 if(options.count("abi-serializer-max-time-ms"))
762 my->abi_serializer_max_time_us = fc::microseconds(options.at("abi-serializer-max-time-ms").as<uint32_t>() * 1000);
763
764 my->chain_config->blocks_dir = my->blocks_dir;
765 my->chain_config->state_dir = app().data_dir() / config::default_state_dir_name;
766 my->chain_config->read_only = my->readonly;
767
768 if (auto resmon_plugin = app().find_plugin<resource_monitor_plugin>()) {
769 resmon_plugin->monitor_directory(my->chain_config->blocks_dir);
770 resmon_plugin->monitor_directory(my->chain_config->state_dir);
771 }
772
773 if( options.count( "chain-state-db-size-mb" ))
774 my->chain_config->state_size = options.at( "chain-state-db-size-mb" ).as<uint64_t>() * 1024 * 1024;
775
776 if( options.count( "chain-state-db-guard-size-mb" ))
777 my->chain_config->state_guard_size = options.at( "chain-state-db-guard-size-mb" ).as<uint64_t>() * 1024 * 1024;
778
779 if( options.count( "max-nonprivileged-inline-action-size" ))
780 my->chain_config->max_nonprivileged_inline_action_size = options.at( "max-nonprivileged-inline-action-size" ).as<uint32_t>();
781
782 if( options.count( "transaction-finality-status-max-storage-size-gb" )) {
783 const uint64_t max_storage_size = options.at( "transaction-finality-status-max-storage-size-gb" ).as<uint64_t>() * 1024 * 1024 * 1024;
784 if (max_storage_size > 0) {
785 const fc::microseconds success_duration = fc::seconds(options.at( "transaction-finality-status-success-duration-sec" ).as<uint64_t>());
786 const fc::microseconds failure_duration = fc::seconds(options.at( "transaction-finality-status-failure-duration-sec" ).as<uint64_t>());
787 my->_trx_finality_status_processing.reset(
788 new chain_apis::trx_finality_status_processing(max_storage_size, success_duration, failure_duration));
789 }
790 }
791
792 if( options.count( "chain-threads" )) {
793 my->chain_config->thread_pool_size = options.at( "chain-threads" ).as<uint16_t>();
794 SYS_ASSERT( my->chain_config->thread_pool_size > 0, plugin_config_exception,
795 "chain-threads ${num} must be greater than 0", ("num", my->chain_config->thread_pool_size) );
796 }
797
798 my->chain_config->sig_cpu_bill_pct = options.at("signature-cpu-billable-pct").as<uint32_t>();
799 SYS_ASSERT( my->chain_config->sig_cpu_bill_pct >= 0 && my->chain_config->sig_cpu_bill_pct <= 100, plugin_config_exception,
800 "signature-cpu-billable-pct must be 0 - 100, ${pct}", ("pct", my->chain_config->sig_cpu_bill_pct) );
801 my->chain_config->sig_cpu_bill_pct *= config::percent_1;
802
803 if( my->wasm_runtime )
804 my->chain_config->wasm_runtime = *my->wasm_runtime;
805
806 my->chain_config->force_all_checks = options.at( "force-all-checks" ).as<bool>();
807 my->chain_config->disable_replay_opts = options.at( "disable-replay-opts" ).as<bool>();
808 my->chain_config->contracts_console = options.at( "contracts-console" ).as<bool>();
809 my->chain_config->allow_ram_billing_in_notify = options.at( "disable-ram-billing-notify-checks" ).as<bool>();
810
811#ifdef SYSIO_DEVELOPER
812 my->chain_config->disable_all_subjective_mitigations = options.at( "disable-all-subjective-mitigations" ).as<bool>();
813#endif
814
815 my->chain_config->maximum_variable_signature_length = options.at( "maximum-variable-signature-length" ).as<uint32_t>();
816
817 if( options.count( "terminate-at-block" ))
818 my->chain_config->terminate_at_block = options.at( "terminate-at-block" ).as<uint32_t>();
819
820 if( options.count( "extract-genesis-json" ) || options.at( "print-genesis-json" ).as<bool>()) {
821 std::optional<genesis_state> gs;
822
823 if( fc::exists( my->blocks_dir / "blocks.log" )) {
824 gs = block_log::extract_genesis_state( my->blocks_dir );
825 SYS_ASSERT( gs,
826 plugin_config_exception,
827 "Block log at '${path}' does not contain a genesis state, it only has the chain-id.",
828 ("path", (my->blocks_dir / "blocks.log").generic_string())
829 );
830 } else {
831 wlog( "No blocks.log found at '${p}'. Using default genesis state.",
832 ("p", (my->blocks_dir / "blocks.log").generic_string()));
833 gs.emplace();
834 }
835
836 if( options.at( "print-genesis-json" ).as<bool>()) {
837 ilog( "Genesis JSON:\n${genesis}", ("genesis", json::to_pretty_string( *gs )));
838 }
839
840 if( options.count( "extract-genesis-json" )) {
841 auto p = options.at( "extract-genesis-json" ).as<bfs::path>();
842
843 if( p.is_relative()) {
844 p = bfs::current_path() / p;
845 }
846
847 SYS_ASSERT( fc::json::save_to_file( *gs, p, true ),
848 misc_exception,
849 "Error occurred while writing genesis JSON to '${path}'",
850 ("path", p.generic_string())
851 );
852
853 ilog( "Saved genesis JSON to '${path}'", ("path", p.generic_string()) );
854 }
855
856 SYS_THROW( extract_genesis_state_exception, "extracted genesis state from blocks.log" );
857 }
858
859 // move fork_db to new location
860 upgrade_from_reversible_to_fork_db( my.get() );
861
862 if(options.count( "block-log-retain-blocks" )) {
863 my->chain_config->prune_config.emplace();
864 my->chain_config->prune_config->prune_blocks = options.at( "block-log-retain-blocks" ).as<uint32_t>();
865 SYS_ASSERT(my->chain_config->prune_config->prune_blocks, plugin_config_exception, "block-log-retain-blocks cannot be 0");
866 }
867
868 if( options.at( "delete-all-blocks" ).as<bool>()) {
869 ilog( "Deleting state database and blocks" );
870 if( options.at( "truncate-at-block" ).as<uint32_t>() > 0 )
871 wlog( "The --truncate-at-block option does not make sense when deleting all blocks." );
872 clear_directory_contents( my->chain_config->state_dir );
873 clear_directory_contents( my->blocks_dir );
874 } else if( options.at( "hard-replay-blockchain" ).as<bool>()) {
875 do_hard_replay(options);
876 } else if( options.at( "replay-blockchain" ).as<bool>()) {
877 ilog( "Replay requested: deleting state database" );
878 if( options.at( "truncate-at-block" ).as<uint32_t>() > 0 )
879 wlog( "The --truncate-at-block option does not work for a regular replay of the blockchain." );
880 clear_chainbase_files( my->chain_config->state_dir );
881 } else if( options.at( "truncate-at-block" ).as<uint32_t>() > 0 ) {
882 wlog( "The --truncate-at-block option can only be used with --hard-replay-blockchain." );
883 }
884
885 std::optional<chain_id_type> chain_id;
886 if (options.count( "snapshot" )) {
887 my->snapshot_path = options.at( "snapshot" ).as<bfs::path>();
888 SYS_ASSERT( fc::exists(*my->snapshot_path), plugin_config_exception,
889 "Cannot load snapshot, ${name} does not exist", ("name", my->snapshot_path->generic_string()) );
890
891 // recover genesis information from the snapshot
892 // used for validation code below
893 auto infile = std::ifstream(my->snapshot_path->generic_string(), (std::ios::in | std::ios::binary));
894 istream_snapshot_reader reader(infile);
895 reader.validate();
896 chain_id = controller::extract_chain_id(reader);
897 infile.close();
898
899 SYS_ASSERT( options.count( "genesis-timestamp" ) == 0,
900 plugin_config_exception,
901 "--snapshot is incompatible with --genesis-timestamp as the snapshot contains genesis information");
902 SYS_ASSERT( options.count( "genesis-json" ) == 0,
903 plugin_config_exception,
904 "--snapshot is incompatible with --genesis-json as the snapshot contains genesis information");
905
906 auto shared_mem_path = my->chain_config->state_dir / "shared_memory.bin";
907 SYS_ASSERT( !fc::is_regular_file(shared_mem_path),
908 plugin_config_exception,
909 "Snapshot can only be used to initialize an empty database." );
910
911 if( fc::is_regular_file( my->blocks_dir / "blocks.log" )) {
912 auto block_log_genesis = block_log::extract_genesis_state(my->blocks_dir);
913 if( block_log_genesis ) {
914 const auto& block_log_chain_id = block_log_genesis->compute_chain_id();
915 SYS_ASSERT( *chain_id == block_log_chain_id,
916 plugin_config_exception,
917 "snapshot chain ID (${snapshot_chain_id}) does not match the chain ID from the genesis state in the block log (${block_log_chain_id})",
918 ("snapshot_chain_id", *chain_id)
919 ("block_log_chain_id", block_log_chain_id)
920 );
921 } else {
922 const auto& block_log_chain_id = block_log::extract_chain_id(my->blocks_dir);
923 SYS_ASSERT( *chain_id == block_log_chain_id,
924 plugin_config_exception,
925 "snapshot chain ID (${snapshot_chain_id}) does not match the chain ID (${block_log_chain_id}) in the block log",
926 ("snapshot_chain_id", *chain_id)
927 ("block_log_chain_id", block_log_chain_id)
928 );
929 }
930 }
931
932 } else {
933
934 chain_id = controller::extract_chain_id_from_db( my->chain_config->state_dir );
935
936 std::optional<genesis_state> block_log_genesis;
937 std::optional<chain_id_type> block_log_chain_id;
938
939 if( fc::is_regular_file( my->blocks_dir / "blocks.log" ) ) {
940 block_log_genesis = block_log::extract_genesis_state( my->blocks_dir );
941 if( block_log_genesis ) {
942 block_log_chain_id = block_log_genesis->compute_chain_id();
943 } else {
944 block_log_chain_id = block_log::extract_chain_id( my->blocks_dir );
945 }
946
947 if( chain_id ) {
948 SYS_ASSERT( *block_log_chain_id == *chain_id, block_log_exception,
949 "Chain ID in blocks.log (${block_log_chain_id}) does not match the existing "
950 " chain ID in state (${state_chain_id}).",
951 ("block_log_chain_id", *block_log_chain_id)
952 ("state_chain_id", *chain_id)
953 );
954 } else if( block_log_genesis ) {
955 ilog( "Starting fresh blockchain state using genesis state extracted from blocks.log." );
956 my->genesis = block_log_genesis;
957 // Delay setting chain_id until later so that the code handling genesis-json below can know
958 // that chain_id still only represents a chain ID extracted from the state (assuming it exists).
959 }
960 }
961
962 if( options.count( "genesis-json" ) ) {
963 bfs::path genesis_file = options.at( "genesis-json" ).as<bfs::path>();
964 if( genesis_file.is_relative()) {
965 genesis_file = bfs::current_path() / genesis_file;
966 }
967
968 SYS_ASSERT( fc::is_regular_file( genesis_file ),
969 plugin_config_exception,
970 "Specified genesis file '${genesis}' does not exist.",
971 ("genesis", genesis_file.generic_string()));
972
973 genesis_state provided_genesis = fc::json::from_file( genesis_file ).as<genesis_state>();
974
975 if( options.count( "genesis-timestamp" ) ) {
976 provided_genesis.initial_timestamp = calculate_genesis_timestamp( options.at( "genesis-timestamp" ).as<string>() );
977
978 ilog( "Using genesis state provided in '${genesis}' but with adjusted genesis timestamp",
979 ("genesis", genesis_file.generic_string()) );
980 } else {
981 ilog( "Using genesis state provided in '${genesis}'", ("genesis", genesis_file.generic_string()));
982 }
983
984 if( block_log_genesis ) {
985 SYS_ASSERT( *block_log_genesis == provided_genesis, plugin_config_exception,
986 "Genesis state, provided via command line arguments, does not match the existing genesis state"
987 " in blocks.log. It is not necessary to provide genesis state arguments when a full blocks.log "
988 "file already exists."
989 );
990 } else {
991 const auto& provided_genesis_chain_id = provided_genesis.compute_chain_id();
992 if( chain_id ) {
993 SYS_ASSERT( provided_genesis_chain_id == *chain_id, plugin_config_exception,
994 "Genesis state, provided via command line arguments, has a chain ID (${provided_genesis_chain_id}) "
995 "that does not match the existing chain ID in the database state (${state_chain_id}). "
996 "It is not necessary to provide genesis state arguments when an initialized database state already exists.",
997 ("provided_genesis_chain_id", provided_genesis_chain_id)
998 ("state_chain_id", *chain_id)
999 );
1000 } else {
1001 if( block_log_chain_id ) {
1002 SYS_ASSERT( provided_genesis_chain_id == *block_log_chain_id, plugin_config_exception,
1003 "Genesis state, provided via command line arguments, has a chain ID (${provided_genesis_chain_id}) "
1004 "that does not match the existing chain ID in blocks.log (${block_log_chain_id}).",
1005 ("provided_genesis_chain_id", provided_genesis_chain_id)
1006 ("block_log_chain_id", *block_log_chain_id)
1007 );
1008 }
1009
1010 chain_id = provided_genesis_chain_id;
1011
1012 ilog( "Starting fresh blockchain state using provided genesis state." );
1013 my->genesis = std::move(provided_genesis);
1014 }
1015 }
1016 } else {
1017 SYS_ASSERT( options.count( "genesis-timestamp" ) == 0,
1018 plugin_config_exception,
1019 "--genesis-timestamp is only valid if also passed in with --genesis-json");
1020 }
1021
1022 if( !chain_id ) {
1023 if( my->genesis ) {
1024 // Uninitialized state database and genesis state extracted from block log
1025 chain_id = my->genesis->compute_chain_id();
1026 } else {
1027 // Uninitialized state database and no genesis state provided
1028
1029 SYS_ASSERT( !block_log_chain_id, plugin_config_exception,
1030 "Genesis state is necessary to initialize fresh blockchain state but genesis state could not be "
1031 "found in the blocks log. Please either load from snapshot or find a blocks log that starts "
1032 "from genesis."
1033 );
1034
1035 ilog( "Starting fresh blockchain state using default genesis state." );
1036 my->genesis.emplace();
1037 chain_id = my->genesis->compute_chain_id();
1038 }
1039 }
1040 }
1041
1042 if ( options.count("read-mode") ) {
1043 my->chain_config->read_mode = options.at("read-mode").as<db_read_mode>();
1044 }
1045 my->api_accept_transactions = options.at( "api-accept-transactions" ).as<bool>();
1046
1047 if( my->chain_config->read_mode == db_read_mode::IRREVERSIBLE || my->chain_config->read_mode == db_read_mode::READ_ONLY ) {
1048 if( my->chain_config->read_mode == db_read_mode::READ_ONLY ) {
1049 wlog( "read-mode = read-only is deprecated use p2p-accept-transactions = false, api-accept-transactions = false instead." );
1050 }
1051 if( my->api_accept_transactions ) {
1052 my->api_accept_transactions = false;
1053 std::stringstream ss; ss << my->chain_config->read_mode;
1054 wlog( "api-accept-transactions set to false due to read-mode: ${m}", ("m", ss.str()) );
1055 }
1056 }
1057 if( my->api_accept_transactions ) {
1059 }
1060
1061 if ( options.count("validation-mode") ) {
1062 my->chain_config->block_validation_mode = options.at("validation-mode").as<validation_mode>();
1063 }
1064
1065 my->chain_config->db_map_mode = options.at("database-map-mode").as<pinnable_mapped_file::map_mode>();
1066
1067#ifdef SYSIO_SYS_VM_OC_RUNTIME_ENABLED
1068 if( options.count("sys-vm-oc-cache-size-mb") )
1069 my->chain_config->eosvmoc_config.cache_size = options.at( "sys-vm-oc-cache-size-mb" ).as<uint64_t>() * 1024u * 1024u;
1070 if( options.count("sys-vm-oc-compile-threads") )
1071 my->chain_config->eosvmoc_config.threads = options.at("sys-vm-oc-compile-threads").as<uint64_t>();
1072 if( options["sys-vm-oc-enable"].as<bool>() )
1073 my->chain_config->eosvmoc_tierup = true;
1074#endif
1075
1076 my->account_queries_enabled = options.at("enable-account-queries").as<bool>();
1077
1078 my->chain.emplace( *my->chain_config, std::move(pfs), *chain_id );
1079
1080 if( options.count( "transaction-retry-max-storage-size-gb" )) {
1081 SYS_ASSERT( !options.count( "producer-name"), plugin_config_exception,
1082 "Transaction retry not allowed on producer nodes." );
1083 const uint64_t max_storage_size = options.at( "transaction-retry-max-storage-size-gb" ).as<uint64_t>() * 1024 * 1024 * 1024;
1084 if( max_storage_size > 0 ) {
1085 const uint32_t p2p_dedup_time_s = options.at( "p2p-dedup-cache-expire-time-sec" ).as<uint32_t>();
1086 const uint32_t trx_retry_interval = options.at( "transaction-retry-interval-sec" ).as<uint32_t>();
1087 const uint32_t trx_retry_max_expire = options.at( "transaction-retry-max-expiration-sec" ).as<uint32_t>();
1088 SYS_ASSERT( trx_retry_interval >= 2 * p2p_dedup_time_s, plugin_config_exception,
1089 "transaction-retry-interval-sec ${ri} must be greater than 2 times p2p-dedup-cache-expire-time-sec ${dd}",
1090 ("ri", trx_retry_interval)("dd", p2p_dedup_time_s) );
1091 SYS_ASSERT( trx_retry_max_expire > trx_retry_interval, plugin_config_exception,
1092 "transaction-retry-max-expiration-sec ${m} should be configured larger than transaction-retry-interval-sec ${i}",
1093 ("m", trx_retry_max_expire)("i", trx_retry_interval) );
1094 my->_trx_retry_db.emplace( *my->chain, max_storage_size,
1095 fc::seconds(trx_retry_interval), fc::seconds(trx_retry_max_expire),
1096 my->abi_serializer_max_time_us );
1097 }
1098 }
1099
1100 // initialize deep mind logging
1101 if ( options.at( "deep-mind" ).as<bool>() ) {
1102 // The actual `fc::dmlog_appender` implementation that is currently used by deep mind
1103 // logger is using `stdout` to prints it's log line out. Deep mind logging outputs
1104 // massive amount of data out of the process, which can lead under pressure to some
1105 // of the system calls (i.e. `fwrite`) to fail abruptly without fully writing the
1106 // entire line.
1107 //
1108 // Recovering from errors on a buffered (line or full) and continuing retrying write
1109 // is merely impossible to do right, because the buffer is actually held by the
1110 // underlying `libc` implementation nor the operation system.
1111 //
1112 // To ensure good functionalities of deep mind tracer, the `stdout` is made unbuffered
1113 // and the actual `fc::dmlog_appender` deals with retry when facing error, enabling a much
1114 // more robust deep mind output.
1115 //
1116 // Changing the standard `stdout` behavior from buffered to unbuffered can is disruptive
1117 // and can lead to weird scenarios in the logging process if `stdout` is used there too.
1118 //
1119 // In a future version, the `fc::dmlog_appender` implementation will switch to a `FIFO` file
1120 // approach, which will remove the dependency on `stdout` and hence this call.
1121 //
1122 // For the time being, when `deep-mind = true` is activated, we set `stdout` here to
1123 // be an unbuffered I/O stream.
1124 setbuf(stdout, NULL);
1125
1126 //verify configuration is correct
1127 SYS_ASSERT( options.at("api-accept-transactions").as<bool>() == false, plugin_config_exception,
1128 "api-accept-transactions must be set to false in order to enable deep-mind logging.");
1129
1130 SYS_ASSERT( options.at("p2p-accept-transactions").as<bool>() == false, plugin_config_exception,
1131 "p2p-accept-transactions must be set to false in order to enable deep-mind logging.");
1132
1133 my->chain->enable_deep_mind( &_deep_mind_log );
1134 }
1135
1136 // set up method providers
1137 my->get_block_by_number_provider = app().get_method<methods::get_block_by_number>().register_provider(
1138 [this]( uint32_t block_num ) -> signed_block_ptr {
1139 return my->chain->fetch_block_by_number( block_num );
1140 } );
1141
1142 my->get_block_by_id_provider = app().get_method<methods::get_block_by_id>().register_provider(
1143 [this]( block_id_type id ) -> signed_block_ptr {
1144 return my->chain->fetch_block_by_id( id );
1145 } );
1146
1147 my->get_head_block_id_provider = app().get_method<methods::get_head_block_id>().register_provider( [this]() {
1148 return my->chain->head_block_id();
1149 } );
1150
1151 my->get_last_irreversible_block_number_provider = app().get_method<methods::get_last_irreversible_block_number>().register_provider(
1152 [this]() {
1153 return my->chain->last_irreversible_block_num();
1154 } );
1155
1156 // relay signals to channels
1157 my->pre_accepted_block_connection = my->chain->pre_accepted_block.connect([this](const signed_block_ptr& blk) {
1158 auto itr = my->loaded_checkpoints.find( blk->block_num() );
1159 if( itr != my->loaded_checkpoints.end() ) {
1160 auto id = blk->calculate_id();
1161 SYS_ASSERT( itr->second == id, checkpoint_exception,
1162 "Checkpoint does not match for block number ${num}: expected: ${expected} actual: ${actual}",
1163 ("num", blk->block_num())("expected", itr->second)("actual", id)
1164 );
1165 }
1166
1167 my->pre_accepted_block_channel.publish(priority::medium, blk);
1168 });
1169
1170 my->accepted_block_header_connection = my->chain->accepted_block_header.connect(
1171 [this]( const block_state_ptr& blk ) {
1172 my->accepted_block_header_channel.publish( priority::medium, blk );
1173 } );
1174
1175 my->accepted_block_connection = my->chain->accepted_block.connect( [this]( const block_state_ptr& blk ) {
1176 if (my->_account_query_db) {
1177 my->_account_query_db->commit_block(blk);
1178 }
1179
1180 if (my->_trx_retry_db) {
1181 my->_trx_retry_db->on_accepted_block(blk);
1182 }
1183
1184 if (my->_trx_finality_status_processing) {
1185 my->_trx_finality_status_processing->signal_accepted_block(blk);
1186 }
1187
1188 my->accepted_block_channel.publish( priority::high, blk );
1189 } );
1190
1191 my->irreversible_block_connection = my->chain->irreversible_block.connect( [this]( const block_state_ptr& blk ) {
1192 if (my->_trx_retry_db) {
1193 my->_trx_retry_db->on_irreversible_block(blk);
1194 }
1195
1196 if (my->_trx_finality_status_processing) {
1197 my->_trx_finality_status_processing->signal_irreversible_block(blk);
1198 }
1199
1200 my->irreversible_block_channel.publish( priority::low, blk );
1201 } );
1202
1203 my->accepted_transaction_connection = my->chain->accepted_transaction.connect(
1204 [this]( const transaction_metadata_ptr& meta ) {
1205 my->accepted_transaction_channel.publish( priority::low, meta );
1206 } );
1207
1208 my->applied_transaction_connection = my->chain->applied_transaction.connect(
1209 [this]( std::tuple<const transaction_trace_ptr&, const packed_transaction_ptr&> t ) {
1210 if (my->_account_query_db) {
1211 my->_account_query_db->cache_transaction_trace(std::get<0>(t));
1212 }
1213
1214 if (my->_trx_retry_db) {
1215 my->_trx_retry_db->on_applied_transaction(std::get<0>(t), std::get<1>(t));
1216 }
1217
1218 if (my->_trx_finality_status_processing) {
1219 my->_trx_finality_status_processing->signal_applied_transaction(std::get<0>(t), std::get<1>(t));
1220 }
1221
1222 my->applied_transaction_channel.publish( priority::low, std::get<0>(t) );
1223 } );
1224
1225 if (my->_trx_finality_status_processing || my->_trx_retry_db) {
1226 my->block_start_connection = my->chain->block_start.connect(
1227 [this]( uint32_t block_num ) {
1228 if (my->_trx_retry_db) {
1229 my->_trx_retry_db->on_block_start(block_num);
1230 }
1231 if (my->_trx_finality_status_processing) {
1232 my->_trx_finality_status_processing->signal_block_start( block_num );
1233 }
1234 } );
1235 }
1236 my->chain->add_indices();
1238
1239}
const mie::Vuint & p
Definition bn.cpp:27
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
Definition exceptions.hpp:7
#define LOAD_VALUE_SET(options, op_name, container)
bfs::path data_dir() const
Get data directory.
auto get_method() -> std::enable_if_t< is_method_decl< MethodDecl >::value, typename MethodDecl::method_type & >
bfs::path config_dir() const
Get config directory.
static variant from_file(const fc::path &p, const parse_type ptype=parse_type::legacy_parser, const uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition json.cpp:797
static bool save_to_file(const T &v, const fc::path &fi, const bool pretty=true, const output_formatting format=output_formatting::stringify_large_ints_and_doubles)
Definition json.hpp:45
static string to_pretty_string(const variant &v, const yield_function_t &yield, const output_formatting format=output_formatting::stringify_large_ints_and_doubles)
Definition json.cpp:775
static variant from_string(const string &utf8_str, const parse_type ptype=parse_type::legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition json.cpp:442
wraps boost::filesystem::path to provide platform independent path manipulation.
T as() const
Definition variant.hpp:327
static std::optional< genesis_state > extract_genesis_state(const fc::path &data_dir)
static chain_id_type extract_chain_id(const fc::path &data_dir)
static std::optional< chain_id_type > extract_chain_id_from_db(const path &state_dir)
static chain_id_type extract_chain_id(snapshot_reader &snapshot)
void do_hard_replay(const variables_map &options)
#define FC_LOG_AND_RETHROW()
#define wlog(FORMAT,...)
Definition logger.hpp:124
static const Segment gs(Segment::gs)
static const Segment ss(Segment::ss)
bool exists(const path &p)
bool is_regular_file(const path &p)
constexpr microseconds seconds(int64_t s)
Definition time.hpp:32
method_decl< chain_plugin_interface, signed_block_ptr(uint32_t block_num)> get_block_by_number
method_decl< chain_plugin_interface, uint32_t()> get_last_irreversible_block_number
method_decl< chain_plugin_interface, signed_block_ptr(const block_id_type &block_id)> get_block_by_id
method_decl< chain_plugin_interface, block_id_type()> get_head_block_id
fc::sha256 block_id_type
Definition types.hpp:231
sysio::chain::action_name action_name
std::shared_ptr< signed_block > signed_block_ptr
Definition block.hpp:105
std::shared_ptr< block_state > block_state_ptr
name account_name
Definition types.hpp:120
std::shared_ptr< transaction_metadata > transaction_metadata_ptr
fc::time_point calculate_genesis_timestamp(string tstr)
protocol_feature_set initialize_protocol_features(const fc::path &p, bool populate_missing_builtins=true)
void clear_chainbase_files(const fc::path &p)
wasm_interface::vm_type vm_type
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Definition pointer.h:1181
unsigned short uint16_t
Definition stdint.h:125
unsigned __int64 uint64_t
Definition stdint.h:136
static constexpr int medium
static constexpr int high
static const string sysio_root_key
Here is the call graph for this function:

◆ plugin_shutdown()

void chain_plugin::plugin_shutdown ( )

Definition at line 1295 of file chain_plugin.cpp.

1295 {
1296 my->pre_accepted_block_connection.reset();
1297 my->accepted_block_header_connection.reset();
1298 my->accepted_block_connection.reset();
1299 my->irreversible_block_connection.reset();
1300 my->accepted_transaction_connection.reset();
1301 my->applied_transaction_connection.reset();
1302 my->block_start_connection.reset();
1303 if(app().is_quiting())
1304 my->chain->get_wasm_interface().indicate_shutting_down();
1305 my->chain.reset();
1306}
Here is the call graph for this function:

◆ plugin_startup()

void chain_plugin::plugin_startup ( )

Definition at line 1241 of file chain_plugin.cpp.

1242{ try {
1243 handle_sighup(); // Sets loggers
1244
1245 SYS_ASSERT( my->chain_config->read_mode != db_read_mode::IRREVERSIBLE || !accept_transactions(), plugin_config_exception,
1246 "read-mode = irreversible. transactions should not be enabled by enable_accept_transactions" );
1247 try {
1248 my->producer_plug = app().find_plugin<producer_plugin>();
1249 SYS_ASSERT(my->producer_plug, plugin_exception, "Failed to find producer_plugin");
1250
1251 auto shutdown = [](){ return app().quit(); };
1252 auto check_shutdown = [](){ return app().is_quiting(); };
1253 if (my->snapshot_path) {
1254 auto infile = std::ifstream(my->snapshot_path->generic_string(), (std::ios::in | std::ios::binary));
1255 auto reader = std::make_shared<istream_snapshot_reader>(infile);
1256 my->chain->startup(shutdown, check_shutdown, reader);
1257 infile.close();
1258 } else if( my->genesis ) {
1259 my->chain->startup(shutdown, check_shutdown, *my->genesis);
1260 } else {
1261 my->chain->startup(shutdown, check_shutdown);
1262 }
1263 } catch (const database_guard_exception& e) {
1264 log_guard_exception(e);
1265 // make sure to properly close the db
1266 my->chain.reset();
1267 throw;
1268 }
1269
1270 if(!my->readonly) {
1271 ilog("starting chain in read/write mode");
1272 }
1273
1274 if (my->genesis) {
1275 ilog("Blockchain started; head block is #${num}, genesis timestamp is ${ts}",
1276 ("num", my->chain->head_block_num())("ts", (std::string)my->genesis->initial_timestamp));
1277 }
1278 else {
1279 ilog("Blockchain started; head block is #${num}", ("num", my->chain->head_block_num()));
1280 }
1281
1282 my->chain_config.reset();
1283
1284 if (my->account_queries_enabled) {
1285 my->account_queries_enabled = false;
1286 try {
1287 my->_account_query_db.emplace(*my->chain);
1288 my->account_queries_enabled = true;
1289 } FC_LOG_AND_DROP(("Unable to enable account queries"));
1290 }
1291
1292
abstract_plugin * find_plugin(const string &name) const
bool is_quiting() const
virtual void shutdown() override
bool accept_transactions() const
void handle_sighup() override
#define FC_CAPTURE_AND_RETHROW(...)
#define FC_LOG_AND_DROP(...)
Here is the call graph for this function:

◆ set_program_options()

void chain_plugin::set_program_options ( options_description & cli,
options_description & cfg )
overridevirtual

Implements appbase::abstract_plugin.

Definition at line 209 of file chain_plugin.cpp.

210{
211 // build wasm_runtime help text
212 std::string wasm_runtime_opt = "Override default WASM runtime (";
213 std::string wasm_runtime_desc;
214 std::string delim;
215#ifdef SYSIO_SYS_VM_JIT_RUNTIME_ENABLED
216 wasm_runtime_opt += " \"sys-vm-jit\"";
217 wasm_runtime_desc += "\"sys-vm-jit\" : A WebAssembly runtime that compiles WebAssembly code to native x86 code prior to execution.\n";
218 delim = ", ";
219#endif
220
221#ifdef SYSIO_SYS_VM_RUNTIME_ENABLED
222 wasm_runtime_opt += delim + "\"sys-vm\"";
223 wasm_runtime_desc += "\"sys-vm\" : A WebAssembly interpreter.\n";
224 delim = ", ";
225#endif
226
227#ifdef SYSIO_SYS_VM_OC_DEVELOPER
228 wasm_runtime_opt += delim + "\"sys-vm-oc\"";
229 wasm_runtime_desc += "\"sys-vm-oc\" : Unsupported. Instead, use one of the other runtimes along with the option enable-sys-vm-oc.\n";
230#endif
231 wasm_runtime_opt += ")\n" + wasm_runtime_desc;
232
233 std::string default_wasm_runtime_str= sysio::chain::wasm_interface::vm_type_string(sysio::chain::config::default_wasm_runtime);
234
235 cfg.add_options()
236 ("blocks-dir", bpo::value<bfs::path>()->default_value("blocks"),
237 "the location of the blocks directory (absolute path or relative to application data dir)")
238 ("protocol-features-dir", bpo::value<bfs::path>()->default_value("protocol_features"),
239 "the location of the protocol_features directory (absolute path or relative to application config dir)")
240 ("checkpoint", bpo::value<vector<string>>()->composing(), "Pairs of [BLOCK_NUM,BLOCK_ID] that should be enforced as checkpoints.")
241 ("wasm-runtime", bpo::value<sysio::chain::wasm_interface::vm_type>()->value_name("runtime")->notifier([](const auto& vm){
242#ifndef SYSIO_SYS_VM_OC_DEVELOPER
243 //throwing an exception here (like SYS_ASSERT) is just gobbled up with a "Failed to initialize" error :(
244 if(vm == wasm_interface::vm_type::eos_vm_oc) {
245 elog("SYS VM OC is a tier-up compiler and works in conjunction with the configured base WASM runtime. Enable SYS VM OC via 'sys-vm-oc-enable' option");
246 SYS_ASSERT(false, plugin_exception, "");
247 }
248#endif
249 })->default_value(sysio::chain::config::default_wasm_runtime, default_wasm_runtime_str), wasm_runtime_opt.c_str()
250 )
251 ("profile-account", boost::program_options::value<vector<string>>()->composing(),
252 "The name of an account whose code will be profiled")
253 ("abi-serializer-max-time-ms", bpo::value<uint32_t>()->default_value(config::default_abi_serializer_max_time_us / 1000),
254 "Override default maximum ABI serialization time allowed in ms")
255 ("chain-state-db-size-mb", bpo::value<uint64_t>()->default_value(config::default_state_size / (1024 * 1024)), "Maximum size (in MiB) of the chain state database")
256 ("chain-state-db-guard-size-mb", bpo::value<uint64_t>()->default_value(config::default_state_guard_size / (1024 * 1024)), "Safely shut down node when free space remaining in the chain state database drops below this size (in MiB).")
257 ("signature-cpu-billable-pct", bpo::value<uint32_t>()->default_value(config::default_sig_cpu_bill_pct / config::percent_1),
258 "Percentage of actual signature recovery cpu to bill. Whole number percentages, e.g. 50 for 50%")
259 ("chain-threads", bpo::value<uint16_t>()->default_value(config::default_controller_thread_pool_size),
260 "Number of worker threads in controller thread pool")
261 ("contracts-console", bpo::bool_switch()->default_value(false),
262 "print contract's output to console")
263 ("deep-mind", bpo::bool_switch()->default_value(false),
264 "print deeper information about chain operations")
265 ("actor-whitelist", boost::program_options::value<vector<string>>()->composing()->multitoken(),
266 "Account added to actor whitelist (may specify multiple times)")
267 ("actor-blacklist", boost::program_options::value<vector<string>>()->composing()->multitoken(),
268 "Account added to actor blacklist (may specify multiple times)")
269 ("contract-whitelist", boost::program_options::value<vector<string>>()->composing()->multitoken(),
270 "Contract account added to contract whitelist (may specify multiple times)")
271 ("contract-blacklist", boost::program_options::value<vector<string>>()->composing()->multitoken(),
272 "Contract account added to contract blacklist (may specify multiple times)")
273 ("action-blacklist", boost::program_options::value<vector<string>>()->composing()->multitoken(),
274 "Action (in the form code::action) added to action blacklist (may specify multiple times)")
275 ("key-blacklist", boost::program_options::value<vector<string>>()->composing()->multitoken(),
276 "Public key added to blacklist of keys that should not be included in authorities (may specify multiple times)")
277 ("sender-bypass-whiteblacklist", boost::program_options::value<vector<string>>()->composing()->multitoken(),
278 "Deferred transactions sent by accounts in this list do not have any of the subjective whitelist/blacklist checks applied to them (may specify multiple times)")
279 ("read-mode", boost::program_options::value<sysio::chain::db_read_mode>()->default_value(sysio::chain::db_read_mode::SPECULATIVE),
280 "Database read mode (\"speculative\", \"head\", \"read-only\", \"irreversible\").\n"
281 "In \"speculative\" mode: database contains state changes by transactions in the blockchain up to the head block as well as some transactions not yet included in the blockchain.\n"
282 "In \"head\" mode: database contains state changes by only transactions in the blockchain up to the head block; transactions received by the node are relayed if valid.\n"
283 "In \"read-only\" mode: (DEPRECATED: see p2p-accept-transactions & api-accept-transactions) database contains state changes by only transactions in the blockchain up to the head block; transactions received via the P2P network are not relayed and transactions cannot be pushed via the chain API.\n"
284 "In \"irreversible\" mode: database contains state changes by only transactions in the blockchain up to the last irreversible block; transactions received via the P2P network are not relayed and transactions cannot be pushed via the chain API.\n"
285 )
286 ( "api-accept-transactions", bpo::value<bool>()->default_value(true), "Allow API transactions to be evaluated and relayed if valid.")
287 ("validation-mode", boost::program_options::value<sysio::chain::validation_mode>()->default_value(sysio::chain::validation_mode::FULL),
288 "Chain validation mode (\"full\" or \"light\").\n"
289 "In \"full\" mode all incoming blocks will be fully validated.\n"
290 "In \"light\" mode all incoming blocks headers will be fully validated; transactions in those validated blocks will be trusted \n")
291 ("disable-ram-billing-notify-checks", bpo::bool_switch()->default_value(false),
292 "Disable the check which subjectively fails a transaction if a contract bills more RAM to another account within the context of a notification handler (i.e. when the receiver is not the code of the action).")
293#ifdef SYSIO_DEVELOPER
294 ("disable-all-subjective-mitigations", bpo::bool_switch()->default_value(false),
295 "Disable all subjective mitigations checks in the entire codebase.")
296#endif
297 ("maximum-variable-signature-length", bpo::value<uint32_t>()->default_value(16384u),
298 "Subjectively limit the maximum length of variable components in a variable legnth signature to this size in bytes")
299 ("trusted-producer", bpo::value<vector<string>>()->composing(), "Indicate a producer whose blocks headers signed by it will be fully validated, but transactions in those validated blocks will be trusted.")
300 ("database-map-mode", bpo::value<chainbase::pinnable_mapped_file::map_mode>()->default_value(chainbase::pinnable_mapped_file::map_mode::mapped),
301 "Database map mode (\"mapped\", \"heap\", or \"locked\").\n"
302 "In \"mapped\" mode database is memory mapped as a file.\n"
303#ifndef _WIN32
304 "In \"heap\" mode database is preloaded in to swappable memory and will use huge pages if available.\n"
305 "In \"locked\" mode database is preloaded, locked in to memory, and will use huge pages if available.\n"
306#endif
307 )
308
309#ifdef SYSIO_SYS_VM_OC_RUNTIME_ENABLED
310 ("sys-vm-oc-cache-size-mb", bpo::value<uint64_t>()->default_value(eosvmoc::config().cache_size / (1024u*1024u)), "Maximum size (in MiB) of the SYS VM OC code cache")
311 ("sys-vm-oc-compile-threads", bpo::value<uint64_t>()->default_value(1u)->notifier([](const auto t) {
312 if(t == 0) {
313 elog("sys-vm-oc-compile-threads must be set to a non-zero value");
314 SYS_ASSERT(false, plugin_exception, "");
315 }
316 }), "Number of threads to use for SYS VM OC tier-up")
317 ("sys-vm-oc-enable", bpo::bool_switch(), "Enable SYS VM OC tier-up runtime")
318#endif
319 ("enable-account-queries", bpo::value<bool>()->default_value(false), "enable queries to find accounts by various metadata.")
320 ("max-nonprivileged-inline-action-size", bpo::value<uint32_t>()->default_value(config::default_max_nonprivileged_inline_action_size), "maximum allowed size (in bytes) of an inline action for a nonprivileged account")
321 ("transaction-retry-max-storage-size-gb", bpo::value<uint64_t>(),
322 "Maximum size (in GiB) allowed to be allocated for the Transaction Retry feature. Setting above 0 enables this feature.")
323 ("transaction-retry-interval-sec", bpo::value<uint32_t>()->default_value(20),
324 "How often, in seconds, to resend an incoming transaction to network if not seen in a block.")
325 ("transaction-retry-max-expiration-sec", bpo::value<uint32_t>()->default_value(120),
326 "Maximum allowed transaction expiration for retry transactions, will retry transactions up to this value.")
327 ("transaction-finality-status-max-storage-size-gb", bpo::value<uint64_t>(),
328 "Maximum size (in GiB) allowed to be allocated for the Transaction Finality Status feature. Setting above 0 enables this feature.")
329 ("transaction-finality-status-success-duration-sec", bpo::value<uint64_t>()->default_value(config::default_max_transaction_finality_status_success_duration_sec),
330 "Duration (in seconds) a successful transaction's Finality Status will remain available from being first identified.")
331 ("transaction-finality-status-failure-duration-sec", bpo::value<uint64_t>()->default_value(config::default_max_transaction_finality_status_failure_duration_sec),
332 "Duration (in seconds) a failed transaction's Finality Status will remain available from being first identified.");
333
335 cfg.add_options()("block-log-retain-blocks", bpo::value<uint32_t>(), "if set, periodically prune the block log to store only configured number of most recent blocks");
336
337
338// TODO: rate limiting
339 /*("per-authorized-account-transaction-msg-rate-limit-time-frame-sec", bpo::value<uint32_t>()->default_value(default_per_auth_account_time_frame_seconds),
340 "The time frame, in seconds, that the per-authorized-account-transaction-msg-rate-limit is imposed over.")
341 ("per-authorized-account-transaction-msg-rate-limit", bpo::value<uint32_t>()->default_value(default_per_auth_account),
342 "Limits the maximum rate of transaction messages that an account is allowed each per-authorized-account-transaction-msg-rate-limit-time-frame-sec.")
343 ("per-code-account-transaction-msg-rate-limit-time-frame-sec", bpo::value<uint32_t>()->default_value(default_per_code_account_time_frame_seconds),
344 "The time frame, in seconds, that the per-code-account-transaction-msg-rate-limit is imposed over.")
345 ("per-code-account-transaction-msg-rate-limit", bpo::value<uint32_t>()->default_value(default_per_code_account),
346 "Limits the maximum rate of transaction messages that an account's code is allowed each per-code-account-transaction-msg-rate-limit-time-frame-sec.")*/
347
348 cli.add_options()
349 ("genesis-json", bpo::value<bfs::path>(), "File to read Genesis State from")
350 ("genesis-timestamp", bpo::value<string>(), "override the initial timestamp in the Genesis State file")
351 ("print-genesis-json", bpo::bool_switch()->default_value(false),
352 "extract genesis_state from blocks.log as JSON, print to console, and exit")
353 ("extract-genesis-json", bpo::value<bfs::path>(),
354 "extract genesis_state from blocks.log as JSON, write into specified file, and exit")
355 ("print-build-info", bpo::bool_switch()->default_value(false),
356 "print build environment information to console as JSON and exit")
357 ("extract-build-info", bpo::value<bfs::path>(),
358 "extract build environment information as JSON, write into specified file, and exit")
359 ("force-all-checks", bpo::bool_switch()->default_value(false),
360 "do not skip any validation checks while replaying blocks (useful for replaying blocks from untrusted source)")
361 ("disable-replay-opts", bpo::bool_switch()->default_value(false),
362 "disable optimizations that specifically target replay")
363 ("replay-blockchain", bpo::bool_switch()->default_value(false),
364 "clear chain state database and replay all blocks")
365 ("hard-replay-blockchain", bpo::bool_switch()->default_value(false),
366 "clear chain state database, recover as many blocks as possible from the block log, and then replay those blocks")
367 ("delete-all-blocks", bpo::bool_switch()->default_value(false),
368 "clear chain state database and block log")
369 ("truncate-at-block", bpo::value<uint32_t>()->default_value(0),
370 "stop hard replay / block log recovery at this block number (if set to non-zero number)")
371 ("terminate-at-block", bpo::value<uint32_t>()->default_value(0),
372 "terminate after reaching this block number (if set to a non-zero number)")
373 ("snapshot", bpo::value<bfs::path>(), "File to read Snapshot State from")
374 ;
375
376}
static bool supports_hole_punching()
Definition cfile.hpp:182
static std::string vm_type_string(vm_type vmtype)
void cli()
Here is the call graph for this function:

◆ transaction_finality_status_enabled()

bool chain_plugin::transaction_finality_status_enabled ( ) const

Definition at line 1399 of file chain_plugin.cpp.

1399 {
1400 return my->_trx_finality_status_processing.get();
1401}

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