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

test: improve mine rotation quorums for IS in functional tests #6431

Merged
merged 1 commit into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 1 addition & 8 deletions test/functional/feature_governance_cl.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,7 @@ def run_test(self):
self.wait_for_sporks_same()
self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))

self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum()

self.sync_blocks()
self.wait_for_chainlocked_block_all_nodes(self.nodes[0].getbestblockhash())
Expand Down
8 changes: 1 addition & 7 deletions test/functional/feature_llmq_chainlocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,7 @@ def run_test(self):
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.wait_for_sporks_same()

self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))
self.mine_cycle_quorum(llmq_type_name="llmq_test_dip0024", llmq_type=103)
self.mine_cycle_quorum()
self.wait_for_chainlocked_block_all_nodes(self.nodes[0].getbestblockhash())

self.log.info("Mine single block, ensure it includes latest chainlock")
Expand Down
12 changes: 3 additions & 9 deletions test/functional/feature_llmq_connections.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,7 @@ def run_test(self):

self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))
self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum()

# Since we IS quorums are mined only using dip24 (rotation) we need to enable rotation, and continue tests on llmq_test_dip0024 for connections.

Expand All @@ -93,7 +87,7 @@ def run_test(self):
try:
with mn.node.assert_debug_log(['removing masternodes quorum connections']):
with mn.node.assert_debug_log(['keeping mn quorum connections']):
self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum(is_first=False)
mn.node.mockscheduler(60) # we check for old connections via the scheduler every 60 seconds
removed = True
except:
Expand All @@ -108,7 +102,7 @@ def run_test(self):
if len(mn.node.quorum("memberof", mn.proTxHash)) > 0:
try:
with mn.node.assert_debug_log(['adding mn inter-quorum connections']):
self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum(is_first=False)
added = True
except:
pass # it's ok to not add connections sometimes
Expand Down
9 changes: 1 addition & 8 deletions test/functional/feature_llmq_is_cl_conflicts.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,7 @@ def run_test(self):

self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))

self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum()

# mine single block, wait for chainlock
self.generate(self.nodes[0], 1, sync_fun=self.no_op)
Expand Down
10 changes: 1 addition & 9 deletions test/functional/feature_llmq_is_retroactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,7 @@ def run_test(self):
self.wait_for_sporks_same()

self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))

self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum()

# Make sure that all nodes are chainlocked at the same height before starting actual tests
self.wait_for_chainlocked_block_all_nodes(self.nodes[0].getbestblockhash(), timeout=30)
Expand Down
20 changes: 17 additions & 3 deletions test/functional/feature_llmq_rotation.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ def run_test(self):
self.wait_for_chainlocked_block_all_nodes(self.nodes[0].getbestblockhash())


(quorum_info_0_0, quorum_info_0_1) = self.mine_cycle_quorum(llmq_type_name=llmq_type_name, llmq_type=llmq_type)
(quorum_info_0_0, quorum_info_0_1) = self.mine_cycle_quorum(is_first=False)
assert(self.test_quorum_listextended(quorum_info_0_0, llmq_type_name))
assert(self.test_quorum_listextended(quorum_info_0_1, llmq_type_name))
quorum_members_0_0 = extract_quorum_members(quorum_info_0_0)
Expand All @@ -176,7 +176,7 @@ def run_test(self):
self.log.info("Wait for chainlock")
self.wait_for_chainlocked_block_all_nodes(self.nodes[0].getbestblockhash())

(quorum_info_1_0, quorum_info_1_1) = self.mine_cycle_quorum(llmq_type_name=llmq_type_name, llmq_type=llmq_type)
(quorum_info_1_0, quorum_info_1_1) = self.mine_cycle_quorum(is_first=False)
assert(self.test_quorum_listextended(quorum_info_1_0, llmq_type_name))
assert(self.test_quorum_listextended(quorum_info_1_1, llmq_type_name))
quorum_members_1_0 = extract_quorum_members(quorum_info_1_0)
Expand Down Expand Up @@ -210,7 +210,7 @@ def run_test(self):
self.wait_for_chainlocked_block_all_nodes(self.nodes[0].getbestblockhash())

self.log.info("Mine a quorum to invalidate")
(quorum_info_3_0, quorum_info_3_1) = self.mine_cycle_quorum(llmq_type_name=llmq_type_name, llmq_type=llmq_type)
(quorum_info_3_0, quorum_info_3_1) = self.mine_cycle_quorum(is_first=False)

new_quorum_list = self.nodes[0].quorum("list", llmq_type)
assert_equal(len(new_quorum_list[llmq_type_name]), len(quorum_list[llmq_type_name]) + 2)
Expand Down Expand Up @@ -383,6 +383,20 @@ def test_quorum_listextended(self, quorum_info, llmq_type_name):
return True
return False

def move_to_next_cycle(self):
cycle_length = 24
mninfos_online = self.mninfo.copy()
nodes = [self.nodes[0]] + [mn.node for mn in mninfos_online]
cur_block = self.nodes[0].getblockcount()

# move forward to next DKG
skip_count = cycle_length - (cur_block % cycle_length)
if skip_count != 0:
self.bump_mocktime(1, nodes=nodes)
self.generate(self.nodes[0], skip_count, sync_fun=self.no_op)
self.sync_blocks(nodes)
self.log.info('Moved from block %d to %d' % (cur_block, self.nodes[0].getblockcount()))


if __name__ == '__main__':
LLMQQuorumRotationTest().main()
9 changes: 1 addition & 8 deletions test/functional/feature_notifications.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,7 @@ def run_test(self):
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", 0)
self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", 4070908800)
self.wait_for_sporks_same()
self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))

(quorum_info_i_0, quorum_info_i_1) = self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
(quorum_info_i_0, quorum_info_i_1) = self.mine_cycle_quorum()
self.nodes[0].sporkupdate("SPORK_19_CHAINLOCKS_ENABLED", 0)
self.wait_for_sporks_same()

Expand Down
15 changes: 2 additions & 13 deletions test/functional/interface_zmq_dash.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,8 @@ def run_test(self):
self.wait_for_sporks_same()
self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))

self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum()

self.sync_blocks()
self.wait_for_chainlocked_block_all_nodes(self.nodes[0].getbestblockhash())
Expand All @@ -162,12 +156,7 @@ def run_test(self):
self.wait_for_chainlocked_block_all_nodes(self.nodes[0].getbestblockhash())
self.test_instantsend_publishers()
# At this point, we need to move forward 3 cycles (3 x 24 blocks) so the first 3 quarters can be created (without DKG sessions)
self.move_to_next_cycle()
self.test_instantsend_publishers()
self.move_to_next_cycle()
self.test_instantsend_publishers()
self.move_to_next_cycle()
self.test_instantsend_publishers()
self.generate(self.nodes[0], 24)
self.mine_cycle_quorum()
self.test_instantsend_publishers()
finally:
Expand Down
8 changes: 1 addition & 7 deletions test/functional/p2p_instantsend.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,7 @@ def run_test(self):
self.wait_for_sporks_same()
self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))
(quorum_info_i_0, quorum_info_i_1) = self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
(quorum_info_i_0, quorum_info_i_1) = self.mine_cycle_quorum()

self.test_mempool_doublespend()
self.test_block_doublespend()
Expand Down
13 changes: 3 additions & 10 deletions test/functional/rpc_verifyislock.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,7 @@ def run_test(self):

self.activate_v19(expected_activation_height=900)
self.log.info("Activated v19 at height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+C height:" + str(self.nodes[0].getblockcount()))
self.move_to_next_cycle()
self.log.info("Cycle H+2C height:" + str(self.nodes[0].getblockcount()))

self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum()
self.bump_mocktime(1)
self.generate(self.nodes[0], 8, sync_fun=self.sync_blocks())

Expand All @@ -64,7 +57,7 @@ def run_test(self):
assert node.verifyislock(request_id, txid, rec_sig, node.getblockcount() + 100)

# Mine one more cycle of rotated quorums
self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum(is_first=False)
# Create an ISLOCK using an active quorum which will be replaced when a new cycle happens
request_id = None
utxos = node.listunspent()
Expand All @@ -87,7 +80,7 @@ def run_test(self):
# Create the ISDLOCK, then mine a cycle quorum to move renew active set
isdlock = self.create_isdlock(rawtx)
# Mine one block to trigger the "signHeight + dkgInterval" verification for the ISDLOCK
self.mine_cycle_quorum(llmq_type_name='llmq_test_dip0024', llmq_type=103)
self.mine_cycle_quorum(is_first=False)
# Verify the ISLOCK for a transaction that is not yet known by the node
rawtx_txid = node.decoderawtransaction(rawtx)["txid"]
assert_raises_rpc_error(-5, "No such mempool or blockchain transaction", node.getrawtransaction, rawtx_txid)
Expand Down
49 changes: 18 additions & 31 deletions test/functional/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -1895,31 +1895,32 @@ def mine_quorum(self, llmq_type_name="llmq_test", llmq_type=100, expected_connec

return new_quorum

def mine_cycle_quorum(self, llmq_type_name="llmq_test_dip0024", llmq_type=103, expected_connections=None, expected_members=None, expected_contributions=None, expected_complaints=0, expected_justifications=0, expected_commitments=None, mninfos_online=None):
def mine_cycle_quorum(self, is_first=True):
spork21_active = self.nodes[0].spork('show')['SPORK_21_QUORUM_ALL_CONNECTED'] <= 1
spork23_active = self.nodes[0].spork('show')['SPORK_23_QUORUM_POSE'] <= 1

if expected_connections is None:
expected_connections = (self.llmq_size_dip0024 - 1) if spork21_active else 2
if expected_members is None:
expected_members = self.llmq_size_dip0024
if expected_contributions is None:
expected_contributions = self.llmq_size_dip0024
if expected_commitments is None:
expected_commitments = self.llmq_size_dip0024
if mninfos_online is None:
mninfos_online = self.mninfo.copy()
llmq_type_name="llmq_test_dip0024"
llmq_type=103
expected_connections = (self.llmq_size_dip0024 - 1) if spork21_active else 2
expected_members = self.llmq_size_dip0024
expected_contributions = self.llmq_size_dip0024
expected_commitments = self.llmq_size_dip0024
mninfos_online = self.mninfo.copy()
expected_complaints=0
expected_justifications=0

self.log.info("Mining quorum: expected_members=%d, expected_connections=%d, expected_contributions=%d, expected_complaints=%d, expected_justifications=%d, "
"expected_commitments=%d" % (expected_members, expected_connections, expected_contributions, expected_complaints,
expected_justifications, expected_commitments))
self.log.info(f"Mining quorum: expected_members={expected_members}, expected_connections={expected_connections}, expected_contributions={expected_contributions}, expected_commitments={expected_commitments}, no complains and justfications expected")

nodes = [self.nodes[0]] + [mn.node for mn in mninfos_online]

# move forward to next DKG
skip_count = 24 - (self.nodes[0].getblockcount() % 24)
cycle_length = 24
cur_block = self.nodes[0].getblockcount()

self.move_blocks(nodes, skip_count)
skip_count = cycle_length - (cur_block % cycle_length)
# move forward to next 3 DKG rounds for the first quorum
extra_blocks = 24 * 3 if is_first else 0
self.move_blocks(nodes, extra_blocks + skip_count)
self.log.info('Moved from block %d to %d' % (cur_block, self.nodes[0].getblockcount()))

q_0 = self.nodes[0].getbestblockhash()
self.log.info("Expected quorum_0 at:" + str(self.nodes[0].getblockcount()))
Expand Down Expand Up @@ -2018,20 +2019,6 @@ def mine_cycle_quorum(self, llmq_type_name="llmq_test_dip0024", llmq_type=103,

return (quorum_info_0, quorum_info_1)

def move_to_next_cycle(self):
cycle_length = 24
mninfos_online = self.mninfo.copy()
nodes = [self.nodes[0]] + [mn.node for mn in mninfos_online]
cur_block = self.nodes[0].getblockcount()

# move forward to next DKG
skip_count = cycle_length - (cur_block % cycle_length)
if skip_count != 0:
self.bump_mocktime(1, nodes=nodes)
self.generate(self.nodes[0], skip_count, sync_fun=self.no_op)
self.sync_blocks(nodes)
self.log.info('Moved from block %d to %d' % (cur_block, self.nodes[0].getblockcount()))

def wait_for_recovered_sig(self, rec_sig_id, rec_sig_msg_hash, llmq_type=100, timeout=10):
def check_recovered_sig():
self.bump_mocktime(1)
Expand Down
Loading