mirror of
https://github.com/Instadapp/trustwallet-assets.git
synced 2024-07-29 22:37:31 +00:00
Checks: multiple errors from a check. (#3990)
Co-authored-by: Catenocrypt <catenocrypt@users.noreply.github.com>
This commit is contained in:
parent
53348b7fff
commit
4eb01f4b8c
|
@ -16,9 +16,9 @@ import { formatSortJson } from "../common/json";
|
||||||
import * as bluebird from "bluebird";
|
import * as bluebird from "bluebird";
|
||||||
import { copyFile } from "fs";
|
import { copyFile } from "fs";
|
||||||
|
|
||||||
async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Promise<[boolean, string, string]> {
|
async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Promise<[boolean, string[], string[]]> {
|
||||||
let errorMsg = "";
|
let errorMsgs: string[] = [];
|
||||||
let warningMsg = "";
|
let warningMsgs: string[] = [];
|
||||||
const assets = getChainAssetsList(chain);
|
const assets = getChainAssetsList(chain);
|
||||||
|
|
||||||
const allowlistPath = getChainAllowlistPath(chain);
|
const allowlistPath = getChainAllowlistPath(chain);
|
||||||
|
@ -31,12 +31,12 @@ async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Pro
|
||||||
|
|
||||||
const commonElementsOrDuplicates = findCommonElementsOrDuplicates(currentAllowlist, currentDenylist);
|
const commonElementsOrDuplicates = findCommonElementsOrDuplicates(currentAllowlist, currentDenylist);
|
||||||
if (commonElementsOrDuplicates && commonElementsOrDuplicates.length > 0) {
|
if (commonElementsOrDuplicates && commonElementsOrDuplicates.length > 0) {
|
||||||
errorMsg += `Denylist and allowlist for chain ${chain} should have no common elements or duplicates, found ${commonElementsOrDuplicates.length} ${commonElementsOrDuplicates[0]}\n`;
|
errorMsgs.push(`Denylist and allowlist for chain ${chain} should have no common elements or duplicates, found ${commonElementsOrDuplicates.length} ${commonElementsOrDuplicates[0]}`);
|
||||||
}
|
}
|
||||||
const allowlistOrphan = arrayDiff(currentAllowlist, assets);
|
const allowlistOrphan = arrayDiff(currentAllowlist, assets);
|
||||||
if (allowlistOrphan && allowlistOrphan.length > 0) {
|
if (allowlistOrphan && allowlistOrphan.length > 0) {
|
||||||
// warning only
|
// warning only
|
||||||
warningMsg += `Allowlist for chain ${chain} contains non-exitent assets, found ${allowlistOrphan.length}, ${allowlistOrphan[0]}\n`;
|
warningMsgs.push(`Allowlist for chain ${chain} contains non-exitent assets, found ${allowlistOrphan.length}, ${allowlistOrphan[0]}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const newDeny = makeUnique(currentDenylist.concat(allowlistOrphan));
|
const newDeny = makeUnique(currentDenylist.concat(allowlistOrphan));
|
||||||
|
@ -47,34 +47,34 @@ async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Pro
|
||||||
const wDiff1 = arrayDiffNocase(newAllow, currentAllowlist);
|
const wDiff1 = arrayDiffNocase(newAllow, currentAllowlist);
|
||||||
if (wDiff1.length > 0) {
|
if (wDiff1.length > 0) {
|
||||||
// warning only
|
// warning only
|
||||||
warningMsg += `Some elements are missing from allowlist for chain ${chain}: ${wDiff1.length} ${wDiff1[0]}\n`;
|
warningMsgs.push(`Some elements are missing from allowlist for chain ${chain}: ${wDiff1.length} ${wDiff1[0]}`);
|
||||||
}
|
}
|
||||||
const wDiff2 = arrayDiffNocase(currentAllowlist, newAllow);
|
const wDiff2 = arrayDiffNocase(currentAllowlist, newAllow);
|
||||||
if (wDiff2.length > 0) {
|
if (wDiff2.length > 0) {
|
||||||
// warning only
|
// warning only
|
||||||
warningMsg += `Some elements should be removed from allowlist for chain ${chain}: ${wDiff2.length} ${wDiff2[0]}\n`;
|
warningMsgs.push(`Some elements should be removed from allowlist for chain ${chain}: ${wDiff2.length} ${wDiff2[0]}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const bDiff1 = arrayDiffNocase(newDeny, currentDenylist);
|
const bDiff1 = arrayDiffNocase(newDeny, currentDenylist);
|
||||||
if (bDiff1.length > 0) {
|
if (bDiff1.length > 0) {
|
||||||
warningMsg += `Some elements are missing from denylist for chain ${chain}: ${bDiff1.length} ${bDiff1[0]}\n`;
|
warningMsgs.push(`Some elements are missing from denylist for chain ${chain}: ${bDiff1.length} ${bDiff1[0]}`);
|
||||||
}
|
}
|
||||||
const bDiff2 = arrayDiffNocase(currentDenylist, newDeny);
|
const bDiff2 = arrayDiffNocase(currentDenylist, newDeny);
|
||||||
if (bDiff2.length > 0) {
|
if (bDiff2.length > 0) {
|
||||||
warningMsg += `Some elements should be removed from denylist for chain ${chain}: ${bDiff2.length} ${bDiff2[0]}\n`;
|
warningMsgs.push(`Some elements should be removed from denylist for chain ${chain}: ${bDiff2.length} ${bDiff2[0]}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
// additionally check for nice formatting, sorting:
|
// additionally check for nice formatting, sorting:
|
||||||
const newAllowText = formatSortJson(newAllow);
|
const newAllowText = formatSortJson(newAllow);
|
||||||
const newDenyText = formatSortJson(newDeny);
|
const newDenyText = formatSortJson(newDeny);
|
||||||
if (newAllowText !== currentAllowlistText) {
|
if (newAllowText !== currentAllowlistText) {
|
||||||
warningMsg += `Allowlist for chain ${chain}: not formatted nicely \n`;
|
warningMsgs.push(`Allowlist for chain ${chain}: not formatted nicely `);
|
||||||
}
|
}
|
||||||
if (newDenyText !== currentDenylistText) {
|
if (newDenyText !== currentDenylistText) {
|
||||||
warningMsg += `Denylist for chain ${chain}: not formatted nicely \n`;
|
warningMsgs.push(`Denylist for chain ${chain}: not formatted nicely `);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (errorMsg.length > 0 || warningMsg.length > 0) {
|
if (errorMsgs.length > 0 || warningMsgs.length > 0) {
|
||||||
// sg wrong, may need to fix
|
// sg wrong, may need to fix
|
||||||
if (!checkOnly) {
|
if (!checkOnly) {
|
||||||
// update
|
// update
|
||||||
|
@ -83,7 +83,7 @@ async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Pro
|
||||||
console.log(`Updated allow and denylists for chain ${chain}`);
|
console.log(`Updated allow and denylists for chain ${chain}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [(errorMsg.length == 0 && warningMsg.length == 0), errorMsg, warningMsg];
|
return [(errorMsgs.length == 0 && warningMsgs.length == 0), errorMsgs, warningMsgs];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class Allowlist implements ActionInterface {
|
export class Allowlist implements ActionInterface {
|
||||||
|
@ -98,11 +98,11 @@ export class Allowlist implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return `Allowlist and denylist for ${chain} should be consistent with assets`},
|
getName: () => { return `Allowlist and denylist for ${chain} should be consistent with assets`},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
const [isOK, errorMsg, warningMsg] = await checkUpdateAllowDenyList(chain, true);
|
const [isOK, errorMsgs, warningMsgs] = await checkUpdateAllowDenyList(chain, true);
|
||||||
if (!isOK) {
|
if (!isOK) {
|
||||||
return [errorMsg, warningMsg];
|
return [errorMsgs, warningMsgs];
|
||||||
}
|
}
|
||||||
return ["", ""];
|
return [[], []];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -106,16 +106,16 @@ export class BinanceAction implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return "Binance chain; assets must exist on chain"},
|
getName: () => { return "Binance chain; assets must exist on chain"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors = [];
|
||||||
const tokenSymbols = await retrieveAssetSymbols();
|
const tokenSymbols = await retrieveAssetSymbols();
|
||||||
const assets = readDirSync(getChainAssetsPath(Binance));
|
const assets = readDirSync(getChainAssetsPath(Binance));
|
||||||
assets.forEach(asset => {
|
assets.forEach(asset => {
|
||||||
if (!(tokenSymbols.indexOf(asset) >= 0)) {
|
if (!(tokenSymbols.indexOf(asset) >= 0)) {
|
||||||
error += `Asset ${asset} missing on chain\n`;
|
errors.push(`Asset ${asset} missing on chain`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log(` ${assets.length} assets checked.`);
|
console.log(` ${assets.length} assets checked.`);
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -11,22 +11,22 @@ export class CosmosAction implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return "Cosmos validator assets must have correct format"},
|
getName: () => { return "Cosmos validator assets must have correct format"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const assets = getChainValidatorsAssets(Cosmos);
|
const assets = getChainValidatorsAssets(Cosmos);
|
||||||
const prefix = "cosmosvaloper1";
|
const prefix = "cosmosvaloper1";
|
||||||
const expLength = 52;
|
const expLength = 52;
|
||||||
assets.forEach(addr => {
|
assets.forEach(addr => {
|
||||||
if (!(addr.startsWith(prefix))) {
|
if (!(addr.startsWith(prefix))) {
|
||||||
error += `Address ${addr} should start with '${prefix}'\n`;
|
errors.push(`Address ${addr} should start with '${prefix}'`);
|
||||||
}
|
}
|
||||||
if (addr.length != expLength) {
|
if (addr.length != expLength) {
|
||||||
error += `Address ${addr} should have length ${expLength}\n`;
|
errors.push(`Address ${addr} should have length ${expLength}`);
|
||||||
}
|
}
|
||||||
if (!isLowerCase(addr)) {
|
if (!isLowerCase(addr)) {
|
||||||
error += `Address ${addr} should be in lowercase\n`;
|
errors.push(`Address ${addr} should be in lowercase`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -75,29 +75,29 @@ export class EthForks implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return `Folder structure for chain ${chain} (ethereum fork)`;},
|
getName: () => { return `Folder structure for chain ${chain} (ethereum fork)`;},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const assetsFolder = getChainAssetsPath(chain);
|
const assetsFolder = getChainAssetsPath(chain);
|
||||||
const assetsList = getChainAssetsList(chain);
|
const assetsList = getChainAssetsList(chain);
|
||||||
console.log(` Found ${assetsList.length} assets for chain ${chain}`);
|
console.log(` Found ${assetsList.length} assets for chain ${chain}`);
|
||||||
await bluebird.each(assetsList, async (address) => {
|
await bluebird.each(assetsList, async (address) => {
|
||||||
const assetPath = `${assetsFolder}/${address}`;
|
const assetPath = `${assetsFolder}/${address}`;
|
||||||
if (!isPathExistsSync(assetPath)) {
|
if (!isPathExistsSync(assetPath)) {
|
||||||
error += `Expect directory at path: ${assetPath}\n`;
|
errors.push(`Expect directory at path: ${assetPath}`);
|
||||||
}
|
}
|
||||||
const inChecksum = toChecksum(address, chain);
|
const inChecksum = toChecksum(address, chain);
|
||||||
if (address !== inChecksum) {
|
if (address !== inChecksum) {
|
||||||
error += `Expect asset at path ${assetPath} in checksum: '${inChecksum}'\n`;
|
errors.push(`Expect asset at path ${assetPath} in checksum: '${inChecksum}'`);
|
||||||
}
|
}
|
||||||
const assetLogoPath = getChainAssetLogoPath(chain, address);
|
const assetLogoPath = getChainAssetLogoPath(chain, address);
|
||||||
if (!isPathExistsSync(assetLogoPath)) {
|
if (!isPathExistsSync(assetLogoPath)) {
|
||||||
error += `Missing file at path '${assetLogoPath}'\n`;
|
errors.push(`Missing file at path '${assetLogoPath}'`);
|
||||||
}
|
}
|
||||||
const [isInfoOK, infoMsg] = isAssetInfoOK(chain, address);
|
const [isInfoOK, infoMsg] = isAssetInfoOK(chain, address);
|
||||||
if (!isInfoOK) {
|
if (!isInfoOK) {
|
||||||
error += infoMsg + "\n";
|
errors.push(infoMsg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -27,54 +27,54 @@ export class FoldersFiles implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return "Repository root dir"},
|
getName: () => { return "Repository root dir"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const dirActualFiles = readDirSync(".");
|
const dirActualFiles = readDirSync(".");
|
||||||
dirActualFiles.forEach(file => {
|
dirActualFiles.forEach(file => {
|
||||||
if (!(rootDirAllowedFiles.indexOf(file) >= 0)) {
|
if (!(rootDirAllowedFiles.indexOf(file) >= 0)) {
|
||||||
error += `File "${file}" should not be in root or added to predifined list\n`;
|
errors.push(`File "${file}" should not be in root or added to predifined list`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
getName: () => { return "Chain folders are lowercase, contain only predefined list of files"},
|
getName: () => { return "Chain folders are lowercase, contain only predefined list of files"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
foundChains.forEach(chain => {
|
foundChains.forEach(chain => {
|
||||||
if (!isLowerCase(chain)) {
|
if (!isLowerCase(chain)) {
|
||||||
error += `Chain folder must be in lowercase "${chain}"\n`;
|
errors.push(`Chain folder must be in lowercase "${chain}"`);
|
||||||
}
|
}
|
||||||
getChainFolderFilesList(chain).forEach(file => {
|
getChainFolderFilesList(chain).forEach(file => {
|
||||||
if (!(chainFolderAllowedFiles.indexOf(file) >= 0)) {
|
if (!(chainFolderAllowedFiles.indexOf(file) >= 0)) {
|
||||||
error += `File '${file}' not allowed in chain folder: ${chain}\n`;
|
errors.push(`File '${file}' not allowed in chain folder: ${chain}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
getName: () => { return "Chain folders have logo, and correct size"},
|
getName: () => { return "Chain folders have logo, and correct size"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
await bluebird.each(foundChains, async (chain) => {
|
await bluebird.each(foundChains, async (chain) => {
|
||||||
const chainLogoPath = getChainLogoPath(chain);
|
const chainLogoPath = getChainLogoPath(chain);
|
||||||
if (!isPathExistsSync(chainLogoPath)) {
|
if (!isPathExistsSync(chainLogoPath)) {
|
||||||
error += `File missing at path "${chainLogoPath}"\n`;
|
errors.push(`File missing at path "${chainLogoPath}"`);
|
||||||
}
|
}
|
||||||
const [isOk, error1] = await isLogoOK(chainLogoPath);
|
const [isOk, error1] = await isLogoOK(chainLogoPath);
|
||||||
if (!isOk) {
|
if (!isOk) {
|
||||||
error += error1 + "\n";
|
errors.push(error1);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
getName: () => { return "Asset folders contain only predefined set of files"},
|
getName: () => { return "Asset folders contain only predefined set of files"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
foundChains.forEach(chain => {
|
foundChains.forEach(chain => {
|
||||||
const assetsPath = getChainAssetsPath(chain);
|
const assetsPath = getChainAssetsPath(chain);
|
||||||
if (isPathExistsSync(assetsPath)) {
|
if (isPathExistsSync(assetsPath)) {
|
||||||
|
@ -82,13 +82,13 @@ export class FoldersFiles implements ActionInterface {
|
||||||
const assetFiles = getChainAssetPath(chain, address)
|
const assetFiles = getChainAssetPath(chain, address)
|
||||||
readDirSync(assetFiles).forEach(assetFolderFile => {
|
readDirSync(assetFiles).forEach(assetFolderFile => {
|
||||||
if (!(assetFolderAllowedFiles.indexOf(assetFolderFile) >= 0)) {
|
if (!(assetFolderAllowedFiles.indexOf(assetFolderFile) >= 0)) {
|
||||||
error += `File '${assetFolderFile}' not allowed at this path: ${assetsPath}\n`;
|
errors.push(`File '${assetFolderFile}' not allowed at this path: ${assetsPath}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}) ;
|
}) ;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
// A single check step
|
// A single check step
|
||||||
export interface CheckStepInterface {
|
export interface CheckStepInterface {
|
||||||
getName(): string;
|
getName(): string;
|
||||||
// return [error, warning], null/"" on success
|
// return [errors, warnings]
|
||||||
check(): Promise<[string, string]>;
|
check(): Promise<[string[], string[]]>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// An action for a check, fix, or update, or a combination.
|
// An action for a check, fix, or update, or a combination.
|
||||||
|
|
|
@ -12,17 +12,17 @@ export class JsonAction implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return "Check all JSON files to have valid content"},
|
getName: () => { return "Check all JSON files to have valid content"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const files = [
|
const files = [
|
||||||
...findFiles(chainsPath, 'json'),
|
...findFiles(chainsPath, 'json'),
|
||||||
];
|
];
|
||||||
|
|
||||||
await bluebird.each(files, async file => {
|
await bluebird.each(files, async file => {
|
||||||
if (!isValidJSON(file)) {
|
if (!isValidJSON(file)) {
|
||||||
error += `${file} path contains invalid JSON\n`;
|
errors.push(`${file} path contains invalid JSON`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -11,22 +11,22 @@ export class KavaAction implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return "Kava validator assets must have correct format"},
|
getName: () => { return "Kava validator assets must have correct format"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const assets = getChainValidatorsAssets(Kava);
|
const assets = getChainValidatorsAssets(Kava);
|
||||||
const prefix = "kavavaloper1";
|
const prefix = "kavavaloper1";
|
||||||
const expLength = 50;
|
const expLength = 50;
|
||||||
assets.forEach(addr => {
|
assets.forEach(addr => {
|
||||||
if (!(addr.startsWith(prefix))) {
|
if (!(addr.startsWith(prefix))) {
|
||||||
error += `Address ${addr} should start with '${prefix}'\n`;
|
errors.push(`Address ${addr} should start with '${prefix}'`);
|
||||||
}
|
}
|
||||||
if (addr.length != expLength) {
|
if (addr.length != expLength) {
|
||||||
error += `Address ${addr} should have length ${expLength}\n`;
|
errors.push(`Address ${addr} should have length ${expLength}`);
|
||||||
}
|
}
|
||||||
if (!isLowerCase(addr)) {
|
if (!isLowerCase(addr)) {
|
||||||
error += `Address ${addr} should be in lowercase\n`;
|
errors.push(`Address ${addr} should be in lowercase`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -16,12 +16,12 @@ import { checkResizeIfTooLarge } from "../common/image";
|
||||||
import { ActionInterface, CheckStepInterface } from "./interface";
|
import { ActionInterface, CheckStepInterface } from "./interface";
|
||||||
|
|
||||||
// return name of large logo, or empty
|
// return name of large logo, or empty
|
||||||
async function checkDownsize(chains, checkOnly: boolean): Promise<string> {
|
async function checkDownsize(chains, checkOnly: boolean): Promise<string[]> {
|
||||||
console.log(`Checking all logos for size ...`);
|
console.log(`Checking all logos for size ...`);
|
||||||
let totalCountChecked: number = 0;
|
let totalCountChecked: number = 0;
|
||||||
let totalCountTooLarge: number = 0;
|
let totalCountTooLarge: number = 0;
|
||||||
let totalCountUpdated: number = 0;
|
let totalCountUpdated: number = 0;
|
||||||
let largePath = "";
|
let largePaths: string[] = [];
|
||||||
await bluebird.map(chains, async chain => {
|
await bluebird.map(chains, async chain => {
|
||||||
let countChecked: number = 0;
|
let countChecked: number = 0;
|
||||||
let countTooLarge: number = 0;
|
let countTooLarge: number = 0;
|
||||||
|
@ -30,7 +30,7 @@ async function checkDownsize(chains, checkOnly: boolean): Promise<string> {
|
||||||
const path = getChainLogoPath(chain);
|
const path = getChainLogoPath(chain);
|
||||||
countChecked++;
|
countChecked++;
|
||||||
const [tooLarge, updated] = await checkResizeIfTooLarge(path, checkOnly);
|
const [tooLarge, updated] = await checkResizeIfTooLarge(path, checkOnly);
|
||||||
if (tooLarge) { largePath = path; }
|
if (tooLarge) { largePaths.push(path); }
|
||||||
countTooLarge += tooLarge ? 1 : 0;
|
countTooLarge += tooLarge ? 1 : 0;
|
||||||
countUpdated += updated ? 1 : 0;
|
countUpdated += updated ? 1 : 0;
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ async function checkDownsize(chains, checkOnly: boolean): Promise<string> {
|
||||||
const path = getChainAssetLogoPath(chain, asset);
|
const path = getChainAssetLogoPath(chain, asset);
|
||||||
countChecked++;
|
countChecked++;
|
||||||
const [tooLarge, updated] = await checkResizeIfTooLarge(path, checkOnly);
|
const [tooLarge, updated] = await checkResizeIfTooLarge(path, checkOnly);
|
||||||
if (tooLarge) { largePath = path; }
|
if (tooLarge) { largePaths.push(path); }
|
||||||
countTooLarge += tooLarge ? 1 : 0;
|
countTooLarge += tooLarge ? 1 : 0;
|
||||||
countUpdated += updated ? 1 : 0;
|
countUpdated += updated ? 1 : 0;
|
||||||
})
|
})
|
||||||
|
@ -55,7 +55,7 @@ async function checkDownsize(chains, checkOnly: boolean): Promise<string> {
|
||||||
const path = getChainValidatorAssetLogoPath(chain, id);
|
const path = getChainValidatorAssetLogoPath(chain, id);
|
||||||
countChecked++;
|
countChecked++;
|
||||||
const [tooLarge, updated] = await checkResizeIfTooLarge(path, checkOnly);
|
const [tooLarge, updated] = await checkResizeIfTooLarge(path, checkOnly);
|
||||||
if (tooLarge) { largePath = path; }
|
if (tooLarge) { largePaths.push(path); }
|
||||||
countTooLarge += tooLarge ? 1 : 0;
|
countTooLarge += tooLarge ? 1 : 0;
|
||||||
countUpdated += updated ? 1 : 0;
|
countUpdated += updated ? 1 : 0;
|
||||||
})
|
})
|
||||||
|
@ -65,11 +65,11 @@ async function checkDownsize(chains, checkOnly: boolean): Promise<string> {
|
||||||
totalCountTooLarge += countTooLarge;
|
totalCountTooLarge += countTooLarge;
|
||||||
totalCountUpdated += countUpdated;
|
totalCountUpdated += countUpdated;
|
||||||
if (countTooLarge > 0 || countUpdated > 0) {
|
if (countTooLarge > 0 || countUpdated > 0) {
|
||||||
console.log(`Checking logos on chain ${chain} completed, ${countChecked} checked, ${countTooLarge} too large, ${largePath}, ${countUpdated} logos updated`);
|
console.log(`Checking logos on chain ${chain} completed, ${countChecked} checked, ${countTooLarge} too large, ${largePaths}, ${countUpdated} logos updated`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
console.log(`Checking logos completed, ${totalCountChecked} logos checked, ${totalCountTooLarge} too large, ${totalCountUpdated} logos updated`);
|
console.log(`Checking logos completed, ${totalCountChecked} logos checked, ${totalCountTooLarge} too large, ${totalCountUpdated} logos updated`);
|
||||||
return largePath;
|
return largePaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LogoSize implements ActionInterface {
|
export class LogoSize implements ActionInterface {
|
||||||
|
@ -81,11 +81,9 @@ export class LogoSize implements ActionInterface {
|
||||||
getName: () => { return "Check that logos are not too large"},
|
getName: () => { return "Check that logos are not too large"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
const foundChains = readDirSync(chainsPath);
|
const foundChains = readDirSync(chainsPath);
|
||||||
var largePath = await checkDownsize(foundChains, true);
|
const largePaths = await checkDownsize(foundChains, true);
|
||||||
if (largePath.length > 0) {
|
const errors: string[] = largePaths.map(p => `Logo too large: ${p}`);
|
||||||
return [`Found at least one logo that is too large: ${largePath}`, ""];
|
return [errors, []];
|
||||||
}
|
|
||||||
return ["", ""];
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -11,22 +11,22 @@ export class TerraAction implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return "Terra validator assets must have correct format"},
|
getName: () => { return "Terra validator assets must have correct format"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const assets = getChainValidatorsAssets(Terra);
|
const assets = getChainValidatorsAssets(Terra);
|
||||||
const prefix = "terravaloper1";
|
const prefix = "terravaloper1";
|
||||||
const expLength = 51;
|
const expLength = 51;
|
||||||
assets.forEach(addr => {
|
assets.forEach(addr => {
|
||||||
if (!(addr.startsWith(prefix))) {
|
if (!(addr.startsWith(prefix))) {
|
||||||
error += `Address ${addr} should start with '${prefix}'\n`;
|
errors.push(`Address ${addr} should start with '${prefix}'`);
|
||||||
}
|
}
|
||||||
if (addr.length != expLength) {
|
if (addr.length != expLength) {
|
||||||
error += `Address ${addr} should have length ${expLength}\n`;
|
errors.push(`Address ${addr} should have length ${expLength}`);
|
||||||
}
|
}
|
||||||
if (!isLowerCase(addr)) {
|
if (!isLowerCase(addr)) {
|
||||||
error += `Address ${addr} should be in lowercase\n`;
|
errors.push(`Address ${addr} should be in lowercase`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -83,14 +83,14 @@ export class TezosAction implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return "Tezos validator assets must have correct format"},
|
getName: () => { return "Tezos validator assets must have correct format"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const assets = getChainValidatorsAssets(Tezos);
|
const assets = getChainValidatorsAssets(Tezos);
|
||||||
assets.forEach(addr => {
|
assets.forEach(addr => {
|
||||||
if (!(eztz.crypto.checkAddress(addr))) {
|
if (!(eztz.crypto.checkAddress(addr))) {
|
||||||
error += `Address ${addr} must be valid Tezos address'\n`;
|
errors.push(`Address ${addr} must be valid Tezos address'`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
|
@ -25,32 +25,32 @@ export class TronAction implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return "Tron assets should be TRC10 or TRC20, logo of correct size"; },
|
getName: () => { return "Tron assets should be TRC10 or TRC20, logo of correct size"; },
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const path = getChainAssetsPath(Tron);
|
const path = getChainAssetsPath(Tron);
|
||||||
const assets = readDirSync(path);
|
const assets = readDirSync(path);
|
||||||
await bluebird.each(assets, async (asset) => {
|
await bluebird.each(assets, async (asset) => {
|
||||||
if (!isTRC10(asset) && !isTRC20(asset)) {
|
if (!isTRC10(asset) && !isTRC20(asset)) {
|
||||||
error += `Asset ${asset} at path '${path}' is not TRC10 nor TRC20\n`;
|
errors.push(`Asset ${asset} at path '${path}' is not TRC10 nor TRC20`);
|
||||||
}
|
}
|
||||||
const assetsLogoPath = getChainAssetLogoPath(Tron, asset);
|
const assetsLogoPath = getChainAssetLogoPath(Tron, asset);
|
||||||
if (!isPathExistsSync(assetsLogoPath)) {
|
if (!isPathExistsSync(assetsLogoPath)) {
|
||||||
error += `Missing file at path '${assetsLogoPath}'\n`;
|
errors.push(`Missing file at path '${assetsLogoPath}'`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
getName: () => { return "Tron validator assets must have correct format"},
|
getName: () => { return "Tron validator assets must have correct format"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const assets = getChainValidatorsAssets(Tron);
|
const assets = getChainValidatorsAssets(Tron);
|
||||||
assets.forEach(addr => {
|
assets.forEach(addr => {
|
||||||
if (!(isTRC20(addr))) {
|
if (!(isTRC20(addr))) {
|
||||||
error += `Address ${addr} should be TRC20 address'\n`;
|
errors.push(`Address ${addr} should be TRC20 address'`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
|
@ -32,30 +32,50 @@ const actionList: ActionInterface[] = [
|
||||||
new WavesAction()
|
new WavesAction()
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const maxErrosFromOneCheck = 5;
|
||||||
|
|
||||||
async function checkStepList(steps: CheckStepInterface[]): Promise<[string[], string[]]> {
|
async function checkStepList(steps: CheckStepInterface[]): Promise<[string[], string[]]> {
|
||||||
var errors: string[] = [];
|
var errorsAll: string[] = [];
|
||||||
var warnings: string[] = [];
|
var warningsAll: string[] = [];
|
||||||
await bluebird.each(steps, async (step) => {
|
await bluebird.each(steps, async (step) => {
|
||||||
try {
|
try {
|
||||||
//console.log(` Running check step '${step.getName()}'...`);
|
//console.log(` Running check step '${step.getName()}'...`);
|
||||||
const [error, warning] = await step.check();
|
const [errors, warnings] = await step.check();
|
||||||
if (error && error.length > 0) {
|
if (errors && errors.length > 0) {
|
||||||
console.log(`- ${chalk.red('X')} '${step.getName()}': '${error}'`);
|
console.log(`- ${chalk.red('X')} '${step.getName()}': ${errors.length} errors`);
|
||||||
errors.push(`${step.getName()}: ${error}`);
|
var cnt = 0;
|
||||||
|
errors.forEach(err => {
|
||||||
|
if (cnt < maxErrosFromOneCheck) {
|
||||||
|
console.log(` ${chalk.red('X')} '${err}'`);
|
||||||
|
errorsAll.push(err);
|
||||||
|
} else if (cnt == maxErrosFromOneCheck) {
|
||||||
|
console.log(` ${chalk.red('X')} ${errors.length} errors in total, omitting rest ...`);
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (warning && warning.length > 0) {
|
if (warnings && warnings.length > 0) {
|
||||||
console.log(`- ${chalk.yellow('!')} '${step.getName()}': '${warning}'`);
|
console.log(`- ${chalk.yellow('!')} '${step.getName()}': ${warnings.length} warnings`);
|
||||||
warnings.push(`${step.getName()}: ${warning}`);
|
var cnt = 0;
|
||||||
|
warnings.forEach(warn => {
|
||||||
|
if (cnt < maxErrosFromOneCheck) {
|
||||||
|
console.log(` ${chalk.yellow('!')} '${warn}'`);
|
||||||
|
warningsAll.push(warn);
|
||||||
|
} else if (cnt == maxErrosFromOneCheck) {
|
||||||
|
console.log(` ${chalk.red('X')} ${warnings.length} warnings in total, omitting rest ...`);
|
||||||
|
}
|
||||||
|
cnt++;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
if (error.length == 0 && warning.length == 0) {
|
if (errors.length == 0 && warnings.length == 0) {
|
||||||
console.log(`- ${chalk.green('✓')} '${step.getName()}' OK`);
|
console.log(`- ${chalk.green('✓')} '${step.getName()}' OK`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`- ${chalk.red('X')} '${step.getName()}': Caught error: ${error.message}`);
|
console.log(`- ${chalk.red('X')} '${step.getName()}': Caught error: ${error.message}`);
|
||||||
errors.push(`${step.getName()}: Exception: ${error.message}`);
|
errorsAll.push(`${step.getName()}: Exception: ${error.message}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [errors, warnings];
|
return [errorsAll, warningsAll];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sanityCheckByActionList(actions: ActionInterface[]): Promise<[string[], string[]]> {
|
async function sanityCheckByActionList(actions: ActionInterface[]): Promise<[string[], string[]]> {
|
||||||
|
|
|
@ -37,11 +37,11 @@ export class Validators implements ActionInterface {
|
||||||
var steps: CheckStepInterface[] = [
|
var steps: CheckStepInterface[] = [
|
||||||
{
|
{
|
||||||
getName: () => { return "Make sure tests added for new staking chain"},
|
getName: () => { return "Make sure tests added for new staking chain"},
|
||||||
check: async (): Promise<[string, string]> => {
|
check: async (): Promise<[string[], string[]]> => {
|
||||||
if (stakingChains.length != 8) {
|
if (stakingChains.length != 8) {
|
||||||
return [`Wrong number of staking chains ${stakingChains.length}`, ""];
|
return [[`Wrong number of staking chains ${stakingChains.length}`], []];
|
||||||
}
|
}
|
||||||
return ["", ""];
|
return [[], []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
@ -49,44 +49,44 @@ export class Validators implements ActionInterface {
|
||||||
steps.push(
|
steps.push(
|
||||||
{
|
{
|
||||||
getName: () => { return `Make sure chain ${chain} has valid list file, has logo`},
|
getName: () => { return `Make sure chain ${chain} has valid list file, has logo`},
|
||||||
check: async () => {
|
check: async (): Promise<[string[], string[]]> => {
|
||||||
const validatorsListPath = getChainValidatorsListPath(chain);
|
const validatorsListPath = getChainValidatorsListPath(chain);
|
||||||
if (!isValidJSON(validatorsListPath)) {
|
if (!isValidJSON(validatorsListPath)) {
|
||||||
return [`Not valid Json file at path ${validatorsListPath}`, ""];
|
return [[`Not valid Json file at path ${validatorsListPath}`], []];
|
||||||
}
|
}
|
||||||
|
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const validatorsList = getChainValidatorsList(chain);
|
const validatorsList = getChainValidatorsList(chain);
|
||||||
const chainValidatorsAssetsList = getChainValidatorsAssets(chain);
|
const chainValidatorsAssetsList = getChainValidatorsAssets(chain);
|
||||||
await bluebird.each(validatorsList, async (val: ValidatorModel) => {
|
await bluebird.each(validatorsList, async (val: ValidatorModel) => {
|
||||||
if (!isValidatorHasAllKeys(val)) {
|
if (!isValidatorHasAllKeys(val)) {
|
||||||
error += `Some key and/or type missing for validator ${JSON.stringify(val)}\n`;
|
errors.push(`Some key and/or type missing for validator ${JSON.stringify(val)}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = val.id;
|
const id = val.id;
|
||||||
const path = getChainValidatorAssetLogoPath(chain, id);
|
const path = getChainValidatorAssetLogoPath(chain, id);
|
||||||
if (!isPathExistsSync(path)) {
|
if (!isPathExistsSync(path)) {
|
||||||
error += `Chain ${chain} asset ${id} logo must be present at path ${path}\n`;
|
errors.push(`Chain ${chain} asset ${id} logo must be present at path ${path}`);
|
||||||
}
|
}
|
||||||
const [isOk, logoMsg] = await isLogoOK(path);
|
const [isOk, logoMsg] = await isLogoOK(path);
|
||||||
if (!isOk) {
|
if (!isOk) {
|
||||||
error += logoMsg + "\n";
|
errors.push(logoMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure validator has corresponding logo
|
// Make sure validator has corresponding logo
|
||||||
if (!(chainValidatorsAssetsList.indexOf(id) >= 0)) {
|
if (!(chainValidatorsAssetsList.indexOf(id) >= 0)) {
|
||||||
error += `Expecting image asset for validator ${id} on chain ${chain}\n`;
|
errors.push(`Expecting image asset for validator ${id} on chain ${chain}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Make sure validator asset logo has corresponding info
|
// Make sure validator asset logo has corresponding info
|
||||||
chainValidatorsAssetsList.forEach(valAssetLogoID => {
|
chainValidatorsAssetsList.forEach(valAssetLogoID => {
|
||||||
if (validatorsList.filter(v => v.id === valAssetLogoID).length != 1) {
|
if (validatorsList.filter(v => v.id === valAssetLogoID).length != 1) {
|
||||||
error += `Expect validator logo ${valAssetLogoID} to have info\n`;
|
errors.push(`Expect validator logo ${valAssetLogoID} to have info`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -18,14 +18,14 @@ export class WavesAction implements ActionInterface {
|
||||||
{
|
{
|
||||||
getName: () => { return "Waves validator assets must have correct format"},
|
getName: () => { return "Waves validator assets must have correct format"},
|
||||||
check: async () => {
|
check: async () => {
|
||||||
var error: string = "";
|
var errors: string[] = [];
|
||||||
const assets = getChainValidatorsAssets(Waves);
|
const assets = getChainValidatorsAssets(Waves);
|
||||||
assets.forEach(addr => {
|
assets.forEach(addr => {
|
||||||
if (!(isWavesAddress(addr))) {
|
if (!(isWavesAddress(addr))) {
|
||||||
error += `Address ${addr} should be a Waves address'\n`;
|
errors.push(`Address ${addr} should be a Waves address'`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return [error, ""];
|
return [errors, []];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
Loading…
Reference in New Issue
Block a user