29 #include <boost/range/adaptor/transformed.hpp> 30 #include <boost/algorithm/string.hpp> 40 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY 41 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "bcutil" 43 namespace po = boost::program_options;
66 return reinterpret_cast<const std::size_t &
>(h);
79 int main(
int argc,
char* argv[])
88 available_dbs =
"available: " + available_dbs;
94 boost::filesystem::path output_file_path;
96 po::options_description desc_cmd_only(
"Command line options");
97 po::options_description desc_cmd_sett(
"Command line options and settings options");
100 "database", available_dbs.c_str(), default_db_type
113 po::options_description desc_options(
"Allowed options");
114 desc_options.add(desc_cmd_only).add(desc_cmd_sett);
116 po::positional_options_description positional_options;
117 positional_options.add(arg_input.name, -1);
119 po::variables_map vm;
122 auto parser = po::command_line_parser(argc, argv).options(desc_options).positional(positional_options);
123 po::store(parser.run(), vm);
133 std::cout << desc_options << std::endl;
153 std::cerr <<
"Invalid database type: " << db_type << std::endl;
168 LOG_PRINT_L0(
"Initializing source blockchain (BlockchainDB)");
170 std::unique_ptr<Blockchain> core_storage;
172 core_storage.reset(
new Blockchain(m_mempool));
176 LOG_ERROR(
"Attempted to use non-existent database type: " << db_type);
177 throw std::runtime_error(
"Attempting to use non-existent database type");
182 LOG_PRINT_L0(
"Loading blockchain from folder " << filename <<
" ...");
188 catch (
const std::exception& e)
193 r = core_storage->
init(db, net_type);
196 LOG_PRINT_L0(
"Source blockchain storage initialized OK");
201 std::unordered_map<output_data, std::list<reference>> outputs;
202 std::unordered_map<uint64_t,uint64_t> indices;
207 const bool coinbase = tx.
vin.size() == 1 && tx.
vin[0].type() ==
typeid(
txin_gen);
211 for (
const auto &out: tx.
vout)
213 if (opt_rct_only && out.amount)
215 uint64_t index = indices[out.amount]++;
217 auto itb = outputs.emplace(od, std::list<reference>());
218 itb.first->first.info(coinbase,
height);
221 for (
const auto &in: tx.
vin)
225 const auto &txin = boost::get<txin_to_key>(in);
226 if (opt_rct_only && txin.amount != 0)
230 for (
size_t n = 0; n < txin.key_offsets.size(); ++n)
239 std::unordered_map<uint64_t, uint64_t> counts;
241 for (
const auto &out: outputs)
243 counts[out.second.size()]++;
248 for (
const auto &c: counts)
250 float percent = 100.f * c.second / total;
251 MINFO(
std::to_string(c.second) <<
" outputs used " << c.first <<
" times (" << percent <<
"%)");
256 MINFO(
"No outputs to process");
const char *const ELECTRONEUM_RELEASE_NAME
output_data(uint64_t a, uint64_t i, bool cb, uint64_t h)
reference(uint64_t h, uint64_t rs, uint64_t p)
virtual uint64_t get_tx_block_height(const crypto::hash &h) const =0
fetches the height of a transaction's block
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
void mlog_set_log(const char *log)
#define CATCH_ENTRY(location, return_val)
std::string mlog_get_default_log_path(const char *default_filename)
bool for_all_transactions(std::function< bool(const crypto::hash &, const cryptonote::transaction &)>, bool pruned) const
perform a check on all transactions in the blockchain
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)
provides the implementation of varint's
const command_line::arg_descriptor< bool, false > arg_stagenet_on
const arg_descriptor< bool > arg_help
std::string blockchain_db_types(const std::string &sep)
std::vector< uint64_t > relative_output_offsets_to_absolute(const std::vector< uint64_t > &off)
virtual void open(const std::string &filename, const int db_flags=0)=0
open a db, or create it if necessary.
std::vector< tx_out > vout
int main(int argc, char *argv[])
Holds cryptonote related classes and helpers.
const char *const ELECTRONEUM_VERSION_FULL
bool blockchain_valid_db_type(const std::string &db_type)
std::vector< txin_v > vin
const command_line::arg_descriptor< bool, false > arg_testnet_on
BlockchainDB * new_db(const std::string &db_type)
bool handle_error_helper(const boost::program_options::options_description &desc, F parser)
const command_line::arg_descriptor< std::string > arg_log_level
unsigned __int64 uint64_t
void cn_fast_hash(const void *data, size_t length, char *hash)
void add_arg(boost::program_options::options_description &description, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg, bool unique=true)
const BlockchainDB & get_db() const
get a reference to the BlockchainDB in use by Blockchain
bool operator==(const output_data &other) const
void info(bool c, uint64_t h) const
const GenericPointer< typename T::ValueType > T2 T::AllocatorType & a
Transaction pool, handles transactions which are not part of a block.
size_t operator()(const output_data &od) const
The BlockchainDB backing store interface declaration/contract.
T get_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, false, true > &arg)
bool init(BlockchainDB *db, const network_type nettype=MAINNET, bool offline=false, const cryptonote::test_options *test_options=NULL, difficulty_type fixed_difficulty=0, const GetCheckpointsCallback &get_checkpoints=nullptr, bool ignore_bsig=false, bool fallback_to_pow=false)
Initialize the Blockchain state.
std::string to_string(t_connection_type type)
bool is_arg_defaulted(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)