add test for -walletrejectlongchains
[bitcoinplatinum.git] / qa / rpc-tests / walletbackup.py
blobe12cb10a50ad74769db771ddb0197c29c5cbf700
1 #!/usr/bin/env python3
2 # Copyright (c) 2014-2016 The Bitcoin Core developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
6 """
7 Exercise the wallet backup code. Ported from walletbackup.sh.
9 Test case is:
10 4 nodes. 1 2 and 3 send transactions between each other,
11 fourth node is a miner.
12 1 2 3 each mine a block to start, then
13 Miner creates 100 blocks so 1 2 3 each have 50 mature
14 coins to spend.
15 Then 5 iterations of 1/2/3 sending coins amongst
16 themselves to get transactions in the wallets,
17 and the miner mining one block.
19 Wallets are backed up using dumpwallet/backupwallet.
20 Then 5 more iterations of transactions and mining a block.
22 Miner then generates 101 more blocks, so any
23 transaction fees paid mature.
25 Sanity check:
26 Sum(1,2,3,4 balances) == 114*50
28 1/2/3 are shutdown, and their wallets erased.
29 Then restore using wallet.dat backup. And
30 confirm 1/2/3/4 balances are same as before.
32 Shutdown again, restore using importwallet,
33 and confirm again balances are correct.
34 """
36 from test_framework.test_framework import BitcoinTestFramework
37 from test_framework.util import *
38 from random import randint
39 import logging
40 logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO, stream=sys.stdout)
42 class WalletBackupTest(BitcoinTestFramework):
44 def __init__(self):
45 super().__init__()
46 self.setup_clean_chain = True
47 self.num_nodes = 4
48 # nodes 1, 2,3 are spenders, let's give them a keypool=100
49 self.extra_args = [["-keypool=100"], ["-keypool=100"], ["-keypool=100"], []]
51 # This mirrors how the network was setup in the bash test
52 def setup_network(self, split=False):
53 self.nodes = start_nodes(self.num_nodes, self.options.tmpdir, self.extra_args)
54 connect_nodes(self.nodes[0], 3)
55 connect_nodes(self.nodes[1], 3)
56 connect_nodes(self.nodes[2], 3)
57 connect_nodes(self.nodes[2], 0)
58 self.is_network_split=False
59 self.sync_all()
61 def one_send(self, from_node, to_address):
62 if (randint(1,2) == 1):
63 amount = Decimal(randint(1,10)) / Decimal(10)
64 self.nodes[from_node].sendtoaddress(to_address, amount)
66 def do_one_round(self):
67 a0 = self.nodes[0].getnewaddress()
68 a1 = self.nodes[1].getnewaddress()
69 a2 = self.nodes[2].getnewaddress()
71 self.one_send(0, a1)
72 self.one_send(0, a2)
73 self.one_send(1, a0)
74 self.one_send(1, a2)
75 self.one_send(2, a0)
76 self.one_send(2, a1)
78 # Have the miner (node3) mine a block.
79 # Must sync mempools before mining.
80 sync_mempools(self.nodes)
81 self.nodes[3].generate(1)
82 sync_blocks(self.nodes)
84 # As above, this mirrors the original bash test.
85 def start_three(self):
86 self.nodes[0] = start_node(0, self.options.tmpdir)
87 self.nodes[1] = start_node(1, self.options.tmpdir)
88 self.nodes[2] = start_node(2, self.options.tmpdir)
89 connect_nodes(self.nodes[0], 3)
90 connect_nodes(self.nodes[1], 3)
91 connect_nodes(self.nodes[2], 3)
92 connect_nodes(self.nodes[2], 0)
94 def stop_three(self):
95 stop_node(self.nodes[0], 0)
96 stop_node(self.nodes[1], 1)
97 stop_node(self.nodes[2], 2)
99 def erase_three(self):
100 os.remove(self.options.tmpdir + "/node0/regtest/wallet.dat")
101 os.remove(self.options.tmpdir + "/node1/regtest/wallet.dat")
102 os.remove(self.options.tmpdir + "/node2/regtest/wallet.dat")
104 def run_test(self):
105 logging.info("Generating initial blockchain")
106 self.nodes[0].generate(1)
107 sync_blocks(self.nodes)
108 self.nodes[1].generate(1)
109 sync_blocks(self.nodes)
110 self.nodes[2].generate(1)
111 sync_blocks(self.nodes)
112 self.nodes[3].generate(100)
113 sync_blocks(self.nodes)
115 assert_equal(self.nodes[0].getbalance(), 50)
116 assert_equal(self.nodes[1].getbalance(), 50)
117 assert_equal(self.nodes[2].getbalance(), 50)
118 assert_equal(self.nodes[3].getbalance(), 0)
120 logging.info("Creating transactions")
121 # Five rounds of sending each other transactions.
122 for i in range(5):
123 self.do_one_round()
125 logging.info("Backing up")
126 tmpdir = self.options.tmpdir
127 self.nodes[0].backupwallet(tmpdir + "/node0/wallet.bak")
128 self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.dump")
129 self.nodes[1].backupwallet(tmpdir + "/node1/wallet.bak")
130 self.nodes[1].dumpwallet(tmpdir + "/node1/wallet.dump")
131 self.nodes[2].backupwallet(tmpdir + "/node2/wallet.bak")
132 self.nodes[2].dumpwallet(tmpdir + "/node2/wallet.dump")
134 logging.info("More transactions")
135 for i in range(5):
136 self.do_one_round()
138 # Generate 101 more blocks, so any fees paid mature
139 self.nodes[3].generate(101)
140 self.sync_all()
142 balance0 = self.nodes[0].getbalance()
143 balance1 = self.nodes[1].getbalance()
144 balance2 = self.nodes[2].getbalance()
145 balance3 = self.nodes[3].getbalance()
146 total = balance0 + balance1 + balance2 + balance3
148 # At this point, there are 214 blocks (103 for setup, then 10 rounds, then 101.)
149 # 114 are mature, so the sum of all wallets should be 114 * 50 = 5700.
150 assert_equal(total, 5700)
153 # Test restoring spender wallets from backups
155 logging.info("Restoring using wallet.dat")
156 self.stop_three()
157 self.erase_three()
159 # Start node2 with no chain
160 shutil.rmtree(self.options.tmpdir + "/node2/regtest/blocks")
161 shutil.rmtree(self.options.tmpdir + "/node2/regtest/chainstate")
163 # Restore wallets from backup
164 shutil.copyfile(tmpdir + "/node0/wallet.bak", tmpdir + "/node0/regtest/wallet.dat")
165 shutil.copyfile(tmpdir + "/node1/wallet.bak", tmpdir + "/node1/regtest/wallet.dat")
166 shutil.copyfile(tmpdir + "/node2/wallet.bak", tmpdir + "/node2/regtest/wallet.dat")
168 logging.info("Re-starting nodes")
169 self.start_three()
170 sync_blocks(self.nodes)
172 assert_equal(self.nodes[0].getbalance(), balance0)
173 assert_equal(self.nodes[1].getbalance(), balance1)
174 assert_equal(self.nodes[2].getbalance(), balance2)
176 logging.info("Restoring using dumped wallet")
177 self.stop_three()
178 self.erase_three()
180 #start node2 with no chain
181 shutil.rmtree(self.options.tmpdir + "/node2/regtest/blocks")
182 shutil.rmtree(self.options.tmpdir + "/node2/regtest/chainstate")
184 self.start_three()
186 assert_equal(self.nodes[0].getbalance(), 0)
187 assert_equal(self.nodes[1].getbalance(), 0)
188 assert_equal(self.nodes[2].getbalance(), 0)
190 self.nodes[0].importwallet(tmpdir + "/node0/wallet.dump")
191 self.nodes[1].importwallet(tmpdir + "/node1/wallet.dump")
192 self.nodes[2].importwallet(tmpdir + "/node2/wallet.dump")
194 sync_blocks(self.nodes)
196 assert_equal(self.nodes[0].getbalance(), balance0)
197 assert_equal(self.nodes[1].getbalance(), balance1)
198 assert_equal(self.nodes[2].getbalance(), balance2)
201 if __name__ == '__main__':
202 WalletBackupTest().main()