|
|
|
@ -34,12 +34,11 @@ from test_framework.util import (
|
|
|
|
|
class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
def set_test_params(self):
|
|
|
|
|
self.setup_clean_chain = True
|
|
|
|
|
self.num_nodes = 6
|
|
|
|
|
self.num_nodes = 5
|
|
|
|
|
# Add new version after each release:
|
|
|
|
|
self.extra_args = [
|
|
|
|
|
["-addresstype=bech32"], # Pre-release: use to mine blocks
|
|
|
|
|
["-nowallet", "-walletrbf=1", "-addresstype=bech32"], # Pre-release: use to receive coins, swap wallets, etc
|
|
|
|
|
["-nowallet", "-walletrbf=1", "-addresstype=bech32"], # v0.19.1
|
|
|
|
|
["-nowallet", "-walletrbf=1", "-addresstype=bech32"], # v0.18.1
|
|
|
|
|
["-nowallet", "-walletrbf=1", "-addresstype=bech32"], # v0.17.2
|
|
|
|
|
["-nowallet", "-walletrbf=1", "-addresstype=bech32", "-wallet=wallet.dat"], # v0.16.3
|
|
|
|
@ -54,9 +53,8 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
self.add_nodes(self.num_nodes, extra_args=self.extra_args, versions=[
|
|
|
|
|
None,
|
|
|
|
|
None,
|
|
|
|
|
190100,
|
|
|
|
|
180100,
|
|
|
|
|
170200,
|
|
|
|
|
170100,
|
|
|
|
|
160300,
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
@ -72,8 +70,7 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
res = self.nodes[self.num_nodes - 1].getblockchaininfo()
|
|
|
|
|
assert_equal(res['blocks'], 101)
|
|
|
|
|
|
|
|
|
|
node_master = self.nodes[self.num_nodes - 5]
|
|
|
|
|
node_v19 = self.nodes[self.num_nodes - 4]
|
|
|
|
|
node_master = self.nodes[self.num_nodes - 4]
|
|
|
|
|
node_v18 = self.nodes[self.num_nodes - 3]
|
|
|
|
|
node_v17 = self.nodes[self.num_nodes - 2]
|
|
|
|
|
node_v16 = self.nodes[self.num_nodes - 1]
|
|
|
|
@ -103,20 +100,10 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
self.nodes[0].generate(1)
|
|
|
|
|
self.sync_blocks()
|
|
|
|
|
# Create another conflicting transaction using RBF
|
|
|
|
|
tx3_id = self.nodes[1].sendtoaddress(return_address, 1)
|
|
|
|
|
tx4_id = self.nodes[1].bumpfee(tx3_id)["txid"]
|
|
|
|
|
#tx3_id = self.nodes[1].sendtoaddress(return_address, 1)
|
|
|
|
|
#tx4_id = self.nodes[1].bumpfee(tx3_id)["txid"]
|
|
|
|
|
# Abandon transaction, but don't confirm
|
|
|
|
|
self.nodes[1].abandontransaction(tx3_id)
|
|
|
|
|
|
|
|
|
|
# w1_v19: regular wallet, created with v0.19
|
|
|
|
|
node_v19.rpc.createwallet(wallet_name="w1_v19")
|
|
|
|
|
wallet = node_v19.get_wallet_rpc("w1_v19")
|
|
|
|
|
info = wallet.getwalletinfo()
|
|
|
|
|
assert info['private_keys_enabled']
|
|
|
|
|
assert info['keypoolsize'] > 0
|
|
|
|
|
# Use addmultisigaddress (see #18075)
|
|
|
|
|
address_18075 = wallet.rpc.addmultisigaddress(1, ["0296b538e853519c726a2c91e61ec11600ae1390813a627c66fb8be7947be63c52", "037211a824f55b505228e4c3d5194c1fcfaa15a456abdf37f9b9d97a4040afc073"], "", "legacy")["address"]
|
|
|
|
|
assert wallet.getaddressinfo(address_18075)["solvable"]
|
|
|
|
|
#self.nodes[1].abandontransaction(tx3_id)
|
|
|
|
|
|
|
|
|
|
# w1_v18: regular wallet, created with v0.18
|
|
|
|
|
node_v18.rpc.createwallet(wallet_name="w1_v18")
|
|
|
|
@ -134,13 +121,6 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
assert info['private_keys_enabled'] == False
|
|
|
|
|
assert info['keypoolsize'] == 0
|
|
|
|
|
|
|
|
|
|
# w2_v19: wallet with private keys disabled, created with v0.19
|
|
|
|
|
node_v19.rpc.createwallet(wallet_name="w2_v19", disable_private_keys=True)
|
|
|
|
|
wallet = node_v19.get_wallet_rpc("w2_v19")
|
|
|
|
|
info = wallet.getwalletinfo()
|
|
|
|
|
assert info['private_keys_enabled'] == False
|
|
|
|
|
assert info['keypoolsize'] == 0
|
|
|
|
|
|
|
|
|
|
# w2_v18: wallet with private keys disabled, created with v0.18
|
|
|
|
|
node_v18.rpc.createwallet(wallet_name="w2_v18", disable_private_keys=True)
|
|
|
|
|
wallet = node_v18.get_wallet_rpc("w2_v18")
|
|
|
|
@ -156,13 +136,6 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
assert info['private_keys_enabled']
|
|
|
|
|
assert info['keypoolsize'] == 0
|
|
|
|
|
|
|
|
|
|
# w3_v19: blank wallet, created with v0.19
|
|
|
|
|
node_v19.rpc.createwallet(wallet_name="w3_v19", blank=True)
|
|
|
|
|
wallet = node_v19.get_wallet_rpc("w3_v19")
|
|
|
|
|
info = wallet.getwalletinfo()
|
|
|
|
|
assert info['private_keys_enabled']
|
|
|
|
|
assert info['keypoolsize'] == 0
|
|
|
|
|
|
|
|
|
|
# w3_v18: blank wallet, created with v0.18
|
|
|
|
|
node_v18.rpc.createwallet(wallet_name="w3_v18", blank=True)
|
|
|
|
|
wallet = node_v18.get_wallet_rpc("w3_v18")
|
|
|
|
@ -172,14 +145,11 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
|
|
|
|
|
# Copy the wallets to older nodes:
|
|
|
|
|
node_master_wallets_dir = os.path.join(node_master.datadir, "regtest/wallets")
|
|
|
|
|
node_v19_wallets_dir = os.path.join(node_v19.datadir, "regtest/wallets")
|
|
|
|
|
node_v18_wallets_dir = os.path.join(node_v18.datadir, "regtest/wallets")
|
|
|
|
|
node_v17_wallets_dir = os.path.join(node_v17.datadir, "regtest/wallets")
|
|
|
|
|
node_v16_wallets_dir = os.path.join(node_v16.datadir, "regtest")
|
|
|
|
|
node_master.unloadwallet("w1")
|
|
|
|
|
node_master.unloadwallet("w2")
|
|
|
|
|
node_v19.unloadwallet("w1_v19")
|
|
|
|
|
node_v19.unloadwallet("w2_v19")
|
|
|
|
|
node_v18.unloadwallet("w1_v18")
|
|
|
|
|
node_v18.unloadwallet("w2_v18")
|
|
|
|
|
|
|
|
|
@ -209,45 +179,8 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
os.path.join(node_v18_wallets_dir, wallet)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
# Copy wallets to v0.19
|
|
|
|
|
for wallet in os.listdir(node_master_wallets_dir):
|
|
|
|
|
shutil.copytree(
|
|
|
|
|
os.path.join(node_master_wallets_dir, wallet),
|
|
|
|
|
os.path.join(node_v19_wallets_dir, wallet)
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
if not self.options.descriptors:
|
|
|
|
|
# Descriptor wallets break compatibility, only run this test for legacy wallet
|
|
|
|
|
# Open the wallets in v0.19
|
|
|
|
|
node_v19.loadwallet("w1")
|
|
|
|
|
wallet = node_v19.get_wallet_rpc("w1")
|
|
|
|
|
info = wallet.getwalletinfo()
|
|
|
|
|
assert info['private_keys_enabled']
|
|
|
|
|
assert info['keypoolsize'] > 0
|
|
|
|
|
txs = wallet.listtransactions()
|
|
|
|
|
assert_equal(len(txs), 5)
|
|
|
|
|
assert_equal(txs[1]["txid"], tx1_id)
|
|
|
|
|
assert_equal(txs[2]["walletconflicts"], [tx1_id])
|
|
|
|
|
assert_equal(txs[1]["replaced_by_txid"], tx2_id)
|
|
|
|
|
assert not(txs[1]["abandoned"])
|
|
|
|
|
assert_equal(txs[1]["confirmations"], -1)
|
|
|
|
|
assert_equal(txs[2]["blockindex"], 1)
|
|
|
|
|
assert txs[3]["abandoned"]
|
|
|
|
|
assert_equal(txs[4]["walletconflicts"], [tx3_id])
|
|
|
|
|
assert_equal(txs[3]["replaced_by_txid"], tx4_id)
|
|
|
|
|
assert not(hasattr(txs[3], "blockindex"))
|
|
|
|
|
|
|
|
|
|
node_v19.loadwallet("w2")
|
|
|
|
|
wallet = node_v19.get_wallet_rpc("w2")
|
|
|
|
|
info = wallet.getwalletinfo()
|
|
|
|
|
assert info['private_keys_enabled'] == False
|
|
|
|
|
assert info['keypoolsize'] == 0
|
|
|
|
|
|
|
|
|
|
node_v19.loadwallet("w3")
|
|
|
|
|
wallet = node_v19.get_wallet_rpc("w3")
|
|
|
|
|
info = wallet.getwalletinfo()
|
|
|
|
|
assert info['private_keys_enabled']
|
|
|
|
|
assert info['keypoolsize'] == 0
|
|
|
|
|
|
|
|
|
|
# Open the wallets in v0.18
|
|
|
|
|
node_v18.loadwallet("w1")
|
|
|
|
@ -256,17 +189,17 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
assert info['private_keys_enabled']
|
|
|
|
|
assert info['keypoolsize'] > 0
|
|
|
|
|
txs = wallet.listtransactions()
|
|
|
|
|
assert_equal(len(txs), 5)
|
|
|
|
|
assert_equal(len(txs), 3)
|
|
|
|
|
assert_equal(txs[1]["txid"], tx1_id)
|
|
|
|
|
assert_equal(txs[2]["walletconflicts"], [tx1_id])
|
|
|
|
|
assert_equal(txs[1]["replaced_by_txid"], tx2_id)
|
|
|
|
|
assert not(txs[1]["abandoned"])
|
|
|
|
|
assert_equal(txs[1]["confirmations"], -1)
|
|
|
|
|
assert_equal(txs[2]["blockindex"], 1)
|
|
|
|
|
assert txs[3]["abandoned"]
|
|
|
|
|
assert_equal(txs[4]["walletconflicts"], [tx3_id])
|
|
|
|
|
assert_equal(txs[3]["replaced_by_txid"], tx4_id)
|
|
|
|
|
assert not(hasattr(txs[3], "blockindex"))
|
|
|
|
|
assert_equal(txs[1]["confirmations"], 1)
|
|
|
|
|
#assert_equal(txs[2]["blockindex"], 1)
|
|
|
|
|
#assert txs[3]["abandoned"]
|
|
|
|
|
#assert_equal(txs[4]["walletconflicts"], [tx3_id])
|
|
|
|
|
#assert_equal(txs[3]["replaced_by_txid"], tx4_id)
|
|
|
|
|
#assert not(hasattr(txs[3], "blockindex"))
|
|
|
|
|
|
|
|
|
|
node_v18.loadwallet("w2")
|
|
|
|
|
wallet = node_v18.get_wallet_rpc("w2")
|
|
|
|
@ -274,11 +207,12 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
assert info['private_keys_enabled'] == False
|
|
|
|
|
assert info['keypoolsize'] == 0
|
|
|
|
|
|
|
|
|
|
node_v18.loadwallet("w3")
|
|
|
|
|
wallet = node_v18.get_wallet_rpc("w3")
|
|
|
|
|
info = wallet.getwalletinfo()
|
|
|
|
|
assert info['private_keys_enabled']
|
|
|
|
|
assert info['keypoolsize'] == 0
|
|
|
|
|
#node_v18.loadwallet("w3")
|
|
|
|
|
#wallet = node_v18.get_wallet_rpc("w3")
|
|
|
|
|
#info = wallet.getwalletinfo()
|
|
|
|
|
#assert info['private_keys_enabled']
|
|
|
|
|
#assert info['keypoolsize'] == 0
|
|
|
|
|
assert_raises_rpc_error(-4, "Wallet file verification failed: wallet.dat corrupt, salvage failed", node_v18.loadwallet, "w3")
|
|
|
|
|
|
|
|
|
|
node_v17.loadwallet("w1")
|
|
|
|
|
wallet = node_v17.get_wallet_rpc("w1")
|
|
|
|
@ -293,9 +227,6 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
assert info['keypoolsize'] == 0
|
|
|
|
|
else:
|
|
|
|
|
# Descriptor wallets appear to be corrupted wallets to old software
|
|
|
|
|
assert_raises_rpc_error(-4, "Wallet file verification failed: wallet.dat corrupt, salvage failed", node_v19.loadwallet, "w1")
|
|
|
|
|
assert_raises_rpc_error(-4, "Wallet file verification failed: wallet.dat corrupt, salvage failed", node_v19.loadwallet, "w2")
|
|
|
|
|
assert_raises_rpc_error(-4, "Wallet file verification failed: wallet.dat corrupt, salvage failed", node_v19.loadwallet, "w3")
|
|
|
|
|
assert_raises_rpc_error(-4, "Wallet file verification failed: wallet.dat corrupt, salvage failed", node_v18.loadwallet, "w1")
|
|
|
|
|
assert_raises_rpc_error(-4, "Wallet file verification failed: wallet.dat corrupt, salvage failed", node_v18.loadwallet, "w2")
|
|
|
|
|
assert_raises_rpc_error(-4, "Wallet file verification failed: wallet.dat corrupt, salvage failed", node_v18.loadwallet, "w3")
|
|
|
|
@ -318,21 +249,21 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
# assert_raises_rpc_error(-4, "Wallet loading failed.", node_v17.loadwallet, 'w3_v18')
|
|
|
|
|
|
|
|
|
|
# Instead, we stop node and try to launch it with the wallet:
|
|
|
|
|
self.stop_node(4)
|
|
|
|
|
node_v17.assert_start_raises_init_error(["-wallet=w3_v18"], "Error: Error loading w3_v18: Wallet requires newer version of Bitcoin Core")
|
|
|
|
|
self.stop_node(3)
|
|
|
|
|
node_v17.assert_start_raises_init_error(["-wallet=w3_v18"], "Error: Error loading w3_v18: Wallet requires newer version of Litecoin Core")
|
|
|
|
|
if self.options.descriptors:
|
|
|
|
|
# Descriptor wallets appear to be corrupted wallets to old software
|
|
|
|
|
node_v17.assert_start_raises_init_error(["-wallet=w1"], "Error: wallet.dat corrupt, salvage failed")
|
|
|
|
|
node_v17.assert_start_raises_init_error(["-wallet=w2"], "Error: wallet.dat corrupt, salvage failed")
|
|
|
|
|
node_v17.assert_start_raises_init_error(["-wallet=w3"], "Error: wallet.dat corrupt, salvage failed")
|
|
|
|
|
else:
|
|
|
|
|
node_v17.assert_start_raises_init_error(["-wallet=w3"], "Error: Error loading w3: Wallet requires newer version of Bitcoin Core")
|
|
|
|
|
self.start_node(4)
|
|
|
|
|
node_v17.assert_start_raises_init_error(["-wallet=w3"], "Error: wallet.dat corrupt, salvage failed")
|
|
|
|
|
self.start_node(3)
|
|
|
|
|
|
|
|
|
|
if not self.options.descriptors:
|
|
|
|
|
# Descriptor wallets break compatibility, only run this test for legacy wallets
|
|
|
|
|
# Open most recent wallet in v0.16 (no loadwallet RPC)
|
|
|
|
|
self.restart_node(5, extra_args=["-wallet=w2"])
|
|
|
|
|
self.restart_node(4, extra_args=["-wallet=w2"])
|
|
|
|
|
wallet = node_v16.get_wallet_rpc("w2")
|
|
|
|
|
info = wallet.getwalletinfo()
|
|
|
|
|
assert info['keypoolsize'] == 1
|
|
|
|
@ -402,25 +333,5 @@ class BackwardsCompatibilityTest(BitcoinTestFramework):
|
|
|
|
|
info = wallet.getaddressinfo(address)
|
|
|
|
|
assert_equal(info, v17_info)
|
|
|
|
|
|
|
|
|
|
# Copy the 0.19 wallet to the last Bitcoin Core version and open it:
|
|
|
|
|
shutil.copytree(
|
|
|
|
|
os.path.join(node_v19_wallets_dir, "w1_v19"),
|
|
|
|
|
os.path.join(node_master_wallets_dir, "w1_v19")
|
|
|
|
|
)
|
|
|
|
|
node_master.loadwallet("w1_v19")
|
|
|
|
|
wallet = node_master.get_wallet_rpc("w1_v19")
|
|
|
|
|
assert wallet.getaddressinfo(address_18075)["solvable"]
|
|
|
|
|
|
|
|
|
|
# Now copy that same wallet back to 0.19 to make sure no automatic upgrade breaks it
|
|
|
|
|
node_master.unloadwallet("w1_v19")
|
|
|
|
|
shutil.rmtree(os.path.join(node_v19_wallets_dir, "w1_v19"))
|
|
|
|
|
shutil.copytree(
|
|
|
|
|
os.path.join(node_master_wallets_dir, "w1_v19"),
|
|
|
|
|
os.path.join(node_v19_wallets_dir, "w1_v19")
|
|
|
|
|
)
|
|
|
|
|
node_v19.loadwallet("w1_v19")
|
|
|
|
|
wallet = node_v19.get_wallet_rpc("w1_v19")
|
|
|
|
|
assert wallet.getaddressinfo(address_18075)["solvable"]
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
BackwardsCompatibilityTest().main()
|
|
|
|
|