Skip to content

Commit 58377f8

Browse files
committed
test: added functional tests for invalid CQuorumCommitment
1 parent bb0b8b0 commit 58377f8

File tree

2 files changed

+69
-6
lines changed

2 files changed

+69
-6
lines changed

test/functional/feature_llmq_dkgerrors.py

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,16 @@
33
# Distributed under the MIT software license, see the accompanying
44
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
55

6-
from test_framework.test_framework import DashTestFramework
6+
import copy
7+
from io import BytesIO
78

9+
from test_framework.test_framework import DashTestFramework
10+
from test_framework.messages import (
11+
CBlock,
12+
CFinalCommitmentPayload,
13+
from_hex,
14+
)
15+
from test_framework.util import assert_equal
816
'''
917
feature_llmq_dkgerrors.py
1018
@@ -20,8 +28,9 @@ def run_test(self):
2028
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
2129
self.wait_for_sporks_same()
2230

23-
self.log.info("Mine one quorum without simulating any errors")
24-
qh = self.mine_quorum()
31+
qh = self.test_qc()
32+
33+
self.log.info("Mine one regular quorum with no invalid members is mined at this point")
2534
self.assert_member_valid(qh, self.mninfo[0].proTxHash, True)
2635

2736
mninfos_valid = self.mninfo.copy()[1:]
@@ -70,6 +79,59 @@ def run_test(self):
7079
qh = self.mine_quorum(expected_contributions=3, expected_complaints=0, expected_justifications=0, expected_commitments=2, mninfos_valid=mninfos_valid)
7180
self.assert_member_valid(qh, self.mninfo[0].proTxHash, True)
7281

82+
def test_qc(self):
83+
quorumHash = self.mine_quorum(skip_maturity=True)
84+
best = self.nodes[0].getbestblockhash()
85+
block_hex = self.nodes[0].getblock(best, 0)
86+
87+
block = from_hex(CBlock(), block_hex)
88+
89+
self.nodes[0].invalidateblock(best)
90+
91+
self.test_invalid(block, 'bad-qc-commitment-type', lambda qc : (setattr(qc, 'llmqType', 77), qc)[1])
92+
self.test_invalid(block, 'bad-qc-invalid', lambda qc : (setattr(qc, 'llmqType', 106), qc)[1])
93+
# TODO: test quorumIndex for rotation quorums
94+
# self.test_invalid(block, 'bad-qc-invalid', lambda qc : (setattr(qc, 'quorumIndex', 2), qc)[1])
95+
self.test_invalid(block, 'bad-qc-invalid', lambda qc : (setattr(qc, 'quorumSig', getattr(qc, 'membersSig')), qc)[1])
96+
self.test_invalid(block, 'bad-qc-invalid', lambda qc : (setattr(qc, 'membersSig', getattr(qc, 'quorumSig')), qc)[1])
97+
self.test_invalid(block, 'bad-qc-invalid', lambda qc : (setattr(qc, 'quorumPublicKey', b'\x00' * 48), qc)[1])
98+
# TODO: test quorumVvecHash
99+
# TODO: test signers
100+
# TODO: test validMembers
101+
102+
self.nodes[0].reconsiderblock(best)
103+
# Mine 8 (SIGN_HEIGHT_OFFSET) more blocks to make sure that the new quorum gets eligible for signing sessions
104+
self.generate(self.nodes[0], 8, sync_fun=lambda: self.sync_blocks(self.nodes))
105+
106+
return quorumHash
107+
108+
def test_invalid(self, original_block, error, transform):
109+
node = self.nodes[0]
110+
111+
block = copy.deepcopy(original_block)
112+
113+
for tx in block.vtx:
114+
if tx.nType == 6:
115+
qc_payload = CFinalCommitmentPayload()
116+
qc_payload.deserialize(BytesIO(tx.vExtraPayload))
117+
# test not only quorum 100, rotation quorums also and single-node quorum
118+
if qc_payload.commitment.llmqType == 100:
119+
qc_payload.commitment = transform(qc_payload.commitment)
120+
121+
tx.vExtraPayload = qc_payload.serialize()
122+
tx.rehash()
123+
124+
def assert_submitblock(block, result_str_1, result_str_2=None):
125+
block.hashMerkleRoot = block.calc_merkle_root()
126+
block.solve()
127+
result_str_2 = result_str_2 or 'duplicate-invalid'
128+
assert_equal(result_str_1, node.submitblock(hexdata=block.serialize().hex()))
129+
assert_equal(result_str_2, node.submitblock(hexdata=block.serialize().hex()))
130+
131+
# TODO: implement similar validation not only for submitblock but for p2p message
132+
assert_submitblock(block, error)
133+
134+
73135
def assert_member_valid(self, quorumHash, proTxHash, expectedValid):
74136
q = self.nodes[0].quorum('info', 100, quorumHash, True)
75137
for m in q['members']:

test/functional/test_framework/test_framework.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,7 +2108,7 @@ def move_blocks(self, nodes, num_blocks):
21082108
self.bump_mocktime(1, nodes=nodes)
21092109
self.generate(self.nodes[0], num_blocks, sync_fun=lambda: self.sync_blocks(nodes))
21102110

2111-
def mine_quorum(self, llmq_type_name="llmq_test", llmq_type=100, expected_connections=None, expected_members=None, expected_contributions=None, expected_complaints=0, expected_justifications=0, expected_commitments=None, mninfos_online=None, mninfos_valid=None):
2111+
def mine_quorum(self, llmq_type_name="llmq_test", llmq_type=100, expected_connections=None, expected_members=None, expected_contributions=None, expected_complaints=0, expected_justifications=0, expected_commitments=None, mninfos_online=None, mninfos_valid=None, skip_maturity=False):
21122112
spork21_active = self.nodes[0].spork('show')['SPORK_21_QUORUM_ALL_CONNECTED'] <= 1
21132113
spork23_active = self.nodes[0].spork('show')['SPORK_23_QUORUM_POSE'] <= 1
21142114

@@ -2185,8 +2185,9 @@ def mine_quorum(self, llmq_type_name="llmq_test", llmq_type=100, expected_connec
21852185
assert_equal(q, new_quorum)
21862186
quorum_info = self.nodes[0].quorum("info", llmq_type, new_quorum)
21872187

2188-
# Mine 8 (SIGN_HEIGHT_OFFSET) more blocks to make sure that the new quorum gets eligible for signing sessions
2189-
self.generate(self.nodes[0], 8, sync_fun=lambda: self.sync_blocks(nodes))
2188+
if not skip_maturity:
2189+
# Mine 8 (SIGN_HEIGHT_OFFSET) more blocks to make sure that the new quorum gets eligible for signing sessions
2190+
self.generate(self.nodes[0], 8, sync_fun=lambda: self.sync_blocks(nodes))
21902191

21912192
self.log.info("New quorum: height=%d, quorumHash=%s, quorumIndex=%d, minedBlock=%s" % (quorum_info["height"], new_quorum, quorum_info["quorumIndex"], quorum_info["minedBlock"]))
21922193

0 commit comments

Comments
 (0)