UNPKG

@covenance/dlc

Version:

Crypto and Bitcoin functions for Covenance DLC implementation

152 lines (126 loc) 5.46 kB
import { Address, PrivateKey, Script, Networks } from '../src/btc'; import { createLiquidationCets, createDlcInitTx, createMaturityCets } from '../src/cet/transactions'; import { OracleEvent, LoanConfig } from '../src/cet/types'; import { Point, utils } from '../src/crypto/secp256k1'; const createLiquidationEvents = async ( config: LoanConfig, startTime: number = (Date.now() / 1000) | 0, ): Promise<OracleEvent[]> => { const count = Math.floor(60 * 60 * 24 * 90 / 60 / 10); const events = new Array<OracleEvent>(count); const mockSignaturePoints = Array.from({ length: count }, () => Point.fromPrivateKey(utils.randomPrivateKey())); // Log progress every 10% of events const progressInterval = Math.max(1, Math.floor(count / 10)); let lastLogged = 0; for (let i = 0; i < count; i++) { events[i] = { id: `event${i}`, timestamp: startTime + i * 60 * 10, outcomeSignaturePoints: mockSignaturePoints, outcomePrices: Array.from({ length: 100 * 10 }, (_, j) => 50000 + j * 100), }; // Log progress periodically if (i - lastLogged >= progressInterval) { const percent = Math.floor((i / count) * 100); console.log(` ${i}/${count} events created (${percent}%)`); lastLogged = i; } } return events; }; async function runBenchmark(): Promise<void> { console.log('\n--- Starting loan setup ---'); // ---------- KEYSETUP ---------- console.log('• Setting up keys...'); const borrowerKey = new PrivateKey(); const lenderKey = new PrivateKey(); const borrowerAddress = new Address(borrowerKey.toPublicKey(), Networks.testnet, 'witnesspubkeyhash'); const lenderAddress = new Address(lenderKey.toPublicKey(), Networks.testnet, 'witnesspubkeyhash'); // ---------- LOAN CONFIG ---------- console.log('• Configuring loan parameters...'); const borrowedAmountUsd = 15_000; // $15k const liquidationThreshold = 0.8; const annualInterestRate = 0.1; const initialBtcPrice = 100_000; // $100k/BTC const collateralAmount = (borrowedAmountUsd / initialBtcPrice) * 2; // 200% collateralisation const config: LoanConfig = { collateralAmount, annualInterestRate, liquidationThreshold, borrowedAmount: borrowedAmountUsd, penaltyPercentage: 0.1 }; // ---------- UTXO & DLC INIT ---------- console.log('• Creating DLC initialization transaction...'); const inputAmount = collateralAmount * 2; const collateralUtxos = [{ txId: 'a'.repeat(64), outputIndex: 0, satoshis: inputAmount * 100_000_000, script: (Script as any).buildWitnessV0Out(borrowerAddress), }]; const borrowerDlcPrivateKey = utils.randomPrivateKey(); const borrowerDlcPubKey = Point.fromPrivateKey(borrowerDlcPrivateKey); const lenderDlcPrivateKey = utils.randomPrivateKey(); const lenderDlcPubKey = Point.fromPrivateKey(lenderDlcPrivateKey); const dlcInitTx = createDlcInitTx( collateralUtxos, collateralAmount * 100_000_000, borrowerDlcPubKey, lenderDlcPubKey, borrowerAddress, ); const dlcUtxo = dlcInitTx.dlcUtxo; // ---------- ORACLE EVENTS ---------- console.log('\n--- Creating liquidation events ---'); const expectedEvents = Math.floor(60 * 60 * 24 * 90 / 60 / 10); console.log(`• Will create ${expectedEvents} liquidation events (${60 * 60 * 24 * 90 / 86400} days × ${60 * 10} min intervals)`); const liquidationEvents = await createLiquidationEvents(config); console.log('✓ Liquidation events created'); console.log('• Creating maturity event...'); const maturityEvent: OracleEvent = { id: 'maturity-event', timestamp: Date.now(), outcomeSignaturePoints: Array.from({ length: 100 * 10 }, () => Point.fromPrivateKey(utils.randomPrivateKey())), outcomePrices: Array.from({ length: 100 * 10 }, (_, j) => 50000 + j * 100), }; // ---------- BENCHMARK ---------- console.log(`\n--- CET creation benchmark ---`); console.log(`Liquidation events: ${liquidationEvents.length}`); const t0 = process.hrtime(); const liquidationCets = createLiquidationCets( liquidationEvents, config, dlcUtxo, borrowerAddress, lenderAddress, ); const t1 = process.hrtime(); const maturityCets = createMaturityCets( maturityEvent, liquidationEvents[0].timestamp, config, dlcUtxo, borrowerAddress, lenderAddress, ); const t2 = process.hrtime(); // ---------- STATISTICS ---------- const nLiquidation = liquidationCets.length; const nMaturity = maturityCets.length; const TOTAL_CETS = nLiquidation + nMaturity; const hrtimeToNs = (t: [number, number]): number => t[0] * 1e9 + t[1]; const nsLiquidation = hrtimeToNs(t1) - hrtimeToNs(t0); const nsMaturity = hrtimeToNs(t2) - hrtimeToNs(t1); const nsTotal = hrtimeToNs(t2) - hrtimeToNs(t0); const fmt = (ns: number): string => `${ns.toFixed(0)}ns`; const fmtRate = (count: number, ns: number): string => (count / (ns / 1e9)).toFixed(3); console.log(`\nResults:`); console.log(` • Liquidation CETs: ${nLiquidation} in ${fmt(nsLiquidation)}${fmtRate(nLiquidation, nsLiquidation)} CET/s`); console.log(` • Maturity CETs: ${nMaturity} in ${fmt(nsMaturity)}${fmtRate(nMaturity, nsMaturity)} CET/s`); console.log(`\nTotal: ${TOTAL_CETS} CETs in ${fmt(nsTotal)}${fmtRate(TOTAL_CETS, nsTotal)} CET/s\n`); } runBenchmark().catch((err) => { console.error('Benchmark failed:', err); process.exit(1); });