Reduce DATUM false rejects and filter miner report

This commit is contained in:
Ben
2026-06-21 10:27:58 -04:00
parent d5c5a90aa6
commit 6dcbb8436d
8 changed files with 227 additions and 6 deletions
+53 -3
View File
@@ -296,12 +296,16 @@ export class DatumService implements OnModuleInit {
await this.sendShareResponse(socket, state, DatumShareResponseStatus.REJECTED, DatumRejectReason.OTHER, pow.nonce, pow.targetByte, pow.jobId);
return;
}
const payoutValidation = this.validateDatumCoinbasePayouts(coinbase, pow, latestTemplate, datumJob.coinbaseValue, datumJob.expectedPayoutOutputs, state.payoutMode);
if (!payoutValidation.valid) {
this.logDatumCoinbaseMismatchOnce(state, payoutValidation);
const payoutValidation = this.validateDatumCoinbasePayoutContext(coinbase, pow, latestTemplate, datumJob, state);
if (!payoutValidation.validation.valid) {
this.logDatumCoinbaseMismatchOnce(state, payoutValidation.validation);
await this.sendShareResponse(socket, state, DatumShareResponseStatus.REJECTED, DatumRejectReason.BAD_COINBASER_ID, pow.nonce, pow.targetByte, pow.jobId);
return;
}
if (payoutValidation.context != null) {
datumJob.expectedPayoutOutputs = payoutValidation.context.payoutOutputs;
datumJob.payoutSnapshotId = payoutValidation.context.payoutSnapshotId;
}
const shareDifficulty = this.getDatumSubmittedShareDifficulty(pow);
const nBits = datumJob.nBits.readUInt32LE(0);
@@ -623,6 +627,52 @@ export class DatumService implements OnModuleInit {
};
}
private validateDatumCoinbasePayoutContext(
coinbase: { coinb1: Buffer; coinb2: Buffer },
pow: DatumPowSubmit,
latestTemplate: IJobTemplate,
datumJob: DatumJobCache,
state: DatumClientState,
): { validation: DatumCoinbasePayoutValidation; context?: DatumCoinbaserPayoutContext } {
const primaryValidation = this.validateDatumCoinbasePayouts(
coinbase,
pow,
latestTemplate,
datumJob.coinbaseValue,
datumJob.expectedPayoutOutputs,
state.payoutMode,
);
if (primaryValidation.valid) {
return { validation: primaryValidation };
}
for (const context of state.coinbaserPayoutContexts.values()) {
if (context.payoutMode != null && context.payoutMode !== state.payoutMode) {
continue;
}
if (context.blockHeight != null && datumJob.height != null && context.blockHeight !== datumJob.height) {
continue;
}
if (context.payoutOutputs === datumJob.expectedPayoutOutputs) {
continue;
}
const validation = this.validateDatumCoinbasePayouts(
coinbase,
pow,
latestTemplate,
datumJob.coinbaseValue,
context.payoutOutputs,
state.payoutMode,
);
if (validation.valid) {
return { validation, context };
}
}
return { validation: primaryValidation };
}
private getDatumPayoutOutputs(latestTemplate: { blockData?: { payoutOutputs?: AddressObject[] } }, rewardValue: number, payoutMode: PayoutMode = 'solo'): DatumPayoutOutput[] {
const configuredOutputs = latestTemplate?.blockData?.payoutOutputs;
const payoutAddresses = payoutMode === 'pplns' && configuredOutputs?.length > 0