Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Svnn ibc proof generation #37

Merged
merged 36 commits into from
May 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
5900424
added unit test for svnn_ibc proof generation + verification
systemzax Apr 16, 2024
7186456
Changed svnn_ibc contract bitset to use uint32_t block size to align …
systemzax Apr 16, 2024
cbd7b6b
Merge branch 'savanna' into svnn_ibc_proof_generation
systemzax Apr 16, 2024
9c1c888
changed bitset instanciation in svnn_ibc_tests, fixed cast in svnn_ib…
systemzax Apr 17, 2024
0c6417d
Merge branch 'svnn_ibc_proof_generation' of https://github.com/antelo…
systemzax Apr 17, 2024
32e694a
Explicit type definition for raw_bitset
systemzax Apr 17, 2024
4b8aced
Merge branch 'savanna' into svnn_ibc_proof_generation
systemzax Apr 17, 2024
0b65953
Use finality_test_cluster in ibc test
systemzax Apr 21, 2024
fa7588d
Improvements to ibc contract bitset
systemzax Apr 21, 2024
c6b5222
Manual merge
systemzax Apr 21, 2024
f961fbd
Removed leftover comment
systemzax Apr 21, 2024
2c0e42a
Fixed wrong block_num in svnn_ibc contract lastproofs inclusion
systemzax Apr 24, 2024
77d31c6
Compute proof path instead of providing it when calling the contract
systemzax Apr 28, 2024
a63949a
Added tests for light proof + different finality block than target block
systemzax Apr 28, 2024
c9b5094
Refactored to avoid the use of target_data variant
systemzax Apr 28, 2024
23cdef9
Replaced binary interface with string interface for bls_pub_key and b…
systemzax Apr 29, 2024
d66a178
implemented svnn_ibc garbage collection, improved tests coverage
systemzax Apr 29, 2024
b2ceafa
Improved svnn_ibc test comments
systemzax Apr 29, 2024
2350442
svnn_ibc test code cleanup
systemzax Apr 29, 2024
ff4f9a8
Merge remote-tracking branch 'origin/savanna' into svnn_ibc_proof_gen…
systemzax Apr 29, 2024
022c3a7
Adjusted svnn_ibc test to reflect changes in quorum_certificate struct
systemzax Apr 29, 2024
1ca06ab
Manual merge in block_header_state.hpp
systemzax Apr 29, 2024
a335485
Merge branch 'main' into svnn_ibc_proof_generation
systemzax Apr 29, 2024
dcd88fc
Updated bls submodule
systemzax Apr 29, 2024
f47bef6
Updated modules recursively
systemzax Apr 29, 2024
2742928
Revert "Updated modules recursively"
systemzax Apr 29, 2024
e599e1d
Revert "Updated bls submodule"
systemzax Apr 29, 2024
8735b22
Revert "Revert "Updated bls submodule""
systemzax Apr 29, 2024
6dfe3e7
Merge branch 'main' into svnn_ibc_proof_generation
systemzax Apr 29, 2024
28c5490
Update unittests/test-contracts/svnn_ibc/svnn_ibc.hpp
systemzax Apr 30, 2024
e3d1fe3
Merge branch 'main' into svnn_ibc_proof_generation
heifner May 1, 2024
8435fd6
Removed commented out code
systemzax May 2, 2024
c83664f
Misc minor fixes
systemzax May 2, 2024
60ad311
Merge branch 'svnn_ibc_proof_generation' of https://github.com/antelo…
systemzax May 2, 2024
e391806
Removed extra comment
systemzax May 2, 2024
dd1689b
updated bls submodule reference
systemzax May 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 0 additions & 12 deletions libraries/chain/block_header_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@ namespace eosio::chain {
// gets updated if a protocol feature causes a breaking change to light block
// header validation

// data for finality_digest
struct finality_digest_data_v1 {
uint32_t major_version{light_header_protocol_version_major};
uint32_t minor_version{light_header_protocol_version_minor};
uint32_t active_finalizer_policy_generation {0};
digest_type finality_tree_digest;
digest_type active_finalizer_policy_and_base_digest;
};

// compute base_digest explicitly because of pointers involved.
digest_type block_header_state::compute_base_digest() const {
digest_type::encoder enc;
Expand Down Expand Up @@ -298,6 +289,3 @@ block_header_state block_header_state::next(const signed_block_header& h, valida

} // namespace eosio::chain

FC_REFLECT( eosio::chain::finality_digest_data_v1,
(major_version)(minor_version)(active_finalizer_policy_generation)
(finality_tree_digest)(active_finalizer_policy_and_base_digest) )
12 changes: 12 additions & 0 deletions libraries/chain/include/eosio/chain/block_header_state.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,16 @@ namespace detail { struct schedule_info; };
constexpr uint32_t light_header_protocol_version_major = 1;
constexpr uint32_t light_header_protocol_version_minor = 0;

// data for finality_digest
struct finality_digest_data_v1 {
uint32_t major_version{light_header_protocol_version_major};
uint32_t minor_version{light_header_protocol_version_minor};
uint32_t active_finalizer_policy_generation {0};
digest_type finality_tree_digest;
digest_type active_finalizer_policy_and_base_digest;

};

// ------------------------------------------------------------------------------------------
// this is used for tracking in-flight `finalizer_policy` changes, which have been requested,
// but are not activated yet. This struct is associated to a block_number in the
Expand Down Expand Up @@ -128,3 +138,5 @@ FC_REFLECT( eosio::chain::block_header_state, (block_id)(header)
(activated_protocol_features)(core)(active_finalizer_policy)
(active_proposer_policy)(proposer_policies)(finalizer_policies)
(finalizer_policy_generation)(header_exts))

FC_REFLECT( eosio::chain::finality_digest_data_v1, (major_version)(minor_version)(active_finalizer_policy_generation)(finality_tree_digest)(active_finalizer_policy_and_base_digest) )
44 changes: 30 additions & 14 deletions unittests/finality_test_cluster.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ finality_test_cluster::finality_test_cluster() {
setup_node(node1, "node1"_n);
setup_node(node2, "node2"_n);

produce_and_push_block(); // make setfinalizer irreversible

// node0's votes
node0.node.control->voted_block().connect( [&]( const eosio::chain::vote_signal_params& v ) {
last_vote_status = std::get<1>(v);
Expand All @@ -26,6 +24,24 @@ finality_test_cluster::finality_test_cluster() {
node2.votes.emplace_back(std::get<2>(v));
});

}

void finality_test_cluster::initial_tests(){

auto block_1_n0 = node0.node.produce_block();
auto block_1_n1 = node1.node.produce_block();
auto block_1_n2 = node2.node.produce_block();

// this block contains the header exten/sion for the instant finality
std::optional<eosio::chain::block_header_extension> ext = block_1_n0->extract_header_extension(eosio::chain::instant_finality_extension::extension_id());
BOOST_TEST(!!ext);
std::optional<eosio::chain::finalizer_policy> fin_policy = std::get<eosio::chain::instant_finality_extension>(*ext).new_finalizer_policy;
BOOST_TEST(!!fin_policy);
BOOST_TEST(fin_policy->finalizers.size() == 3);
BOOST_TEST(fin_policy->generation == 1);

produce_and_push_block(); // make setfinalizer irreversible

// form a 3-chain to make LIB advacing on node0
// node0's vote (internal voting) and node1's vote make the quorum
for (auto i = 0; i < 3; ++i) {
Expand All @@ -46,6 +62,7 @@ finality_test_cluster::finality_test_cluster() {
n.votes.clear();
n.prev_lib_num = n.node.control->if_irreversible_block_num();
}

}

eosio::chain::vote_status finality_test_cluster::wait_on_vote(uint32_t connection_id, bool duplicate) {
Expand All @@ -61,13 +78,14 @@ eosio::chain::vote_status finality_test_cluster::wait_on_vote(uint32_t connectio
FC_ASSERT(false, "Duplicate should not have been signaled");
}
return duplicate ? eosio::chain::vote_status::duplicate : last_vote_status.load();
}
}

// node0 produces a block and pushes it to node1 and node2
void finality_test_cluster::produce_and_push_block() {
eosio::chain::signed_block_ptr finality_test_cluster::produce_and_push_block() {
auto b = node0.node.produce_block();
node1.node.push_block(b);
node2.node.push_block(b);
return b;
}

// send node1's vote identified by "vote_index" in the collected votes
Expand Down Expand Up @@ -128,6 +146,13 @@ bool finality_test_cluster::produce_blocks_and_verify_lib_advancing() {
return true;
}

void finality_test_cluster::produce_blocks(uint32_t blocks_count) {
for (uint32_t i = 0; i < blocks_count; ++i) {
produce_and_push_block();
process_node1_vote();
}
}

void finality_test_cluster::node1_corrupt_vote_block_id() {
std::lock_guard g(node1.votes_mtx);
node1_orig_vote = node1.votes[0];
Expand Down Expand Up @@ -194,15 +219,6 @@ void finality_test_cluster::setup_node(node_info& node, eosio::chain::account_na
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
std::optional<eosio::chain::block_header_extension> ext = block->extract_header_extension(eosio::chain::instant_finality_extension::extension_id());
BOOST_TEST(!!ext);
std::optional<eosio::chain::finalizer_policy> fin_policy = std::get<eosio::chain::instant_finality_extension>(*ext).new_finalizer_policy;
BOOST_TEST(!!fin_policy);
BOOST_TEST(fin_policy->finalizers.size() == 3);
BOOST_TEST(fin_policy->generation == 1);
}

// send a vote to node0
Expand Down Expand Up @@ -235,4 +251,4 @@ eosio::chain::vote_status finality_test_cluster::process_vote(node_info& node, v
vote_index = node.votes.size() - 1;
g.unlock();
return process_vote( node, vote_index, mode );
}
}
37 changes: 22 additions & 15 deletions unittests/finality_test_cluster.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

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

Expand Down Expand Up @@ -29,11 +30,22 @@ class finality_test_cluster {
weak,
};

struct node_info {
eosio::testing::tester node;
uint32_t prev_lib_num{0};
std::mutex votes_mtx;
std::vector<eosio::chain::vote_message_ptr> votes;
fc::crypto::blslib::bls_private_key priv_key;
};

// Construct a test network and activate IF.
finality_test_cluster();

// node0 produces a block and pushes it to node1 and node2
void produce_and_push_block();
eosio::chain::signed_block_ptr produce_and_push_block();

// make setfinalizer final and test finality
void initial_tests();

// send node1's vote identified by "index" in the collected votes
eosio::chain::vote_status process_node1_vote(uint32_t vote_index, vote_mode mode = vote_mode::strong, bool duplicate = false);
Expand All @@ -46,7 +58,7 @@ class finality_test_cluster {

// send node2's latest vote
eosio::chain::vote_status process_node2_vote(vote_mode mode = vote_mode::strong);

// returns true if node0's LIB has advanced
bool node0_lib_advancing();

Expand All @@ -61,6 +73,9 @@ class finality_test_cluster {
// node1_votes and node2_votes when starting.
bool produce_blocks_and_verify_lib_advancing();

// Produces and propagate finality votes block_count blocks.
void produce_blocks(uint32_t blocks_count);

// Intentionally corrupt node1's vote's block_id and save the original vote
void node1_corrupt_vote_block_id();

Expand All @@ -73,24 +88,16 @@ class finality_test_cluster {
// Restore node1's original vote
void node1_restore_to_original_vote();

private:

struct node_info {
eosio::testing::tester node;
uint32_t prev_lib_num{0};
std::mutex votes_mtx;
std::vector<eosio::chain::vote_message_ptr> votes;
fc::crypto::blslib::bls_private_key priv_key;
};

std::atomic<uint32_t> last_connection_vote{0};
std::atomic<eosio::chain::vote_status> last_vote_status{};

std::array<node_info, 3> nodes;
node_info& node0 = nodes[0];
node_info& node1 = nodes[1];
node_info& node2 = nodes[2];

private:

std::atomic<uint32_t> last_connection_vote{0};
std::atomic<eosio::chain::vote_status> last_vote_status{};

eosio::chain::vote_message_ptr node1_orig_vote;

// sets up "node_index" node
Expand Down
43 changes: 31 additions & 12 deletions unittests/finality_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ BOOST_AUTO_TEST_SUITE(finality_tests)
// verify LIB advances with 2 finalizers voting.
BOOST_AUTO_TEST_CASE(two_votes) { try {
finality_test_cluster cluster;

cluster.initial_tests();

for (auto i = 0; i < 3; ++i) {
// node0 produces a block and pushes to node1 and node2
cluster.produce_and_push_block();
Expand All @@ -26,6 +27,7 @@ BOOST_AUTO_TEST_CASE(two_votes) { try {
// verify LIB does not advances with finalizers not voting.
BOOST_AUTO_TEST_CASE(no_votes) { try {
finality_test_cluster cluster;
cluster.initial_tests();

cluster.produce_and_push_block();
cluster.node0_lib_advancing(); // reset
Expand All @@ -47,7 +49,8 @@ BOOST_AUTO_TEST_CASE(no_votes) { try {
// verify LIB advances with all of the three finalizers voting
BOOST_AUTO_TEST_CASE(all_votes) { try {
finality_test_cluster cluster;

cluster.initial_tests();

cluster.produce_and_push_block();
for (auto i = 0; i < 3; ++i) {
// process node1 and node2's votes
Expand All @@ -66,7 +69,8 @@ BOOST_AUTO_TEST_CASE(all_votes) { try {
// verify LIB advances when votes conflict (strong first and followed by weak)
BOOST_AUTO_TEST_CASE(conflicting_votes_strong_first) { try {
finality_test_cluster cluster;

cluster.initial_tests();

cluster.produce_and_push_block();
for (auto i = 0; i < 3; ++i) {
cluster.process_node1_vote(); // strong
Expand All @@ -82,7 +86,8 @@ BOOST_AUTO_TEST_CASE(conflicting_votes_strong_first) { try {
// verify LIB advances when votes conflict (weak first and followed by strong)
BOOST_AUTO_TEST_CASE(conflicting_votes_weak_first) { try {
finality_test_cluster cluster;

cluster.initial_tests();

cluster.produce_and_push_block();
for (auto i = 0; i < 3; ++i) {
cluster.process_node1_vote(finality_test_cluster::vote_mode::weak); // weak
Expand All @@ -98,6 +103,7 @@ BOOST_AUTO_TEST_CASE(conflicting_votes_weak_first) { try {
// Verify a delayed vote works
BOOST_AUTO_TEST_CASE(one_delayed_votes) { try {
finality_test_cluster cluster;
cluster.initial_tests();

// hold the vote for the first block to simulate delay
cluster.produce_and_push_block();
Expand Down Expand Up @@ -131,6 +137,7 @@ BOOST_AUTO_TEST_CASE(one_delayed_votes) { try {
// Verify 3 consecutive delayed votes work
BOOST_AUTO_TEST_CASE(three_delayed_votes) { try {
finality_test_cluster cluster;
cluster.initial_tests();

// produce 4 blocks and hold the votes for the first 3 to simulate delayed votes
// The 4 blocks have the same QC claim as no QCs are created because missing one vote
Expand Down Expand Up @@ -171,7 +178,8 @@ BOOST_AUTO_TEST_CASE(three_delayed_votes) { try {

BOOST_AUTO_TEST_CASE(out_of_order_votes) { try {
finality_test_cluster cluster;

cluster.initial_tests();

// produce 3 blocks and hold the votes to simulate delayed votes
// The 3 blocks have the same QC claim as no QCs are created because missing votes
for (auto i = 0; i < 3; ++i) {
Expand Down Expand Up @@ -211,7 +219,8 @@ BOOST_AUTO_TEST_CASE(out_of_order_votes) { try {
// Verify a vote which was delayed by a large number of blocks does not cause any issues
BOOST_AUTO_TEST_CASE(long_delayed_votes) { try {
finality_test_cluster cluster;

cluster.initial_tests();

// Produce and push a block, vote on it after a long delay.
constexpr uint32_t delayed_vote_index = 0;
cluster.produce_and_push_block();
Expand Down Expand Up @@ -244,7 +253,8 @@ BOOST_AUTO_TEST_CASE(long_delayed_votes) { try {

BOOST_AUTO_TEST_CASE(lost_votes) { try {
finality_test_cluster cluster;

cluster.initial_tests();

// Produce and push a block, never vote on it to simulate lost.
// The block contains a strong QC extension for prior block
cluster.produce_and_push_block();
Expand All @@ -270,7 +280,8 @@ BOOST_AUTO_TEST_CASE(lost_votes) { try {

BOOST_AUTO_TEST_CASE(one_weak_vote) { try {
finality_test_cluster cluster;

cluster.initial_tests();

// Produce and push a block
cluster.produce_and_push_block();
// Change the vote to a weak vote and process it
Expand Down Expand Up @@ -303,6 +314,7 @@ BOOST_AUTO_TEST_CASE(one_weak_vote) { try {

BOOST_AUTO_TEST_CASE(two_weak_votes) { try {
finality_test_cluster cluster;
cluster.initial_tests();

// Produce and push a block
cluster.produce_and_push_block();
Expand Down Expand Up @@ -340,6 +352,7 @@ BOOST_AUTO_TEST_CASE(two_weak_votes) { try {

BOOST_AUTO_TEST_CASE(intertwined_weak_votes) { try {
finality_test_cluster cluster;
cluster.initial_tests();

cluster.produce_and_push_block();
BOOST_REQUIRE(cluster.node2_lib_advancing());
Expand Down Expand Up @@ -385,7 +398,8 @@ BOOST_AUTO_TEST_CASE(intertwined_weak_votes) { try {
// Verify a combination of weak, delayed, lost votes still work
BOOST_AUTO_TEST_CASE(weak_delayed_lost_vote) { try {
finality_test_cluster cluster;

cluster.initial_tests();

cluster.produce_and_push_block();
BOOST_REQUIRE(cluster.node2_lib_advancing());
BOOST_REQUIRE(cluster.node1_lib_advancing());
Expand Down Expand Up @@ -431,7 +445,8 @@ BOOST_AUTO_TEST_CASE(weak_delayed_lost_vote) { try {
// Verify a combination of delayed, weak, lost votes still work
BOOST_AUTO_TEST_CASE(delayed_strong_weak_lost_vote) { try {
finality_test_cluster cluster;

cluster.initial_tests();

// A delayed vote (index 0)
constexpr uint32_t delayed_index = 0;
cluster.produce_and_push_block();
Expand Down Expand Up @@ -478,7 +493,8 @@ BOOST_AUTO_TEST_CASE(delayed_strong_weak_lost_vote) { try {
// verify duplicate votes do not affect LIB advancing
BOOST_AUTO_TEST_CASE(duplicate_votes) { try {
finality_test_cluster cluster;

cluster.initial_tests();

cluster.produce_and_push_block();
for (auto i = 0; i < 5; ++i) {
cluster.process_node1_vote(i, finality_test_cluster::vote_mode::strong);
Expand All @@ -495,6 +511,7 @@ BOOST_AUTO_TEST_CASE(duplicate_votes) { try {
// verify unknown_proposal votes are handled properly
BOOST_AUTO_TEST_CASE(unknown_proposal_votes) { try {
finality_test_cluster cluster;
cluster.initial_tests();

// node0 produces a block and pushes to node1
cluster.produce_and_push_block();
Expand All @@ -519,6 +536,7 @@ BOOST_AUTO_TEST_CASE(unknown_proposal_votes) { try {
// verify unknown finalizer_key votes are handled properly
BOOST_AUTO_TEST_CASE(unknown_finalizer_key_votes) { try {
finality_test_cluster cluster;
cluster.initial_tests();

// node0 produces a block and pushes to node1
cluster.produce_and_push_block();
Expand All @@ -542,7 +560,8 @@ BOOST_AUTO_TEST_CASE(unknown_finalizer_key_votes) { try {
// verify corrupted signature votes are handled properly
BOOST_AUTO_TEST_CASE(corrupted_signature_votes) { try {
finality_test_cluster cluster;

cluster.initial_tests();

// node0 produces a block and pushes to node1
cluster.produce_and_push_block();

Expand Down
Loading
Loading