Add SV2 DATUM payout hardening

This commit is contained in:
Ben
2026-06-12 23:54:50 -04:00
parent bcd6bb0aa7
commit a33c530268
59 changed files with 7852 additions and 81 deletions
+86 -10
View File
@@ -1,6 +1,7 @@
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import * as bitcoinjs from 'bitcoinjs-lib';
import { DataSource, IsNull, Repository } from 'typeorm';
import { BlocksEntity } from './blocks.entity';
@@ -19,31 +20,106 @@ export class BlocksService {
public async save(block: Partial<BlocksEntity>) {
await this.blocksRepository.save(block);
const blockHash = block.blockHash ?? this.getBlockHash(block.blockData);
const existing = blockHash == null
? null
: await this.blocksRepository.findOne({
select: { id: true, blockSubmissionResult: true, payoutSnapshotId: true },
where: { blockHash },
});
if (existing != null) {
if (this.isSuccessfulBlockSubmission(block.blockSubmissionResult)) {
await this.blocksRepository.update(existing.id, {
blockSubmissionResult: 'SUCCESS!',
payoutSnapshotId: block.payoutSnapshotId ?? existing.payoutSnapshotId,
});
}
return;
}
await this.blocksRepository.save({
...block,
blockHash,
});
}
public async getFoundBlocks() {
return await this.blocksRepository.find({
const rows = await this.blocksRepository.find({
select: {
height: true,
minerAddress: true,
worker: true,
sessionId: true
}
sessionId: true,
blockHash: true,
blockSubmissionResult: true,
createdAt: true,
},
where: [
{ blockSubmissionResult: 'SUCCESS!' },
{ blockSubmissionResult: IsNull() },
],
order: {
height: 'DESC',
createdAt: 'DESC',
},
});
return this.uniqueFoundBlocks(rows);
}
public async getFoundBlocksByAddress(address: string) {
return await this.blocksRepository.find({
const rows = await this.blocksRepository.find({
select: {
height: true,
minerAddress: true,
worker: true,
sessionId: true
sessionId: true,
blockHash: true,
blockSubmissionResult: true,
createdAt: true,
},
where: {
minerAddress: address
where: [
{ minerAddress: address, blockSubmissionResult: 'SUCCESS!' },
{ minerAddress: address, blockSubmissionResult: IsNull() },
],
order: {
height: 'DESC',
createdAt: 'DESC',
},
});
return this.uniqueFoundBlocks(rows);
}
private uniqueFoundBlocks(rows: Partial<BlocksEntity>[]): Partial<BlocksEntity>[] {
const seenBlocks = new Set<string>();
const seenHeights = new Set<number>();
return rows.filter(row => {
if (row.height != null && seenHeights.has(row.height)) {
return false;
}
const key = row.blockHash || `height:${row.height}`;
if (seenBlocks.has(key)) {
return false;
}
seenBlocks.add(key);
if (row.height != null) {
seenHeights.add(row.height);
}
return true;
});
}
}
private getBlockHash(blockData?: string): string | undefined {
if (blockData == null || blockData.length < 160) {
return undefined;
}
try {
return bitcoinjs.Block.fromHex(blockData).getId();
} catch {
return undefined;
}
}
private isSuccessfulBlockSubmission(result?: string | null): boolean {
return result == null || result === 'SUCCESS!';
}
}