rwadurian/backend/services/mining-service/prisma/seed.ts

192 lines
6.2 KiB
TypeScript
Raw 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.

import { PrismaClient } from '@prisma/client';
import Decimal from 'decimal.js';
const prisma = new PrismaClient();
/**
* Mining Service 数据库初始化
*
* 根据需求文档:
* - 积分股共 100.02 亿
* - 其中 100 亿通过 4 年时间销毁至 0 (实际是10年每年销毁10亿)
* - 其中 200 万原始积分股作为全网贡献值分配
* - 第一个两年分配 100 万积分股给全网
* - 第二个两年分配 50 万积分股给全网
* - 以此类推(减半机制)
*/
async function main() {
console.log('Starting mining-service seed...');
// ============================================================
// 1. 初始化挖矿配置 (MiningConfig)
// ============================================================
const existingConfig = await prisma.miningConfig.findFirst();
if (!existingConfig) {
// 总积分股: 100.02B (100,020,000,000)
const totalShares = new Decimal('100020000000');
// 分配池: 200M (200,000,000) - 用于挖矿分配
// 注意需求说200万但这里使用200万作为分配池
const distributionPool = new Decimal('2000000'); // 200万
// 第一纪元分配量: 100万 (第一个两年)
const era1Distribution = new Decimal('1000000');
// 每分钟分配量 = 100万 / (2年 * 365天 * 24小时 * 60分钟)
// = 1,000,000 / 1,051,200 = 0.95129375951...
const minutesIn2Years = 2 * 365 * 24 * 60; // 1,051,200 分钟
const minuteDistribution = era1Distribution.dividedBy(minutesIn2Years);
await prisma.miningConfig.create({
data: {
totalShares: totalShares,
distributionPool: distributionPool,
remainingDistribution: era1Distribution, // 第一纪元剩余分配量
halvingPeriodYears: 2,
currentEra: 1,
eraStartDate: new Date(), // 从现在开始
minuteDistribution: minuteDistribution,
isActive: false, // 需要手动激活
activatedAt: null,
},
});
console.log('✅ MiningConfig created:');
console.log(` - Total Shares: ${totalShares.toFixed(0)}`);
console.log(` - Distribution Pool: ${distributionPool.toFixed(0)}`);
console.log(` - Era 1 Distribution: ${era1Distribution.toFixed(0)}`);
console.log(` - Minute Distribution: ${minuteDistribution.toFixed(18)}`);
} else {
console.log('⏭️ MiningConfig already exists, skipping...');
}
// ============================================================
// 2. 初始化黑洞账户 (BlackHole)
// ============================================================
const existingBlackHole = await prisma.blackHole.findFirst();
if (!existingBlackHole) {
// 目标销毁量: 100亿 (100,000,000,000)
// 注意需求说100亿通过4年销毁但实际设计是10年
const targetBurn = new Decimal('10000000000'); // 100亿
await prisma.blackHole.create({
data: {
totalBurned: 0,
targetBurn: targetBurn,
remainingBurn: targetBurn,
lastBurnMinute: null,
},
});
console.log('✅ BlackHole created:');
console.log(` - Target Burn: ${targetBurn.toFixed(0)}`);
} else {
console.log('⏭️ BlackHole already exists, skipping...');
}
// ============================================================
// 3. 初始化第一纪元记录 (MiningEra)
// ============================================================
const existingEra = await prisma.miningEra.findUnique({
where: { eraNumber: 1 },
});
if (!existingEra) {
const era1Distribution = new Decimal('1000000');
const minutesIn2Years = 2 * 365 * 24 * 60;
const minuteDistribution = era1Distribution.dividedBy(minutesIn2Years);
await prisma.miningEra.create({
data: {
eraNumber: 1,
startDate: new Date(),
endDate: null,
initialDistribution: era1Distribution,
totalDistributed: 0,
minuteDistribution: minuteDistribution,
isActive: true,
},
});
console.log('✅ MiningEra 1 created');
} else {
console.log('⏭️ MiningEra 1 already exists, skipping...');
}
// ============================================================
// 4. 初始化池账户 (PoolAccount)
// ============================================================
const poolTypes = [
{
poolType: 'SHARE_POOL',
name: '积分股池',
balance: new Decimal('100020000000'), // 100.02B 初始
description: '总积分股池,认种产生的绿积分注入此池',
},
{
poolType: 'BLACK_HOLE_POOL',
name: '黑洞积分股池',
balance: new Decimal('0'),
description: '销毁池,积分股销毁后进入此池',
},
{
poolType: 'CIRCULATION_POOL',
name: '流通积分股池',
balance: new Decimal('0'),
description: '流通池,用户卖出的积分股进入此池',
},
];
for (const pool of poolTypes) {
const existing = await prisma.poolAccount.findUnique({
where: { poolType: pool.poolType as any },
});
if (!existing) {
await prisma.poolAccount.create({
data: {
poolType: pool.poolType as any,
name: pool.name,
balance: pool.balance,
totalInflow: pool.balance,
totalOutflow: 0,
isActive: true,
description: pool.description,
},
});
console.log(`✅ PoolAccount ${pool.poolType} created`);
} else {
console.log(`⏭️ PoolAccount ${pool.poolType} already exists, skipping...`);
}
}
console.log('\n🎉 Mining-service seed completed!');
// 输出当前状态
console.log('\n📊 Current Status:');
const config = await prisma.miningConfig.findFirst();
const blackHole = await prisma.blackHole.findFirst();
const pools = await prisma.poolAccount.findMany();
if (config) {
console.log(` Mining Active: ${config.isActive}`);
console.log(` Remaining Distribution: ${config.remainingDistribution}`);
}
if (blackHole) {
console.log(` Total Burned: ${blackHole.totalBurned}`);
console.log(` Remaining Burn: ${blackHole.remainingBurn}`);
}
console.log(` Pool Accounts: ${pools.length}`);
}
main()
.catch((e) => {
console.error('❌ Seed failed:', e);
process.exit(1);
})
.finally(async () => {
await prisma.$disconnect();
});