wallet_startup.py raw
1 #!/usr/bin/env python3
2 # Copyright (c) 2017-2022 The Limenka developers
3 # Distributed under the MIT software license, see the accompanying
4 # file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 """Test wallet load on startup.
6
7 Verify that a limenkad node can maintain list of wallets loading on startup
8 """
9 import os
10 import stat
11
12 from test_framework.test_framework import LimenkaTestFramework
13 from test_framework.util import (
14 assert_equal,
15 assert_raises_rpc_error,
16 is_dir_writable,
17 )
18
19
20 class WalletStartupTest(LimenkaTestFramework):
21 def add_options(self, parser):
22 self.add_wallet_options(parser)
23
24 def set_test_params(self):
25 self.setup_clean_chain = True
26 self.num_nodes = 1
27 self.supports_cli = True
28
29 def skip_test_if_missing_module(self):
30 self.skip_if_no_wallet()
31
32 def setup_nodes(self):
33 self.add_nodes(self.num_nodes)
34 self.start_nodes()
35
36 def test_load_unwritable_wallet(self, node):
37 self.log.info("Test wallet load failure due to non-writable directory")
38 wallet_name = "bad_permissions"
39
40 node.createwallet(wallet_name)
41 node.unloadwallet(wallet_name)
42
43 dir_path = node.wallets_path / wallet_name
44 original_dir_perms = dir_path.stat().st_mode
45 os.chmod(dir_path, original_dir_perms & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH))
46
47 if is_dir_writable(dir_path):
48 self.log.warning("Skipping load non-writable directory test: unable to enforce read-only permissions")
49 else:
50 # Ensure we don't load a wallet located in a non-writable directory.
51 # The node will crash later on if we cannot write to disk.
52 assert_raises_rpc_error(-4, f"Failed to open database in directory '{str(dir_path)}': directory is not writable", node.loadwallet, wallet_name)
53
54 # Reset directory permissions for cleanup
55 dir_path.chmod(original_dir_perms)
56
57 def run_test(self):
58 self.log.info('Should start without any wallets')
59 assert_equal(self.nodes[0].listwallets(), [])
60 assert_equal(self.nodes[0].listwalletdir(), {'wallets': []})
61
62 self.log.info('New default wallet should load by default when there are no other wallets')
63 self.nodes[0].createwallet(wallet_name='', load_on_startup=False)
64 self.restart_node(0)
65 assert_equal(self.nodes[0].listwallets(), [''])
66
67 self.log.info('Test load on startup behavior')
68 self.nodes[0].createwallet(wallet_name='w0', load_on_startup=True)
69 self.nodes[0].createwallet(wallet_name='w1', load_on_startup=False)
70 self.nodes[0].createwallet(wallet_name='w2', load_on_startup=True)
71 self.nodes[0].createwallet(wallet_name='w3', load_on_startup=False)
72 self.nodes[0].createwallet(wallet_name='w4', load_on_startup=False)
73 self.nodes[0].unloadwallet(wallet_name='w0', load_on_startup=False)
74 self.nodes[0].unloadwallet(wallet_name='w4', load_on_startup=False)
75 self.nodes[0].loadwallet(filename='w4', load_on_startup=True)
76 assert_equal(set(self.nodes[0].listwallets()), set(('', 'w1', 'w2', 'w3', 'w4')))
77 self.restart_node(0)
78 assert_equal(set(self.nodes[0].listwallets()), set(('', 'w2', 'w4')))
79 self.nodes[0].unloadwallet(wallet_name='', load_on_startup=False)
80 self.nodes[0].unloadwallet(wallet_name='w4', load_on_startup=False)
81 self.nodes[0].loadwallet(filename='w3', load_on_startup=True)
82 self.nodes[0].loadwallet(filename='')
83 self.restart_node(0)
84 assert_equal(set(self.nodes[0].listwallets()), set(('w2', 'w3')))
85
86 self.test_load_unwritable_wallet(self.nodes[0])
87
88 if __name__ == '__main__':
89 WalletStartupTest(__file__).main()
90