Skip to content

Commit

Permalink
Merge pull request #1678 from IntersectMBO/bugfix/incorrect-dRep-meta…
Browse files Browse the repository at this point in the history
…data-url-hash

Bug Fix: Incorrect dRep anchor URL and dataHash on dRep registration
  • Loading branch information
kneerose authored Aug 6, 2024
2 parents ac38100 + b850faf commit 4ee15a2
Show file tree
Hide file tree
Showing 6 changed files with 167 additions and 16 deletions.
76 changes: 76 additions & 0 deletions tests/govtool-frontend/playwright/lib/_mock/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,80 @@ export const valid = {

return username;
},
metadata: () => ({
"@context": {
"@language": "en-us",
CIP100:
"https://github.com/cardano-foundation/CIPs/blob/master/CIP-0100/README.md#",
CIPQQQ:
"https://github.com/cardano-foundation/CIPs/blob/master/CIP-QQQ/README.md#",
hashAlgorithm: "CIP100:hashAlgorithm",
body: {
"@id": "CIPQQQ:body",
"@context": {
references: {
"@id": "CIPQQQ:references",
"@container": "@set",
"@context": {
GovernanceMetadata: "CIP100:GovernanceMetadataReference",
Other: "CIP100:OtherReference",
label: "CIP100:reference-label",
uri: "CIP100:reference-uri",
referenceHash: {
"@id": "CIPQQQ:referenceHash",
"@context": {
hashDigest: "CIPQQQ:hashDigest",
hashAlgorithm: "CIP100:hashAlgorithm",
},
},
},
},
dRepName: "CIPQQQ:dRepName",
bio: "CIPQQQ:bio",
email: "CIPQQQ:email",
},
},
authors: {
"@id": "CIP100:authors",
"@container": "@set",
"@context": {
name: "http://xmlns.com/foaf/0.1/name",
witness: {
"@id": "CIP100:witness",
"@context": {
witnessAlgorithm: "CIP100:witnessAlgorithm",
publicKey: "CIP100:publicKey",
signature: "CIP100:signature",
},
},
},
},
},
authors: [],
hashAlgorithm: {
"@value": "blake2b-256",
},
body: {
bio: {
"@value": faker.lorem.sentences(),
},
dRepName: {
"@value": faker.person.firstName(),
},
email: {
"@value": faker.internet.email(),
},
references: [
{
"@type": "Other",
label: {
"@value": "Label",
},
uri: {
"@value": faker.internet.url(),
},
},
],
},
}),
};
28 changes: 28 additions & 0 deletions tests/govtool-frontend/playwright/lib/helpers/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { faker } from "@faker-js/faker";
import { valid as mockValid } from "@mock/index";
import { Download } from "@playwright/test";
import metadataBucketService from "@services/metadataBucketService";
const blake = require("blakejs");

import * as fs from "fs";

export async function downloadMetadata(download: Download): Promise<{
Expand All @@ -11,3 +16,26 @@ export async function downloadMetadata(download: Download): Promise<{
const jsonData = JSON.parse(fileContent);
return { name: download.suggestedFilename(), data: jsonData };
}

function calculateMetadataHash() {
try {
const data = JSON.stringify(mockValid.metadata());

const buffer = Buffer.from(data, "utf8");
const hexDigest = blake.blake2bHex(buffer, null, 32);

const jsonData = JSON.parse(data);
return { hexDigest, jsonData };
} catch (error) {
console.error("Error reading file:", error);
}
}

export async function uploadMetadataAndGetJsonHash() {
const { hexDigest: dataHash, jsonData } = calculateMetadataHash();
const url = await metadataBucketService.uploadMetadata(
faker.person.firstName(),
jsonData
);
return { dataHash, url };
}
10 changes: 9 additions & 1 deletion tests/govtool-frontend/playwright/lib/helpers/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { LockInterceptor, LockInterceptorInfo } from "lib/lockInterceptor";
import { Logger } from "../../../cypress/lib/logger/logger";
import convertBufferToHex from "./convertBufferToHex";
import { ShelleyWallet } from "./crypto";
import { uploadMetadataAndGetJsonHash } from "./metadata";
import { WalletAndAnchorType } from "@types";

/**
* Polls the transaction status until it's resolved or times out.
Expand Down Expand Up @@ -112,9 +114,15 @@ export async function transferAdaForWallet(
}

export async function registerDRepForWallet(wallet: ShelleyWallet) {
const dataHashAndUrl = await uploadMetadataAndGetJsonHash();
const metadataAnchorAndWallet: WalletAndAnchorType = {
...dataHashAndUrl,
wallet: wallet.json(),
};
const registrationRes = await kuberService.dRepRegistration(
convertBufferToHex(wallet.stakeKey.private),
convertBufferToHex(wallet.stakeKey.pkh)
convertBufferToHex(wallet.stakeKey.pkh),
metadataAnchorAndWallet
);
await pollTransaction(registrationRes.txId, registrationRes.lockInfo);
}
41 changes: 29 additions & 12 deletions tests/govtool-frontend/playwright/lib/services/kuberService.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { faucetWallet } from "@constants/staticWallets";
import { KuberValue, ProtocolParams, StaticWallet } from "@types";
import {
KuberValue,
ProtocolParams,
StaticWallet,
WalletAndAnchorType,
} from "@types";
import * as blake from "blakejs";
import environments from "lib/constants/environments";
import { LockInterceptor, LockInterceptorInfo } from "lib/lockInterceptor";
Expand Down Expand Up @@ -37,7 +42,11 @@ class Kuber {
this.version = version;
}

static generateCert(type: CertificateType, key: string) {
static generateCert(
type: CertificateType,
key: string,
metadata?: WalletAndAnchorType
) {
if (type === "registerstake" || type === "deregisterdrep") {
return {
type: type,
Expand All @@ -48,9 +57,8 @@ class Kuber {
type: "registerdrep",
key: key,
anchor: {
url: "https://bit.ly/3zCH2HL",
dataHash:
"1111111111111111111111111111111111111111111111111111111111111111",
url: metadata?.url || "",
dataHash: metadata?.dataHash || "",
},
};
}
Expand Down Expand Up @@ -178,27 +186,36 @@ const kuberService = {
return kuber.signAndSubmitTx(req);
},

multipleDRepRegistration: (wallets: StaticWallet[]) => {
multipleDRepRegistration: (metadataAndWallets: WalletAndAnchorType[]) => {
const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private);
const req = {
certificates: wallets.map((wallet) =>
Kuber.generateCert("registerdrep", wallet.stake.pkh)
certificates: metadataAndWallets.map((metadataAndWallet) =>
Kuber.generateCert(
"registerdrep",
metadataAndWallet.wallet.stake.pkh,
metadataAndWallet
)
),
selections: wallets.map((wallet) => {
selections: metadataAndWallets.map((metadata) => {
return {
type: "PaymentSigningKeyShelley_ed25519",
description: "Stake Signing Key",
cborHex: `5820${wallet.stake.private}`,
cborHex: `5820${metadata.wallet.stake.private}`,
};
}),
};
return kuber.signAndSubmitTx(req);
},

dRepRegistration: (stakeSigningKey: string, pkh: string) => {
dRepRegistration: (
stakeSigningKey: string,
pkh: string,
metadata: WalletAndAnchorType
) => {
const kuber = new Kuber(faucetWallet.address, faucetWallet.payment.private);

const req = {
certificates: [Kuber.generateCert("registerdrep", pkh)],
certificates: [Kuber.generateCert("registerdrep", pkh, metadata)],
selections: [
{
type: "PaymentSigningKeyShelley_ed25519",
Expand Down
6 changes: 6 additions & 0 deletions tests/govtool-frontend/playwright/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,9 @@ export type ProposedGovAction = {
updatedAt: string;
};
};

export type WalletAndAnchorType = {
url: string;
dataHash: string;
wallet: StaticWallet;
};
22 changes: 19 additions & 3 deletions tests/govtool-frontend/playwright/tests/dRep.setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import environments from "@constants/environments";
import { dRepWallets } from "@constants/staticWallets";
import { setAllureEpic, setAllureStory } from "@helpers/allure";
import { ShelleyWallet } from "@helpers/crypto";
import { uploadMetadataAndGetJsonHash } from "@helpers/metadata";
import { pollTransaction } from "@helpers/transaction";
import { expect, test as setup } from "@playwright/test";
import kuberService from "@services/kuberService";
Expand Down Expand Up @@ -34,7 +35,15 @@ setup("Register DRep of static wallets", async () => {
setup.setTimeout(environments.txTimeOut);

try {
const res = await kuberService.multipleDRepRegistration(dRepWallets);
// Submit metadata to obtain a URL and generate hash value.
const metadataPromises = dRepWallets.map(async (dRepWallet) => {
return { ...(await uploadMetadataAndGetJsonHash()), wallet: dRepWallet };
});

const metadataAndDRepWallets = await Promise.all(metadataPromises);
const res = await kuberService.multipleDRepRegistration(
metadataAndDRepWallets
);

await pollTransaction(res.txId, res.lockInfo);
} catch (err) {
Expand Down Expand Up @@ -64,9 +73,16 @@ setup("Setup temporary DRep wallets", async () => {
]);
await pollTransaction(initializeRes.txId, initializeRes.lockInfo);

// Submit metadata to obtain a URL and generate hash value.
const metadataPromises = dRepWallets.map(async (dRepWallet) => {
return { ...(await uploadMetadataAndGetJsonHash()), wallet: dRepWallet };
});

const metadatasAndDRepWallets = await Promise.all(metadataPromises);
// register dRep
const registrationRes =
await kuberService.multipleDRepRegistration(dRepWallets);
const registrationRes = await kuberService.multipleDRepRegistration(
metadatasAndDRepWallets
);
await pollTransaction(registrationRes.txId, registrationRes.lockInfo);

// transfer 600 ADA for dRep registration
Expand Down

0 comments on commit 4ee15a2

Please sign in to comment.