2020-10-14 01:20:42 +00:00
import { chainsWithDenylist } from "./blockchains" ;
2020-08-18 06:50:32 +00:00
import {
2020-11-20 10:40:44 +00:00
getChainAssetInfoPath ,
getChainAssetLogoPath ,
//getChainAssetsList,
getChainAssetsPath ,
2020-08-18 06:50:32 +00:00
getChainAllowlistPath ,
2020-08-24 15:06:21 +00:00
getChainDenylistPath
2020-10-14 01:20:42 +00:00
} from "./repo-structure" ;
2020-08-18 06:50:32 +00:00
import {
2020-11-20 10:40:44 +00:00
isPathExistsSync ,
readDirSync ,
readFileSync ,
writeFileSync
} from "./filesystem" ;
import {
//arrayDiff,
2020-08-18 06:50:32 +00:00
arrayDiffNocase ,
findCommonElementsOrDuplicates ,
makeUnique
2020-10-14 01:20:42 +00:00
} from "./types" ;
import { ActionInterface , CheckStepInterface } from "./interface" ;
import { formatSortJson } from "./json" ;
2020-08-18 06:50:32 +00:00
import * as bluebird from "bluebird" ;
2020-11-20 10:40:44 +00:00
// 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 ;
}
2020-09-16 12:52:10 +00:00
async function checkUpdateAllowDenyList ( chain : string , checkOnly : boolean ) : Promise < [ boolean , string [ ] , string [ ] ] > {
2020-09-18 14:39:31 +00:00
const errorMsgs : string [ ] = [ ] ;
const warningMsgs : string [ ] = [ ] ;
2020-08-18 06:50:32 +00:00
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 ) {
2020-09-16 12:52:10 +00:00
errorMsgs . push ( ` Denylist and allowlist for chain ${ chain } should have no common elements or duplicates, found ${ commonElementsOrDuplicates . length } ${ commonElementsOrDuplicates [ 0 ] } ` ) ;
2020-08-18 06:50:32 +00:00
}
2020-11-20 10:40:44 +00:00
//const assetsWithLogo = getChainAssetsList(chain);
const assetsWithInfoNotInAllow = await findFullAssetsWithNoAllow ( chain , currentAllowlist ) ;
2020-11-19 09:18:14 +00:00
/ *
2020-11-20 10:40:44 +00:00
const allowlistOrphan = arrayDiff ( currentAllowlist , assetsWithLogo ) ;
2020-08-18 06:50:32 +00:00
if ( allowlistOrphan && allowlistOrphan . length > 0 ) {
2020-08-24 15:06:21 +00:00
// warning only
2020-11-20 10:40:44 +00:00
warningMsgs . push ( ` Allowlist for chain ${ chain } contains non-exitent assetsWithLogo, found ${ allowlistOrphan . length } , ${ allowlistOrphan [ 0 ] } ` ) ;
2020-08-18 06:50:32 +00:00
}
2020-11-19 09:18:14 +00:00
* /
2020-08-18 06:50:32 +00:00
2020-11-19 09:18:14 +00:00
//const newDeny = makeUnique(currentDenylist.concat(allowlistOrphan));
2020-11-20 10:40:44 +00:00
const tempAssetsOrAllow = makeUnique ( currentAllowlist . concat ( assetsWithInfoNotInAllow ) ) ;
2020-11-19 09:18:14 +00:00
const newAllow = makeUnique ( arrayDiffNocase ( tempAssetsOrAllow , currentDenylist ) ) ;
2020-08-18 06:50:32 +00:00
//console.log(currentAllowlist.length, "vs.", newAllow.length);
//console.log(currentDenylist.length, "vs.", newDeny.length);
const wDiff1 = arrayDiffNocase ( newAllow , currentAllowlist ) ;
if ( wDiff1 . length > 0 ) {
2020-08-24 15:06:21 +00:00
// warning only
2020-09-16 12:52:10 +00:00
warningMsgs . push ( ` Some elements are missing from allowlist for chain ${ chain } : ${ wDiff1 . length } ${ wDiff1 [ 0 ] } ` ) ;
2020-08-18 06:50:32 +00:00
}
const wDiff2 = arrayDiffNocase ( currentAllowlist , newAllow ) ;
if ( wDiff2 . length > 0 ) {
2020-08-24 15:06:21 +00:00
// warning only
2020-09-16 12:52:10 +00:00
warningMsgs . push ( ` Some elements should be removed from allowlist for chain ${ chain } : ${ wDiff2 . length } ${ wDiff2 [ 0 ] } ` ) ;
2020-08-18 06:50:32 +00:00
}
2020-11-19 09:18:14 +00:00
/ *
2020-08-18 06:50:32 +00:00
const bDiff1 = arrayDiffNocase ( newDeny , currentDenylist ) ;
if ( bDiff1 . length > 0 ) {
2020-09-16 12:52:10 +00:00
warningMsgs . push ( ` Some elements are missing from denylist for chain ${ chain } : ${ bDiff1 . length } ${ bDiff1 [ 0 ] } ` ) ;
2020-08-18 06:50:32 +00:00
}
const bDiff2 = arrayDiffNocase ( currentDenylist , newDeny ) ;
if ( bDiff2 . length > 0 ) {
2020-09-16 12:52:10 +00:00
warningMsgs . push ( ` Some elements should be removed from denylist for chain ${ chain } : ${ bDiff2 . length } ${ bDiff2 [ 0 ] } ` ) ;
2020-08-18 06:50:32 +00:00
}
2020-11-19 09:18:14 +00:00
* /
2020-08-18 06:50:32 +00:00
// additionally check for nice formatting, sorting:
const newAllowText = formatSortJson ( newAllow ) ;
if ( newAllowText !== currentAllowlistText ) {
2020-09-16 12:52:10 +00:00
warningMsgs . push ( ` Allowlist for chain ${ chain } : not formatted nicely ` ) ;
2020-08-18 06:50:32 +00:00
}
2020-11-19 09:18:14 +00:00
const newDenyText = formatSortJson ( currentDenylist ) ; // formatSortJson(newDeny);
2020-08-18 06:50:32 +00:00
if ( newDenyText !== currentDenylistText ) {
2020-09-16 12:52:10 +00:00
warningMsgs . push ( ` Denylist for chain ${ chain } : not formatted nicely ` ) ;
2020-08-18 06:50:32 +00:00
}
2020-09-16 12:52:10 +00:00
if ( errorMsgs . length > 0 || warningMsgs . length > 0 ) {
2020-08-18 06:50:32 +00:00
// sg wrong, may need to fix
if ( ! checkOnly ) {
// update
writeFileSync ( allowlistPath , newAllowText ) ;
writeFileSync ( denylistPath , newDenyText ) ;
console . log ( ` Updated allow and denylists for chain ${ chain } ` ) ;
}
}
2020-09-16 12:52:10 +00:00
return [ ( errorMsgs . length == 0 && warningMsgs . length == 0 ) , errorMsgs , warningMsgs ] ;
2020-08-18 06:50:32 +00:00
}
2020-10-14 01:20:42 +00:00
export class Allowlists implements ActionInterface {
2020-08-18 06:50:32 +00:00
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 ( ) = > {
2020-09-16 12:52:10 +00:00
const [ isOK , errorMsgs , warningMsgs ] = await checkUpdateAllowDenyList ( chain , true ) ;
2020-08-18 06:50:32 +00:00
if ( ! isOK ) {
2020-09-16 12:52:10 +00:00
return [ errorMsgs , warningMsgs ] ;
2020-08-18 06:50:32 +00:00
}
2020-09-16 12:52:10 +00:00
return [ [ ] , [ ] ] ;
2020-08-18 06:50:32 +00:00
}
}
) ;
} ) ;
return steps ;
}
async consistencyFix ( ) : Promise < void > {
await bluebird . each ( chainsWithDenylist , async ( chain ) = > await checkUpdateAllowDenyList ( chain , false ) ) ;
}
}