aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2026-10-07 08:21:47 -0700
committerAdam Soltys <[email protected]>2026-10-07 08:21:47 -0700
commit90d0396819ddfbabb8b7f45e8fc3ac0992a6b014 (patch)
treeadb0aeb5e1919fb93838491168b2647160e88a07 /tools
parentbba8280a241ce86b0f372818d7aca85073d8e53a (diff)
downloadcoinosv3-90d0396819ddfbabb8b7f45e8fc3ac0992a6b014.tar.gz
coinosv3-90d0396819ddfbabb8b7f45e8fc3ac0992a6b014.zip
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 <[email protected]>
Diffstat (limited to 'tools')
-rw-r--r--tools/ark/alice.js46
-rw-r--r--tools/ark/ln-e2e-test.js4
-rw-r--r--tools/ark/ln-test.js4
-rw-r--r--tools/ark/manager-test.js4
-rw-r--r--tools/ark/receive-test.js5
-rw-r--r--tools/ark/scheduled-refresh-test.js17
6 files changed, 58 insertions, 22 deletions
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); }
+ }
+}
diff --git a/tools/ark/ln-e2e-test.js b/tools/ark/ln-e2e-test.js
index 4d31b56..088dcb0 100644
--- a/tools/ark/ln-e2e-test.js
+++ b/tools/ark/ln-e2e-test.js
@@ -18,11 +18,10 @@ import { sha256 } from '@noble/hashes/sha256';
import { ArkManager } from '../../src/ark/manager.js';
import { lnReceiveFee } from '../../src/ark/lightning.js';
+import { ALICE, aliceReady } from './alice.js';
const ARK = process.env.ARK_URL || 'http://127.0.0.1:3535';
const ESPLORA = process.env.ESPLORA_URL || 'http://127.0.0.1:30002';
-const BARK = `${process.env.HOME}/bark/target/debug/bark`;
-const ALICE = `${BARK} --datadir ${process.env.HOME}/ark-regtest/alice`;
const CLC = 'docker exec clc lightning-cli --regtest';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -45,6 +44,7 @@ const account = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic)).derive("m/86'
const mgr = await new ArkManager({ account, storage, arkUrl: ARK, esploraUrl: ESPLORA }).init();
console.log('\n[0] fund manager from alice');
+await aliceReady();
sh(`${ALICE} -q send ${mgr.address()} "25000 sat"`);
for (let i = 0; i < 10 && !mgr.balance().spendableSat; i++) { await mgr.sync(); await sleep(1500); }
check('funded 25000 sat', mgr.balance().spendableSat === 25000, JSON.stringify(mgr.balance()));
diff --git a/tools/ark/ln-test.js b/tools/ark/ln-test.js
index c76d914..87e29d4 100644
--- a/tools/ark/ln-test.js
+++ b/tools/ark/ln-test.js
@@ -19,11 +19,10 @@ import { secp256k1 } from '@noble/curves/secp256k1';
import { ArkManager } from '../../src/ark/manager.js';
import { decodeBolt11 } from '../../src/ark/lightning.js';
+import { ALICE, aliceReady } from './alice.js';
const ARK = process.env.ARK_URL || 'http://127.0.0.1:3535';
const ESPLORA = process.env.ESPLORA_URL || 'http://127.0.0.1:30002';
-const BARK = `${process.env.HOME}/bark/target/debug/bark`;
-const ALICE = `${BARK} --datadir ${process.env.HOME}/ark-regtest/alice`;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const sh = (cmd) => execSync(cmd, { shell: '/bin/bash' }).toString().trim();
@@ -89,6 +88,7 @@ const account = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic)).derive("m/86'
const mgr = await new ArkManager({ account, storage, arkUrl: ARK, esploraUrl: ESPLORA }).init();
console.log('\n[0] fund manager from alice');
+await aliceReady();
sh(`${ALICE} -q send ${mgr.address()} "25000 sat"`);
for (let i = 0; i < 10 && !mgr.balance().spendableSat; i++) { await mgr.sync(); await sleep(1500); }
check('funded 25000 sat', mgr.balance().spendableSat === 25000, JSON.stringify(mgr.balance()));
diff --git a/tools/ark/manager-test.js b/tools/ark/manager-test.js
index 74a1c5c..6cbc506 100644
--- a/tools/ark/manager-test.js
+++ b/tools/ark/manager-test.js
@@ -17,11 +17,10 @@ import { hex } from '@scure/base';
import { ArkManager } from '../../src/ark/manager.js';
import { decodeVtxo, vtxoBytesFromStr } from '../../src/ark/proto.js';
import { validateVtxo } from '../../src/ark/validate.js';
+import { ALICE, aliceReady } from './alice.js';
const ARK = process.env.ARK_URL || 'http://127.0.0.1:3535';
const ESPLORA = process.env.ESPLORA_URL || 'http://127.0.0.1:30002';
-const BARK = `${process.env.HOME}/bark/target/debug/bark`;
-const ALICE = `${BARK} --datadir ${process.env.HOME}/ark-regtest/alice`;
const BCLI = `docker exec bc bitcoin-cli -rpcwallet=coinos`;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -52,6 +51,7 @@ let mgr = await newManager();
// --- 1. receive with full validation ---
console.log('\n[1] receive');
const addr = mgr.address();
+await aliceReady();
sh(`${ALICE} -q send ${addr} "20000 sat"`);
for (let i = 0; i < 10 && !mgr.balance().spendableSat; i++) { await mgr.sync(); await sleep(1500); }
check('received 20000 sat', mgr.balance().spendableSat === 20000, JSON.stringify(mgr.balance()));
diff --git a/tools/ark/receive-test.js b/tools/ark/receive-test.js
index 1e6adbe..ac916ad 100644
--- a/tools/ark/receive-test.js
+++ b/tools/ark/receive-test.js
@@ -17,11 +17,11 @@ import {
getArkInfo, handshake, encodeAddress, decodeAddress,
blindMailboxId, readMailbox,
} from '../../src/ark/proto.js';
+import { ALICE as ALICE_CLI, aliceReady } from './alice.js';
const ARK = process.env.ARK_URL || 'http://127.0.0.1:3535';
const ESPLORA = process.env.ESPLORA_URL || 'http://127.0.0.1:30002';
-const BARK = `${process.env.HOME}/bark/target/debug/bark`;
-const ALICE = `${BARK} --datadir ${process.env.HOME}/ark-regtest/alice -q`;
+const ALICE = `${ALICE_CLI} -q`;
const AMOUNT_SAT = 12345;
const MNEMONIC = 'rug rebuild abstract kiwi rifle vast food robust rifle spirit dilemma stumble';
@@ -57,6 +57,7 @@ console.log('round-trip decode:', decodeAddress(address));
// --- 3. pay it from the bark CLI ---
console.log(`\npaying ${AMOUNT_SAT} sat from alice (bark CLI)...`);
+await aliceReady();
execSync(`${ALICE} send ${address} "${AMOUNT_SAT} sat"`, { stdio: 'inherit' });
// --- 4. read mailbox, decode, validate ---
diff --git a/tools/ark/scheduled-refresh-test.js b/tools/ark/scheduled-refresh-test.js
index bb030c4..c406514 100644
--- a/tools/ark/scheduled-refresh-test.js
+++ b/tools/ark/scheduled-refresh-test.js
@@ -15,11 +15,10 @@ import { wordlist } from '@scure/bip39/wordlists/english';
import { HDKey } from '@scure/bip32';
import { ArkManager } from '../../src/ark/manager.js';
+import { ALICE, aliceReady } from './alice.js';
const ARK = process.env.ARK_URL || 'http://127.0.0.1:3535';
const ESPLORA = process.env.ESPLORA_URL || 'http://127.0.0.1:30002';
-const BARK = `${process.env.HOME}/bark/target/debug/bark`;
-const ALICE = `${BARK} --datadir ${process.env.HOME}/ark-regtest/alice`;
const BCLI = `docker exec bc bitcoin-cli -rpcwallet=coinos`;
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
@@ -44,18 +43,8 @@ const account = HDKey.fromMasterSeed(mnemonicToSeedSync(mnemonic)).derive("m/86'
const mgr = await new ArkManager({ account, storage, arkUrl: ARK, esploraUrl: ESPLORA }).init();
// This test mines a coin's whole lifetime in step 5, which also expires the
-// funding wallet's coins — an expired vtxo can be refreshed but not sent, so
-// re-running against a chain that already ran it would fund nothing.
-const fundingReady = () => {
- const alice = JSON.parse(sh(`${ALICE} -q vtxos`));
- const tip = tipHeight();
- if (!alice.some((v) => v.expiry_height <= tip)) return;
- console.log(' … refreshing the funding wallet\'s expired coins first');
- sh(`${ALICE} refresh --all >/dev/null`);
- mine(3);
- sh(`${ALICE} -q balance >/dev/null`);
-};
-fundingReady();
+// funding wallet's coins — aliceReady() refreshes them on the next run.
+await aliceReady();
const receive = async (sat) => {
const before = mgr.balance().spendableSat;