test: Test loading wallets with conflicts without a chain

Loading a wallet with conflicts without a chain (e.g. wallet tool and
migration) would previously result in an assertion due to -1 being both
a valid number of conflict confirmations, and the indicator that that
member has not been set yet.
This commit is contained in:
Andrew Chow
2023-09-26 21:23:18 -04:00
parent 4660fc82a1
commit 782701ce7d
2 changed files with 101 additions and 0 deletions

View File

@@ -727,6 +727,49 @@ class WalletMigrationTest(BitcoinTestFramework):
self.nodes[0].loadwallet(info_migration["watchonly_name"])
assert_equal(wallet_wo.getbalances()['mine']['trusted'], 5)
def test_conflict_txs(self):
self.log.info("Test migration when wallet contains conflicting transactions")
def_wallet = self.nodes[0].get_wallet_rpc(self.default_wallet_name)
wallet = self.create_legacy_wallet("conflicts")
def_wallet.sendtoaddress(wallet.getnewaddress(), 10)
self.generate(self.nodes[0], 1)
# parent tx
parent_txid = wallet.sendtoaddress(wallet.getnewaddress(), 9)
parent_txid_bytes = bytes.fromhex(parent_txid)[::-1]
conflict_utxo = wallet.gettransaction(txid=parent_txid, verbose=True)["decoded"]["vin"][0]
# The specific assertion in MarkConflicted being tested requires that the parent tx is already loaded
# by the time the child tx is loaded. Since transactions end up being loaded in txid order due to how both
# and sqlite store things, we can just grind the child tx until it has a txid that is greater than the parent's.
locktime = 500000000 # Use locktime as nonce, starting at unix timestamp minimum
addr = wallet.getnewaddress()
while True:
child_send_res = wallet.send(outputs=[{addr: 8}], add_to_wallet=False, locktime=locktime)
child_txid = child_send_res["txid"]
child_txid_bytes = bytes.fromhex(child_txid)[::-1]
if (child_txid_bytes > parent_txid_bytes):
wallet.sendrawtransaction(child_send_res["hex"])
break
locktime += 1
# conflict with parent
conflict_unsigned = self.nodes[0].createrawtransaction(inputs=[conflict_utxo], outputs=[{wallet.getnewaddress(): 9.9999}])
conflict_signed = wallet.signrawtransactionwithwallet(conflict_unsigned)["hex"]
conflict_txid = self.nodes[0].sendrawtransaction(conflict_signed)
self.generate(self.nodes[0], 1)
assert_equal(wallet.gettransaction(txid=parent_txid)["confirmations"], -1)
assert_equal(wallet.gettransaction(txid=child_txid)["confirmations"], -1)
assert_equal(wallet.gettransaction(txid=conflict_txid)["confirmations"], 1)
wallet.migratewallet()
assert_equal(wallet.gettransaction(txid=parent_txid)["confirmations"], -1)
assert_equal(wallet.gettransaction(txid=child_txid)["confirmations"], -1)
assert_equal(wallet.gettransaction(txid=conflict_txid)["confirmations"], 1)
wallet.unloadwallet()
def run_test(self):
self.generate(self.nodes[0], 101)
@@ -743,6 +786,7 @@ class WalletMigrationTest(BitcoinTestFramework):
self.test_direct_file()
self.test_addressbook()
self.test_migrate_raw_p2sh()
self.test_conflict_txs()
if __name__ == '__main__':
WalletMigrationTest().main()