forked from trustwallet/assets
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathallowlists.ts
More file actions
155 lines (141 loc) · 6.01 KB
/
allowlists.ts
File metadata and controls
155 lines (141 loc) · 6.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
import { chainsWithDenylist } from "./blockchains";
import {
getChainAssetInfoPath,
getChainAssetLogoPath,
//getChainAssetsList,
getChainAssetsPath,
getChainAllowlistPath,
getChainDenylistPath
} from "./repo-structure";
import {
isPathExistsSync,
readDirSync,
readFileSync,
writeFileSync
} from "./filesystem";
import {
//arrayDiff,
arrayDiffNocase,
findCommonElementsOrDuplicates,
makeUnique
} from "./types";
import { ActionInterface, CheckStepInterface } from "./interface";
import { formatSortJson } from "./json";
import * as bluebird from "bluebird";
// Find assets for which full info is available -- logo+info -- and is not in the allowlist
async function findFullAssetsWithNoAllow(chain: string, allowlist: string[]): Promise<string[]> {
const list: string[] = [];
const assetsPath = getChainAssetsPath(chain);
if (!isPathExistsSync(assetsPath)) {
return list;
}
await bluebird.mapSeries(readDirSync(assetsPath), async asset => {
if (allowlist.includes(asset)) {
// present in allowlist, skip
return;
}
const logoPath = getChainAssetLogoPath(chain, asset);
if (!isPathExistsSync(logoPath)) {
return;
}
const infoPath = getChainAssetInfoPath(chain, asset);
if (!isPathExistsSync(infoPath)) {
return;
}
// both files exist, not in allowlist
list.push(asset);
});
return list;
}
async function checkUpdateAllowDenyList(chain: string, checkOnly: boolean ): Promise<[boolean, string[], string[]]> {
const errorMsgs: string[] = [];
const warningMsgs: string[] = [];
const allowlistPath = getChainAllowlistPath(chain);
const denylistPath = getChainDenylistPath(chain);
const currentAllowlistText = readFileSync(allowlistPath);
const currentDenylistText = readFileSync(denylistPath);
const currentAllowlist = JSON.parse(currentAllowlistText);
const currentDenylist = JSON.parse(currentDenylistText);
const commonElementsOrDuplicates = findCommonElementsOrDuplicates(currentAllowlist, currentDenylist);
if (commonElementsOrDuplicates && commonElementsOrDuplicates.length > 0) {
errorMsgs.push(`Denylist and allowlist for chain ${chain} should have no common elements or duplicates, found ${commonElementsOrDuplicates.length} ${commonElementsOrDuplicates[0]}`);
}
//const assetsWithLogo = getChainAssetsList(chain);
const assetsWithInfoNotInAllow = await findFullAssetsWithNoAllow(chain, currentAllowlist);
/*
const allowlistOrphan = arrayDiff(currentAllowlist, assetsWithLogo);
if (allowlistOrphan && allowlistOrphan.length > 0) {
// warning only
warningMsgs.push(`Allowlist for chain ${chain} contains non-exitent assetsWithLogo, found ${allowlistOrphan.length}, ${allowlistOrphan[0]}`);
}
*/
//const newDeny = makeUnique(currentDenylist.concat(allowlistOrphan));
const tempAssetsOrAllow = makeUnique(currentAllowlist.concat(assetsWithInfoNotInAllow));
const newAllow = makeUnique(arrayDiffNocase(tempAssetsOrAllow, currentDenylist));
//console.log(currentAllowlist.length, "vs.", newAllow.length);
//console.log(currentDenylist.length, "vs.", newDeny.length);
const wDiff1 = arrayDiffNocase(newAllow, currentAllowlist);
if (wDiff1.length > 0) {
// warning only
warningMsgs.push(`Some elements are missing from allowlist for chain ${chain}: ${wDiff1.length} ${wDiff1[0]}`);
}
const wDiff2 = arrayDiffNocase(currentAllowlist, newAllow);
if (wDiff2.length > 0) {
// warning only
warningMsgs.push(`Some elements should be removed from allowlist for chain ${chain}: ${wDiff2.length} ${wDiff2[0]}`);
}
/*
const bDiff1 = arrayDiffNocase(newDeny, currentDenylist);
if (bDiff1.length > 0) {
warningMsgs.push(`Some elements are missing from denylist for chain ${chain}: ${bDiff1.length} ${bDiff1[0]}`);
}
const bDiff2 = arrayDiffNocase(currentDenylist, newDeny);
if (bDiff2.length > 0) {
warningMsgs.push(`Some elements should be removed from denylist for chain ${chain}: ${bDiff2.length} ${bDiff2[0]}`);
}
*/
// additionally check for nice formatting, sorting:
const newAllowText = formatSortJson(newAllow);
if (newAllowText !== currentAllowlistText) {
warningMsgs.push(`Allowlist for chain ${chain}: not formatted nicely `);
}
const newDenyText = formatSortJson(currentDenylist); // formatSortJson(newDeny);
if (newDenyText !== currentDenylistText) {
warningMsgs.push(`Denylist for chain ${chain}: not formatted nicely `);
}
if (errorMsgs.length > 0 || warningMsgs.length > 0) {
// sg wrong, may need to fix
if (!checkOnly) {
// update
writeFileSync(allowlistPath, newAllowText);
writeFileSync(denylistPath, newDenyText);
console.log(`Updated allow and denylists for chain ${chain}`);
}
}
return [(errorMsgs.length == 0 && warningMsgs.length == 0), errorMsgs, warningMsgs];
}
export class Allowlists implements ActionInterface {
getName(): string { return "Allowlists"; }
getSanityChecks = null;
getConsistencyChecks(): CheckStepInterface[] {
const steps: CheckStepInterface[] = [];
chainsWithDenylist.forEach(chain => {
steps.push(
{
getName: () => { return `Allowlist and denylist for ${chain} should be consistent with assets`},
check: async () => {
const [isOK, errorMsgs, warningMsgs] = await checkUpdateAllowDenyList(chain, true);
if (!isOK) {
return [errorMsgs, warningMsgs];
}
return [[], []];
}
}
);
});
return steps;
}
async consistencyFix(): Promise<void> {
await bluebird.each(chainsWithDenylist, async (chain) => await checkUpdateAllowDenyList(chain, false));
}
}