fix(pool-account): 修复 seed.ts 覆盖池余额 + 激活挖矿前校验池余额
1. seed.ts upsert 的 update 子句移除 balance/targetBurn/remainingBurn, 避免重新部署时将已有池余额清零(导致 BurnConsumer 和 MiningDistributionConsumer 因余额不足崩溃) 2. activateMining 激活前检查 SHARE_POOL_A/B 余额,任一为0则阻止激活 并返回 400 错误提示先通过区块链充值 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
4f5b18be48
commit
46f85b13b0
|
|
@ -152,6 +152,32 @@ export class ConfigController {
|
|||
@ApiOperation({ summary: '激活挖矿' })
|
||||
async activateMining(@Req() req: any) {
|
||||
const miningServiceUrl = this.appConfigService.get<string>('MINING_SERVICE_URL', 'http://localhost:3021');
|
||||
const walletServiceUrl = this.appConfigService.get<string>('MINING_WALLET_SERVICE_URL', 'http://localhost:3025');
|
||||
|
||||
// 安全检查:池账户余额不能为0
|
||||
try {
|
||||
const [poolARes, poolBRes] = await Promise.all([
|
||||
fetch(`${walletServiceUrl}/api/v2/pool-accounts/SHARE_POOL_A`),
|
||||
fetch(`${walletServiceUrl}/api/v2/pool-accounts/SHARE_POOL_B`),
|
||||
]);
|
||||
if (poolARes.ok && poolBRes.ok) {
|
||||
const poolA = await poolARes.json();
|
||||
const poolB = await poolBRes.json();
|
||||
const balA = parseFloat(poolA?.data?.balance ?? poolA?.balance ?? '0');
|
||||
const balB = parseFloat(poolB?.data?.balance ?? poolB?.balance ?? '0');
|
||||
if (balA <= 0 || balB <= 0) {
|
||||
const msg = `池账户余额不足,无法激活挖矿。积分股池A余额: ${balA},积分股池B余额: ${balB}。请先通过区块链充值。`;
|
||||
this.logger.warn(msg);
|
||||
throw new BadRequestException(msg);
|
||||
}
|
||||
} else {
|
||||
this.logger.warn('无法获取池账户余额,跳过安全检查');
|
||||
}
|
||||
} catch (error) {
|
||||
if (error instanceof BadRequestException) throw error;
|
||||
this.logger.warn('池账户余额检查失败,跳过安全检查', error);
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await fetch(`${miningServiceUrl}/api/v2/mining/admin/activate`, {
|
||||
method: 'POST',
|
||||
|
|
@ -163,6 +189,7 @@ export class ConfigController {
|
|||
this.logger.log(`Mining activated by admin ${req.admin?.id}`);
|
||||
return result;
|
||||
} catch (error) {
|
||||
if (error instanceof BadRequestException) throw error;
|
||||
this.logger.error('Failed to activate mining', error);
|
||||
return { success: false, message: 'Failed to activate mining' };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ async function main() {
|
|||
// 积分股池A: 100亿 (10,000,000,000) - 用于销毁
|
||||
// 积分股池B: 200万 (2,000,000) - 用于挖矿分配
|
||||
// 总计: 100.02亿 (10,002,000,000)
|
||||
// 直接 upsert 覆盖,不检查是否存在
|
||||
// upsert: 已存在时只更新元数据(name/description),不覆盖余额等运营数据
|
||||
const poolAccounts = [
|
||||
{
|
||||
poolType: 'SHARE_POOL_A',
|
||||
|
|
@ -99,10 +99,8 @@ async function main() {
|
|||
const created = await prisma.poolAccount.upsert({
|
||||
where: { poolType: pool.poolType as any },
|
||||
update: {
|
||||
// 仅更新元数据,绝不覆盖 balance/targetBurn/remainingBurn
|
||||
name: pool.name,
|
||||
balance: pool.balance,
|
||||
targetBurn: pool.targetBurn,
|
||||
remainingBurn: pool.targetBurn,
|
||||
description: pool.description,
|
||||
isActive: true,
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in New Issue