rpc_signer.py
1 #!/usr/bin/env python3 2 # Copyright (c) 2017-present 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 external signer. 6 7 Verify that a bitcoind node can use an external signer command. 8 See also wallet_signer.py for tests that require wallet context. 9 """ 10 import os 11 import platform 12 import sys 13 14 from test_framework.test_framework import BitcoinTestFramework 15 from test_framework.util import ( 16 assert_equal, 17 assert_raises_rpc_error, 18 ) 19 20 21 class RPCSignerTest(BitcoinTestFramework): 22 def mock_signer_path(self): 23 path = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'mocks', 'signer.py') 24 return sys.executable + " " + path 25 26 def set_test_params(self): 27 self.num_nodes = 4 28 29 self.extra_args = [ 30 [], 31 [f"-signer={self.mock_signer_path()}", '-keypool=10'], 32 [f"-signer={self.mock_signer_path()}", '-keypool=10'], 33 ["-signer=fake.py"], 34 ] 35 36 def skip_test_if_missing_module(self): 37 self.skip_if_no_external_signer() 38 39 def set_mock_result(self, node, res): 40 with open(os.path.join(node.cwd, "mock_result"), "w") as f: 41 f.write(res) 42 43 def clear_mock_result(self, node): 44 os.remove(os.path.join(node.cwd, "mock_result")) 45 46 def run_test(self): 47 self.log.debug(f"-signer={self.mock_signer_path()}") 48 49 assert_raises_rpc_error(-1, 'Error: restart bitcoind with -signer=<cmd>', 50 self.nodes[0].enumeratesigners 51 ) 52 53 # Handle script missing: 54 assert_raises_rpc_error( 55 -1, 56 "CreateProcess failed: The system cannot find the file specified." 57 if platform.system() == "Windows" 58 else "execve failed: No such file or directory", 59 self.nodes[3].enumeratesigners, 60 ) 61 62 # Handle error thrown by script 63 self.set_mock_result(self.nodes[1], "2") 64 assert_raises_rpc_error(-1, 'RunCommandParseJSON error', 65 self.nodes[1].enumeratesigners 66 ) 67 self.clear_mock_result(self.nodes[1]) 68 69 self.set_mock_result(self.nodes[1], '0 [{"type": "trezor", "model": "trezor_t", "error": "fingerprint not found"}]') 70 assert_raises_rpc_error(-1, 'fingerprint not found', 71 self.nodes[1].enumeratesigners 72 ) 73 self.clear_mock_result(self.nodes[1]) 74 75 assert_equal({'fingerprint': '00000001', 'name': 'trezor_t'} in self.nodes[1].enumeratesigners()['signers'], True) 76 77 if __name__ == '__main__': 78 RPCSignerTest(__file__).main()