Skip to content

Commit 01297fe

Browse files
committed
squash: WIP test for custom_address_update protocol change
1 parent 4398b1b commit 01297fe

File tree

3 files changed

+181
-1
lines changed

3 files changed

+181
-1
lines changed
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
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 that nodes with support for custom reward addresses are compatible
7+
# to nodes without it before the change actually activates. For this,
8+
# we run two masternodes (one with and one without support) and check
9+
# that they can both see each other's masternode.
10+
#
11+
# We use five nodes:
12+
# - node 0 is a masternode with default protocol (i.e. "new")
13+
# - node 1 is a masternode with previous protocol (i.e. "old")
14+
# - nodes 2-4 are just used to get above the "three full nodes" threshold
15+
# (together with node 3, independent of the masternodes online)
16+
17+
from test_framework import BitcoinTestFramework
18+
from util import *
19+
from masternode import *
20+
21+
import collections
22+
import time
23+
24+
OLD_PROTOCOL = 70915
25+
NEW_PROTOCOL = 71000
26+
27+
28+
def args_for (n):
29+
base = ["-debug", "-nolistenonion", "-activeversion=%d" % OLD_PROTOCOL]
30+
if n == 1:
31+
base.extend (["-protocolversion=%d" % OLD_PROTOCOL])
32+
return base
33+
34+
35+
class CustomAddressUpdateTest (BitcoinTestFramework):
36+
37+
def setup_chain (self):
38+
for i in range (5):
39+
initialize_datadir (self.options.tmpdir, i)
40+
41+
def setup_network (self, config_line=None, extra_args=[]):
42+
self.nodes = [
43+
start_node (i, self.options.tmpdir, extra_args=args_for (i))
44+
for i in range (5)
45+
]
46+
47+
# We want to work with mock times that are beyond the genesis
48+
# block timestamp but before current time (so that nodes being
49+
# started up and before they get on mocktime aren't rejecting
50+
# the on-disk blockchain).
51+
self.time = 1580000000
52+
assert self.time < time.time ()
53+
set_node_times (self.nodes, self.time)
54+
55+
connect_nodes (self.nodes[0], 2)
56+
connect_nodes (self.nodes[1], 2)
57+
connect_nodes (self.nodes[2], 3)
58+
connect_nodes (self.nodes[2], 4)
59+
connect_nodes (self.nodes[3], 4)
60+
61+
self.is_network_split = False
62+
63+
def start_node (self, n):
64+
"""Starts node n (0 or 1) with the proper arguments
65+
and masternode config for it."""
66+
67+
assert n in [0, 1]
68+
configs = [[c.getLine ()] for c in self.cfg]
69+
70+
args = args_for (n)
71+
args.append ("-masternode")
72+
args.append ("-masternodeprivkey=%s" % self.cfg[n].privkey)
73+
args.append ("-masternodeaddr=127.0.0.1:%d" % p2p_port (n))
74+
75+
self.nodes[n] = start_node (n, self.options.tmpdir,
76+
extra_args=args, mn_config_lines=configs[n])
77+
self.nodes[n].setmocktime (self.time)
78+
79+
for i in [2, 3, 4]:
80+
connect_nodes (self.nodes[n], i)
81+
sync_blocks (self.nodes)
82+
83+
def stop_node (self, n):
84+
"""Stops node n."""
85+
86+
stop_node (self.nodes[n], n)
87+
self.nodes[n] = None
88+
89+
def advance_time (self, dt=1):
90+
"""Advances mocktime by the given number of seconds."""
91+
92+
self.time += dt
93+
set_node_times (self.nodes, self.time)
94+
95+
def mine_blocks (self, n):
96+
"""Mines blocks with node 2."""
97+
98+
self.nodes[2].setgenerate(True, n)
99+
sync_blocks (self.nodes)
100+
101+
def run_test (self):
102+
assert_equal (self.nodes[0].getnetworkinfo ()["protocolversion"], NEW_PROTOCOL)
103+
assert_equal (self.nodes[1].getnetworkinfo ()["protocolversion"], OLD_PROTOCOL)
104+
105+
self.fund_masternodes ()
106+
self.start_masternodes ()
107+
108+
def fund_masternodes (self):
109+
print ("Funding masternodes...")
110+
111+
# The collateral needs 15 confirmations, and the masternode broadcast
112+
# signature must be later than that block's timestamp. Thus we start
113+
# with a very early timestamp.
114+
genesis = self.nodes[0].getblockhash (0)
115+
genesisTime = self.nodes[0].getblockheader (genesis)["time"]
116+
assert genesisTime < self.time
117+
set_node_times (self.nodes, genesisTime)
118+
119+
self.nodes[0].setgenerate (True, 1)
120+
sync_blocks (self.nodes)
121+
self.nodes[1].setgenerate (True, 1)
122+
sync_blocks (self.nodes)
123+
self.mine_blocks (25)
124+
assert_equal (self.nodes[0].getbalance (), 1250)
125+
assert_equal (self.nodes[1].getbalance (), 1250)
126+
127+
id1 = self.nodes[0].allocatefunds ("masternode", "mn1", "copper")["txhash"]
128+
id2 = self.nodes[1].allocatefunds ("masternode", "mn2", "copper")["txhash"]
129+
sync_mempools (self.nodes)
130+
self.mine_blocks (15)
131+
set_node_times (self.nodes, self.time)
132+
self.mine_blocks (1)
133+
134+
self.cfg = [
135+
fund_masternode (self.nodes[0], "mn1", "copper", id1, "localhost:%d" % p2p_port (0)),
136+
fund_masternode (self.nodes[1], "mn2", "copper", id2, "localhost:%d" % p2p_port (1)),
137+
]
138+
139+
def start_masternodes (self):
140+
print ("Starting masternodes...")
141+
142+
for i in range (2):
143+
self.stop_node (i)
144+
self.start_node (i)
145+
res = self.nodes[i].startmasternode ("mn%d" % (i + 1))
146+
assert_equal (res, {"status": "success"})
147+
148+
# Check status of the masternodes themselves.
149+
for i in [0, 1]:
150+
data = self.nodes[i].getmasternodestatus ()
151+
assert_equal (data["status"], 4)
152+
assert_equal (data["txhash"], self.cfg[i].txid)
153+
assert_equal (data["outputidx"], self.cfg[i].vout)
154+
assert_equal (data["message"], "Masternode successfully started")
155+
156+
# Both masternodes should see each other, independent of the
157+
# protocol version used.
158+
lists = [[]] * 2
159+
for i in range (2):
160+
lists[i] = self.nodes[i].listmasternodes ()
161+
while len (lists[i]) < 2:
162+
time.sleep (0.1)
163+
lists[i] = self.nodes[i].listmasternodes ()
164+
assert_equal (lists[0], lists[1])
165+
166+
lst = lists[0]
167+
assert_equal (len (lst), 2)
168+
for i in range (2):
169+
assert_equal (lst[i]["tier"], "COPPER")
170+
assert_equal (lst[i]["status"], "ENABLED")
171+
n = self.nodes[i]
172+
for key in ["addr", "rewardscript"]:
173+
assert_equal (lst[i][key], n.getmasternodestatus ()[key])
174+
assert_equal (lst[i]["txhash"], self.cfg[i].txid)
175+
assert_equal (lst[i]["outidx"], self.cfg[i].vout)
176+
177+
178+
if __name__ == '__main__':
179+
CustomAddressUpdateTest ().main ()

divi/qa/rpc-tests/test_runner.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
'StakingVaultStaking.py',
7878
'StakingVaultDeactivation.py',
7979
'StakingVaultSpam.py',
80+
'custom_address_update.py',
8081
'forknotify.py',
8182
'getchaintips.py',
8283
'httpbasics.py',

divi/src/activemasternode.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,4 +253,4 @@ bool CActiveMasternode::UpdatePing(CMasternodePing& mnp) const
253253
return true;
254254
}
255255
return false;
256-
}
256+
}

0 commit comments

Comments
 (0)