Changeset View
Changeset View
Standalone View
Standalone View
test/functional/interface_bitcoin_cli.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2017-2019 The Bitcoin Core developers | # Copyright (c) 2017-2019 The Bitcoin Core developers | ||||
# Distributed under the MIT software license, see the accompanying | # Distributed under the MIT software license, see the accompanying | ||||
# file COPYING or http://www.opensource.org/licenses/mit-license.php. | # file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
"""Test bitcoin-cli""" | """Test bitcoin-cli""" | ||||
from decimal import Decimal | from decimal import Decimal | ||||
from test_framework.test_framework import BitcoinTestFramework | from test_framework.test_framework import BitcoinTestFramework | ||||
from test_framework.util import ( | from test_framework.util import ( | ||||
assert_equal, | assert_equal, | ||||
assert_raises_process_error, | assert_raises_process_error, | ||||
assert_raises_rpc_error, | |||||
get_auth_cookie, | get_auth_cookie, | ||||
) | ) | ||||
# The block reward of coinbaseoutput.nValue (50) BTC/block matures after | # The block reward of coinbaseoutput.nValue (50) BTC/block matures after | ||||
# COINBASE_MATURITY (100) blocks. Therefore, after mining 101 blocks we expect | # COINBASE_MATURITY (100) blocks. Therefore, after mining 101 blocks we expect | ||||
# node 0 to have a balance of (BLOCKS - COINBASE_MATURITY) * 50 BTC/block. | # node 0 to have a balance of (BLOCKS - COINBASE_MATURITY) * 50 BTC/block. | ||||
BLOCKS = 101 | BLOCKS = 101 | ||||
BALANCE = (BLOCKS - 100) * 50000000 | BALANCE = (BLOCKS - 100) * 50000000 | ||||
JSON_PARSING_ERROR = 'error: Error parsing JSON:foo' | JSON_PARSING_ERROR = 'error: Error parsing JSON:foo' | ||||
BLOCKS_VALUE_OF_ZERO = 'error: the first argument (number of blocks to generate, default: 1) must be an integer value greater than zero' | BLOCKS_VALUE_OF_ZERO = 'error: the first argument (number of blocks to generate, default: 1) must be an integer value greater than zero' | ||||
TOO_MANY_ARGS = 'error: too many arguments (maximum 2 for nblocks and maxtries)' | TOO_MANY_ARGS = 'error: too many arguments (maximum 2 for nblocks and maxtries)' | ||||
WALLET_NOT_LOADED = 'Requested wallet does not exist or is not loaded' | |||||
WALLET_NOT_SPECIFIED = 'Wallet file not specified' | |||||
class TestBitcoinCli(BitcoinTestFramework): | class TestBitcoinCli(BitcoinTestFramework): | ||||
def set_test_params(self): | def set_test_params(self): | ||||
self.setup_clean_chain = True | self.setup_clean_chain = True | ||||
self.num_nodes = 1 | self.num_nodes = 1 | ||||
def skip_test_if_missing_module(self): | def skip_test_if_missing_module(self): | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | def run_test(self): | ||||
BALANCE + Decimal('9999995.50'), | BALANCE + Decimal('9999995.50'), | ||||
Decimal(9000000), | Decimal(9000000), | ||||
Decimal(31000000)] | Decimal(31000000)] | ||||
self.nodes[0].createwallet(wallet_name=wallets[1]) | self.nodes[0].createwallet(wallet_name=wallets[1]) | ||||
self.nodes[0].createwallet(wallet_name=wallets[2]) | self.nodes[0].createwallet(wallet_name=wallets[2]) | ||||
w1 = self.nodes[0].get_wallet_rpc(wallets[0]) | w1 = self.nodes[0].get_wallet_rpc(wallets[0]) | ||||
w2 = self.nodes[0].get_wallet_rpc(wallets[1]) | w2 = self.nodes[0].get_wallet_rpc(wallets[1]) | ||||
w3 = self.nodes[0].get_wallet_rpc(wallets[2]) | w3 = self.nodes[0].get_wallet_rpc(wallets[2]) | ||||
rpcwallet2 = '-rpcwallet={}'.format(wallets[1]) | |||||
rpcwallet3 = '-rpcwallet={}'.format(wallets[2]) | |||||
w1.walletpassphrase(password, self.rpc_timeout) | w1.walletpassphrase(password, self.rpc_timeout) | ||||
w2.encryptwallet(password) | w2.encryptwallet(password) | ||||
w1.sendtoaddress(w2.getnewaddress(), amounts[1]) | w1.sendtoaddress(w2.getnewaddress(), amounts[1]) | ||||
w1.sendtoaddress(w3.getnewaddress(), amounts[2]) | w1.sendtoaddress(w3.getnewaddress(), amounts[2]) | ||||
# Mine a block to confirm; adds a block reward (50 BTC) to the | # Mine a block to confirm; adds a block reward (50 BTC) to the | ||||
# default wallet. | # default wallet. | ||||
self.nodes[0].generate(1) | self.nodes[0].generate(1) | ||||
Show All 39 Lines | def run_test(self): | ||||
cli_get_info = self.nodes[0].cli('-getinfo').send_cli() | cli_get_info = self.nodes[0].cli('-getinfo').send_cli() | ||||
assert 'balances' not in cli_get_info.keys() | assert 'balances' not in cli_get_info.keys() | ||||
assert_equal(cli_get_info['balance'], amounts[1]) | assert_equal(cli_get_info['balance'], amounts[1]) | ||||
self.log.info( | self.log.info( | ||||
"Test -getinfo with -rpcwallet=remaining-non-default-wallet" | "Test -getinfo with -rpcwallet=remaining-non-default-wallet" | ||||
" returns only its balance") | " returns only its balance") | ||||
cli_get_info = self.nodes[0].cli( | cli_get_info = self.nodes[0].cli('-getinfo', rpcwallet2).send_cli() | ||||
'-getinfo', '-rpcwallet={}'.format(wallets[1])).send_cli() | |||||
assert 'balances' not in cli_get_info.keys() | assert 'balances' not in cli_get_info.keys() | ||||
assert_equal(cli_get_info['balance'], amounts[1]) | assert_equal(cli_get_info['balance'], amounts[1]) | ||||
self.log.info( | self.log.info( | ||||
"Test -getinfo with -rpcwallet=unloaded wallet returns" | "Test -getinfo with -rpcwallet=unloaded wallet returns" | ||||
" no balances") | " no balances") | ||||
cli_get_info = self.nodes[0].cli( | cli_get_info = self.nodes[0].cli('-getinfo', rpcwallet3).send_cli() | ||||
'-getinfo', '-rpcwallet={}'.format(wallets[2])).send_cli() | |||||
assert 'balance' not in cli_get_info_keys | assert 'balance' not in cli_get_info_keys | ||||
assert 'balances' not in cli_get_info_keys | assert 'balances' not in cli_get_info_keys | ||||
# Test bitcoin-cli -generate. | # Test bitcoin-cli -generate. | ||||
n1 = 3 | n1 = 3 | ||||
n2 = 5 | n2 = 4 | ||||
w2.walletpassphrase(password, self.rpc_timeout) | w2.walletpassphrase(password, self.rpc_timeout) | ||||
blocks = self.nodes[0].getblockcount() | blocks = self.nodes[0].getblockcount() | ||||
self.log.info('Test -generate with no args') | self.log.info('Test -generate with no args') | ||||
generate = self.nodes[0].cli('-generate').send_cli() | generate = self.nodes[0].cli('-generate').send_cli() | ||||
assert_equal(set(generate.keys()), {'address', 'blocks'}) | assert_equal(set(generate.keys()), {'address', 'blocks'}) | ||||
assert_equal(len(generate["blocks"]), 1) | assert_equal(len(generate["blocks"]), 1) | ||||
assert_equal(self.nodes[0].getblockcount(), blocks + 1) | assert_equal(self.nodes[0].getblockcount(), blocks + 1) | ||||
Show All 15 Lines | def run_test(self): | ||||
assert_equal(len(generate["blocks"]), n1) | assert_equal(len(generate["blocks"]), n1) | ||||
assert_equal(self.nodes[0].getblockcount(), blocks + 1 + n1) | assert_equal(self.nodes[0].getblockcount(), blocks + 1 + n1) | ||||
self.log.info('Test -generate with nblocks and maxtries') | self.log.info('Test -generate with nblocks and maxtries') | ||||
generate = self.nodes[0].cli('-generate', n2, 1000000).send_cli() | generate = self.nodes[0].cli('-generate', n2, 1000000).send_cli() | ||||
assert_equal(set(generate.keys()), {'address', 'blocks'}) | assert_equal(set(generate.keys()), {'address', 'blocks'}) | ||||
assert_equal(len(generate["blocks"]), n2) | assert_equal(len(generate["blocks"]), n2) | ||||
assert_equal(self.nodes[0].getblockcount(), blocks + 1 + n1 + n2) | assert_equal(self.nodes[0].getblockcount(), blocks + 1 + n1 + n2) | ||||
self.log.info('Test -generate -rpcwallet in single-wallet mode') | |||||
generate = self.nodes[0].cli(rpcwallet2, '-generate').send_cli() | |||||
assert_equal(set(generate.keys()), {'address', 'blocks'}) | |||||
assert_equal(len(generate["blocks"]), 1) | |||||
assert_equal(self.nodes[0].getblockcount(), blocks + 2 + n1 + n2) | |||||
self.log.info( | |||||
'Test -generate -rpcwallet=unloaded wallet raises RPC error') | |||||
assert_raises_rpc_error(-18, | |||||
WALLET_NOT_LOADED, | |||||
self.nodes[0].cli(rpcwallet3, | |||||
'-generate').echo) | |||||
assert_raises_rpc_error(-18, | |||||
WALLET_NOT_LOADED, | |||||
self.nodes[0].cli(rpcwallet3, | |||||
'-generate', | |||||
'foo').echo) | |||||
assert_raises_rpc_error(-18, | |||||
WALLET_NOT_LOADED, | |||||
self.nodes[0].cli(rpcwallet3, | |||||
'-generate', | |||||
0).echo) | |||||
assert_raises_rpc_error(-18, | |||||
WALLET_NOT_LOADED, | |||||
self.nodes[0].cli(rpcwallet3, | |||||
'-generate', | |||||
1, | |||||
2, | |||||
3).echo) | |||||
# Test bitcoin-cli -generate with -rpcwallet in multiwallet mode. | |||||
self.nodes[0].loadwallet(wallets[2]) | |||||
n3 = 4 | |||||
n4 = 10 | |||||
blocks = self.nodes[0].getblockcount() | |||||
self.log.info('Test -generate -rpcwallet with no args') | |||||
generate = self.nodes[0].cli(rpcwallet2, '-generate').send_cli() | |||||
assert_equal(set(generate.keys()), {'address', 'blocks'}) | |||||
assert_equal(len(generate["blocks"]), 1) | |||||
assert_equal(self.nodes[0].getblockcount(), blocks + 1) | |||||
self.log.info('Test -generate -rpcwallet with bad args') | |||||
assert_raises_process_error( | |||||
1, JSON_PARSING_ERROR, self.nodes[0].cli( | |||||
rpcwallet2, '-generate', 'foo').echo) | |||||
assert_raises_process_error( | |||||
1, BLOCKS_VALUE_OF_ZERO, self.nodes[0].cli( | |||||
rpcwallet2, '-generate', 0).echo) | |||||
assert_raises_process_error( | |||||
1, TOO_MANY_ARGS, self.nodes[0].cli( | |||||
rpcwallet2, '-generate', 1, 2, 3).echo) | |||||
self.log.info('Test -generate -rpcwallet with nblocks') | |||||
generate = self.nodes[0].cli( | |||||
rpcwallet2, '-generate', n3).send_cli() | |||||
assert_equal(set(generate.keys()), {'address', 'blocks'}) | |||||
assert_equal(len(generate["blocks"]), n3) | |||||
assert_equal(self.nodes[0].getblockcount(), blocks + 1 + n3) | |||||
self.log.info( | |||||
'Test -generate -rpcwallet with nblocks and maxtries') | |||||
generate = self.nodes[0].cli( | |||||
rpcwallet2, '-generate', n4, 1000000).send_cli() | |||||
assert_equal(set(generate.keys()), {'address', 'blocks'}) | |||||
assert_equal(len(generate["blocks"]), n4) | |||||
assert_equal(self.nodes[0].getblockcount(), blocks + 1 + n3 + n4) | |||||
self.log.info( | |||||
'Test -generate without -rpcwallet in multiwallet mode raises RPC error') | |||||
assert_raises_rpc_error(-19, | |||||
WALLET_NOT_SPECIFIED, | |||||
self.nodes[0].cli('-generate').echo) | |||||
assert_raises_rpc_error(-19, | |||||
WALLET_NOT_SPECIFIED, | |||||
self.nodes[0].cli('-generate', | |||||
'foo').echo) | |||||
assert_raises_rpc_error(-19, WALLET_NOT_SPECIFIED, | |||||
self.nodes[0].cli('-generate', 0).echo) | |||||
assert_raises_rpc_error(-19, WALLET_NOT_SPECIFIED, | |||||
self.nodes[0].cli('-generate', 1, 2, 3).echo) | |||||
else: | else: | ||||
self.log.info( | self.log.info( | ||||
"*** Wallet not compiled; cli getwalletinfo and -getinfo wallet tests skipped") | "*** Wallet not compiled; cli getwalletinfo and -getinfo wallet tests skipped") | ||||
# maintain block parity with the wallet_compiled conditional branch | # maintain block parity with the wallet_compiled conditional branch | ||||
self.nodes[0].generate(10) | self.nodes[0].generate(25) | ||||
self.log.info("Test -version with node stopped") | self.log.info("Test -version with node stopped") | ||||
self.stop_node(0) | self.stop_node(0) | ||||
cli_response = self.nodes[0].cli().send_cli('-version') | cli_response = self.nodes[0].cli().send_cli('-version') | ||||
assert "{} RPC client version".format( | assert "{} RPC client version".format( | ||||
self.config['environment']['PACKAGE_NAME']) in cli_response | self.config['environment']['PACKAGE_NAME']) in cli_response | ||||
self.log.info( | self.log.info( | ||||
"Test -rpcwait option successfully waits for RPC connection") | "Test -rpcwait option successfully waits for RPC connection") | ||||
# Start node without RPC connection. | # Start node without RPC connection. | ||||
self.nodes[0].start() | self.nodes[0].start() | ||||
# ensure cookie file is available to avoid race condition | # ensure cookie file is available to avoid race condition | ||||
self.nodes[0].wait_for_cookie_credentials() | self.nodes[0].wait_for_cookie_credentials() | ||||
blocks = self.nodes[0].cli('-rpcwait').send_cli('getblockcount') | blocks = self.nodes[0].cli('-rpcwait').send_cli('getblockcount') | ||||
self.nodes[0].wait_for_rpc_connection() | self.nodes[0].wait_for_rpc_connection() | ||||
assert_equal(blocks, BLOCKS + 10) | assert_equal(blocks, BLOCKS + 25) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
TestBitcoinCli().main() | TestBitcoinCli().main() |