From 63b56272bf2165eafd72fa4a02014cfbeb9e965b Mon Sep 17 00:00:00 2001 From: Alfredo Garcia Date: Wed, 3 Jun 2026 19:36:50 -0300 Subject: [PATCH] wallet.py: add sync barriers to fix wallet-scan race wallet.py read z_gettotalbalance / z_listtransactions immediately after mining, before the wallet had scanned and committed the new blocks, causing a flaky transparent-balance assertion (0 vs 6.25). Poll for the expected wallet view (no synchronous wallet-sync RPC yet, zcash/wallet#316) before the wallet-side assertions. Co-Authored-By: Claude Opus 4.8 (1M context) --- qa/rpc-tests/wallet.py | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/qa/rpc-tests/wallet.py b/qa/rpc-tests/wallet.py index c871395f2..61d3e2603 100755 --- a/qa/rpc-tests/wallet.py +++ b/qa/rpc-tests/wallet.py @@ -10,6 +10,29 @@ from test_framework.test_framework import BitcoinTestFramework from test_framework.util import assert_equal, assert_true + +def wait_for_wallet_transparent(wallet, expected, timeout=60): + # z_gettotalbalance reflects only blocks the wallet has scanned and committed; after + # mining there is a delay before that view catches up. Poll for the expected value + # instead of racing it (there is no synchronous wallet-sync RPC yet, zcash/wallet#316). + deadline = time.time() + timeout + balance = wallet.z_gettotalbalance(1, True)['transparent'] + while balance != expected and time.time() < deadline: + time.sleep(0.5) + balance = wallet.z_gettotalbalance(1, True)['transparent'] + return balance + + +def wait_for_wallet_txcount(wallet, expected, timeout=60): + # Same sync barrier, for the wallet's view of its transaction count. + deadline = time.time() + timeout + count = len(wallet.z_listtransactions()) + while count != expected and time.time() < deadline: + time.sleep(0.5) + count = len(wallet.z_listtransactions()) + return count + + # Test that we can create a wallet and use an address from it to mine blocks. class WalletTest (BitcoinTestFramework): @@ -26,7 +49,8 @@ def run_test(self): node_balance = self.nodes[0].getaddressbalance(transparent_address) assert_equal(node_balance['balance'], 625000000) - # Zallet can see the balance. + # Zallet can see the balance, once it has scanned the coinbase block. + wait_for_wallet_transparent(self.wallets[0], '6.25000000') wallet_balance = self.wallets[0].z_gettotalbalance(1, True) # TODO: Result is a string (https://github.com/zcash/wallet/issues/15) assert_equal(wallet_balance['transparent'], '6.25000000') @@ -34,13 +58,11 @@ def run_test(self): # Mine another block self.nodes[0].generate(1) - # Wait for the wallet to sync - time.sleep(1) - node_balance = self.nodes[0].getaddressbalance(transparent_address) assert_equal(node_balance['balance'], 1250000000) - # There are 2 transactions in the wallet + # There are 2 transactions in the wallet, once it has scanned the new block. + wait_for_wallet_txcount(self.wallets[0], 2) assert_equal(len(self.wallets[0].z_listtransactions()), 2) # Confirmed balance in the wallet is either 6.25 or 12.5 ZEC