[internal] Fixes and Checks: separate into consistency and sanity (#3197)

* rename to sanityFix
* Infra for consistency checks and Fixes.
* Whitelist check moved to consistency check only.

Co-authored-by: Catenocrypt <catenocrypt@users.noreply.github.com>
This commit is contained in:
Adam R 2020-08-10 10:56:41 +02:00 committed by GitHub
parent c2807fad5b
commit 294d8bcb5d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 250 additions and 69 deletions

View File

@ -1,9 +1,9 @@
name: Fixes and Consistency Updates - Dry run
name: Fixes (sanity and consistency) - Dry run
on:
pull_request:
branches: [master]
jobs:
fix-dryrun:
fix-all-dryrun:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

View File

@ -1,11 +1,11 @@
name: Fixes and Consistency Updates
name: Fixes
on:
push:
# This runs on fork branches too
branches: [ '*' ]
workflow_dispatch:
jobs:
fix:
fix-all:
runs-on: ubuntu-latest
steps:
- name: Checkout (trustwallet repo, secret token)
@ -25,8 +25,12 @@ jobs:
node-version: 12
- name: Install Dependencies
run: npm ci
- name: Run fix script
- name: Run fix script (trustwallet repo, sanity and consistency)
if: github.repository_owner == 'trustwallet'
run: npm run fix
- name: Run fix script (fork repo, sanity only)
if: github.repository_owner != 'trustwallet'
run: npm run fix-sanity
- name: Show fix result (diff); run 'npm run fix' locally
run: |
git status
@ -42,4 +46,4 @@ jobs:
with:
commit_user_name: trust-wallet-merge-bot
commit_user_email: mergebot@trustwallet.com
commit_message: Fixes and Consistency Updates
commit_message: Fixes (sanity and consistency, auto)

View File

@ -19,9 +19,11 @@ jobs:
run: npm ci
- name: Run scripts
run: npm run update
- name: Show fix result (diff); run 'npm run fix' locally
- name: Show update result (diff)
if: success()
run: git status
run: |
git status
git diff
- name: Run check
run: npm run check
- name: Run test

View File

@ -16,7 +16,7 @@ jobs:
with:
node-version: '12.x'
- uses: bahmutov/npm-install@v1
- name: Run check
run: npm run check
- name: Run check (sanity only)
run: npm run check-sanity
- name: Run test
run: npm t

View File

@ -6,7 +6,9 @@
"scripts": {
"test": "jest",
"check": "ts-node ./script/main/check",
"check-sanity": "ts-node ./script/main/check-sanity",
"fix": "ts-node ./script/main/fix",
"fix-sanity": "ts-node ./script/main/fix-sanity",
"update": "ts-node ./script/main/update"
},
"repository": {

View File

@ -5,7 +5,7 @@ import { isChecksum } from "../../script/common/eth-web3";
import { isTRC10, isTRC20 } from "../../script/action/tron";
import { retrieveAssetSymbols } from "../../script/action/binance";
export function getChecks(): CheckStepInterface[] {
export function getSanityChecks(): CheckStepInterface[] {
const cmcMap: mapTiker[] = JSON.parse(readFileSync("./pricing/coinmarketcap/mapping.json"));
return [
{

View File

@ -1,13 +1,17 @@
import { ActionInterface, CheckStepInterface } from "../../script/action/interface";
import { run } from "./script";
import { getChecks } from "./check";
import { getSanityChecks } from "./check";
export class Coinmarketcap implements ActionInterface {
getName(): string { return "Coinmarketcap mapping"; }
getChecks(): CheckStepInterface[] { return getChecks(); }
getSanityChecks(): CheckStepInterface[] { return getSanityChecks(); }
getConsistencyChecks = null;
fix = null;
sanityFix = null;
consistencyFix = null;
async update(): Promise<void> {
await run();

View File

@ -101,7 +101,7 @@ async function fetchMissingImages(toFetch: any[]): Promise<string[]> {
export class BinanceAction implements ActionInterface {
getName(): string { return "Binance chain"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Binance chain; assets must exist on chain"},
@ -120,8 +120,12 @@ export class BinanceAction implements ActionInterface {
},
];
}
fix = null;
getConsistencyChecks = null;
sanityFix = null;
consistencyFix = null;
async update(): Promise<void> {
// retrieve missing token images; BEP2 (bep8 not supported)

View File

@ -6,7 +6,7 @@ import { isLowerCase } from "../common/types";
export class CosmosAction implements ActionInterface {
getName(): string { return "Cosmos chain"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Cosmos validator assets must have correct format"},
@ -32,7 +32,11 @@ export class CosmosAction implements ActionInterface {
];
}
fix = null;
getConsistencyChecks = null;
sanityFix = null;
consistencyFix = null;
update = null;
}

View File

@ -68,7 +68,7 @@ async function checkAddressChecksums() {
export class EthForks implements ActionInterface {
getName(): string { return "Ethereum forks"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
var steps: CheckStepInterface[] = [];
ethForkChains.forEach(chain => {
steps.push(
@ -105,10 +105,14 @@ export class EthForks implements ActionInterface {
return steps;
}
async fix(): Promise<void> {
getConsistencyChecks = null;
async sanityFix(): Promise<void> {
await formatInfos();
await checkAddressChecksums();
}
consistencyFix = null;
update = null;
}

View File

@ -22,7 +22,7 @@ const foundChains = readDirSync(chainsPath)
export class FoldersFiles implements ActionInterface {
getName(): string { return "Folders and Files"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Repository root dir"},
@ -94,7 +94,11 @@ export class FoldersFiles implements ActionInterface {
];
}
fix = null;
getConsistencyChecks = null;
sanityFix = null;
consistencyFix = null;
update = null;
}

View File

@ -8,8 +8,18 @@ export interface CheckStepInterface {
// An action for a check, fix, or update, or a combination.
export interface ActionInterface {
getName(): string;
// return check steps for check (0, 1, or more)
getChecks(): CheckStepInterface[];
fix(): Promise<void>;
// return check steps for sanity check (0, 1, or more)
getSanityChecks(): CheckStepInterface[];
// return check steps for consistenct check (0, 1, or more)
getConsistencyChecks(): CheckStepInterface[];
sanityFix(): Promise<void>;
consistencyFix(): Promise<void>;
update(): Promise<void>;
}
export enum FixCheckMode {
CheckSanityOnly = 1,
CheckAll,
FixSanityOnly,
FixAll
}

View File

@ -7,7 +7,7 @@ import * as bluebird from "bluebird";
export class JsonAction implements ActionInterface {
getName(): string { return "Json files"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Check all JSON files to have valid content"},
@ -29,7 +29,11 @@ export class JsonAction implements ActionInterface {
];
}
fix = null;
getConsistencyChecks = null;
sanityFix = null;
consistencyFix = null;
update = null;
}

View File

@ -6,7 +6,7 @@ import { isLowerCase } from "../common/types";
export class KavaAction implements ActionInterface {
getName(): string { return "Kava chain"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Kava validator assets must have correct format"},
@ -32,7 +32,11 @@ export class KavaAction implements ActionInterface {
];
}
fix = null;
getConsistencyChecks = null;
sanityFix = null;
consistencyFix = null;
update = null;
}

View File

@ -75,7 +75,7 @@ async function checkDownsize(chains, checkOnly: boolean): Promise<string> {
export class LogoSize implements ActionInterface {
getName(): string { return "Logo sizes"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Check that logos are not too large"},
@ -91,10 +91,14 @@ export class LogoSize implements ActionInterface {
];
}
async fix(): Promise<void> {
getConsistencyChecks = null;
async sanityFix(): Promise<void> {
const foundChains = readDirSync(chainsPath);
await checkDownsize(foundChains, false);
}
consistencyFix = null;
update = null;
}

View File

@ -6,7 +6,7 @@ import { isLowerCase } from "../common/types";
export class TerraAction implements ActionInterface {
getName(): string { return "Terra chain"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Terra validator assets must have correct format"},
@ -32,7 +32,11 @@ export class TerraAction implements ActionInterface {
];
}
fix = null;
getConsistencyChecks = null;
sanityFix = null;
consistencyFix = null;
update = null;
}

View File

@ -78,7 +78,7 @@ async function gen_validators_tezos() {
export class TezosAction implements ActionInterface {
getName(): string { return "Tezos"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Tezos validator assets must have correct format"},
@ -96,7 +96,11 @@ export class TezosAction implements ActionInterface {
];
}
fix = null;
getConsistencyChecks = null;
sanityFix = null;
consistencyFix = null;
async update(): Promise<void> {
await gen_validators_tezos();

View File

@ -20,7 +20,7 @@ export function isTRC20(address: string): boolean {
export class TronAction implements ActionInterface {
getName(): string { return "Tron chain"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Tron assets should be TRC10 or TRC20, logo of correct size"; },
@ -56,7 +56,11 @@ export class TronAction implements ActionInterface {
];
}
fix = null;
getConsistencyChecks = null;
sanityFix = null;
consistencyFix = null;
update = null;
}

View File

@ -54,13 +54,13 @@ async function checkStepList(steps: CheckStepInterface[]): Promise<number> {
return returnCode;
}
async function checkActionList(actions: ActionInterface[]): Promise<number> {
console.log("Running checks...");
async function sanityCheckByActionList(actions: ActionInterface[]): Promise<number> {
console.log("Running sanity checks...");
var returnCode = 0;
await bluebird.each(actions, async (action) => {
try {
if (action.getChecks) {
const steps = action.getChecks();
if (action.getSanityChecks) {
const steps = action.getSanityChecks();
if (steps && steps.length > 0) {
console.log(` Action '${action.getName()}' has ${steps.length} check steps`);
const ret1 = await checkStepList(steps);
@ -76,23 +76,64 @@ async function checkActionList(actions: ActionInterface[]): Promise<number> {
returnCode = 3;
}
});
console.log(`All checks done, returnCode ${returnCode}`);
console.log(`All sanity checks done, returnCode ${returnCode}`);
return returnCode;
}
async function fixByList(actions: ActionInterface[]) {
console.log("Running fixes...");
async function consistencyCheckByActionList(actions: ActionInterface[]): Promise<number> {
console.log("Running consistency checks...");
var returnCode = 0;
await bluebird.each(actions, async (action) => {
try {
if (action.fix) {
console.log(`Fix '${action.getName()}':`);
await action.fix();
if (action.getConsistencyChecks) {
const steps = action.getConsistencyChecks();
if (steps && steps.length > 0) {
console.log(` Action '${action.getName()}' has ${steps.length} check steps`);
const ret1 = await checkStepList(steps);
if (ret1 != 0) {
returnCode = ret1;
} else {
console.log(`- ${chalk.green('✓')} Action '${action.getName()}' OK, all ${steps.length} steps`);
}
}
}
} catch (error) {
console.log(`- ${chalk.red('X')} '${action.getName()}' Caught error: ${error.message}`);
returnCode = 3;
}
});
console.log(`All consistency checks done, returnCode ${returnCode}`);
return returnCode;
}
async function sanityFixByList(actions: ActionInterface[]) {
console.log("Running sanity fixes...");
await bluebird.each(actions, async (action) => {
try {
if (action.sanityFix) {
console.log(`Sanity fix '${action.getName()}':`);
await action.sanityFix();
}
} catch (error) {
console.log(`Caught error: ${error.message}`);
}
});
console.log("All fixes done.");
console.log("All sanity fixes done.");
}
async function consistencyFixByList(actions: ActionInterface[]) {
console.log("Running consistency fixes...");
await bluebird.each(actions, async (action) => {
try {
if (action.consistencyFix) {
console.log(`Sanity fix '${action.getName()}':`);
await action.consistencyFix();
}
} catch (error) {
console.log(`Caught error: ${error.message}`);
}
});
console.log("All consistency fixes done.");
}
async function updateByList(actions: ActionInterface[]) {
@ -110,12 +151,20 @@ async function updateByList(actions: ActionInterface[]) {
console.log("All updates done.");
}
export async function checkAll(): Promise<number> {
return await checkActionList(actionList);
export async function sanityCheckAll(): Promise<number> {
return await sanityCheckByActionList(actionList);
}
export async function fixAll() {
await fixByList(actionList);
export async function consistencyCheckAll(): Promise<number> {
return await consistencyCheckByActionList(actionList);
}
export async function sanityFixAll() {
await sanityFixByList(actionList);
}
export async function consistencyFixAll() {
await consistencyFixByList(actionList);
}
export async function updateAll() {

View File

@ -33,7 +33,7 @@ function isValidatorHasAllKeys(val: ValidatorModel): boolean {
export class Validators implements ActionInterface {
getName(): string { return "Validators"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
var steps = [
{
getName: () => { return "Make sure tests added for new staking chain"},
@ -94,9 +94,13 @@ export class Validators implements ActionInterface {
return steps;
}
async fix(): Promise<void> {
getConsistencyChecks = null;
async sanityFix(): Promise<void> {
formatValidators();
}
consistencyFix = null;
update = null;
}

View File

@ -13,7 +13,7 @@ export function isWavesAddress(address: string): boolean {
export class WavesAction implements ActionInterface {
getName(): string { return "Waves chain"; }
getChecks(): CheckStepInterface[] {
getSanityChecks(): CheckStepInterface[] {
return [
{
getName: () => { return "Waves validator assets must have correct format"},
@ -31,7 +31,11 @@ export class WavesAction implements ActionInterface {
];
}
fix = null;
getConsistencyChecks = null;
sanityFix = null;
consistencyFix = null;
update = null;
}

View File

@ -8,7 +8,7 @@ import {
makeUnique
} from "../common/types";
import { ActionInterface, CheckStepInterface } from "./interface";
import { formatSortJson, formatUniqueSortJson } from "../common/json";
import { formatSortJson } from "../common/json";
import * as bluebird from "bluebird";
async function checkUpdateWhiteBlackList(chain: string, checkOnly: boolean ): Promise<[boolean, string]> {
@ -55,11 +55,22 @@ async function checkUpdateWhiteBlackList(chain: string, checkOnly: boolean ): Pr
wrongMsg += `Some elements should be removed from blacklist for chain ${chain}: ${bDiff2.length} ${bDiff2[0]}\n`;
}
// additionally check for nice formatting, sorting:
const newWhiteText = formatSortJson(newWhite);
const newBlackText = formatSortJson(newBlack);
if (newWhiteText !== currentWhitelistText) {
wrongMsg += `Whitelist for chain ${chain}: not formatted nicely \n`;
}
if (newBlackText !== currentBlacklistText) {
wrongMsg += `Blacklist for chain ${chain}: not formatted nicely \n`;
}
if (wrongMsg.length > 0) {
// sg wrong, may need to fix
if (!checkOnly) {
// update
writeFileSync(whitelistPath, formatSortJson(newWhite));
writeFileSync(blacklistPath, formatSortJson(newBlack));
writeFileSync(whitelistPath, newWhiteText);
writeFileSync(blacklistPath, newBlackText);
console.log(`Updated white and blacklists for chain ${chain}`);
}
}
@ -69,7 +80,9 @@ async function checkUpdateWhiteBlackList(chain: string, checkOnly: boolean ): Pr
export class Whitelist implements ActionInterface {
getName(): string { return "Whitelists"; }
getChecks(): CheckStepInterface[] {
getSanityChecks = null;
getConsistencyChecks(): CheckStepInterface[] {
const steps: CheckStepInterface[] = [];
chainsWithBlacklist.forEach(chain => {
steps.push(
@ -88,8 +101,9 @@ export class Whitelist implements ActionInterface {
return steps;
}
sanityFix = null;
async fix(): Promise<void> {
async consistencyFix(): Promise<void> {
await bluebird.each(chainsWithBlacklist, async (chain) => await checkUpdateWhiteBlackList(chain, false));
}

View File

@ -0,0 +1,13 @@
import { sanityCheckAll } from "../action/update-all";
export async function main() {
try {
const returnCode = await sanityCheckAll();
process.exit(returnCode);
} catch(err) {
console.error(err);
process.exit(1);
}
}
main();

View File

@ -1,13 +1,29 @@
import { checkAll } from "../action/update-all";
import { sanityCheckAll, consistencyCheckAll } from "../action/update-all";
export async function main() {
var returnCode: number = 0;
try {
const returnCode = await checkAll();
process.exit(returnCode);
const ret1 = await sanityCheckAll();
if (ret1 != 0) {
returnCode = ret1;
}
} catch(err) {
console.error(err);
process.exit(1);
returnCode = 1;
}
try {
const ret1 = await consistencyCheckAll();
if (ret1 != 0) {
returnCode = ret1;
}
} catch(err) {
console.error(err);
returnCode = 1;
}
process.exit(returnCode);
}
main();

12
script/main/fix-sanity.ts Normal file
View File

@ -0,0 +1,12 @@
import { sanityFixAll, consistencyFixAll } from "../action/update-all";
export async function main() {
try {
await sanityFixAll();
} catch(err) {
console.error(err);
process.exit(1);
}
}
main();

View File

@ -1,8 +1,15 @@
import { fixAll } from "../action/update-all";
import { sanityFixAll, consistencyFixAll } from "../action/update-all";
export async function main() {
try {
await fixAll();
await sanityFixAll();
} catch(err) {
console.error(err);
process.exit(1);
}
try {
await consistencyFixAll();
} catch(err) {
console.error(err);
process.exit(1);