1
0
Fork 0
forked from lthn/blockchain

Merge branch 'develop' into release

This commit is contained in:
cryptozoidberg 2021-12-02 16:47:37 +01:00
commit a9605d2556
No known key found for this signature in database
GPG key ID: 22DEB97A54C6FDEC
12 changed files with 340 additions and 41 deletions

View file

@ -578,13 +578,13 @@ bool blockchain_storage::set_checkpoints(checkpoints&& chk_pts)
catch (const std::exception& ex)
{
m_db.abort_transaction();
LOG_ERROR("UNKNOWN EXCEPTION WHILE ADDINIG NEW BLOCK: " << ex.what());
LOG_ERROR("UNKNOWN EXCEPTION WHILE SETTING CHECKPOINTS: " << ex.what());
return false;
}
catch (...)
{
m_db.abort_transaction();
LOG_ERROR("UNKNOWN EXCEPTION WHILE ADDINIG NEW BLOCK.");
LOG_ERROR("UNKNOWN EXCEPTION WHILE SETTING CHECKPOINTS.");
return false;
}
@ -594,7 +594,7 @@ bool blockchain_storage::prune_ring_signatures_and_attachments(uint64_t height,
{
CRITICAL_REGION_LOCAL(m_read_lock);
CHECK_AND_ASSERT_MES(height < m_db_blocks.size(), false, "prune_ring_signatures called with wrong parameter: " << height << ", m_blocks.size() " << m_db_blocks.size());
CHECK_AND_ASSERT_MES(height < m_db_blocks.size(), false, "prune_ring_signatures called with wrong parameter: " << height << ", m_blocks.size() = " << m_db_blocks.size());
auto vptr = m_db_blocks[height];
CHECK_AND_ASSERT_MES(vptr.get(), false, "Failed to get block on height");
@ -626,22 +626,20 @@ bool blockchain_storage::prune_ring_signatures_and_attachments_if_need()
{
CRITICAL_REGION_LOCAL(m_read_lock);
if (m_db_blocks.size() > 1 && m_checkpoints.get_top_checkpoint_height() && m_checkpoints.get_top_checkpoint_height() > m_db_current_pruned_rs_height)
{
uint64_t pruning_last_height = std::min(m_db_blocks.size() - 1, m_checkpoints.get_top_checkpoint_height());
if (pruning_last_height > m_db_current_pruned_rs_height)
uint64_t top_block_height = get_top_block_height();
uint64_t pruning_end_height = m_checkpoints.get_checkpoint_before_height(top_block_height);
if (pruning_end_height > m_db_current_pruned_rs_height)
{
LOG_PRINT_CYAN("Starting pruning ring signatues and attachments from height " << m_db_current_pruned_rs_height + 1 << " to height " << pruning_end_height
<< " (" << pruning_end_height - m_db_current_pruned_rs_height << " blocks), top block height is " << top_block_height, LOG_LEVEL_0);
uint64_t tx_count = 0, sig_count = 0, attach_count = 0;
for(uint64_t height = m_db_current_pruned_rs_height + 1; height <= pruning_end_height; height++)
{
LOG_PRINT_CYAN("Starting pruning ring signatues and attachments from height " << m_db_current_pruned_rs_height + 1 << " to height " << pruning_last_height
<< " (" << pruning_last_height - m_db_current_pruned_rs_height << " blocks)", LOG_LEVEL_0);
uint64_t tx_count = 0, sig_count = 0, attach_count = 0;
for(uint64_t height = m_db_current_pruned_rs_height + 1; height <= pruning_last_height; height++)
{
bool res = prune_ring_signatures_and_attachments(height, tx_count, sig_count, attach_count);
CHECK_AND_ASSERT_MES(res, false, "failed to prune_ring_signatures_and_attachments for height = " << height);
}
m_db_current_pruned_rs_height = pruning_last_height;
LOG_PRINT_CYAN("Transaction pruning finished: " << sig_count << " signatures and " << attach_count << " attachments released in " << tx_count << " transactions.", LOG_LEVEL_0);
bool res = prune_ring_signatures_and_attachments(height, tx_count, sig_count, attach_count);
CHECK_AND_ASSERT_MES(res, false, "failed to prune_ring_signatures_and_attachments for height = " << height);
}
m_db_current_pruned_rs_height = pruning_end_height;
LOG_PRINT_CYAN("Transaction pruning finished: " << sig_count << " signatures and " << attach_count << " attachments released in " << tx_count << " transactions.", LOG_LEVEL_0);
}
return true;
}
@ -1036,7 +1034,9 @@ void blockchain_storage::purge_alt_block_txs_hashs(const block& b)
//------------------------------------------------------------------
void blockchain_storage::do_erase_altblock(alt_chain_container::iterator it)
{
purge_altblock_keyimages_from_big_heap(it->second.bl, get_block_hash(it->second.bl));
crypto::hash id = get_block_hash(it->second.bl);
LOG_PRINT_L1("erasing alt block " << print16(id) << " @ " << get_block_height(it->second.bl));
purge_altblock_keyimages_from_big_heap(it->second.bl, id);
purge_alt_block_txs_hashs(it->second.bl);
m_alternative_chains.erase(it);
}

View file

@ -396,7 +396,7 @@ namespace currency
else
{
CHECK_AND_ASSERT_MES(*block_ind_ptr < m_db_blocks.size(), false, "Internal error: bl_id=" << string_tools::pod_to_hex(bl_id)
<< " have index record with offset=" << *block_ind_ptr << ", bigger then m_blocks.size()=" << m_db_blocks.size());
<< " have index record with offset=" << *block_ind_ptr << ", bigger then m_db_blocks.size()=" << m_db_blocks.size());
blocks.push_back(m_db_blocks[*block_ind_ptr]->bl);
}
}

View file

@ -36,11 +36,11 @@ namespace currency
if(height > blockchain_last_block_height)
return false;
auto it = m_points.lower_bound(height);
auto it = m_points.lower_bound(height); // if found, it->first >= height
if(it == m_points.end())
return false;
if(it->first <= blockchain_last_block_height)
return true;
return true; // this is the case only if height <= it->first <= blockchain_last_block_height
else
return false;
}
@ -68,4 +68,27 @@ namespace currency
return false;
}
}
//---------------------------------------------------------------------------
uint64_t checkpoints::get_checkpoint_before_height(uint64_t height) const
{
// returns height of the leftmost CP with height that is LESS than the given height
// ex:
// If there are two CP at 11 and 15:
// get_checkpoint_before_height(10) = 0
// get_checkpoint_before_height(11) = 0
// get_checkpoint_before_height(12) = 11
// get_checkpoint_before_height(13) = 11
// get_checkpoint_before_height(14) = 11
// get_checkpoint_before_height(15) = 11
// get_checkpoint_before_height(16) = 15
uint64_t top_cp = get_top_checkpoint_height();
if (height > top_cp)
return top_cp;
auto it = m_points.lower_bound(height); // if found, it->first >= height
if (it == m_points.end() || it == m_points.begin())
return 0;
return (--it)->first;
}
}

View file

@ -20,6 +20,8 @@ namespace currency
bool is_height_passed_zone(uint64_t height, uint64_t blockchain_last_block_height) const;
bool check_block(uint64_t height, const crypto::hash& h) const;
uint64_t get_top_checkpoint_height() const;
uint64_t get_checkpoint_before_height(uint64_t height) const;
private:
std::map<uint64_t, crypto::hash> m_points;
};

View file

@ -548,15 +548,29 @@ void MainWindow::restore_pos(bool consider_showed)
}
else
{
QPoint pos;
QSize sz;
pos.setX(m_config.m_window_position.first);
pos.setY(m_config.m_window_position.second);
sz.setHeight(m_config.m_window_size.first);
sz.setWidth(m_config.m_window_size.second);
this->move(pos);
this->resize(sz);
QPoint point = QApplication::desktop()->screenGeometry().bottomRight();
if (m_config.m_window_position.first + m_config.m_window_size.second > point.x() ||
m_config.m_window_position.second + m_config.m_window_size.first > point.y()
)
{
QSize sz = AUTO_VAL_INIT(sz);
sz.setHeight(770);
sz.setWidth(1200);
this->resize(sz);
store_window_pos();
//reset position(screen changed or other reason)
}
else
{
QPoint pos = AUTO_VAL_INIT(pos);
QSize sz = AUTO_VAL_INIT(sz);
pos.setX(m_config.m_window_position.first);
pos.setY(m_config.m_window_position.second);
sz.setHeight(m_config.m_window_size.first);
sz.setWidth(m_config.m_window_size.second);
this->move(pos);
this->resize(sz);
}
}
if (consider_showed)
@ -645,7 +659,7 @@ bool MainWindow::show_inital()
{
m_config = AUTO_VAL_INIT(m_config);
this->show();
QSize sz;
QSize sz = AUTO_VAL_INIT(sz);
sz.setHeight(770);
sz.setWidth(1200);
this->resize(sz);

@ -1 +1 @@
Subproject commit 6299e3014aea2f1c5055405f37f0e9de4afc60dd
Subproject commit 20f9219e5f782e019983680791a59b79701e0081

View file

@ -57,7 +57,7 @@ bool clean_data_directory()
{
std::string config_folder = command_line::get_arg(g_vm, command_line::arg_data_dir);
static const std::set<std::string> files = { CURRENCY_POOLDATA_FOLDERNAME_OLD, CURRENCY_BLOCKCHAINDATA_FOLDERNAME_OLD, P2P_NET_DATA_FILENAME, MINER_CONFIG_FILENAME, GUI_SECURE_CONFIG_FILENAME, GUI_CONFIG_FILENAME, GUI_INTERNAL_CONFIG };
static const std::set<std::string> files = { CURRENCY_POOLDATA_FOLDERNAME_OLD, CURRENCY_BLOCKCHAINDATA_FOLDERNAME_OLD, P2P_NET_DATA_FILENAME, MINER_CONFIG_FILENAME, GUI_SECURE_CONFIG_FILENAME, GUI_CONFIG_FILENAME, GUI_INTERNAL_CONFIG2 };
static const std::set<std::string> prefixes = { CURRENCY_POOLDATA_FOLDERNAME_PREFIX, CURRENCY_BLOCKCHAINDATA_FOLDERNAME_PREFIX };
std::vector<boost::filesystem::path> entries_to_remove;
@ -743,6 +743,9 @@ int main(int argc, char* argv[])
#undef MARK_TEST_AS_POSTPONED
// TODO // GENERATE_AND_PLAY(wallet_spend_form_auditable_and_track);
GENERATE_AND_PLAY(pos_minting_tx_packing);
GENERATE_AND_PLAY(multisig_wallet_test);
@ -814,6 +817,7 @@ int main(int argc, char* argv[])
GENERATE_AND_PLAY(gen_checkpoints_reorganize);
GENERATE_AND_PLAY(gen_checkpoints_pos_validation_on_altchain);
GENERATE_AND_PLAY(gen_checkpoints_and_invalid_tx_to_pool);
GENERATE_AND_PLAY(gen_checkpoints_set_after_switching_to_altchain);
GENERATE_AND_PLAY(gen_no_attchments_in_coinbase);
GENERATE_AND_PLAY(gen_no_attchments_in_coinbase_gentime);

View file

@ -36,13 +36,18 @@ bool checkpoints_test::set_checkpoint(currency::core& c, size_t ev_index, const
{
if (pcp.hash != null_hash && pcp.hash != get_block_hash(b))
continue;
currency::checkpoints cp;
cp.add_checkpoint(currency::get_block_height(b), epee::string_tools::pod_to_hex(currency::get_block_hash(b)));
c.set_checkpoints(std::move(cp));
m_local_checkpoints.add_checkpoint(pcp.height, epee::string_tools::pod_to_hex(currency::get_block_hash(b)));
c.set_checkpoints(currency::checkpoints(m_local_checkpoints));
LOG_PRINT_YELLOW("CHECKPOINT set at height " << pcp.height, LOG_LEVEL_0);
//for(uint64_t h = 0; h <= pcp.height + 1; ++h)
// LOG_PRINT_MAGENTA("%% " << h << " : " << m_local_checkpoints.get_checkpoint_before_height(h), LOG_LEVEL_0);
return true;
}
}
LOG_ERROR("set_checkpoint failed trying to set checkpoint at height " << pcp.height);
return false;
}
@ -395,8 +400,13 @@ bool gen_checkpoints_prun_txs_after_blockchain_load::generate(std::vector<test_e
DO_CALLBACK(events, "check_not_being_in_cp_zone");
DO_CALLBACK_PARAMS(events, "set_checkpoint", params_checkpoint(CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 2));
events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true)); // tx_0 goes with blk_1_bad
MAKE_TX(events, tx_0, miner_acc, alice, MK_TEST_COINS(1), blk_0r);
std::vector<attachment_v> attach;
attach.push_back(tx_comment{"jokes are funny"});
// tx pool won't accept the tx, because it cannot be verified in CP zone
// set kept_by_block flag, so tx_0 be accepted
events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, true));
MAKE_TX_ATTACH(events, tx_0, miner_acc, alice, MK_TEST_COINS(1), blk_0r, attach);
events.push_back(event_visitor_settings(event_visitor_settings::set_txs_kept_by_block, false));
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_0);
@ -407,11 +417,12 @@ bool gen_checkpoints_prun_txs_after_blockchain_load::generate(std::vector<test_e
DO_CALLBACK(events, "check_not_being_in_cp_zone");
MAKE_TX(events, tx_1, miner_acc, alice, MK_TEST_COINS(1), blk_3);
MAKE_TX_ATTACH(events, tx_1, miner_acc, alice, MK_TEST_COINS(1), blk_3, attach);
MAKE_NEXT_BLOCK_TX1(events, blk_4, blk_3, miner_acc, tx_1);
DO_CALLBACK(events, "check_not_being_in_cp_zone");
// BCS tx pruning (on interval 0 - CP1) should be triggered once the following checkpoint is set
DO_CALLBACK_PARAMS(events, "set_checkpoint", params_checkpoint(CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 6));
MAKE_NEXT_BLOCK(events, blk_5, blk_4, miner_acc);
@ -437,8 +448,8 @@ bool gen_checkpoints_prun_txs_after_blockchain_load::check_txs(currency::core& c
r = c.get_transaction(m_tx1_id, tx_1);
CHECK_AND_ASSERT_MES(r, false, "can't get transaction tx_1");
CHECK_AND_ASSERT_MES(tx_1.signatures.empty(), false, "tx_1 has non-empty sig");
CHECK_AND_ASSERT_MES(tx_1.attachment.empty(), false, "tx_1 has non-empty attachments");
CHECK_AND_ASSERT_MES(!tx_1.signatures.empty(), false, "tx_1 has empty sig");
CHECK_AND_ASSERT_MES(!tx_1.attachment.empty(), false, "tx_1 has empty attachments");
return true;
}
@ -895,3 +906,64 @@ bool gen_checkpoints_and_invalid_tx_to_pool::c1(currency::core& c, size_t ev_ind
return true;
}
//------------------------------------------------------------------------------
gen_checkpoints_set_after_switching_to_altchain::gen_checkpoints_set_after_switching_to_altchain()
{
}
bool gen_checkpoints_set_after_switching_to_altchain::generate(std::vector<test_event_entry>& events) const
{
// Test outline:
// 0) no checkpoints are set;
// 1) core is in a subchain, that will become alternative;
// 2) checkpoint is set (in the furute), transaction pruning is executed;
// 3) core continues to sync, chain switching occurs
// Make sure that chain switching is still possible after pruning.
// 0 ... N N+1 N+2 N+3 N+4 N+5 N+6 <- height (N = CURRENCY_MINED_MONEY_UNLOCK_WINDOW)
// tx1
// (0 )- (0r)- (1 )- (2a)- (3a)- <- alt chain
// \
// \- (2 )- <- main chain
bool r = false;
GENERATE_ACCOUNT(miner_acc);
GENERATE_ACCOUNT(alice_acc);
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time());
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
DO_CALLBACK(events, "check_not_being_in_cp_zone");
MAKE_NEXT_BLOCK(events, blk_1, blk_0r, miner_acc);
MAKE_TX(events, tx1, miner_acc, alice_acc, MK_TEST_COINS(1), blk_1);
MAKE_NEXT_BLOCK_TX1(events, blk_2a, blk_1, miner_acc, tx1);
MAKE_NEXT_BLOCK(events, blk_3a, blk_2a, miner_acc);
DO_CALLBACK(events, "check_not_being_in_cp_zone");
// 0 ... N N+1 N+2 N+3 N+4 N+5 N+6 <- height (N = CURRENCY_MINED_MONEY_UNLOCK_WINDOW)
// +-----------> CP <- checkpoint
// tx1 |
// (0 )- (0r)- (1 )- (2a)- (3a)- <- alt chain
// \ | <- when CP set up
// \- (2 )- (3 )- (4 )- (5 )- (6 )- <- main chain
DO_CALLBACK_PARAMS(events, "set_checkpoint", params_checkpoint(CURRENCY_MINED_MONEY_UNLOCK_WINDOW + 5));
MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_acc);
MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_acc);
MAKE_NEXT_BLOCK(events, blk_4, blk_3, miner_acc); // <-- this should trigger the switching
DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(get_block_height(blk_4), get_block_hash(blk_4)));
DO_CALLBACK(events, "check_being_in_cp_zone");
MAKE_NEXT_BLOCK(events, blk_5, blk_4, miner_acc); // <-- CHECKPOINT
MAKE_NEXT_BLOCK(events, blk_6, blk_5, miner_acc);
DO_CALLBACK_PARAMS(events, "check_top_block", params_top_block(get_block_height(blk_6), get_block_hash(blk_6)));
DO_CALLBACK(events, "check_not_being_in_cp_zone");
return true;
}

View file

@ -23,6 +23,9 @@ protected:
uint64_t height;
crypto::hash hash;
};
private:
currency::checkpoints m_local_checkpoints;
};
struct gen_checkpoints_attachments_basic : public checkpoints_test
@ -109,3 +112,9 @@ struct gen_checkpoints_and_invalid_tx_to_pool : public checkpoints_test
bool generate(std::vector<test_event_entry>& events) const;
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
};
struct gen_checkpoints_set_after_switching_to_altchain : public checkpoints_test
{
gen_checkpoints_set_after_switching_to_altchain();
bool generate(std::vector<test_event_entry>& events) const;
};

View file

@ -3553,5 +3553,87 @@ bool wallet_watch_only_and_chain_switch::c1(currency::core& c, size_t ev_index,
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt, MK_TEST_COINS(7), false, UINT64_MAX, 0, 0, MK_TEST_COINS(7), 0), false, "");
return true;
}
//------------------------------------------------------------------------------
wallet_spend_form_auditable_and_track::wallet_spend_form_auditable_and_track()
{
REGISTER_CALLBACK_METHOD(wallet_spend_form_auditable_and_track, c1);
}
bool wallet_spend_form_auditable_and_track::generate(std::vector<test_event_entry>& events) const
{
bool r = false;
m_accounts.resize(TOTAL_ACCS_COUNT);
account_base& miner_acc = m_accounts[MINER_ACC_IDX]; miner_acc.generate();
account_base& alice_acc = m_accounts[ALICE_ACC_IDX]; alice_acc.generate(true); // Alice has auditable wallet
account_base& bob_acc = m_accounts[BOB_ACC_IDX]; bob_acc = alice_acc; bob_acc.make_account_watch_only(); // Bob has Alice's tracking wallet
MAKE_GENESIS_BLOCK(events, blk_0, miner_acc, test_core_time::get_time());
REWIND_BLOCKS_N(events, blk_0r, blk_0, miner_acc, CURRENCY_MINED_MONEY_UNLOCK_WINDOW);
MAKE_TX(events, tx_1, miner_acc, alice_acc, MK_TEST_COINS(5), blk_0r);
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_acc, tx_1);
REWIND_BLOCKS_N(events, blk_1r, blk_1, miner_acc, WALLET_DEFAULT_TX_SPENDABLE_AGE);
std::vector<attachment_v> attachments;
tx_comment comment_attachment = AUTO_VAL_INIT(comment_attachment);
m_comment = "Jokes are funny!";
comment_attachment.comment = m_comment;
attachments.push_back(comment_attachment);
MAKE_TX_ATTACH(events, tx_2, alice_acc, miner_acc, MK_TEST_COINS(1), blk_1r, attachments);
MAKE_NEXT_BLOCK_TX1(events, blk_2, blk_1r, miner_acc, tx_2);
DO_CALLBACK(events, "c1");
return true;
}
bool wallet_spend_form_auditable_and_track::c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events)
{
bool r = false;
std::shared_ptr<tools::wallet2> miner_wlt = init_playtime_test_wallet(events, c, MINER_ACC_IDX);
std::shared_ptr<tools::wallet2> alice_wlt = init_playtime_test_wallet(events, c, ALICE_ACC_IDX);
std::shared_ptr<tools::wallet2> bob_wlt = init_playtime_test_wallet(events, c, BOB_ACC_IDX);
// make sure Alice's wallet is autibale and not watch-only
CHECK_AND_ASSERT_MES(!alice_wlt->is_watch_only() && alice_wlt->is_auditable(), false, "incorrect type of Alice's wallet");
// make sure Bob's wallet is a tracking wallet
CHECK_AND_ASSERT_MES(bob_wlt->is_watch_only() && bob_wlt->is_auditable(), false, "incorrect type of Bob's wallet");
const account_public_address& bob_addr = bob_wlt->get_account().get_public_address();
const account_public_address& alice_addr = alice_wlt->get_account().get_public_address();
// make sure their addresses are linked indeed
CHECK_AND_ASSERT_MES(bob_addr.view_public_key == alice_addr.view_public_key && bob_addr.spend_public_key == alice_addr.spend_public_key, false,
"Bob's tracking wallet address is not linked with Alice's one");
CHECK_AND_ASSERT_MES(c.get_pool_transactions_count() == 0, false, "Incorrect txs count in the pool: " << c.get_pool_transactions_count());
bob_wlt->refresh();
// check the balances
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Alice", alice_wlt, MK_TEST_COINS(3), false, UINT64_MAX, 0, 0, 0, 0), false, "");
CHECK_AND_ASSERT_MES(refresh_wallet_and_check_balance("", "Bob", bob_wlt, MK_TEST_COINS(3), false, UINT64_MAX, 0, 0, 0, 0), false, "");
r = false;
bool r_comment = false;
bob_wlt->enumerate_transfers_history([&](const tools::wallet_public::wallet_transfer_info& wti) {
if (wti.amount == MK_TEST_COINS(5))
{
r_comment = (wti.comment == m_comment);
if (!r_comment)
return false; // stop
}
return true; // continue
}, true);
CHECK_AND_ASSERT_MES(r, false, "cannot get comment from tx");
CHECK_AND_ASSERT_MES(r_comment, false, "wrong comment got from tx");
return true;
}

View file

@ -276,3 +276,12 @@ struct wallet_watch_only_and_chain_switch : public wallet_test
mutable crypto::hash m_split_point_block_id;
mutable uint64_t m_split_point_block_height;
};
struct wallet_spend_form_auditable_and_track : public wallet_test
{
wallet_spend_form_auditable_and_track();
bool generate(std::vector<test_event_entry>& events) const;
bool c1(currency::core& c, size_t ev_index, const std::vector<test_event_entry>& events);
mutable std::string m_comment;
};

View file

@ -39,3 +39,87 @@ TEST(checkpoints_test, test_checkpoints_for_alternative)
r = cp.is_height_passed_zone(11, 12);
ASSERT_FALSE(r);
}
TEST(checkpoints_test, get_checkpoint_before_height_1)
{
currency::checkpoints cp;
cp.add_checkpoint(15, "0000000000000000000000000000000000000000000000000000000000000000");
for (uint64_t h = 0; h <= 15; ++h)
ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 0);
ASSERT_TRUE(cp.get_checkpoint_before_height(16) == 15);
for (uint64_t h = 17; h < 100; ++h)
ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 15);
}
TEST(checkpoints_test, get_checkpoint_before_height_2)
{
currency::checkpoints cp;
cp.add_checkpoint(11, "0000000000000000000000000000000000000000000000000000000000000000");
cp.add_checkpoint(15, "0000000000000000000000000000000000000000000000000000000000000000");
for (uint64_t h = 0; h < 11; ++h)
ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 0);
ASSERT_TRUE(cp.get_checkpoint_before_height(11) == 0);
ASSERT_TRUE(cp.get_checkpoint_before_height(12) == 11);
ASSERT_TRUE(cp.get_checkpoint_before_height(13) == 11);
ASSERT_TRUE(cp.get_checkpoint_before_height(14) == 11);
ASSERT_TRUE(cp.get_checkpoint_before_height(15) == 11);
ASSERT_TRUE(cp.get_checkpoint_before_height(16) == 15);
for (uint64_t h = 17; h < 100; ++h)
ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 15);
}
TEST(checkpoints_test, get_checkpoint_before_height_3)
{
currency::checkpoints cp;
cp.add_checkpoint(11, "0000000000000000000000000000000000000000000000000000000000000000");
cp.add_checkpoint(15, "0000000000000000000000000000000000000000000000000000000000000000");
cp.add_checkpoint(21, "0000000000000000000000000000000000000000000000000000000000000000");
for (uint64_t h = 0; h < 11; ++h)
ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 0);
ASSERT_TRUE(cp.get_checkpoint_before_height(11) == 0);
ASSERT_TRUE(cp.get_checkpoint_before_height(12) == 11);
ASSERT_TRUE(cp.get_checkpoint_before_height(13) == 11);
ASSERT_TRUE(cp.get_checkpoint_before_height(14) == 11);
ASSERT_TRUE(cp.get_checkpoint_before_height(15) == 11);
ASSERT_TRUE(cp.get_checkpoint_before_height(16) == 15);
ASSERT_TRUE(cp.get_checkpoint_before_height(17) == 15);
ASSERT_TRUE(cp.get_checkpoint_before_height(18) == 15);
ASSERT_TRUE(cp.get_checkpoint_before_height(19) == 15);
ASSERT_TRUE(cp.get_checkpoint_before_height(20) == 15);
ASSERT_TRUE(cp.get_checkpoint_before_height(21) == 15);
ASSERT_TRUE(cp.get_checkpoint_before_height(22) == 21);
for (uint64_t h = 22; h < 100; ++h)
ASSERT_TRUE(cp.get_checkpoint_before_height(h) == 21);
}
TEST(checkpoints_test, is_in_checkpoint_zone)
{
currency::checkpoints cp;
cp.add_checkpoint(11, "0000000000000000000000000000000000000000000000000000000000000000");
cp.add_checkpoint(15, "0000000000000000000000000000000000000000000000000000000000000000");
cp.add_checkpoint(21, "0000000000000000000000000000000000000000000000000000000000000000");
for (uint64_t h = 0; h < 22; ++h)
ASSERT_TRUE(cp.is_in_checkpoint_zone(h));
for (uint64_t h = 22; h < 100; ++h)
ASSERT_FALSE(cp.is_in_checkpoint_zone(h));
}