2017-12-20 09:34:08 +01:00
#!/usr/bin/env python3
# Copyright (c) 2017 The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
""" Test various command line arguments and configuration file parameters. """
import os
from test_framework . test_framework import BitcoinTestFramework
2018-03-22 11:04:37 +01:00
2017-12-20 09:34:08 +01:00
class ConfArgsTest ( BitcoinTestFramework ) :
def set_test_params ( self ) :
self . setup_clean_chain = True
self . num_nodes = 1
2018-09-06 12:52:06 +02:00
def test_config_file_parser ( self ) :
# Assume node is stopped
inc_conf_file_path = os . path . join ( self . nodes [ 0 ] . datadir , ' include.conf ' )
2021-07-19 20:00:59 +02:00
with open ( os . path . join ( self . nodes [ 0 ] . datadir , ' dash.conf ' ) , ' a ' , encoding = ' utf-8 ' ) as conf :
2018-09-06 12:52:06 +02:00
conf . write ( ' includeconf= {} \n ' . format ( inc_conf_file_path ) )
2019-06-20 22:59:10 +02:00
self . nodes [ 0 ] . assert_start_raises_init_error (
expected_msg = ' Error parsing command line arguments: Invalid parameter -dash_cli ' ,
extra_args = [ ' -dash_cli=1 ' ] ,
)
with open ( inc_conf_file_path , ' w ' , encoding = ' utf-8 ' ) as conf :
conf . write ( ' dash_conf=1 \n ' )
with self . nodes [ 0 ] . assert_debug_log ( expected_msgs = [ ' Ignoring unknown configuration value dash_conf ' ] ) :
self . start_node ( 0 )
self . stop_node ( 0 )
2018-09-06 12:52:06 +02:00
with open ( inc_conf_file_path , ' w ' , encoding = ' utf-8 ' ) as conf :
conf . write ( ' -dash=1 \n ' )
self . nodes [ 0 ] . assert_start_raises_init_error ( expected_msg = ' Error reading configuration file: parse error on line 1: -dash=1, options in configuration file must be specified without leading - ' )
with open ( inc_conf_file_path , ' w ' , encoding = ' utf-8 ' ) as conf :
conf . write ( ' nono \n ' )
self . nodes [ 0 ] . assert_start_raises_init_error ( expected_msg = ' Error reading configuration file: parse error on line 1: nono, if you intended to specify a negated option, use nono=1 instead ' )
2018-11-12 15:20:30 +01:00
with open ( inc_conf_file_path , ' w ' , encoding = ' utf-8 ' ) as conf :
conf . write ( ' server=1 \n rpcuser=someuser \n rpcpassword=some#pass ' )
self . nodes [ 0 ] . assert_start_raises_init_error ( expected_msg = ' Error reading configuration file: parse error on line 3, using # in rpcpassword can be ambiguous and should be avoided ' )
Merge #14708: Warn unrecognised sections in the config file
3fb09b9889665a24b34f25e9d1385a05058a28b7 Warn unrecognized sections in the config file (Akio Nakamura)
Pull request description:
This PR intends to resolve #14702.
In the config file, sections are specified by square bracket pair "[]"$,
or included in the option name itself which separated by a period"(.)".
Typicaly, [testnet] is not a correct section name and specified options
in that section are ignored but user cannot recognize what is happen.
So, add some log-warning messages if unrecognized section names are
present in the config file after checking section only args.
note: Currentry, followings are out of scope of this PR.
1) Empty section name or option name can describe.
e.g. [] , .a=b, =c
2) Multiple period characters can exist in the section name and option name.
e.g. [c.d.e], [..], f.g.h.i=j, ..=k
Tree-SHA512: 2cea02a0525feb40320613989a75cd7b7b1bd12158d5e6f3174ca77e6a25bb84425dd8812f62483df9fc482045c7b5402d69bc714430518b1847d055a2dc304b
2018-11-21 16:43:46 +01:00
with open ( inc_conf_file_path , ' w ' , encoding = ' utf-8 ' ) as conf :
conf . write ( ' testnot.datadir=1 \n [testnet] \n ' )
self . restart_node ( 0 )
self . nodes [ 0 ] . stop_node ( expected_stderr = ' Warning: Section [testnet] is not recognized. ' + os . linesep + ' Warning: Section [testnot] is not recognized. ' )
2018-09-06 12:52:06 +02:00
with open ( inc_conf_file_path , ' w ' , encoding = ' utf-8 ' ) as conf :
conf . write ( ' ' ) # clear
2021-06-08 04:19:35 +02:00
def test_log_buffer ( self ) :
2020-01-11 00:37:33 +01:00
with self . nodes [ 0 ] . assert_debug_log ( expected_msgs = [ ' Warning: parsed potentially confusing double-negative -connect=0 \n ' ] ) :
2021-06-08 04:19:35 +02:00
self . start_node ( 0 , extra_args = [ ' -noconnect=0 ' ] )
self . stop_node ( 0 )
2017-12-20 09:34:08 +01:00
def run_test ( self ) :
self . stop_node ( 0 )
2021-06-08 04:19:35 +02:00
self . test_log_buffer ( )
2018-09-06 12:52:06 +02:00
self . test_config_file_parser ( )
2017-12-20 09:34:08 +01:00
# Remove the -datadir argument so it doesn't override the config file
self . nodes [ 0 ] . args = [ arg for arg in self . nodes [ 0 ] . args if not arg . startswith ( " -datadir " ) ]
2018-03-22 11:04:37 +01:00
default_data_dir = self . nodes [ 0 ] . datadir
2017-12-20 09:34:08 +01:00
new_data_dir = os . path . join ( default_data_dir , ' newdatadir ' )
new_data_dir_2 = os . path . join ( default_data_dir , ' newdatadir2 ' )
# Check that using -datadir argument on non-existent directory fails
self . nodes [ 0 ] . datadir = new_data_dir
2021-04-08 22:29:01 +02:00
self . nodes [ 0 ] . assert_start_raises_init_error ( [ ' -datadir= ' + new_data_dir ] , ' Error: Specified data directory " ' + new_data_dir + ' " does not exist. ' )
2017-12-20 09:34:08 +01:00
# Check that using non-existent datadir in conf file fails
2020-02-29 20:45:39 +01:00
conf_file = os . path . join ( default_data_dir , " dash.conf " )
Merge #11862: Network specific conf sections
c25321f Add config changes to release notes (Anthony Towns)
5e3cbe0 [tests] Unit tests for -testnet/-regtest in [test]/[regtest] sections (Anthony Towns)
005ad26 ArgsManager: special handling for -regtest and -testnet (Anthony Towns)
608415d [tests] Unit tests for network-specific config entries (Anthony Towns)
68797e2 ArgsManager: Warn when ignoring network-specific config setting (Anthony Towns)
d1fc4d9 ArgsManager: limit some options to only apply on mainnet when in default section (Anthony Towns)
8a9817d [tests] Use regtest section in functional tests configs (Anthony Towns)
30f9407 [tests] Unit tests for config file sections (Anthony Towns)
95eb66d ArgsManager: support config file sections (Anthony Towns)
4d34fcc ArgsManager: drop m_negated_args (Anthony Towns)
3673ca3 ArgsManager: keep command line and config file arguments separate (Anthony Towns)
Pull request description:
The weekly meeting on [2017-12-07](http://www.erisian.com.au/meetbot/bitcoin-core-dev/2017/bitcoin-core-dev.2017-12-07-19.00.log.html) discussed allowing options to bitcoin to have some sensitivity to what network is in use. @theuni suggested having sections in the config file:
<cfields> an alternative to that would be sections in a config file. and on the
cmdline they'd look like namespaces. so, [testnet] port=5. or -testnet::port=5.
This approach is (more or less) supported by `boost::program_options::detail::config_file_iterator` -- when it sees a `[testnet]` section with `port=5`, it will treat that the same as "testnet.port=5". So `[testnet] port=5` (or `testnet.port=5` without the section header) in bitcoin.conf and `-testnet.port=5` on the command line.
The other aspect to this question is possibly limiting some options so that there is no possibility of accidental cross-contamination across networks. For example, if you're using a particular wallet.dat on mainnet, you may not want to accidentally use the same wallet on testnet and risk reusing keys.
I've set this up so that the `-addnode` and `-wallet` options are `NETWORK_ONLY`, so that if you have a bitcoin.conf:
wallet=/secret/wallet.dat
upnp=1
and you run `bitcoind -testnet` or `bitcoind -regtest`, then the `wallet=` setting will be ignored, and should behave as if your bitcoin.conf had specified:
upnp=1
[main]
wallet=/secret/wallet.dat
For any `NETWORK_ONLY` options, if you're using `-testnet` or `-regtest`, you'll have to add the prefix to any command line options. This was necessary for `multiwallet.py` for instance.
I've left the "default" options as taking precedence over network specific ones, which might be backwards. So if you have:
maxmempool=200
[regtest]
maxmempool=100
your maxmempool will still be 200 on regtest. The advantage of doing it this way is that if you have `[regtest] maxmempool=100` in bitcoin.conf, and then say `bitcoind -regtest -maxmempool=200`, the same result is probably in line with what you expect...
The other thing to note is that I'm using the chain names from `chainparamsbase.cpp` / `ChainNameFromCommandLine`, so the sections are `[main]`, `[test]` and `[regtest]`; not `[mainnet]` or `[testnet]` as might be expected.
Thoughts? Ping @MeshCollider @laanwj @jonasschnelli @morcos
Tree-SHA512: f00b5eb75f006189987e5c15e154a42b66ee251777768c1e185d764279070fcb7c41947d8794092b912a03d985843c82e5189871416995436a6260520fb7a4db
2020-04-29 14:50:51 +02:00
2021-01-22 15:58:07 +01:00
# datadir needs to be set before [chain] section
Merge #11862: Network specific conf sections
c25321f Add config changes to release notes (Anthony Towns)
5e3cbe0 [tests] Unit tests for -testnet/-regtest in [test]/[regtest] sections (Anthony Towns)
005ad26 ArgsManager: special handling for -regtest and -testnet (Anthony Towns)
608415d [tests] Unit tests for network-specific config entries (Anthony Towns)
68797e2 ArgsManager: Warn when ignoring network-specific config setting (Anthony Towns)
d1fc4d9 ArgsManager: limit some options to only apply on mainnet when in default section (Anthony Towns)
8a9817d [tests] Use regtest section in functional tests configs (Anthony Towns)
30f9407 [tests] Unit tests for config file sections (Anthony Towns)
95eb66d ArgsManager: support config file sections (Anthony Towns)
4d34fcc ArgsManager: drop m_negated_args (Anthony Towns)
3673ca3 ArgsManager: keep command line and config file arguments separate (Anthony Towns)
Pull request description:
The weekly meeting on [2017-12-07](http://www.erisian.com.au/meetbot/bitcoin-core-dev/2017/bitcoin-core-dev.2017-12-07-19.00.log.html) discussed allowing options to bitcoin to have some sensitivity to what network is in use. @theuni suggested having sections in the config file:
<cfields> an alternative to that would be sections in a config file. and on the
cmdline they'd look like namespaces. so, [testnet] port=5. or -testnet::port=5.
This approach is (more or less) supported by `boost::program_options::detail::config_file_iterator` -- when it sees a `[testnet]` section with `port=5`, it will treat that the same as "testnet.port=5". So `[testnet] port=5` (or `testnet.port=5` without the section header) in bitcoin.conf and `-testnet.port=5` on the command line.
The other aspect to this question is possibly limiting some options so that there is no possibility of accidental cross-contamination across networks. For example, if you're using a particular wallet.dat on mainnet, you may not want to accidentally use the same wallet on testnet and risk reusing keys.
I've set this up so that the `-addnode` and `-wallet` options are `NETWORK_ONLY`, so that if you have a bitcoin.conf:
wallet=/secret/wallet.dat
upnp=1
and you run `bitcoind -testnet` or `bitcoind -regtest`, then the `wallet=` setting will be ignored, and should behave as if your bitcoin.conf had specified:
upnp=1
[main]
wallet=/secret/wallet.dat
For any `NETWORK_ONLY` options, if you're using `-testnet` or `-regtest`, you'll have to add the prefix to any command line options. This was necessary for `multiwallet.py` for instance.
I've left the "default" options as taking precedence over network specific ones, which might be backwards. So if you have:
maxmempool=200
[regtest]
maxmempool=100
your maxmempool will still be 200 on regtest. The advantage of doing it this way is that if you have `[regtest] maxmempool=100` in bitcoin.conf, and then say `bitcoind -regtest -maxmempool=200`, the same result is probably in line with what you expect...
The other thing to note is that I'm using the chain names from `chainparamsbase.cpp` / `ChainNameFromCommandLine`, so the sections are `[main]`, `[test]` and `[regtest]`; not `[mainnet]` or `[testnet]` as might be expected.
Thoughts? Ping @MeshCollider @laanwj @jonasschnelli @morcos
Tree-SHA512: f00b5eb75f006189987e5c15e154a42b66ee251777768c1e185d764279070fcb7c41947d8794092b912a03d985843c82e5189871416995436a6260520fb7a4db
2020-04-29 14:50:51 +02:00
conf_file_contents = open ( conf_file , encoding = ' utf8 ' ) . read ( )
with open ( conf_file , ' w ' , encoding = ' utf8 ' ) as f :
2017-12-20 09:34:08 +01:00
f . write ( " datadir= " + new_data_dir + " \n " )
Merge #11862: Network specific conf sections
c25321f Add config changes to release notes (Anthony Towns)
5e3cbe0 [tests] Unit tests for -testnet/-regtest in [test]/[regtest] sections (Anthony Towns)
005ad26 ArgsManager: special handling for -regtest and -testnet (Anthony Towns)
608415d [tests] Unit tests for network-specific config entries (Anthony Towns)
68797e2 ArgsManager: Warn when ignoring network-specific config setting (Anthony Towns)
d1fc4d9 ArgsManager: limit some options to only apply on mainnet when in default section (Anthony Towns)
8a9817d [tests] Use regtest section in functional tests configs (Anthony Towns)
30f9407 [tests] Unit tests for config file sections (Anthony Towns)
95eb66d ArgsManager: support config file sections (Anthony Towns)
4d34fcc ArgsManager: drop m_negated_args (Anthony Towns)
3673ca3 ArgsManager: keep command line and config file arguments separate (Anthony Towns)
Pull request description:
The weekly meeting on [2017-12-07](http://www.erisian.com.au/meetbot/bitcoin-core-dev/2017/bitcoin-core-dev.2017-12-07-19.00.log.html) discussed allowing options to bitcoin to have some sensitivity to what network is in use. @theuni suggested having sections in the config file:
<cfields> an alternative to that would be sections in a config file. and on the
cmdline they'd look like namespaces. so, [testnet] port=5. or -testnet::port=5.
This approach is (more or less) supported by `boost::program_options::detail::config_file_iterator` -- when it sees a `[testnet]` section with `port=5`, it will treat that the same as "testnet.port=5". So `[testnet] port=5` (or `testnet.port=5` without the section header) in bitcoin.conf and `-testnet.port=5` on the command line.
The other aspect to this question is possibly limiting some options so that there is no possibility of accidental cross-contamination across networks. For example, if you're using a particular wallet.dat on mainnet, you may not want to accidentally use the same wallet on testnet and risk reusing keys.
I've set this up so that the `-addnode` and `-wallet` options are `NETWORK_ONLY`, so that if you have a bitcoin.conf:
wallet=/secret/wallet.dat
upnp=1
and you run `bitcoind -testnet` or `bitcoind -regtest`, then the `wallet=` setting will be ignored, and should behave as if your bitcoin.conf had specified:
upnp=1
[main]
wallet=/secret/wallet.dat
For any `NETWORK_ONLY` options, if you're using `-testnet` or `-regtest`, you'll have to add the prefix to any command line options. This was necessary for `multiwallet.py` for instance.
I've left the "default" options as taking precedence over network specific ones, which might be backwards. So if you have:
maxmempool=200
[regtest]
maxmempool=100
your maxmempool will still be 200 on regtest. The advantage of doing it this way is that if you have `[regtest] maxmempool=100` in bitcoin.conf, and then say `bitcoind -regtest -maxmempool=200`, the same result is probably in line with what you expect...
The other thing to note is that I'm using the chain names from `chainparamsbase.cpp` / `ChainNameFromCommandLine`, so the sections are `[main]`, `[test]` and `[regtest]`; not `[mainnet]` or `[testnet]` as might be expected.
Thoughts? Ping @MeshCollider @laanwj @jonasschnelli @morcos
Tree-SHA512: f00b5eb75f006189987e5c15e154a42b66ee251777768c1e185d764279070fcb7c41947d8794092b912a03d985843c82e5189871416995436a6260520fb7a4db
2020-04-29 14:50:51 +02:00
f . write ( conf_file_contents )
2021-04-08 22:29:01 +02:00
self . nodes [ 0 ] . assert_start_raises_init_error ( [ ' -conf= ' + conf_file ] , ' Error reading configuration file: specified data directory " ' + new_data_dir + ' " does not exist. ' )
2017-12-20 09:34:08 +01:00
# Create the directory and ensure the config file now works
os . mkdir ( new_data_dir )
self . start_node ( 0 , [ ' -conf= ' + conf_file , ' -wallet=w1 ' ] )
self . stop_node ( 0 )
2021-01-22 15:58:07 +01:00
assert os . path . exists ( os . path . join ( new_data_dir , self . chain , ' wallets ' , ' w1 ' ) )
2017-12-20 09:34:08 +01:00
# Ensure command line argument overrides datadir in conf
os . mkdir ( new_data_dir_2 )
self . nodes [ 0 ] . datadir = new_data_dir_2
self . start_node ( 0 , [ ' -datadir= ' + new_data_dir_2 , ' -conf= ' + conf_file , ' -wallet=w2 ' ] )
2021-01-22 15:58:07 +01:00
assert os . path . exists ( os . path . join ( new_data_dir_2 , self . chain , ' wallets ' , ' w2 ' ) )
2017-12-20 09:34:08 +01:00
if __name__ == ' __main__ ' :
ConfArgsTest ( ) . main ( )