diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index 4e5ede1697315..b6d3b0c281f58 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -60,6 +60,7 @@ set_node_times, SPORK_ACTIVATION_TIME, SPORK_DEACTIVATION_TIME, + satoshi_round ) class TestStatus(Enum): @@ -1453,3 +1454,16 @@ def setup_3_masternodes_network(self): # Now everything is set, can start both masternodes self.controller_start_all_masternodes() + + def spend_collateral(self, mnOwner, collateralOutpoint, miner): + send_value = satoshi_round(100 - 0.001) + inputs = [{'txid': collateralOutpoint.hash, 'vout': collateralOutpoint.n}] + outputs = {} + outputs[mnOwner.getnewaddress()] = float(send_value) + rawtx = mnOwner.createrawtransaction(inputs, outputs) + signedtx = mnOwner.signrawtransaction(rawtx) + txid = miner.sendrawtransaction(signedtx['hex']) + self.sync_mempools() + self.log.info("Collateral spent in %s" % txid) + self.send_pings([self.remoteTwo]) + self.stake(1, [self.remoteTwo]) diff --git a/test/functional/tiertwo_governance_sync_basic.py b/test/functional/tiertwo_governance_sync_basic.py index 26aaf10e66014..5a7c317d6c4e9 100755 --- a/test/functional/tiertwo_governance_sync_basic.py +++ b/test/functional/tiertwo_governance_sync_basic.py @@ -67,7 +67,7 @@ def check_proposal_existence(self, proposalName, proposalHash): assert(len(proposals) > 0) assert_equal(proposals[0]["Hash"], proposalHash) - def check_vote_existence(self, proposalName, mnCollateralHash, voteType): + def check_vote_existence(self, proposalName, mnCollateralHash, voteType, voteValid): for i in range(0, len(self.nodes)): node = self.nodes[i] votesInfo = node.getbudgetvotes(proposalName) @@ -76,6 +76,7 @@ def check_vote_existence(self, proposalName, mnCollateralHash, voteType): for voteInfo in votesInfo: if (voteInfo["mnId"].split("-")[0] == mnCollateralHash) : assert_equal(voteInfo["Vote"], voteType) + assert_equal(voteInfo["fValid"], voteValid) found = True assert_true(found, "Error checking vote existence in node " + str(i)) @@ -182,7 +183,7 @@ def run_test(self): # check that the vote was accepted everywhere self.stake(1, [self.remoteOne, self.remoteTwo]) - self.check_vote_existence(firstProposalName, self.mnOneCollateral.hash, "YES") + self.check_vote_existence(firstProposalName, self.mnOneCollateral.hash, "YES", True) self.log.info("all good, MN1 vote accepted everywhere!") # now let's vote for the proposal with the second MN @@ -192,7 +193,7 @@ def run_test(self): # check that the vote was accepted everywhere self.stake(1, [self.remoteOne, self.remoteTwo]) - self.check_vote_existence(firstProposalName, self.mnTwoCollateral.hash, "YES") + self.check_vote_existence(firstProposalName, self.mnTwoCollateral.hash, "YES", True) self.log.info("all good, MN2 vote accepted everywhere!") # now let's vote for the proposal with the first DMN @@ -202,7 +203,7 @@ def run_test(self): # check that the vote was accepted everywhere self.stake(1, [self.remoteOne, self.remoteTwo]) - self.check_vote_existence(firstProposalName, self.proRegTx1.hash, "YES") + self.check_vote_existence(firstProposalName, self.proRegTx1.hash, "YES", True) self.log.info("all good, DMN1 vote accepted everywhere!") # Now check the budget @@ -263,6 +264,27 @@ def run_test(self): expected_budget[0]["RemainingPaymentCount"] -= 1 self.check_budgetprojection(expected_budget) + self.stake(1, [self.remoteOne, self.remoteTwo]) + + # now let's verify that votes expire properly. + # Drop one MN and one DMN + self.log.info("expiring MN1..") + self.spend_collateral(self.ownerOne, self.mnOneCollateral, self.miner) + self.wait_until_mn_vinspent(self.mnOneCollateral.hash, 30, [self.remoteTwo]) + self.stake(12, [self.remoteTwo]) # create blocks to remove staled votes + time.sleep(2) # wait a little bit + self.check_vote_existence(firstProposalName, self.mnOneCollateral.hash, "YES", False) + self.log.info("MN1 vote expired after collateral spend, all good") + + self.log.info("expiring DMN..") + self.spend_collateral(self.ownerOne, self.proRegTx1, self.miner) + self.wait_until_mn_vinspent(self.proRegTx1.hash, 30, [self.remoteTwo]) + self.stake(12, [self.remoteTwo]) # create blocks to remove staled votes + time.sleep(2) # wait a little bit + self.check_vote_existence(firstProposalName, self.proRegTx1.hash, "YES", False) + self.log.info("DMN vote expired after collateral spend, all good") + + if __name__ == '__main__': MasternodeGovernanceBasicTest().main() diff --git a/test/functional/tiertwo_masternode_activation.py b/test/functional/tiertwo_masternode_activation.py index cba3132e65786..47ce2480c67b2 100755 --- a/test/functional/tiertwo_masternode_activation.py +++ b/test/functional/tiertwo_masternode_activation.py @@ -5,10 +5,8 @@ from test_framework.test_framework import PivxTier2TestFramework from test_framework.util import ( - assert_greater_than_or_equal, connect_nodes_clique, disconnect_nodes, - satoshi_round, wait_until, ) @@ -43,19 +41,6 @@ def reconnect_and_restart_masternodes(self): self.wait_until_mnsync_finished() self.controller_start_all_masternodes() - def spend_collateral(self): - send_value = satoshi_round(100 - 0.001) - inputs = [{'txid': self.mnOneCollateral.hash, 'vout': self.mnOneCollateral.n}] - outputs = {} - outputs[self.ownerOne.getnewaddress()] = float(send_value) - rawtx = self.ownerOne.createrawtransaction(inputs, outputs) - signedtx = self.ownerOne.signrawtransaction(rawtx) - txid = self.miner.sendrawtransaction(signedtx['hex']) - self.sync_mempools() - self.log.info("Collateral spent in %s" % txid) - self.send_pings([self.remoteTwo]) - self.stake(1, [self.remoteTwo]) - # Similar to base class wait_until_mn_status but skipping the disconnected nodes def wait_until_mn_expired(self, _timeout, removed=False): collaterals = { @@ -105,7 +90,7 @@ def run_test(self): self.reconnect_and_restart_masternodes() self.advance_mocktime(30) self.log.info("spending the collateral now..") - self.spend_collateral() + self.spend_collateral(self.ownerOne, self.mnOneCollateral, self.miner) self.sync_blocks() self.log.info("checking mn status..") time.sleep(3) # wait a little bit