| 949 | } |
| 950 | |
| 951 | bool BlockChain::internal_import() { |
| 952 | auto idea_start = std::chrono::high_resolution_clock::now(); |
| 953 | try { |
| 954 | while (true) { |
| 955 | if (get_tip_height() + 1 >= m_internal_import_chain.size()) |
| 956 | break; |
| 957 | const Hash bid = m_internal_import_chain.at(get_tip_height() + 1); |
| 958 | RawBlock rb; |
| 959 | if (!get_block(bid, &rb)) { |
| 960 | m_log(logging::WARNING) << "Block not found during internal import for height=" << get_tip_height() + 1 |
| 961 | << " bid=" << bid; |
| 962 | break; |
| 963 | } |
| 964 | PreparedBlock pb{std::move(rb), m_currency, nullptr}; |
| 965 | api::BlockHeader info; |
| 966 | if (!add_block(pb, &info, false, "internal_import")) { |
| 967 | m_log(logging::WARNING) << "Block corrupted during internal import for height=" << get_tip_height() + 1 |
| 968 | << " bid=" << bid; |
| 969 | break; |
| 970 | } |
| 971 | // if (get_tip_height() % m_config.db_commit_every_n_blocks == 0) |
| 972 | // db_commit(); |
| 973 | auto idea_ms = std::chrono::duration_cast<std::chrono::milliseconds>( |
| 974 | std::chrono::high_resolution_clock::now() - idea_start); |
| 975 | if (idea_ms.count() > 200) |
| 976 | return true; // import in chunks of 0.2 seconds |
| 977 | } |
| 978 | } catch (const std::exception &ex) { |
| 979 | m_log(logging::WARNING) << "Block corrupted during internal import for height=" << get_tip_height() + 1 |
| 980 | << " exception=" << common::what(ex); |
| 981 | } |
| 982 | m_log(logging::INFO) << "Finished internal importing of blocks, will continue downloading..."; |
| 983 | m_internal_import_chain.clear(); |
| 984 | m_db.del("internal_import_chain", true); |
| 985 | db_commit(); |
| 986 | return false; |
| 987 | } |
| 988 | |
| 989 | void BlockChain::test_undo_everything(Height new_tip_height) { |
| 990 | for (DB::Cursor cur = m_db.begin(CHECKPOINT_PREFIX_STABLE); !cur.end(); cur.erase()) { |