mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Merge #6271: feat: simplify and speedup feature_governance.py test by generating less blocks
42dffe8541
chore: improve logging of functional tests feature_governance.py (Konstantin Akimov)922b796800
feat: simplify and speedup feature_governance.py test by generating less blocks (Konstantin Akimov) Pull request description: ## Issue being fixed or feature implemented Too many blocks are generated in a functional tests `feature_governance.py` ## What was done? 1. Activate v20 faster for `feature_governance.py`, drop generation of useless blocks, simplify code. 2. Added extra logging for this test by converting comments to logs. ## How Has This Been Tested? Run `test/functional/feature_governance.py` Locally improvement of performance is less than 5 seconds. `tsan` jobs on CI: ``` 204/264 - feature_governance.py --legacy-wallet passed, Duration: 243 s 208/264 - feature_governance.py --descriptors passed, Duration: 270 s ``` ↑ [old version](https://gitlab.com/dashpay/dash/-/jobs/7805625816) vs [new version](https://gitlab.com/dashpay/dash/-/jobs/7819897536) ↓: ``` 193/264 - feature_governance.py --legacy-wallet passed, Duration: 220 s 199/264 - feature_governance.py --descriptors passed, Duration: 240 s ``` Most of the time is spent in `feature_governance.py` on stage "let all fulfilled requests expire for re-sync to work correctly" so that's a very minor optimization. ## Breaking Changes N/A ## Checklist: - [x] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have added or updated relevant unit/integration/functional/e2e tests - [ ] I have made corresponding changes to the documentation - [x] I have assigned this pull request to a milestone ACKs for top commit: UdjinM6: utACK42dffe8541
PastaPastaPasta: utACK42dffe8541
Tree-SHA512: 9257301043efca8b3775fff64e598b153e00bc48779212e6237ab63f06a043a66764d72e38d9e6071b82477e55884b9bce410f4d3fabeb13da631505113e86bc
This commit is contained in:
commit
05740e8264
@ -17,16 +17,16 @@ class DashGovernanceTest (DashTestFramework):
|
||||
def set_test_params(self):
|
||||
self.set_dash_test_params(6, 5, [[
|
||||
"-budgetparams=10:10:10",
|
||||
'-testactivationheight=v20@240',
|
||||
'-testactivationheight=v20@160',
|
||||
]] * 6, fast_dip3_enforcement=True)
|
||||
|
||||
def check_superblockbudget(self, v20_active):
|
||||
v20_state = self.nodes[0].getblockchaininfo()["softforks"]["v20"]
|
||||
assert_equal(v20_state["active"], v20_active)
|
||||
assert_equal(self.nodes[0].getsuperblockbudget(200), self.expected_old_budget)
|
||||
assert_equal(self.nodes[0].getsuperblockbudget(220), self.expected_old_budget)
|
||||
assert_equal(self.nodes[0].getsuperblockbudget(240), self.expected_v20_budget)
|
||||
assert_equal(self.nodes[0].getsuperblockbudget(260), self.expected_v20_budget)
|
||||
assert_equal(self.nodes[0].getsuperblockbudget(120), self.expected_old_budget)
|
||||
assert_equal(self.nodes[0].getsuperblockbudget(140), self.expected_old_budget)
|
||||
assert_equal(self.nodes[0].getsuperblockbudget(160), self.expected_v20_budget)
|
||||
assert_equal(self.nodes[0].getsuperblockbudget(180), self.expected_v20_budget)
|
||||
|
||||
def check_superblock(self):
|
||||
# Make sure Superblock has only payments that fit into the budget
|
||||
@ -53,6 +53,7 @@ class DashGovernanceTest (DashTestFramework):
|
||||
assert_equal(payments_found, 2)
|
||||
|
||||
def run_test(self):
|
||||
self.log.info("Start testing...")
|
||||
governance_info = self.nodes[0].getgovernanceinfo()
|
||||
assert_equal(governance_info['governanceminquorum'], 1)
|
||||
assert_equal(governance_info['proposalfee'], 1)
|
||||
@ -78,7 +79,7 @@ class DashGovernanceTest (DashTestFramework):
|
||||
sb_cycle = 20
|
||||
sb_maturity_window = 10
|
||||
sb_immaturity_window = sb_cycle - sb_maturity_window
|
||||
self.expected_old_budget = satoshi_round("928.57142840")
|
||||
self.expected_old_budget = satoshi_round("1000")
|
||||
self.expected_v20_budget = satoshi_round("18.57142860")
|
||||
|
||||
self.nodes[0].sporkupdate("SPORK_2_INSTANTSEND_ENABLED", 4070908800)
|
||||
@ -87,26 +88,23 @@ class DashGovernanceTest (DashTestFramework):
|
||||
|
||||
assert_equal(len(self.nodes[0].gobject("list-prepared")), 0)
|
||||
|
||||
# TODO: drop these extra 80 blocks - doesn't work without them
|
||||
for _ in range(8):
|
||||
self.bump_mocktime(10)
|
||||
self.nodes[0].generate(10)
|
||||
self.sync_blocks()
|
||||
|
||||
self.log.info("Check 1st superblock before v20")
|
||||
self.nodes[0].generate(3)
|
||||
self.bump_mocktime(3)
|
||||
self.sync_blocks()
|
||||
assert_equal(self.nodes[0].getblockcount(), 210)
|
||||
assert_equal(self.nodes[0].getblockcount(), 130)
|
||||
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], False)
|
||||
self.check_superblockbudget(False)
|
||||
|
||||
self.log.info("Check 2nd superblock before v20")
|
||||
self.nodes[0].generate(10)
|
||||
self.bump_mocktime(10)
|
||||
self.sync_blocks()
|
||||
assert_equal(self.nodes[0].getblockcount(), 220)
|
||||
assert_equal(self.nodes[0].getblockcount(), 140)
|
||||
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], False)
|
||||
self.check_superblockbudget(False)
|
||||
|
||||
self.log.info("Prepare proposals")
|
||||
proposal_time = self.mocktime
|
||||
self.p0_payout_address = self.nodes[0].getnewaddress()
|
||||
self.p1_payout_address = self.nodes[0].getnewaddress()
|
||||
@ -162,10 +160,10 @@ class DashGovernanceTest (DashTestFramework):
|
||||
|
||||
block_count = self.nodes[0].getblockcount()
|
||||
|
||||
# Move until 1 block before the Superblock maturity window starts
|
||||
self.log.info("Move until 1 block before the Superblock maturity window starts")
|
||||
n = sb_immaturity_window - block_count % sb_cycle
|
||||
# v20 is expected to be activate since block 240
|
||||
assert block_count + n < 240
|
||||
self.log.info("v20 is expected to be activate since block 160")
|
||||
assert block_count + n < 160
|
||||
for _ in range(n - 1):
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
@ -174,7 +172,7 @@ class DashGovernanceTest (DashTestFramework):
|
||||
|
||||
assert_equal(len(self.nodes[0].gobject("list", "valid", "triggers")), 0)
|
||||
|
||||
# Detect payee node
|
||||
self.log.info("Detect payee node")
|
||||
mn_list = self.nodes[0].protx("list", "registered", True)
|
||||
height_protx_list = []
|
||||
for mn in mn_list:
|
||||
@ -190,54 +188,54 @@ class DashGovernanceTest (DashTestFramework):
|
||||
break
|
||||
assert payee_idx is not None
|
||||
|
||||
# Isolate payee node and create a trigger
|
||||
self.log.info("Isolate payee node and create a trigger")
|
||||
self.isolate_node(payee_idx)
|
||||
isolated = self.nodes[payee_idx]
|
||||
|
||||
# Move 1 block inside the Superblock maturity window on the isolated node
|
||||
self.log.info("Move 1 block inside the Superblock maturity window on the isolated node")
|
||||
isolated.generate(1)
|
||||
self.bump_mocktime(1)
|
||||
# The isolated "winner" should submit new trigger and vote for it
|
||||
self.log.info("The isolated 'winner' should submit new trigger and vote for it")
|
||||
self.wait_until(lambda: len(isolated.gobject("list", "valid", "triggers")) == 1, timeout=5)
|
||||
isolated_trigger_hash = list(isolated.gobject("list", "valid", "triggers").keys())[0]
|
||||
self.wait_until(lambda: list(isolated.gobject("list", "valid", "triggers").values())[0]['YesCount'] == 1, timeout=5)
|
||||
more_votes = wait_until_helper(lambda: list(isolated.gobject("list", "valid", "triggers").values())[0]['YesCount'] > 1, timeout=5, do_assert=False)
|
||||
assert_equal(more_votes, False)
|
||||
|
||||
# Move 1 block enabling the Superblock maturity window on non-isolated nodes
|
||||
self.log.info("Move 1 block enabling the Superblock maturity window on non-isolated nodes")
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
assert_equal(self.nodes[0].getblockcount(), 230)
|
||||
assert_equal(self.nodes[0].getblockcount(), 150)
|
||||
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], False)
|
||||
self.check_superblockbudget(False)
|
||||
|
||||
# The "winner" should submit new trigger and vote for it, but it's isolated so no triggers should be found
|
||||
self.log.info("The 'winner' should submit new trigger and vote for it, but it's isolated so no triggers should be found")
|
||||
has_trigger = wait_until_helper(lambda: len(self.nodes[0].gobject("list", "valid", "triggers")) >= 1, timeout=5, do_assert=False)
|
||||
assert_equal(has_trigger, False)
|
||||
|
||||
# Move 1 block inside the Superblock maturity window on non-isolated nodes
|
||||
self.log.info("Move 1 block inside the Superblock maturity window on non-isolated nodes")
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
|
||||
# There is now new "winner" who should submit new trigger and vote for it
|
||||
self.log.info("There is now new 'winner' who should submit new trigger and vote for it")
|
||||
self.wait_until(lambda: len(self.nodes[0].gobject("list", "valid", "triggers")) == 1, timeout=5)
|
||||
winning_trigger_hash = list(self.nodes[0].gobject("list", "valid", "triggers").keys())[0]
|
||||
self.wait_until(lambda: list(self.nodes[0].gobject("list", "valid", "triggers").values())[0]['YesCount'] == 1, timeout=5)
|
||||
more_votes = wait_until_helper(lambda: list(self.nodes[0].gobject("list", "valid", "triggers").values())[0]['YesCount'] > 1, timeout=5, do_assert=False)
|
||||
assert_equal(more_votes, False)
|
||||
|
||||
# Make sure amounts aren't trimmed
|
||||
self.log.info("Make sure amounts aren't trimmed")
|
||||
payment_amounts_expected = [str(satoshi_round(str(self.p0_amount))), str(satoshi_round(str(self.p1_amount))), str(satoshi_round(str(self.p2_amount)))]
|
||||
data_string = list(self.nodes[0].gobject("list", "valid", "triggers").values())[0]["DataString"]
|
||||
payment_amounts_trigger = json.loads(data_string)["payment_amounts"].split("|")
|
||||
for amount_str in payment_amounts_trigger:
|
||||
assert(amount_str in payment_amounts_expected)
|
||||
|
||||
# Move another block inside the Superblock maturity window on non-isolated nodes
|
||||
self.log.info("Move another block inside the Superblock maturity window on non-isolated nodes")
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
|
||||
# Every non-isolated MN should vote for the same trigger now, no new triggers should be created
|
||||
self.log.info("Every non-isolated MN should vote for the same trigger now, no new triggers should be created")
|
||||
self.wait_until(lambda: list(self.nodes[0].gobject("list", "valid", "triggers").values())[0]['YesCount'] == self.mn_count - 1, timeout=5)
|
||||
more_triggers = wait_until_helper(lambda: len(self.nodes[0].gobject("list", "valid", "triggers")) > 1, timeout=5, do_assert=False)
|
||||
assert_equal(more_triggers, False)
|
||||
@ -251,9 +249,9 @@ class DashGovernanceTest (DashTestFramework):
|
||||
self.bump_mocktime(1)
|
||||
return node.mnsync("status")["IsSynced"]
|
||||
|
||||
# make sure isolated node is fully synced at this point
|
||||
self.log.info("make sure isolated node is fully synced at this point")
|
||||
self.wait_until(lambda: sync_gov(isolated))
|
||||
# let all fulfilled requests expire for re-sync to work correctly
|
||||
self.log.info("let all fulfilled requests expire for re-sync to work correctly")
|
||||
self.bump_mocktime(5 * 60)
|
||||
|
||||
for node in self.nodes:
|
||||
@ -263,53 +261,53 @@ class DashGovernanceTest (DashTestFramework):
|
||||
node.mnsync("next")
|
||||
self.wait_until(lambda: sync_gov(node))
|
||||
|
||||
# Should see two triggers now
|
||||
self.log.info("Should see two triggers now")
|
||||
self.wait_until(lambda: len(isolated.gobject("list", "valid", "triggers")) == 2, timeout=5)
|
||||
self.wait_until(lambda: len(self.nodes[0].gobject("list", "valid", "triggers")) == 2, timeout=5)
|
||||
more_triggers = wait_until_helper(lambda: len(self.nodes[0].gobject("list", "valid", "triggers")) > 2, timeout=5, do_assert=False)
|
||||
assert_equal(more_triggers, False)
|
||||
|
||||
# Move another block inside the Superblock maturity window
|
||||
self.log.info("Move another block inside the Superblock maturity window")
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
self.sync_blocks()
|
||||
|
||||
# Should see NO votes on both triggers now
|
||||
self.log.info("Should see NO votes on both triggers now")
|
||||
self.wait_until(lambda: self.nodes[0].gobject("list", "valid", "triggers")[winning_trigger_hash]['NoCount'] == 1, timeout=5)
|
||||
self.wait_until(lambda: self.nodes[0].gobject("list", "valid", "triggers")[isolated_trigger_hash]['NoCount'] == self.mn_count - 1, timeout=5)
|
||||
|
||||
# Remember vote count
|
||||
self.log.info("Remember vote count")
|
||||
before = self.nodes[1].gobject("count")["votes"]
|
||||
|
||||
# Bump mocktime to let MNs vote again
|
||||
self.log.info("Bump mocktime to let MNs vote again")
|
||||
self.bump_mocktime(GOVERNANCE_UPDATE_MIN + 1, update_schedulers=False)
|
||||
|
||||
# Move another block inside the Superblock maturity window
|
||||
self.log.info("Move another block inside the Superblock maturity window")
|
||||
with self.nodes[1].assert_debug_log(["CGovernanceManager::VoteGovernanceTriggers"]):
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
self.sync_blocks()
|
||||
|
||||
# Vote count should not change even though MNs are allowed to vote again
|
||||
self.log.info("Vote count should not change even though MNs are allowed to vote again")
|
||||
assert_equal(before, self.nodes[1].gobject("count")["votes"])
|
||||
# Revert mocktime back to avoid issues in tests below
|
||||
self.log.info("Revert mocktime back to avoid issues in tests below")
|
||||
self.bump_mocktime(GOVERNANCE_UPDATE_MIN * -1, update_schedulers=False)
|
||||
|
||||
block_count = self.nodes[0].getblockcount()
|
||||
n = sb_cycle - block_count % sb_cycle
|
||||
|
||||
# Move remaining n blocks until actual Superblock
|
||||
self.log.info("Move remaining n blocks until actual Superblock")
|
||||
for i in range(n):
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
self.sync_blocks()
|
||||
# comparing to 239 because bip9 forks are active when the tip is one block behind the activation height
|
||||
self.check_superblockbudget(block_count + i + 1 >= 239)
|
||||
# comparing to 159 because bip9 forks are active when the tip is one block behind the activation height
|
||||
self.check_superblockbudget(block_count + i + 1 >= 159)
|
||||
|
||||
self.check_superblockbudget(True)
|
||||
self.check_superblock()
|
||||
|
||||
# Move a few block past the recent superblock height and make sure we have no new votes
|
||||
self.log.info("Move a few block past the recent superblock height and make sure we have no new votes")
|
||||
for _ in range(5):
|
||||
with self.nodes[1].assert_debug_log("", [f"Voting NO-FUNDING for trigger:{winning_trigger_hash} success"]):
|
||||
self.nodes[0].generate(1)
|
||||
@ -322,28 +320,28 @@ class DashGovernanceTest (DashTestFramework):
|
||||
block_count = self.nodes[0].getblockcount()
|
||||
n = sb_cycle - block_count % sb_cycle
|
||||
|
||||
# Move remaining n blocks until the next Superblock
|
||||
self.log.info("Move remaining n blocks until the next Superblock")
|
||||
for _ in range(n - 1):
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
self.sync_blocks()
|
||||
# Wait for new trigger and votes
|
||||
self.wait_until(lambda: have_trigger_for_height(self.nodes, 260))
|
||||
# Mine superblock
|
||||
self.log.info("Wait for new trigger and votes")
|
||||
self.wait_until(lambda: have_trigger_for_height(self.nodes, 180))
|
||||
self.log.info("Mine superblock")
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
self.sync_blocks()
|
||||
assert_equal(self.nodes[0].getblockcount(), 260)
|
||||
assert_equal(self.nodes[0].getblockcount(), 180)
|
||||
assert_equal(self.nodes[0].getblockchaininfo()["softforks"]["v20"]["active"], True)
|
||||
|
||||
# Mine and check a couple more superblocks
|
||||
self.log.info("Mine and check a couple more superblocks")
|
||||
for i in range(2):
|
||||
for _ in range(sb_cycle - 1):
|
||||
self.nodes[0].generate(1)
|
||||
self.bump_mocktime(1)
|
||||
self.sync_blocks()
|
||||
# Wait for new trigger and votes
|
||||
sb_block_height = 260 + (i + 1) * sb_cycle
|
||||
sb_block_height = 180 + (i + 1) * sb_cycle
|
||||
self.wait_until(lambda: have_trigger_for_height(self.nodes, sb_block_height))
|
||||
# Mine superblock
|
||||
self.nodes[0].generate(1)
|
||||
|
Loading…
Reference in New Issue
Block a user