difftreelog
Merge pull request #852 from UniqueNetwork/feat/improvements-to-identity-setter
in: master
3 files changed
tests/package.jsondiffbeforeafterboth32 "fix": "eslint --ext .ts,.js src/ --fix",32 "fix": "eslint --ext .ts,.js src/ --fix",33 "setup": "ts-node ./src/util/globalSetup.ts",33 "setup": "ts-node ./src/util/globalSetup.ts",34 "setIdentities": "ts-node ./src/util/identitySetter.ts",34 "setIdentities": "ts-node ./src/util/identitySetter.ts",35 "checkRelayIdentities": "ts-node ./src/util/relayIdentitiesChecker.ts",35 "test": "yarn setup && mocha --timeout 9999999 -r ts-node/register './src/**/*.*test.ts'",36 "test": "yarn setup && mocha --timeout 9999999 -r ts-node/register './src/**/*.*test.ts'",36 "testParallelFull": "yarn testParallel && yarn testSequential",37 "testParallelFull": "yarn testParallel && yarn testSequential",37 "testParallel": "yarn setup && mocha --parallel --timeout 9999999 -r ts-node/register './src/**/*.test.ts'",38 "testParallel": "yarn setup && mocha --parallel --timeout 9999999 -r ts-node/register './src/**/*.test.ts'",tests/src/util/identitySetter.tsdiffbeforeafterboth1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.1// Copyright 2019-2022 Unique Network (Gibraltar) Ltd.2// SPDX-License-Identifier: Apache-2.02// SPDX-License-Identifier: Apache-2.03//4// Pulls identities and sub-identities from a chain and then uses sudo to force upload them into another.5// Only changed or previously non-existent data are inserted.3//6//4// Usage: `yarn setIdentities [relay WS URL] [parachain WS URL] [sudo key]`7// Usage: `yarn setIdentities [relay WS URL] [parachain WS URL] [sudo key]`5// Example: `yarn setIdentities wss://polkadot-rpc.dwellir.com ws://localhost:9944 escape pattern miracle train sudden cart adapt embark wedding alien lamp mesh`8// Example: `yarn setIdentities wss://polkadot-rpc.dwellir.com ws://localhost:9944 escape pattern miracle train sudden cart adapt embark wedding alien lamp mesh`12const paraUrl = process.argv[3] ?? 'ws://localhost:9944';15const paraUrl = process.argv[3] ?? 'ws://localhost:9944';13const key = process.argv.length > 4 ? process.argv.slice(4).join(' ') : '//Alice';16const key = process.argv.length > 4 ? process.argv.slice(4).join(' ') : '//Alice';141715function extractAccountId(key: any): string {18export function extractAccountId(key: any): string {16 return (key as any).toHuman()[0];19 return (key as any).toHuman()[0];17}20}2122export function extractIdentityInfo(value: any): object {23 const heart = (value as any).unwrap();24 const identity = heart.toJSON();25 identity.judgements = heart.judgements.toHuman();26 return identity;27}182819function extractIdentity(key: any, value: any): [string, any] {29export function extractIdentity(key: any, value: any): [string, any] {20 return [extractAccountId(key), (value as any).unwrap()];30 return [extractAccountId(key), extractIdentityInfo(value)];21}31}223223async function getIdentities(helper: ChainHelperBase, noneCasePredicate?: (key: any, value: any) => void) {33export async function getIdentities(helper: ChainHelperBase, noneCasePredicate?: (key: any, value: any) => void) {24 const identities: [string, any][] = [];34 const identities: [string, any][] = [];25 for(const [key, v] of await helper.getApi().query.identity.identityOf.entries()) {35 for(const [key, v] of await helper.getApi().query.identity.identityOf.entries()) {26 const value = v as any;36 const value = v as any;33 return identities;43 return identities;34}44}354546// whether the existing chain data is more important than the coming47function isCurrentChainDataPriority(helper: ChainHelperBase, currentChainId: number | undefined, relayChainId: number) {48 if (!currentChainId) return false;49 // information has come from local chain, and is automatically superior50 if (currentChainId == helper.chain.getChainProperties().ss58Format) return true;51 // the lower the id, the more important it is (Polkadot has ss58 prefix = 0, Kusama has ss58 prefix = 2)52 return currentChainId < relayChainId;53}5455// construct an object with all data necessary for insertion from storage query results36function constructSubInfo(identityAccount: string, subQuery: any, supers: any[], ss58?: number): [string, any] {56export function constructSubInfo(identityAccount: string, subQuery: any, supers: any[], ss58?: number): [string, any] {37 const deposit = subQuery.toJSON()[0];57 const deposit = subQuery.toJSON()[0];38 const subIdentities = subQuery.toHuman()[1];58 const subIdentities = subQuery.toHuman()[1];39 subIdentities.map((sub: string) => supers.find((sup: any) => sup[0] === sub));59 subIdentities.map((sub: string) => supers.find((sup: any) => sup[0] === sub));40 // supers.find((x: any) => x[0] === subIdentities[0])![1].toHuman();6041 return [61 return [42 encodeAddress(identityAccount, ss58), [62 encodeAddress(identityAccount, ss58), [43 deposit,63 deposit,44 subIdentities.map((sub: string) => [64 subIdentities.map((sub: string): [string, object] | null => {45 encodeAddress(sub, ss58),46 supers.find((sup: any) => sup[0] === sub)![1].toJSON()[1],65 const sup = supers.find((sup: any) => sup[0] === sub);66 if (!sup) {67 console.error(`Error: Could not find info on super for \nsub-identity account\t${sub} of \nsuper account \t\t${identityAccount}, skipping.`);68 return null;69 }70 return [encodeAddress(sub, ss58), sup[1].toJSON()[1]];47 ]),71 }).filter((x: any) => x),48 ],72 ],49 ];73 ];50}74}517552async function getSubs(helper: ChainHelperBase) {76export async function getSubs(helper: ChainHelperBase) {53 return (await helper.getApi().query.identity.subsOf.entries()).map(([key, value]) => [extractAccountId(key), value as any]);77 return (await helper.getApi().query.identity.subsOf.entries()).map(([key, value]) => [extractAccountId(key), value as any]);54}78}557956async function getSupers(helper: ChainHelperBase) {80export async function getSupers(helper: ChainHelperBase) {57 return (await helper.getApi().query.identity.superOf.entries()).map(([key, value]) => [extractAccountId(key), value as any]);81 return (await helper.getApi().query.identity.superOf.entries()).map(([key, value]) => [extractAccountId(key), value as any]);58}82}598360// The utility for pulling identity and sub-identity data84// The utility for pulling identity and sub-identity data61const forceInsertIdentities = async (): Promise<void> => {85const forceInsertIdentities = async (): Promise<void> => {86 let relaySS58Prefix = 0;62 const identitiesOnRelay: any[] = [];87 const identitiesOnRelay: any[] = [];63 const subsOnRelay: any[] = [];88 const subsOnRelay: any[] = [];64 const identitiesToRemove: string[] = [];89 const identitiesToRemove: string[] = [];65 await usingPlaygrounds(async helper => {90 await usingPlaygrounds(async helper => {66 try {91 try {92 relaySS58Prefix = helper.chain.getChainProperties().ss58Format;67 // iterate over every identity93 // iterate over every identity68 for(const [key, value] of await getIdentities(helper, (key, _value) => identitiesToRemove.push((key as any).toHuman()[0]))) {94 for(const [key, value] of await getIdentities(helper, (key, _value) => identitiesToRemove.push((key as any).toHuman()[0]))) {69 // if any of the judgements resulted in a good confirmed outcome, keep this identity95 // if any of the judgements resulted in a good confirmed outcome, keep this identity96 let knownGood = false, reasonable = false;70 if (value.toHuman().judgements.filter((x: any) => x[1] == 'Reasonable' || x[1] == 'KnownGood').length == 0) continue;97 for (const [_id, judgement] of value.judgements) {98 if (judgement == 'KnownGood') knownGood = true;99 if (judgement == 'Reasonable') reasonable = true;100 }101 if (!(reasonable || knownGood)) continue;102 // replace the registrator id with the relay chain's ss58 format103 value.judgements = [[helper.chain.getChainProperties().ss58Format, knownGood ? 'KnownGood' : 'Reasonable']];71 identitiesOnRelay.push([key, value]);104 identitiesOnRelay.push([key, value]);72 }105 }73106100 const ss58Format = helper.chain.getChainProperties().ss58Format;133 const ss58Format = helper.chain.getChainProperties().ss58Format;101 const paraIdentities = await getIdentities(helper);134 const paraIdentities = await getIdentities(helper);102 const identitiesToAdd: any[] = [];135 const identitiesToAdd: any[] = [];136 const paraAccountsRegistrators: {[name: string]: number} = {};103137104 // cross-reference every account for changes138 // cross-reference every account for changes105 for (const [key, value] of identitiesOnRelay) {139 for (const [key, value] of identitiesOnRelay) {106 const encodedKey = encodeAddress(key, ss58Format);140 const encodedKey = encodeAddress(key, ss58Format);107141142 // only update if the identity info does not exist or is changed108 const identity = paraIdentities.find(i => i[0] === encodedKey);143 const identity = paraIdentities.find(i => i[0] === encodedKey);109 if (identity) {144 if (identity) {110 // only update if the identity info does not exist or is changed145 const registratorId = identity[1].judgements[0][0];146 paraAccountsRegistrators[encodedKey] = registratorId;111 if (JSON.stringify(value) === JSON.stringify(identity[1])) {147 if (isCurrentChainDataPriority(helper, registratorId, value.judgements[0][0])148 || JSON.stringify(value.info) === JSON.stringify(identity[1].info)) {112 continue;149 continue;113 }150 }114 }151 }119 // identitiesToRemove.push((key as any).toHuman()[0]);157 // identitiesToRemove.push((key as any).toHuman()[0]);120 }158 }121122 const paraSubs = await getSubs(helper);123 const supersOfSubs = await getSupers(helper);124 const subsToUpdate: any[] = [];125159126 if (identitiesToRemove.length != 0)160 if (identitiesToRemove.length != 0)127 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceRemoveIdentities', [identitiesToRemove]);161 await helper.getSudo().executeExtrinsic(superuser, 'api.tx.identity.forceRemoveIdentities', [identitiesToRemove]);132 + ` and found ${identitiesToRemove.length} identities for potential removal.`166 + ` and found ${identitiesToRemove.length} identities for potential removal.`133 + ` Now there are ${(await helper.getApi().query.identity.identityOf.keys()).length}.`);167 + ` Now there are ${(await helper.getApi().query.identity.identityOf.keys()).length}.`);168169 // fill sub-identities170 const paraSubs = await getSubs(helper);171 const supersOfSubs = await getSupers(helper);172 const subsToUpdate: any[] = [];134173135 for (const [key, value] of subsOnRelay) {174 for (const [key, value] of subsOnRelay) {136 const encodedKey = encodeAddress(key, ss58Format);175 const encodedKey = encodeAddress(key, ss58Format);137 const sub = paraSubs.find(i => i[0] === encodedKey);176 const sub = paraSubs.find(i => i[0] === encodedKey);138 if (sub) {177 if (sub) {139 // only update if the sub-identity info does not exist or is changed178 // only update if the sub-identity info does not exist or is changed140 if (JSON.stringify(value) === JSON.stringify(constructSubInfo(sub[0], sub[1], supersOfSubs)[1])) {179 if (isCurrentChainDataPriority(helper, paraAccountsRegistrators[encodedKey], relaySS58Prefix)180 || JSON.stringify(value) === JSON.stringify(constructSubInfo(sub[0], sub[1], supersOfSubs)[1])) {141 continue;181 continue;142 }182 }143 }183 } else if (value[1].length == 0)184 continue;185144 subsToUpdate.push([key, value]);186 subsToUpdate.push([key, value]);145 }187 }156 }, paraUrl);198 }, paraUrl);157};199};158200201if (process.argv[1] === module.filename)159forceInsertIdentities().catch(() => process.exit(1));202 forceInsertIdentities().catch(() => process.exit(1));203tests/src/util/relayIdentitiesChecker.tsdiffbeforeafterbothno changes