Changeset View
Standalone View
test/functional/wallet_encryption.py
#!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||
# Copyright (c) 2016 The Bitcoin Core developers | # Copyright (c) 2016 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 Wallet encryption""" | """Test Wallet encryption""" | ||||
import time | import time | ||||
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_rpc_error, | assert_raises_rpc_error, | ||||
) | ) | ||||
class WalletEncryptionTest(BitcoinTestFramework): | class WalletEncryptionTest(BitcoinTestFramework): | ||||
florian: blame the linter | |||||
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 run_test(self): | def run_test(self): | ||||
passphrase = "WalletPassphrase" | passphrase = "WalletPassphrase" | ||||
passphrase2 = "SecondWalletPassphrase" | passphrase2 = "SecondWalletPassphrase" | ||||
# Make sure the wallet isn't encrypted first | # Make sure the wallet isn't encrypted first | ||||
address = self.nodes[0].getnewaddress() | address = self.nodes[0].getnewaddress() | ||||
privkey = self.nodes[0].dumpprivkey(address) | privkey = self.nodes[0].dumpprivkey(address) | ||||
assert_equal(privkey[:1], "c") | assert_equal(privkey[:1], "c") | ||||
assert_equal(len(privkey), 52) | assert_equal(len(privkey), 52) | ||||
# Encrypt the wallet | # Encrypt the wallet | ||||
self.nodes[0].node_encrypt_wallet(passphrase) | self.nodes[0].node_encrypt_wallet(passphrase) | ||||
self.start_node(0) | self.start_node(0) | ||||
# Check the encrypted wallet is marked as locked on initialization | |||||
assert_equal(self.nodes[0].getwalletinfo()['unlocked_until'], 0) | |||||
# Test that the wallet is encrypted | # Test that the wallet is encrypted | ||||
assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", | assert_raises_rpc_error( | ||||
-13, "Please enter the wallet passphrase with walletpassphrase first", | |||||
self.nodes[0].dumpprivkey, address) | self.nodes[0].dumpprivkey, address) | ||||
# Check that walletpassphrase works | # Check that walletpassphrase works | ||||
self.nodes[0].walletpassphrase(passphrase, 2) | self.nodes[0].walletpassphrase(passphrase, 2) | ||||
assert_equal(privkey, self.nodes[0].dumpprivkey(address)) | assert_equal(privkey, self.nodes[0].dumpprivkey(address)) | ||||
# Check that the timeout is right | # Check that the timeout is right | ||||
time.sleep(2) | time.sleep(2) | ||||
assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", | assert_raises_rpc_error( | ||||
-13, "Please enter the wallet passphrase with walletpassphrase first", | |||||
self.nodes[0].dumpprivkey, address) | self.nodes[0].dumpprivkey, address) | ||||
# Test wrong passphrase | # Test wrong passphrase | ||||
assert_raises_rpc_error(-14, "wallet passphrase entered was incorrect", | assert_raises_rpc_error(-14, "wallet passphrase entered was incorrect", | ||||
self.nodes[0].walletpassphrase, passphrase + "wrong", 10) | self.nodes[0].walletpassphrase, passphrase + "wrong", 10) | ||||
# Test walletlock | # Test walletlock and unlocked_until values | ||||
self.nodes[0].walletpassphrase(passphrase, 84600) | self.nodes[0].walletpassphrase(passphrase, 84600) | ||||
assert_equal(privkey, self.nodes[0].dumpprivkey(address)) | assert_equal(privkey, self.nodes[0].dumpprivkey(address)) | ||||
assert( | |||||
abs(self.nodes[0].getwalletinfo()['unlocked_until'] - (time.time() + 84600)) < 2) | |||||
FabienUnsubmitted Done Inline ActionsI'm not a fan of the assertion being time dependent. If for some reason the dumpprivkey rpc lasts more than a second the test will fail. Fabien: I'm not a fan of the assertion being time dependent. If for some reason the `dumpprivkey` rpc… | |||||
deadalnixUnsubmitted Done Inline ActionsYes, this needs to be reworked. Timing dependent assertions are to be avoided, especially since there are time mocking capabilities. It would also be worth looking at what core does and backport that if they already fixed it. deadalnix: Yes, this needs to be reworked. Timing dependent assertions are to be avoided, especially since… | |||||
florianAuthorUnsubmitted Done Inline ActionsThanks for the mocktime idea, I fixed it. Core just fixed the bug on wallet.h (https://github.com/bitcoin/bitcoin/pull/9993). florian: Thanks for the mocktime idea, I fixed it. Core just fixed the bug on wallet.h (https://github. | |||||
florianAuthorUnsubmitted Done Inline ActionsI agree and I fixed it, but please note this test already had time dependencies. For instance, that assert on line 46 breaks if the rpc call on 45 takes more than 2 seconds to return. This is the reason I chose a 2 seconds tolerance on the diff you reviewed. florian: I agree and I fixed it, but please note this test already had time dependencies. For instance… | |||||
self.nodes[0].walletlock() | self.nodes[0].walletlock() | ||||
assert_raises_rpc_error(-13, "Please enter the wallet passphrase with walletpassphrase first", | assert_raises_rpc_error( | ||||
-13, "Please enter the wallet passphrase with walletpassphrase first", | |||||
self.nodes[0].dumpprivkey, address) | self.nodes[0].dumpprivkey, address) | ||||
assert_equal(self.nodes[0].getwalletinfo()['unlocked_until'], 0) | |||||
# Test passphrase changes | # Test passphrase changes | ||||
self.nodes[0].walletpassphrasechange(passphrase, passphrase2) | self.nodes[0].walletpassphrasechange(passphrase, passphrase2) | ||||
assert_raises_rpc_error(-14, "wallet passphrase entered was incorrect", | assert_raises_rpc_error(-14, "wallet passphrase entered was incorrect", | ||||
self.nodes[0].walletpassphrase, passphrase, 10) | self.nodes[0].walletpassphrase, passphrase, 10) | ||||
self.nodes[0].walletpassphrase(passphrase2, 10) | self.nodes[0].walletpassphrase(passphrase2, 10) | ||||
assert_equal(privkey, self.nodes[0].dumpprivkey(address)) | assert_equal(privkey, self.nodes[0].dumpprivkey(address)) | ||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
WalletEncryptionTest().main() | WalletEncryptionTest().main() |
blame the linter