diff --git a/unittests/finality_proof.hpp b/unittests/finality_proof.hpp index 21f854204b..519085ecf5 100644 --- a/unittests/finality_proof.hpp +++ b/unittests/finality_proof.hpp @@ -28,6 +28,7 @@ namespace finality_proof { digest_type level_2_commitments_digest; digest_type finality_leaf; digest_type finality_root; + block_timestamp_type parent_timestamp; }; static digest_type hash_pair(const digest_type& a, const digest_type& b) { @@ -140,6 +141,9 @@ namespace finality_proof { finalizer_policy active_finalizer_policy; digest_type active_finalizer_policy_digest; + block_timestamp_type timestamp; + block_timestamp_type parent_timestamp; + // counter to (optimistically) track internal policy changes std::unordered_map blocks_since_proposed_policy; @@ -168,14 +172,17 @@ namespace finality_proof { //skip this part on genesis if (!is_genesis){ + parent_timestamp = timestamp; for (const auto& p : blocks_since_proposed_policy){ - //under the happy path with strong QCs in every block, a policy becomes active `2 * eosio::testing::num_chains_to_final` blocks after being proposed - if (p.second.blocks_since_proposed == 2 * eosio::testing::num_chains_to_final){ + + //under the happy path with strong QCs in every block, a policy becomes active 4 blocks after being proposed + if (p.second.blocks_since_proposed == 2 * eosio::testing::num_chains_to_final && p.first != active_finalizer_policy_digest){ active_finalizer_policy = p.second.policy; active_finalizer_policy_digest = p.first; } - //under the happy path with strong QCs in every block, a policy becomes pending `num_chains_to_final` blocks after being proposed - else if (p.second.blocks_since_proposed == eosio::testing::num_chains_to_final){ + //under the happy path with strong QCs in every block, a policy becomes pending 2 blocks after being proposed + else if (p.second.blocks_since_proposed == eosio::testing::num_chains_to_final && p.first != last_pending_finalizer_policy_digest){ + last_pending_finalizer_policy = p.second.policy; last_pending_finalizer_policy_digest = p.first; last_pending_finalizer_policy_start_num = block->block_num(); @@ -183,6 +190,8 @@ namespace finality_proof { } } + timestamp = block->timestamp; + // if we have policy diffs, process them if (has_finalizer_policy_diffs(block)){ if (is_genesis) { @@ -203,8 +212,6 @@ namespace finality_proof { } } - ilog("block num : ${bn} : lpfp_sn -> ${sn}", ("bn", block->block_num())("sn", last_pending_finalizer_policy_start_num)); - //process votes and collect / compute the IBC-relevant data this->process_votes(1, this->num_needed_for_quorum); //enough to reach quorum threshold @@ -242,6 +249,8 @@ namespace finality_proof { // compute finality leaf digest_type finality_leaf = fc::sha256::hash(valid_t::finality_leaf_node_t{ .block_num = block->block_num(), + .timestamp = timestamp, + .parent_timestamp = parent_timestamp, .finality_digest = finality_digest, .action_mroot = action_mroot }); @@ -273,7 +282,8 @@ namespace finality_proof { .level_3_commitments_digest = level_3_commitments_digest, .level_2_commitments_digest = level_2_commitments_digest, .finality_leaf = finality_leaf, - .finality_root = finality_root + .finality_root = finality_root , + .parent_timestamp = parent_timestamp }; } @@ -302,4 +312,4 @@ namespace finality_proof { }; -} +} \ No newline at end of file diff --git a/unittests/svnn_ibc_tests.cpp b/unittests/svnn_ibc_tests.cpp index 9c0cf94053..808f788c56 100644 --- a/unittests/svnn_ibc_tests.cpp +++ b/unittests/svnn_ibc_tests.cpp @@ -18,7 +18,6 @@ using namespace eosio::testing; using mvo = mutable_variant_object; - std::string bitset_to_input_string(const boost::dynamic_bitset& bitset) { static const char* hexchar = "0123456789abcdef"; @@ -54,9 +53,6 @@ auto active_finalizers_string = [](const finality_proof::ibc_block_data_t& bd) BOOST_AUTO_TEST_SUITE(svnn_ibc) -BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_test -#if 0 // TODO re-enabled - BOOST_AUTO_TEST_CASE(ibc_test) { try { // cluster is set up with the head about to produce IF Genesis @@ -106,7 +102,11 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t BOOST_TEST(block_6_result.qc_data.qc.has_value()); // create a few proofs we'll use to perform tests - // heavy proof #1. Proving finality of block #2 using block #2 finality root + + // heavy proof #1. Proving finality of block #2 using block #2 finality root. + + // Under 2-chains finality, a QC over block #2 (delivered by block #3) and a strong QC on block #3 + // (delivered by block #4) constitutes a valid 2-chains and results in #2 becoming final. mutable_variant_object heavy_proof_1 = mvo() ("proof", mvo() ("finality_proof", mvo() //proves finality of block #2 @@ -119,8 +119,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("finality_mroot", block_3_result.finality_root) ) ("qc", mvo() - ("signature", block_5_result.qc_data.qc.value().active_policy_sig.sig.to_string()) - ("finalizers", active_finalizers_string(block_5_result)) + ("signature", block_4_result.qc_data.qc.value().active_policy_sig.sig.to_string()) + ("finalizers", active_finalizers_string(block_4_result)) ) ) ("target_block_proof_of_inclusion", mvo() @@ -135,6 +135,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("witness_hash", block_2_result.level_2_commitments_digest) ("finality_mroot", block_2_result.finality_root) ) + ("timestamp", block_2_result.block->timestamp) + ("parent_timestamp", block_2_result.parent_timestamp) ("dynamic_data", mvo() ("block_num", block_2_result.block->block_num()) ("action_proofs", fc::variants()) @@ -158,8 +160,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("finality_mroot", block_3_result.finality_root) ) ("qc", mvo() - ("signature", block_5_result.qc_data.qc.value().active_policy_sig.sig.to_string()) - ("finalizers", active_finalizers_string(block_5_result)) + ("signature", block_4_result.qc_data.qc.value().active_policy_sig.sig.to_string()) + ("finalizers", active_finalizers_string(block_4_result)) ) ) ("target_block_proof_of_inclusion", mvo() @@ -169,6 +171,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("major_version", 1) ("minor_version", 0) ("finality_digest", block_2_result.finality_digest) + ("timestamp", block_2_result.block->timestamp) + ("parent_timestamp", block_2_result.parent_timestamp) ("dynamic_data", mvo() ("block_num", block_2_result.block->block_num()) ("action_proofs", fc::variants()) @@ -192,8 +196,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("finality_mroot", block_4_result.finality_root) ) ("qc", mvo() - ("signature", block_6_result.qc_data.qc.value().active_policy_sig.sig.to_string()) - ("finalizers", active_finalizers_string(block_6_result)) + ("signature", block_5_result.qc_data.qc.value().active_policy_sig.sig.to_string()) + ("finalizers", active_finalizers_string(block_5_result)) ) ) ("target_block_proof_of_inclusion", mvo() @@ -208,6 +212,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("witness_hash", block_2_result.level_2_commitments_digest) ("finality_mroot", block_2_result.finality_root) ) + ("timestamp", block_2_result.block->timestamp) + ("parent_timestamp", block_2_result.parent_timestamp) ("dynamic_data", mvo() ("block_num", block_2_result.block->block_num()) ("action_proofs", fc::variants()) @@ -233,6 +239,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("witness_hash", block_2_result.level_2_commitments_digest) ("finality_mroot", block_2_result.finality_root) ) + ("timestamp", block_2_result.block->timestamp) + ("parent_timestamp", block_2_result.parent_timestamp) ("dynamic_data", mvo() ("block_num", block_2_result.block->block_num()) ("action_proofs", fc::variants()) @@ -284,9 +292,9 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t // take note of policy digest prior to changes digest_type previous_policy_digest = cluster.active_finalizer_policy_digest; - // at this stage, we can test the change in pending policy. + // At this stage, we can prepare to test the change of pending policy. - // we first take a note of the pending policy. When we get a QC on block #9, the pending policy will update. + // We first take a note of the pending policy. When we get a QC on block #9, the pending policy will update. digest_type pending_policy_digest = cluster.last_pending_finalizer_policy_digest; // change the finalizer policy by rotating the key of node0 @@ -295,25 +303,30 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t // produce a new block. This block contains a new proposed finalizer policy auto block_8_result = cluster.produce_block(); + // verify we have a QC + BOOST_TEST(block_8_result.qc_data.qc.has_value()); + // verify the block header contains the proposed finalizer policy differences BOOST_TEST(finality_proof::has_finalizer_policy_diffs(block_8_result.block)); // advance finality auto block_9_result = cluster.produce_block(); + // verify we have a QC + BOOST_TEST(block_9_result.qc_data.qc.has_value()); + // pending policy is still the same BOOST_TEST(pending_policy_digest==cluster.last_pending_finalizer_policy_digest); // QC on #9 included in #10 makes #8 final, proposed policy is now pending auto block_10_result = cluster.produce_block(); - // verify that the last pending policy has been updated - BOOST_TEST(pending_policy_digest!=cluster.last_pending_finalizer_policy_digest); - - // verify we have all the QCs up to this point - BOOST_TEST(block_8_result.qc_data.qc.has_value()); - BOOST_TEST(block_9_result.qc_data.qc.has_value()); + // verify we have a QC BOOST_TEST(block_10_result.qc_data.qc.has_value()); + BOOST_TEST(!block_10_result.qc_data.qc.value().pending_policy_sig.has_value()); //verify this block requires a single QC + + // Verify that the last pending policy has been updated + BOOST_TEST(pending_policy_digest!=cluster.last_pending_finalizer_policy_digest); // At this stage, we can prove the inclusion of actions into block #7. @@ -387,8 +400,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("finality_mroot", block_8_result.finality_root) ) ("qc", mvo() - ("signature", block_10_result.qc_data.qc.value().active_policy_sig.sig.to_string()) - ("finalizers", active_finalizers_string(block_10_result)) + ("signature", block_9_result.qc_data.qc.value().active_policy_sig.sig.to_string()) + ("finalizers", active_finalizers_string(block_9_result)) ) ) ("target_block_proof_of_inclusion", mvo() @@ -403,6 +416,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("witness_hash", block_7_result.level_2_commitments_digest) ("finality_mroot", block_7_result.finality_root) ) + ("timestamp", block_7_result.block->timestamp) + ("parent_timestamp", block_7_result.parent_timestamp) ("dynamic_data", mvo() ("block_num", block_7_result.block->block_num()) ("action_proofs", fc::variants({onblock_action_proof})) @@ -427,6 +442,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("witness_hash", block_7_result.level_2_commitments_digest) ("finality_mroot", block_7_result.finality_root) ) + ("timestamp", block_7_result.block->timestamp) + ("parent_timestamp", block_7_result.parent_timestamp) ("dynamic_data", mvo() ("block_num", block_7_result.block->block_num()) ("action_proofs", fc::variants({action_proof_1, action_proof_2})) @@ -440,47 +457,22 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t action_trace check_action_heavy_proof_trace = cluster.node0.push_action("ibc"_n, "checkproof"_n, "ibc"_n, action_heavy_proof)->action_traces[0]; action_trace check_action_light_proof_trace = cluster.node0.push_action("ibc"_n, "checkproof"_n, "ibc"_n, action_light_proof)->action_traces[0]; - - // At this stage, we can test the change in pending policy. - - // We first take a note of the pending policy. When we get a QC on block #10, the pending policy will update. - digest_type pending_policy_digest = cluster.last_pending_finalizer_policy_digest; - - // still the same - BOOST_TEST(pending_policy_digest==cluster.last_pending_finalizer_policy_digest); - - // QC on #10 included in #11 makes #8 final, proposed policy is now pending - auto block_11_result = cluster.produce_block(); - - BOOST_TEST(!block_11_result.qc_data.qc.value().pending_policy_sig.has_value()); - - // verify that the last pending policy has been updated - BOOST_TEST(pending_policy_digest!=cluster.last_pending_finalizer_policy_digest); - - auto block_12_result = cluster.produce_block(); - - // block #12 contains our first joint policies QCs - BOOST_TEST(block_12_result.qc_data.qc.value().pending_policy_sig.has_value()); - - auto block_13_result = cluster.produce_block(); //new policy takes effect on next block - - BOOST_TEST(block_13_result.qc_data.qc.value().pending_policy_sig.has_value()); - - //verify that the current finalizer policy is still in force up to this point - BOOST_TEST(previous_policy_digest==cluster.active_finalizer_policy_digest); - auto block_14_result = cluster.produce_block(); + auto block_11_result = cluster.produce_block(); // last pending policy (proposed in #8) takes effect and becomes active on next block + BOOST_TEST(block_11_result.qc_data.qc.value().pending_policy_sig.has_value()); //this block requires joint policies QCs - BOOST_TEST(block_14_result.qc_data.qc.value().pending_policy_sig.has_value()); + auto block_12_result = cluster.produce_block(); + BOOST_TEST(block_12_result.qc_data.qc.value().pending_policy_sig.has_value()); //this block requires joint policies QCs //verify that the new finalizer policy is now in force BOOST_TEST(previous_policy_digest!=cluster.active_finalizer_policy_digest); - auto block_13_result = cluster.produce_block(); + auto block_13_result = cluster.produce_block(); + BOOST_TEST(!block_13_result.qc_data.qc.value().pending_policy_sig.has_value()); //verify this block requires a single QC + auto block_14_result = cluster.produce_block(); - auto block_15_result = cluster.produce_block(); - BOOST_TEST(!block_15_result.qc_data.qc.value().pending_policy_sig.has_value()); + auto block_15_result = cluster.produce_block(); auto block_16_result = cluster.produce_block(); auto block_17_result = cluster.produce_block(); @@ -516,8 +508,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("finality_mroot", block_11_result.finality_root) ) ("qc", mvo() - ("signature", block_14_result.qc_data.qc.value().active_policy_sig.sig.to_string()) - ("finalizers", active_finalizers_string(block_14_result)) + ("signature", block_12_result.qc_data.qc.value().active_policy_sig.sig.to_string()) + ("finalizers", active_finalizers_string(block_12_result)) ) ) ("target_block_proof_of_inclusion", mvo() @@ -528,13 +520,15 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("major_version", 1) ("minor_version", 0) ("finalizer_policy_generation", 1) - ("last_pending_finalizer_policy_start_num", block_11_result.block->block_num()) ("final_on_strong_qc_block_num", 13) ("new_finalizer_policy", cluster.last_pending_finalizer_policy) ("witness_hash", block_10_result.base_digest) ("reversible_blocks_mroot", block_10_result.finality_data.reversible_blocks_mroot) + ("last_pending_finalizer_policy_start_num", block_10_result.last_pending_finalizer_policy_start_num ) ("finality_mroot", block_10_result.finality_root) ) + ("timestamp", block_10_result.block->timestamp) + ("parent_timestamp", block_10_result.parent_timestamp) ("dynamic_data", mvo() ("block_num", block_10_result.block->block_num()) ("action_proofs", fc::variants()) @@ -565,8 +559,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("finality_mroot", block_12_result.finality_root) ) ("qc", mvo() - ("signature", block_15_result.qc_data.qc.value().active_policy_sig.sig.to_string()) - ("finalizers", active_finalizers_string(block_15_result)) + ("signature", block_13_result.qc_data.qc.value().active_policy_sig.sig.to_string()) + ("finalizers", active_finalizers_string(block_13_result)) ) ) ("target_block_proof_of_inclusion", mvo() @@ -581,6 +575,8 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ("witness_hash", block_11_result.level_2_commitments_digest) ("finality_mroot", block_11_result.finality_root) ) + ("timestamp", block_11_result.block->timestamp) + ("parent_timestamp", block_11_result.parent_timestamp) ("dynamic_data", mvo() ("block_num", block_11_result.block->block_num()) ("action_proofs", fc::variants()) @@ -684,5 +680,5 @@ BOOST_AUTO_TEST_CASE(ibc_test) {} // TODO remove this and re-enable actual ibc_t ); } FC_LOG_AND_RETHROW() } -#endif // TODO re-enable + BOOST_AUTO_TEST_SUITE_END() diff --git a/unittests/test-contracts/savanna/common/savanna.hpp b/unittests/test-contracts/savanna/common/savanna.hpp index a3a754a4a3..46cf9ce0d3 100644 --- a/unittests/test-contracts/savanna/common/savanna.hpp +++ b/unittests/test-contracts/savanna/common/savanna.hpp @@ -365,8 +365,8 @@ namespace savanna { //finality data block_finality_data finality_data; - time_point timestamp; - time_point parent_timestamp; + block_timestamp timestamp; + block_timestamp parent_timestamp; //dynamic_data to be verified dynamic_data_v0 dynamic_data; @@ -376,8 +376,8 @@ namespace savanna { checksum256 resolved_finality_digest; checksum256 resolved_action_mroot; - time_point resolved_timestamp; - time_point resolved_parent_timestamp; + block_timestamp resolved_timestamp; + block_timestamp resolved_parent_timestamp; extended_block_data_internal(const extended_block_data& base) : extended_block_data(base){ @@ -402,8 +402,8 @@ namespace savanna { uint32_t major_version = 0 ; uint32_t minor_version = 0 ; - time_point timestamp; - time_point parent_timestamp; + block_timestamp timestamp; + block_timestamp parent_timestamp; checksum256 finality_digest; @@ -414,8 +414,8 @@ namespace savanna { struct simple_block_data_internal : simple_block_data { checksum256 resolved_action_mroot; - time_point resolved_timestamp; - time_point resolved_parent_timestamp; + block_timestamp resolved_timestamp; + block_timestamp resolved_parent_timestamp; simple_block_data_internal(const simple_block_data& base) : simple_block_data(base){ diff --git a/unittests/test-contracts/savanna/ibc/ibc.abi b/unittests/test-contracts/savanna/ibc/ibc.abi index 98f90e1974..f10ef45593 100644 --- a/unittests/test-contracts/savanna/ibc/ibc.abi +++ b/unittests/test-contracts/savanna/ibc/ibc.abi @@ -186,11 +186,11 @@ }, { "name": "timestamp", - "type": "time_point" + "type": "block_timestamp_type" }, { "name": "parent_timestamp", - "type": "time_point" + "type": "block_timestamp_type" }, { "name": "dynamic_data", @@ -336,11 +336,11 @@ }, { "name": "timestamp", - "type": "time_point" + "type": "block_timestamp_type" }, { "name": "parent_timestamp", - "type": "time_point" + "type": "block_timestamp_type" }, { "name": "finality_digest", diff --git a/unittests/test-contracts/savanna/ibc/ibc.wasm b/unittests/test-contracts/savanna/ibc/ibc.wasm index deff49ee1d..8e14eafc1e 100755 Binary files a/unittests/test-contracts/savanna/ibc/ibc.wasm and b/unittests/test-contracts/savanna/ibc/ibc.wasm differ