Skip to content

Commit f084ffb

Browse files
x3c41aclaude
andauthored
Added live network test support for Westend bulletin chain (#216)
* Add live network test support for Westend bulletin chain - Add store_big_data_live.js for testing against live Westend/Paseo networks - Uses pre-authorized accounts (//Signer1, etc.) instead of sudo - Supports --skip-ipfs-verify for storage-only tests - Supports --fast mode for broadcast-only (no block wait) - Supports --num-signers for parallel uploads - Add ipfs-reconnect-westend-live.sh for live IPFS peer connections - Update justfile with improved live test recipes: - run-live-tests-westend/paseo with image_size parameter - setup-live-ipfs/teardown-live-ipfs for Docker kubo management - connect-live-ipfs-westend for peer connections - Auto-detects missing IPFS config and uses --skip-ipfs-verify Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add --skip-authorize and --skip-ipfs-verify flags for live network testing - Add --skip-authorize flag to skip sudo authorization (for pre-authorized accounts) - Add --skip-ipfs-verify flag to skip IPFS download verification - Update justfile live test recipes to use new flags Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 7ddacd0 commit f084ffb

File tree

2 files changed

+67
-62
lines changed

2 files changed

+67
-62
lines changed

examples/justfile

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -632,11 +632,11 @@ run-authorize-preimage-and-store-papi runtime ws_url="ws://localhost:10000" seed
632632
# ============================================================================
633633
#
634634
# Run store-big-data test against live Bulletin chain deployments.
635-
# These require pre-authorized accounts and a local Docker Kubo connected to collators.
635+
# These require pre-authorized accounts.
636636
#
637637
# Usage:
638638
# just run-live-tests-westend <seed>
639-
# just run-live-tests-paseo <seed>
639+
# just run-live-tests-westend <seed> http://127.0.0.1:8283 small
640640

641641
# Live network endpoints
642642
WESTEND_RPC := "wss://westend-bulletin-rpc.polkadot.io"
@@ -646,26 +646,19 @@ PASEO_RPC := "wss://paseo-bulletin-rpc.polkadot.io"
646646
# Parameters:
647647
# ws_url - WebSocket URL of the Bulletin chain node
648648
# seed - Account seed phrase (must be pre-authorized on the network)
649-
# http_ipfs_api - IPFS API URL (default: http://127.0.0.1:8283 for local Docker Kubo)
650-
_run-live-tests ws_url seed http_ipfs_api="http://127.0.0.1:8283": npm-install
649+
# ipfs_gateway_url - IPFS Gateway URL (default: http://127.0.0.1:8283)
650+
# image_size - Image size preset: small, big32, big64, big96 (default: small)
651+
_run-live-tests ws_url seed ipfs_gateway_url="http://127.0.0.1:8283" image_size="small": npm-install
651652
#!/usr/bin/env bash
652653
set -e
653654
echo "🌐 Running live tests against: {{ ws_url }}"
654655
just papi-generate "{{ ws_url }}"
655-
656-
# To use local Docker Kubo with external RPC:
657-
# 1. Start local IPFS: docker run -d --name ipfs-node -p 4011:4011 -p 5011:5011 -p 8283:8283 ipfs/kubo:latest
658-
# 2. Connect to Bulletin IPFS nodes: docker exec ipfs-node ipfs swarm connect <multiaddr>
659-
# (Get multiaddrs from the Bulletin chain's IPFS bootstrap list)
660-
661-
node store_big_data.js "{{ ws_url }}" "{{ seed }}" "{{ http_ipfs_api }}"
656+
node store_big_data.js "{{ ws_url }}" "{{ seed }}" "{{ ipfs_gateway_url }}" "{{ image_size }}" --skip-authorize --skip-ipfs-verify
662657

663658
# Run live tests against Westend Bulletin
664-
run-live-tests-westend seed http_ipfs_api="http://127.0.0.1:8283":
665-
just _run-live-tests "{{ WESTEND_RPC }}" "{{ seed }}" "{{ http_ipfs_api }}"
659+
run-live-tests-westend seed ipfs_gateway_url="http://127.0.0.1:8283" image_size="small":
660+
just _run-live-tests "{{ WESTEND_RPC }}" "{{ seed }}" "{{ ipfs_gateway_url }}" "{{ image_size }}"
666661

667662
# Run live tests against Paseo Bulletin
668-
run-live-tests-paseo seed http_ipfs_api="http://127.0.0.1:8283":
669-
just _run-live-tests "{{ PASEO_RPC }}" "{{ seed }}" "{{ http_ipfs_api }}"
670-
671-
# TODO: missingn PoP
663+
run-live-tests-paseo seed ipfs_gateway_url="http://127.0.0.1:8283" image_size="small":
664+
just _run-live-tests "{{ PASEO_RPC }}" "{{ seed }}" "{{ ipfs_gateway_url }}" "{{ image_size }}"

examples/store_big_data.js

Lines changed: 57 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ import { bulletin } from './.papi/descriptors/dist/index.mjs';
3030

3131
// Command line arguments: [ws_url] [seed] [ipfs_gateway_url] [image_size]
3232
// Note: --signer-disc=XX flag is also supported for parallel runs
33+
// Note: --skip-authorize flag skips account authorization (for live networks)
34+
// Note: --skip-ipfs-verify flag skips IPFS download verification
3335
const args = process.argv.slice(2).filter(arg => !arg.startsWith('--'));
3436
const NODE_WS = args[0] || 'ws://localhost:10000';
3537
const SEED = args[1] || '//Alice';
@@ -40,6 +42,11 @@ const IPFS_API_URL = IPFS_GATEWAY_URL.replace(':8283', ':5011');
4042
const IMAGE_SIZE = args[3] || 'big64';
4143
const NUM_SIGNERS = 16;
4244

45+
// Optional flags
46+
const signerDiscriminator = process.argv.find(arg => arg.startsWith("--signer-disc="))?.split("=")[1] ?? null;
47+
const SKIP_AUTHORIZE = process.argv.includes("--skip-authorize");
48+
const SKIP_IPFS_VERIFY = process.argv.includes("--skip-ipfs-verify");
49+
4350
// -------------------- queue --------------------
4451
const queue = [];
4552
function pushToQueue(data) {
@@ -238,13 +245,12 @@ export async function storeChunkedFile(api, filePath) {
238245
}
239246

240247
// Connect to IPFS API (for ipfs-http-client operations like block.get)
241-
const ipfs = create({
242-
url: IPFS_API_URL,
243-
});
244-
245-
// Optional signer discriminator, when we want to run the script in parallel and don't take care of nonces.
246-
// E.g.: node store_big_data.js --signer-disc=BB
247-
const signerDiscriminator = process.argv.find(arg => arg.startsWith("--signer-disc="))?.split("=")[1] ?? null;
248+
let ipfs = null;
249+
if (!SKIP_IPFS_VERIFY) {
250+
ipfs = create({
251+
url: IPFS_API_URL,
252+
});
253+
}
248254

249255
async function main() {
250256
await cryptoWaitReady()
@@ -263,7 +269,6 @@ async function main() {
263269
// Init WS PAPI client and typed api.
264270
client = createClient(getWsProvider(NODE_WS));
265271
const bulletinAPI = client.getTypedApi(bulletin);
266-
const { sudoSigner, _ } = setupKeyringAndSigners(SEED, '//Bigdatasigner');
267272

268273
// Let's do parallelism with multiple accounts
269274
const signers = Array.from({ length: NUM_SIGNERS }, (_, i) => {
@@ -275,15 +280,18 @@ async function main() {
275280
}
276281
});
277282

278-
// Authorize accounts.
279-
await authorizeAccount(
280-
bulletinAPI,
281-
sudoSigner,
282-
signers.map(a => a.address),
283-
100,
284-
BigInt(100 * 1024 * 1024), // 100 MiB
285-
TX_MODE_FINALIZED_BLOCK,
286-
);
283+
// Authorize accounts (skip for live networks with pre-authorized accounts)
284+
if (!SKIP_AUTHORIZE) {
285+
const { sudoSigner, _ } = setupKeyringAndSigners(SEED, '//Bigdatasigner');
286+
await authorizeAccount(
287+
bulletinAPI,
288+
sudoSigner,
289+
signers.map(a => a.address),
290+
100,
291+
BigInt(100 * 1024 * 1024), // 100 MiB
292+
TX_MODE_FINALIZED_BLOCK,
293+
);
294+
}
287295

288296
// Start 8 workers
289297
signers.forEach((signer, i) => {
@@ -319,38 +327,42 @@ async function main() {
319327
);
320328
console.log(`Downloading...${cid} / ${rootCid}`);
321329
assert.deepStrictEqual(cid, rootCid, '❌ CID mismatch between stored and computed DAG root');
322-
let downloadedContent = await fetchCid(IPFS_GATEWAY_URL, rootCid);
323-
console.log(`✅ Reconstructed file size: ${downloadedContent.length} bytes`);
324-
await fileToDisk(downloadedFileByDagPath, downloadedContent);
325-
filesAreEqual(filePath, downloadedFileByDagPath);
326-
assert.strictEqual(
327-
dataSize,
328-
downloadedContent.length,
329-
'❌ Failed to download all the data!'
330-
);
331-
332-
// Check all chunks are there.
333-
console.log(`Downloading by chunks...`);
334-
let downloadedChunks = [];
335-
for (const chunk of chunks) {
336-
// Download the chunk from IPFS.
337-
let block = await ipfs.block.get(chunk.cid, {timeout: 15000});
338-
downloadedChunks.push(block);
339-
}
340-
let fullBuffer = Buffer.concat(downloadedChunks);
341-
console.log(`✅ Reconstructed file size: ${fullBuffer.length} bytes`);
342-
await fileToDisk(downloadedFilePath, fullBuffer);
343-
filesAreEqual(filePath, downloadedFilePath);
344-
assert.strictEqual(
345-
dataSize,
346-
fullBuffer.length,
347-
'❌ Failed to download all the data!'
348-
);
349330

350331
// Print storage statistics
351332
await printStatistics(dataSize, bulletinAPI);
352333

353-
logTestResult(true, 'Store Big Data Test');
334+
// IPFS verification (skip with --skip-ipfs-verify)
335+
if (!SKIP_IPFS_VERIFY) {
336+
let downloadedContent = await fetchCid(IPFS_GATEWAY_URL, rootCid);
337+
console.log(`✅ Reconstructed file size: ${downloadedContent.length} bytes`);
338+
await fileToDisk(downloadedFileByDagPath, downloadedContent);
339+
filesAreEqual(filePath, downloadedFileByDagPath);
340+
assert.strictEqual(
341+
dataSize,
342+
downloadedContent.length,
343+
'❌ Failed to download all the data!'
344+
);
345+
346+
// Check all chunks are there.
347+
console.log(`Downloading by chunks...`);
348+
let downloadedChunks = [];
349+
for (const chunk of chunks) {
350+
// Download the chunk from IPFS.
351+
let block = await ipfs.block.get(chunk.cid, {timeout: 15000});
352+
downloadedChunks.push(block);
353+
}
354+
let fullBuffer = Buffer.concat(downloadedChunks);
355+
console.log(`✅ Reconstructed file size: ${fullBuffer.length} bytes`);
356+
await fileToDisk(downloadedFilePath, fullBuffer);
357+
filesAreEqual(filePath, downloadedFilePath);
358+
assert.strictEqual(
359+
dataSize,
360+
fullBuffer.length,
361+
'❌ Failed to download all the data!'
362+
);
363+
}
364+
365+
logTestResult(true, SKIP_IPFS_VERIFY ? 'Store Big Data Test (Storage Only)' : 'Store Big Data Test');
354366
resultCode = 0;
355367
} catch (error) {
356368
logError(`Error: ${error.message}`);

0 commit comments

Comments
 (0)