Skip to content

Commit

Permalink
feat: 🎸 track instruction mediator affirms
Browse files Browse the repository at this point in the history
Signed-off-by: Eric Richardson <eric@polymesh.network>
  • Loading branch information
polymath-eric committed Feb 21, 2024
1 parent 5c4a27f commit 1b978b4
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 4 deletions.
15 changes: 15 additions & 0 deletions schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2351,3 +2351,18 @@ type CustomClaimType @entity {
createdBlock: Block!
updatedBlock: Block!
}

"""
Represents a mediator's approval for an instruction
"""
type MeditatorAffirmation @entity {
id: ID! # did/instruction ID
identity: Identity!
instruction: Instruction!
"""
If expiry is present the time should be check top ensure the affirmation is still valid
"""
expiry: Date
createdBlock: Block!
updatedBlock: Block!
}
56 changes: 53 additions & 3 deletions src/mappings/entities/mapSettlement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
Instruction,
InstructionStatusEnum,
Leg,
MeditatorAffirmation,
ModuleIdEnum,
Settlement,
SettlementResultEnum,
Expand Down Expand Up @@ -231,7 +232,7 @@ const handleInstructionFinalizedEvent = async (
eventIdx: number,
extrinsic?: SubstrateExtrinsic
): Promise<void> => {
const [, rawInstructionId] = params;
const [rawIdentityId, rawInstructionId] = params;

const address = getSignerAddress(extrinsic);
const instructionId = getTextValue(rawInstructionId);
Expand All @@ -250,11 +251,27 @@ const handleInstructionFinalizedEvent = async (
updatedBlockId: blockId,
});

await Promise.all([
const promises = [
settlement.save(),
instruction.save(),
...(await updateLegs(blockId, address, instructionId, settlementId)),
]);
];

// incase the rejector was a mediator who previously affirmed their affirmation should be removed
if (eventId === EventIdEnum.InstructionRejected) {
const clearMediatorAffirmation = async () => {
const identityId = getTextValue(rawIdentityId);
const id = `${identityId}/${instructionId}`;
const affirmedMediator = await MeditatorAffirmation.get(id);
if (affirmedMediator) {
await MeditatorAffirmation.remove(id);
}
};

promises.push(clearMediatorAffirmation());
}

await Promise.all(promises);
};

const handleFailedToExecuteInstruction = async (
Expand All @@ -273,6 +290,31 @@ const handleFailedToExecuteInstruction = async (
await instruction.save();
};

const handleMediatorAffirmation = async (blockId: string, params: Codec[]): Promise<void> => {
const [rawIdentityId, rawInstructionId, expiryOpt] = params;

const identityId = getTextValue(rawIdentityId);
const instructionId = getTextValue(rawInstructionId);
const expiry = getDateValue(expiryOpt);

await MeditatorAffirmation.create({
id: `${identityId}/${instructionId}`,
identityId,
instructionId,
expiry,
createdBlockId: blockId,
updatedBlockId: blockId,
}).save();
};

const handleMediatorWithdrawn = async (params: Codec[]): Promise<void> => {
const [rawIdentityId, rawInstructionId] = params;
const identityId = getTextValue(rawIdentityId);
const instructionId = getTextValue(rawInstructionId);

await MeditatorAffirmation.remove(`${identityId}/${instructionId}`);
};

export async function mapSettlement(args: HandlerArgs): Promise<void> {
const { blockId, eventId, moduleId, params, eventIdx, extrinsic } = args;
if (moduleId === ModuleIdEnum.settlement) {
Expand All @@ -292,6 +334,14 @@ export async function mapSettlement(args: HandlerArgs): Promise<void> {
await handleInstructionCreated(args);
}

if (eventId === EventIdEnum.MediatorAffirmationReceived) {
await handleMediatorAffirmation(blockId, params);
}

if (eventId === EventIdEnum.MediatorAffirmationWithdrawn) {
await handleMediatorWithdrawn(params);
}

if (updateEvents.includes(eventId)) {
await handleInstructionUpdate(blockId, eventId, params, extrinsic);
}
Expand Down
2 changes: 1 addition & 1 deletion src/mappings/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export const getNumberValue = (item: Codec): number => {
return Number(getTextValue(item));
};

export const getDateValue = (item: Codec): Date => {
export const getDateValue = (item: Codec): Date | undefined => {
return item?.toString().trim().length > 0 ? new Date(Number(item.toString())) : undefined;
};

Expand Down

0 comments on commit 1b978b4

Please sign in to comment.