mirror of
https://github.com/pezkuwichain/pezkuwi-wallet-utils.git
synced 2026-10-20 18:56:26 +00:00
fix(chains): strip every keyed provider URL, and make the gate fail closed
The first pass matched only `infura.io/.../v3/<lowercase hex>`, so it missed `https://...infura.io/v3/<key>`, upper-case keys and hosts, and Nova's OnFinality `?apikey=` URLs (Moonriver, and the Hades testnet in v20/v21 preConfigured). preConfigured was copied from Nova without the filter, and the integrity check passed if grep itself failed. - one predicate, is_keyed(), in sync_from_nova.py: Infura /v3/ ids and apikey/api_key/key/token query values, case-insensitive; {PLACEHOLDER} values are allowed - preConfigured details are filtered after the copy; a chain left with no node loses its details file and its index entry (Hades, v20/v21 only) - rewritten files keep their own indent, so the diff is the data change only - check 5 imports is_keyed() and checks every string in every JSON file under chains/; an unreadable file or an empty tree is an error - check 3 reports a grep error instead of passing on it
This commit is contained in:
1 parent
7f0bb6a3d3
commit
b5f5af2cce
20 files changed
+92
-161
No files matched your search
@@ -1355,10 +1355,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -1369,10 +1369,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -1380,10 +1380,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -1441,10 +1441,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -183,10 +183,6 @@
|
|||||||
"chainId": "65c489fb7bfaf4a27f283faf694a64a8d7ae8fc0ed970fc4ebbf25d03095e4d0",
|
"chainId": "65c489fb7bfaf4a27f283faf694a64a8d7ae8fc0ed970fc4ebbf25d03095e4d0",
|
||||||
"name": "Niskala (TESTNET)"
|
"name": "Niskala (TESTNET)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"chainId": "d9d12d9139d020f658d4469fa5c02e331195227da62567d7bf9bbd1abaf77522",
|
|
||||||
"name": "Parachain Hades testnet (TESTNET)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"chainId": "466edf864b4314b97f36e45ec21ddb39e0bdc52789377b91be0957d5afad2eb2",
|
"chainId": "466edf864b4314b97f36e45ec21ddb39e0bdc52789377b91be0957d5afad2eb2",
|
||||||
"name": "Energy Web X Paseo (TESTNET)"
|
"name": "Energy Web X Paseo (TESTNET)"
|
||||||
|
|||||||
@@ -139,10 +139,6 @@
|
|||||||
"chainId": "65c489fb7bfaf4a27f283faf694a64a8d7ae8fc0ed970fc4ebbf25d03095e4d0",
|
"chainId": "65c489fb7bfaf4a27f283faf694a64a8d7ae8fc0ed970fc4ebbf25d03095e4d0",
|
||||||
"name": "Niskala (TESTNET)"
|
"name": "Niskala (TESTNET)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"chainId": "d9d12d9139d020f658d4469fa5c02e331195227da62567d7bf9bbd1abaf77522",
|
|
||||||
"name": "Parachain Hades testnet (TESTNET)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"chainId": "466edf864b4314b97f36e45ec21ddb39e0bdc52789377b91be0957d5afad2eb2",
|
"chainId": "466edf864b4314b97f36e45ec21ddb39e0bdc52789377b91be0957d5afad2eb2",
|
||||||
"name": "Energy Web X Paseo (TESTNET)"
|
"name": "Energy Web X Paseo (TESTNET)"
|
||||||
|
|||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"chainId": "d9d12d9139d020f658d4469fa5c02e331195227da62567d7bf9bbd1abaf77522",
|
|
||||||
"name": "Parachain Hades testnet (TESTNET)",
|
|
||||||
"assets": [
|
|
||||||
{
|
|
||||||
"assetId": 0,
|
|
||||||
"symbol": "notNodl",
|
|
||||||
"precision": 11,
|
|
||||||
"icon": "https://raw.githubusercontent.com/novasamatech/nova-utils/master/icons/tokens/white/Default.svg"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"url": "wss://node-6957502816543653888.lh.onfinality.io/ws?apikey=09b04494-3139-4b57-a5d1-e1c4c18748ce",
|
|
||||||
"name": "OnFinality"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"addressPrefix": 37
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"chainId": "d9d12d9139d020f658d4469fa5c02e331195227da62567d7bf9bbd1abaf77522",
|
|
||||||
"name": "Parachain Hades testnet (TESTNET)",
|
|
||||||
"assets": [
|
|
||||||
{
|
|
||||||
"assetId": 0,
|
|
||||||
"symbol": "notNodl",
|
|
||||||
"precision": 11,
|
|
||||||
"icon": "https://raw.githubusercontent.com/novasamatech/nova-utils/master/icons/tokens/white/Default.svg"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"url": "wss://node-6957502816543653888.lh.onfinality.io/ws?apikey=09b04494-3139-4b57-a5d1-e1c4c18748ce",
|
|
||||||
"name": "OnFinality"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"addressPrefix": 37
|
|
||||||
}
|
|
||||||
@@ -187,10 +187,6 @@
|
|||||||
"chainId": "65c489fb7bfaf4a27f283faf694a64a8d7ae8fc0ed970fc4ebbf25d03095e4d0",
|
"chainId": "65c489fb7bfaf4a27f283faf694a64a8d7ae8fc0ed970fc4ebbf25d03095e4d0",
|
||||||
"name": "Niskala (TESTNET)"
|
"name": "Niskala (TESTNET)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"chainId": "d9d12d9139d020f658d4469fa5c02e331195227da62567d7bf9bbd1abaf77522",
|
|
||||||
"name": "Parachain Hades testnet (TESTNET)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"chainId": "466edf864b4314b97f36e45ec21ddb39e0bdc52789377b91be0957d5afad2eb2",
|
"chainId": "466edf864b4314b97f36e45ec21ddb39e0bdc52789377b91be0957d5afad2eb2",
|
||||||
"name": "Energy Web X Paseo (TESTNET)"
|
"name": "Energy Web X Paseo (TESTNET)"
|
||||||
|
|||||||
@@ -135,10 +135,6 @@
|
|||||||
"chainId": "65c489fb7bfaf4a27f283faf694a64a8d7ae8fc0ed970fc4ebbf25d03095e4d0",
|
"chainId": "65c489fb7bfaf4a27f283faf694a64a8d7ae8fc0ed970fc4ebbf25d03095e4d0",
|
||||||
"name": "Niskala (TESTNET)"
|
"name": "Niskala (TESTNET)"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"chainId": "d9d12d9139d020f658d4469fa5c02e331195227da62567d7bf9bbd1abaf77522",
|
|
||||||
"name": "Parachain Hades testnet (TESTNET)"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"chainId": "466edf864b4314b97f36e45ec21ddb39e0bdc52789377b91be0957d5afad2eb2",
|
"chainId": "466edf864b4314b97f36e45ec21ddb39e0bdc52789377b91be0957d5afad2eb2",
|
||||||
"name": "Energy Web X Paseo (TESTNET)"
|
"name": "Energy Web X Paseo (TESTNET)"
|
||||||
|
|||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"chainId": "d9d12d9139d020f658d4469fa5c02e331195227da62567d7bf9bbd1abaf77522",
|
|
||||||
"name": "Parachain Hades testnet (TESTNET)",
|
|
||||||
"assets": [
|
|
||||||
{
|
|
||||||
"assetId": 0,
|
|
||||||
"symbol": "notNodl",
|
|
||||||
"precision": 11,
|
|
||||||
"icon": "Default.svg"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"url": "wss://node-7273232234617282560.nv.onfinality.io/ws?apikey=b937a7d7-7395-49b9-b745-60a0342fa365",
|
|
||||||
"name": "OnFinality"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"addressPrefix": 37
|
|
||||||
}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{
|
|
||||||
"chainId": "d9d12d9139d020f658d4469fa5c02e331195227da62567d7bf9bbd1abaf77522",
|
|
||||||
"name": "Parachain Hades testnet (TESTNET)",
|
|
||||||
"assets": [
|
|
||||||
{
|
|
||||||
"assetId": 0,
|
|
||||||
"symbol": "notNodl",
|
|
||||||
"precision": 11,
|
|
||||||
"icon": "Default.svg"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"url": "wss://node-7273232234617282560.nv.onfinality.io/ws?apikey=b937a7d7-7395-49b9-b745-60a0342fa365",
|
|
||||||
"name": "OnFinality"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"addressPrefix": 37
|
|
||||||
}
|
|
||||||
@@ -1225,10 +1225,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -1283,10 +1283,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -1315,10 +1315,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -1329,10 +1329,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -1355,10 +1355,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -1355,10 +1355,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"nodes": [
|
"nodes": [
|
||||||
{
|
|
||||||
"url": "wss://moonriver.api.onfinality.io/ws?apikey=41935d3d-3d6c-4a90-a0e1-33c065401d05",
|
|
||||||
"name": "OnFinality node"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
"url": "wss://moonriver.api.onfinality.io/public-ws",
|
||||||
"name": "OnFinality node"
|
"name": "OnFinality node"
|
||||||
|
|||||||
@@ -88,6 +88,8 @@ grep = subprocess.run(
|
|||||||
capture_output=True,
|
capture_output=True,
|
||||||
text=True,
|
text=True,
|
||||||
)
|
)
|
||||||
|
if grep.returncode not in (0, 1):
|
||||||
|
errors.append(f"grep for working-branch asset URLs failed: {grep.stderr.strip()}")
|
||||||
if grep.stdout.strip():
|
if grep.stdout.strip():
|
||||||
files = grep.stdout.strip().splitlines()
|
files = grep.stdout.strip().splitlines()
|
||||||
errors.append(
|
errors.append(
|
||||||
@@ -107,21 +109,41 @@ for fixture in ("pezkuwi_assets_for_testBalance.json",):
|
|||||||
f"tests/{fixture} has drifted from pezkuwi-overlay/tests/{fixture}"
|
f"tests/{fixture} has drifted from pezkuwi-overlay/tests/{fixture}"
|
||||||
)
|
)
|
||||||
|
|
||||||
# ── 5. No third-party API key in a node URL ──────────────────────────────────
|
# ── 5. No third-party API key in a URL ───────────────────────────────────────
|
||||||
#
|
#
|
||||||
# Nova's configs shipped Nova's own Infura project keys inside node URLs, and
|
# Nova's configs shipped Nova's own provider keys (Infura project ids, OnFinality
|
||||||
# every sync copied them into ours. Our builds fill {INFURA_API_KEY} from our
|
# apikeys) inside node URLs, and every sync copied them into ours. Our builds fill
|
||||||
# own secret; a keyed URL is someone else's quota and dies when they rotate it.
|
# {INFURA_API_KEY}-style placeholders from our own secrets; a keyed URL is someone
|
||||||
grep = subprocess.run(
|
# else's quota and dies when they rotate it. The predicate is the one the sync
|
||||||
["grep", "-rlE", r"infura\.io/.*/v3/[0-9a-f]{32}", str(ROOT / "chains")],
|
# uses, and every string in every JSON file is checked, so a file that does not
|
||||||
capture_output=True,
|
# parse is a failure, not a pass.
|
||||||
text=True,
|
sys.path.insert(0, str(ROOT / "scripts"))
|
||||||
)
|
from sync_from_nova import is_keyed # noqa: E402
|
||||||
if grep.stdout.strip():
|
|
||||||
files = grep.stdout.strip().splitlines()
|
keyed_files = []
|
||||||
|
json_files = sorted(p for p in (ROOT / "chains").rglob("*.json"))
|
||||||
|
if not json_files:
|
||||||
|
errors.append("chains/ has no JSON files; the key check would have checked nothing")
|
||||||
|
for path in json_files:
|
||||||
|
try:
|
||||||
|
doc = json.loads(path.read_text(encoding="utf-8"))
|
||||||
|
except (OSError, ValueError) as exc:
|
||||||
|
errors.append(f"{path.relative_to(ROOT)} could not be read for the key check: {exc}")
|
||||||
|
continue
|
||||||
|
stack = [doc]
|
||||||
|
while stack:
|
||||||
|
node = stack.pop()
|
||||||
|
if isinstance(node, dict):
|
||||||
|
stack.extend(node.values())
|
||||||
|
elif isinstance(node, list):
|
||||||
|
stack.extend(node)
|
||||||
|
elif isinstance(node, str) and is_keyed(node):
|
||||||
|
keyed_files.append(path)
|
||||||
|
break
|
||||||
|
if keyed_files:
|
||||||
errors.append(
|
errors.append(
|
||||||
f"{len(files)} file(s) under chains/ embed an Infura key in a node URL; "
|
f"{len(keyed_files)} file(s) under chains/ embed a provider key in a URL; "
|
||||||
f"use {{INFURA_API_KEY}}, e.g. {Path(files[0]).relative_to(ROOT)}"
|
f"use a {{PLACEHOLDER}}, e.g. {keyed_files[0].relative_to(ROOT)}"
|
||||||
)
|
)
|
||||||
|
|
||||||
if errors:
|
if errors:
|
||||||
|
|||||||
+57
-16
@@ -52,25 +52,65 @@ def load_blacklist() -> set:
|
|||||||
return set()
|
return set()
|
||||||
|
|
||||||
|
|
||||||
# Nova's configs carry Nova's own Infura project keys written into node URLs.
|
# Nova's configs carry Nova's own provider keys written into node URLs (Infura
|
||||||
# They are not ours to use: our builds fill `{INFURA_API_KEY}` from our own
|
# project ids, OnFinality apikeys). They are not ours to use: our builds fill
|
||||||
# secret, and a keyed URL breaks for every user the day Nova rotates it.
|
# placeholders like `{INFURA_API_KEY}` from our own secrets, and a keyed URL
|
||||||
KEYED_ENDPOINT = re.compile(r"infura\.io/.*/v3/[0-9a-f]{32}")
|
# breaks for every user the day Nova rotates it. check_pezkuwi_integrity.py
|
||||||
|
# imports this same predicate, so the filter and the gate cannot disagree.
|
||||||
|
KEYED_ENDPOINT = re.compile(
|
||||||
|
r"infura\.io/(?:[^?#\s]*/)?v3/[0-9a-z]{32}"
|
||||||
|
r"|[?&](?:api[_-]?key|apikey|access[_-]?token|token|key)=(?!\{)[^&#\s]+",
|
||||||
|
re.IGNORECASE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def is_keyed(url: str) -> bool:
|
||||||
|
"""True if the URL embeds a literal credential rather than a {PLACEHOLDER}."""
|
||||||
|
return bool(KEYED_ENDPOINT.search(url))
|
||||||
|
|
||||||
|
|
||||||
|
def strip_chain(chain: dict) -> dict | None:
|
||||||
|
"""The chain without keyed nodes; None if no node is left."""
|
||||||
|
nodes = chain.get('nodes')
|
||||||
|
if not isinstance(nodes, list):
|
||||||
|
return chain
|
||||||
|
kept = [n for n in nodes if not (isinstance(n, dict) and is_keyed(str(n.get('url', ''))))]
|
||||||
|
if not kept:
|
||||||
|
return None
|
||||||
|
return chain if len(kept) == len(nodes) else {**chain, 'nodes': kept}
|
||||||
|
|
||||||
|
|
||||||
def strip_keyed_endpoints(chains: list) -> list:
|
def strip_keyed_endpoints(chains: list) -> list:
|
||||||
"""Drop nodes whose URL embeds a third-party API key, and any chain left with no node."""
|
"""Drop nodes whose URL embeds a third-party key, and any chain left with no node."""
|
||||||
out = []
|
return [c for c in (strip_chain(c) for c in chains) if c is not None]
|
||||||
for chain in chains:
|
|
||||||
nodes = chain.get('nodes')
|
|
||||||
if nodes is not None:
|
def rewrite_in_place(path: Path, data):
|
||||||
kept = [n for n in nodes if not KEYED_ENDPOINT.search(n.get('url', ''))]
|
"""Rewrite a JSON file keeping its own indent and trailing newline, so a
|
||||||
if not kept:
|
filtered copy of Nova's file differs from it only where the data does."""
|
||||||
continue
|
raw = path.read_text(encoding='utf-8')
|
||||||
if len(kept) != len(nodes):
|
second = raw.split('\n', 2)[1] if raw.count('\n') >= 1 else ''
|
||||||
chain = {**chain, 'nodes': kept}
|
indent = (len(second) - len(second.lstrip(' '))) or 2
|
||||||
out.append(chain)
|
out = json.dumps(data, indent=indent, ensure_ascii=False)
|
||||||
return out
|
path.write_text(out + ('\n' if raw.endswith('\n') else ''), encoding='utf-8')
|
||||||
|
|
||||||
|
|
||||||
|
def strip_preconfigured(preconfig: Path):
|
||||||
|
"""Apply strip_chain to every details file; a chain left with no node is
|
||||||
|
removed together with its entry in the matching index."""
|
||||||
|
for details, index in (("details", "chains.json"), ("detailsDev", "chains_dev.json")):
|
||||||
|
dropped = set()
|
||||||
|
for f in sorted((preconfig / details).glob("*.json")):
|
||||||
|
chain = load_json(f)
|
||||||
|
stripped = strip_chain(chain)
|
||||||
|
if stripped is None:
|
||||||
|
dropped.add(chain.get('chainId'))
|
||||||
|
f.unlink()
|
||||||
|
elif stripped is not chain:
|
||||||
|
rewrite_in_place(f, stripped)
|
||||||
|
index_file = preconfig / index
|
||||||
|
if dropped and index_file.exists():
|
||||||
|
rewrite_in_place(index_file, [c for c in load_json(index_file) if c.get('chainId') not in dropped])
|
||||||
|
|
||||||
|
|
||||||
def merge_chains(nova_chains: list, pezkuwi_chains: list, blocked_ids: set) -> list:
|
def merge_chains(nova_chains: list, pezkuwi_chains: list, blocked_ids: set) -> list:
|
||||||
@@ -165,6 +205,7 @@ def sync_chains():
|
|||||||
if output_preconfig.exists():
|
if output_preconfig.exists():
|
||||||
shutil.rmtree(output_preconfig)
|
shutil.rmtree(output_preconfig)
|
||||||
shutil.copytree(nova_preconfig, output_preconfig)
|
shutil.copytree(nova_preconfig, output_preconfig)
|
||||||
|
strip_preconfigured(output_preconfig)
|
||||||
|
|
||||||
|
|
||||||
def sync_xcm():
|
def sync_xcm():
|
||||||
|
|||||||
Reference in new issue
Block a user