680{
682
684
685 std::string default_db_type = "lmdb";
686
688 available_dbs = "available: " + available_dbs;
689
693 std::string m_config_folder;
694 std::string db_arg_str;
695
697
698 std::string import_file_path;
699
700 po::options_description desc_cmd_only("Command line options");
701 po::options_description desc_cmd_sett("Command line options and settings options");
709 "count-blocks"
710 , "Count blocks in bootstrap file and exit"
711 , false
712 };
714 "database", available_dbs.c_str(), default_db_type
715 };
717 "Blindly trust the import file and use potentially malicious blocks and transactions during import (only enable if you exported the file yourself)", false};
719 "Batch transactions for faster import", true};
721 "Resume from current height if output database already exists", true};
722
728
733
734
735
736 desc_cmd_sett.add_options()
737 (arg_noverify.name,
make_semantic(arg_noverify), arg_noverify.description)
738 (arg_batch.name,
make_semantic(arg_batch), arg_batch.description)
739 (arg_resume.name,
make_semantic(arg_resume), arg_resume.description)
740 ;
741
742 po::options_description desc_options("Allowed options");
743 desc_options.add(desc_cmd_only).add(desc_cmd_sett);
745
746 po::variables_map vm;
748 {
749 po::store(po::parse_command_line(argc, argv, desc_options), vm);
750 po::notify(vm);
751 return true;
752 });
753 if (! r)
754 return 1;
755
761
763 {
765 std::cout << desc_options << std::endl;
766 return 1;
767 }
768
770 {
771 std::cerr <<
"Error: batch-size set, but batch option not enabled" <<
ENDL;
772 return 1;
773 }
774 if (! db_batch_size)
775 {
776 std::cerr <<
"Error: batch-size must be > 0" <<
ENDL;
777 return 1;
778 }
780 {
781
782
783
784
785
786 if (db_batch_size > db_batch_size_verify)
787 {
788 db_batch_size = db_batch_size_verify;
789 }
790 }
791
794 if (opt_testnet && opt_stagenet)
795 {
796 std::cerr <<
"Error: Can't specify more than one of --testnet and --stagenet" <<
ENDL;
797 return 1;
798 }
801
805 else
806 mlog_set_log(std::string(std::to_string(log_level) +
",bcutil:INFO").c_str());
807
808 MINFO(
"Starting...");
809
810 boost::filesystem::path fs_import_file_path;
811
814 else
815 fs_import_file_path = boost::filesystem::path(m_config_folder) /
"export" /
BLOCKCHAIN_RAW;
816
817 import_file_path = fs_import_file_path.string();
818
820 {
822 bootstrap.count_blocks(import_file_path);
823 return 0;
824 }
825
826
827 std::string db_type;
828 int db_flags = 0;
832 {
833 std::cerr <<
"Error parsing database argument(s)" <<
ENDL;
834 return 1;
835 }
836
838 {
839 std::cerr << "Invalid database type: " << db_type << std::endl;
840 return 1;
841 }
842
843 MINFO(
"database: " << db_type);
844 MINFO(
"database flags: " << db_flags);
845 MINFO(
"verify: " << std::boolalpha << opt_verify << std::noboolalpha);
846 if (opt_batch)
847 {
848 MINFO(
"batch: " << std::boolalpha << opt_batch << std::noboolalpha
849 << " batch size: " << db_batch_size);
850 }
851 else
852 {
853 MINFO(
"batch: " << std::boolalpha << opt_batch << std::noboolalpha);
854 }
855 MINFO(
"resume: " << std::boolalpha << opt_resume << std::noboolalpha);
856 MINFO(
"nettype: " << (opt_testnet ?
"testnet" : opt_stagenet ?
"stagenet" :
"mainnet"));
857
858 MINFO(
"bootstrap file path: " << import_file_path);
859 MINFO(
"database path: " << m_config_folder);
860
862 {
864 "Import is set to proceed WITHOUT VERIFICATION.\n"
865 "This is a DANGEROUS operation: if the file was tampered with in transit, or obtained from a malicious source,\n"
866 "you could end up with a compromised database. It is recommended to NOT use " << arg_noverify.name << ".\n"
867 "*****************************************************************************************\n"
868 "You have 90 seconds to press ^C or terminate this program before unverified import starts\n"
869 "*****************************************************************************************");
870 sleep(90);
871 }
872
875
876 try
877 {
878
880#if defined(PER_BLOCK_CHECKPOINT)
882#else
884#endif
885 if (!
core.
init(vm,
nullptr, get_checkpoints))
886 {
887 std::cerr <<
"Failed to initialize core" <<
ENDL;
888 return 1;
889 }
891
893 {
898 return 0;
899 }
900
902 {
903 MINFO(
"Dropping hard fork tables...");
906 return 0;
907 }
908
910
911
912
913
914
916 }
918 {
919 std::cout << std::string(
"Error loading blockchain db: ") + e.
what() +
" -- shutting down now" <<
ENDL;
921 return 1;
922 }
923
924 return 0;
925
927}
int import_from_file(cryptonote::core &core, const std::string &import_file_path, uint64_t block_stop=0)
int pop_blocks(cryptonote::core &core, int num_blocks)
int parse_db_arguments(const std::string &db_arg_str, std::string &db_type, int &db_flags)
bool validate_file_checksum_against_dns(std::string import_file_path)
uint64_t num_blocks(const std::vector< test_event_entry > &events)
virtual void drop_hard_fork_info()=0
delete hard fork info from database
virtual void set_batch_transactions(bool)=0
sets whether or not to batch transactions
A generic BlockchainDB exception.
const char * what() const
static void init_options(boost::program_options::options_description &desc)
adds command line options to the given options set
bool deinit()
performs safe shutdown steps for core and core components
void disable_dns_checkpoints(bool disable=true)
set whether or not to enable or disable DNS checkpoints
bool init(const boost::program_options::variables_map &vm, const test_options *test_options=NULL, const GetCheckpointsCallback &get_checkpoints=nullptr)
initializes the core as needed
void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size=MAX_LOG_FILE_SIZE, const std::size_t max_log_files=MAX_LOG_FILES)
#define CATCH_ENTRY(location, return_val)
std::string mlog_get_default_log_path(const char *default_filename)
void mlog_set_log(const char *log)
#define MCLOG_RED(level, cat, x)
const epee::span< const unsigned char > GetCheckpointsData(cryptonote::network_type network)
void add_arg(boost::program_options::options_description &description, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg, bool unique=true)
const arg_descriptor< bool > arg_help
boost::program_options::typed_value< T, char > * make_semantic(const arg_descriptor< T, true > &)
bool is_arg_defaulted(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
bool handle_error_helper(const boost::program_options::options_description &desc, F parser)
std::enable_if<!std::is_same< T, bool >::value, bool >::type has_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
T get_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, false, true > &arg)
const command_line::arg_descriptor< std::string, false, true, 2 > arg_data_dir
const command_line::arg_descriptor< bool, false > arg_testnet_on
std::function< const epee::span< const unsigned char >(cryptonote::network_type network)> GetCheckpointsCallback
Callback routine that returns checkpoints data for specific network type.
bool blockchain_valid_db_type(const std::string &db_type)
const command_line::arg_descriptor< bool, false > arg_stagenet_on
std::string blockchain_db_types(const std::string &sep)
const command_line::arg_descriptor< std::string > arg_log_level
@ Warning
Useful when application has potentially harmful situtaions.
const char *const ELECTRONEUM_RELEASE_NAME
const char *const ELECTRONEUM_VERSION_FULL