32 #include <boost/algorithm/string.hpp>
37 #include <unordered_set>
57 #undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
58 #define ELECTRONEUM_DEFAULT_LOG_CATEGORY "cn"
62 #define MERROR_VER(x) MCERROR("verify", x)
64 #define BAD_SEMANTICS_TXES_MAX_SIZE 100
67 #define BLOCK_SIZE_SANITY_LEEWAY 100
73 ,
"Run on testnet. The wallet must be launched with --testnet flag."
78 ,
"Run on stagenet. The wallet must be launched with --stagenet flag."
83 ,
"Run in a regression testing mode."
88 ,
"Fixed difficulty used for testing."
93 ,
"Ignore block signature & signatory verification. Used for testing."
98 ,
"Specify data directory"
102 if (testnet_stagenet[0])
103 return (boost::filesystem::path(val) /
"testnet").
string();
104 else if (testnet_stagenet[1])
105 return (boost::filesystem::path(val) /
"stagenet").
string();
111 ,
"Do not listen for peers, nor connect to any"
114 "disable-dns-checkpoints"
115 ,
"Do not retrieve checkpoints from DNS"
118 "block-download-max-size"
119 ,
"Set maximum size of block download queue in bytes (0 for default)"
125 ,
"For net tests: in download, discard ALL blocks instead checking/saving them (very fast)"
128 "test-drop-download-height"
129 ,
"Like test-drop-download but discards only after around certain height"
133 "test-dbg-lock-sleep"
134 ,
"Sleep time in ms, defaults to 0 (off), used to debug before/after locking mutex. Values 100 to 1000 are good for tests."
138 "enforce-dns-checkpointing"
139 ,
"checkpoints from DNS server will be enforced"
144 ,
"Sync up most of the way by using embedded, known block hashes."
148 "prep-blocks-threads"
149 ,
"Max number of threads to use when preparing block hashes in groups."
154 ,
"Show time-stats when processing blocks/txs and disk synchronization."
159 ,
"How many blocks to sync at once during chain synchronization (0 = adaptive)."
164 ,
"Check for new versions of electroneum: [disabled|notify|download|update]"
169 ,
"Relay blocks as fluffy blocks (obsolete, now default)"
174 ,
"Relay blocks as normal blocks"
179 ,
"Pad relayed transactions to help defend against traffic volume analysis"
184 ,
"Set maximum txpool weight in bytes."
189 ,
"Run a program for each new block, '%s' will be replaced by the block hash"
199 ,
"Run a program for each reorg, '%s' will be replaced by the split height, "
200 "'%h' will be replaced by the new blockchain height, '%n' will be "
201 "replaced by the number of new blocks in the new chain, and '%d' will be "
202 "replaced by the number of blocks discarded from the old chain"
207 ,
"Run a program when the block rate undergoes large fluctuations. This might "
208 "be a sign of large amounts of hash rate going on and off the Electroneum network, "
209 "and thus be of potential interest in predicting attacks. %t will be replaced "
210 "by the number of minutes for the observation window, %b by the number of "
211 "blocks observed within that window, and %e by the number of blocks that was "
212 "expected in that window. It is suggested that this notification is used to "
213 "automatically increase the number of confirmations required before a payment "
225 ,
"Disables all Validator feature and fallback consensus to standard Proof-of-Work (CryptoNote V1)."
226 "This argument is a decentralization safety measure in case something happens with Electroneum Ltd"
227 "so that users can fork the network to Proof of Work. (Anti Meteor Feature)."
228 "Before using this flag, please determine whether or not you want to use a checkpoint for the PoW fork (--fallback-to-pow-checkpoint-hash and --fallback-to-pow-checkpoint-height)"
229 "Please note that this is only a temporary solution so that people can continue the chain in a sensible decentralised way immediately if Electroneum ceased to exist. Long term solutions are explained in our docs folder"
230 "***WARNING: IF YOU USE THIS ARGUMENT AND MINE BLOCKS AND LATER WISH TO RETURN TO THE TIP OF THE V8 *MODERATED* BLOCKCHAIN, YOU WILL HAVE TO MANUALLY POP BLOCKS BACK USING THE DAEMON (OR IMPORT) PROGRAM"
235 "fallback-to-pow-checkpoint-height"
236 ,
"Used in conjunction with --fallback-to-pow. This flag allows you to specify the *height* of a checkpoint that would mark the new beginning of the PoW chain agreed upon by the community"
241 "fallback-to-pow-checkpoint-hash"
242 ,
"Used in conjunction with --fallback-to-pow. This flag allows you to specify the *hash* of a checkpoint that would mark the new beginning of the PoW chain agreed upon by the community"
249 m_mempool(m_blockchain_storage),
250 m_blockchain_storage(m_mempool),
253 m_starter_message_showed(
false),
254 m_target_blockchain_height(0),
255 m_checkpoints_path(
""),
256 m_last_dns_checkpoints_update(0),
257 m_last_json_checkpoints_update(0),
258 m_disable_dns_checkpoints(
false),
259 m_update_download(0),
261 m_update_available(
false),
262 m_pad_transactions(
false)
264 m_checkpoints_updating.clear();
270 m_pprotocol = pprotocol;
272 m_pprotocol = &m_protocol_stub;
282 m_checkpoints_path = path;
292 if (m_nettype !=
MAINNET || m_disable_dns_checkpoints)
return true;
294 if (m_checkpoints_updating.test_and_set())
return true;
297 if (
time(NULL) - m_last_dns_checkpoints_update >= 3600)
300 m_last_dns_checkpoints_update =
time(NULL);
301 m_last_json_checkpoints_update =
time(NULL);
303 else if (
time(NULL) - m_last_json_checkpoints_update >= 600)
306 m_last_json_checkpoints_update =
time(NULL);
309 m_checkpoints_updating.clear();
320 return m_validators->getSerializedValidatorList();
324 return m_validators->setValidatorsList(v_list,
true, isEmergencyUpdate);
328 return m_validators->isValid();
334 m_blockchain_storage.
cancel();
338 boost::lock_guard<boost::mutex> lock(m_update_mutex);
339 handle = m_update_download;
340 m_update_download = 0;
385 bool core::handle_command_line(
const boost::program_options::variables_map& vm)
396 auto data_dir = boost::filesystem::path(m_config_folder);
401 if (!
checkpoints.init_default_checkpoints(m_nettype))
403 throw std::runtime_error(
"Failed to initialize checkpoints");
406 if(m_fallback_to_pow_checkpoint_height != 0 && m_fallback_to_pow_checkpoint_hash !=
""){
407 checkpoints.add_checkpoint(m_fallback_to_pow_checkpoint_height, m_fallback_to_pow_checkpoint_hash);
413 boost::filesystem::path checkpoint_json_hashfile_fullpath =
data_dir /
json;
421 m_fluffy_blocks_enabled = !
get_arg(vm, arg_no_fluffy_blocks);
422 m_pad_transactions =
get_arg(vm, arg_pad_transactions);
426 MWARNING(arg_fluffy_blocks.name <<
" is obsolete, it is now default");
458 std::vector<std::pair<cryptonote::blobdata, cryptonote::block>> bs;
461 for (
const auto &b: bs)
462 blocks.push_back(b.second);
466 bool core::get_transactions(
const std::vector<crypto::hash>& txs_ids, std::vector<cryptonote::blobdata>& txs, std::vector<crypto::hash>& missed_txs)
const
471 bool core::get_split_transactions_blobs(
const std::vector<crypto::hash>& txs_ids, std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>>& txs, std::vector<crypto::hash>& missed_txs)
const
482 bool core::get_transactions(
const std::vector<crypto::hash>& txs_ids, std::vector<transaction>& txs, std::vector<crypto::hash>& missed_txs)
const
511 bool r = handle_command_line(vm);
523 bool is_validator_key_valid = std::count_if(validator_key.begin(), validator_key.end(), [](
int c) {return !std::isxdigit(c);}) == 0;
524 if(!is_validator_key_valid || validator_key.size() % 2 != 0) {
525 validator_key.clear();
528 boost::filesystem::path folder(m_config_folder);
533 CHECK_AND_ASSERT_MES (boost::filesystem::exists(folder) || boost::filesystem::create_directories(folder),
false,
534 std::string(
"Failed to create directory ").append(folder.string()).c_str());
539 const boost::filesystem::path old_files = folder;
540 if (boost::filesystem::exists(old_files /
"blockchain.bin"))
542 MWARNING(
"Found old-style blockchain.bin in " << old_files.string());
543 MWARNING(
"Electroneum now uses a new format. You can either remove blockchain.bin to start syncing");
544 MWARNING(
"the blockchain anew, or use electroneum-blockchain-export and electroneum-blockchain-import to");
545 MWARNING(
"convert your existing blockchain.bin to the new format. See README.md for instructions.");
552 std::unique_ptr<BlockchainDB> db(
new_db(db_type));
555 LOG_ERROR(
"Attempted to use non-existent database type");
559 folder /= db->get_db_name();
560 MGINFO(
"Loading blockchain from folder " << folder.string() <<
" ...");
565 bool sync_on_blocks =
true;
571 if (!db->remove_data_file(filename))
573 MERROR(
"Failed to remove data file in " << filename);
582 std::vector<std::string> options;
584 boost::split(options, db_sync_mode, boost::is_any_of(
" :"));
587 for(
const auto &
option : options)
593 if(options.size() == 0)
596 db_flags = DEFAULT_FLAGS;
599 bool safemode =
false;
600 if(options.size() >= 1)
602 if(options[0] ==
"safe")
608 else if(options[0] ==
"fast")
613 else if(options[0] ==
"fastest")
616 sync_threshold = 1000;
620 db_flags = DEFAULT_FLAGS;
623 if(options.size() >= 2 && !safemode)
625 if(options[1] ==
"sync")
627 else if(options[1] ==
"async")
631 if(options.size() >= 3 && !safemode)
635 if (*endptr ==
'\0' || !strcmp(endptr,
"blocks"))
637 sync_on_blocks =
true;
640 else if (!strcmp(endptr,
"bytes"))
642 sync_on_blocks =
false;
647 LOG_ERROR(
"Invalid db sync mode: " << options[2]);
655 db->open(filename, db_flags);
666 sync_on_blocks, sync_threshold, sync_mode, fast_sync, validator_key);
673 catch (
const std::exception &e)
675 MERROR(
"Failed to parse block notify spec: " << e.
what());
683 catch (
const std::exception &e)
685 MERROR(
"Failed to parse reorg notify spec: " << e.
what());
693 catch (
const std::exception &e)
695 MERROR(
"Failed to parse block rate notify spec: " << e.
what());
706 r = m_blockchain_storage.
init(db.release(), m_nettype, m_offline, regtest ? ®test_test_options :
test_options, fixed_difficulty, get_checkpoints, ignore_bsig, m_fallback_to_pow);
708 r = m_mempool.
init(max_txpool_weight);
721 MGINFO(
"Loading checkpoints");
728 if (check_updates_string ==
"disabled")
729 check_updates_level = UPDATES_DISABLED;
730 else if (check_updates_string ==
"notify")
731 check_updates_level = UPDATES_NOTIFY;
732 else if (check_updates_string ==
"download")
733 check_updates_level = UPDATES_DOWNLOAD;
734 else if (check_updates_string ==
"update")
735 check_updates_level = UPDATES_UPDATE;
737 MERROR(
"Invalid argument to --dns-versions-check: " << check_updates_string);
741 check_updates_level = UPDATES_DISABLED;
743 r = m_miner.
init(vm, m_nettype, m_fallback_to_pow);
751 MGINFO(
"Pruning blockchain...");
760 if(!m_fallback_to_pow) {
765 m_validators->enable();
769 return load_state_data();
777 bool core::load_state_data()
787 m_blockchain_storage.
deinit();
793 m_test_drop_download =
false;
798 m_test_drop_download_height =
height;
803 return m_test_drop_download;
808 if (m_test_drop_download_height == 0)
819 tvc = boost::value_initialized<tx_verification_context>();
823 LOG_PRINT_L1(
"WRONG TRANSACTION BLOB, too big size " << tx_blob.size() <<
", rejected");
829 tx_hash = crypto::null_hash;
831 if(!parse_tx_from_blob(tx, tx_hash, tx_blob))
833 LOG_PRINT_L1(
"WRONG TRANSACTION BLOB, Failed to parse, rejected");
839 bad_semantics_txes_lock.lock();
840 for (
int idx = 0; idx < 2; ++idx)
842 if (bad_semantics_txes[idx].find(tx_hash) != bad_semantics_txes[idx].end())
844 bad_semantics_txes_lock.unlock();
845 LOG_PRINT_L1(
"Transaction already seen with bad semantics, rejected");
850 bad_semantics_txes_lock.unlock();
863 if (tx.
version < min_tx_version)
874 if(!check_tx_syntax(tx))
876 LOG_PRINT_L1(
"WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash <<
" syntax, rejected");
877 tvc.m_verification_failed =
true;
884 void core::set_semantics_failed(
const crypto::hash &tx_hash)
886 LOG_PRINT_L1(
"WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash <<
" semantic, rejected");
887 bad_semantics_txes_lock.lock();
888 bad_semantics_txes[0].insert(tx_hash);
891 std::swap(bad_semantics_txes[0], bad_semantics_txes[1]);
892 bad_semantics_txes[0].clear();
894 bad_semantics_txes_lock.unlock();
897 bool core::handle_incoming_tx_accumulated_batch(std::vector<tx_verification_batch_info> &tx_info,
bool keeped_by_block)
902 MTRACE(
"Skipping semantics check for tx kept by block in embedded hash area");
906 std::vector<const rct::rctSig*> rvv;
907 for (
size_t n = 0; n < tx_info.size(); ++n)
909 if (!check_tx_semantic(*tx_info[n].tx, keeped_by_block))
911 set_semantics_failed(tx_info[n].tx_hash);
912 tx_info[n].tvc.m_verification_failed =
true;
913 tx_info[n].result =
false;
919 LOG_PRINT_L1(
"One transaction among this group has bad semantics, verifying one at a time");
921 const bool assumed_bad = rvv.size() == 1;
922 for (
size_t n = 0; n < tx_info.size(); ++n)
924 if (!tx_info[n].result)
930 set_semantics_failed(tx_info[n].tx_hash);
931 tx_info[n].tvc.m_verification_failed =
true;
932 tx_info[n].result =
false;
940 bool core::handle_incoming_txs(
const std::vector<blobdata>& tx_blobs, std::vector<tx_verification_context>& tvc,
bool keeped_by_block,
bool relayed,
bool do_not_relay)
946 std::vector<result> results(tx_blobs.size());
948 tvc.resize(tx_blobs.size());
951 std::vector<blobdata>::const_iterator it = tx_blobs.begin();
952 for (
size_t i = 0; i < tx_blobs.size(); i++, ++it) {
953 tpool.
submit(&waiter, [&, i, it] {
956 results[i].res = handle_incoming_tx_pre(*it, tvc[i], results[i].tx, results[i].
hash, keeped_by_block, relayed, do_not_relay);
958 catch (
const std::exception &e)
960 MERROR_VER(
"Exception in handle_incoming_tx_pre: " << e.what());
961 tvc[i].m_verification_failed =
true;
962 results[i].res =
false;
967 it = tx_blobs.begin();
968 std::vector<bool> already_have(tx_blobs.size(),
false);
969 for (
size_t i = 0; i < tx_blobs.size(); i++, ++it) {
972 if(m_mempool.
have_tx(results[i].hash))
974 LOG_PRINT_L2(
"tx " << results[i].
hash <<
"already have transaction in tx_pool");
975 already_have[i] =
true;
977 else if(m_blockchain_storage.
have_tx(results[i].hash))
979 LOG_PRINT_L2(
"tx " << results[i].
hash <<
" already have transaction in blockchain");
980 already_have[i] =
true;
984 tpool.
submit(&waiter, [&, i, it] {
987 results[i].res = handle_incoming_tx_post(*it, tvc[i], results[i].tx, results[i].
hash, keeped_by_block, relayed, do_not_relay);
989 catch (
const std::exception &e)
991 MERROR_VER(
"Exception in handle_incoming_tx_post: " << e.what());
992 tvc[i].m_verification_failed =
true;
993 results[i].res =
false;
1000 std::vector<tx_verification_batch_info>
tx_info;
1001 tx_info.reserve(tx_blobs.size());
1002 for (
size_t i = 0; i < tx_blobs.size(); i++) {
1003 if (!results[i].
res || already_have[i])
1005 tx_info.push_back({&results[i].tx, results[i].hash, tvc[i], results[i].res});
1008 handle_incoming_tx_accumulated_batch(
tx_info, keeped_by_block);
1011 it = tx_blobs.begin();
1012 for (
size_t i = 0; i < tx_blobs.size(); i++, ++it) {
1013 if (!results[i].
res)
1018 if (keeped_by_block)
1020 if (already_have[i])
1024 ok &= add_new_tx(results[i].tx, results[i].
hash, tx_blobs[i], weight, tvc[i], keeped_by_block, relayed, do_not_relay);
1025 if(tvc[i].m_verification_failed)
1026 {
MERROR_VER(
"Transaction verification failed: " << results[i].
hash);}
1027 else if(tvc[i].m_verification_impossible)
1028 {
MERROR_VER(
"Transaction verification impossible: " << results[i].
hash);}
1030 if(tvc[i].m_added_to_pool)
1040 std::vector<cryptonote::blobdata> tx_blobs;
1041 tx_blobs.push_back(tx_blob);
1042 std::vector<tx_verification_context> tvcv(1);
1050 st_inf.mining_speed = m_miner.
get_speed();
1059 bool core::check_tx_semantic(
const transaction& tx,
bool keeped_by_block)
const
1089 if((tx.
version != 2 && amount_in <= amount_out) || (tx.
version == 2 && amount_in != amount_out)) {
1090 MERROR_VER(
"tx with wrong amounts: ins " << amount_in <<
", outs " << amount_out <<
", rejected for tx id= "
1105 if(!check_tx_inputs_utxos_diff(tx))
1107 MERROR_VER(
"tx uses a single utxo more than once");
1114 if(!check_tx_inputs_keyimages_diff(tx))
1116 MERROR_VER(
"tx uses a single key image more than once");
1120 if (!check_tx_inputs_keyimages_domain(tx))
1122 MERROR_VER(
"tx uses key image not in the valid domain");
1138 for(
auto& ki: key_im)
1148 if (block_sync_size > 0)
1149 return block_sync_size;
1150 if (
height >= quick_height)
1170 std::vector<transaction> txs;
1171 std::vector<crypto::hash> missed_txs;
1175 for(
const auto& tx: txs)
1180 emission_amount += coinbase_amount - tx_fee_amount;
1181 total_fee_amount += tx_fee_amount;
1186 return std::pair<uint64_t, uint64_t>(emission_amount, total_fee_amount);
1189 bool core::check_tx_inputs_keyimages_diff(
const transaction& tx)
const
1191 std::unordered_set<crypto::key_image> ki;
1192 for(
const auto& in: tx.
vin)
1195 if(!ki.insert(tokey_in.k_image).second)
1201 bool core::check_tx_inputs_utxos_diff(
const transaction& tx)
const
1203 std::unordered_set<std::string> ins;
1204 for(
const auto& in: tx.vin)
1213 bool core::check_tx_inputs_ring_members_diff(
const transaction& tx)
const
1218 for(
const auto& in: tx.vin)
1221 for (
size_t n = 1; n < tokey_in.key_offsets.size(); ++n)
1222 if (tokey_in.key_offsets[n] == 0)
1229 bool core::check_tx_inputs_keyimages_domain(
const transaction& tx)
const
1231 std::unordered_set<crypto::key_image> ki;
1232 for(
const auto& in: tx.vin)
1241 bool core::add_new_tx(transaction& tx, tx_verification_context& tvc,
bool keeped_by_block,
bool relayed,
bool do_not_relay)
1247 return add_new_tx(tx, tx_hash, bl, tx_weight, tvc, keeped_by_block, relayed, do_not_relay);
1258 if(m_mempool.
have_tx(tx_hash))
1260 LOG_PRINT_L2(
"tx " << tx_hash <<
"already have transaction in tx_pool");
1264 if(m_blockchain_storage.
have_tx(tx_hash))
1266 LOG_PRINT_L2(
"tx " << tx_hash <<
" already have transaction in blockchain");
1271 return m_mempool.
add_tx(tx, tx_hash, blob, tx_weight, tvc, keeped_by_block, relayed, do_not_relay,
version);
1274 bool core::relay_txpool_transactions()
1277 std::vector<std::pair<crypto::hash, cryptonote::blobdata>> txs;
1280 cryptonote_connection_context fake_context =
AUTO_VAL_INIT(fake_context);
1283 for (
auto it = txs.begin(); it != txs.end(); ++it)
1285 r.txs.push_back(it->second);
1295 std::vector<std::pair<crypto::hash, cryptonote::blobdata>> txs;
1300 LOG_ERROR(
"Failed to parse relayed transaction");
1303 txs.push_back(std::make_pair(tx_hash,
std::move(tx_blob)));
1322 bool core::find_blockchain_supplement(
const uint64_t req_start_block,
const std::list<crypto::hash>& qblock_ids, std::vector<std::pair<std::pair<cryptonote::blobdata, crypto::hash>, std::vector<std::pair<crypto::hash, cryptonote::blobdata> > > >&
blocks,
uint64_t& total_height,
uint64_t& start_height,
bool pruned,
bool get_miner_tx_hash,
size_t max_count)
const
1324 return m_blockchain_storage.
find_blockchain_supplement(req_start_block, qblock_ids,
blocks, total_height, start_height, pruned, get_miner_tx_hash, max_count);
1334 return m_blockchain_storage.
get_output_distribution(amount, from_height, to_height, start_height, distribution, base);
1365 bce.
txs.push_back(txblob);
1372 bvc = boost::value_initialized<block_verification_context>();
1374 std::vector<block_complete_entry>
blocks;
1379 catch (
const std::exception &e)
1384 std::vector<block> pblocks;
1387 MERROR(
"Block found, but failed to prepare to add");
1400 std::vector<crypto::hash> missed_txs;
1401 std::vector<cryptonote::blobdata> txs;
1405 LOG_PRINT_L1(
"Block found but, seems that reorganize just happened after that, do not relay this block");
1409 <<
", b.tx_hashes.size()=" << b.
tx_hashes.size() <<
", missed_txs.size()" << missed_txs.size());
1414 arg.b.txs.push_back(tx);
1418 if(m_fallback_to_pow) {
1422 update_miner_block_template();
1446 m_incoming_tx_lock.
lock();
1463 m_incoming_tx_lock.
unlock();
1472 bvc = boost::value_initialized<block_verification_context>();
1480 if (((
size_t)-1) <= 0xffffffff && block_blob.size() >= 0x3fffffff)
1481 MWARNING(
"This block's size is " << block_blob.size() <<
", closing on the 32 bit limit");
1493 LOG_PRINT_L1(
"Failed to parse and validate new block");
1500 add_new_block(*b, bvc);
1505 if(update_miner_blocktemplate)
1506 update_miner_block_template();
1524 LOG_PRINT_L1(
"WRONG BLOCK BLOB, sanity check failed on size " << block_blob.size() <<
", rejected");
1560 bool core::check_tx_syntax(
const transaction& tx)
const
1628 bool core::update_miner_block_template()
1636 if(!m_starter_message_showed)
1640 main_message =
"The daemon is running offline and will not attempt to sync to the Electroneum network.";
1642 main_message =
"The daemon will start synchronizing with the network. This may take a long time to complete.";
1643 MGINFO_YELLOW(
ENDL <<
"**********************************************************************" <<
ENDL
1644 << main_message <<
ENDL
1646 <<
"You can set the level of process detailization through \"set_log <level|categories>\" command," <<
ENDL
1647 <<
"where <level> is between 0 (no details) and 4 (very verbose), or custom category based levels (eg, *:WARNING)." <<
ENDL
1649 <<
"Use the \"help\" command to see the list of available commands." <<
ENDL
1650 <<
"Use \"help <command>\" to see a command's documentation." <<
ENDL
1651 <<
"**********************************************************************" <<
ENDL);
1652 m_starter_message_showed =
true;
1656 m_txpool_auto_relayer.
do_call(boost::bind(&core::relay_txpool_transactions,
this));
1657 m_check_updates_interval.
do_call(boost::bind(&core::check_updates,
this));
1658 m_check_disk_space_interval.
do_call(boost::bind(&core::check_disk_space,
this));
1659 m_block_rate_interval.
do_call(boost::bind(&core::check_block_rate,
this));
1664 if(!m_fallback_to_pow) {
1665 m_validators->on_idle();
1671 bool core::check_fork_time()
1680 MCLOG_RED(level,
"global",
"**********************************************************************");
1681 MCLOG_RED(level,
"global",
"Last scheduled hard fork is too far in the past.");
1682 MCLOG_RED(level,
"global",
"We are most likely forked from the network. Daemon update needed now.");
1683 MCLOG_RED(level,
"global",
"**********************************************************************");
1686 MCLOG_RED(level,
"global",
"**********************************************************************");
1687 MCLOG_RED(level,
"global",
"Last scheduled hard fork time shows a daemon update is needed soon.");
1688 MCLOG_RED(level,
"global",
"**********************************************************************");
1716 bool core::check_updates()
1718 static const char software[] =
"electroneum";
1720 static const char buildtag[] = BOOST_PP_STRINGIZE(BUILD_TAG);
1721 static const char subdir[] =
"cli";
1723 static const char buildtag[] =
"source";
1724 static const char subdir[] =
"source";
1730 if (check_updates_level == UPDATES_DISABLED)
1734 MCDEBUG(
"updates",
"Checking for a new " << software <<
" version for " << buildtag);
1740 m_update_available =
false;
1746 m_update_available =
true;
1748 if (check_updates_level == UPDATES_NOTIFY) {
1749 std::vector<std::string> version_split;
1750 std::vector<std::string> latest_version_split;
1753 boost::split(latest_version_split,
version, [](
char c){
return c ==
'.';});
1757 for(
size_t i = 0; i < 2; i++) {
1758 if(version_split[i] != latest_version_split[i]) {
1769 const char *slash = strrchr(url.c_str(),
'/');
1771 filename = slash + 1;
1777 boost::unique_lock<boost::mutex> lock(m_update_mutex);
1779 if (m_update_download != 0)
1781 MCDEBUG(
"updates",
"Already downloading update");
1788 MCDEBUG(
"updates",
"We don't have that file already, downloading");
1789 const std::string tmppath = path.string() +
".tmp";
1792 MCDEBUG(
"updates",
"We have part of the file already, resuming download");
1794 m_last_update_length = 0;
1796 bool remove =
false, good =
true;
1802 MCERROR(
"updates",
"Failed to hash " << tmppath);
1808 MCERROR(
"updates",
"Download from " << uri <<
" does not match the expected hash");
1815 MCERROR(
"updates",
"Failed to download " << uri);
1818 boost::unique_lock<boost::mutex> lock(m_update_mutex);
1819 m_update_download = 0;
1825 MCERROR(
"updates",
"Failed to rename downloaded file");
1831 if (!boost::filesystem::remove(tmppath))
1833 MCERROR(
"updates",
"Failed to remove invalid downloaded file");
1840 if (length >= m_last_update_length + 1024 * 1024 * 10)
1842 m_last_update_length = length;
1843 MCDEBUG(
"updates",
"Downloaded " << length <<
"/" << (content_length ?
std::to_string(content_length) :
"unknown"));
1850 MCDEBUG(
"updates",
"We already have " << path <<
" with expected hash");
1855 if (check_updates_level == UPDATES_DOWNLOAD)
1858 MCERROR(
"updates",
"Download/update not implemented yet");
1862 bool core::check_disk_space()
1865 if (free_space < 1ull * 1024 * 1024 * 1024)
1868 MCLOG_RED(level,
"global",
"Free space is below 1 GB on " << m_config_folder);
1883 static double probability1(
unsigned int blocks,
unsigned int expected)
1889 static double probability(
unsigned int blocks,
unsigned int expected)
1894 for (
unsigned int b = 0; b <=
blocks; ++b)
1895 p += probability1(b, expected);
1897 else if (
blocks > expected)
1899 for (
unsigned int b =
blocks; b <= expected * 3 ; ++b)
1900 p += probability1(b, expected);
1905 bool core::check_block_rate()
1907 MDEBUG(
"Not checking block rate, not applicable.");
1912 MDEBUG(
"Not checking block rate, offline or syncing");
1918 const time_t now =
time(NULL);
1921 static const unsigned int seconds[] = { 5400, 3600, 1800, 1200, 600 };
1922 for (
size_t n = 0; n <
sizeof(seconds)/
sizeof(seconds[0]); ++n)
1925 const time_t time_boundary = now -
static_cast<time_t
>(seconds[n]);
1926 for (time_t ts: timestamps) b += ts >= time_boundary;
1928 MDEBUG(
"blocks in the last " << seconds[n] / 60 <<
" minutes: " << b <<
" (probability " << p <<
")");
1931 MWARNING(
"There were " << b <<
" blocks in the last " << seconds[n] / 60 <<
" minutes, there might be large hash rate changes, or we might be partitioned, cut off from the Electroneum network or under attack. Or it could be just sheer bad luck.");
1933 std::shared_ptr<tools::Notify> block_rate_notify = m_block_rate_notify;
1934 if (block_rate_notify)
1959 m_target_blockchain_height = target_blockchain_height;
1964 return m_target_blockchain_height;
1969 boost::filesystem::path path(m_config_folder);
1970 boost::filesystem::space_info si = boost::filesystem::space(path);
1971 return si.available;
1990 bool is_validator_key_valid = std::count_if(
key.begin(),
key.end(), [](
int c) {return !std::isxdigit(c);}) == 0;
1991 if(!is_validator_key_valid ||
key.size() % 2 != 0) {
2009 return boost::algorithm::hex(b_str);
const unsigned char checkpoints[]
#define JSON_HASH_FILE_NAME
static void init_options(boost::program_options::options_description &desc)
init command line options
virtual void set_block_cumulative_difficulty(uint64_t height, difficulty_type diff)=0
sets a block's cumulative difficulty
virtual std::vector< address_outputs > get_addr_output_batch(const crypto::public_key &combined_key, uint64_t start_db_index=0, uint64_t batch_size=100, bool desc=false)=0
virtual difficulty_type get_block_cumulative_difficulty(const uint64_t &height) const =0
fetch a block's cumulative difficulty
virtual uint64_t get_balance(const crypto::public_key &combined_key)=0
crypto::hash get_tail_id() const
get the hash of the most recent block on the blockchain
crypto::hash get_block_id_by_height(uint64_t height) const
gets a block's hash given a height
bool prepare_handle_incoming_blocks(const std::vector< block_complete_entry > &blocks_entry, std::vector< block > &blocks)
performs some preprocessing on a group of incoming blocks to speed up verification
uint8_t get_current_hard_fork_version() const
gets the current hardfork version in use/voted for
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.
bool prune_blockchain(uint32_t pruning_seed=0)
bool find_blockchain_supplement(const std::list< crypto::hash > &qblock_ids, std::vector< crypto::hash > &hashes, uint64_t &start_height, uint64_t ¤t_height, bool clip_pruned) const
get recent block hashes for a foreign chain
bool get_tx_outputs_gindexs(const crypto::hash &tx_id, std::vector< uint64_t > &indexs) const
gets the global indices for outputs from a given transaction
bool get_block_by_hash(const crypto::hash &h, block &blk, bool *orphan=NULL) const
gets the block with a given hash
void safesyncmode(const bool onoff)
Put DB in safe sync mode.
bool get_split_transactions_blobs(const t_ids_container &txs_ids, t_tx_container &txs, t_missed_container &missed_txs) const
void set_enforce_dns_checkpoints(bool enforce)
configure whether or not to enforce DNS-based checkpoints
bool check_blockchain_pruning()
bool update_checkpoints(const std::string &file_path, bool check_dns)
loads new checkpoints from a file and optionally from DNS
void set_show_time_stats(bool stats)
set whether or not to show/print time statistics
bool deinit()
Uninitializes the blockchain state.
static const std::vector< HardFork::Params > & get_hard_fork_heights(network_type nettype)
gets the hardfork heights of given network
HardFork::State get_hard_fork_state() const
gets the hardfork voting state object
void set_block_notify(const std::shared_ptr< tools::Notify > ¬ify)
sets a block notify object to call for every new block
void set_reorg_notify(const std::shared_ptr< tools::Notify > ¬ify)
sets a reorg notify object to call for every reorg
bool get_alternative_blocks(std::vector< block > &blocks) const
compiles a list of all blocks stored as alternative chains
bool update_blockchain_pruning()
void on_new_tx_from_block(const cryptonote::transaction &tx)
called when we see a tx originating from a block
bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector< uint64_t > &distribution, uint64_t &base) const
gets per block distribution of outputs of a given amount
uint64_t get_current_cumulative_block_weight_limit() const
gets the block weight limit based on recent blocks
std::vector< time_t > get_last_block_timestamps(unsigned int blocks) const
returns the timestamps of the last N blocks
bool for_blocks_range(const uint64_t &h1, const uint64_t &h2, std::function< bool(uint64_t, const crypto::hash &, const block &)>) const
perform a check on all blocks in the blockchain in the given range
bool get_transactions_blobs(const t_ids_container &txs_ids, t_tx_container &txs, t_missed_container &missed_txs, bool pruned=false) const
gets transactions based on a list of transaction hashes
bool have_block(const crypto::hash &id) const
checks if a block is known about with a given hash
bool cleanup_handle_incoming_blocks(bool force_sync=false)
incoming blocks post-processing, cleanup, and disk sync
uint8_t get_hard_fork_version(uint64_t height) const
returns the actual hardfork version for a given block height
void set_validator_key(std::string key)
set validator key
void set_validators_list_instance(std::unique_ptr< electroneum::basic::Validators > &v)
const BlockchainDB & get_db() const
get a reference to the BlockchainDB in use by Blockchain
size_t get_alternative_blocks_count() const
returns the number of alternative blocks stored
uint8_t get_ideal_hard_fork_version() const
returns the newest hardfork version known to the blockchain
uint32_t get_blockchain_pruning_seed() const
bool have_tx(const crypto::hash &id) const
search the blockchain for a transaction by hash
size_t get_total_transactions() const
gets the total number of transactions on the main chain
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const
returns the earliest block a given version may activate
bool reset_and_set_genesis_block(const block &b)
clears the blockchain and starts a new one
void set_user_options(uint64_t maxthreads, bool sync_on_blocks, uint64_t sync_threshold, blockchain_db_sync_mode sync_mode, bool fast_sync, std::string validator_key)
Update the validators public key by fetching data from electroneum's endpoint.
bool get_short_chain_history(std::list< crypto::hash > &ids) const
gets the hashes for a subset of the blockchain
bool get_blocks(uint64_t start_offset, size_t count, std::vector< std::pair< cryptonote::blobdata, block >> &blocks, std::vector< cryptonote::blobdata > &txs) const
get blocks and transactions from blocks based on start height and count
bool add_new_block(const block &bl_, block_verification_context &bvc)
adds a block to the blockchain
bool get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request &req, COMMAND_RPC_GET_OUTPUTS_BIN::response &res) const
gets specific outputs to mix with
bool create_block_template(block &b, const account_public_address &miner_address, difficulty_type &di, uint64_t &height, uint64_t &expected_reward, const blobdata &ex_nonce)
creates a new block to mine against
bool have_tx_keyimg_as_spent(const crypto::key_image &key_im) const
check if a key image is already spent on the blockchain
bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request &arg, NOTIFY_RESPONSE_GET_OBJECTS::request &rsp)
retrieves a set of blocks and their transactions, and possibly other transactions
bool get_transactions(const t_ids_container &txs_ids, t_tx_container &txs, t_missed_container &missed_txs) const
uint64_t get_current_blockchain_height() const
get the current height of the blockchain
void set_checkpoints(checkpoints &&chk_pts)
assign a set of blockchain checkpoint hashes
A generic BlockchainDB exception.
const char * what() const
A container for blockchain checkpoints.
size_t get_pool_transactions_count() const
get the total number of transactions in the pool
bool pool_has_tx(const crypto::hash &txid) const
checks if the pool has a transaction with the given hash
std::vector< address_outputs > get_address_batch_history(const address_parse_info &addr, const uint64_t &start_tx_id=0, const uint64_t &batch_size=100, bool desc=false)
void safesyncmode(const bool onoff)
Put DB in safe sync mode.
bool update_blockchain_pruning()
incrementally prunes blockchain
virtual bool handle_block_found(block &b, block_verification_context &bvc)
stores and relays a block found by a miner
bool set_validator_key(std::string key)
set validator key
void get_blockchain_top(uint64_t &height, crypto::hash &top_id) const
get the hash and height of the most recent block
bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request &arg, NOTIFY_RESPONSE_GET_OBJECTS::request &rsp, cryptonote_connection_context &context)
retrieves a set of blocks and their transactions, and possibly other transactions
size_t get_alternative_blocks_count() const
returns the number of alternative blocks stored
void stop()
stops the daemon running
bool is_key_image_spent(const crypto::key_image &key_im) const
check if a key image is already spent on the blockchain
void set_cryptonote_protocol(i_cryptonote_protocol *pprotocol)
set the pointer to the cryptonote protocol object to use
uint8_t get_hard_fork_version(uint64_t height) const
return the hard fork version for a given block height
static void init_options(boost::program_options::options_description &desc)
adds command line options to the given options set
bool get_transactions(const std::vector< crypto::hash > &txs_ids, std::vector< cryptonote::blobdata > &txs, std::vector< crypto::hash > &missed_txs) const
std::pair< uint64_t, uint64_t > get_coinbase_tx_sum(const uint64_t start_offset, const size_t count)
get the sum of coinbase tx amounts between blocks
bool get_test_drop_download_height() const
gets whether or not to drop blocks
bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector< uint64_t > &distribution, uint64_t &base) const
gets per block distribution of outputs of a given amount
void graceful_exit()
tells the daemon to wind down operations and stop running
void test_drop_download_height(uint64_t height)
sets to drop blocks downloaded below a certain height
bool get_short_chain_history(std::list< crypto::hash > &ids) const
gets the hashes for a subset of the blockchain
bool are_key_images_spent_in_pool(const std::vector< crypto::key_image > &key_im, std::vector< bool > &spent) const
check if multiple key images are spent in the transaction pool
bool on_idle()
calls various idle routines
uint64_t get_free_space() const
get free disk space on the blockchain partition
uint32_t get_blockchain_pruning_seed() const
get the blockchain pruning seed
difficulty_type get_block_cumulative_difficulty(uint64_t height) const
uint64_t get_current_blockchain_height() const
get the current height of the blockchain
bool get_blocks(uint64_t start_offset, size_t count, std::vector< std::pair< cryptonote::blobdata, block >> &blocks, std::vector< cryptonote::blobdata > &txs) const
bool have_block(const crypto::hash &id) const
checks if a block is known about with a given hash
void set_block_cumulative_difficulty(uint64_t height, difficulty_type diff)
bool handle_incoming_txs(const std::vector< blobdata > &tx_blobs, std::vector< tx_verification_context > &tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
handles a list of incoming transactions
bool prepare_handle_incoming_blocks(const std::vector< block_complete_entry > &blocks_entry, std::vector< block > &blocks)
performs some preprocessing on a group of incoming blocks to speed up verification
bool set_genesis_block(const block &b)
clears the blockchain and starts a new one
Blockchain & get_blockchain_storage()
gets the Blockchain instance
bool get_split_transactions_blobs(const std::vector< crypto::hash > &txs_ids, std::vector< std::tuple< crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata >> &txs, std::vector< crypto::hash > &missed_txs) const
size_t get_blockchain_total_transactions() const
gets the total number of transactions on the main chain
uint8_t get_ideal_hard_fork_version() const
returns the newest hardfork version known to the blockchain
crypto::hash get_tail_id() const
get the hash of the most recent block on the blockchain
bool get_test_drop_download() const
gets whether or not to drop blocks (for testing)
bool cleanup_handle_incoming_blocks(bool force_sync=false)
incoming blocks post-processing, cleanup, and disk sync
bool isValidatorsListValid()
get Validators List state
bool get_pool_transaction_stats(struct txpool_stats &stats, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool
bool get_pool_transaction_hashes(std::vector< crypto::hash > &txs, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool
bool get_stat_info(core_stat_info &st_inf) const
gets some stats about the daemon
void set_checkpoints_file_path(const std::string &path)
set the file path to read from when loading checkpoints
bool check_blockchain_pruning()
checks the blockchain pruning if enabled
std::string sign_message(std::string sk, std::string msg)
size_t get_block_sync_size(uint64_t height) const
get the number of blocks to sync in one go
virtual bool get_block_template(block &b, const account_public_address &adr, difficulty_type &diffic, uint64_t &height, uint64_t &expected_reward, const blobdata &ex_nonce)
creates a new block to mine against
bool deinit()
performs safe shutdown steps for core and core components
uint64_t get_balance(const address_parse_info &addr)
bool update_checkpoints()
tells the Blockchain to update its checkpoints
std::time_t get_start_time() const
gets start_time
void set_checkpoints(checkpoints &&chk_pts)
assign a set of blockchain checkpoint hashes
std::string print_pool(bool short_format) const
get a string containing human-readable pool information
std::string get_validators_list()
Get a serialized representation of the list of validators.
bool handle_incoming_block(const blobdata &block_blob, const block *b, block_verification_context &bvc, bool update_miner_blocktemplate=true)
handles an incoming block
void set_target_blockchain_height(uint64_t target_blockchain_height)
sets the target blockchain height
bool get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request &req, COMMAND_RPC_GET_OUTPUTS_BIN::response &res) const
gets specific outputs to mix with
crypto::hash get_block_id_by_height(uint64_t height) const
gets a block's hash given a height
i_cryptonote_protocol * get_protocol()
get the cryptonote protocol instance
uint64_t get_target_blockchain_height() const
gets the target blockchain height
bool get_alternative_blocks(std::vector< block > &blocks) const
compiles a list of all blocks stored as alternative chains
void set_enforce_dns_checkpoints(bool enforce_dns)
set whether or not we enforce DNS checkpoints
bool check_incoming_block_size(const blobdata &block_blob) const
check the size of a block against the current maximum
bool get_pool_for_rpc(std::vector< cryptonote::rpc::tx_in_pool > &tx_infos, cryptonote::rpc::key_images_with_tx_hashes &key_image_infos) const
get information about all transactions and key images in the pool
void test_drop_download()
sets to drop blocks downloaded (for testing)
bool find_blockchain_supplement(const std::list< crypto::hash > &qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request &resp) const
get recent block hashes for a foreign chain
bool prune_blockchain(uint32_t pruning_seed=0)
prune the blockchain
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const
return the earliest block a given version may activate
bool get_block_by_hash(const crypto::hash &h, block &blk, bool *orphan=NULL) const
gets the block with a given hash
bool are_key_images_spent(const std::vector< crypto::key_image > &key_im, std::vector< bool > &spent) const
check if multiple key images are spent
bool handle_incoming_tx(const blobdata &tx_blob, tx_verification_context &tvc, bool keeped_by_block, bool relayed, bool do_not_relay)
handles an incoming transaction
std::vector< std::string > generate_ed25519_keypair()
bool get_pool_transaction(const crypto::hash &id, cryptonote::blobdata &tx) const
get a specific transaction from the pool
virtual void on_transaction_relayed(const cryptonote::blobdata &tx)
called when a transaction is relayed
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
bool get_pool_transactions_and_spent_keys_info(std::vector< tx_info > &tx_infos, std::vector< spent_key_image_info > &key_image_infos, bool include_unrelayed_txes=true) const
bool get_pool_transactions(std::vector< transaction > &txs, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool
electroneum::basic::list_update_outcome set_validators_list(std::string v_list, bool isEmergencyUpdate)
set the list of validators according to the serialized string passed in as parameter
bool get_txpool_backlog(std::vector< tx_backlog_entry > &backlog) const
bool get_tx_outputs_gindexs(const crypto::hash &tx_id, std::vector< uint64_t > &indexs) const
gets the global indices for outputs from a given transaction
uint64_t get_speed() const
static void init_options(boost::program_options::options_description &desc)
bool on_block_chain_update()
bool init(const boost::program_options::variables_map &vm, network_type nettype, bool fallback_to_pow=false)
std::vector< txin_v > vin
rct::rctSig rct_signatures
Transaction pool, handles transactions which are not part of a block.
void on_idle()
action to take periodically
void set_relayed(const std::vector< std::pair< crypto::hash, cryptonote::blobdata >> &txs)
tell the pool that certain transactions were just relayed
bool get_pool_for_rpc(std::vector< cryptonote::rpc::tx_in_pool > &tx_infos, cryptonote::rpc::key_images_with_tx_hashes &key_image_infos) const
get information about all transactions and key images in the pool
bool have_tx(const crypto::hash &id) const
checks if the pool has a transaction with the given hash
void get_transaction_hashes(std::vector< crypto::hash > &txs, bool include_unrelayed_txes=true) const
get a list of all transaction hashes in the pool
bool add_tx(transaction &tx, const crypto::hash &id, const cryptonote::blobdata &blob, size_t tx_weight, tx_verification_context &tvc, bool kept_by_block, bool relayed, bool do_not_relay, uint8_t version)
void get_transactions(std::vector< transaction > &txs, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool
bool get_transactions_and_spent_keys_info(std::vector< tx_info > &tx_infos, std::vector< spent_key_image_info > &key_image_infos, bool include_sensitive_data=true) const
get information about all transactions and key images in the pool
bool init(size_t max_txpool_weight=0)
loads pool state (if any) from disk, and initializes pool
std::string print_pool(bool short_format) const
get a string containing human-readable pool information
void get_transaction_backlog(std::vector< tx_backlog_entry > &backlog, bool include_unrelayed_txes=true) const
get (weight, fee, receive time) for all transaction in the pool
size_t validate(uint8_t version)
remove transactions from the pool which are no longer valid
void get_transaction_stats(struct txpool_stats &stats, bool include_unrelayed_txes=true) const
get a summary statistics of all transaction hashes in the pool
size_t get_transactions_count(bool include_unrelayed_txes=true) const
get the total number of transactions in the pool
bool get_relayable_transactions(std::vector< std::pair< crypto::hash, cryptonote::blobdata >> &txs) const
get a list of all relayable transactions and their hashes
bool get_transaction(const crypto::hash &h, cryptonote::blobdata &txblob) const
get a specific transaction from the pool
bool check_for_key_images(const std::vector< crypto::key_image > &key_images, std::vector< bool > spent) const
check for presence of key images in the pool
bool deinit()
attempts to save the transaction pool state to disk
bool do_call(functor_t functr)
#define HF_VERSION_PUBLIC_TX
#define CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE
#define HF_VERSION_ENFORCE_RCT
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT
#define DEFAULT_TXPOOL_MAX_WEIGHT
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4
#define DIFFICULTY_TARGET_V6
#define BAD_SEMANTICS_TXES_MAX_SIZE
#define BLOCK_SIZE_SANITY_LEEWAY
expect< void > success() noexcept
#define MCLOG_CYAN(level, cat, x)
#define MCLOG_RED(level, cat, x)
#define CATCH_ENTRY_L0(lacation, return_val)
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
void add_arg(boost::program_options::options_description &description, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg, bool unique=true)
bool is_arg_defaulted(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)
public_key addKeys(const public_key &A, const public_key &B)
std::vector< std::string > create_ed25519_keypair()
std::string sign_message(const std::string &message, const std::string &privateKey)
std::unordered_map< crypto::key_image, std::vector< crypto::hash > > key_images_with_tx_hashes
Holds cryptonote related classes and helpers.
const command_line::arg_descriptor< std::string, false, true, 2 > arg_data_dir
boost::multiprecision::uint128_t difficulty_type
uint64_t get_outs_etn_amount(const transaction &tx)
const command_line::arg_descriptor< bool > arg_db_salvage
bool get_tx_fee(const transaction &tx, uint64_t &fee)
double factorial(unsigned int n)
const command_line::arg_descriptor< bool > arg_regtest_on
const command_line::arg_descriptor< bool > arg_offline
block_complete_entry get_block_complete_entry(block &b, tx_memory_pool &pool)
const command_line::arg_descriptor< difficulty_type > arg_fixed_difficulty
bool get_block_hash(const block &b, crypto::hash &res)
bool parse_and_validate_block_from_blob(const blobdata &b_blob, block &b, crypto::hash *block_hash)
uint64_t get_block_height(const block &b)
const command_line::arg_descriptor< bool > arg_fallback_to_pow
const command_line::arg_descriptor< bool, false > arg_testnet_on
BlockchainDB * new_db(const std::string &db_type)
@ db_async
handle syncing calls instead of the backing db, asynchronously
@ db_nosync
Leave syncing up to the backing db (safest, but slowest because of disk I/O)
@ db_sync
handle syncing calls instead of the backing db, synchronously
@ db_defaultsync
user didn't specify, use db_async
const command_line::arg_descriptor< std::string > arg_fallback_to_pow_checkpoint_hash
crypto::hash get_transaction_hash(const transaction &t)
bool check_outs_valid(const transaction &tx)
const command_line::arg_descriptor< std::string > arg_db_type
blobdata block_to_blob(const block &b)
const command_line::arg_descriptor< bool, false > arg_stagenet_on
const command_line::arg_descriptor< uint64_t > arg_fallback_to_pow_checkpoint_height
const command_line::arg_descriptor< bool > arg_disable_dns_checkpoints
bool check_etn_overflow(const transaction &tx)
const command_line::arg_descriptor< bool > arg_skip_block_sig_verification
bool parse_and_validate_tx_from_blob(const blobdata &tx_blob, transaction &tx)
bool get_inputs_etn_amount(const transaction &tx, uint64_t &etn)
bool check_inputs_types_supported(const transaction &tx)
const command_line::arg_descriptor< size_t > arg_block_download_max_size
const command_line::arg_descriptor< std::string > arg_db_sync_mode
bool t_serializable_object_to_blob(const t_object &to, blobdata &b_blob)
std::function< const epee::span< const unsigned char >cryptonote::network_type network)> GetCheckpointsCallback
Callback routine that returns checkpoints data for specific network type.
uint64_t get_transaction_weight(const transaction &tx, size_t blob_size)
Level
Represents enumeration for severity level used to determine level of logging.
@ Warning
Useful when application has potentially harmful situtaions.
@ Info
Mainly useful to represent current progress of application.
@ Fatal
Severe error information that will presumably abort application.
unsigned int & g_test_dbg_lock_sleep()
bool is_file_exist(const std::string &path)
std::string to_string(t_connection_type type)
mdb_size_t count(MDB_cursor *cur)
version
Supported socks variants.
std::unique_ptr< void, terminate > context
Unique ZMQ context handle, calls zmq_term on destruction.
void scalarmultKey(key &aP, const key &P, const key &a)
bool verRctSemanticsSimple(const std::vector< const rctSig * > &rvv)
const T & move(const T &t)
boost::filesystem::path data_dir
unsigned __int64 uint64_t
epee::misc_utils::struct_init< request_t > request
crypto::public_key m_view_public_key
crypto::public_key m_spend_public_key
account_public_address address
std::vector< blobdata > txs
bool m_added_to_main_chain
bool m_verification_failed
std::vector< crypto::hash > tx_hashes
virtual bool relay_block(NOTIFY_NEW_BLOCK::request &arg, cryptonote_connection_context &exclude_context)=0
virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request &arg, cryptonote_connection_context &exclude_context)=0
bool m_verification_failed
#define CRITICAL_REGION_LOCAL(x)
DISABLE_VS_WARNINGS(4244 4345 4503) using namespace crypto
const char *const ELECTRONEUM_VERSION