mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-01-11 04:12:36 -03:00
292b1a3e9c
If there are multiple external signers, `GetExternalSigner()` will just pick the first one in the list. If the user has two or more hardware wallets connected at the same time, he might not notice this. This PR adds a check and fails with suitable message.
83 lines
2.8 KiB
Python
Executable file
83 lines
2.8 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
# Copyright (c) 2017-2021 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 external signer.
|
|
|
|
Verify that a bitcoind node can use an external signer command.
|
|
See also wallet_signer.py for tests that require wallet context.
|
|
"""
|
|
import os
|
|
import platform
|
|
|
|
from test_framework.test_framework import BitcoinTestFramework
|
|
from test_framework.util import (
|
|
assert_equal,
|
|
assert_raises_rpc_error,
|
|
)
|
|
|
|
|
|
class RPCSignerTest(BitcoinTestFramework):
|
|
def mock_signer_path(self):
|
|
path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mocks', 'signer.py')
|
|
if platform.system() == "Windows":
|
|
return "py " + path
|
|
else:
|
|
return path
|
|
|
|
def set_test_params(self):
|
|
self.num_nodes = 4
|
|
# The experimental syscall sandbox feature (-sandbox) is not compatible with -signer (which
|
|
# invokes execve).
|
|
self.disable_syscall_sandbox = True
|
|
|
|
self.extra_args = [
|
|
[],
|
|
[f"-signer={self.mock_signer_path()}", '-keypool=10'],
|
|
[f"-signer={self.mock_signer_path()}", '-keypool=10'],
|
|
["-signer=fake.py"],
|
|
]
|
|
|
|
def skip_test_if_missing_module(self):
|
|
self.skip_if_no_external_signer()
|
|
|
|
def set_mock_result(self, node, res):
|
|
with open(os.path.join(node.cwd, "mock_result"), "w", encoding="utf8") as f:
|
|
f.write(res)
|
|
|
|
def clear_mock_result(self, node):
|
|
os.remove(os.path.join(node.cwd, "mock_result"))
|
|
|
|
def run_test(self):
|
|
self.log.debug(f"-signer={self.mock_signer_path()}")
|
|
|
|
assert_raises_rpc_error(-1, 'Error: restart bitcoind with -signer=<cmd>',
|
|
self.nodes[0].enumeratesigners
|
|
)
|
|
|
|
# Handle script missing:
|
|
assert_raises_rpc_error(
|
|
-1,
|
|
"CreateProcess failed: The system cannot find the file specified."
|
|
if platform.system() == "Windows"
|
|
else "execve failed: No such file or directory",
|
|
self.nodes[3].enumeratesigners,
|
|
)
|
|
|
|
# Handle error thrown by script
|
|
self.set_mock_result(self.nodes[1], "2")
|
|
assert_raises_rpc_error(-1, 'RunCommandParseJSON error',
|
|
self.nodes[1].enumeratesigners
|
|
)
|
|
self.clear_mock_result(self.nodes[1])
|
|
|
|
self.set_mock_result(self.nodes[1], '0 [{"type": "trezor", "model": "trezor_t", "error": "fingerprint not found"}]')
|
|
assert_raises_rpc_error(-1, 'fingerprint not found',
|
|
self.nodes[1].enumeratesigners
|
|
)
|
|
self.clear_mock_result(self.nodes[1])
|
|
|
|
assert_equal({'fingerprint': '00000001', 'name': 'trezor_t'} in self.nodes[1].enumeratesigners()['signers'], True)
|
|
|
|
if __name__ == '__main__':
|
|
RPCSignerTest().main()
|