2019-01-31 17:07:45 +01:00
#!/usr/bin/env python3
2023-08-16 19:27:31 +02:00
# Copyright (c) 2018-2020 The Bitcoin Core developers
2019-01-31 17:07:45 +01:00
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
""" Test dash-wallet. """
2019-07-08 14:56:59 +02:00
import hashlib
import os
import stat
2019-01-31 17:07:45 +01:00
import subprocess
import textwrap
2020-12-17 15:18:13 +01:00
from collections import OrderedDict
2019-01-31 17:07:45 +01:00
from test_framework . test_framework import BitcoinTestFramework
from test_framework . util import assert_equal
2019-07-08 14:56:59 +02:00
BUFFER_SIZE = 16 * 1024
2019-01-31 17:07:45 +01:00
class ToolWalletTest ( BitcoinTestFramework ) :
def set_test_params ( self ) :
self . num_nodes = 1
self . setup_clean_chain = True
2019-09-17 19:36:30 +02:00
self . rpc_timeout = 120
2019-01-31 17:07:45 +01:00
def skip_test_if_missing_module ( self ) :
self . skip_if_no_wallet ( )
Merge #17497: test: skip tests when utils haven't been compiled
a67352161c68fea9764cc31aff199f112d8572c6 test: skip tool_wallet test when bitcoin-wallet isn't compiled (fanquake)
e9277baed64e1d4054a102e40b39a9aed7839c2f test: skip wallet_listreceivedby test when the cli isn't compiled (fanquake)
621d398750d9f5ce3e7ec75ccb160b3534dcc436 test: skip bitcoin_cli test when the cli isn't compiled (fanquake)
Pull request description:
Don't try and run the `interface_bitcoin_cli.py` test when `bitcoin-cli` isn't available.
```bash
stdout:
2019-11-17T01:51:41.623000Z TestFramework (INFO): Initializing test directory /var/folders/z2/cn877pxd3czdfh47mfkmbwgm0000gn/T/test_runner_₿_🏃_20191116_205141/interface_bitcoin_cli_0
2019-11-17T01:51:41.890000Z TestFramework (ERROR): Unexpected exception caught during testing
Traceback (most recent call last):
File "/Users/michael/github/bitcoin/test/functional/test_framework/test_framework.py", line 111, in main
self.run_test()
File "/Users/michael/github/bitcoin/test/functional/interface_bitcoin_cli.py", line 18, in run_test
cli_response = self.nodes[0].cli("-version").send_cli()
File "/Users/michael/github/bitcoin/test/functional/test_framework/test_node.py", line 528, in send_cli
process = subprocess.Popen(p_args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
File "/Users/michael/.pyenv/versions/3.5.6/lib/python3.5/subprocess.py", line 676, in __init__
restore_signals, start_new_session)
File "/Users/michael/.pyenv/versions/3.5.6/lib/python3.5/subprocess.py", line 1289, in _execute_child
raise child_exception_type(errno_num, err_msg)
FileNotFoundError: [Errno 2] No such file or directory: '/Users/michael/github/bitcoin/src/bitcoin-cli'
```
Top commit has no ACKs.
Tree-SHA512: de27513a615d9d21271a0948e012c3209351e7374efd19bfa1bb9cda77e8fffe15d99e3424e4dbfa8cf826084f8af1670726f4703bd2b6093e7d37df4bea64f0
2019-11-19 16:11:27 +01:00
self . skip_if_no_wallet_tool ( )
2019-01-31 17:07:45 +01:00
def dash_wallet_process ( self , * args ) :
binary = self . config [ " environment " ] [ " BUILDDIR " ] + ' /src/dash-wallet ' + self . config [ " environment " ] [ " EXEEXT " ]
2020-12-16 17:43:15 +01:00
default_args = [ ' -datadir= {} ' . format ( self . nodes [ 0 ] . datadir ) , ' -chain= %s ' % self . chain ]
2020-12-18 07:55:51 +01:00
if self . options . descriptors and ' create ' in args :
2020-12-16 17:43:15 +01:00
default_args . append ( ' -descriptors ' )
return subprocess . Popen ( [ binary ] + default_args + list ( args ) , stdin = subprocess . PIPE , stdout = subprocess . PIPE , stderr = subprocess . PIPE , universal_newlines = True )
2019-01-31 17:07:45 +01:00
def assert_raises_tool_error ( self , error , * args ) :
p = self . dash_wallet_process ( * args )
stdout , stderr = p . communicate ( )
assert_equal ( p . poll ( ) , 1 )
assert_equal ( stdout , ' ' )
assert_equal ( stderr . strip ( ) , error )
def assert_tool_output ( self , output , * args ) :
p = self . dash_wallet_process ( * args )
stdout , stderr = p . communicate ( )
assert_equal ( stderr , ' ' )
assert_equal ( stdout , output )
2019-07-08 14:56:59 +02:00
assert_equal ( p . poll ( ) , 0 )
2019-01-31 17:07:45 +01:00
2019-07-08 14:56:59 +02:00
def wallet_shasum ( self ) :
h = hashlib . sha1 ( )
mv = memoryview ( bytearray ( BUFFER_SIZE ) )
with open ( self . wallet_path , ' rb ' , buffering = 0 ) as f :
for n in iter ( lambda : f . readinto ( mv ) , 0 ) :
h . update ( mv [ : n ] )
return h . hexdigest ( )
2019-01-31 17:07:45 +01:00
2019-07-08 14:56:59 +02:00
def wallet_timestamp ( self ) :
return os . path . getmtime ( self . wallet_path )
def wallet_permissions ( self ) :
return oct ( os . lstat ( self . wallet_path ) . st_mode ) [ - 3 : ]
def log_wallet_timestamp_comparison ( self , old , new ) :
result = ' unchanged ' if new == old else ' increased! '
self . log . debug ( ' Wallet file timestamp {} ' . format ( result ) )
2020-12-16 17:43:15 +01:00
def get_expected_info_output ( self , name = " " , transactions = 0 , keypool = 2 , address = 0 ) :
wallet_name = self . default_wallet_name if name == " " else name
output_types = 1 # p2pkh
if self . options . descriptors :
return textwrap . dedent ( ''' \
Wallet info
== == == == == =
Name : % s
Format : sqlite
Descriptors : yes
Encrypted : no
HD ( hd seed available ) : yes
Keypool Size : % d
Transactions : % d
Address Book : % d
''' % (wallet_name, keypool * output_types, transactions, address))
else :
return textwrap . dedent ( ''' \
Wallet info
== == == == == =
Name : % s
Format : bdb
Descriptors : no
Encrypted : no
HD ( hd seed available ) : yes
Keypool Size : % d
Transactions : % d
Address Book : % d
''' % (wallet_name, keypool, transactions, address * output_types))
2020-12-17 15:18:13 +01:00
def read_dump ( self , filename ) :
dump = OrderedDict ( )
with open ( filename , " r " , encoding = " utf8 " ) as f :
for row in f :
row = row . strip ( )
key , value = row . split ( ' , ' )
dump [ key ] = value
return dump
def assert_is_sqlite ( self , filename ) :
with open ( filename , ' rb ' ) as f :
file_magic = f . read ( 16 )
assert file_magic == b ' SQLite format 3 \x00 '
def assert_is_bdb ( self , filename ) :
with open ( filename , ' rb ' ) as f :
f . seek ( 12 , 0 )
file_magic = f . read ( 4 )
assert file_magic == b ' \x00 \x05 \x31 \x62 ' or file_magic == b ' \x62 \x31 \x05 \x00 '
def write_dump ( self , dump , filename , magic = None , skip_checksum = False ) :
if magic is None :
magic = " BITCOIN_CORE_WALLET_DUMP "
with open ( filename , " w " , encoding = " utf8 " ) as f :
row = " , " . join ( [ magic , dump [ magic ] ] ) + " \n "
f . write ( row )
for k , v in dump . items ( ) :
if k == magic or k == " checksum " :
continue
row = " , " . join ( [ k , v ] ) + " \n "
f . write ( row )
if not skip_checksum :
row = " , " . join ( [ " checksum " , dump [ " checksum " ] ] ) + " \n "
f . write ( row )
def assert_dump ( self , expected , received ) :
e = expected . copy ( )
r = received . copy ( )
# BDB will add a "version" record that is not present in sqlite
# In that case, we should ignore this record in both
# But because this also effects the checksum, we also need to drop that.
v_key = " 0776657273696f6e " # Version key
if v_key in e and v_key not in r :
del e [ v_key ]
del e [ " checksum " ]
del r [ " checksum " ]
if v_key not in e and v_key in r :
del r [ v_key ]
del e [ " checksum " ]
del r [ " checksum " ]
assert_equal ( len ( e ) , len ( r ) )
for k , v in e . items ( ) :
assert_equal ( v , r [ k ] )
def do_tool_createfromdump ( self , wallet_name , dumpfile , file_format = None ) :
dumppath = os . path . join ( self . nodes [ 0 ] . datadir , dumpfile )
rt_dumppath = os . path . join ( self . nodes [ 0 ] . datadir , " rt- {} .dump " . format ( wallet_name ) )
dump_data = self . read_dump ( dumppath )
args = [ " -wallet= {} " . format ( wallet_name ) ,
" -dumpfile= {} " . format ( dumppath ) ]
if file_format is not None :
args . append ( " -format= {} " . format ( file_format ) )
args . append ( " createfromdump " )
load_output = " "
if file_format is not None and file_format != dump_data [ " format " ] :
load_output + = " Warning: Dumpfile wallet format \" {} \" does not match command line specified format \" {} \" . \n " . format ( dump_data [ " format " ] , file_format )
self . assert_tool_output ( load_output , * args )
assert os . path . isdir ( os . path . join ( self . nodes [ 0 ] . datadir , " regtest/wallets " , wallet_name ) )
self . assert_tool_output ( " The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile. \n " , ' -wallet= {} ' . format ( wallet_name ) , ' -dumpfile= {} ' . format ( rt_dumppath ) , ' dump ' )
rt_dump_data = self . read_dump ( rt_dumppath )
wallet_dat = os . path . join ( self . nodes [ 0 ] . datadir , " regtest/wallets/ " , wallet_name , " wallet.dat " )
if rt_dump_data [ " format " ] == " bdb " :
self . assert_is_bdb ( wallet_dat )
else :
self . assert_is_sqlite ( wallet_dat )
2019-07-08 14:56:59 +02:00
def test_invalid_tool_commands_and_args ( self ) :
self . log . info ( ' Testing that various invalid commands raise with specific error messages ' )
2019-01-31 17:07:45 +01:00
self . assert_raises_tool_error ( ' Invalid command: foo ' , ' foo ' )
2019-07-08 14:56:59 +02:00
# `dash-wallet help` raises an error. Use `dash-wallet -help`.
2019-01-31 17:07:45 +01:00
self . assert_raises_tool_error ( ' Invalid command: help ' , ' help ' )
self . assert_raises_tool_error ( ' Error: two methods provided (info and create). Only one method should be provided. ' , ' info ' , ' create ' )
self . assert_raises_tool_error ( ' Error parsing command line arguments: Invalid parameter -foo ' , ' -foo ' )
2023-07-05 20:27:28 +02:00
locked_dir = os . path . join ( self . options . tmpdir , " node0 " , self . chain , " wallets " )
2020-11-02 16:54:06 +01:00
error = ' Error initializing wallet database environment " {} " ! ' . format ( locked_dir )
if self . options . descriptors :
error = " SQLiteDatabase: Unable to obtain an exclusive lock on the database, is it being used by another dashd? "
2022-03-03 20:34:50 +01:00
self . assert_raises_tool_error (
2023-02-15 05:07:34 +01:00
error ,
2022-11-30 20:23:48 +01:00
' -wallet= ' + self . default_wallet_name ,
2022-03-03 20:34:50 +01:00
' info ' ,
)
2023-07-05 20:27:28 +02:00
path = os . path . join ( self . options . tmpdir , " node0 " , self . chain , " wallets " , " nonexistent.dat " )
2022-10-17 04:33:10 +02:00
self . assert_raises_tool_error ( " Failed to load database path ' {} ' . Path does not exist. " . format ( path ) , ' -wallet=nonexistent.dat ' , ' info ' )
2019-01-31 17:07:45 +01:00
2019-07-08 14:56:59 +02:00
def test_tool_wallet_info ( self ) :
# Stop the node to close the wallet to call the info command.
2019-01-31 17:07:45 +01:00
self . stop_node ( 0 )
2019-07-08 14:56:59 +02:00
self . log . info ( ' Calling wallet tool info, testing output ' )
#
# TODO: Wallet tool info should work with wallet file permissions set to
# read-only without raising:
# "Error loading wallet.dat. Is wallet being used by another process?"
# The following lines should be uncommented and the tests still succeed:
#
# self.log.debug('Setting wallet file permissions to 400 (read-only)')
# os.chmod(self.wallet_path, stat.S_IRUSR)
# assert(self.wallet_permissions() in ['400', '666']) # Sanity check. 666 because Appveyor.
# shasum_before = self.wallet_shasum()
timestamp_before = self . wallet_timestamp ( )
self . log . debug ( ' Wallet file timestamp before calling info: {} ' . format ( timestamp_before ) )
2020-12-16 17:43:15 +01:00
out = self . get_expected_info_output ( address = 1 )
2022-11-30 20:23:48 +01:00
self . assert_tool_output ( out , ' -wallet= ' + self . default_wallet_name , ' info ' )
2024-02-09 18:36:14 +01:00
2019-07-08 14:56:59 +02:00
timestamp_after = self . wallet_timestamp ( )
self . log . debug ( ' Wallet file timestamp after calling info: {} ' . format ( timestamp_after ) )
self . log_wallet_timestamp_comparison ( timestamp_before , timestamp_after )
self . log . debug ( ' Setting wallet file permissions back to 600 (read/write) ' )
os . chmod ( self . wallet_path , stat . S_IRUSR | stat . S_IWUSR )
assert ( self . wallet_permissions ( ) in [ ' 600 ' , ' 666 ' ] ) # Sanity check. 666 because Appveyor.
#
# TODO: Wallet tool info should not write to the wallet file.
# The following lines should be uncommented and the tests still succeed:
#
# assert_equal(timestamp_before, timestamp_after)
# shasum_after = self.wallet_shasum()
# assert_equal(shasum_before, shasum_after)
# self.log.debug('Wallet file shasum unchanged\n')
def test_tool_wallet_info_after_transaction ( self ) :
"""
Mutate the wallet with a transaction to verify that the info command
output changes accordingly .
"""
2019-01-31 17:07:45 +01:00
self . start_node ( 0 )
2019-07-08 14:56:59 +02:00
self . log . info ( ' Generating transaction to mutate wallet ' )
2019-01-31 17:07:45 +01:00
self . nodes [ 0 ] . generate ( 1 )
self . stop_node ( 0 )
2019-07-08 14:56:59 +02:00
self . log . info ( ' Calling wallet tool info after generating a transaction, testing output ' )
shasum_before = self . wallet_shasum ( )
timestamp_before = self . wallet_timestamp ( )
self . log . debug ( ' Wallet file timestamp before calling info: {} ' . format ( timestamp_before ) )
2020-12-16 17:43:15 +01:00
out = self . get_expected_info_output ( transactions = 1 , address = 1 )
2022-11-30 20:23:48 +01:00
self . assert_tool_output ( out , ' -wallet= ' + self . default_wallet_name , ' info ' )
2019-07-08 14:56:59 +02:00
shasum_after = self . wallet_shasum ( )
timestamp_after = self . wallet_timestamp ( )
self . log . debug ( ' Wallet file timestamp after calling info: {} ' . format ( timestamp_after ) )
self . log_wallet_timestamp_comparison ( timestamp_before , timestamp_after )
#
# TODO: Wallet tool info should not write to the wallet file.
# This assertion should be uncommented and succeed:
# assert_equal(timestamp_before, timestamp_after)
assert_equal ( shasum_before , shasum_after )
self . log . debug ( ' Wallet file shasum unchanged \n ' )
def test_tool_wallet_create_on_existing_wallet ( self ) :
self . log . info ( ' Calling wallet tool create on an existing wallet, testing output ' )
shasum_before = self . wallet_shasum ( )
timestamp_before = self . wallet_timestamp ( )
self . log . debug ( ' Wallet file timestamp before calling create: {} ' . format ( timestamp_before ) )
2020-12-16 17:43:15 +01:00
out = " Topping up keypool... \n " + self . get_expected_info_output ( name = " foo " , keypool = 2000 )
2019-01-31 17:07:45 +01:00
self . assert_tool_output ( out , ' -wallet=foo ' , ' create ' )
2019-07-08 14:56:59 +02:00
shasum_after = self . wallet_shasum ( )
timestamp_after = self . wallet_timestamp ( )
self . log . debug ( ' Wallet file timestamp after calling create: {} ' . format ( timestamp_after ) )
self . log_wallet_timestamp_comparison ( timestamp_before , timestamp_after )
assert_equal ( timestamp_before , timestamp_after )
assert_equal ( shasum_before , shasum_after )
self . log . debug ( ' Wallet file shasum unchanged \n ' )
def test_getwalletinfo_on_different_wallet ( self ) :
self . log . info ( ' Starting node with arg -wallet=foo ' )
2022-11-30 20:23:48 +01:00
self . start_node ( 0 , [ ' -nowallet ' , ' -wallet=foo ' ] )
2019-07-08 14:56:59 +02:00
self . log . info ( ' Calling getwalletinfo on a different wallet ( " foo " ), testing output ' )
shasum_before = self . wallet_shasum ( )
timestamp_before = self . wallet_timestamp ( )
self . log . debug ( ' Wallet file timestamp before calling getwalletinfo: {} ' . format ( timestamp_before ) )
2019-01-31 17:07:45 +01:00
out = self . nodes [ 0 ] . getwalletinfo ( )
self . stop_node ( 0 )
2019-07-08 14:56:59 +02:00
shasum_after = self . wallet_shasum ( )
timestamp_after = self . wallet_timestamp ( )
self . log . debug ( ' Wallet file timestamp after calling getwalletinfo: {} ' . format ( timestamp_after ) )
2019-01-31 17:07:45 +01:00
assert_equal ( 0 , out [ ' txcount ' ] )
2020-12-16 17:43:15 +01:00
if not self . options . descriptors :
assert_equal ( 1000 , out [ ' keypoolsize ' ] )
assert_equal ( 1000 , out [ ' keypoolsize_hd_internal ' ] )
assert_equal ( True , ' hdchainid ' in out )
else :
assert_equal ( 1000 , out [ ' keypoolsize ' ] )
assert_equal ( 1000 , out [ ' keypoolsize_hd_internal ' ] )
2019-01-31 17:07:45 +01:00
2019-07-08 14:56:59 +02:00
self . log_wallet_timestamp_comparison ( timestamp_before , timestamp_after )
assert_equal ( timestamp_before , timestamp_after )
assert_equal ( shasum_after , shasum_before )
self . log . debug ( ' Wallet file shasum unchanged \n ' )
2022-03-06 08:00:20 +01:00
def test_salvage ( self ) :
# TODO: Check salvage actually salvages and doesn't break things. https://github.com/bitcoin/bitcoin/issues/7463
self . log . info ( ' Check salvage ' )
2022-11-30 20:24:02 +01:00
self . start_node ( 0 )
self . nodes [ 0 ] . createwallet ( " salvage " )
2022-03-06 08:00:20 +01:00
self . stop_node ( 0 )
self . assert_tool_output ( ' ' , ' -wallet=salvage ' , ' salvage ' )
2023-06-27 20:51:40 +02:00
def test_wipe ( self ) :
2020-12-16 17:43:15 +01:00
out = self . get_expected_info_output ( transactions = 1 , address = 1 )
2023-06-27 20:51:40 +02:00
self . assert_tool_output ( out , ' -wallet= ' + self . default_wallet_name , ' info ' )
self . assert_tool_output ( ' ' , ' -wallet= ' + self . default_wallet_name , ' wipetxes ' )
2020-12-16 17:43:15 +01:00
out = self . get_expected_info_output ( transactions = 0 , address = 1 )
2023-06-27 20:51:40 +02:00
self . assert_tool_output ( out , ' -wallet= ' + self . default_wallet_name , ' info ' )
2020-12-17 15:18:13 +01:00
def test_dump_createfromdump ( self ) :
self . start_node ( 0 )
self . nodes [ 0 ] . createwallet ( " todump " )
file_format = self . nodes [ 0 ] . get_wallet_rpc ( " todump " ) . getwalletinfo ( ) [ " format " ]
self . nodes [ 0 ] . createwallet ( " todump2 " )
self . stop_node ( 0 )
self . log . info ( ' Checking dump arguments ' )
self . assert_raises_tool_error ( ' No dump file provided. To use dump, -dumpfile=<filename> must be provided. ' , ' -wallet=todump ' , ' dump ' )
self . log . info ( ' Checking basic dump ' )
wallet_dump = os . path . join ( self . nodes [ 0 ] . datadir , " wallet.dump " )
self . assert_tool_output ( ' The dumpfile may contain private keys. To ensure the safety of your Bitcoin, do not share the dumpfile. \n ' , ' -wallet=todump ' , ' -dumpfile= {} ' . format ( wallet_dump ) , ' dump ' )
dump_data = self . read_dump ( wallet_dump )
orig_dump = dump_data . copy ( )
# Check the dump magic
assert_equal ( dump_data [ ' BITCOIN_CORE_WALLET_DUMP ' ] , ' 1 ' )
# Check the file format
assert_equal ( dump_data [ " format " ] , file_format )
self . log . info ( ' Checking that a dumpfile cannot be overwritten ' )
self . assert_raises_tool_error ( ' File {} already exists. If you are sure this is what you want, move it out of the way first. ' . format ( wallet_dump ) , ' -wallet=todump2 ' , ' -dumpfile= {} ' . format ( wallet_dump ) , ' dump ' )
self . log . info ( ' Checking createfromdump arguments ' )
self . assert_raises_tool_error ( ' No dump file provided. To use createfromdump, -dumpfile=<filename> must be provided. ' , ' -wallet=todump ' , ' createfromdump ' )
non_exist_dump = os . path . join ( self . nodes [ 0 ] . datadir , " wallet.nodump " )
self . assert_raises_tool_error ( ' Unknown wallet file format " notaformat " provided. Please provide one of " bdb " or " sqlite " . ' , ' -wallet=todump ' , ' -format=notaformat ' , ' -dumpfile= {} ' . format ( wallet_dump ) , ' createfromdump ' )
self . assert_raises_tool_error ( ' Dump file {} does not exist. ' . format ( non_exist_dump ) , ' -wallet=todump ' , ' -dumpfile= {} ' . format ( non_exist_dump ) , ' createfromdump ' )
wallet_path = os . path . join ( self . nodes [ 0 ] . datadir , ' regtest/wallets/todump2 ' )
self . assert_raises_tool_error ( ' Failed to create database path \' {} \' . Database already exists. ' . format ( wallet_path ) , ' -wallet=todump2 ' , ' -dumpfile= {} ' . format ( wallet_dump ) , ' createfromdump ' )
2020-12-18 07:55:51 +01:00
self . assert_raises_tool_error ( " The -descriptors option can only be used with the ' create ' command. " , ' -descriptors ' , ' -wallet=todump2 ' , ' -dumpfile= {} ' . format ( wallet_dump ) , ' createfromdump ' )
2020-12-17 15:18:13 +01:00
self . log . info ( ' Checking createfromdump ' )
self . do_tool_createfromdump ( " load " , " wallet.dump " )
if self . is_bdb_compiled ( ) :
self . do_tool_createfromdump ( " load-bdb " , " wallet.dump " , " bdb " )
2020-12-18 07:55:51 +01:00
if self . is_sqlite_compiled ( ) :
self . do_tool_createfromdump ( " load-sqlite " , " wallet.dump " , " sqlite " )
2020-12-17 15:18:13 +01:00
self . log . info ( ' Checking createfromdump handling of magic and versions ' )
bad_ver_wallet_dump = os . path . join ( self . nodes [ 0 ] . datadir , " wallet-bad_ver1.dump " )
dump_data [ " BITCOIN_CORE_WALLET_DUMP " ] = " 0 "
self . write_dump ( dump_data , bad_ver_wallet_dump )
self . assert_raises_tool_error ( ' Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version 0 ' , ' -wallet=badload ' , ' -dumpfile= {} ' . format ( bad_ver_wallet_dump ) , ' createfromdump ' )
assert not os . path . isdir ( os . path . join ( self . nodes [ 0 ] . datadir , " regtest/wallets " , " badload " ) )
bad_ver_wallet_dump = os . path . join ( self . nodes [ 0 ] . datadir , " wallet-bad_ver2.dump " )
dump_data [ " BITCOIN_CORE_WALLET_DUMP " ] = " 2 "
self . write_dump ( dump_data , bad_ver_wallet_dump )
self . assert_raises_tool_error ( ' Error: Dumpfile version is not supported. This version of bitcoin-wallet only supports version 1 dumpfiles. Got dumpfile with version 2 ' , ' -wallet=badload ' , ' -dumpfile= {} ' . format ( bad_ver_wallet_dump ) , ' createfromdump ' )
assert not os . path . isdir ( os . path . join ( self . nodes [ 0 ] . datadir , " regtest/wallets " , " badload " ) )
bad_magic_wallet_dump = os . path . join ( self . nodes [ 0 ] . datadir , " wallet-bad_magic.dump " )
del dump_data [ " BITCOIN_CORE_WALLET_DUMP " ]
dump_data [ " not_the_right_magic " ] = " 1 "
self . write_dump ( dump_data , bad_magic_wallet_dump , " not_the_right_magic " )
self . assert_raises_tool_error ( ' Error: Dumpfile identifier record is incorrect. Got " not_the_right_magic " , expected " BITCOIN_CORE_WALLET_DUMP " . ' , ' -wallet=badload ' , ' -dumpfile= {} ' . format ( bad_magic_wallet_dump ) , ' createfromdump ' )
assert not os . path . isdir ( os . path . join ( self . nodes [ 0 ] . datadir , " regtest/wallets " , " badload " ) )
self . log . info ( ' Checking createfromdump handling of checksums ' )
bad_sum_wallet_dump = os . path . join ( self . nodes [ 0 ] . datadir , " wallet-bad_sum1.dump " )
dump_data = orig_dump . copy ( )
checksum = dump_data [ " checksum " ]
dump_data [ " checksum " ] = " 1 " * 64
self . write_dump ( dump_data , bad_sum_wallet_dump )
self . assert_raises_tool_error ( ' Error: Dumpfile checksum does not match. Computed {} , expected {} ' . format ( checksum , " 1 " * 64 ) , ' -wallet=bad ' , ' -dumpfile= {} ' . format ( bad_sum_wallet_dump ) , ' createfromdump ' )
assert not os . path . isdir ( os . path . join ( self . nodes [ 0 ] . datadir , " regtest/wallets " , " badload " ) )
bad_sum_wallet_dump = os . path . join ( self . nodes [ 0 ] . datadir , " wallet-bad_sum2.dump " )
del dump_data [ " checksum " ]
self . write_dump ( dump_data , bad_sum_wallet_dump , skip_checksum = True )
self . assert_raises_tool_error ( ' Error: Missing checksum ' , ' -wallet=badload ' , ' -dumpfile= {} ' . format ( bad_sum_wallet_dump ) , ' createfromdump ' )
assert not os . path . isdir ( os . path . join ( self . nodes [ 0 ] . datadir , " regtest/wallets " , " badload " ) )
bad_sum_wallet_dump = os . path . join ( self . nodes [ 0 ] . datadir , " wallet-bad_sum3.dump " )
dump_data [ " checksum " ] = " 2 " * 10
self . write_dump ( dump_data , bad_sum_wallet_dump )
self . assert_raises_tool_error ( ' Error: Dumpfile checksum does not match. Computed {} , expected {} {} ' . format ( checksum , " 2 " * 10 , " 0 " * 54 ) , ' -wallet=badload ' , ' -dumpfile= {} ' . format ( bad_sum_wallet_dump ) , ' createfromdump ' )
assert not os . path . isdir ( os . path . join ( self . nodes [ 0 ] . datadir , " regtest/wallets " , " badload " ) )
2024-04-09 18:10:58 +02:00
def test_nonhd ( self ) :
self . log . info ( ' Check non-hd wallet ' )
self . start_node ( 0 , [ ' -usehd=0 ' , ' -nowallet ' ] )
self . nodes [ 0 ] . createwallet ( " nohd " )
assert_equal ( False , ' hdchainid ' in self . nodes [ 0 ] . get_wallet_rpc ( ' nohd ' ) . getwalletinfo ( ) )
self . restart_node ( 0 , [ ' -usehd=1 ' , ' -nowallet ' ] )
self . nodes [ 0 ] . createwallet ( " hd " )
assert_equal ( True , ' hdchainid ' in self . nodes [ 0 ] . get_wallet_rpc ( ' hd ' ) . getwalletinfo ( ) )
self . stop_node ( 0 )
2019-07-08 14:56:59 +02:00
def run_test ( self ) :
2022-11-30 20:23:48 +01:00
self . wallet_path = os . path . join ( self . nodes [ 0 ] . datadir , self . chain , ' wallets ' , self . default_wallet_name , self . wallet_data_filename )
2019-07-08 14:56:59 +02:00
self . test_invalid_tool_commands_and_args ( )
# Warning: The following tests are order-dependent.
self . test_tool_wallet_info ( )
self . test_tool_wallet_info_after_transaction ( )
2020-12-16 17:43:15 +01:00
self . test_tool_wallet_create_on_existing_wallet ( )
self . test_getwalletinfo_on_different_wallet ( )
2020-11-02 16:54:06 +01:00
if not self . options . descriptors :
# Salvage is a legacy wallet only thing
2023-02-12 11:51:09 +01:00
self . test_salvage ( )
2023-06-27 20:51:40 +02:00
self . test_wipe ( )
2024-04-09 18:10:58 +02:00
self . test_nonhd ( )
2020-12-17 15:18:13 +01:00
self . test_dump_createfromdump ( )
2019-07-08 14:56:59 +02:00
2019-01-31 17:07:45 +01:00
if __name__ == ' __main__ ' :
ToolWalletTest ( ) . main ( )