Skip to content

Commit 6aaff2f

Browse files
committed
Regtest for segwit light.
This adds the new regtest segwit_light.py, which verifies that sending of transactions and staking still works after the fork, and that the new rules work as expected. It also explicitly checks that transaction malleability is not an issue anymore for chains of pre-signed transactions.
1 parent 1d60f15 commit 6aaff2f

File tree

3 files changed

+121
-3
lines changed

3 files changed

+121
-3
lines changed

divi/qa/rpc-tests/around_segwit_light.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
from authproxy import JSONRPCException
1212
from util import *
1313

14-
ACTIVATION_TIME = 2_100_000_000
14+
from segwit_light import ACTIVATION_TIME
1515

1616
# Offset around the activation time where no restrictions are in place.
1717
NO_RESTRICTIONS = 24 * 3_600
@@ -123,12 +123,13 @@ def run_test (self):
123123
set_node_times (self.nodes, ACTIVATION_TIME - MEMPOOL_RESTRICTED)
124124
self.expect_mempool_restricted ("txid")
125125
set_node_times (self.nodes, ACTIVATION_TIME + MEMPOOL_RESTRICTED)
126-
self.expect_mempool_restricted ("txid")
126+
self.node.setgenerate (True, 1)
127+
self.expect_mempool_restricted ("baretxid")
127128

128129
# Finally, we should run into mempool-only or no restrictions
129130
# at all if we go further into the future, away from the fork.
130131
set_node_times (self.nodes, ACTIVATION_TIME + WALLET_RESTRICTED)
131-
self.expect_wallet_restricted ("txid")
132+
self.expect_wallet_restricted ("baretxid")
132133
set_node_times (self.nodes, ACTIVATION_TIME + NO_RESTRICTIONS)
133134
self.expect_unrestricted ()
134135

divi/qa/rpc-tests/segwit_light.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2020 The DIVI developers
3+
# Distributed under the MIT/X11 software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
6+
# Tests the policy changes in wallet and mempool around the
7+
# segwit-light activation time that prevent spending of
8+
# unconfirmed outputs.
9+
10+
from test_framework import BitcoinTestFramework
11+
from util import *
12+
13+
from PowToPosTransition import createPoSStacks, generatePoSBlocks
14+
15+
ACTIVATION_TIME = 2_000_000_000
16+
17+
18+
class SegwitLightTest (BitcoinTestFramework):
19+
20+
def setup_network (self, split=False):
21+
args = ["-debug", "-spendzeroconfchange"]
22+
self.nodes = start_nodes (2, self.options.tmpdir, extra_args=[args]*2)
23+
connect_nodes (self.nodes[0], 1)
24+
self.is_network_split = False
25+
26+
def run_test (self):
27+
# Activate the fork and PoS. We go beyond the fork to ensure
28+
# the mempool/wallet limitations are lifted already.
29+
set_node_times (self.nodes, ACTIVATION_TIME + 3_600 * 24 * 7)
30+
reconnect_all (self.nodes)
31+
self.nodes[0].setgenerate (True, 1)
32+
sync_blocks (self.nodes)
33+
createPoSStacks (self.nodes[:1], self.nodes)
34+
generatePoSBlocks (self.nodes, 0, 100)
35+
blk = self.nodes[1].getblockheader (self.nodes[1].getbestblockhash ())
36+
assert_greater_than (blk["time"], ACTIVATION_TIME)
37+
38+
# Send some normal transactions from the wallet (but in a chain).
39+
self.nodes[0].sendtoaddress (self.nodes[1].getnewaddress (), 1_000)
40+
generatePoSBlocks (self.nodes, 0, 1)
41+
assert_equal (self.nodes[1].getbalance (), 1_000)
42+
addr = self.nodes[0].getnewaddress ()
43+
id1 = self.nodes[1].sendtoaddress (addr, 900)
44+
id2 = self.nodes[1].sendtoaddress (addr, 90)
45+
id3 = self.nodes[1].sendtoaddress (addr, 9)
46+
assert_equal (set (self.nodes[1].getrawmempool ()), set ([id1, id2, id3]))
47+
sync_mempools (self.nodes)
48+
generatePoSBlocks (self.nodes, 0, 1)
49+
assert_equal (self.nodes[1].getrawmempool (), [])
50+
assert_greater_than (1, self.nodes[1].getbalance ())
51+
52+
# Build a transaction on top of an unconfirmed one, that we will malleate.
53+
# The prepared transaction should still be valid. For malleating, we use
54+
# funds on a 1-of-2 multisig address, and then change which wallet
55+
# is signing.
56+
keys = [
57+
n.validateaddress (n.getnewaddress ())["pubkey"]
58+
for n in self.nodes
59+
]
60+
multisig = self.nodes[0].addmultisigaddress (1, keys)
61+
assert_equal (self.nodes[1].addmultisigaddress (1, keys), multisig)
62+
txid0 = self.nodes[0].sendtoaddress (multisig, 1_000)
63+
data0 = self.nodes[0].getrawtransaction (txid0, 1)
64+
btxid = data0["baretxid"]
65+
outputIndex = None
66+
for i in range (len (data0["vout"])):
67+
if data0["vout"][i]["scriptPubKey"]["addresses"] == [multisig]:
68+
assert outputIndex is None
69+
outputIndex = i
70+
assert outputIndex is not None
71+
generatePoSBlocks (self.nodes, 0, 1)
72+
out = self.nodes[0].gettxout (btxid, outputIndex)
73+
assert_equal (out["confirmations"], 1)
74+
assert_equal (out["value"], 1_000)
75+
assert_equal (out["scriptPubKey"]["addresses"], [multisig])
76+
77+
inputs = [{"txid": btxid, "vout": outputIndex}]
78+
tempAddr = self.nodes[0].getnewaddress ("temp")
79+
outputs = {tempAddr: 999}
80+
unsigned1 = self.nodes[0].createrawtransaction (inputs, outputs)
81+
signed1 = self.nodes[0].signrawtransaction (unsigned1)
82+
assert_equal (signed1["complete"], True)
83+
signed1 = signed1["hex"]
84+
data1 = self.nodes[0].decoderawtransaction (signed1)
85+
86+
prevtx = [
87+
{
88+
"txid": data1["baretxid"],
89+
"vout": 0,
90+
"scriptPubKey": self.nodes[0].validateaddress (tempAddr)["scriptPubKey"],
91+
}
92+
]
93+
inputs = [{"txid": data1["baretxid"], "vout": 0}]
94+
finalAddr = self.nodes[1].getnewaddress ("final")
95+
outputs = {finalAddr: 998}
96+
unsigned2 = self.nodes[0].createrawtransaction (inputs, outputs)
97+
signed2 = self.nodes[0].signrawtransaction (unsigned2, prevtx)
98+
assert_equal (signed2["complete"], True)
99+
signed2 = signed2["hex"]
100+
data2 = self.nodes[0].decoderawtransaction (signed2)
101+
102+
signed1p = self.nodes[1].signrawtransaction (unsigned1)
103+
assert_equal (signed1p["complete"], True)
104+
signed1p = signed1p["hex"]
105+
data1p = self.nodes[0].decoderawtransaction (signed1p)
106+
assert_equal (data1["baretxid"], data1p["baretxid"])
107+
assert data1["txid"] != data1p["txid"]
108+
109+
self.nodes[0].sendrawtransaction (signed1p)
110+
self.nodes[0].sendrawtransaction (signed2)
111+
generatePoSBlocks (self.nodes, 0, 1)
112+
sync_blocks (self.nodes)
113+
assert_equal (self.nodes[1].getbalance ("final"), 998)
114+
115+
if __name__ == '__main__':
116+
SegwitLightTest ().main ()

divi/qa/rpc-tests/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@
105105
'rpcbind_test.py',
106106
'remotestart.py',
107107
'remotestart.py --outdated_ping',
108+
'segwit_light.py',
108109
'smartfees.py',
109110
'sync.py',
110111
'txindex.py',

0 commit comments

Comments
 (0)