mirror of
https://github.com/dashpay/dash.git
synced 2024-12-24 11:32:46 +01:00
Merge #6278: perf: reduced delays and syncs in functional tests to run faster
874ef8cda2
fix: mine_quorum_no_checks -> mine_quorum_less_checks: do some checks to make sure quorums are mined correctly (UdjinM6)4f636f47b4
fix: re-order functional tests: move governance to 60+seconds category (Konstantin Akimov)fe49f3f178
refactor: removed dead and commented code from test_framework.py (Konstantin Akimov)cd1958c82a
perf: removed sleep(6) from mine_cycle_quorum in functional tests (Konstantin Akimov)3f17a01a83
fix: bump mocktime in simplepose when generating blocks to improve robustness (Konstantin Akimov)132d95e651
perf: remove sleep(1) from each step of quorum creation in functional tests (Konstantin Akimov)4c57ad1c05
chore: increase batch size from 10 to 50 for faster block generation in functional tests (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented Functional tests take too long time to run. (PR is recreated from https://github.com/dashpay/dash/pull/6268 because CI is broken) ## What was done? - increased robustness `feature_llmq_simplepose.py` by adding missing bump for mocktime during block generations - removed sleep(1) from each stage of mine_quorum - removed sleep(6) from final stage of mine_cycled_quorum - size of batch for block generation in `feature_asset_locks.py` and in `activate_fork_by_name()` increased from 10 blocks to 50 blocks - moved governance's functional tests to "60 seconds+" category because they always the last one to wait if running more than 10 jobs at once Plus extra refactoring which removes dead and commented code from test_framework.py ## How Has This Been Tested? Locally, the functional tests speed up with these fixes for 15% for overall time and 20% for accumulated time `test/functional/test_runner.py -j20` Before: ``` ALL | ✓ Passed | 7860 s (accumulated) Runtime: 481 s ``` After: ``` ALL | ✓ Passed | 6237 s (accumulated) Runtime: 416 s ``` --- CI tsan job speeds up for 5 minutes in absolute time (~5%) and 1000 seconds in accumulated time. ``` ALL | ✓ Passed | 23854 s (accumulated) Runtime: 6249 s ``` ↑ [old version](https://gitlab.com/dashpay/dash/-/jobs/7822664869) vs [new version](https://gitlab.com/dashpay/dash/-/jobs/7825461091) ↓ ``` ALL | ✓ Passed | 22901 s (accumulated) Runtime: 5962 s ``` ## Breaking Changes N/A ## Checklist: - [x] I have performed a self-review of my own code - [x] I have commented my code, particularly in hard-to-understand areas - [x] I have added or updated relevant unit/integration/functional/e2e tests - [x] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone ACKs for top commit: UdjinM6: utACK874ef8cda2
PastaPastaPasta: utACK874ef8cda2
Tree-SHA512: 514fa2fb32abd59c90f63b68fccc8c3d3b6d16b0b6ad7459c4a348825815e7d3012177565dea1f70b8a1f28ede1a297f91361365454d1be85955e77260451cf5
This commit is contained in:
commit
61201b80da
@ -219,11 +219,11 @@ class AssetLocksTest(DashTestFramework):
|
||||
except JSONRPCException as e:
|
||||
assert expected_error in e.error['message']
|
||||
|
||||
def slowly_generate_batch(self, count):
|
||||
self.log.info(f"Slowly generate {count} blocks")
|
||||
def generate_batch(self, count):
|
||||
self.log.info(f"Generate {count} blocks")
|
||||
while count > 0:
|
||||
self.log.info(f"Generating batch of blocks {count} left")
|
||||
batch = min(10, count)
|
||||
batch = min(50, count)
|
||||
count -= batch
|
||||
self.bump_mocktime(batch)
|
||||
self.nodes[1].generate(batch)
|
||||
@ -426,7 +426,7 @@ class AssetLocksTest(DashTestFramework):
|
||||
self.validate_credit_pool_balance(locked - 2 * COIN)
|
||||
|
||||
self.log.info("Generating many blocks to make quorum far behind (even still active)...")
|
||||
self.slowly_generate_batch(too_late_height - node.getblockcount() - 1)
|
||||
self.generate_batch(too_late_height - node.getblockcount() - 1)
|
||||
self.check_mempool_result(tx=asset_unlock_tx_too_late, result_expected={'allowed': True, 'fees': {'base': Decimal(str(tiny_amount / COIN))}})
|
||||
node.generate(1)
|
||||
self.sync_all()
|
||||
@ -444,7 +444,7 @@ class AssetLocksTest(DashTestFramework):
|
||||
for inode in self.nodes:
|
||||
inode.invalidateblock(block_asset_unlock)
|
||||
self.validate_credit_pool_balance(locked)
|
||||
self.slowly_generate_batch(50)
|
||||
self.generate_batch(50)
|
||||
self.validate_credit_pool_balance(locked)
|
||||
for inode in self.nodes:
|
||||
inode.reconsiderblock(block_to_reconsider)
|
||||
@ -510,7 +510,7 @@ class AssetLocksTest(DashTestFramework):
|
||||
assert spend_txid_in_block in block['tx']
|
||||
|
||||
self.log.info("Fast forward to the next day to reset all current unlock limits...")
|
||||
self.slowly_generate_batch(blocks_in_one_day)
|
||||
self.generate_batch(blocks_in_one_day)
|
||||
self.mine_quorum_2_nodes(llmq_type_name='llmq_test_platform', llmq_type=106)
|
||||
|
||||
total = self.get_credit_pool_balance()
|
||||
@ -585,7 +585,7 @@ class AssetLocksTest(DashTestFramework):
|
||||
assert pending_txid in node.getrawmempool()
|
||||
|
||||
self.log.info("Fast forward to next day again...")
|
||||
self.slowly_generate_batch(blocks_in_one_day - 1)
|
||||
self.generate_batch(blocks_in_one_day - 1)
|
||||
self.log.info("Checking mempool is empty now...")
|
||||
self.mempool_size = 0
|
||||
self.check_mempool_size()
|
||||
@ -618,7 +618,7 @@ class AssetLocksTest(DashTestFramework):
|
||||
|
||||
|
||||
self.log.info("generate many blocks to be sure that mempool is empty after expiring txes...")
|
||||
self.slowly_generate_batch(60)
|
||||
self.generate_batch(60)
|
||||
self.log.info("Checking that credit pool is not changed...")
|
||||
assert_equal(new_total, self.get_credit_pool_balance())
|
||||
self.check_mempool_size()
|
||||
|
@ -92,16 +92,16 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
for mn in self.mninfo:
|
||||
assert not self.check_punished(mn) and not self.check_banned(mn)
|
||||
|
||||
def mine_quorum_no_check(self, expected_good_nodes, mninfos_online):
|
||||
def mine_quorum_less_checks(self, expected_good_nodes, mninfos_online):
|
||||
# Unlike in mine_quorum we skip most of the checks and only care about
|
||||
# nodes moving forward from phase to phase and the fact that the quorum is actually mined.
|
||||
self.log.info("Mining a quorum with no checks")
|
||||
# nodes moving forward from phase to phase correctly and the fact that the quorum is actually mined.
|
||||
self.log.info("Mining a quorum with less checks")
|
||||
nodes = [self.nodes[0]] + [mn.node for mn in mninfos_online]
|
||||
|
||||
# move forward to next DKG
|
||||
skip_count = 24 - (self.nodes[0].getblockcount() % 24)
|
||||
if skip_count != 0:
|
||||
self.bump_mocktime(1, nodes=nodes)
|
||||
self.bump_mocktime(skip_count, nodes=nodes)
|
||||
self.nodes[0].generate(skip_count)
|
||||
self.sync_blocks(nodes)
|
||||
|
||||
@ -112,7 +112,7 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
self.move_blocks(nodes, 2)
|
||||
|
||||
self.log.info("Waiting for phase 2 (contribute)")
|
||||
self.wait_for_quorum_phase(q, 2, expected_good_nodes, None, 0, mninfos_online)
|
||||
self.wait_for_quorum_phase(q, 2, expected_good_nodes, "receivedContributions", expected_good_nodes, mninfos_online)
|
||||
self.move_blocks(nodes, 2)
|
||||
|
||||
self.log.info("Waiting for phase 3 (complain)")
|
||||
@ -124,7 +124,7 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
self.move_blocks(nodes, 2)
|
||||
|
||||
self.log.info("Waiting for phase 5 (commit)")
|
||||
self.wait_for_quorum_phase(q, 5, expected_good_nodes, None, 0, mninfos_online)
|
||||
self.wait_for_quorum_phase(q, 5, expected_good_nodes, "receivedPrematureCommitments", expected_good_nodes, mninfos_online)
|
||||
self.move_blocks(nodes, 2)
|
||||
|
||||
self.log.info("Waiting for phase 6 (mining)")
|
||||
@ -147,6 +147,7 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
quorum_info = self.nodes[0].quorum("info", 100, new_quorum)
|
||||
|
||||
# Mine 8 (SIGN_HEIGHT_OFFSET) more blocks to make sure that the new quorum gets eligible for signing sessions
|
||||
self.bump_mocktime(8)
|
||||
self.nodes[0].generate(8)
|
||||
self.sync_blocks(nodes)
|
||||
self.log.info("New quorum: height=%d, quorumHash=%s, quorumIndex=%d, minedBlock=%s" % (quorum_info["height"], new_quorum, quorum_info["quorumIndex"], quorum_info["minedBlock"]))
|
||||
@ -174,7 +175,7 @@ class LLMQSimplePoSeTest(DashTestFramework):
|
||||
# 6th time is when it should be banned for sure.
|
||||
for _ in range(6):
|
||||
self.reset_probe_timeouts()
|
||||
self.mine_quorum_no_check(expected_contributors - 1, mninfos_online)
|
||||
self.mine_quorum_less_checks(expected_contributors - 1, mninfos_online)
|
||||
|
||||
assert self.check_banned(mn)
|
||||
|
||||
|
@ -1136,7 +1136,7 @@ class DashTestFramework(BitcoinTestFramework):
|
||||
self.wait_for_sporks_same()
|
||||
|
||||
# mine blocks in batches
|
||||
batch_size = 10
|
||||
batch_size = 50
|
||||
if expected_activation_height is not None:
|
||||
height = self.nodes[0].getblockcount()
|
||||
assert height < expected_activation_height
|
||||
@ -1170,9 +1170,6 @@ class DashTestFramework(BitcoinTestFramework):
|
||||
self.nodes[0].sporkupdate("SPORK_17_QUORUM_DKG_ENABLED", spork17_value)
|
||||
self.wait_for_sporks_same()
|
||||
|
||||
def activate_dip0024(self, expected_activation_height=None):
|
||||
self.activate_by_name('dip0024', expected_activation_height)
|
||||
|
||||
def activate_v19(self, expected_activation_height=None):
|
||||
self.activate_by_name('v19', expected_activation_height)
|
||||
|
||||
@ -1794,7 +1791,6 @@ class DashTestFramework(BitcoinTestFramework):
|
||||
wait_until_helper(wait_func, timeout=timeout, sleep=sleep)
|
||||
|
||||
def move_blocks(self, nodes, num_blocks):
|
||||
time.sleep(1)
|
||||
self.bump_mocktime(1, nodes=nodes)
|
||||
self.nodes[0].generate(num_blocks)
|
||||
self.sync_blocks(nodes)
|
||||
@ -1913,19 +1909,11 @@ class DashTestFramework(BitcoinTestFramework):
|
||||
# move forward to next DKG
|
||||
skip_count = 24 - (self.nodes[0].getblockcount() % 24)
|
||||
|
||||
# if skip_count != 0:
|
||||
# self.bump_mocktime(1, nodes=nodes)
|
||||
# self.nodes[0].generate(skip_count)
|
||||
# time.sleep(4)
|
||||
# self.sync_blocks(nodes)
|
||||
|
||||
self.move_blocks(nodes, skip_count)
|
||||
|
||||
q_0 = self.nodes[0].getbestblockhash()
|
||||
self.log.info("Expected quorum_0 at:" + str(self.nodes[0].getblockcount()))
|
||||
# time.sleep(4)
|
||||
self.log.info("Expected quorum_0 hash:" + str(q_0))
|
||||
# time.sleep(4)
|
||||
self.log.info("quorumIndex 0: Waiting for phase 1 (init)")
|
||||
self.wait_for_quorum_phase(q_0, 1, expected_members, None, 0, mninfos_online, llmq_type_name)
|
||||
self.log.info("quorumIndex 0: Waiting for quorum connections (init)")
|
||||
@ -1937,9 +1925,7 @@ class DashTestFramework(BitcoinTestFramework):
|
||||
|
||||
q_1 = self.nodes[0].getbestblockhash()
|
||||
self.log.info("Expected quorum_1 at:" + str(self.nodes[0].getblockcount()))
|
||||
# time.sleep(2)
|
||||
self.log.info("Expected quorum_1 hash:" + str(q_1))
|
||||
# time.sleep(2)
|
||||
self.log.info("quorumIndex 1: Waiting for phase 1 (init)")
|
||||
self.wait_for_quorum_phase(q_1, 1, expected_members, None, 0, mninfos_online, llmq_type_name)
|
||||
self.log.info("quorumIndex 1: Waiting for quorum connections (init)")
|
||||
@ -1996,14 +1982,12 @@ class DashTestFramework(BitcoinTestFramework):
|
||||
|
||||
self.log.info("quorumIndex 1: Waiting for phase 6 (finalization)")
|
||||
self.wait_for_quorum_phase(q_1, 6, expected_members, None, 0, mninfos_online, llmq_type_name)
|
||||
time.sleep(6)
|
||||
self.log.info("Mining final commitments")
|
||||
self.bump_mocktime(1, nodes=nodes)
|
||||
self.nodes[0].getblocktemplate() # this calls CreateNewBlock
|
||||
self.nodes[0].generate(1)
|
||||
self.sync_blocks(nodes)
|
||||
|
||||
time.sleep(6)
|
||||
self.log.info("Waiting for quorum(s) to appear in the list")
|
||||
self.wait_for_quorums_list(q_0, q_1, nodes, llmq_type_name)
|
||||
|
||||
@ -2038,7 +2022,6 @@ class DashTestFramework(BitcoinTestFramework):
|
||||
self.bump_mocktime(1, nodes=nodes)
|
||||
self.nodes[0].generate(skip_count)
|
||||
self.sync_blocks(nodes)
|
||||
time.sleep(1)
|
||||
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):
|
||||
|
@ -133,6 +133,10 @@ BASE_SCRIPTS = [
|
||||
'feature_dip4_coinbasemerkleroots.py', # NOTE: needs dash_hash to pass
|
||||
'feature_asset_locks.py', # NOTE: needs dash_hash to pass
|
||||
'feature_mnehf.py', # NOTE: needs dash_hash to pass
|
||||
'feature_governance.py --legacy-wallet',
|
||||
'feature_governance.py --descriptors',
|
||||
'feature_governance_cl.py --legacy-wallet',
|
||||
'feature_governance_cl.py --descriptors',
|
||||
# vv Tests less than 60s vv
|
||||
'p2p_sendheaders.py', # NOTE: needs dash_hash to pass
|
||||
'p2p_sendheaders_compressed.py', # NOTE: needs dash_hash to pass
|
||||
@ -294,10 +298,6 @@ BASE_SCRIPTS = [
|
||||
'feature_cltv.py',
|
||||
'feature_new_quorum_type_activation.py',
|
||||
'feature_governance_objects.py',
|
||||
'feature_governance.py --legacy-wallet',
|
||||
'feature_governance.py --descriptors',
|
||||
'feature_governance_cl.py --legacy-wallet',
|
||||
'feature_governance_cl.py --descriptors',
|
||||
'p2p_governance_invs.py',
|
||||
'rpc_uptime.py',
|
||||
'feature_discover.py',
|
||||
|
Loading…
Reference in New Issue
Block a user