Skip to content

Commit 72d5a31

Browse files
committed
[Tests] Fix/Update mining_pos_coldstaking test
1 parent 5ffa6b5 commit 72d5a31

File tree

4 files changed

+92
-100
lines changed

4 files changed

+92
-100
lines changed

test/functional/mining_pos_coldStaking.py

Lines changed: 84 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,13 @@
77
from io import BytesIO
88
from time import sleep
99

10-
from test_framework.authproxy import JSONRPCException
1110
from test_framework.messages import CTransaction, CTxIn, CTxOut, COIN, COutPoint
1211
from test_framework.mininode import network_thread_start
1312
from test_framework.pivx_node import PivxTestNode
1413
from test_framework.script import CScript, OP_CHECKSIG
1514
from test_framework.test_framework import PivxTestFramework
16-
from test_framework.util import connect_nodes_bi, p2p_port, bytes_to_hex_str, \
17-
assert_equal, assert_greater_than, sync_blocks, assert_raises_rpc_error
15+
from test_framework.util import connect_nodes_bi, p2p_port, bytes_to_hex_str, set_node_times, \
16+
assert_equal, assert_greater_than, sync_blocks, sync_mempools, assert_raises_rpc_error
1817

1918
# filter utxos based on first 5 bytes of scriptPubKey
2019
def getDelegatedUtxos(utxos):
@@ -24,11 +23,15 @@ def getDelegatedUtxos(utxos):
2423
class PIVX_ColdStakingTest(PivxTestFramework):
2524

2625
def set_test_params(self):
27-
self.setup_clean_chain = True
2826
self.num_nodes = 3
2927
self.extra_args = [['-staking=1']] * self.num_nodes
3028
self.extra_args[0].append('-sporkkey=932HEevBSujW2ud7RfB1YF91AFygbBRQj3de3LyaCRqNzKKgWXi')
3129

30+
def setup_chain(self):
31+
# Start with PoW cache: 200 blocks
32+
self._initialize_chain()
33+
self.enable_mocktime()
34+
3235

3336
def setup_network(self):
3437
''' Can't rely on syncing all the nodes when staking=1
@@ -79,40 +82,53 @@ def isColdStakingEnforced(self):
7982
def run_test(self):
8083
self.description = "Performs tests on the Cold Staking P2CS implementation"
8184
self.init_test()
82-
LAST_POW_BLOCK = 250
8385
NUM_OF_INPUTS = 20
84-
INPUT_VALUE = 50
85-
INITAL_MINED_BLOCKS = LAST_POW_BLOCK + 1
86+
INPUT_VALUE = 249
8687

8788
# nodes[0] - coin-owner
8889
# nodes[1] - cold-staker
8990

90-
# 1) nodes[0] mines 20 blocks. nodes[2] mines 231 blocks.
91-
# -----------------------------------------------------------
92-
# Check that SPORK 17 is disabled
93-
assert (not self.isColdStakingEnforced())
91+
# 1) nodes[0] and nodes[2] mine 25 blocks each
92+
# --------------------------------------------
9493
print("*** 1 ***")
95-
self.log.info("Mining %d blocks..." % INITAL_MINED_BLOCKS)
96-
self.generateBlock(20, 0)
97-
sync_blocks(self.nodes)
98-
self.log.info("20 Blocks mined.")
99-
self.generateBlock(INITAL_MINED_BLOCKS-20)
94+
self.log.info("Mining 50 Blocks...")
95+
for peer in [0, 2]:
96+
for j in range(25):
97+
self.mocktime = self.generate_pow(peer, self.mocktime)
98+
sync_blocks(self.nodes)
99+
100+
# 2) node[1] sends his entire balance (50 mature rewards) to node[2]
101+
# - node[2] stakes a block - node[1] locks the change
102+
print("*** 2 ***")
103+
self.log.info("Emptying node1 balance")
104+
assert_equal(self.nodes[1].getbalance(), 50 * 250)
105+
txid = self.nodes[1].sendtoaddress(self.nodes[2].getnewaddress(), (50 * 250 - 0.01))
106+
assert (txid is not None)
107+
sync_mempools(self.nodes)
108+
self.mocktime = self.generate_pos(2, self.mocktime)
100109
sync_blocks(self.nodes)
101-
self.log.info("251 Blocks mined.")
110+
# lock the change output (so it's not used as stake input in generate_pos)
111+
for x in self.nodes[1].listunspent():
112+
assert (self.nodes[1].lockunspent(False, [{"txid": x['txid'], "vout": x['vout']}]))
113+
# check that it cannot stake
114+
sleep(1)
115+
assert_equal(self.nodes[1].getstakingstatus()["stakeablecoins"], False)
102116

103-
# 2) nodes[0] generates a owner address
117+
# 3) nodes[0] generates a owner address
104118
# nodes[1] generates a cold-staking address.
105119
# ---------------------------------------------
106-
print("*** 2 ***")
120+
print("*** 3 ***")
107121
owner_address = self.nodes[0].getnewaddress()
108122
self.log.info("Owner Address: %s" % owner_address)
109123
staker_address = self.nodes[1].getnewstakingaddress()
110124
staker_privkey = self.nodes[1].dumpprivkey(staker_address)
111125
self.log.info("Staking Address: %s" % staker_address)
112126

113-
# 3) Check enforcement.
127+
# 4) Check enforcement.
114128
# ---------------------
115-
print("*** 3 ***")
129+
print("*** 4 ***")
130+
# Check that SPORK 17 is disabled
131+
assert (not self.isColdStakingEnforced())
116132
self.log.info("Creating a stake-delegation tx before cold staking enforcement...")
117133
assert_raises_rpc_error(-4, "The transaction was rejected!",
118134
self.nodes[0].delegatestake, staker_address, INPUT_VALUE, owner_address, False, False, True)
@@ -123,9 +139,9 @@ def run_test(self):
123139
# double check
124140
assert (self.isColdStakingEnforced())
125141

126-
# 4) nodes[0] delegates a number of inputs for nodes[1] to stake em.
142+
# 5) nodes[0] delegates a number of inputs for nodes[1] to stake em.
127143
# ------------------------------------------------------------------
128-
print("*** 4 ***")
144+
print("*** 5 ***")
129145
self.log.info("First check warning when using external addresses...")
130146
assert_raises_rpc_error(-5, "Only the owner of the key to owneraddress will be allowed to spend these coins",
131147
self.nodes[0].delegatestake, staker_address, INPUT_VALUE, "yCgCXC8N5VThhfiaVuKaNLkNnrWduzVnoT")
@@ -152,38 +168,39 @@ def run_test(self):
152168
assert(res != None and res["txid"] != None and res["txid"] != "")
153169
assert_equal(res["owner_address"], owner_address)
154170
assert_equal(res["staker_address"], staker_address)
155-
self.generateBlock()
171+
sync_mempools(self.nodes)
172+
self.mocktime = self.generate_pos(2, self.mocktime)
156173
sync_blocks(self.nodes)
157174
self.log.info("%d Txes created." % NUM_OF_INPUTS)
158175
# check balances:
159176
self.expected_balance = NUM_OF_INPUTS * INPUT_VALUE
160177
self.expected_immature_balance = 0
161178
self.checkBalances()
162179

163-
# 5) check that the owner (nodes[0]) can spend the coins.
180+
# 6) check that the owner (nodes[0]) can spend the coins.
164181
# -------------------------------------------------------
165-
print("*** 5 ***")
182+
print("*** 6 ***")
166183
self.log.info("Spending back one of the delegated UTXOs...")
167184
delegated_utxos = getDelegatedUtxos(self.nodes[0].listunspent())
168-
assert_equal(20, len(delegated_utxos))
185+
assert_equal(NUM_OF_INPUTS, len(delegated_utxos))
169186
assert_equal(len(delegated_utxos), len(self.nodes[0].listcoldutxos()))
170187
u = delegated_utxos[0]
171188
txhash = self.spendUTXOwithNode(u, 0)
172189
assert(txhash != None)
173190
self.log.info("Good. Owner was able to spend - tx: %s" % str(txhash))
174191

175-
self.generateBlock()
192+
self.mocktime = self.generate_pos(2, self.mocktime)
176193
sync_blocks(self.nodes)
177194
# check balances after spend.
178195
self.expected_balance -= float(u["amount"])
179196
self.checkBalances()
180197
self.log.info("Balances check out after spend")
181-
assert_equal(19, len(self.nodes[0].listcoldutxos()))
198+
assert_equal(NUM_OF_INPUTS-1, len(self.nodes[0].listcoldutxos()))
182199

183-
# 6) check that the staker CANNOT use the coins to stake yet.
200+
# 7) check that the staker CANNOT use the coins to stake yet.
184201
# He needs to whitelist the owner first.
185202
# -----------------------------------------------------------
186-
print("*** 6 ***")
203+
print("*** 7 ***")
187204
self.log.info("Trying to generate a cold-stake block before whitelisting the owner...")
188205
assert_equal(self.nodes[1].getstakingstatus()["stakeablecoins"], False)
189206
self.log.info("Nice. Cold staker was NOT able to create the block yet.")
@@ -193,25 +210,25 @@ def run_test(self):
193210
assert(ret)
194211
self.log.info("Delegator address %s whitelisted" % owner_address)
195212

196-
# 7) check that the staker CANNOT spend the coins.
213+
# 8) check that the staker CANNOT spend the coins.
197214
# ------------------------------------------------
198-
print("*** 7 ***")
215+
print("*** 8 ***")
199216
self.log.info("Trying to spend one of the delegated UTXOs with the cold-staking key...")
200217
delegated_utxos = getDelegatedUtxos(self.nodes[0].listunspent())
201218
assert_greater_than(len(delegated_utxos), 0)
202219
u = delegated_utxos[0]
203220
assert_raises_rpc_error(-26, "mandatory-script-verify-flag-failed (Script failed an OP_CHECKCOLDSTAKEVERIFY operation",
204221
self.spendUTXOwithNode, u, 1)
205222
self.log.info("Good. Cold staker was NOT able to spend (failed OP_CHECKCOLDSTAKEVERIFY)")
206-
self.generateBlock()
223+
self.mocktime = self.generate_pos(2, self.mocktime)
207224
sync_blocks(self.nodes)
208225

209-
# 8) check that the staker can use the coins to stake a block with internal miner.
226+
# 9) check that the staker can use the coins to stake a block with internal miner.
210227
# --------------------------------------------------------------------------------
211-
print("*** 8 ***")
228+
print("*** 9 ***")
212229
assert_equal(self.nodes[1].getstakingstatus()["stakeablecoins"], True)
213230
self.log.info("Generating one valid cold-stake block...")
214-
self.generateBlock(1, 1)
231+
self.mocktime = self.generate_pos(1, self.mocktime)
215232
self.log.info("New block created by cold-staking. Trying to submit...")
216233
newblockhash = self.nodes[1].getbestblockhash()
217234
self.log.info("Block %s submitted" % newblockhash)
@@ -223,20 +240,20 @@ def run_test(self):
223240
self.log.info("Great. Cold-staked block was accepted!")
224241

225242
# check balances after staked block.
226-
self.expected_balance -= 50
227-
self.expected_immature_balance += 300
243+
self.expected_balance -= INPUT_VALUE
244+
self.expected_immature_balance += (INPUT_VALUE + 250)
228245
self.checkBalances()
229246
self.log.info("Balances check out after staked block")
230247

231-
# 9) check that the staker can use the coins to stake a block with a rawtransaction.
248+
# 10) check that the staker can use the coins to stake a block with a rawtransaction.
232249
# ----------------------------------------------------------------------------------
233-
print("*** 9 ***")
250+
print("*** 10 ***")
234251
self.log.info("Generating another valid cold-stake block...")
235252
stakeable_coins = getDelegatedUtxos(self.nodes[0].listunspent())
236253
stakeInputs = self.get_prevouts(1, stakeable_coins)
237254
assert_greater_than(len(stakeInputs), 0)
238255
# Create the block
239-
new_block = self.stake_next_block(1, stakeInputs, None, staker_privkey)
256+
new_block = self.stake_next_block(1, stakeInputs, self.mocktime, staker_privkey)
240257
self.log.info("New block created (rawtx) by cold-staking. Trying to submit...")
241258
# Try to submit the block
242259
ret = self.nodes[1].submitblock(bytes_to_hex_str(new_block.serialize()))
@@ -248,22 +265,24 @@ def run_test(self):
248265
assert_equal(self.nodes[0].getblockcount(), self.nodes[1].getblockcount())
249266
assert_equal(new_block.hash, self.nodes[0].getbestblockhash())
250267
self.log.info("Great. Cold-staked block was accepted!")
268+
self.mocktime += 60
269+
set_node_times(self.nodes, self.mocktime)
251270

252271
# check balances after staked block.
253-
self.expected_balance -= 50
254-
self.expected_immature_balance += 300
272+
self.expected_balance -= INPUT_VALUE
273+
self.expected_immature_balance += (INPUT_VALUE + 250)
255274
self.checkBalances()
256275
self.log.info("Balances check out after staked block")
257276

258-
# 10) check that the staker cannot stake a block changing the coinstake scriptPubkey.
277+
# 11) check that the staker cannot stake a block changing the coinstake scriptPubkey.
259278
# ----------------------------------------------------------------------------------
260-
print("*** 10 ***")
279+
print("*** 11 ***")
261280
self.log.info("Generating one invalid cold-stake block (changing first coinstake output)...")
262281
stakeable_coins = getDelegatedUtxos(self.nodes[0].listunspent())
263282
stakeInputs = self.get_prevouts(1, stakeable_coins)
264283
assert_greater_than(len(stakeInputs), 0)
265284
# Create the block (with dummy key)
266-
new_block = self.stake_next_block(1, stakeInputs, None, "")
285+
new_block = self.stake_next_block(1, stakeInputs, self.mocktime, "")
267286
self.log.info("New block created (rawtx) by cold-staking. Trying to submit...")
268287
# Try to submit the block
269288
ret = self.nodes[1].submitblock(bytes_to_hex_str(new_block.serialize()))
@@ -277,15 +296,15 @@ def run_test(self):
277296
self.checkBalances()
278297
self.log.info("Balances check out after (non) staked block")
279298

280-
# 11) neither adding different outputs to the coinstake.
299+
# 12) neither adding different outputs to the coinstake.
281300
# ------------------------------------------------------
282-
print("*** 11 ***")
301+
print("*** 12 ***")
283302
self.log.info("Generating another invalid cold-stake block (adding coinstake output)...")
284303
stakeable_coins = getDelegatedUtxos(self.nodes[0].listunspent())
285304
stakeInputs = self.get_prevouts(1, stakeable_coins)
286305
assert_greater_than(len(stakeInputs), 0)
287306
# Create the block
288-
new_block = self.stake_next_block(1, stakeInputs, None, staker_privkey)
307+
new_block = self.stake_next_block(1, stakeInputs, self.mocktime, staker_privkey)
289308
# Add output (dummy key address) to coinstake (taking 100 PIV from the pot)
290309
self.add_output_to_coinstake(new_block, 100)
291310
self.log.info("New block created (rawtx) by cold-staking. Trying to submit...")
@@ -301,20 +320,20 @@ def run_test(self):
301320
self.checkBalances()
302321
self.log.info("Balances check out after (non) staked block")
303322

304-
# 12) Now node[0] gets mad and spends all the delegated coins, voiding the P2CS contracts.
323+
# 13) Now node[0] gets mad and spends all the delegated coins, voiding the P2CS contracts.
305324
# ----------------------------------------------------------------------------------------
306325
self.log.info("Let's void the contracts.")
307-
self.generateBlock()
326+
self.mocktime = self.generate_pos(2, self.mocktime)
308327
sync_blocks(self.nodes)
309-
print("*** 12 ***")
328+
print("*** 13 ***")
310329
self.log.info("Cancel the stake delegation spending the delegated utxos...")
311330
delegated_utxos = getDelegatedUtxos(self.nodes[0].listunspent())
312331
# remove one utxo to spend later
313332
final_spend = delegated_utxos.pop()
314333
txhash = self.spendUTXOsWithNode(delegated_utxos, 0)
315334
assert(txhash != None)
316335
self.log.info("Good. Owner was able to void the stake delegations - tx: %s" % str(txhash))
317-
self.generateBlock()
336+
self.mocktime = self.generate_pos(2, self.mocktime)
318337
sync_blocks(self.nodes)
319338

320339
# deactivate SPORK 17 and check that the owner can still spend the last utxo
@@ -323,7 +342,7 @@ def run_test(self):
323342
txhash = self.spendUTXOsWithNode([final_spend], 0)
324343
assert(txhash != None)
325344
self.log.info("Good. Owner was able to void a stake delegation (with SPORK 17 disabled) - tx: %s" % str(txhash))
326-
self.generateBlock()
345+
self.mocktime = self.generate_pos(2, self.mocktime)
327346
sync_blocks(self.nodes)
328347

329348
# check balances after big spend.
@@ -334,42 +353,34 @@ def run_test(self):
334353
self.setColdStakingEnforcement()
335354
assert (self.isColdStakingEnforced())
336355

337-
# 13) check that coinstaker is empty and can no longer stake.
356+
# 14) check that coinstaker is empty and can no longer stake.
338357
# -----------------------------------------------------------
339-
print("*** 13 ***")
358+
print("*** 14 ***")
340359
self.log.info("Trying to generate one cold-stake block again...")
341360
assert_equal(self.nodes[1].getstakingstatus()["stakeablecoins"], False)
342361
self.log.info("Cigar. Cold staker was NOT able to create any more blocks.")
343362

344-
# 14) check balances when mature.
363+
# 15) check balances when mature.
345364
# -----------------------------------------------------------
346-
print("*** 14 ***")
365+
print("*** 15 ***")
347366
self.log.info("Staking 100 blocks to mature the cold stakes...")
348-
self.generateBlock(100)
367+
for i in range(2):
368+
for peer in [0, 2]:
369+
for j in range(25):
370+
self.mocktime = self.generate_pos(peer, self.mocktime)
371+
sync_blocks(self.nodes)
349372
self.expected_balance = self.expected_immature_balance
350373
self.expected_immature_balance = 0
351374
self.checkBalances()
352375
delegated_utxos = getDelegatedUtxos(self.nodes[0].listunspent())
353376
txhash = self.spendUTXOsWithNode(delegated_utxos, 0)
354377
assert (txhash != None)
355378
self.log.info("Good. Owner was able to spend the cold staked coins - tx: %s" % str(txhash))
356-
self.generateBlock()
379+
self.mocktime = self.generate_pos(2, self.mocktime)
357380
sync_blocks(self.nodes)
358381
self.expected_balance = 0
359382
self.checkBalances()
360383

361-
def generateBlock(self, n=1, nodeid=2):
362-
fStaked = False
363-
while (not fStaked):
364-
try:
365-
self.nodes[nodeid].generate(n)
366-
fStaked = True
367-
except JSONRPCException as e:
368-
if ("Couldn't create new block" in str(e)):
369-
# Sleep two seconds and retry
370-
sleep(2)
371-
else:
372-
raise e
373384

374385
def checkBalances(self):
375386
w_info = self.nodes[0].getwalletinfo()

test/functional/mining_pos_reorg.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,6 @@ def findUtxoInList(txid, vout, utxo_list):
7070
for nblock in range(5):
7171
self.mocktime = self.generate_pos(peer, self.mocktime)
7272
sync_blocks(self.nodes)
73-
set_node_times(self.nodes, self.mocktime)
7473
block_time_0 = block_time_1 = self.mocktime
7574
self.log.info("Blocks staked.")
7675

test/functional/test_framework/test_framework.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -725,9 +725,6 @@ def test_PoS_chain_balances(self):
725725
assert_equal(zcBalance['Immature'], 0)
726726
if peer == 2:
727727
assert_equal(len(zclist), len(zclist_spendable))
728-
else:
729-
# last mints added on accumulators - not spendable
730-
assert_equal(0, len(zclist_spendable))
731728
assert_equal(set([x['denomination'] for x in zclist]), set(vZC_DENOMS))
732729
assert_equal([x['confirmations'] for x in zclist], [30-peer] * len(vZC_DENOMS))
733730

0 commit comments

Comments
 (0)