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