Skip to content

Commit

Permalink
Merge pull request #2240 from AntelopeIO/update_weak_tests
Browse files Browse the repository at this point in the history
IF: reenable weak vote related tests
  • Loading branch information
linh2931 authored Feb 17, 2024
2 parents e3156fe + 0cbd0c3 commit 999e5c3
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 27 deletions.
16 changes: 16 additions & 0 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1860,6 +1860,18 @@ struct controller_impl {
);
}

digest_type get_strong_digest_by_id( const block_id_type& id ) const {
return fork_db.apply<digest_type>(
overloaded{
[](const fork_database_legacy_t&) -> digest_type { return digest_type{}; },
[&](const fork_database_if_t& forkdb) -> digest_type {
auto bsp = forkdb.get_block(id);
return bsp ? bsp->strong_digest : digest_type{};
}
}
);
}

fc::sha256 calculate_integrity_hash() {
fc::sha256::encoder enc;
auto hash_writer = std::make_shared<integrity_hash_snapshot_writer>(enc);
Expand Down Expand Up @@ -4463,6 +4475,10 @@ block_id_type controller::get_block_id_for_num( uint32_t block_num )const { try
return id;
} FC_CAPTURE_AND_RETHROW( (block_num) ) }

digest_type controller::get_strong_digest_by_id( const block_id_type& id ) const {
return my->get_strong_digest_by_id(id);
}

fc::sha256 controller::calculate_integrity_hash() { try {
return my->calculate_integrity_hash();
} FC_LOG_AND_RETHROW() }
Expand Down
2 changes: 2 additions & 0 deletions libraries/chain/include/eosio/chain/controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,8 @@ namespace eosio::chain {
std::optional<signed_block_header> fetch_block_header_by_id( const block_id_type& id )const;
// thread-safe
block_id_type get_block_id_for_num( uint32_t block_num )const;
// thread-safe
digest_type get_strong_digest_by_id( const block_id_type& id ) const; // used in unittests

fc::sha256 calculate_integrity_hash();
void write_snapshot( const snapshot_writer_ptr& snapshot );
Expand Down
4 changes: 2 additions & 2 deletions libraries/testing/include/eosio/testing/tester.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ namespace eosio { namespace testing {

// libtester uses 1 as weight of each of the finalizer, sets (2/3 finalizers + 1)
// as threshold, and makes all finalizers vote QC
transaction_trace_ptr set_finalizers(const vector<account_name>& finalizer_names);
std::pair<transaction_trace_ptr, std::vector<fc::crypto::blslib::bls_private_key>> set_finalizers(const vector<account_name>& finalizer_names);

// Finalizer policy input to set up a test: weights, threshold and local finalizers
// which participate voting.
Expand All @@ -269,7 +269,7 @@ namespace eosio { namespace testing {
uint64_t threshold {0};
std::vector<account_name> local_finalizers;
};
transaction_trace_ptr set_finalizers(const finalizer_policy_input& input);
std::pair<transaction_trace_ptr, std::vector<fc::crypto::blslib::bls_private_key>> set_finalizers(const finalizer_policy_input& input);

void link_authority( account_name account, account_name code, permission_name req, action_name type = {} );
void unlink_authority( account_name account, account_name code, action_name type = {} );
Expand Down
11 changes: 7 additions & 4 deletions libraries/testing/tester.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1174,7 +1174,7 @@ namespace eosio { namespace testing {

}

transaction_trace_ptr base_tester::set_finalizers(const vector<account_name>& finalizer_names) {
std::pair<transaction_trace_ptr, std::vector<fc::crypto::blslib::bls_private_key>> base_tester::set_finalizers(const vector<account_name>& finalizer_names) {
auto num_finalizers = finalizer_names.size();
std::vector<finalizer_policy_input::finalizer_info> finalizers_info;
finalizers_info.reserve(num_finalizers);
Expand All @@ -1191,16 +1191,18 @@ namespace eosio { namespace testing {
return set_finalizers(policy_input);
}

transaction_trace_ptr base_tester::set_finalizers(const finalizer_policy_input& input) {
std::pair<transaction_trace_ptr, std::vector<fc::crypto::blslib::bls_private_key>> base_tester::set_finalizers(const finalizer_policy_input& input) {
chain::bls_pub_priv_key_map_t local_finalizer_keys;
fc::variants finalizer_auths;
std::vector<fc::crypto::blslib::bls_private_key> priv_keys;

for (const auto& f: input.finalizers) {
auto [privkey, pubkey, pop] = get_bls_key( f.name );

// if it is a local finalizer, set up public to private key mapping for voting
if( auto it = std::ranges::find_if(input.local_finalizers, [&](const auto& name) { return name == f.name; }); it != input.local_finalizers.end()) {
local_finalizer_keys[pubkey.to_string()] = privkey.to_string();
priv_keys.emplace_back(privkey);
};

finalizer_auths.emplace_back(
Expand All @@ -1217,8 +1219,9 @@ namespace eosio { namespace testing {
fin_policy_variant("threshold", input.threshold);
fin_policy_variant("finalizers", std::move(finalizer_auths));

return push_action( config::system_account_name, "setfinalizer"_n, config::system_account_name,
fc::mutable_variant_object()("finalizer_policy", std::move(fin_policy_variant)));
return { push_action( config::system_account_name, "setfinalizer"_n, config::system_account_name,
fc::mutable_variant_object()("finalizer_policy", std::move(fin_policy_variant))),
priv_keys };
}

const table_id_object* base_tester::find_table( name code, name scope, name table ) {
Expand Down
12 changes: 11 additions & 1 deletion unittests/finality_test_cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,11 @@ void finality_test_cluster::setup_node(node_info& node, eosio::chain::account_na
.threshold = 2,
.local_finalizers = {local_finalizer}
};
node.node.set_finalizers(policy_input);

auto [trace_ptr, priv_keys] = node.node.set_finalizers(policy_input);
FC_ASSERT( priv_keys.size() == 1, "number of private keys should be 1" );
node.priv_key = priv_keys[0]; // we only have one private key

auto block = node.node.produce_block();

// this block contains the header extension for the instant finality
Expand All @@ -178,7 +182,13 @@ eosio::chain::vote_status finality_test_cluster::process_vote(node_info& node, s
vote.strong = true;
} else {
vote.strong = false;

// fetch the strong digest
auto strong_digest = node.node.control->get_strong_digest_by_id(vote.proposal_id);
// convert the strong digest to weak and sign it
vote.sig = node.priv_key.sign(eosio::chain::create_weak_digest(strong_digest));
}

return node0.node.control->process_vote_message( vote );
}

Expand Down
2 changes: 2 additions & 0 deletions unittests/finality_test_cluster.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <eosio/chain/hotstuff/finalizer_authority.hpp>
#include <fc/crypto/bls_private_key.hpp>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wsign-compare"
Expand Down Expand Up @@ -78,6 +79,7 @@ class finality_test_cluster {
eosio::testing::tester node;
uint32_t prev_lib_num{0};
std::vector<eosio::chain::vote_message> votes;
fc::crypto::blslib::bls_private_key priv_key;
};

std::array<node_info, 3> nodes;
Expand Down
25 changes: 5 additions & 20 deletions unittests/finality_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ BOOST_AUTO_TEST_CASE(long_delayed_votes) { try {
cluster.process_node1_vote();
// the vote makes a strong QC for the current block, prompting LIB advance on node0
BOOST_REQUIRE(cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

for (auto i = 2; i < 100; ++i) {
Expand Down Expand Up @@ -221,22 +220,18 @@ BOOST_AUTO_TEST_CASE(lost_votes) { try {

// the vote makes a strong QC for the current block, prompting LIB advance on node0
BOOST_REQUIRE(cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

BOOST_REQUIRE(cluster.produce_blocks_and_verify_lib_advancing());
} FC_LOG_AND_RETHROW() }

#warning "Re-enable these tests"
#if 0
BOOST_AUTO_TEST_CASE(one_weak_vote) { try {
finality_test_cluster cluster;

// Produce and push a block
cluster.produce_and_push_block();
// Change the vote to a weak vote and process it
cluster.process_node1_vote(0, finality_test_cluster::vote_mode::weak);

// A weak QC is created and LIB does not advance on node0
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// The strong QC extension for prior block makes LIB advance on node1
Expand All @@ -248,21 +243,19 @@ BOOST_AUTO_TEST_CASE(one_weak_vote) { try {
// its final_on_strong_qc_block_num is nullopt due to previous QC was weak.
// Cannot advance LIB.
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
// no 2-chain was formed as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

cluster.produce_and_push_block();
cluster.process_node1_vote();
BOOST_REQUIRE(cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

cluster.produce_and_push_block();
cluster.process_node1_vote();
// the vote makes a strong QC and a higher final_on_strong_qc,
// prompting LIB advance on node0
BOOST_REQUIRE(cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(cluster.node1_lib_advancing());

// now a 3 chain has formed.
Expand All @@ -285,28 +278,26 @@ BOOST_AUTO_TEST_CASE(two_weak_votes) { try {
cluster.process_node1_vote(finality_test_cluster::vote_mode::weak);
// A weak QC cannot advance LIB on node0
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
// no 2-chain was formed as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

cluster.produce_and_push_block();
cluster.process_node1_vote();
// the vote makes a strong QC for the current block, prompting LIB advance on node0
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

cluster.produce_and_push_block();
cluster.process_node1_vote();
// the vote makes a strong QC for the current block, prompting LIB advance on node0
BOOST_REQUIRE(cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

// now a 3 chain has formed.
BOOST_REQUIRE(cluster.produce_blocks_and_verify_lib_advancing());
} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(interwined_weak_votes) { try {
BOOST_AUTO_TEST_CASE(intertwined_weak_votes) { try {
finality_test_cluster cluster;

// Weak vote
Expand All @@ -324,23 +315,22 @@ BOOST_AUTO_TEST_CASE(interwined_weak_votes) { try {
// its final_on_strong_qc_block_num is nullopt due to previous QC was weak.
// Cannot advance LIB.
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
// no 2-chain was formed as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

// Weak vote
cluster.produce_and_push_block();
cluster.process_node1_vote(finality_test_cluster::vote_mode::weak);
// A weak QC cannot advance LIB on node0
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

// Strong vote
cluster.produce_and_push_block();
cluster.process_node1_vote();
// the vote makes a strong QC for the current block, prompting LIB advance on node0
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
// no 2-chain was formed as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

// Strong vote
Expand Down Expand Up @@ -374,13 +364,11 @@ BOOST_AUTO_TEST_CASE(weak_delayed_lost_vote) { try {
// The vote makes a strong QC, but final_on_strong_qc is null.
// Do not advance LIB
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

// A lost vote
cluster.produce_and_push_block();
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

// The delayed vote arrives
Expand Down Expand Up @@ -429,13 +417,11 @@ BOOST_AUTO_TEST_CASE(delayed_strong_weak_lost_vote) { try {
// The vote makes a strong QC, but final_on_strong_qc is null.
// LIB did not advance.
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

// A lost vote
cluster.produce_and_push_block();
BOOST_REQUIRE(!cluster.node0_lib_advancing());
// the block does not has a QC extension as prior block was not a strong block
BOOST_REQUIRE(!cluster.node1_lib_advancing());

// The delayed vote arrives
Expand All @@ -455,7 +441,6 @@ BOOST_AUTO_TEST_CASE(delayed_strong_weak_lost_vote) { try {

BOOST_REQUIRE(cluster.produce_blocks_and_verify_lib_advancing());
} FC_LOG_AND_RETHROW() }
#endif

// verify duplicate votes do not affect LIB advancing
BOOST_AUTO_TEST_CASE(duplicate_votes) { try {
Expand Down

0 comments on commit 999e5c3

Please sign in to comment.