Skip to content

Commit 8c500df

Browse files
random-zebraFuzzbawls
authored andcommitted
Tests: Add sapling_fillblock functional test
Github-Pull: #2062 Rebased-From: e0d9a08
1 parent ce7f265 commit 8c500df

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2020 The PIVX developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or https://www.opensource.org/licenses/mit-license.php .
5+
6+
from test_framework.test_framework import PivxTestFramework
7+
8+
from test_framework.util import (
9+
assert_greater_than,
10+
assert_greater_than_or_equal,
11+
assert_equal,
12+
Decimal,
13+
satoshi_round,
14+
sync_blocks,
15+
sync_mempools,
16+
)
17+
18+
import time
19+
20+
def timed(f):
21+
start = time.time()
22+
ret = f()
23+
elapsed = time.time() - start
24+
return ret, elapsed
25+
26+
MAX_SHIELDED_BLOCKSIZE = 750000
27+
28+
class SaplingFillBlockTest(PivxTestFramework):
29+
30+
def set_test_params(self):
31+
self.num_nodes = 2
32+
self.setup_clean_chain = True
33+
self.extra_args = [["-blockmaxsize=1999000"], []]
34+
35+
def utxo_splitter(self, node_from, n_inputs, node_to):
36+
txids = []
37+
# collect utxos
38+
utxos = node_from.listunspent()
39+
assert_greater_than_or_equal(len(utxos), n_inputs)
40+
# sort by size
41+
sorted(utxos, key=lambda utxo: utxo["amount"], reverse=True)
42+
# pick the first N
43+
utxos = utxos[:n_inputs]
44+
# split each one in 100 (use fixed 0.05 PIV fee)
45+
for u in utxos:
46+
prevout = [{"txid": u["txid"], "vout": u["vout"]}]
47+
output_amt = satoshi_round((u["amount"] - Decimal("0.05")) / 100)
48+
recipients = {node_to.getnewaddress(): output_amt for _ in range(100)}
49+
rawTx_unsigned = node_from.createrawtransaction(prevout, recipients)
50+
rawTx_signed = node_from.signrawtransaction(rawTx_unsigned)["hex"]
51+
txids.append(node_from.sendrawtransaction(rawTx_signed))
52+
return txids
53+
54+
def check_mempool(self, miner, txids):
55+
self.log.info("Checking mempool...")
56+
sync_mempools(self.nodes)
57+
mempool_info = miner.getmempoolinfo()
58+
assert_equal(mempool_info['size'], len(txids))
59+
mempool_bytes = mempool_info['bytes']
60+
self.log.info("Miner's mempool size: %d bytes" % mempool_bytes)
61+
assert_greater_than_or_equal(mempool_bytes, 1000000)
62+
63+
def mine_and_checkblock(self, miner, alice):
64+
self.log.info("Mining the block...")
65+
bhash, elapsed = timed(lambda: miner.generate(1)[0])
66+
self.log.info("Block mined in %d seconds" % elapsed)
67+
_, elapsed = timed(lambda: self.sync_all())
68+
bsize = alice.getblock(bhash, True)["size"]
69+
self.log.info("Peers synced in %d seconds. Block size: %d" % (elapsed, bsize))
70+
# Only shielded txes in mempool. Block size must be below
71+
# MAX_SHIELDED_BLOCKSIZE + 513 (header + coinbase + coinstake)
72+
assert_greater_than(MAX_SHIELDED_BLOCKSIZE + 513, bsize)
73+
74+
def send_shielded(self, node, n_txes, from_address, shield_to):
75+
txids = []
76+
for i in range(n_txes):
77+
txids.append(node.shieldedsendmany(from_address, shield_to))
78+
if (i + 1) % 200 == 0:
79+
self.log.info("...%d Transactions created..." % (i + 1))
80+
return txids
81+
82+
83+
def run_test(self):
84+
miner = self.nodes[0]
85+
alice = self.nodes[1]
86+
# First mine 300 blocks
87+
self.log.info("Generating 300 blocks...")
88+
miner.generate(300)
89+
sync_blocks(self.nodes)
90+
assert_equal(self.nodes[0].getblockchaininfo()['upgrades']['v5 shield']['status'], 'active')
91+
92+
## -- First check that the miner never produces blocks with more than 750kB of shielded txes
93+
94+
# Split 10 utxos (of 250 PIV each) in 1000 new utxos of ~2.5 PIV each (to alice)
95+
UTXOS_TO_SPLIT = 10
96+
UTXOS_TO_SHIELD = UTXOS_TO_SPLIT * 100
97+
self.log.info("Creating %d utxos..." % UTXOS_TO_SHIELD)
98+
txids = self.utxo_splitter(miner, UTXOS_TO_SPLIT, alice)
99+
assert_equal(len(txids), UTXOS_TO_SPLIT)
100+
miner.generate(2)
101+
sync_blocks(self.nodes)
102+
new_utxos = alice.listunspent()
103+
assert_equal(len(new_utxos), UTXOS_TO_SHIELD)
104+
105+
# Now alice shields the new utxos individually (fixed 0.2 PIV fee --> ~2.3 PIV notes)
106+
self.log.info("Shielding utxos...")
107+
alice_z_addr = alice.getnewshieldedaddress()
108+
shield_to = [{"address": alice_z_addr, "amount": new_utxos[0]["amount"] - Decimal("0.2")}]
109+
txids = self.send_shielded(alice, UTXOS_TO_SHIELD, "from_transparent", shield_to)
110+
111+
# Check mempool
112+
self.check_mempool(miner, txids)
113+
114+
# Mine the block
115+
self.mine_and_checkblock(miner, alice)
116+
self.log.info("Done. %d txes still in mempool." % miner.getmempoolinfo()['size'])
117+
118+
119+
if __name__ == '__main__':
120+
SaplingFillBlockTest().main()

test/functional/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@
160160
# These tests are not run by the travis build process.
161161
# Longest test should go first, to favor running tests in parallel
162162
# vv Tests less than 20m vv
163+
'sapling_fillblock.py', # ~ 780 sec
163164
'feature_fee_estimation.py', # ~ 360 sec
164165
# vv Tests less than 5m vv
165166
# vv Tests less than 2m vv

0 commit comments

Comments
 (0)