Skip to content

Commit

Permalink
Asset: Changes to packages & scripts for VC (#194)
Browse files Browse the repository at this point in the history
  • Loading branch information
vatsa287 authored Mar 22, 2024
1 parent 6964ff2 commit 5dcdeb2
Show file tree
Hide file tree
Showing 14 changed files with 1,220 additions and 814 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async function main() {
const { mnemonic: issuerMnemonic, document: issuerDid } = await createDid(
networkAuthorityIdentity
)
const issuerKeys = Cord.Utils.Keys.generateKeypairs(issuerMnemonic)
const issuerKeys = Cord.Utils.Keys.generateKeypairs(issuerMnemonic, 'sr25519')
console.log(
`πŸ› Issuer (${issuerDid?.assertionMethod![0].type}): ${issuerDid.uri}`
)
Expand Down
4 changes: 2 additions & 2 deletions demo/src/asset-tx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ async function main() {
const { mnemonic: issuerMnemonic, document: issuerDid } = await createDid(
networkAuthorityIdentity
)
const issuerKeys = Cord.Utils.Keys.generateKeypairs(issuerMnemonic)
const issuerKeys = Cord.Utils.Keys.generateKeypairs(issuerMnemonic, 'sr25519')
console.log(
`πŸ› Issuer (${issuerDid?.assertionMethod![0].type}): ${issuerDid.uri}`
)

const { mnemonic: holderMnemonic, document: holderDid } = await createDid(
networkAuthorityIdentity
)
const holderKeys = Cord.Utils.Keys.generateKeypairs(holderMnemonic)
const holderKeys = Cord.Utils.Keys.generateKeypairs(holderMnemonic, 'sr25519')
console.log(
`πŸ› Holder (${holderDid?.assertionMethod![0].type}): ${holderDid.uri}`
)
Expand Down
248 changes: 248 additions & 0 deletions demo/src/asset-vc-benchmark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,248 @@
import * as Cord from "@cord.network/sdk";
import { addNetworkMember } from "./utils/createAuthorities.js";
import { createAccount } from "./utils/createAccount.js";
import { createDid } from "./utils/generateDid";
import { BN } from '@polkadot/util'
import { uriToIdentifier } from '@cord.network/identifier'

import moment from "moment";
import { Address } from '../../packages/utils/lib/esm/Crypto';

const { NETWORK_ADDRESS, ANCHOR_URI } = process.env;

export const sleep = (ms: number): Promise<void> => {
return new Promise((resolve) => {
setTimeout(() => resolve(), ms);
});
};

async function main() {
const networkAddress = "ws://127.0.0.1:9944";
const anchorUri = "//Alice";
if (!anchorUri || !networkAddress) {
console.log("Missing variables");
return -1;
}
console.log("Env Variables: ", networkAddress, anchorUri);

// Temporarily suppress console.log
let originalConsoleLog = console.log;
console.log = () => {};
Cord.ConfigService.set({ submitTxResolveOn: Cord.Chain.IS_IN_BLOCK });

await Cord.connect(networkAddress);
const api = Cord.ConfigService.get("api");

// Restore console.log
console.log = originalConsoleLog;
const txCount = 20000;
const perBlock = 350;

// Step 1: Setup Identities
console.log(`\n❄️ Identities`);
const networkAuthorityIdentity = Cord.Utils.Crypto.makeKeypairFromUri(
anchorUri,
"sr25519",
);
const { account: issuerIdentity } = createAccount();
console.log(`🏦 Issuer (${issuerIdentity.type}): ${issuerIdentity.address}`);
await addNetworkMember(networkAuthorityIdentity, issuerIdentity.address);
console.log("βœ… Issuer Identity created!");

const { mnemonic: issuerMnemonic, document: issuerDid } = await createDid(
networkAuthorityIdentity
)
const issuerKeys = Cord.Utils.Keys.generateKeypairs(issuerMnemonic, 'sr25519')
console.log(
`πŸ› Issuer (${issuerDid?.assertionMethod![0].type}): ${issuerDid.uri}`
)

// Step 2: Create a new Chain Space
console.log(`\n❄️ Chain Space Creation `)
const spaceProperties = await Cord.ChainSpace.buildFromProperties(
issuerDid.uri
)
console.dir(spaceProperties, {
depth: null,
colors: true,
})

console.log(`\n❄️ Chain Space Properties `)
const space = await Cord.ChainSpace.dispatchToChain(
spaceProperties,
issuerDid.uri,
issuerIdentity,
async ({ data }) => ({
signature: issuerKeys.authentication.sign(data),
keyType: issuerKeys.authentication.type,
})
)
console.dir(space, {
depth: null,
colors: true,
})
console.log('βœ… Chain Space created!')

console.log(`\n❄️ Chain Space Approval `)
await Cord.ChainSpace.sudoApproveChainSpace(
networkAuthorityIdentity,
space.uri,
100000
)
console.log(`βœ… Chain Space Approved`)

// Step 3: Create assets on-chain
console.log = () => {};

/* Check which options one needs: note below only agree */
Cord.ConfigService.set({ submitTxResolveOn: Cord.Chain.IS_READY });
//Cord.ConfigService.set({ submitTxResolveOn: Cord.Chain.IS_IN_BLOCK});
//Cord.ConfigService.set({ submitTxResolveOn: Cord.Chain.IS_FINALIZED });
console.log = originalConsoleLog;

console.log(`\n❄️ Create On-Chain Assets `);
let assetProperties: Cord.IAssetProperties = {
assetType: Cord.AssetTypeOf.art,
assetDesc: "Asset - " + Cord.Utils.UUID.generate(),
assetQty: 1000000,
assetValue: 10,
assetTag: "Tag - " + Cord.Utils.UUID.generate(),
assetMeta: "Meta - " + Cord.Utils.UUID.generate(),
};

const assetEntry = await Cord.Asset.buildFromAssetProperties(
assetProperties,
issuerDid.uri,
space.uri
);

console.dir(assetEntry, {
depth: null,
colors: true,
});

const extrinsic = await Cord.Asset.dispatchCreateVcToChain(
assetProperties.assetQty,
assetEntry.digest,
assetEntry.creator,
issuerIdentity,
space.authorization,
assetEntry.uri,
async ({ data }) => ({
signature: issuerKeys.authentication.sign(data),
keyType: issuerKeys.authentication.type,
}),
)

console.log("βœ… Asset created!");

console.log(`\n❄️ Transaction Benchmarking `);

let tx_batch: any = [];
let startTxPrep = moment();

try {
for (let j = 0; j < (txCount / perBlock); j++) {
let tx_batch1: any = [];
for (let k = 0; k < perBlock; k++) {
const { account: holderIdentity } = createAccount();

const assetIssuance = await Cord.Asset.buildFromIssueProperties(
assetEntry.uri,
`did:cord:${holderIdentity.address}`,
1,
issuerDid.uri,
space.uri,
);

const authorizationId: Cord.AuthorizationId = uriToIdentifier(space.authorization)

const tx = await api.tx.asset.vcIssue(
assetIssuance.entry,
assetIssuance.digest,
authorizationId
)

tx_batch1.push(tx);

process.stdout.write(
" πŸ”– Preparing " +
(j * perBlock + 1 + k) +
" transactions took " +
moment.duration(moment().diff(startTxPrep)).as("seconds").toFixed(3) +
"s\r",
);
}
tx_batch[j] = tx_batch1;
}
} catch (e: any) {
console.log(e.errorCode, "-", e.message);
}
console.log("\n");

//Cord.ConfigService.set({ submitTxResolveOn: Cord.Chain.IS_FINALIZED });
console.log = originalConsoleLog;
let batchAncStartTime = moment();

let promises = [];
for (let j = 0; j < tx_batch.length; j++) {
try {
let extSignCallback: Cord.SignExtrinsicCallback = async ({ data }) => ({
signature: issuerKeys.authentication.sign(data),
keyType: issuerKeys.authentication.type,
})

/* Use nonce when authorizing tx in batch(loop) */
const authorizedBatch = await Cord.Did.authorizeBatch({
batchFunction: api.tx.utility.batchAll,
did: issuerDid.uri,
nonce: new BN(j+3),
extrinsics: tx_batch[j],
sign: extSignCallback,
submitter: issuerIdentity.address
})

await authorizedBatch.signAsync(issuerIdentity, {nonce: 2+j});
const send:any = new Promise((resolve) => authorizedBatch.send((result) => {
if (result.status.isReady)
//if (result.isInBlock)
//if (result.isFinalized)
return resolve(true);
}));
promises.push(send);

} catch (e: any) {
console.log(e.errorCode, "-", e.message);
}
}
await Promise.all(promises);

var batchAncDuration = moment
.duration(moment().diff(batchAncStartTime))
.as("seconds");

console.log(
`\n 🎁 Anchoring a batch of ${
txCount
} transactions took ${batchAncDuration.toFixed(3)}s`,
);
console.log(
` πŸ™Œ Block TPS (batch transactions) - ${+(
txCount / batchAncDuration
).toFixed(0)} `,
);

await sleep(1000);
// await sleep(10000);

await api.disconnect();
}
main()
.then(() => console.log("\nBye! πŸ‘‹ πŸ‘‹ πŸ‘‹ "))
.finally(Cord.disconnect);

process.on("SIGINT", async () => {
console.log("\nBye! πŸ‘‹ πŸ‘‹ πŸ‘‹ \n");
Cord.disconnect();
process.exit(0);
});
Loading

0 comments on commit 5dcdeb2

Please sign in to comment.