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);
524 bool is_validator_key_valid = std::count_if(validator_key.begin(), validator_key.end(), [](
int c) {
return !std::isxdigit(c);}) == 0;
525 if(!is_validator_key_valid || validator_key.size() % 2 != 0) {
526 validator_key.clear();
529 boost::filesystem::path folder(m_config_folder);
534 CHECK_AND_ASSERT_MES (boost::filesystem::exists(folder) || boost::filesystem::create_directories(folder),
false,
535 std::string(
"Failed to create directory ").append(folder.string()).c_str());
540 const boost::filesystem::path old_files = folder;
541 if (boost::filesystem::exists(old_files /
"blockchain.bin"))
543 MWARNING(
"Found old-style blockchain.bin in " << old_files.string());
544 MWARNING(
"Electroneum now uses a new format. You can either remove blockchain.bin to start syncing");
545 MWARNING(
"the blockchain anew, or use electroneum-blockchain-export and electroneum-blockchain-import to");
546 MWARNING(
"convert your existing blockchain.bin to the new format. See README.md for instructions.");
553 std::unique_ptr<BlockchainDB> db(
new_db(db_type));
556 LOG_ERROR(
"Attempted to use non-existent database type");
560 folder /= db->get_db_name();
561 MGINFO(
"Loading blockchain from folder " << folder.string() <<
" ...");
566 bool sync_on_blocks =
true;
572 if (!db->remove_data_file(filename))
574 MERROR(
"Failed to remove data file in " << filename);
583 std::vector<std::string> options;
585 boost::split(options, db_sync_mode, boost::is_any_of(
" :"));
588 for(
const auto &
option : options)
594 if(options.size() == 0)
597 db_flags = DEFAULT_FLAGS;
600 bool safemode =
false;
601 if(options.size() >= 1)
603 if(options[0] ==
"safe")
609 else if(options[0] ==
"fast")
614 else if(options[0] ==
"fastest")
617 sync_threshold = 1000;
621 db_flags = DEFAULT_FLAGS;
624 if(options.size() >= 2 && !safemode)
626 if(options[1] ==
"sync")
628 else if(options[1] ==
"async")
632 if(options.size() >= 3 && !safemode)
636 if (*endptr ==
'\0' || !strcmp(endptr,
"blocks"))
638 sync_on_blocks =
true;
641 else if (!strcmp(endptr,
"bytes"))
643 sync_on_blocks =
false;
648 LOG_ERROR(
"Invalid db sync mode: " << options[2]);
659 db->open(filename, db_flags);
670 sync_on_blocks, sync_threshold, sync_mode, fast_sync, validator_key);
677 catch (
const std::exception &e)
679 MERROR(
"Failed to parse block notify spec: " << e.what());
687 catch (
const std::exception &e)
689 MERROR(
"Failed to parse reorg notify spec: " << e.what());
697 catch (
const std::exception &e)
699 MERROR(
"Failed to parse block rate notify spec: " << e.what());
710 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);
712 r = m_mempool.
init(max_txpool_weight);
725 MGINFO(
"Loading checkpoints");
732 if (check_updates_string ==
"disabled")
733 check_updates_level = UPDATES_DISABLED;
734 else if (check_updates_string ==
"notify")
735 check_updates_level = UPDATES_NOTIFY;
736 else if (check_updates_string ==
"download")
737 check_updates_level = UPDATES_DOWNLOAD;
738 else if (check_updates_string ==
"update")
739 check_updates_level = UPDATES_UPDATE;
741 MERROR(
"Invalid argument to --dns-versions-check: " << check_updates_string);
745 check_updates_level = UPDATES_DISABLED;
747 r = m_miner.
init(vm, m_nettype, m_fallback_to_pow);
755 MGINFO(
"Pruning blockchain...");
764 if(!m_fallback_to_pow) {
769 m_validators->enable();
773 return load_state_data();
781 bool core::load_state_data()
791 m_blockchain_storage.
deinit();
797 m_test_drop_download =
false;
802 m_test_drop_download_height =
height;
807 return m_test_drop_download;
812 if (m_test_drop_download_height == 0)
823 tvc = boost::value_initialized<tx_verification_context>();
827 LOG_PRINT_L1(
"WRONG TRANSACTION BLOB, too big size " << tx_blob.size() <<
", rejected");
833 tx_hash = crypto::null_hash;
835 if(!parse_tx_from_blob(tx, tx_hash, tx_blob))
837 LOG_PRINT_L1(
"WRONG TRANSACTION BLOB, Failed to parse, rejected");
843 bad_semantics_txes_lock.lock();
844 for (
int idx = 0; idx < 2; ++idx)
846 if (bad_semantics_txes[idx].find(tx_hash) != bad_semantics_txes[idx].end())
848 bad_semantics_txes_lock.unlock();
849 LOG_PRINT_L1(
"Transaction already seen with bad semantics, rejected");
854 bad_semantics_txes_lock.unlock();
867 if (tx.
version < min_tx_version)
878 if(!check_tx_syntax(tx))
880 LOG_PRINT_L1(
"WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash <<
" syntax, rejected");
881 tvc.m_verification_failed =
true;
888 void core::set_semantics_failed(
const crypto::hash &tx_hash)
890 LOG_PRINT_L1(
"WRONG TRANSACTION BLOB, Failed to check tx " << tx_hash <<
" semantic, rejected");
891 bad_semantics_txes_lock.lock();
892 bad_semantics_txes[0].insert(tx_hash);
895 std::swap(bad_semantics_txes[0], bad_semantics_txes[1]);
896 bad_semantics_txes[0].clear();
898 bad_semantics_txes_lock.unlock();
901 bool core::handle_incoming_tx_accumulated_batch(std::vector<tx_verification_batch_info> &tx_info,
bool keeped_by_block)
906 MTRACE(
"Skipping semantics check for tx kept by block in embedded hash area");
910 std::vector<const rct::rctSig*> rvv;
911 for (
size_t n = 0; n < tx_info.size(); ++n)
913 if (!check_tx_semantic(*tx_info[n].tx, keeped_by_block))
915 set_semantics_failed(tx_info[n].tx_hash);
916 tx_info[n].tvc.m_verification_failed =
true;
917 tx_info[n].result =
false;
923 LOG_PRINT_L1(
"One transaction among this group has bad semantics, verifying one at a time");
925 const bool assumed_bad = rvv.size() == 1;
926 for (
size_t n = 0; n < tx_info.size(); ++n)
928 if (!tx_info[n].result)
934 set_semantics_failed(tx_info[n].tx_hash);
935 tx_info[n].tvc.m_verification_failed =
true;
936 tx_info[n].result =
false;
944 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)
950 std::vector<result> results(tx_blobs.size());
952 tvc.resize(tx_blobs.size());
955 std::vector<blobdata>::const_iterator it = tx_blobs.begin();
956 for (
size_t i = 0; i < tx_blobs.size(); i++, ++it) {
957 tpool.
submit(&waiter, [&, i, it] {
960 results[i].res = handle_incoming_tx_pre(*it, tvc[i], results[i].tx, results[i].
hash, keeped_by_block, relayed, do_not_relay);
962 catch (
const std::exception &e)
964 MERROR_VER(
"Exception in handle_incoming_tx_pre: " << e.what());
965 tvc[i].m_verification_failed =
true;
966 results[i].res =
false;
971 it = tx_blobs.begin();
972 std::vector<bool> already_have(tx_blobs.size(),
false);
973 for (
size_t i = 0; i < tx_blobs.size(); i++, ++it) {
976 if(m_mempool.
have_tx(results[i].hash))
978 LOG_PRINT_L2(
"tx " << results[i].
hash <<
"already have transaction in tx_pool");
979 already_have[i] =
true;
981 else if(m_blockchain_storage.
have_tx(results[i].hash))
983 LOG_PRINT_L2(
"tx " << results[i].
hash <<
" already have transaction in blockchain");
984 already_have[i] =
true;
988 tpool.
submit(&waiter, [&, i, it] {
991 results[i].res = handle_incoming_tx_post(*it, tvc[i], results[i].tx, results[i].
hash, keeped_by_block, relayed, do_not_relay);
993 catch (
const std::exception &e)
995 MERROR_VER(
"Exception in handle_incoming_tx_post: " << e.what());
996 tvc[i].m_verification_failed =
true;
997 results[i].res =
false;
1002 waiter.
wait(&tpool);
1004 std::vector<tx_verification_batch_info>
tx_info;
1005 tx_info.reserve(tx_blobs.size());
1006 for (
size_t i = 0; i < tx_blobs.size(); i++) {
1007 if (!results[i].
res || already_have[i])
1009 tx_info.push_back({&results[i].tx, results[i].hash, tvc[i], results[i].res});
1012 handle_incoming_tx_accumulated_batch(
tx_info, keeped_by_block);
1015 it = tx_blobs.begin();
1016 for (
size_t i = 0; i < tx_blobs.size(); i++, ++it) {
1017 if (!results[i].
res)
1022 if (keeped_by_block)
1024 if (already_have[i])
1028 ok &= add_new_tx(results[i].tx, results[i].
hash, tx_blobs[i], weight, tvc[i], keeped_by_block, relayed, do_not_relay);
1029 if(tvc[i].m_verification_failed)
1030 {
MERROR_VER(
"Transaction verification failed: " << results[i].
hash);}
1031 else if(tvc[i].m_verification_impossible)
1032 {
MERROR_VER(
"Transaction verification impossible: " << results[i].
hash);}
1034 if(tvc[i].m_added_to_pool)
1044 std::vector<cryptonote::blobdata> tx_blobs;
1045 tx_blobs.push_back(tx_blob);
1046 std::vector<tx_verification_context> tvcv(1);
1054 st_inf.mining_speed = m_miner.
get_speed();
1063 bool core::check_tx_semantic(
const transaction& tx,
bool keeped_by_block)
const 1093 if((tx.
version == 1 && amount_in <= amount_out) || (tx.
version == 2 && amount_in != amount_out)) {
1095 MERROR_VER(
"V" << tx.
version <<
" tx with wrong amounts: ins " << amount_in <<
", outs " << amount_out <<
", rejected for tx id= " 1102 bool only_bridge_dests =
true;
1106 portal_address_viewkey_hex_str =
"2b95a2eb2c62253c57e82b082b850bbf22a1a7829aaea09c7c1511c1cced4375";
1107 portal_address_spendkey_hex_str =
"8ce0f34fd37c7f7d07c44024eb5b3cdf275d1b3e75c3464b808dce532e861137";
1109 portal_address_viewkey_hex_str =
"5866666666666666666666666666666666666666666666666666666666666666";
1110 portal_address_spendkey_hex_str =
"5bd0c0e25eee6133850edd2b255ed9e3d6bb99fd5f08b7b5cf7f2618ad6ff2a3";
1113 for (
auto output: tx.
vout){
1114 const auto out = boost::get<txout_to_key_public>(output.target);
1117 if(out_spendkey_str != portal_address_spendkey_hex_str || out_viewkey_str != portal_address_viewkey_hex_str){
1118 only_bridge_dests =
false;
1119 if(amount_in <= amount_out){
1120 MERROR_VER(
"v3 tx with some outs not going to the bridge should be fee paying: ins " << amount_in <<
", outs " << amount_out <<
", rejected for tx id= " 1127 if (only_bridge_dests && amount_in < amount_out){
1128 MERROR_VER(
"v3 sc_migration tx has wrong amounts: ins " << amount_in <<
", outs " << amount_out <<
", rejected for tx id= " 1144 if(!check_tx_inputs_utxos_diff(tx))
1146 MERROR_VER(
"tx uses a single utxo more than once");
1153 if(!check_tx_inputs_keyimages_diff(tx))
1155 MERROR_VER(
"tx uses a single key image more than once");
1159 if (!check_tx_inputs_keyimages_domain(tx))
1161 MERROR_VER(
"tx uses key image not in the valid domain");
1177 for(
auto& ki: key_im)
1187 for(
auto& po: public_outputs)
1197 if (block_sync_size > 0)
1198 return block_sync_size;
1199 if (
height >= quick_height)
1219 std::vector<transaction> txs;
1220 std::vector<crypto::hash> missed_txs;
1224 for(
const auto& tx: txs)
1229 emission_amount += coinbase_amount - tx_fee_amount;
1230 total_fee_amount += tx_fee_amount;
1235 return std::pair<uint64_t, uint64_t>(emission_amount, total_fee_amount);
1238 bool core::check_tx_inputs_keyimages_diff(
const transaction& tx)
const 1240 std::unordered_set<crypto::key_image> ki;
1241 for(
const auto& in: tx.
vin)
1244 if(!ki.insert(tokey_in.k_image).second)
1250 bool core::check_tx_inputs_utxos_diff(
const transaction& tx)
const 1252 std::unordered_set<std::string> ins;
1253 for(
const auto& in: tx.vin)
1262 bool core::check_tx_inputs_ring_members_diff(
const transaction& tx)
const 1267 for(
const auto& in: tx.vin)
1270 for (
size_t n = 1; n < tokey_in.key_offsets.size(); ++n)
1271 if (tokey_in.key_offsets[n] == 0)
1278 bool core::check_tx_inputs_keyimages_domain(
const transaction& tx)
const 1280 std::unordered_set<crypto::key_image> ki;
1281 for(
const auto& in: tx.vin)
1290 bool core::add_new_tx(transaction& tx, tx_verification_context& tvc,
bool keeped_by_block,
bool relayed,
bool do_not_relay)
1296 return add_new_tx(tx, tx_hash, bl, tx_weight, tvc, keeped_by_block, relayed, do_not_relay);
1307 if(m_mempool.
have_tx(tx_hash))
1309 LOG_PRINT_L2(
"tx " << tx_hash <<
"already have transaction in tx_pool");
1313 if(m_blockchain_storage.
have_tx(tx_hash))
1315 LOG_PRINT_L2(
"tx " << tx_hash <<
" already have transaction in blockchain");
1320 return m_mempool.
add_tx(tx, tx_hash, blob, tx_weight, tvc, keeped_by_block, relayed, do_not_relay,
version);
1323 bool core::relay_txpool_transactions()
1326 std::vector<std::pair<crypto::hash, cryptonote::blobdata>> txs;
1329 cryptonote_connection_context fake_context =
AUTO_VAL_INIT(fake_context);
1332 for (
auto it = txs.begin(); it != txs.end(); ++it)
1334 r.txs.push_back(it->second);
1344 std::vector<std::pair<crypto::hash, cryptonote::blobdata>> txs;
1349 LOG_ERROR(
"Failed to parse relayed transaction");
1352 txs.push_back(std::make_pair(tx_hash,
std::move(tx_blob)));
1371 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 1373 return m_blockchain_storage.
find_blockchain_supplement(req_start_block, qblock_ids,
blocks, total_height, start_height, pruned, get_miner_tx_hash, max_count);
1383 return m_blockchain_storage.
get_output_distribution(amount, from_height, to_height, start_height, distribution, base);
1414 bce.
txs.push_back(txblob);
1421 bvc = boost::value_initialized<block_verification_context>();
1423 std::vector<block_complete_entry>
blocks;
1428 catch (
const std::exception &e)
1433 std::vector<block> pblocks;
1436 MERROR(
"Block found, but failed to prepare to add");
1449 std::vector<crypto::hash> missed_txs;
1450 std::vector<cryptonote::blobdata> txs;
1454 LOG_PRINT_L1(
"Block found but, seems that reorganize just happened after that, do not relay this block");
1458 <<
", b.tx_hashes.size()=" << b.
tx_hashes.size() <<
", missed_txs.size()" << missed_txs.size());
1463 arg.b.txs.push_back(tx);
1467 if(m_fallback_to_pow) {
1471 update_miner_block_template();
1495 m_incoming_tx_lock.
lock();
1512 m_incoming_tx_lock.
unlock();
1521 bvc = boost::value_initialized<block_verification_context>();
1529 if (((
size_t)-1) <= 0xffffffff && block_blob.size() >= 0x3fffffff)
1530 MWARNING(
"This block's size is " << block_blob.size() <<
", closing on the 32 bit limit");
1542 LOG_PRINT_L1(
"Failed to parse and validate new block");
1549 add_new_block(*b, bvc);
1554 if(update_miner_blocktemplate)
1555 update_miner_block_template();
1573 LOG_PRINT_L1(
"WRONG BLOCK BLOB, sanity check failed on size " << block_blob.size() <<
", rejected");
1609 bool core::check_tx_syntax(
const transaction& tx)
const 1682 bool core::update_miner_block_template()
1690 if(!m_starter_message_showed)
1694 main_message =
"The daemon is running offline and will not attempt to sync to the Electroneum network.";
1696 main_message =
"The daemon will start synchronizing with the network. This may take a long time to complete.";
1697 MGINFO_YELLOW(
ENDL <<
"**********************************************************************" <<
ENDL 1698 << main_message <<
ENDL 1700 <<
"You can set the level of process detailization through \"set_log <level|categories>\" command," <<
ENDL 1701 <<
"where <level> is between 0 (no details) and 4 (very verbose), or custom category based levels (eg, *:WARNING)." <<
ENDL 1703 <<
"Use the \"help\" command to see the list of available commands." <<
ENDL 1704 <<
"Use \"help <command>\" to see a command's documentation." <<
ENDL 1705 <<
"**********************************************************************" <<
ENDL);
1706 m_starter_message_showed =
true;
1710 m_txpool_auto_relayer.
do_call(boost::bind(&core::relay_txpool_transactions,
this));
1711 m_check_updates_interval.
do_call(boost::bind(&core::check_updates,
this));
1712 m_check_disk_space_interval.
do_call(boost::bind(&core::check_disk_space,
this));
1713 m_block_rate_interval.
do_call(boost::bind(&core::check_block_rate,
this));
1718 if(!m_fallback_to_pow) {
1719 m_validators->on_idle();
1725 bool core::check_fork_time()
1734 MCLOG_RED(level,
"global",
"**********************************************************************");
1735 MCLOG_RED(level,
"global",
"Last scheduled hard fork is too far in the past.");
1736 MCLOG_RED(level,
"global",
"We are most likely forked from the network. Daemon update needed now.");
1737 MCLOG_RED(level,
"global",
"**********************************************************************");
1740 MCLOG_RED(level,
"global",
"**********************************************************************");
1741 MCLOG_RED(level,
"global",
"Last scheduled hard fork time shows a daemon update is needed soon.");
1742 MCLOG_RED(level,
"global",
"**********************************************************************");
1770 bool core::check_updates()
1772 static const char software[] =
"electroneum";
1774 static const char buildtag[] = BOOST_PP_STRINGIZE(BUILD_TAG);
1775 static const char subdir[] =
"cli";
1777 static const char buildtag[] =
"source";
1778 static const char subdir[] =
"source";
1784 if (check_updates_level == UPDATES_DISABLED)
1788 MCDEBUG(
"updates",
"Checking for a new " << software <<
" version for " << buildtag);
1794 m_update_available =
false;
1800 m_update_available =
true;
1802 if (check_updates_level == UPDATES_NOTIFY) {
1803 std::vector<std::string> version_split;
1804 std::vector<std::string> latest_version_split;
1807 boost::split(latest_version_split,
version, [](
char c){
return c ==
'.';});
1811 for(
size_t i = 0; i < 2; i++) {
1812 if(version_split[i] != latest_version_split[i]) {
1823 const char *slash = strrchr(url.c_str(),
'/');
1825 filename = slash + 1;
1831 boost::unique_lock<boost::mutex> lock(m_update_mutex);
1833 if (m_update_download != 0)
1835 MCDEBUG(
"updates",
"Already downloading update");
1842 MCDEBUG(
"updates",
"We don't have that file already, downloading");
1843 const std::string tmppath = path.string() +
".tmp";
1846 MCDEBUG(
"updates",
"We have part of the file already, resuming download");
1848 m_last_update_length = 0;
1850 bool remove =
false, good =
true;
1856 MCERROR(
"updates",
"Failed to hash " << tmppath);
1862 MCERROR(
"updates",
"Download from " << uri <<
" does not match the expected hash");
1869 MCERROR(
"updates",
"Failed to download " << uri);
1872 boost::unique_lock<boost::mutex> lock(m_update_mutex);
1873 m_update_download = 0;
1879 MCERROR(
"updates",
"Failed to rename downloaded file");
1885 if (!boost::filesystem::remove(tmppath))
1887 MCERROR(
"updates",
"Failed to remove invalid downloaded file");
1894 if (length >= m_last_update_length + 1024 * 1024 * 10)
1896 m_last_update_length = length;
1897 MCDEBUG(
"updates",
"Downloaded " << length <<
"/" << (content_length ?
std::to_string(content_length) :
"unknown"));
1904 MCDEBUG(
"updates",
"We already have " << path <<
" with expected hash");
1909 if (check_updates_level == UPDATES_DOWNLOAD)
1912 MCERROR(
"updates",
"Download/update not implemented yet");
1916 bool core::check_disk_space()
1919 if (free_space < 1ull * 1024 * 1024 * 1024)
1922 MCLOG_RED(level,
"global",
"Free space is below 1 GB on " << m_config_folder);
1937 static double probability1(
unsigned int blocks,
unsigned int expected)
1943 static double probability(
unsigned int blocks,
unsigned int expected)
1948 for (
unsigned int b = 0; b <=
blocks; ++b)
1949 p += probability1(b, expected);
1951 else if (
blocks > expected)
1953 for (
unsigned int b =
blocks; b <= expected * 3 ; ++b)
1954 p += probability1(b, expected);
1959 bool core::check_block_rate()
1961 MDEBUG(
"Not checking block rate, not applicable.");
1966 MDEBUG(
"Not checking block rate, offline or syncing");
1972 const time_t now =
time(NULL);
1975 static const unsigned int seconds[] = { 5400, 3600, 1800, 1200, 600 };
1976 for (
size_t n = 0; n <
sizeof(seconds)/
sizeof(seconds[0]); ++n)
1979 const time_t time_boundary = now -
static_cast<time_t
>(seconds[n]);
1980 for (time_t ts: timestamps) b += ts >= time_boundary;
1982 MDEBUG(
"blocks in the last " << seconds[n] / 60 <<
" minutes: " << b <<
" (probability " << p <<
")");
1985 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.");
1987 std::shared_ptr<tools::Notify> block_rate_notify = m_block_rate_notify;
1988 if (block_rate_notify)
2013 m_target_blockchain_height = target_blockchain_height;
2018 return m_target_blockchain_height;
2023 boost::filesystem::path path(m_config_folder);
2024 boost::filesystem::space_info si = boost::filesystem::space(path);
2025 return si.available;
2044 bool is_validator_key_valid = std::count_if(
key.begin(),
key.end(), [](
int c) {
return !std::isxdigit(c);}) == 0;
2045 if(!is_validator_key_valid ||
key.size() % 2 != 0) {
2063 return boost::algorithm::hex(b_str);
void on_idle()
action to take periodically
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 get_test_drop_download() const
gets whether or not to drop blocks (for testing)
virtual bool relay_block(NOTIFY_NEW_BLOCK::request &arg, cryptonote_connection_context &exclude_context)=0
uint64_t get_current_cumulative_block_weight_limit() const
gets the block weight limit based on recent blocks
uint8_t get_hard_fork_version(uint64_t height) const
return the hard fork version for a given block height
#define CHECK_AND_ASSERT_THROW_MES(expr, message)
void stop()
stops the daemon running
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
std::vector< crypto::hash > tx_hashes
void test_drop_download_height(uint64_t height)
sets to drop blocks downloaded below a certain height
bool get_tx_fee(const transaction &tx, uint64_t &fee)
crypto::hash get_tail_id() const
get the hash of the most recent block on the blockchain
bool deinit()
performs safe shutdown steps for core and core components
bool check_blockchain_pruning()
bool get_split_transactions_blobs(const t_ids_container &txs_ids, t_tx_container &txs, t_missed_container &missed_txs) const
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.
uint32_t get_blockchain_pruning_seed() const
get the blockchain pruning seed
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 ...
handle syncing calls instead of the backing db, asynchronously
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 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 test_drop_download()
sets to drop blocks downloaded (for testing)
bool check_outs_valid(const transaction &tx)
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
bool utxo_nonexistence_from_output(const txin_to_key_public &public_output) const
check if a single utxo in a transaction has already been spent using the hash and out index (v3 tx on...
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 ...
std::string sign_message(std::string sk, std::string msg)
uint64_t get_outs_etn_amount(const transaction &tx)
bool m_verification_failed
bool get_stat_info(core_stat_info &st_inf) const
gets some stats about the daemon
const command_line::arg_descriptor< size_t > arg_block_download_max_size
void scalarmultKey(key &aP, const key &P, const key &a)
void get_transactions(std::vector< transaction > &txs, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
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_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request &req, COMMAND_RPC_GET_OUTPUTS_BIN::response &res) const
gets specific outputs to mix with
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
user didn't specify, use db_async
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 ...
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
std::vector< blobdata > txs
Severe error information that will presumably abort application.
void set_validators_list_instance(std::unique_ptr< electroneum::basic::Validators > &v)
std::string print_pool(bool short_format) const
get a string containing human-readable pool information
bool set_validator_key(std::string key)
set validator key
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
#define MCLOG_RED(level, cat, x)
handle syncing calls instead of the backing db, synchronously
std::function< const epee::span< const unsigned char >cryptonote::network_type network)> GetCheckpointsCallback
Callback routine that returns checkpoints data for specific network type.
virtual uint64_t get_balance(const crypto::public_key &combined_key)=0
void set_block_notify(const std::shared_ptr< tools::Notify > ¬ify)
sets a block notify object to call for every new block
const command_line::arg_descriptor< std::string > arg_db_sync_mode
static const std::vector< HardFork::Params > & get_hard_fork_heights(network_type nettype)
gets the hardfork heights of given network
const command_line::arg_descriptor< bool, false > arg_stagenet_on
unsigned int & g_test_dbg_lock_sleep()
void set_enforce_dns_checkpoints(bool enforce)
configure whether or not to enforce DNS-based checkpoints
public_key addKeys(const public_key &A, const public_key &B)
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const
return the earliest block a given version may activate
uint64_t get_current_blockchain_height() const
get the current height of the blockchain
crypto::hash get_block_id_by_height(uint64_t height) const
gets a block's hash given a height
virtual difficulty_type get_block_cumulative_difficulty(const uint64_t &height) const =0
fetch a block's cumulative difficulty
virtual bool relay_transactions(NOTIFY_NEW_TRANSACTIONS::request &arg, cryptonote_connection_context &exclude_context)=0
#define JSON_HASH_FILE_NAME
#define DEFAULT_TXPOOL_MAX_WEIGHT
bool is_file_exist(const std::string &path)
difficulty_type get_block_cumulative_difficulty(uint64_t height) const
bool pool_has_tx(const crypto::hash &txid) const
checks if the pool has a transaction with the given hash
uint64_t get_transaction_weight(const transaction &tx, size_t blob_size)
Level
Represents enumeration for severity level used to determine level of logging.
block_complete_entry get_block_complete_entry(block &b, tx_memory_pool &pool)
boost::filesystem::path data_dir
size_t get_transactions_count(bool include_unrelayed_txes=true) const
get the total number of transactions in the pool
std::unordered_map< crypto::key_image, std::vector< crypto::hash > > key_images_with_tx_hashes
bool add_new_block(const block &bl_, block_verification_context &bvc)
adds a block to the blockchain
#define CRYPTONOTE_COINBASE_BLOB_RESERVED_SIZE
bool init(const boost::program_options::variables_map &vm, network_type nettype, bool fallback_to_pow=false)
static void init_options(boost::program_options::options_description &desc)
void safesyncmode(const bool onoff)
Put DB in safe sync mode.
bool isValidatorsListValid()
get Validators List state
void set_checkpoints(checkpoints &&chk_pts)
assign a set of blockchain checkpoint hashes
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 ...
virtual bool handle_block_found(block &b, block_verification_context &bvc)
stores and relays a block found by a miner
virtual std::vector< address_txs > get_addr_tx_batch(const crypto::public_key &combined_key, uint64_t start_db_index=0, uint64_t batch_size=100, bool desc=false)=0
bool utxo_nonexistant(const std::vector< txin_to_key_public > &public_outputs, std::vector< bool > &spent) const
check if multiple public outputs are found in the utxo database or not
void set_reorg_notify(const std::shared_ptr< tools::Notify > ¬ify)
sets a reorg notify object to call for every reorg
bool get_short_chain_history(std::list< crypto::hash > &ids) const
gets the hashes for a subset of the blockchain
bool update_checkpoints(const std::string &file_path, bool check_dns)
loads new checkpoints from a file and optionally from DNS
std::vector< tx_out > vout
bool init(size_t max_txpool_weight=0)
loads pool state (if any) from disk, and initializes pool
bool get_blocks(uint64_t start_offset, size_t count, std::vector< std::pair< cryptonote::blobdata, block >> &blocks, std::vector< cryptonote::blobdata > &txs) const
uint8_t get_current_hard_fork_version() const
gets the current hardfork version in use/voted for
Holds cryptonote related classes and helpers.
size_t get_total_transactions() const
gets the total number of transactions on the main chain
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
const command_line::arg_descriptor< difficulty_type > arg_fixed_difficulty
virtual void set_block_cumulative_difficulty(uint64_t height, difficulty_type diff)=0
sets a block's cumulative difficulty
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 ...
std::vector< txin_v > vin
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
mdb_size_t count(MDB_cursor *cur)
size_t validate(uint8_t version)
remove transactions from the pool which are no longer valid
crypto::public_key m_spend_public_key
bool cleanup_handle_incoming_blocks(bool force_sync=false)
incoming blocks post-processing, cleanup, and disk sync
uint64_t get_current_blockchain_height() const
get the current height of the blockchain
const command_line::arg_descriptor< bool, false > arg_testnet_on
crypto::hash get_tail_id() const
get the hash of the most recent block on the blockchain
BlockchainDB * new_db(const std::string &db_type)
void set_cryptonote_protocol(i_cryptonote_protocol *pprotocol)
set the pointer to the cryptonote protocol object to use
crypto::public_key m_view_public_key
const command_line::arg_descriptor< bool > arg_disable_dns_checkpoints
#define DIFFICULTY_TARGET_V6
bool on_block_chain_update()
rct::rctSig rct_signatures
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 get_pool_transactions(std::vector< transaction > &txs, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool
void set_enforce_dns_checkpoints(bool enforce_dns)
set whether or not we enforce DNS checkpoints
bool check_inputs_types_supported(const transaction &tx)
bool get_block_hash(const block &b, crypto::hash &res)
#define BLOCK_SIZE_SANITY_LEEWAY
bool on_idle()
calls various idle routines
i_cryptonote_protocol * get_protocol()
get the cryptonote protocol instance
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 set_checkpoints(checkpoints &&chk_pts)
assign a set of blockchain checkpoint hashes
void graceful_exit()
tells the daemon to wind down operations and stop running
void get_blockchain_top(uint64_t &height, crypto::hash &top_id) const
get the hash and height of the most recent block
HardFork::State get_hard_fork_state() const
gets the hardfork voting state object
uint64_t get_target_blockchain_height() const
gets the target blockchain height
bool get_pool_transaction_stats(struct txpool_stats &stats, bool include_unrelayed_txes=true) const
get a list of all transactions in the pool
void set_show_time_stats(bool stats)
set whether or not to show/print time statistics
account_public_address address
bool get_pool_transaction(const crypto::hash &id, cryptonote::blobdata &tx) const
get a specific transaction from the pool
bool prune_blockchain(uint32_t pruning_seed=0)
unsigned __int64 uint64_t
bool check_blockchain_pruning()
checks the blockchain pruning if enabled
bool get_test_drop_download_height() const
gets whether or not to drop blocks
const char *const ELECTRONEUM_VERSION
const command_line::arg_descriptor< std::string, false, true, 2 > arg_data_dir
bool reset_and_set_genesis_block(const block &b)
clears the blockchain and starts a new one
#define CRITICAL_REGION_LOCAL(x)
void set_relayed(const std::vector< std::pair< crypto::hash, cryptonote::blobdata >> &txs)
tell the pool that certain transactions were just relayed
bool t_serializable_object_to_blob(const t_object &to, blobdata &b_blob)
std::unique_ptr< void, terminate > context
Unique ZMQ context handle, calls zmq_term on destruction.
bool update_checkpoints()
tells the Blockchain to update its checkpoints
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
Leave syncing up to the backing db (safest, but slowest because of disk I/O)
size_t get_block_sync_size(uint64_t height) const
get the number of blocks to sync in one go
static void init_options(boost::program_options::options_description &desc)
adds command line options to the given options set
bool get_txpool_backlog(std::vector< tx_backlog_entry > &backlog) const
uint8_t get_ideal_hard_fork_version() const
returns the newest hardfork version known to the blockchain
bool get_block_by_hash(const crypto::hash &h, block &blk, bool *orphan=NULL) const
gets the block with a given hash
void set_target_blockchain_height(uint64_t target_blockchain_height)
sets the target blockchain height
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
void on_new_tx_from_block(const cryptonote::transaction &tx)
called when we see a tx originating from a block
bool set_genesis_block(const block &b)
clears the blockchain and starts a new one
const command_line::arg_descriptor< std::string > arg_db_type
bool parse_and_validate_tx_from_blob(const blobdata &tx_blob, transaction &tx)
bool update_blockchain_pruning()
incrementally prunes blockchain
uint64_t get_speed() const
Useful when application has potentially harmful situtaions.
version
Supported socks variants.
bool update_blockchain_pruning()
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 get_transactions(const t_ids_container &txs_ids, t_tx_container &txs, t_missed_container &missed_txs) const
virtual void on_transaction_relayed(const cryptonote::blobdata &tx)
called when a transaction is relayed
bool have_block(const crypto::hash &id) const
checks if a block is known about with a given hash
bool handle_incoming_block(const blobdata &block_blob, const block *b, block_verification_context &bvc, bool update_miner_blocktemplate=true)
handles an incoming block
bool have_tx_keyimg_as_spent(const crypto::key_image &key_im) const
check if a key image is already spent on the blockchain
const command_line::arg_descriptor< bool > arg_offline
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
size_t get_pool_transactions_count() const
get the total number of transactions in the pool
bool is_key_image_spent(const crypto::key_image &key_im) const
check if a key image is already spent on the blockchain
Transaction pool, handles transactions which are not part of a block.
crypto::hash get_block_id_by_height(uint64_t height) const
gets a block's hash given a height
expect< void > success() noexcept
#define HF_VERSION_ENFORCE_RCT
uint32_t get_blockchain_pruning_seed() const
A generic BlockchainDB exception.
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
Mainly useful to represent current progress of application.
bool deinit()
attempts to save the transaction pool state to disk
bool get_alternative_blocks(std::vector< block > &blocks) const
compiles a list of all blocks stored as alternative chains
Blockchain & get_blockchain_storage()
gets the Blockchain instance
const T & move(const T &t)
bool have_tx(const crypto::hash &id) const
search the blockchain for a transaction by hash
void set_checkpoints_file_path(const std::string &path)
set the file path to read from when loading checkpoints
const command_line::arg_descriptor< bool > arg_fallback_to_pow
boost::multiprecision::uint128_t difficulty_type
#define BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4
bool get_transaction(const crypto::hash &h, cryptonote::blobdata &txblob) const
get a specific transaction from the pool
bool have_block(const crypto::hash &id) const
checks if a block is known about with a given hash
uint64_t get_free_space() const
get free disk space on the blockchain partition
size_t get_alternative_blocks_count() const
returns the number of alternative blocks stored
std::string get_validators_list()
Get a serialized representation of the list of validators.
bool get_alternative_blocks(std::vector< block > &blocks) const
compiles a list of all blocks stored as alternative chains
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
const command_line::arg_descriptor< bool > arg_addr_db_salvage
uint8_t get_ideal_hard_fork_version() const
returns the newest hardfork version known to the blockchain
#define HF_VERSION_PUBLIC_TX
const command_line::arg_descriptor< bool > arg_skip_block_sig_verification
uint8_t get_hard_fork_version(uint64_t height) const
returns the actual hardfork version for a given block height
crypto::hash get_transaction_hash(const transaction &t)
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
void safesyncmode(const bool onoff)
Put DB in safe sync mode.
#define MCLOG_CYAN(level, cat, x)
bool have_tx(const crypto::hash &id) const
checks if the pool has a transaction with the given hash
T get_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, false, true > &arg)
bool check_etn_overflow(const transaction &tx)
const command_line::arg_descriptor< bool > arg_db_salvage
static void init_options(boost::program_options::options_description &desc)
init command line options
bool m_added_to_main_chain
bool get_inputs_etn_amount(const transaction &tx, uint64_t &etn)
std::vector< std::string > generate_ed25519_keypair()
bool utxo_spent_in_pool(const txin_to_key_public &in) const
get a summary statistics of all transaction hashes in the pool
const command_line::arg_descriptor< bool > arg_regtest_on
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.
double factorial(unsigned int n)
std::vector< address_txs > get_addr_tx_batch_history(const address_parse_info &addr, const uint64_t &start_tx_id=0, const uint64_t &batch_size=100, bool desc=false)
DISABLE_VS_WARNINGS(4244 4345 4503) using namespace crypto
std::vector< std::string > create_ed25519_keypair()
const command_line::arg_descriptor< uint64_t > arg_fallback_to_pow_checkpoint_height
bool prune_blockchain(uint32_t pruning_seed=0)
prune the blockchain
size_t get_alternative_blocks_count() const
returns the number of alternative blocks stored
A container for blockchain checkpoints.
bool get_block_by_hash(const crypto::hash &h, block &blk, bool *orphan=NULL) const
gets the block with a given hash
const command_line::arg_descriptor< std::string > arg_fallback_to_pow_checkpoint_hash
std::string to_string(t_connection_type type)
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 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
const unsigned char checkpoints[]
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
std::string sign_message(const std::string &message, const std::string &privateKey)
blobdata block_to_blob(const block &b)
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)
bool pool_has_utxo_as_spent(const txin_to_key_public &in) const
get a summary statistics of all transaction hashes in the pool
epee::misc_utils::struct_init< request_t > request
#define DBF_ADDR_TX_SALVAGE
void set_block_cumulative_difficulty(uint64_t height, difficulty_type diff)
#define CATCH_ENTRY_L0(lacation, return_val)
bool get_transactions(const std::vector< crypto::hash > &txs_ids, std::vector< cryptonote::blobdata > &txs, std::vector< crypto::hash > &missed_txs) const
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
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 check_incoming_block_size(const blobdata &block_blob) const
check the size of a block against the current maximum
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
bool do_call(functor_t functr)
bool m_verification_failed
const char * what() const
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 verRctSemanticsSimple(const std::vector< const rctSig *> &rvv)
bool is_arg_defaulted(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
bool deinit()
Uninitializes the blockchain state.
uint64_t get_block_height(const block &b)
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
uint64_t get_earliest_ideal_height_for_version(uint8_t version) const
returns the earliest block a given version may activate
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 parse_and_validate_block_from_blob(const blobdata &b_blob, block &b, crypto::hash *block_hash)
void set_validator_key(std::string key)
set validator key
std::string print_pool(bool short_format) const
get a string containing human-readable pool information
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 cleanup_handle_incoming_blocks(bool force_sync=false)
incoming blocks post-processing, cleanup, and disk sync
#define BAD_SEMANTICS_TXES_MAX_SIZE
bool get_relayable_transactions(std::vector< std::pair< crypto::hash, cryptonote::blobdata >> &txs) const
get a list of all relayable transactions and their hashes
size_t get_blockchain_total_transactions() const
gets the total number of transactions on the main chain
uint64_t get_balance(const address_parse_info &addr)
std::time_t get_start_time() const
gets start_time
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