Skip to content

Commit

Permalink
Merge pull request #366 from desci-labs/draft-node-fix
Browse files Browse the repository at this point in the history
Draft node fix
  • Loading branch information
hubsmoke authored Jun 19, 2024
2 parents 144615c + 2fc8a43 commit 0102dad
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 103 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "NodeAttestation" ALTER COLUMN "nodeDpid10" DROP NOT NULL;
2 changes: 1 addition & 1 deletion desci-server/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,7 @@ model NodeAttestation {
community DesciCommunity @relation(fields: [desciCommunityId], references: [id])
claimedById Int
claimedBy User @relation(fields: [claimedById], references: [id])
nodeDpid10 String
nodeDpid10 String?
nodeUuid String
node Node @relation(fields: [nodeUuid], references: [uuid])
nodeVersion Int
Expand Down
2 changes: 1 addition & 1 deletion desci-server/src/controllers/attestations/claims.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const removeClaim = async (req: RequestWithUser, res: Response, _next: Ne
const node = await prisma.node.findFirst({ where: { uuid: body.nodeUuid } });
if (!node) throw new NotFoundError('Node not found');

const claim = await attestationService.getClaimOnDpid(body.claimId, body.dpid.toString());
const claim = await attestationService.getClaimOnUuid(body.claimId, body.nodeUuid);
if (!claim) throw new NotFoundError();

if (node.ownerId !== req.user.id || claim.claimedById !== req.user.id) throw new AuthFailureError();
Expand Down
10 changes: 5 additions & 5 deletions desci-server/src/controllers/attestations/show.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ type ShowNodeAttestationsResponse = {
};

export const showNodeAttestations = async (
req: Request<{ dpid: string }>,
req: Request<{ uuid: string }>,
res: Response<ShowNodeAttestationsResponse>,
) => {
const { dpid } = req.params;
const { uuid } = req.params;

const logger = parentLogger.child({
module: 'ATTESTATIONS::showNodeAttestationsController',
user: (req as any).user,
dpid,
uuid,
});
logger.trace(`showNodeAttestations`);

if (!dpid) throw new BadRequestError('DPID is required');
if (!uuid) throw new BadRequestError('uuid is required');

let attestations = await attestationService.getAllNodeAttestations(dpid);
let attestations = await attestationService.getAllNodeAttestations(uuid);
attestations = attestations.map((att) => ({
...att,
_count: undefined,
Expand Down
136 changes: 54 additions & 82 deletions desci-server/src/controllers/nodes/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
} from '../../services/nodeManager.js';
import { discordNotify } from '../../utils/discordUtils.js';
import { ensureUuidEndsWithDot } from '../../utils.js';

import { getOrCreateDpid, upgradeDpid } from './createDpid.js';

export type PublishReqBody = {
Expand All @@ -40,13 +41,23 @@ export type PublishResBody =
| {
error: string;
};

async function updateAssociatedAttestations(nodeUuid: string, dpid: string) {
const logger = parentLogger.child({
// id: req.id,
module: 'NODE::publishController',
});
logger.info({ nodeUuid, dpid }, `[updateAssociatedAttestations]`);
return await prisma.nodeAttestation.updateMany({
where: {
nodeUuid,
},
data: {
nodeDpid10: dpid,
},
});
}
// call node publish service and add job to queue
export const publish = async (
req: PublishRequest,
res: Response<PublishResBody>,
_next: NextFunction
) => {
export const publish = async (req: PublishRequest, res: Response<PublishResBody>, _next: NextFunction) => {
const { uuid, cid, manifest, transactionId, ceramicStream, commitId, useNewPublish } = req.body;
// debugger;
const email = req.user.email;
Expand Down Expand Up @@ -112,19 +123,8 @@ export const publish = async (
let publishTask: PublishTaskQueue | undefined;

if (useNewPublish) {
logger.info(
{ceramicStream, commitId, uuid, owner: owner.id},
"Triggering new publish flow"
);
await syncPublish(
ceramicStream,
commitId,
node,
owner,
cid,
uuid,
manifest,
);
logger.info({ ceramicStream, commitId, uuid, owner: owner.id }, 'Triggering new publish flow');
await syncPublish(ceramicStream, commitId, node, owner, cid, uuid, manifest);
} else {
publishTask = await prisma.publishTaskQueue.create({
data: {
Expand All @@ -138,7 +138,7 @@ export const publish = async (
status: PublishTaskQueueStatus.WAITING,
},
});
};
}

saveInteraction(
req,
Expand All @@ -156,14 +156,15 @@ export const publish = async (
owner.id,
);

updateAssociatedAttestations(node.uuid, manifest.dpid.id);
return res.send({
ok: true,
taskId: publishTask?.id,
});
} catch (err) {
logger.error({ err }, '[publish::publish] node-publish-err');
return res.status(400).send({ ok: false, error: err.message });
};
}
};

/**
Expand All @@ -176,7 +177,7 @@ export const publish = async (
*
* Semantically, these can both be made fire-and-forget promises if we can
* manage without instantly having the dPID alias available in this function.
*/
*/
const syncPublish = async (
ceramicStream: string,
commitId: string,
Expand All @@ -200,14 +201,12 @@ const syncPublish = async (
nodeId: node.id,
},
orderBy: {
id: "desc",
id: 'desc',
},
});

// Prevent duplicating the NodeVersion entry if the latest version is the same as the one we're trying to publish, as a draft save is triggered before publishing
const latestNodeVersionId = latestNodeVersion?.manifestUrl === cid
? latestNodeVersion.id
: -1;
const latestNodeVersionId = latestNodeVersion?.manifestUrl === cid ? latestNodeVersion.id : -1;

const nodeVersion = await prisma.nodeVersion.upsert({
where: {
Expand All @@ -233,7 +232,7 @@ const syncPublish = async (
`[publish:publish] stream on record does not match passed streamID`,
{ database: node.ceramicStream, ceramicStream },
);
};
}

const legacyDpid = manifest.dpid?.id ? parseInt(manifest.dpid.id) : undefined;
let dpidAlias: number = node.dpidAlias;
Expand All @@ -245,11 +244,8 @@ const syncPublish = async (
// The only reason this isn't just fire-and-forget is that we want the dpid
// for the discord notification, which won't be available otherwise for
// first time publishes.
promises.push(
createOrUpgradeDpidAlias(legacyDpid, ceramicStream, uuid)
.then(dpid => dpidAlias = dpid)
);
};
promises.push(createOrUpgradeDpidAlias(legacyDpid, ceramicStream, uuid).then((dpid) => (dpidAlias = dpid)));
}

promises.push(
handlePublicDataRefs({
Expand All @@ -258,7 +254,7 @@ const syncPublish = async (
manifestCid: cid,
nodeVersionId: nodeVersion.id,
nodeUuid: node.uuid,
})
}),
);

await Promise.all(promises);
Expand All @@ -277,7 +273,7 @@ const syncPublish = async (
/**
* Creates new dPID if legacyDpid is falsy, otherwise tries to upgrade
* the dPID by binding the stream in the alias registry for that dPID.
*/
*/
const createOrUpgradeDpidAlias = async (
legacyDpid: number | undefined,
ceramicStream: string,
Expand All @@ -290,29 +286,21 @@ const createOrUpgradeDpidAlias = async (
} else {
// Will nicely return the existing dpid if this is called multiple times
dpidAlias = await getOrCreateDpid(ceramicStream);
};
}
await setDpidAlias(uuid, dpidAlias);
return dpidAlias;
};

type PublishData = {
nodeId: number,
nodeUuid: string,
userId: number,
manifestCid: string,
nodeVersionId: number,
nodeId: number;
nodeUuid: string;
userId: number;
manifestCid: string;
nodeVersionId: number;
};

const handlePublicDataRefs = async (
params: PublishData,
): Promise<void> => {
const {
nodeId,
nodeUuid,
userId,
manifestCid,
nodeVersionId,
} = params;
const handlePublicDataRefs = async (params: PublishData): Promise<void> => {
const { nodeId, nodeUuid, userId, manifestCid, nodeVersionId } = params;

const logger = parentLogger.child({
module: 'NODE::handlePublicDataRefs',
Expand All @@ -329,47 +317,31 @@ const handlePublicDataRefs = async (
/***
* Traverse the DAG structure to find all relevant CIDs and get relevant info for indexing
*/
cidsRequiredForPublish = await getAllCidsRequiredForPublish(
manifestCid,
nodeUuid,
userId,
nodeId,
nodeVersionId
);
cidsRequiredForPublish = await getAllCidsRequiredForPublish(manifestCid, nodeUuid, userId, nodeId, nodeVersionId);

/**
* Index the DAGs from IPFS in order to avoid recurrent IPFS calls when requesting data in the future
*/
const newPublicDataRefs = await createPublicDataRefs(
cidsRequiredForPublish,
userId,
nodeVersionId,
);
const newPublicDataRefs = await createPublicDataRefs(cidsRequiredForPublish, userId, nodeVersionId);

/**
* Save a success for configurable service quality tracking purposes
*/
await saveInteractionWithoutReq(
ActionType.PUBLISH_NODE_CID_SUCCESS,
{
params,
result: { newPublicDataRefs },
}
);
await saveInteractionWithoutReq(ActionType.PUBLISH_NODE_CID_SUCCESS, {
params,
result: { newPublicDataRefs },
});
} catch (error) {
logger.error({ error }, `[publish::publish] error=${error}`);
/**
* Save a failure for configurable service quality tracking purposes
*/
await saveInteractionWithoutReq(
ActionType.PUBLISH_NODE_CID_FAIL,
{
params,
error
}
);
await saveInteractionWithoutReq(ActionType.PUBLISH_NODE_CID_FAIL, {
params,
error,
});
throw error;
};
}
};

export const publishHandler = async ({
Expand Down Expand Up @@ -462,11 +434,11 @@ export const publishHandler = async ({
logger.trace(`[publish::publish] nodeUuid=${node.uuid}, manifestCid=${cid}, transaction=${transactionId}`);

await handlePublicDataRefs({
nodeId: node.id,
nodeUuid: node.uuid,
userId: owner.id,
manifestCid: cid,
nodeVersionId: nodeVersion.id,
nodeId: node.id,
nodeUuid: node.uuid,
userId: owner.id,
manifestCid: cid,
nodeVersionId: nodeVersion.id,
});

const manifest = await getManifestByCid(cid);
Expand Down
2 changes: 1 addition & 1 deletion desci-server/src/routes/v1/attestations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ router.get(
asyncHander(showCommunityClaims),
);

router.get('/:dpid', [validate(showNodeAttestationsSchema)], asyncHander(showNodeAttestations));
router.get('/:uuid', [validate(showNodeAttestationsSchema)], asyncHander(showNodeAttestations));
router.get('/:claimId/reactions', [validate(getAttestationReactionsSchema)], asyncHander(getAttestationReactions));
router.get(
'/:claimId/verifications',
Expand Down
8 changes: 4 additions & 4 deletions desci-server/src/routes/v1/attestations/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const showCommunityClaimsSchema = z.object({

export const showNodeAttestationsSchema = z.object({
params: z.object({
dpid,
uuid: z.string(),
}),
});

Expand Down Expand Up @@ -149,7 +149,7 @@ export const claimAttestationSchema = z.object({
attestationId: z.coerce.number(),
nodeVersion: z.coerce.number(),
nodeUuid: z.string(),
nodeDpid: z.string(),
nodeDpid: z.string().optional(),
claimerId: z.coerce.number(),
}),
});
Expand All @@ -159,14 +159,14 @@ export const claimEntryAttestationsSchema = z.object({
communityId: z.coerce.number(),
nodeVersion: z.coerce.number(),
nodeUuid: z.string(),
nodeDpid: z.string(),
nodeDpid: z.string().optional(),
claimerId: z.coerce.number(),
}),
});

export const removeClaimSchema = z.object({
body: z.object({
dpid,
dpid: z.coerce.number().optional(),
nodeUuid: z.string(),
claimId: z.coerce.number(),
}),
Expand Down
9 changes: 7 additions & 2 deletions desci-server/src/services/Attestation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
NoAccessError,
VerificationError,
VerificationNotFoundError,
ensureUuidEndsWithDot,
logger,
} from '../internal.js';
import { communityService } from '../internal.js';
Expand Down Expand Up @@ -229,9 +230,9 @@ export class AttestationService {
});
}

async getAllNodeAttestations(dpid: string) {
async getAllNodeAttestations(uuid: string) {
return prisma.nodeAttestation.findMany({
where: { nodeDpid10: dpid, revoked: false },
where: { nodeUuid: ensureUuidEndsWithDot(uuid), revoked: false },
include: {
community: { select: { name: true, description: true, keywords: true, image_url: true } },
attestation: { select: { protected: true, verified_image_url: true } },
Expand Down Expand Up @@ -445,6 +446,10 @@ export class AttestationService {
return prisma.nodeAttestation.findFirst({ where: { id, nodeDpid10 } });
}

async getClaimOnUuid(id: number, nodeUuid: string) {
return prisma.nodeAttestation.findFirst({ where: { id, nodeUuid } });
}

async verifyClaim(nodeAttestationId: number, userId: number) {
assert(nodeAttestationId > 0, 'Error: nodeAttestationId is Zero');
assert(userId > 0, 'Error: userId is Zero');
Expand Down
2 changes: 1 addition & 1 deletion desci-server/src/services/Communities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ export class CommunityService {
left outer JOIN "Annotation" ON t1."id" = "Annotation"."nodeAttestationId"
left outer JOIN "NodeAttestationReaction" ON t1."id" = "NodeAttestationReaction"."nodeAttestationId"
left outer JOIN "NodeAttestationVerification" ON t1."id" = "NodeAttestationVerification"."nodeAttestationId"
WHERE t1."revoked" = false AND
WHERE t1."revoked" = false AND t1."nodeDpid10" IS NOT NULL AND
EXISTS
(SELECT *
from "CommunityEntryAttestation" c1
Expand Down
Loading

0 comments on commit 0102dad

Please sign in to comment.