Skip to content

Commit

Permalink
Merge branch 'cosmos:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
pr0n00gler authored May 8, 2024
2 parents f6b13c8 + b4e168e commit 246ad8b
Show file tree
Hide file tree
Showing 547 changed files with 21,057 additions and 2,643 deletions.
19 changes: 18 additions & 1 deletion .github/workflows/utility/chain_registry.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,17 @@ export const nonChainDirectories = [
"_memo_keys",
"_non-cosmos",
"_template",
"_scripts",
"testnets",
".gitignore",
"assetlist.schema.json",
"chain.schema.json",
"ibc_data.schema.json",
"memo_keys.schema.json",
"versions.schema.json",
"README.md",
"LICENSE"
"LICENSE",
"package.json"
]

export const assetSchema = {
Expand Down Expand Up @@ -294,6 +297,20 @@ export function getAssetPropertyWithTrace(chainName, baseDenom, property) {
return value;
}

export function getAssetPropertyWithTraceCustom(chainName, baseDenom, property, types) {
let value = getAssetProperty(chainName, baseDenom, property);
if (value) { return value; }
if (property === "traces") { return; }
let traces = getAssetProperty(chainName, baseDenom, "traces");
if (!traces) { return; }
if (!types.includes(traces[traces.length - 1].type)) { return; }
let originAsset = {
chainName: traces[traces.length - 1].counterparty.chain_name,
baseDenom: traces[traces.length - 1].counterparty.base_denom
}
return getAssetPropertyWithTraceCustom(originAsset.chainName, originAsset.baseDenom, property, types);
}

export function getAssetPropertyWithTraceIBC(chainName, baseDenom, property) {
let value = getAssetProperty(chainName, baseDenom, property);
if (!value) {
Expand Down
19 changes: 18 additions & 1 deletion .github/workflows/utility/chain_registry_local.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,17 @@ export const nonChainDirectories = [
"_memo_keys",
"_non-cosmos",
"_template",
"_scripts",
"testnets",
".gitignore",
"assetlist.schema.json",
"chain.schema.json",
"ibc_data.schema.json",
"memo_keys.schema.json",
"versions.schema.json",
"README.md",
"LICENSE"
"LICENSE",
"package.json"
]

export const assetSchema = {
Expand Down Expand Up @@ -294,6 +297,20 @@ export function getAssetPropertyWithTrace(chainName, baseDenom, property) {
return value;
}

export function getAssetPropertyWithTraceCustom(chainName, baseDenom, property, types) {
let value = getAssetProperty(chainName, baseDenom, property);
if (value) { return value; }
if (property === "traces") { return; }
let traces = getAssetProperty(chainName, baseDenom, "traces");
if (!traces) { return; }
if (!types.includes(traces[traces.length - 1].type)) { return; }
let originAsset = {
chainName: traces[traces.length - 1].counterparty.chain_name,
baseDenom: traces[traces.length - 1].counterparty.base_denom
}
return getAssetPropertyWithTraceCustom(originAsset.chainName, originAsset.baseDenom, property, types);
}

export function getAssetPropertyWithTraceIBC(chainName, baseDenom, property) {
let value = getAssetProperty(chainName, baseDenom, property);
if (!value) {
Expand Down
64 changes: 50 additions & 14 deletions .github/workflows/utility/sync_images.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -129,22 +129,46 @@ function compareImages(imageContainingObject) {
let newImageContainingObject = imageContainingObject;
if(imageContainingObject.logo_URIs){
if(imageContainingObject.images){

//Look for a full match (i.e., png and svg both match)
let match = false;
imageContainingObject.images.forEach((image) => {
if(imageContainingObject.logo_URIs.png == image.png &&
imageContainingObject.logo_URIs.svg == image.svg) {
if (
imageContainingObject.logo_URIs.png == image.png &&
imageContainingObject.logo_URIs.svg == image.svg
) {
match = true;
return newImageContainingObject;
return;
}
});
if(!match){
newImageContainingObject.images.push({
png: imageContainingObject.logo_URIs.png,
svg: imageContainingObject.logo_URIs.svg
});
newImageContainingObject.hasUpdated = true;
if (match) {
return newImageContainingObject;
}

//Look for a partial match, and update the image object
for (let i = 0; i < imageContainingObject.images.length; i++) {
if (
imageContainingObject.logo_URIs.png == imageContainingObject.images[i].png ||
imageContainingObject.logo_URIs.svg == imageContainingObject.images[i].svg
) {
newImageContainingObject.images[i] = {
image_sync: imageContainingObject.images[i].image_sync,
png: imageContainingObject.logo_URIs.png || imageContainingObject.images[i].png,
svg: imageContainingObject.logo_URIs.svg || imageContainingObject.images[i].svg,
theme: imageContainingObject.images[i].theme
};
newImageContainingObject.hasUpdated = true;
return newImageContainingObject;
}
}

//There was no match, so add logo URI files as a new image
newImageContainingObject.images.push({
png: imageContainingObject.logo_URIs.png,
svg: imageContainingObject.logo_URIs.svg
});
newImageContainingObject.hasUpdated = true;

} else {
newImageContainingObject.images = [{
png: imageContainingObject.logo_URIs.png,
Expand Down Expand Up @@ -195,7 +219,10 @@ function getLinkedImages(){
if(images) {
let replacementImage;
images?.forEach((image) => {
replacementImage = getLinkedImage(image?.image_sync?.chain_name, image?.image_sync?.base_denom);
if (!image?.image_sync) {
return;
}
replacementImage = getLinkedImage(image.image_sync.chain_name, image.image_sync.base_denom);
if(replacementImage){
image.png = replacementImage?.png;
image.svg = replacementImage?.svg;
Expand All @@ -216,11 +243,14 @@ function getLinkedImages(){
if(images) {
images?.forEach((image) => {
let replacementImage;
replacementImage = getLinkedImage(image?.image_sync?.chain_name, image?.image_sync?.base_denom);
if (!image?.image_sync) {
return;
}
replacementImage = getLinkedImage(image.image_sync.chain_name, image.image_sync.base_denom);
if(replacementImage){
image.png = replacementImage?.png;
image.svg = replacementImage?.svg;
image.theme = replacementImage?.theme;
image.png = replacementImage.png;
image.svg = replacementImage.svg;
image.theme = replacementImage.theme;
}
});
chain_reg.setAssetProperty(assetPointer.chain_name, assetPointer.base_denom, "images", images);
Expand All @@ -239,6 +269,12 @@ function getLinkedImage(chain_name, base_denom){
if(!images){return;}
let image = images[0];
if(image.image_sync){
if (
base_denom == image.image_sync.base_denom &&
chain_name == image.image_sync.chain_name
) {
return;
}
return getLinkedImage(image.image_sync.chain_name, image.image_sync.base_denom);
} else {
return image;
Expand Down
161 changes: 161 additions & 0 deletions .github/workflows/utility/validate_data.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
// Purpose:
// to validate various data throughout the Chain Registry, prioritizing data that often gets missed by manual review
// e.g., whether fee assets are registered to the chain's assetlist

// -- THE PLAN --
//
// read each chain's directory and files
// read chain.json
// read fee_tokens
// check if fee token exists in the assetlist.
// read staking
// chaeck if staking token exists in the assetlist
//

import * as path from 'path';
import * as chain_reg from './chain_registry_local.mjs';


const chainIdMap = new Map();


function checkChainIdConflict(chain_name) {

// Not concerned by conflicts with 'Killed' chains--could be a hard fork
let chain_status = chain_reg.getFileProperty(chain_name, "chain", "status");
if (!chain_status || chain_status === "killed") { return; }

let chain_id = chain_reg.getFileProperty(chain_name, "chain", "chain_id");
if (!chain_id) { return; } // must have a chainId
if (chainIdMap.has(chain_id)) {
let conflict_chain_name = chainIdMap.get(chain_id);
throw new Error(`Duplicate chain ID for ${chain_name} found! Chain ID ${chain_id} is also claimed by ${conflict_chain_name}.`);
}
chainIdMap.set(chain_id, chain_name);

}

function checkFeeTokensAreRegistered(chain_name) {

let fees = chain_reg.getFileProperty(chain_name, "chain", "fees");
fees?.fee_tokens?.forEach((fee_token) => {
if (!fee_token.denom) {
throw new Error(`One of ${chain_name}'s fee tokens does not have denom specified.`);
}
if (!chain_reg.getAssetProperty(chain_name, fee_token.denom, "base")) {
throw new Error(`Chain ${chain_name} does not have fee token ${fee_token.denom} defined in its Assetlist.`);
}
});

}

function checkStakingTokensAreRegistered(chain_name) {

let staking = chain_reg.getFileProperty(chain_name, "chain", "staking");
staking?.staking_tokens?.forEach((staking_token) => {
if (!staking_token.denom) {
throw new Error(`One of ${chain_name}'s staking tokens does not have denom specified.`);
}
if (!chain_reg.getAssetProperty(chain_name, staking_token.denom, "base")) {
throw new Error(`Chain ${chain_name} does not have staking token ${staking_token.denom} defined in its Assetlist.`);
}
});

}

function checkDenomUnits(asset) {

if (!asset.base) { return; }
let VALID_BASE_UNIT;
let VALID_DISPLAY_UNIT;
asset.denom_units?.forEach((denom_unit) => {

let denom_and_aliases = [];
denom_and_aliases.push(denom_unit.denom);
denom_unit.aliases?.forEach((alias) => {
if (denom_and_aliases.includes(alias)) { return; }
denom_and_aliases.push(alias);
});

//find base unit
if (denom_and_aliases.includes(asset.base)) {
if (denom_unit.exponent !== 0) {
throw new Error(`Base denomination ${asset.base} is not defined as having 0 exponent.`)
}
if (VALID_BASE_UNIT) {
throw new Error(`Base denomination ${asset.base} refers to multiple denom_units.`);
}
VALID_BASE_UNIT = true;
}

//find display unit
if (asset.display) {
if (denom_and_aliases.includes(asset.display)) {
if (VALID_DISPLAY_UNIT) {
throw new Error(`Display denomination ${asset.display} refers to multiple denom_units.`);
}
VALID_DISPLAY_UNIT = true;
}
}

//check if IBC hashes contain lowercase letters
denom_and_aliases.forEach((denom) => {
if (!denom.startsWith("ibc/")) { return; }
const substring = denom.substring(4);
if (substring.toUpperCase() !== substring) {
throw new Error(`Denom ${denom} is an IBC hash denomination, yet contains lowercase letters after "ibc/"`);
}
});

});

if (!VALID_BASE_UNIT) {
throw new Error(`Base denomination ${asset.base} is not defined as a denom_unit.`);
}
if (!VALID_DISPLAY_UNIT) {
throw new Error(`Display denomination ${asset.display} is not defined as a denom_unit.`);
}

}


export function validate_chain_files() {

//get Chain Names
const chainRegChains = chain_reg.getChains();

//iterate each chain
chainRegChains.forEach((chain_name) => {

//console.log(chain_name);

//check if chain_id is registered by another chain
checkChainIdConflict(chain_name);

//check if all fee tokens are registered
checkFeeTokensAreRegistered(chain_name);

//check if all staking tokens are registered
checkStakingTokensAreRegistered(chain_name);

//get chain's assets
const chainAssets = chain_reg.getFileProperty(chain_name, "assetlist", "assets");

//iterate each asset
chainAssets?.forEach((asset) => {

//check denom units
checkDenomUnits(asset);

});


});

}

function main() {
validate_chain_files();
}

main();
42 changes: 21 additions & 21 deletions .github/workflows/validate_data.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
on: [pull_request, workflow_dispatch]
name: PR Workflow
name: Data Validation PR Workflow
jobs:
jobname:
validate_zone_data:
name: Validate Data
runs-on: ubuntu-latest

defaults:
run:
shell: bash

steps:
- name: checkout the repo
uses: actions/checkout@v3 #Checks out the registry; sets up python

- name: Set up Python
uses: actions/setup-python@v3

- name: Checkout repository
uses: actions/checkout@v2
with:
python-version: 3.9

- name: Install Python dependencies
run: |
python -m pip install --upgrade pip
cd .github/workflows/utility
- name: Run Data Validation python script
shell: python
run: |
import sys
sys.path.insert(1, '.github/workflows/utility')
import validate_data
validate_data.runAll()
token: ${{ secrets.GITHUB_TOKEN }}
submodules: true

- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 19.6.0

- name: Run code Node JS to Validate Data
working-directory: ./.github/workflows/utility
run: node validate_data.mjs
Loading

0 comments on commit 246ad8b

Please sign in to comment.