Skip to content

Commit 1f01a5f

Browse files
committed
[Tests] Functional testing for ProUpReg txes
1 parent 48e8862 commit 1f01a5f

File tree

3 files changed

+106
-4
lines changed

3 files changed

+106
-4
lines changed

test/functional/test_framework/test_framework.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1324,10 +1324,19 @@ def check_mn_list_on_node(self, idx, mns):
13241324
mnlist = self.nodes[idx].listmasternodes()
13251325
if len(mnlist) != len(mns):
13261326
raise Exception("Invalid mn list on node %d:\n%s\nExpected:%s" % (idx, str(mnlist), str(mns)))
1327-
protxs = [x["proTxHash"] for x in mnlist]
1327+
protxs = {x["proTxHash"]: x for x in mnlist}
13281328
for mn in mns:
13291329
if mn.proTx not in protxs:
13301330
raise Exception("ProTx for mn %d (%s) not found in the list of node %d" % (mn.idx, mn.proTx, idx))
1331+
mn2 = protxs[mn.proTx]
1332+
collateral = mn.collateral.to_json()
1333+
assert_equal(mn.owner, mn2["dmnstate"]["ownerAddress"])
1334+
assert_equal(mn.operator, mn2["dmnstate"]["operatorAddress"])
1335+
assert_equal(mn.voting, mn2["dmnstate"]["votingAddress"])
1336+
assert_equal(mn.ipport, mn2["dmnstate"]["service"])
1337+
assert_equal(mn.payee, mn2["dmnstate"]["payoutAddress"])
1338+
assert_equal(collateral["txid"], mn2["collateralHash"])
1339+
assert_equal(collateral["vout"], mn2["collateralIndex"])
13311340

13321341
def check_proreg_payload(self, dmn, json_tx):
13331342
assert "payload" in json_tx

test/functional/tiertwo_deterministicmns.py

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,11 @@ def run_test(self):
283283
mns[0].proTx, mns[1].ipport, "", mns[0].operator_key)
284284
self.log.info("Trying to update the payout address when the reward is 0...")
285285
assert_raises_rpc_error(-8, "Operator reward is 0. Cannot set operator payout address",
286-
miner.protx_update_service, mns[0].proTx, mns[0].ipport,
286+
miner.protx_update_service, mns[0].proTx, "",
287287
miner.getnewaddress(), mns[0].operator_key)
288+
self.log.info("Trying to update the operator payee to an invalid address...")
289+
assert_raises_rpc_error(-5, "invalid PIVX address InvalidPayee",
290+
miner.protx_update_service, dmn2c.proTx, "", "InvalidPayee", "")
288291
self.log.info("Update IP address...")
289292
mns[0].ipport = "127.0.0.1:1000"
290293
# Controller should already have the key (as it was generated there), no need to pass it
@@ -302,6 +305,59 @@ def run_test(self):
302305
self.log.info("Checking payment...")
303306
assert_equal(self.get_addr_balance(self.nodes[dmn2c.idx], new_address), Decimal('0.3'))
304307

308+
# Test ProUpReg txes
309+
self.log.info("Trying to update a non-existent masternode...")
310+
assert_raises_rpc_error(-8, "not found", miner.protx_update_registrar,
311+
"%064x" % getrandbits(256), "", "", "")
312+
self.log.info("Trying to update an operator address to an already used one...")
313+
assert_raises_rpc_error(-1, "bad-protx-dup-key", controller.protx_update_registrar,
314+
mns[0].proTx, mns[1].operator, "", "")
315+
self.log.info("Trying to update the payee to an invalid address...")
316+
assert_raises_rpc_error(-5, "invalid PIVX address InvalidPayee", controller.protx_update_registrar,
317+
mns[0].proTx, "", "", "InvalidPayee")
318+
self.log.info("Update operator address...")
319+
mns[0].operator = self.nodes[mns[0].idx].getnewaddress()
320+
mns[0].operator_key = self.nodes[mns[0].idx].dumpprivkey(mns[0].operator)
321+
# Controller should already have the key (as it was generated there), no need to pass it
322+
controller.protx_update_registrar(mns[0].proTx, mns[0].operator, "", "")
323+
self.sync_mempools([miner, controller])
324+
miner.generate(1)
325+
self.sync_blocks()
326+
# Updating the operator address, clears the IP (and puts the mn in PoSe banned state)
327+
mns[0].ipport = "[::]:0"
328+
self.check_mn_list(mns)
329+
old_mn0_balance = self.get_addr_balance(controller, mns[0].payee)
330+
self.log.info("Update operator address (with external key)...")
331+
mns[0].operator = self.nodes[mns[0].idx].getnewaddress()
332+
mns[0].operator_key = self.nodes[mns[0].idx].dumpprivkey(mns[0].operator)
333+
ownerKey = controller.dumpprivkey(mns[0].owner)
334+
miner.protx_update_registrar(mns[0].proTx, mns[0].operator, "", "", ownerKey)
335+
miner.generate(1)
336+
self.sync_blocks()
337+
self.check_mn_list(mns)
338+
self.log.info("Update voting address...")
339+
mns[1].voting = controller.getnewaddress()
340+
controller.protx_update_registrar(mns[1].proTx, "", mns[1].voting, "")
341+
self.sync_mempools([miner, controller])
342+
miner.generate(1)
343+
self.sync_blocks()
344+
self.check_mn_list(mns)
345+
self.log.info("Update payout address...")
346+
old_payee = mns[2].payee
347+
old_mn2_bal = self.get_addr_balance(controller, old_payee)
348+
mns[2].payee = controller.getnewaddress()
349+
controller.protx_update_registrar(mns[2].proTx, "", "", mns[2].payee)
350+
self.sync_mempools([miner, controller])
351+
miner.generate(len(mns))
352+
self.sync_blocks()
353+
self.check_mn_list(mns)
354+
# Check payment to new address
355+
self.log.info("Checking payments...")
356+
assert_equal(self.get_addr_balance(controller, old_payee), old_mn2_bal)
357+
assert_equal(self.get_addr_balance(controller, mns[2].payee), Decimal('3'))
358+
# The PoSe banned node didn't receive any more payment
359+
assert_equal(self.get_addr_balance(controller, mns[0].payee), old_mn0_balance)
360+
305361
self.log.info("All good.")
306362

307363

test/functional/tiertwo_reorg_mempool.py

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ def disconnect_all(self):
5454
def register_masternode(self, from_node, dmn, collateral_addr):
5555
dmn.proTx = from_node.protx_register_fund(collateral_addr, dmn.ipport, dmn.owner,
5656
dmn.operator, dmn.voting, dmn.payee)
57+
dmn.collateral = COutPoint(int(dmn.proTx, 16),
58+
get_collateral_vout(from_node.getrawtransaction(dmn.proTx, True)))
5759

5860
def run_test(self):
5961
self.disable_mocktime()
@@ -179,7 +181,21 @@ def run_test(self):
179181
proupserv2_txid = nodeA.protx_update_service(mnsA[2].proTx, "127.0.0.1:2000")
180182
proupserv3_txid = nodeA.protx_update_service(pre_split_mn.proTx, "127.0.0.1:1001")
181183

182-
# Now nodeA has 4 proReg txes in its mempool, and 3 proUpServ txes
184+
# Send valid proUpReg tx to the mempool
185+
operator_to_reuse = nodeA.getnewaddress()
186+
proupreg1_txid = nodeA.protx_update_registrar(mnsA[3].proTx, operator_to_reuse, "", "")
187+
188+
# Try sending another one, reusing the operator key used by another mempool proTx
189+
self.log.info("Testing proUpReg in-mempool duplicate-operator-key rejection...")
190+
assert_raises_rpc_error(-26, "protx-dup", nodeA.protx_update_registrar,
191+
mnsA[4].proTx, mempool_dmn1.operator, "", "")
192+
193+
# Now send other two valid proUpServ txes to the mempool, without mining them
194+
new_voting_address = nodeA.getnewaddress()
195+
proupreg2_txid = nodeA.protx_update_registrar(mnsA[4].proTx, "", new_voting_address, "")
196+
proupreg3_txid = nodeA.protx_update_registrar(pre_split_mn.proTx, "", new_voting_address, "")
197+
198+
# Now nodeA has 4 proReg txes in its mempool, 3 proUpServ txes, and 3 proUpReg txes
183199
mempoolA = nodeA.getrawmempool()
184200
assert mempool_dmn1.proTx in mempoolA
185201
assert mempool_dmn2.proTx in mempoolA
@@ -188,6 +204,9 @@ def run_test(self):
188204
assert proupserv1_txid in mempoolA
189205
assert proupserv2_txid in mempoolA
190206
assert proupserv3_txid in mempoolA
207+
assert proupreg1_txid in mempoolA
208+
assert proupreg2_txid in mempoolA
209+
assert proupreg3_txid in mempoolA
191210

192211
assert_equal(nodeA.getblockcount(), 208)
193212

@@ -230,13 +249,22 @@ def run_test(self):
230249
self.register_masternode(nodeB, dmn, collateral_addr)
231250
mnsB.append(dmn)
232251
nodeB.generate(1)
252+
self.check_mn_list_on_node(1, mnsB)
233253

234254
# Register one masternode reusing the IP of the proUpServ mempool tx on chainA
235-
dmn1000 = create_new_dmn(0, nodeB, collateral_addr, None)
255+
dmn1000 = create_new_dmn(free_idx, nodeB, collateral_addr, None)
256+
free_idx += 1
236257
dmn1000.ipport = "127.0.0.1:1000"
237258
mnsB.append(dmn1000)
238259
self.register_masternode(nodeB, dmn1000, collateral_addr)
239260

261+
# Register one masternode reusing the operator-key of the proUpReg mempool tx on chainA
262+
dmnop = create_new_dmn(free_idx, nodeB, collateral_addr, None)
263+
free_idx += 1
264+
dmnop.operator = operator_to_reuse
265+
mnsB.append(dmnop)
266+
self.register_masternode(nodeB, dmnop, collateral_addr)
267+
240268
# Then mine 10 more blocks on chain B
241269
nodeB.generate(10)
242270
self.check_mn_list_on_node(1, mnsB)
@@ -275,6 +303,13 @@ def run_test(self):
275303
assert proupserv1_txid not in mempoolA
276304
assert proupserv2_txid not in mempoolA
277305
assert proupserv3_txid in mempoolA
306+
# The first mempool proUpReg tx has been removed as the operator key is
307+
# now used by a newly connected masternode.
308+
# The second mempool proUpReg tx has been removed as it was meant to update
309+
# a masternode that is not in the deterministic list anymore.
310+
assert proupreg1_txid not in mempoolA
311+
assert proupreg2_txid not in mempoolA
312+
assert proupreg3_txid in mempoolA
278313
# The mempool contains also all the ProReg from the disconnected blocks,
279314
# except the ones re-registered and replayed on chain B.
280315
for mn in mnsA:
@@ -291,8 +326,10 @@ def run_test(self):
291326
mnsB.append(mempool_dmn2)
292327
mnsB.append(mempool_dmn3)
293328
# proupserv3 has changed the IP of the pre_split masternode
329+
# and proupreg3 has changed its voting address
294330
mnsB.remove(pre_split_mn)
295331
pre_split_mn.ipport = "127.0.0.1:1001"
332+
pre_split_mn.voting = new_voting_address
296333
mnsB.append(pre_split_mn)
297334
# the ProReg txes, that were added back to the mempool from the
298335
# disconnected blocks, have been mined again

0 commit comments

Comments
 (0)