/ test / functional / rpc_dumptxoutset.py
rpc_dumptxoutset.py
 1  #!/usr/bin/env python3
 2  # Copyright (c) 2019-2022 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.
 5  """Test the generation of UTXO snapshots using `dumptxoutset`.
 6  """
 7  
 8  from test_framework.blocktools import COINBASE_MATURITY
 9  from test_framework.test_framework import BitcoinTestFramework
10  from test_framework.util import (
11      assert_equal,
12      assert_raises_rpc_error,
13      sha256sum_file,
14  )
15  
16  
17  class DumptxoutsetTest(BitcoinTestFramework):
18      def set_test_params(self):
19          self.setup_clean_chain = True
20          self.num_nodes = 1
21  
22      def check_expected_network(self, node, active):
23          rev_file = node.blocks_path / "rev00000.dat"
24          bogus_file = node.blocks_path / "bogus.dat"
25          rev_file.rename(bogus_file)
26          assert_raises_rpc_error(
27              -1, 'Could not roll back to requested height.', node.dumptxoutset, 'utxos.dat', rollback=99)
28          assert_equal(node.getnetworkinfo()['networkactive'], active)
29  
30          # Cleanup
31          bogus_file.rename(rev_file)
32  
33      def run_test(self):
34          """Test a trivial usage of the dumptxoutset RPC command."""
35          node = self.nodes[0]
36          mocktime = node.getblockheader(node.getblockhash(0))['time'] + 1
37          node.setmocktime(mocktime)
38          self.generate(node, COINBASE_MATURITY)
39  
40          FILENAME = 'txoutset.dat'
41          out = node.dumptxoutset(FILENAME, "latest")
42          expected_path = node.chain_path / FILENAME
43  
44          assert expected_path.is_file()
45  
46          assert_equal(out['coins_written'], 100)
47          assert_equal(out['base_height'], 100)
48          assert_equal(out['path'], str(expected_path))
49          # Blockhash should be deterministic based on mocked time.
50          assert_equal(
51              out['base_hash'],
52              '09abf0e7b510f61ca6cf33bab104e9ee99b3528b371d27a2d4b39abb800fba7e')
53  
54          # UTXO snapshot hash should be deterministic based on mocked time.
55          assert_equal(
56              sha256sum_file(str(expected_path)).hex(),
57              '31fcdd0cf542a4b1dfc13c3c05106620ce48951ef62907dd8e5e8c15a0aa993b')
58  
59          assert_equal(
60              out['txoutset_hash'], 'a0b7baa3bf5ccbd3279728f230d7ca0c44a76e9923fca8f32dbfd08d65ea496a')
61          assert_equal(out['nchaintx'], 101)
62  
63          # Specifying a path to an existing or invalid file will fail.
64          assert_raises_rpc_error(
65              -8, '{} already exists'.format(FILENAME),  node.dumptxoutset, FILENAME, "latest")
66          invalid_path = node.datadir_path / "invalid" / "path"
67          assert_raises_rpc_error(
68              -8, "Couldn't open file {}.incomplete for writing".format(invalid_path), node.dumptxoutset, invalid_path, "latest")
69  
70          self.log.info("Test that dumptxoutset with unknown dump type fails")
71          assert_raises_rpc_error(
72              -8, 'Invalid snapshot type "bogus" specified. Please specify "rollback" or "latest"', node.dumptxoutset, 'utxos.dat', "bogus")
73  
74          self.log.info("Test that dumptxoutset failure does not leave the network activity suspended when it was on previously")
75          self.check_expected_network(node, True)
76  
77          self.log.info("Test that dumptxoutset failure leaves the network activity suspended when it was off")
78          node.setnetworkactive(False)
79          self.check_expected_network(node, False)
80          node.setnetworkactive(True)
81  
82  
83  if __name__ == '__main__':
84      DumptxoutsetTest(__file__).main()