mirror of
https://github.com/pezkuwichain/pezkuwi-subquery.git
synced 2026-04-22 03:07:57 +00:00
fix: handle pruned RPC state in SubQuery node
Substrate nodes prune historical state by default (~256 blocks). When SubQuery restarts and tries to fetch runtime version for old blocks, it crashes with "State already discarded". This patch adds a fallback to current runtime version when historical state is unavailable, preventing crash loops on pruned RPC endpoints. Also removes --pull from deploy workflow to avoid unnecessary full rebuilds on every push.
This commit is contained in:
@@ -15,5 +15,5 @@ jobs:
|
|||||||
script: |
|
script: |
|
||||||
cd /opt/subquery
|
cd /opt/subquery
|
||||||
git pull origin main
|
git pull origin main
|
||||||
docker compose -f docker-compose.prod.yml build --pull
|
docker compose -f docker-compose.prod.yml build
|
||||||
docker compose -f docker-compose.prod.yml up -d
|
docker compose -f docker-compose.prod.yml up -d
|
||||||
|
|||||||
@@ -41,4 +41,9 @@ RUN node -e " \
|
|||||||
fs.writeFileSync(p, JSON.stringify(pkg, null, 2)); \
|
fs.writeFileSync(p, JSON.stringify(pkg, null, 2)); \
|
||||||
"
|
"
|
||||||
|
|
||||||
|
# Patch: handle pruned blockchain state gracefully.
|
||||||
|
# Without this, SubQuery crashes when RPC nodes have pruned old block state.
|
||||||
|
COPY docker/patches/pruned-state-fallback.js /tmp/pruned-state-fallback.js
|
||||||
|
RUN node /tmp/pruned-state-fallback.js && rm /tmp/pruned-state-fallback.js
|
||||||
|
|
||||||
ENTRYPOINT ["/app/node_modules/.bin/subql-node"]
|
ENTRYPOINT ["/app/node_modules/.bin/subql-node"]
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Patch @subql/node to handle pruned blockchain state.
|
||||||
|
*
|
||||||
|
* Problem: Substrate nodes prune historical state by default (~256 blocks).
|
||||||
|
* When SubQuery restarts and tries to fetch runtime version for old blocks,
|
||||||
|
* state_getRuntimeVersion fails with "State already discarded" and the node
|
||||||
|
* enters a crash loop.
|
||||||
|
*
|
||||||
|
* Fix: When getRuntimeVersion(blockHash) fails due to pruned state,
|
||||||
|
* fall back to getRuntimeVersion() (current runtime version).
|
||||||
|
* This is safe for chains with infrequent spec upgrades.
|
||||||
|
*/
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
// --- Patch 1: base-runtime.service.js ---
|
||||||
|
// Handles getSpecFromApi() and getRuntimeVersion() which call
|
||||||
|
// this.api.rpc.state.getRuntimeVersion(parentBlockHash)
|
||||||
|
const runtimeFile =
|
||||||
|
"/app/node_modules/@subql/node/dist/indexer/runtime/base-runtime.service.js";
|
||||||
|
let runtimeCode = fs.readFileSync(runtimeFile, "utf8");
|
||||||
|
|
||||||
|
const runtimeMatches = (
|
||||||
|
runtimeCode.match(
|
||||||
|
/await this\.api\.rpc\.state\.getRuntimeVersion\(\w+\)/g
|
||||||
|
) || []
|
||||||
|
).length;
|
||||||
|
|
||||||
|
runtimeCode = runtimeCode.replace(
|
||||||
|
/await this\.api\.rpc\.state\.getRuntimeVersion\((\w+)\)/g,
|
||||||
|
"await this.api.rpc.state.getRuntimeVersion($1).catch(() => this.api.rpc.state.getRuntimeVersion())"
|
||||||
|
);
|
||||||
|
fs.writeFileSync(runtimeFile, runtimeCode);
|
||||||
|
console.log(`Patched base-runtime.service.js (${runtimeMatches} call sites)`);
|
||||||
|
|
||||||
|
// --- Patch 2: utils/substrate.js ---
|
||||||
|
// Handles fetchRuntimeVersionRange() which calls
|
||||||
|
// api.rpc.state.getRuntimeVersion(hash).catch((e) => { throw ... })
|
||||||
|
const utilsFile =
|
||||||
|
"/app/node_modules/@subql/node/dist/utils/substrate.js";
|
||||||
|
let utilsCode = fs.readFileSync(utilsFile, "utf8");
|
||||||
|
|
||||||
|
const utilsBefore = utilsCode.includes("getRuntimeVersion(hash).catch((e)");
|
||||||
|
|
||||||
|
// Insert a fallback .catch before the existing error handler:
|
||||||
|
// Original: getRuntimeVersion(hash).catch((e) => { throw... })
|
||||||
|
// Patched: getRuntimeVersion(hash).catch(() => getRuntimeVersion()).catch((e) => { throw... })
|
||||||
|
utilsCode = utilsCode.replace(
|
||||||
|
/api\.rpc\.state\.getRuntimeVersion\(hash\)\.catch\(\(e\)/g,
|
||||||
|
"api.rpc.state.getRuntimeVersion(hash).catch(() => api.rpc.state.getRuntimeVersion()).catch((e)"
|
||||||
|
);
|
||||||
|
fs.writeFileSync(utilsFile, utilsCode);
|
||||||
|
console.log(`Patched utils/substrate.js (had target: ${utilsBefore})`);
|
||||||
|
|
||||||
|
console.log("All pruned-state patches applied.");
|
||||||
Reference in New Issue
Block a user