dgb-wallet/packages/p2p/scripts/cache-demo.ts
Digibyte.X d50286a9a5 DigiByte.X Wallet — recovery-first web wallet monorepo
Packages: core (BIP39/32/44/49/84/86 derivation, WIF), keystore (PBKDF2 +
AES-GCM), psbt, p2p (BIP157/158 SPV daemon, Dandelion++ broadcast with
relay-echo verification), blockbook, rpc, electrum, net, bns, web-ui
(React/Vite), mobile (Expo). ops/ holds the nginx vhost, systemd unit and
push.sh deploy script for digibyte.x/web.
2026-09-20 20:16:52 +02:00

87 lines
3.1 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Milestone A6 demo — persistent, disk-backed header chain.
// Run once: downloads N headers from network, writes them to disk as
// they arrive. Run again: adopts the tip from disk in milliseconds
// and resumes from there.
//
// Usage:
// npm run cache -w @dgb-wallet/p2p [target_height] [cache_dir]
import { rm } from 'node:fs/promises';
import {
PeerPool,
HeaderChain,
encodeGetHeaders,
defaultCacheDir,
type BlockHeader,
} from '../src/index.js';
const DGB_GENESIS_HASH = '7497ea1b465eb39f1c8f507bc877078fe016d6fcb6dfad3a64c98dcc6e1e8496';
const args = process.argv.slice(2).filter((a) => !a.startsWith('--'));
const TARGET = Number(args[0]) || 80_000;
const CACHE_DIR = args[1] || defaultCacheDir();
const CLEAR = process.argv.includes('--clear');
console.log('\n=== DigiByte Header Cache Demo (A6, disk-backed) ===\n');
console.log(`Cache dir: ${CACHE_DIR}`);
console.log(`Target: ${TARGET.toLocaleString()} headers`);
if (CLEAR) console.log('Flag --clear given → wiping cache first');
console.log();
if (CLEAR) {
await rm(CACHE_DIR, { recursive: true, force: true });
}
const t0 = Date.now();
const chain = new HeaderChain({ dir: CACHE_DIR });
chain.appendGenesis({
hash: DGB_GENESIS_HASH, prevBlock: '00'.repeat(32), merkleRoot: '',
version: 0, timestamp: 0, bits: 0, nonce: 0, raw: Buffer.alloc(80),
}, 0);
const startTip = chain.tipHeight;
const openMs = Date.now() - t0;
console.log(`[chain] opened in ${openMs}ms — tip=${startTip.toLocaleString()} (adopted from disk)`);
if (chain.tipHeight >= TARGET) {
console.log(`\nAlready at or past target height ${TARGET.toLocaleString()}. Nothing to sync.`);
console.log(`Elapsed: ${(Date.now() - t0)}ms (this launch is entirely disk-served)`);
chain.close();
process.exit(0);
}
console.log(`\nSyncing headers from ${chain.tipHeight.toLocaleString()} to ${TARGET.toLocaleString()}...`);
const pool = new PeerPool({ poolSize: 3, peerOpts: { handshakeTimeoutMs: 10_000 } });
let peer: ReturnType<typeof pool.pickReady>[number] | null = null;
const netStart = Date.now();
pool.on('connect', () => {
if (peer) return;
peer = pool.pickReady()[0];
if (!peer) return;
console.log(` peer: ${peer.host}:${peer.port}`);
peer.on('headers', (headers: BlockHeader[]) => {
chain.append(headers); // writes straight to disk, batched per call
process.stdout.write(`\r height: ${chain.tipHeight.toLocaleString()} `);
if (chain.tipHeight >= TARGET) {
const netMs = Date.now() - netStart;
const added = chain.tipHeight - startTip;
console.log(`\n\n network sync: ${netMs}ms for ${added.toLocaleString()} new headers`);
console.log(` disk usage: ${(chain.tipHeight * 80 / 1024 / 1024).toFixed(1)} MiB (80 bytes × ${chain.tipHeight.toLocaleString()} headers)`);
chain.close();
pool.stop();
process.exit(0);
} else if (headers.length >= 2000) {
peer!.send('getheaders', encodeGetHeaders(70019, chain.buildLocator()));
}
});
peer.send('getheaders', encodeGetHeaders(70019, chain.buildLocator()));
});
setTimeout(() => {
console.error('\ntimed out before reaching target');
chain.close();
pool.stop();
process.exit(1);
}, 120_000);