Skip to content

Commit 4012327

Browse files
committed
Merge branch 'type-1-ftso-fix' into 'main'
type 1 rewarding fix See merge request flarenetwork/ftso/ftso-scaling!156
2 parents 75180bd + a17f92c commit 4012327

File tree

6 files changed

+461
-419
lines changed

6 files changed

+461
-419
lines changed

libs/fsp-rewards/src/DataManagerForRewarding.ts

Lines changed: 75 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,7 @@ import {
99
} from "../../ftso-core/src/IndexerClient";
1010
import { RewardEpoch } from "../../ftso-core/src/RewardEpoch";
1111
import { RewardEpochManager } from "../../ftso-core/src/RewardEpochManager";
12-
import {
13-
EPOCH_SETTINGS,
14-
FTSO2_PROTOCOL_ID,
15-
} from "../../ftso-core/src/constants";
12+
import { EPOCH_SETTINGS, FTSO2_PROTOCOL_ID } from "../../ftso-core/src/constants";
1613
import { DataForCalculations } from "../../ftso-core/src/data/DataForCalculations";
1714
import { ECDSASignature } from "../../ftso-core/src/fsp-utils/ECDSASignature";
1815
import { ProtocolMessageMerkleRoot } from "../../ftso-core/src/fsp-utils/ProtocolMessageMerkleRoot";
@@ -23,7 +20,11 @@ import { ILogger } from "../../ftso-core/src/utils/ILogger";
2320
import { errorString } from "../../ftso-core/src/utils/error";
2421
import { Address, MessageHash } from "../../ftso-core/src/voting-types";
2522
import { IndexerClientForRewarding } from "./IndexerClientForRewarding";
26-
import { ADDITIONAL_REWARDED_FINALIZATION_WINDOWS, FDC_PROTOCOL_ID, WRONG_SIGNATURE_INDICATOR_MESSAGE_HASH } from "./constants";
23+
import {
24+
ADDITIONAL_REWARDED_FINALIZATION_WINDOWS,
25+
FDC_PROTOCOL_ID,
26+
WRONG_SIGNATURE_INDICATOR_MESSAGE_HASH,
27+
} from "./constants";
2728
import {
2829
DataForRewardCalculation,
2930
FDCDataForVotingRound,
@@ -112,7 +113,6 @@ export class DataManagerForRewarding extends DataManager {
112113
};
113114
}
114115

115-
116116
/**
117117
* Prepare data for median calculation and rewarding given the voting round id and the random generation benching window.
118118
* - queries relevant commits and reveals from chain indexer database
@@ -198,13 +198,16 @@ export class DataManagerForRewarding extends DataManager {
198198
this.logger.debug(`Valid reveals from: ${JSON.stringify(Array.from(partialData.validEligibleReveals.keys()))}`);
199199
}
200200
//////// FDC ////////
201-
const validEligibleBitVotes: SubmissionData[] = this.extractSubmissionsWithValidEligibleBitVotes(reveals, rewardEpoch);
201+
const validEligibleBitVotes: SubmissionData[] = this.extractSubmissionsWithValidEligibleBitVotes(
202+
reveals,
203+
rewardEpoch
204+
);
202205
const dataForRound = {
203206
...partialData,
204207
randomGenerationBenchingWindow,
205208
benchingWindowRevealOffenders,
206209
rewardEpoch,
207-
validEligibleBitVoteSubmissions: validEligibleBitVotes
210+
validEligibleBitVoteSubmissions: validEligibleBitVotes,
208211
} as DataForCalculations;
209212
result.push(dataForRound);
210213
}
@@ -214,22 +217,20 @@ export class DataManagerForRewarding extends DataManager {
214217
};
215218
}
216219

217-
218-
219220
/**
220-
* Extract signature payloads for the given voting round id from the given submissions.
221-
* Each signature is filtered out for the correct voting round id, protocol id and eligible signer.
222-
* Signatures are returned in the form of a map
223-
* from message hash to a list of signatures to submission data containing parsed signature payload.
224-
* The last signed message for a specific message hash is considered.
225-
* ASSUMPTION: all signature submissions for voting round id, hence contained ,
226-
* between reveal deadline for votingRoundId (hence in voting epoch votingRoundId + 1) and
227-
* the end of the voting epoch votingRoundId + 1 + ADDITIONAL_REWARDED_FINALIZATION_WINDOWS
228-
* @param votingRoundId
229-
* @param rewardEpoch
230-
* @param submissions
231-
* @returns
232-
*/
221+
* Extract signature payloads for the given voting round id from the given submissions.
222+
* Each signature is filtered out for the correct voting round id, protocol id and eligible signer.
223+
* Signatures are returned in the form of a map
224+
* from message hash to a list of signatures to submission data containing parsed signature payload.
225+
* The last signed message for a specific message hash is considered.
226+
* ASSUMPTION: all signature submissions for voting round id, hence contained ,
227+
* between reveal deadline for votingRoundId (hence in voting epoch votingRoundId + 1) and
228+
* the end of the voting epoch votingRoundId + 1 + ADDITIONAL_REWARDED_FINALIZATION_WINDOWS
229+
* @param votingRoundId
230+
* @param rewardEpoch
231+
* @param submissions
232+
* @returns
233+
*/
233234
public static extractSignatures(
234235
votingRoundId: number,
235236
rewardEpoch: RewardEpoch,
@@ -244,23 +245,26 @@ export class DataManagerForRewarding extends DataManager {
244245
try {
245246
const signaturePayload = SignaturePayload.decode(message.payload);
246247
if (signaturePayload.message && signaturePayload.message.protocolId !== message.protocolId) {
247-
throw new Error(`Protocol id mismatch in signed message. Expected ${message.protocolId}, got ${signaturePayload.message.protocolId}`);
248+
throw new Error(
249+
`Protocol id mismatch in signed message. Expected ${message.protocolId}, got ${signaturePayload.message.protocolId}`
250+
);
248251
}
249252
if (signaturePayload.message && signaturePayload.message.votingRoundId !== message.votingRoundId) {
250-
throw new Error(`Voting round id mismatch in signed message. Expected ${message.votingRoundId}, got ${signaturePayload.message.votingRoundId}`);
253+
throw new Error(
254+
`Voting round id mismatch in signed message. Expected ${message.votingRoundId}, got ${signaturePayload.message.votingRoundId}`
255+
);
251256
}
252-
if (
253-
message.votingRoundId === votingRoundId &&
254-
message.protocolId === protocolId
255-
) {
257+
if (message.votingRoundId === votingRoundId && message.protocolId === protocolId) {
256258
// - Override the messageHash if provided
257-
// - Require
259+
// - Require
258260

259261
let messageHash = providedMessageHash ?? ProtocolMessageMerkleRoot.hash(signaturePayload.message);
260262

261263
const signer = ECDSASignature.recoverSigner(messageHash, signaturePayload.signature).toLowerCase();
262264
// submit signature address should match the signingPolicyAddress
263-
const expectedSigner = rewardEpoch.getSigningAddressFromSubmitSignatureAddress(submission.submitAddress.toLowerCase());
265+
const expectedSigner = rewardEpoch.getSigningAddressFromSubmitSignatureAddress(
266+
submission.submitAddress.toLowerCase()
267+
);
264268
// if the expected signer is not found, the signature is not valid for rewarding
265269
if (!expectedSigner) {
266270
continue;
@@ -280,7 +284,7 @@ export class DataManagerForRewarding extends DataManager {
280284
if (!rewardEpoch.isEligibleSignerAddress(expectedSigner)) {
281285
continue;
282286
}
283-
// wrong signature by eligible signer
287+
// wrong signature by eligible signer
284288
signaturePayload.messageHash = WRONG_SIGNATURE_INDICATOR_MESSAGE_HASH;
285289
} else {
286290
signaturePayload.messageHash = providedMessageHash;
@@ -309,7 +313,7 @@ export class DataManagerForRewarding extends DataManager {
309313
signatures.push(submissionData);
310314
}
311315
} catch (e) {
312-
console.log(e)
316+
console.log(e);
313317
logger.warn(`Issues with parsing submission message: ${e.message}`);
314318
}
315319
}
@@ -388,10 +392,7 @@ export class DataManagerForRewarding extends DataManager {
388392
fastUpdatesData = fastUpdatesDataResponse.data;
389393
}
390394
if (useFDCData) {
391-
const partialFdcDataResponse = await this.getFDCDataForVotingRoundRange(
392-
firstVotingRoundId,
393-
lastVotingRoundId
394-
);
395+
const partialFdcDataResponse = await this.getFDCDataForVotingRoundRange(firstVotingRoundId, lastVotingRoundId);
395396
if (partialFdcDataResponse.status !== DataAvailabilityStatus.OK) {
396397
return {
397398
status: partialFdcDataResponse.status,
@@ -440,21 +441,24 @@ export class DataManagerForRewarding extends DataManager {
440441
startIndexFinalizations,
441442
endIndexFinalizations
442443
);
443-
const signatures = DataManagerForRewarding.extractSignatures(
444-
votingRoundId,
445-
rewardEpoch,
446-
votingRoundSignatures,
447-
FTSO2_PROTOCOL_ID,
448-
undefined,
449-
this.logger
450-
);
451444
const finalizations = this.extractFinalizations(
452445
votingRoundId,
453446
rewardEpoch,
454447
votingRoundFinalizations,
455448
FTSO2_PROTOCOL_ID
456449
);
457450
const firstSuccessfulFinalization = finalizations.find(finalization => finalization.successfulOnChain);
451+
RelayMessage.augment(firstSuccessfulFinalization.messages);
452+
const consensusMessageHashFTSO = firstSuccessfulFinalization.messages.protocolMessageHash;
453+
454+
const signatures = DataManagerForRewarding.extractSignatures(
455+
votingRoundId,
456+
rewardEpoch,
457+
votingRoundSignatures,
458+
FTSO2_PROTOCOL_ID,
459+
consensusMessageHashFTSO,
460+
this.logger
461+
);
458462

459463
let fdcData: FDCDataForVotingRound | undefined;
460464
let fdcRewardData: FDCRewardData | undefined;
@@ -468,10 +472,12 @@ export class DataManagerForRewarding extends DataManager {
468472
FDC_PROTOCOL_ID
469473
);
470474
const fdcFirstSuccessfulFinalization = fdcFinalizations.find(finalization => finalization.successfulOnChain);
471-
let fdcSignatures = new Map<MessageHash, GenericSubmissionData<ISignaturePayload>[]>;
475+
let fdcSignatures = new Map<MessageHash, GenericSubmissionData<ISignaturePayload>[]>();
472476
if (fdcFirstSuccessfulFinalization) {
473477
if (!fdcFirstSuccessfulFinalization.messages.protocolMessageMerkleRoot) {
474-
throw new Error(`Protocol message merkle root is missing for FDC finalization ${fdcFirstSuccessfulFinalization.messages.protocolMessageHash}`);
478+
throw new Error(
479+
`Protocol message merkle root is missing for FDC finalization ${fdcFirstSuccessfulFinalization.messages.protocolMessageHash}`
480+
);
475481
}
476482
RelayMessage.augment(fdcFirstSuccessfulFinalization.messages);
477483
const consensusMessageHash = fdcFirstSuccessfulFinalization.messages.protocolMessageHash;
@@ -488,15 +494,23 @@ export class DataManagerForRewarding extends DataManager {
488494
dataForCalculations.validEligibleBitVoteSubmissions,
489495
fdcSignatures,
490496
rewardEpoch
491-
)
497+
);
492498
}
493499

494500
const partialData = partialFdcData[votingRoundId - firstVotingRoundId];
495501
if (partialData.votingRoundId !== votingRoundId) {
496502
throw new Error(`Voting round id mismatch: ${partialData.votingRoundId} !== ${votingRoundId}`);
497503
}
498-
if (partialData && partialData.nonDuplicationIndices && fdcRewardData && fdcRewardData.consensusBitVote !== undefined) {
499-
consensusBitVoteIndices = bitVoteIndicesNum(fdcRewardData.consensusBitVote, partialData.nonDuplicationIndices.length);
504+
if (
505+
partialData &&
506+
partialData.nonDuplicationIndices &&
507+
fdcRewardData &&
508+
fdcRewardData.consensusBitVote !== undefined
509+
) {
510+
consensusBitVoteIndices = bitVoteIndicesNum(
511+
fdcRewardData.consensusBitVote,
512+
partialData.nonDuplicationIndices.length
513+
);
500514
for (const bitVoteIndex of consensusBitVoteIndices) {
501515
for (const [i, originalIndex] of partialData.nonDuplicationIndices[bitVoteIndex].entries()) {
502516
partialData.attestationRequests[originalIndex].confirmed = true;
@@ -512,7 +526,7 @@ export class DataManagerForRewarding extends DataManager {
512526
firstSuccessfulFinalization: fdcFirstSuccessfulFinalization,
513527
...fdcRewardData,
514528
consensusBitVoteIndices,
515-
}
529+
};
516530
}
517531

518532
const dataForRound: DataForRewardCalculation = {
@@ -521,7 +535,7 @@ export class DataManagerForRewarding extends DataManager {
521535
finalizations,
522536
firstSuccessfulFinalization,
523537
fastUpdatesData: fastUpdatesData[votingRoundId - firstVotingRoundId],
524-
fdcData
538+
fdcData,
525539
};
526540
result.push(dataForRound);
527541
}
@@ -531,7 +545,6 @@ export class DataManagerForRewarding extends DataManager {
531545
};
532546
}
533547

534-
535548
/**
536549
* Extract signatures and finalizations for the given voting round id from indexer database.
537550
* This function is used for reward calculation, which is executed at the time when all the data
@@ -734,7 +747,7 @@ export class DataManagerForRewarding extends DataManager {
734747
throw new Error(`FastUpdateFeeds is undefined for voting round ${votingRoundId}`);
735748
}
736749

737-
if (fastUpdateFeeds as any === "CONTRACT_CHANGE") {
750+
if ((fastUpdateFeeds as any) === "CONTRACT_CHANGE") {
738751
result.push(undefined);
739752
this.logger.error(`WARN: FastUpdateFeeds contract change for voting round ${votingRoundId}`);
740753
continue;
@@ -757,8 +770,10 @@ export class DataManagerForRewarding extends DataManager {
757770
firstVotingRoundId: number,
758771
lastVotingRoundId: number
759772
): Promise<DataMangerResponse<PartialFDCDataForVotingRound[]>> {
760-
761-
const attestationRequestsResponse = await this.indexerClient.getAttestationRequestEvents(firstVotingRoundId, lastVotingRoundId);
773+
const attestationRequestsResponse = await this.indexerClient.getAttestationRequestEvents(
774+
firstVotingRoundId,
775+
lastVotingRoundId
776+
);
762777
if (attestationRequestsResponse.status !== BlockAssuranceResult.OK) {
763778
return {
764779
status: DataAvailabilityStatus.NOT_OK,
@@ -785,7 +800,10 @@ export class DataManagerForRewarding extends DataManager {
785800
* Note that payloads may contain messages from other protocols!
786801
* If data provider submits multiple bitvotes, the last submission is considered
787802
*/
788-
public extractSubmissionsWithValidEligibleBitVotes(submissionDataArray: SubmissionData[], rewardEpoch: RewardEpoch): SubmissionData[] {
803+
public extractSubmissionsWithValidEligibleBitVotes(
804+
submissionDataArray: SubmissionData[],
805+
rewardEpoch: RewardEpoch
806+
): SubmissionData[] {
789807
const voterToLastBitVote = new Map<Address, SubmissionData>();
790808
for (const submission of submissionDataArray) {
791809
for (const message of submission.messages) {
@@ -810,5 +828,4 @@ export class DataManagerForRewarding extends DataManager {
810828
}
811829
return [...voterToLastBitVote.values()];
812830
}
813-
814831
}

0 commit comments

Comments
 (0)