UNPKG

filecoin-pin

Version:

Bridge IPFS content to Filecoin Onchain Cloud using familiar tools

117 lines 6.23 kB
import { SIZE_CONSTANTS, TIME_CONSTANTS } from '@filoz/synapse-sdk'; import { describe, expect, it } from 'vitest'; import { applyFloorPricing, BUFFER_DENOMINATOR, BUFFER_NUMERATOR, calculatePieceUploadRequirements, calculateRequiredAllowances, computeAdjustmentForExactDaysWithPiece, DEFAULT_LOCKUP_DAYS, getFloorAllowances, } from '../../core/payments/index.js'; function makeStatus(params) { const currentAllowances = { rateAllowance: 0n, lockupAllowance: 0n, lockupUsed: params.lockupUsed ?? 0n, rateUsed: params.rateUsed ?? 0n, maxLockupPeriod: BigInt(DEFAULT_LOCKUP_DAYS) * TIME_CONSTANTS.EPOCHS_PER_DAY, }; return { network: 'calibration', address: '0x0000000000000000000000000000000000000000', filBalance: 0n, walletUsdfcBalance: 0n, filecoinPayBalance: params.filecoinPayBalance, currentAllowances, }; } function getBufferedFloorDeposit() { const floor = getFloorAllowances(); return (floor.lockupAllowance * BUFFER_NUMERATOR) / BUFFER_DENOMINATOR; } describe('applyFloorPricing', () => { const mockPricing = 100000000000000n; // Some arbitrary price per TiB per epoch const smallCases = [ { label: 'tiny file (1 byte)', size: 1 }, { label: 'small file (1 KB)', size: 1024 }, { label: 'medium file (1 MB)', size: 1024 * 1024 }, ]; for (const { label, size } of smallCases) { it(`applies floor pricing to ${label}`, () => { const baseAllowances = calculateRequiredAllowances(size, mockPricing); const floorAdjusted = applyFloorPricing(baseAllowances); const floor = getFloorAllowances(); expect(floorAdjusted.rateAllowance).toBe(floor.rateAllowance); expect(floorAdjusted.lockupAllowance).toBe(floor.lockupAllowance); }); } it('does not apply floor for large file when base cost exceeds floor', () => { // Use a very high price to ensure base cost exceeds floor const highPrice = 1000000000000000000n; // 1 USDFC per TiB per epoch const largeFile = Number(SIZE_CONSTANTS.GiB) * 100; // 100 GiB const baseAllowances = calculateRequiredAllowances(largeFile, highPrice); const floorAdjusted = applyFloorPricing(baseAllowances); const floor = getFloorAllowances(); // Base cost should exceed floor, so base is returned expect(floorAdjusted.rateAllowance).toBeGreaterThan(floor.rateAllowance); expect(floorAdjusted.lockupAllowance).toBeGreaterThan(floor.lockupAllowance); expect(floorAdjusted.rateAllowance).toBe(baseAllowances.rateAllowance); }); }); describe('calculatePieceUploadRequirements - Floor Pricing Integration', () => { const mockPricing = 100000000000000n; const floorSizes = [ { label: '0-byte file', size: 0 }, { label: '1 KB file', size: 1024 }, ]; for (const { label, size } of floorSizes) { it(`enforces floor price for ${label}`, () => { const status = makeStatus({ filecoinPayBalance: 0n }); const requirements = calculatePieceUploadRequirements(status, size, mockPricing); const floor = getFloorAllowances(); expect(requirements.required.rateAllowance).toBe(floor.rateAllowance); expect(requirements.required.lockupAllowance).toBe(floor.lockupAllowance); }); } it('requires deposit with 10% buffer applied', () => { const status = makeStatus({ filecoinPayBalance: 0n }); const requirements = calculatePieceUploadRequirements(status, 0, mockPricing); const bufferedFloor = getBufferedFloorDeposit(); expect(requirements.totalDepositNeeded).toBe(bufferedFloor); // User needs to deposit the buffered amount expect(requirements.insufficientDeposit).toBe(bufferedFloor); expect(requirements.canUpload).toBe(false); }); it('allows upload when deposit meets buffered floor price', () => { const bufferedFloor = getBufferedFloorDeposit(); const status = makeStatus({ filecoinPayBalance: bufferedFloor }); const requirements = calculatePieceUploadRequirements(status, 0, mockPricing); expect(requirements.canUpload).toBe(true); expect(requirements.insufficientDeposit).toBe(0n); }); it('blocks upload when deposit is below buffered floor price', () => { const bufferedFloor = getBufferedFloorDeposit(); const slightlyLess = bufferedFloor - 1n; const status = makeStatus({ filecoinPayBalance: slightlyLess }); const requirements = calculatePieceUploadRequirements(status, 0, mockPricing); expect(requirements.canUpload).toBe(false); expect(requirements.insufficientDeposit).toBe(1n); }); }); describe('computeAdjustmentForExactDaysWithPiece - Floor Pricing Integration', () => { const mockPricing = 100000000000000n; it('applies floor pricing for small file in auto-fund calculation', () => { const status = makeStatus({ filecoinPayBalance: 0n, lockupUsed: 0n, rateUsed: 0n }); const adjustment = computeAdjustmentForExactDaysWithPiece(status, 30, 1024, mockPricing); const floor = getFloorAllowances(); // Should use floor-adjusted allowances expect(adjustment.newRateUsed).toBe(floor.rateAllowance); expect(adjustment.newLockupUsed).toBe(floor.lockupAllowance); }); it('calculates correct deposit delta with floor pricing', () => { const status = makeStatus({ filecoinPayBalance: 0n, lockupUsed: 0n, rateUsed: 0n }); const adjustment = computeAdjustmentForExactDaysWithPiece(status, 30, 0, mockPricing); const floor = getFloorAllowances(); // Target deposit = buffered lockup + runway const bufferedLockup = getBufferedFloorDeposit(); const perDay = floor.rateAllowance * TIME_CONSTANTS.EPOCHS_PER_DAY; const safety = perDay > 0n ? perDay / 24n : 1n; const runwayCost = 30n * perDay + safety; expect(adjustment.delta).toBeGreaterThan(0n); expect(adjustment.targetDeposit).toBe(bufferedLockup + runwayCost); }); }); //# sourceMappingURL=floor-pricing.test.js.map