-
Notifications
You must be signed in to change notification settings - Fork 26
[1.0.4] Finality violation tests 1.0.0 #610
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
base: release/1.0
Are you sure you want to change the base?
Changes from 18 commits
686986e
b345e76
920d7aa
0f83dea
2eff199
38ccb3b
cbcbc27
a686f00
a82435a
e295f9d
bca8c83
84f6c08
3fc7806
5a26775
90f5f45
e7d3263
9e90bbf
484c229
4da02e7
5acaae2
7ea485e
1be2257
891207d
19d1b5d
2f5a557
67440e4
3559929
ec68dd5
0ff0c8d
a99e673
772eeb2
792462d
00820b2
ead0837
f408f9f
81bf80b
18deabb
9c47427
26e809b
b1761b2
e1c8e41
19e5591
411adc2
a62ab3f
fa81154
264a2b9
b10e275
17355c8
14f8873
b223247
e92e125
52436cf
891296e
f07308f
1e1f0e4
d1a4ee9
d48f25c
5e0953e
9bdddce
513c350
d715a31
e85e5f8
243c11d
8d8d4ba
4946954
68c2c1d
bae1c27
6c253f5
1b7fb4f
eca9352
b4b47f8
1b743a3
18d1882
2ba9e04
cc20819
ad56709
2d9202f
fce30e8
20090c6
c7ade59
c8fd55f
955aa87
241af18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -359,4 +359,4 @@ namespace finality_proof { | |
|
|
||
| }; | ||
|
|
||
| } | ||
| } | ||
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -86,7 +86,7 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
| ) | ||
| ("active_policy_qc", mvo() | ||
| ("signature", block_4_result.qc_data.qc.value().active_policy_sig.sig.to_string()) | ||
| ("finalizers", finality_proof::finalizers_string(block_4_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ("strong_votes", finality_proof::finalizers_string(block_4_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ) | ||
| ) | ||
| ("target_block_proof_of_inclusion", mvo() | ||
|
|
@@ -125,7 +125,7 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
| ) | ||
| ("active_policy_qc", mvo() | ||
| ("signature", block_4_result.qc_data.qc.value().active_policy_sig.sig.to_string()) | ||
| ("finalizers", finality_proof::finalizers_string(block_4_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ("strong_votes", finality_proof::finalizers_string(block_4_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ) | ||
| ) | ||
| ("target_block_proof_of_inclusion", mvo() | ||
|
|
@@ -160,7 +160,7 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
| ) | ||
| ("active_policy_qc", mvo() | ||
| ("signature", block_5_result.qc_data.qc.value().active_policy_sig.sig.to_string()) | ||
| ("finalizers", finality_proof::finalizers_string(block_5_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ("strong_votes", finality_proof::finalizers_string(block_5_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ) | ||
| ) | ||
| ("target_block_proof_of_inclusion", mvo() | ||
|
|
@@ -294,8 +294,8 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
|
|
||
| // onblock action proof | ||
| mutable_variant_object onblock_action_proof = mvo() | ||
| ("target_block_index", 0) | ||
| ("final_block_index", 3) | ||
| ("target_action_index", 0) | ||
| ("final_action_index", 3) | ||
| ("target", mvo() | ||
| ("action", mvo() | ||
| ("account", block_7_result.onblock_trace.act.account) | ||
|
|
@@ -313,8 +313,8 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
|
|
||
| // first action proof (check_heavy_proof_1) | ||
| mutable_variant_object action_proof_1 = mvo() | ||
| ("target_block_index", 1) | ||
| ("final_block_index", 3) | ||
| ("target_action_index", 1) | ||
| ("final_action_index", 3) | ||
| ("target", mvo() | ||
| ("action", mvo() | ||
| ("account", check_heavy_proof_1_trace.act.account) | ||
|
|
@@ -331,8 +331,8 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
|
|
||
| // second action proof (check_light_proof_1) | ||
| mutable_variant_object action_proof_2 = mvo() | ||
| ("target_block_index", 2) | ||
| ("final_block_index", 3) | ||
| ("target_action_index", 2) | ||
| ("final_action_index", 3) | ||
| ("target", mvo() | ||
| ("action", mvo() | ||
| ("account", check_light_proof_1_trace.act.account) | ||
|
|
@@ -360,7 +360,7 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
| ) | ||
| ("active_policy_qc", mvo() | ||
| ("signature", block_9_result.qc_data.qc.value().active_policy_sig.sig.to_string()) | ||
| ("finalizers", finality_proof::finalizers_string(block_9_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ("strong_votes", finality_proof::finalizers_string(block_9_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ) | ||
| ) | ||
| ("target_block_proof_of_inclusion", mvo() | ||
|
|
@@ -462,7 +462,7 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
| ) | ||
| ("active_policy_qc", mvo() | ||
| ("signature", block_11_result.qc_data.qc.value().active_policy_sig.sig.to_string()) | ||
| ("finalizers", finality_proof::finalizers_string(block_11_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ("strong_votes", finality_proof::finalizers_string(block_11_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ) | ||
| ) | ||
| ("target_block_proof_of_inclusion", mvo() | ||
|
|
@@ -521,11 +521,11 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
| ) | ||
| ("active_policy_qc", mvo() | ||
| ("signature", block_12_result.qc_data.qc.value().active_policy_sig.sig.to_string()) | ||
| ("finalizers", finality_proof::finalizers_string(block_12_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ("strong_votes", finality_proof::finalizers_string(block_12_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ) | ||
| ("pending_policy_qc", mvo() | ||
| ("signature", block_12_result.qc_data.qc.value().pending_policy_sig.value().sig.to_string()) | ||
| ("finalizers", finality_proof::finalizers_string(block_12_result.qc_data.qc.value().pending_policy_sig.value().strong_votes.value())) | ||
| ("strong_votes", finality_proof::finalizers_string(block_12_result.qc_data.qc.value().pending_policy_sig.value().strong_votes.value())) | ||
| ) | ||
| ) | ||
| ("target_block_proof_of_inclusion", mvo() | ||
|
|
@@ -574,7 +574,7 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
| ) | ||
| ("active_policy_qc", mvo() | ||
| ("signature", block_13_result.qc_data.qc.value().active_policy_sig.sig.to_string()) | ||
| ("finalizers", finality_proof::finalizers_string(block_13_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ("strong_votes", finality_proof::finalizers_string(block_13_result.qc_data.qc.value().active_policy_sig.strong_votes.value())) | ||
| ) | ||
| ) | ||
| ("target_block_proof_of_inclusion", mvo() | ||
|
|
@@ -666,43 +666,43 @@ BOOST_AUTO_TEST_SUITE(svnn_ibc) | |
| ); | ||
|
|
||
| chain.push_action("ibc"_n, "testbitset"_n, "ibc"_n, mvo() | ||
| ("bitset_string", "30") //bitset bytes are reversed, so we do the same to test | ||
| ("bitset_string", "03") | ||
| ("bitset_vector", bitset_2) | ||
| ("finalizers_count", 3) | ||
| ); | ||
|
|
||
| chain.push_action("ibc"_n, "testbitset"_n, "ibc"_n, mvo() | ||
| ("bitset_string", "ae00") | ||
| ("bitset_string", "00ea") | ||
| ("bitset_vector", bitset_3) | ||
| ("finalizers_count", 11) | ||
| ); | ||
|
|
||
| chain.push_action("ibc"_n, "testbitset"_n, "ibc"_n, mvo() | ||
| ("bitset_string", "1263") | ||
| ("bitset_string", "3621") | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As another example, I would expect this hex string to be |
||
| ("bitset_vector", bitset_4) | ||
| ("finalizers_count", 14) | ||
| ); | ||
|
|
||
| chain.push_action("ibc"_n, "testbitset"_n, "ibc"_n, mvo() | ||
| ("bitset_string", "fffff1") | ||
| ("bitset_string", "1fffff") | ||
| ("bitset_vector", bitset_5) | ||
| ("finalizers_count", 21) | ||
| ); | ||
|
|
||
| chain.push_action("ibc"_n, "testbitset"_n, "ibc"_n, mvo() | ||
| ("bitset_string", "fff700") | ||
| ("bitset_string", "007fff") | ||
| ("bitset_vector", bitset_6) | ||
| ("finalizers_count", 21) | ||
| ); | ||
|
|
||
| chain.push_action("ibc"_n, "testbitset"_n, "ibc"_n, mvo() | ||
| ("bitset_string", "30") | ||
| ("bitset_string", "03") | ||
| ("bitset_vector", bitset_7) | ||
| ("finalizers_count", 4) | ||
| ); | ||
|
|
||
| chain.push_action("ibc"_n, "testbitset"_n, "ibc"_n, mvo() | ||
| ("bitset_string", "c0") | ||
| ("bitset_string", "0c") | ||
| ("bitset_vector", bitset_8) | ||
| ("finalizers_count", 4) | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -22,12 +22,18 @@ namespace savanna { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return std::string(res.begin(), res.end()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| inline std::string create_strong_digest(const checksum256& digest){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::array<uint8_t, 32> fd_data = digest.extract_as_byte_array(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return std::string(fd_data.begin(), fd_data.end()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| struct quorum_certificate_input { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //representation of a bitset, where each bit represents the ordinal finalizer position according to canonical sorting rules of the finalizer policy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::vector<uint8_t> finalizers; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //string representation of a BLS signature | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::string signature; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::optional<bool> is_weak; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //representation of optional strong and weak bitsets, where each bit represents the ordinal finalizer position according to canonical sorting rules of the finalizer policy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::optional<std::vector<uint8_t>> strong_votes; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::optional<std::vector<uint8_t>> weak_votes; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //string representation of a BLS signature | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::string signature; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| struct finalizer_authority_internal { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -120,7 +126,8 @@ namespace savanna { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 _compute_root(const std::vector<checksum256>& proof_nodes, const checksum256& target, const uint64_t target_block_index, const uint64_t final_block_index){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 hash = target; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::vector<bool> proof_path = _get_proof_path(target_block_index, final_block_index+1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check(proof_path.size() == proof_nodes.size(), "internal error"); //should not happen | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check(proof_path.size() == proof_nodes.size(), "proof path size and proof nodes size mismatch"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (int i = 0 ; i < proof_nodes.size() ; i++){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const checksum256 node = proof_nodes[i]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| hash = hash_pair(proof_path[i] ? std::make_pair(node, hash) : std::make_pair(hash, node)); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -134,54 +141,112 @@ namespace savanna { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bls_g1_add(op1, op2, r); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return r; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void check_duplicate_votes(const savanna::bitset& strong_votes, const savanna::bitset& weak_votes, const finalizer_policy_input& finalizer_policy){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto fa_itr = finalizer_policy.finalizers.begin(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto fa_end_itr = finalizer_policy.finalizers.end(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| size_t index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while (fa_itr != fa_end_itr){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool voted_strong = strong_votes.test(index); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool voted_weak = weak_votes.test(index); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check (!(voted_strong && voted_weak), "conflicting finalizer votes detected in QC"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| index++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fa_itr++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // verify signature | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool _verify(const std::string& public_key, const std::string& signature, const std::string& message){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return bls_signature_verify(decode_bls_public_key_to_g1(public_key), decode_bls_signature_to_g2(signature), message); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //verify that the quorum certificate over the finality digest is valid | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void _check_qc(const quorum_certificate_input& qc, const checksum256& finality_digest, const finalizer_policy_input& finalizer_policy){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t aggregate_keys(const savanna::bitset& votes, const finalizer_policy_input& finalizer_policy, bls_g1& agg_pub_key){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be better to return a pair of the aggregate key and the total weight. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto fa_itr = finalizer_policy.finalizers.begin(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto fa_end_itr = finalizer_policy.finalizers.end(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| size_t finalizer_count = finalizer_policy.finalizers.size(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| savanna::bitset b(finalizer_count, qc.finalizers); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool first = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| size_t index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t weight = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bls_g1 agg_pub_key; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while (fa_itr != fa_end_itr){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (b.test(index)){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bls_g1 pub_key = decode_bls_public_key_to_g1(fa_itr->public_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (first){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| first=false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| agg_pub_key = pub_key; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else agg_pub_key = _g1add(agg_pub_key, pub_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| weight+=fa_itr->weight; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| index++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fa_itr++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (votes.test(index)){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bls_g1 pub_key = decode_bls_public_key_to_g1(fa_itr->public_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (first){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| first=false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| agg_pub_key = pub_key; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else agg_pub_key = _g1add(agg_pub_key, pub_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| weight+=fa_itr->weight; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| index++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| fa_itr++; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //verify that we have enough vote weight to meet the quorum threshold of the target policy | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check(weight>=finalizer_policy.threshold, "insufficient signatures to reach quorum"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return weight; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void _verify(const std::vector<std::string>& messages, const std::vector<bls_g1>& agg_pub_keys, const std::string& agg_sig){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::string message; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check(messages.size() == agg_pub_keys.size(), "messages vector and pub key vectors must be of the same size"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (qc.is_weak.has_value() && qc.is_weak.value() == true) message = create_weak_digest(finality_digest); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (size_t i = 0 ; i < messages.size(); i++){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //verify signature validity | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check(bls_signature_verify(agg_pub_keys[i], decode_bls_signature_to_g2(agg_sig), messages[i]), "signature verification failed"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This doesn't make sense as a way to check the aggregate signature. See how Spring does it. Lines 205 to 208 in d89dc9f
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //verify that the quorum certificate over the finality digest is valid | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void _check_qc(const quorum_certificate_input& qc, const checksum256& finality_digest, const finalizer_policy_input& finalizer_policy, const bool count_strong_only, const bool enforce_threshold_check){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check(qc.strong_votes.has_value() || qc.weak_votes.has_value(), "quorum certificate must have at least one bitset"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| size_t finalizer_count = finalizer_policy.finalizers.size(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t weight = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (count_strong_only){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bls_g1 agg_pub_key; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check(qc.strong_votes.has_value(), "required strong votes are missing"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| savanna::bitset strong_b(finalizer_count, qc.strong_votes.value()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| weight = aggregate_keys(strong_b, finalizer_policy, agg_pub_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _verify({create_strong_digest(finality_digest)}, {agg_pub_key}, qc.signature); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This only works if the weak bitset is empty. If it is not empty, then the QC signature would be an aggregate signature formed from the aggregate public key of the strong votes (calculated here) corresponding to the strong digest AND the aggregate public key to the weak votes corresponding to the weak digest. I think Spring will never bother generating a QC with mixed strong and weak votes when the strong votes are sufficient to meet the threshold. But as far as the protocol is concerned, if weak votes are present, the QC is treated as a weak QC and the aggregate signature must incorporate the effect of those weak votes. I think these contracts should not necessarily assume that and be able to handle validating the signature with |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::array<uint8_t, 32> fd_data = finality_digest.extract_as_byte_array(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| message = std::string(fd_data.begin(), fd_data.end()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (qc.strong_votes.has_value() && qc.weak_votes.has_value()){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //weak QC (composed of strong and weak votes) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bls_g1 strong_agg_pub_key; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bls_g1 weak_agg_pub_key; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| savanna::bitset strong_b(finalizer_count, qc.strong_votes.value()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| savanna::bitset weak_b(finalizer_count, qc.weak_votes.value()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check_duplicate_votes(strong_b, weak_b, finalizer_policy); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t strong_weight = aggregate_keys(strong_b, finalizer_policy, strong_agg_pub_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t weak_weight = aggregate_keys(strong_b, finalizer_policy, weak_agg_pub_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _verify({create_strong_digest(finality_digest), create_weak_digest(finality_digest)}, {strong_agg_pub_key, weak_agg_pub_key}, qc.signature); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| weight=strong_weight+weak_weight; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else if (qc.weak_votes.has_value()){ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //weak QC (composed of weak votes) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bls_g1 agg_pub_key; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| savanna::bitset weak_b(finalizer_count, qc.weak_votes.value()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| weight = aggregate_keys(weak_b, finalizer_policy, agg_pub_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _verify({create_weak_digest(finality_digest)}, {agg_pub_key}, qc.signature); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //strong QC | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bls_g1 agg_pub_key; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| savanna::bitset strong_b(finalizer_count, qc.strong_votes.value()); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| weight = aggregate_keys(strong_b, finalizer_policy, agg_pub_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| _verify({create_strong_digest(finality_digest)}, {agg_pub_key}, qc.signature); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Basically you just need the three cases within the largest else branch here. Although there is a cleaner way of structuring this code See: Lines 168 to 209 in d89dc9f
I don't think there is even a reason to have the |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
arhag marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| std::string s_agg_pub_key = encode_g1_to_bls_public_key(agg_pub_key); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //verify signature validity | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| check(_verify(s_agg_pub_key, qc.signature, message), "signature verification failed"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (enforce_threshold_check) check(weight>=finalizer_policy.threshold, "insufficient signatures to reach quorum"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 get_merkle_root(const std::vector<checksum256>& leaves) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -268,8 +333,8 @@ namespace savanna { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| struct action_proof_of_inclusion { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t target_block_index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t final_block_index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t target_action_index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t final_action_index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| action_data target; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -278,7 +343,7 @@ namespace savanna { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //returns the merkle root obtained by hashing target.digest() with merkle_branches | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 root() const { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 digest = action_data_internal(target).digest(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 root = _compute_root(merkle_branches, digest, target_block_index, final_block_index); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 root = _compute_root(merkle_branches, digest, target_action_index, final_action_index); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return root; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -331,8 +396,8 @@ namespace savanna { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| struct reversible_proof_of_inclusion { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t target_block_index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t final_block_index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t target_reversible_block_index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| uint64_t final_reversible_block_index = 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| block_ref_data target; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -341,7 +406,7 @@ namespace savanna { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //returns the merkle root obtained by hashing target.digest() with merkle_branches | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 root() const { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 digest = target.digest(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 root = _compute_root(merkle_branches, digest, target_block_index, final_block_index); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| checksum256 root = _compute_root(merkle_branches, digest, target_reversible_block_index, final_reversible_block_index); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return root; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still does not look correct to me.
If I want to check whether the third finalizer (
i == 2) is present, I would expect to look at thei/4 == 0nibble (using 0-based indexing and counting from left to right, i.e. most significant nibble to least significant nibble). Then converting that nibble into bits, I would expect thei%4 == 2bit in that nibble (using 0-based indexing and counting from MSB to LSB) to represent the presence of that finalizer.So, given a bit string of
011:I would expect the 3rd most significant bit of the first nibble to be 1. Similarly for the 2nd most significant bit of the first nibble. But, I would expect the 1st most significant bit of the first nibble to be 0. Furthermore, I would expect all other bits that are needed for padding purposes to be 0.
So the first nibble should be the hex digit
6(which has binary representation0110). And if we need an even number of nibbles in the hex string, then we can pad with a 0 nibble at the end to get the hex representation60in this case.