654 {
655 ilog(
"initializing chain plugin");
656
657 try {
658 try {
660 } catch ( const std::exception& ) {
661 elog(
"SYSIO_ROOT_KEY ('${root_key}') is invalid. Recompile with a valid public 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>() ) {
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
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));
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())
722 else
723 my->blocks_dir = bld;
724 }
725
726 protocol_feature_set pfs;
727 {
729 auto pfd = options.at( "protocol-features-dir" ).as<bfs::path>();
730 if( pfd.is_relative())
732 else
733 protocol_features_dir = pfd;
734
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 ) {
743 auto itr = my->loaded_checkpoints.find(item.first);
744 if( itr != my->loaded_checkpoints.end() ) {
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"))
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) {
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" )) {
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()));
834 }
835
836 if( options.at( "print-genesis-json" ).as<bool>()) {
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
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
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." );
874 } else if( options.at( "hard-replay-blockchain" ).as<bool>()) {
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." );
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>();
889 "Cannot load snapshot, ${name} does not exist", ("name", my->snapshot_path->generic_string()) );
890
891
892
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();
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";
908 plugin_config_exception,
909 "Snapshot can only be used to initialize an empty database." );
910
913 if( block_log_genesis ) {
914 const auto& block_log_chain_id = block_log_genesis->compute_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 {
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
935
936 std::optional<genesis_state> block_log_genesis;
937 std::optional<chain_id_type> block_log_chain_id;
938
941 if( block_log_genesis ) {
942 block_log_chain_id = block_log_genesis->compute_chain_id();
943 } else {
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
958
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
969 plugin_config_exception,
970 "Specified genesis file '${genesis}' does not exist.",
971 ("genesis", genesis_file.generic_string()));
972
974
975 if( options.count( "genesis-timestamp" ) ) {
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
1025 chain_id = my->genesis->compute_chain_id();
1026 } else {
1027
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
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,
1096 my->abi_serializer_max_time_us );
1097 }
1098 }
1099
1100
1101 if ( options.at( "deep-mind" ).as<bool>() ) {
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124 setbuf(stdout, NULL);
1125
1126
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
1134 }
1135
1136
1139 return my->chain->fetch_block_by_number( block_num );
1140 } );
1141
1144 return my->chain->fetch_block_by_id( id );
1145 } );
1146
1148 return my->chain->head_block_id();
1149 } );
1150
1152 [this]() {
1153 return my->chain->last_irreversible_block_num();
1154 } );
1155
1156
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
1168 });
1169
1170 my->accepted_block_header_connection = my->chain->accepted_block_header.connect(
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
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(
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(
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}
#define SYS_THROW(exc_type, FORMAT,...)
#define SYS_ASSERT(expr, exc_type, FORMAT,...)
#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)
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)
static string to_pretty_string(const variant &v, const yield_function_t &yield, const output_formatting format=output_formatting::stringify_large_ints_and_doubles)
static variant from_string(const string &utf8_str, const parse_type ptype=parse_type::legacy_parser, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
wraps boost::filesystem::path to provide platform independent path manipulation.
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 enable_accept_transactions()
void do_hard_replay(const variables_map &options)
#define FC_LOG_AND_RETHROW()
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)
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
sysio::chain::action_name action_name
std::shared_ptr< signed_block > signed_block_ptr
std::shared_ptr< block_state > block_state_ptr
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
unsigned __int64 uint64_t
static constexpr int medium
static constexpr int high
static const string sysio_root_key