From 90d0396819ddfbabb8b7f45e8fc3ac0992a6b014 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Wed, 7 Oct 2026 08:21:47 -0700 Subject: ark tests: shared aliceReady() keeps the bark funding wallet usable scheduled-refresh-test mines a whole vtxo lifetime, which expires alice's coins; every test run after it funded nothing (spendableSat 0) or was handed an expired coin (receive-test). The helper refreshes expired coins and boards more when alice runs low, and the funding tests call it before paying. Co-Authored-By: Claude Opus 5.5 --- tools/ark/alice.js | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 tools/ark/alice.js (limited to 'tools/ark/alice.js') diff --git a/tools/ark/alice.js b/tools/ark/alice.js new file mode 100644 index 0000000..9c33661 --- /dev/null +++ b/tools/ark/alice.js @@ -0,0 +1,46 @@ +// alice = the bark CLI wallet the regtest ark tests fund from. +// +// scheduled-refresh-test mines a coin's whole lifetime, which expires alice's +// coins too — an expired vtxo can be refreshed but not sent, so any test that +// runs after it would fund nothing ("spendableSat 0") or hand out an expired +// coin. Every funding test also drains her a little. aliceReady() refreshes +// expired coins back to life and boards more when she runs low; a no-op when +// she's healthy. + +import { execSync } from 'node:child_process'; + +export const ALICE = `${process.env.HOME}/bark/target/debug/bark --datadir ${process.env.HOME}/ark-regtest/alice`; +const BCLI = 'docker exec bc bitcoin-cli -rpcwallet=coinos'; +const sh = (cmd) => execSync(cmd, { shell: '/bin/bash' }).toString().trim(); +const mine = (n) => sh(`${BCLI} generatetoaddress ${n} $(${BCLI} getnewaddress) >/dev/null`); +const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); + +const LOW_SAT = 200_000; +const TOP_UP_BTC = '0.01'; + +export const aliceBalance = () => JSON.parse(sh(`${ALICE} -q balance`)).spendable_sat; +const expiredCoins = () => { + const tip = Number(sh(`${BCLI} getblockcount`)); + return JSON.parse(sh(`${ALICE} -q vtxos`)).filter((v) => v.expiry_height <= tip); +}; + +export async function aliceReady() { + if (expiredCoins().length) { + console.log(' … refreshing alice\'s expired coins first'); + sh(`${ALICE} -q refresh --all >/dev/null`); + // the round's output turns spendable once its funding tx confirms and the + // indexer has seen it — keep mining until bark agrees + for (let i = 0; i < 20 && (expiredCoins().length || !aliceBalance()); i++) { mine(1); await sleep(1500); } + } + if (aliceBalance() < LOW_SAT) { + console.log(` … topping alice up (board ${TOP_UP_BTC} BTC)`); + const { address } = JSON.parse(sh(`${ALICE} -q onchain address`)); + sh(`${BCLI} sendtoaddress ${address} ${TOP_UP_BTC} >/dev/null`); + mine(1); + for (let i = 0; i < 20; i++) { + try { sh(`${ALICE} -q board --all >/dev/null 2>&1`); break; } catch { await sleep(1500); } // wallet sync lag + } + const before = aliceBalance(); + for (let i = 0; i < 20 && aliceBalance() <= before; i++) { mine(1); await sleep(1500); } + } +} -- cgit v1.2.3