Skip to content

Commit

Permalink
[Tests] Introduce tiertwo_dmn_compatibility functional test
Browse files Browse the repository at this point in the history
  • Loading branch information
random-zebra committed May 23, 2021
1 parent 6ad7ea6 commit acfa24b
Show file tree
Hide file tree
Showing 6 changed files with 239 additions and 62 deletions.
5 changes: 3 additions & 2 deletions src/rpc/masternode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,9 @@ UniValue startmasternode(const JSONRPCRequest& request)
pwallet->Lock();

if(!found) {
statusObj.pushKV("success", false);
statusObj.pushKV("error_message", "Could not find alias in config. Verify with listmasternodeconf.");
statusObj.pushKV("alias", alias);
statusObj.pushKV("result", "failed");
statusObj.pushKV("error", "Could not find alias in config. Verify with listmasternodeconf.");
}

return statusObj;
Expand Down
110 changes: 72 additions & 38 deletions test/functional/test_framework/test_framework.py
Original file line number Diff line number Diff line change
Expand Up @@ -1069,34 +1069,67 @@ def stake_and_ping(self, node_id, num_blocks, with_ping_mns=[]):
self.send_pings(with_ping_mns)



def setupDMN(self,
mnOwner,
miner,
mnRemotePos):
self.log.info("Creating proRegTx for deterministic masternode...")
collateralAdd = mnOwner.getnewaddress("dmn1")
# send to the owner the collateral tx cost + some dust for the ProReg and fee
fundingTxId = miner.sendtoaddress(collateralAdd, Decimal('10001'))
# confirm and verify reception
self.stake_and_sync(self.nodes.index(miner), 1)
assert_greater_than(mnOwner.getrawtransaction(fundingTxId, 1)["confirmations"], 0)
# create and send the ProRegTx funding the collateral
operatorAdd = self.nodes[mnRemotePos].getnewaddress("dmn_operator")
ipport = "127.0.0.1:"+str(p2p_port(mnRemotePos))
mnRemotePos,
strType, # "fund"|"internal"|"external"
outpoint=None): # COutPoint, only for "external"
self.log.info("Creating%s proRegTx for deterministic masternode..." % (
" and funding" if strType == "fFund" else ""))
collateralAdd = mnOwner.getnewaddress("dmn")
ipport = "127.0.0.1:" + str(p2p_port(mnRemotePos))
ownerAdd = mnOwner.getnewaddress("dmn_owner")
operatorAdd = mnOwner.getnewaddress("dmn_operator")
operatorKey = mnOwner.dumpprivkey(operatorAdd)
votingAdd = mnOwner.getnewaddress("dmn_voting")
proTxId = mnOwner.protx_register_fund(collateralAdd, ipport, ownerAdd, operatorAdd, votingAdd, collateralAdd)
if strType == "fund":
# send to the owner the collateral tx cost + some dust for the ProReg and fee
fundingTxId = miner.sendtoaddress(collateralAdd, Decimal('101'))
# confirm and verify reception
self.stake_and_sync(self.nodes.index(miner), 1)
assert_greater_than(mnOwner.getrawtransaction(fundingTxId, 1)["confirmations"], 0)
# create and send the ProRegTx funding the collateral
proTxId = mnOwner.protx_register_fund(collateralAdd, ipport, ownerAdd,
operatorAdd, votingAdd, collateralAdd)
elif strType == "internal":
mnOwner.getnewaddress("dust")
# send to the owner the collateral tx cost + some dust for the ProReg and fee
collateralTxId = miner.sendtoaddress(collateralAdd, Decimal('100'))
miner.sendtoaddress(collateralAdd, Decimal('1'))
# confirm and verify reception
self.stake_and_sync(self.nodes.index(miner), 1)
json_tx = mnOwner.getrawtransaction(collateralTxId, True)
collateralTxId_n = -1
for o in json_tx["vout"]:
if o["value"] == Decimal('100'):
collateralTxId_n = o["n"]
break
assert_greater_than(collateralTxId_n, -1)
assert_greater_than(json_tx["confirmations"], 0)
proTxId = mnOwner.protx_register(collateralTxId, collateralTxId_n, ipport, ownerAdd,
operatorAdd, votingAdd, collateralAdd)
elif strType == "external":
self.log.info("Setting up ProRegTx with collateral externally-signed...")
# send the tx from the miner
payoutAdd = mnOwner.getnewaddress("payout")
register_res = miner.protx_register_prepare(outpoint.hash, outpoint.n, ipport, ownerAdd,
operatorAdd, votingAdd, payoutAdd)
self.log.info("ProTx prepared")
message_to_sign = register_res["signMessage"]
collateralAdd = register_res["collateralAddress"]
signature = mnOwner.signmessage(collateralAdd, message_to_sign)
self.log.info("ProTx signed")
proTxId = miner.protx_register_submit(register_res["tx"], signature)
else:
raise Exception("Type %s not available" % strType)

self.sync_mempools([mnOwner, miner])
# confirm and verify inclusion in list
self.stake_and_sync(self.nodes.index(miner), 1)
assert_greater_than(self.nodes[mnRemotePos].getrawtransaction(proTxId, 1)["confirmations"], 0)
assert proTxId in self.nodes[mnRemotePos].protx_list(False)
return (
proTxId,
self.nodes[mnRemotePos].dumpprivkey(operatorAdd)
)

return COutPoint(proTxId, 0), operatorKey

def setupMasternode(self,
mnOwner,
Expand Down Expand Up @@ -1134,8 +1167,8 @@ def setupMasternode(self,
# lock collateral
mnOwner.lockunspent(False, [{"txid": collateralTxId, "vout": collateralTxId_n}])

# return the collateral id
return collateralTxId
# return the collateral outpoint
return COutPoint(collateralTxId, collateralTxId_n)


class SkipTest(Exception):
Expand All @@ -1160,10 +1193,10 @@ def set_test_params(self):
self.ownerTwoPos = 2
self.remoteTwoPos = 3
self.minerPos = 4
self.remoteDMNPos = 5
self.remoteDMN1Pos = 5

self.extra_args = [["-nuparams=v5_shield:249", "-nuparams=v6_evo:250"]] * self.num_nodes
for i in [self.remoteOnePos, self.remoteTwoPos, self.remoteDMNPos]:
for i in [self.remoteOnePos, self.remoteTwoPos, self.remoteDMN1Pos]:
self.extra_args[i] += ["-listen", "-externalip=127.0.0.1"]
self.extra_args[self.minerPos].append("-sporkkey=932HEevBSujW2ud7RfB1YF91AFygbBRQj3de3LyaCRqNzKKgWXi")

Expand All @@ -1179,10 +1212,10 @@ def set_test_params(self):
self.ownerTwo = None # self.nodes[self.ownerTwoPos]
self.remoteTwo = None # self.nodes[self.remoteTwoPos]
self.miner = None # self.nodes[self.minerPos]
self.remoteDMN = None # self.nodes[self.remoteDMNPos]
self.mnOneTxHash = ""
self.mnTwoTxHash = ""
self.proRegTx = ""
self.remoteDMN1 = None # self.nodes[self.remoteDMN1Pos]
self.mnOneCollateral = COutPoint()
self.mnTwoCollateral = COutPoint()
self.proRegTx1 = COutPoint()


def send_3_pings(self):
Expand All @@ -1200,12 +1233,12 @@ def stake(self, num_blocks, with_ping_mns=[]):
def controller_start_all_masternodes(self):
self.controller_start_masternode(self.ownerOne, self.masternodeOneAlias)
self.controller_start_masternode(self.ownerTwo, self.masternodeTwoAlias)
self.wait_until_mn_preenabled(self.mnOneTxHash, 40)
self.wait_until_mn_preenabled(self.mnTwoTxHash, 40)
self.wait_until_mn_preenabled(self.mnOneCollateral.hash, 40)
self.wait_until_mn_preenabled(self.mnTwoCollateral.hash, 40)
self.log.info("masternodes started, waiting until both get enabled..")
self.send_3_pings()
self.wait_until_mn_enabled(self.mnOneTxHash, 120, [self.remoteOne, self.remoteTwo])
self.wait_until_mn_enabled(self.mnTwoTxHash, 120, [self.remoteOne, self.remoteTwo])
self.wait_until_mn_enabled(self.mnOneCollateral.hash, 120, [self.remoteOne, self.remoteTwo])
self.wait_until_mn_enabled(self.mnTwoCollateral.hash, 120, [self.remoteOne, self.remoteTwo])
self.log.info("masternodes enabled and running properly!")

def advance_mocktime_and_stake(self, secs_to_add):
Expand All @@ -1219,9 +1252,9 @@ def setup_3_masternodes_network(self):
self.ownerTwo = self.nodes[self.ownerTwoPos]
self.remoteTwo = self.nodes[self.remoteTwoPos]
self.miner = self.nodes[self.minerPos]
self.remoteDMN = self.nodes[self.remoteDMNPos]
ownerOneDir = os.path.join(self.options.tmpdir, "node0")
ownerTwoDir = os.path.join(self.options.tmpdir, "node2")
self.remoteDMN1 = self.nodes[self.remoteDMN1Pos]
ownerOneDir = os.path.join(self.options.tmpdir, "node%d" % self.ownerOnePos)
ownerTwoDir = os.path.join(self.options.tmpdir, "node%d" % self.ownerTwoPos)

self.log.info("generating 256 blocks..")
# First mine 250 PoW blocks
Expand All @@ -1233,26 +1266,27 @@ def setup_3_masternodes_network(self):

self.log.info("masternodes setup..")
# setup first masternode node, corresponding to nodeOne
self.mnOneTxHash = self.setupMasternode(
self.mnOneCollateral = self.setupMasternode(
self.ownerOne,
self.miner,
self.masternodeOneAlias,
os.path.join(ownerOneDir, "regtest"),
self.remoteOnePos,
self.mnOnePrivkey)
# setup second masternode node, corresponding to nodeTwo
self.mnTwoTxHash = self.setupMasternode(
self.mnTwoCollateral = self.setupMasternode(
self.ownerTwo,
self.miner,
self.masternodeTwoAlias,
os.path.join(ownerTwoDir, "regtest"),
self.remoteTwoPos,
self.mnTwoPrivkey)
# setup deterministic masternode
self.proRegTx, self.dmnPrivkey = self.setupDMN(
self.proRegTx1, self.dmn1Privkey = self.setupDMN(
self.ownerOne,
self.miner,
self.remoteDMNPos
self.remoteDMN1Pos,
"fund"
)

self.log.info("masternodes setup completed, initializing them..")
Expand All @@ -1265,7 +1299,7 @@ def setup_3_masternodes_network(self):
remoteTwoPort = p2p_port(self.remoteTwoPos)
self.remoteOne.initmasternode(self.mnOnePrivkey, "127.0.0.1:"+str(remoteOnePort))
self.remoteTwo.initmasternode(self.mnTwoPrivkey, "127.0.0.1:"+str(remoteTwoPort))
self.remoteDMN.initmasternode(self.dmnPrivkey, "", True)
self.remoteDMN1.initmasternode(self.dmn1Privkey, "", True)

# wait until mnsync complete on all nodes
self.stake(1)
Expand Down
1 change: 1 addition & 0 deletions test/functional/test_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
TIERTWO_SCRIPTS = [
# Longest test should go first, to favor running tests in parallel
'tiertwo_governance_sync_basic.py',
'tiertwo_mn_compatibility.py',
'tiertwo_masternode_activation.py',
'tiertwo_masternode_ping.py',
]
Expand Down
22 changes: 11 additions & 11 deletions test/functional/tiertwo_governance_sync_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,16 @@ def check_budgetprojection(self, expected):
def run_test(self):
self.enable_mocktime()
self.setup_3_masternodes_network()
txHashSet = set([self.mnOneTxHash, self.mnTwoTxHash, self.proRegTx])
txHashSet = set([self.mnOneCollateral.hash, self.mnTwoCollateral.hash, self.proRegTx1.hash])
# check mn list from miner
self.check_mn_list(self.miner, txHashSet)

# check status of masternodes
self.check_mns_status_legacy(self.remoteOne, self.mnOneTxHash)
self.check_mns_status_legacy(self.remoteOne, self.mnOneCollateral.hash)
self.log.info("MN1 active")
self.check_mns_status_legacy(self.remoteTwo, self.mnTwoTxHash)
self.check_mns_status_legacy(self.remoteTwo, self.mnTwoCollateral.hash)
self.log.info("MN2 active")
self.check_mns_status(self.remoteDMN, self.proRegTx)
self.check_mns_status(self.remoteDMN1, self.proRegTx1.hash)
self.log.info("DMN1 active")

# Prepare the proposal
Expand Down Expand Up @@ -182,7 +182,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.mnOneTxHash, "YES")
self.check_vote_existence(firstProposalName, self.mnOneCollateral.hash, "YES")
self.log.info("all good, MN1 vote accepted everywhere!")

# now let's vote for the proposal with the second MN
Expand All @@ -192,18 +192,18 @@ def run_test(self):

# check that the vote was accepted everywhere
self.stake(1, [self.remoteOne, self.remoteTwo])
self.check_vote_existence(firstProposalName, self.mnTwoTxHash, "YES")
self.check_vote_existence(firstProposalName, self.mnTwoCollateral.hash, "YES")
self.log.info("all good, MN2 vote accepted everywhere!")

# now let's vote for the proposal with the first DMN
self.log.info("Voting with DMN...")
voteResult = self.ownerOne.mnbudgetvote("alias", proposalHash, "yes", self.proRegTx)
self.log.info("Voting with DMN1...")
voteResult = self.ownerOne.mnbudgetvote("alias", proposalHash, "yes", self.proRegTx1.hash)
assert_equal(voteResult["detail"][0]["result"], "success")

# check that the vote was accepted everywhere
self.stake(1, [self.remoteOne, self.remoteTwo])
self.check_vote_existence(firstProposalName, self.proRegTx, "YES")
self.log.info("all good, DM1 vote accepted everywhere!")
self.check_vote_existence(firstProposalName, self.proRegTx1.hash, "YES")
self.log.info("all good, DMN1 vote accepted everywhere!")

# Now check the budget
blockStart = nextSuperBlockHeight
Expand Down Expand Up @@ -245,7 +245,7 @@ def run_test(self):
voteResult = self.ownerTwo.mnfinalbudget("vote-many", budgetFinHash, True)
assert_equal(voteResult["detail"][0]["result"], "success")
self.log.info("Remote Two voted successfully.")
voteResult = self.remoteDMN.mnfinalbudget("vote", budgetFinHash)
voteResult = self.remoteDMN1.mnfinalbudget("vote", budgetFinHash)
assert_equal(voteResult["detail"][0]["result"], "success")
self.log.info("DMN voted successfully.")
self.stake(2, [self.remoteOne, self.remoteTwo])
Expand Down
15 changes: 4 additions & 11 deletions test/functional/tiertwo_masternode_activation.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,8 @@ def reconnect_and_restart_masternodes(self):
self.controller_start_all_masternodes()

def spend_collateral(self):
mnCollateralOutputs = self.ownerOne.getmasternodeoutputs()
mnCollateralOutputIndex = -1
for x in mnCollateralOutputs:
if x["txhash"] == self.mnOneTxHash:
mnCollateralOutputIndex = x["outputidx"]
break
assert_greater_than_or_equal(mnCollateralOutputIndex, 0)
send_value = satoshi_round(100 - 0.001)
inputs = [{'txid' : self.mnOneTxHash, 'vout' : mnCollateralOutputIndex}]
inputs = [{'txid': self.mnOneCollateral.hash, 'vout': self.mnOneCollateral.n}]
outputs = {}
outputs[self.ownerOne.getnewaddress()] = float(send_value)
rawtx = self.ownerOne.createrawtransaction(inputs, outputs)
Expand All @@ -66,8 +59,8 @@ def spend_collateral(self):
# Similar to base class wait_until_mn_status but skipping the disconnected nodes
def wait_until_mn_expired(self, _timeout, removed=False):
collaterals = {
self.remoteOnePos: self.mnOneTxHash,
self.remoteTwoPos: self.mnTwoTxHash
self.remoteOnePos: self.mnOneCollateral.hash,
self.remoteTwoPos: self.mnTwoCollateral.hash
}
for k in collaterals:
for i in range(self.num_nodes):
Expand Down Expand Up @@ -116,7 +109,7 @@ def run_test(self):
self.sync_blocks()
self.log.info("checking mn status..")
time.sleep(3) # wait a little bit
self.wait_until_mn_vinspent(self.mnOneTxHash, 30, [self.remoteTwo])
self.wait_until_mn_vinspent(self.mnOneCollateral.hash, 30, [self.remoteTwo])
self.log.info("masternode list updated successfully, vin spent")


Expand Down
Loading

0 comments on commit acfa24b

Please sign in to comment.