From 7e59d159761b8100e571d3eed9c3b989bc5b06a9 Mon Sep 17 00:00:00 2001 From: David Dal Busco Date: Thu, 5 Dec 2024 07:49:55 +0100 Subject: [PATCH] feat: gather subnets metadata (#886) * feat: gather subnets metadata Signed-off-by: David Dal Busco * feat: gather statistics Signed-off-by: David Dal Busco * feat: merge also specified subnets Signed-off-by: David Dal Busco * feat: fetch specialization Signed-off-by: David Dal Busco --------- Signed-off-by: David Dal Busco --- package-lock.json | 22 +-- package.json | 2 +- scripts/cmc.subnets.mjs | 81 ++++++++- src/frontend/src/lib/env/subnets.json | 253 +++++++++++++++++++++----- 4 files changed, 289 insertions(+), 69 deletions(-) diff --git a/package-lock.json b/package-lock.json index de6418ccf..c8019a959 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,7 +12,7 @@ "@dfinity/agent": "^2.1.3", "@dfinity/auth-client": "^2.1.3", "@dfinity/candid": "^2.1.3", - "@dfinity/cmc": "^4.0.2", + "@dfinity/cmc": "^4.0.2-next-2024-12-04", "@dfinity/ic-management": "^6.0.1", "@dfinity/identity": "^2.1.3", "@dfinity/ledger-icp": "^2.6.4", @@ -728,15 +728,15 @@ } }, "node_modules/@dfinity/cmc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@dfinity/cmc/-/cmc-4.0.2.tgz", - "integrity": "sha512-RBf/Kl+LNxKWudOBawU7ZLrY+s0DAjL9P1+sap199isrL68eRSOhxm53DPBATF9oUJ2VzSYr0X49mvC0vCyO+Q==", + "version": "4.0.2-next-2024-12-04", + "resolved": "https://registry.npmjs.org/@dfinity/cmc/-/cmc-4.0.2-next-2024-12-04.tgz", + "integrity": "sha512-/z3kb5GvUtPbI0OHTTv3VnG9R7vuAGM4HMMKcneeJXObciJZD49jbNuEAz+3B3KZ2/FjPPDUkxu4hE4ZtjValw==", "license": "Apache-2.0", "peerDependencies": { - "@dfinity/agent": "^2.0.0", - "@dfinity/candid": "^2.0.0", - "@dfinity/principal": "^2.0.0", - "@dfinity/utils": "^2.7.1" + "@dfinity/agent": "*", + "@dfinity/candid": "*", + "@dfinity/principal": "*", + "@dfinity/utils": "*" } }, "node_modules/@dfinity/eslint-config-oisy-wallet": { @@ -11126,9 +11126,9 @@ "requires": {} }, "@dfinity/cmc": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@dfinity/cmc/-/cmc-4.0.2.tgz", - "integrity": "sha512-RBf/Kl+LNxKWudOBawU7ZLrY+s0DAjL9P1+sap199isrL68eRSOhxm53DPBATF9oUJ2VzSYr0X49mvC0vCyO+Q==", + "version": "4.0.2-next-2024-12-04", + "resolved": "https://registry.npmjs.org/@dfinity/cmc/-/cmc-4.0.2-next-2024-12-04.tgz", + "integrity": "sha512-/z3kb5GvUtPbI0OHTTv3VnG9R7vuAGM4HMMKcneeJXObciJZD49jbNuEAz+3B3KZ2/FjPPDUkxu4hE4ZtjValw==", "requires": {} }, "@dfinity/eslint-config-oisy-wallet": { diff --git a/package.json b/package.json index 54d871bda..3d855c091 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "@dfinity/agent": "^2.1.3", "@dfinity/auth-client": "^2.1.3", "@dfinity/candid": "^2.1.3", - "@dfinity/cmc": "^4.0.2", + "@dfinity/cmc": "^4.0.2-next-2024-12-04", "@dfinity/ic-management": "^6.0.1", "@dfinity/identity": "^2.1.3", "@dfinity/ledger-icp": "^2.6.4", diff --git a/scripts/cmc.subnets.mjs b/scripts/cmc.subnets.mjs index a9aa7afa3..7311758f7 100755 --- a/scripts/cmc.subnets.mjs +++ b/scripts/cmc.subnets.mjs @@ -1,7 +1,7 @@ #!/usr/bin/env node import { CMCCanister } from '@dfinity/cmc'; -import { jsonReplacer } from '@dfinity/utils'; +import { jsonReplacer, nonNullish } from '@dfinity/utils'; import { existsSync, mkdirSync, writeFileSync } from 'node:fs'; import { join } from 'node:path'; import { icAnonymousAgent } from './actor.mjs'; @@ -13,7 +13,12 @@ if (!existsSync(DATA_FOLDER)) { mkdirSync(DATA_FOLDER, { recursive: true }); } -const listSubnets = async () => { +/** + * The list of subnets used by the CMC to create canisters randomly if no parameters are provided when creating a canister. + * Which means that these are subnets that can also be used if a developer wants to specify a particular subnet. + * @returns {Promise} + */ +const listSubnetIds = async () => { const agent = await icAnonymousAgent(); const { getDefaultSubnets } = CMCCanister.create({ @@ -24,14 +29,74 @@ const listSubnets = async () => { return await getDefaultSubnets({ certified: true }); }; -const writeSubnets = (subnets) => { - const subnetsList = subnets.map((principal) => ({ - subnetId: principal.toText() - })); +/** + * The list of subnets supported by the CMC to create canisters only if specified, + * i.e., those subnets are not used when creating a canister in a random subnet. + * @returns {Promise} + */ +const listSpecifiedSubnetIds = async () => { + const agent = await icAnonymousAgent(); + + const { getSubnetTypesToSubnets } = CMCCanister.create({ + agent, + canisterId: CMC_ID + }); - writeFileSync(join(DATA_FOLDER, 'subnets.json'), JSON.stringify(subnetsList, jsonReplacer, 8)); + return await getSubnetTypesToSubnets({ certified: true }); }; -const subnets = await listSubnets(); +/** + * The Dashboard API provides some information about the subnets, like their type and also statistics. + * @returns {Promise} + */ +const listSubnets = async () => { + const response = await fetch('https://ic-api.internetcomputer.org/api/v3/subnets'); + + if (!response.ok) { + throw new Error('Fetching the Dashboard API failed!'); + } + + return await response.json(); +}; + +const writeSubnets = (subnets) => { + writeFileSync(join(DATA_FOLDER, 'subnets.json'), JSON.stringify(subnets, jsonReplacer, 8)); +}; + +// CMC.get_default_subnets +const subnetIds = await listSubnetIds(); + +// CMC.get_subnet_types_to_subnets +const { data: specifiedSubnetIds } = await listSpecifiedSubnetIds(); + +// Metadata from the dashboard API +const { subnets: subnetsMetadata } = await listSubnets(); + +const subnets = [ + ...subnetIds.map((subnetId) => ({ subnetId })), + ...specifiedSubnetIds.flatMap(([specialization, subnetIds]) => + subnetIds.map((subnetId) => ({ subnetId, specialization })) + ) +].map(({ subnetId: sId, specialization }) => { + const subnetId = sId.toText(); + const metadata = subnetsMetadata.find(({ subnet_id }) => subnet_id === subnetId); + + return { + subnetId, + ...(nonNullish(specialization) && { specialization }), + ...(nonNullish(metadata) && { + // The dashboard was instructed long ago to display verified_application as application + type: metadata.subnet_type === 'verified_application' ? 'application' : metadata.subnet_type, + canisters: { + stopped: metadata.stopped_canisters, + running: metadata.running_canisters + }, + nodes: { + up: metadata.up_nodes, + total: metadata.total_nodes + } + }) + }; +}); writeSubnets(subnets); diff --git a/src/frontend/src/lib/env/subnets.json b/src/frontend/src/lib/env/subnets.json index fb2354697..4cb67a5c8 100644 --- a/src/frontend/src/lib/env/subnets.json +++ b/src/frontend/src/lib/env/subnets.json @@ -1,53 +1,208 @@ [ { - "subnetId": "3hhby-wmtmw-umt4t-7ieyg-bbiig-xiylg-sblrt-voxgt-bqckd-a75bf-rqe" - }, - { - "subnetId": "4ecnw-byqwz-dtgss-ua2mh-pfvs7-c3lct-gtf4e-hnu75-j7eek-iifqm-sqe" - }, - { - "subnetId": "6pbhf-qzpdk-kuqbr-pklfa-5ehhf-jfjps-zsj6q-57nrl-kzhpd-mu7hc-vae" - }, - { - "subnetId": "brlsh-zidhj-3yy3e-6vqbz-7xnih-xeq2l-as5oc-g32c4-i5pdn-2wwof-oae" - }, - { - "subnetId": "cv73p-6v7zi-u67oy-7jc3h-qspsz-g5lrj-4fn7k-xrax3-thek2-sl46v-jae" - }, - { - "subnetId": "e66qm-3cydn-nkf4i-ml4rb-4ro6o-srm5s-x5hwq-hnprz-3meqp-s7vks-5qe" - }, - { - "subnetId": "fuqsr-in2lc-zbcjj-ydmcw-pzq7h-4xm2z-pto4i-dcyee-5z4rz-x63ji-nae" - }, - { - "subnetId": "gmq5v-hbozq-uui6y-o55wc-ihop3-562wb-3qspg-nnijg-npqp5-he3cj-3ae" - }, - { - "subnetId": "jtdsg-3h6gi-hs7o5-z2soi-43w3z-soyl3-ajnp3-ekni5-sw553-5kw67-nqe" - }, - { - "subnetId": "lspz2-jx4pu-k3e7p-znm7j-q4yum-ork6e-6w4q6-pijwq-znehu-4jabe-kqe" - }, - { - "subnetId": "mpubz-g52jc-grhjo-5oze5-qcj74-sex34-omprz-ivnsm-qvvhr-rfzpv-vae" - }, - { - "subnetId": "nl6hn-ja4yw-wvmpy-3z2jx-ymc34-pisx3-3cp5z-3oj4a-qzzny-jbsv3-4qe" - }, - { - "subnetId": "o3ow2-2ipam-6fcjo-3j5vt-fzbge-2g7my-5fz2m-p4o2t-dwlc4-gt2q7-5ae" - }, - { - "subnetId": "opn46-zyspe-hhmyp-4zu6u-7sbrh-dok77-m7dch-im62f-vyimr-a3n2c-4ae" - }, - { - "subnetId": "pjljw-kztyl-46ud4-ofrj6-nzkhm-3n4nt-wi3jt-ypmav-ijqkt-gjf66-uae" - }, - { - "subnetId": "qdvhd-os4o2-zzrdw-xrcv4-gljou-eztdp-bj326-e6jgr-tkhuc-ql6v2-yqe" - }, - { - "subnetId": "yinp6-35cfo-wgcd2-oc4ty-2kqpf-t4dul-rfk33-fsq3r-mfmua-m2ngh-jqe" + "subnetId": "4ecnw-byqwz-dtgss-ua2mh-pfvs7-c3lct-gtf4e-hnu75-j7eek-iifqm-sqe", + "type": "application", + "canisters": { + "stopped": 112, + "running": 6717 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "4zbus-z2bmt-ilreg-xakz4-6tyre-hsqj4-slb4g-zjwqo-snjcc-iqphi-3qe", + "type": "application", + "canisters": { + "stopped": 1, + "running": 111 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "brlsh-zidhj-3yy3e-6vqbz-7xnih-xeq2l-as5oc-g32c4-i5pdn-2wwof-oae", + "type": "application", + "canisters": { + "stopped": 28, + "running": 32822 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "cv73p-6v7zi-u67oy-7jc3h-qspsz-g5lrj-4fn7k-xrax3-thek2-sl46v-jae", + "type": "application", + "canisters": { + "stopped": 176, + "running": 50860 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "e66qm-3cydn-nkf4i-ml4rb-4ro6o-srm5s-x5hwq-hnprz-3meqp-s7vks-5qe", + "type": "application", + "canisters": { + "stopped": 83, + "running": 35335 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "fuqsr-in2lc-zbcjj-ydmcw-pzq7h-4xm2z-pto4i-dcyee-5z4rz-x63ji-nae", + "type": "application", + "canisters": { + "stopped": 0, + "running": 19857 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "gmq5v-hbozq-uui6y-o55wc-ihop3-562wb-3qspg-nnijg-npqp5-he3cj-3ae", + "type": "application", + "canisters": { + "stopped": 49, + "running": 33539 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "jtdsg-3h6gi-hs7o5-z2soi-43w3z-soyl3-ajnp3-ekni5-sw553-5kw67-nqe", + "type": "application", + "canisters": { + "stopped": 3, + "running": 26775 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "lspz2-jx4pu-k3e7p-znm7j-q4yum-ork6e-6w4q6-pijwq-znehu-4jabe-kqe", + "type": "application", + "canisters": { + "stopped": 86, + "running": 39354 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "mpubz-g52jc-grhjo-5oze5-qcj74-sex34-omprz-ivnsm-qvvhr-rfzpv-vae", + "type": "application", + "canisters": { + "stopped": 88, + "running": 54876 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "nl6hn-ja4yw-wvmpy-3z2jx-ymc34-pisx3-3cp5z-3oj4a-qzzny-jbsv3-4qe", + "type": "application", + "canisters": { + "stopped": 33, + "running": 31138 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "o3ow2-2ipam-6fcjo-3j5vt-fzbge-2g7my-5fz2m-p4o2t-dwlc4-gt2q7-5ae", + "type": "application", + "canisters": { + "stopped": 55, + "running": 56166 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "opn46-zyspe-hhmyp-4zu6u-7sbrh-dok77-m7dch-im62f-vyimr-a3n2c-4ae", + "type": "application", + "canisters": { + "stopped": 44, + "running": 39369 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "pjljw-kztyl-46ud4-ofrj6-nzkhm-3n4nt-wi3jt-ypmav-ijqkt-gjf66-uae", + "type": "application", + "canisters": { + "stopped": 63, + "running": 31676 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "qdvhd-os4o2-zzrdw-xrcv4-gljou-eztdp-bj326-e6jgr-tkhuc-ql6v2-yqe", + "type": "application", + "canisters": { + "stopped": 15, + "running": 52409 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "bkfrj-6k62g-dycql-7h53p-atvkj-zg4to-gaogh-netha-ptybj-ntsgw-rqe", + "specialization": "european", + "type": "application", + "canisters": { + "stopped": 6, + "running": 22789 + }, + "nodes": { + "up": 13, + "total": 13 + } + }, + { + "subnetId": "pzp6e-ekpqk-3c5x7-2h6so-njoeq-mt45d-h3h6c-q3mxf-vpeq5-fk5o7-yae", + "specialization": "fiduciary", + "type": "application", + "canisters": { + "stopped": 7, + "running": 716 + }, + "nodes": { + "up": 34, + "total": 34 + } } ]