diff --git a/web/src/hooks/useFetchJSONZST.js b/web/src/hooks/useFetchJSONZST.js index 7ca7578..2106398 100644 --- a/web/src/hooks/useFetchJSONZST.js +++ b/web/src/hooks/useFetchJSONZST.js @@ -3,8 +3,14 @@ import { ZSTDDecoder } from "zstddec"; const zst = new ZSTDDecoder(); export async function fetchJSONZST(url) { + if (url.endsWith(".json")) { + return fetch(url).then((res) => res.json()); + } let initingZst = zst.init(); - let res = await fetch(url); + let res = await fetch(url, { + // IPFS gateways are slow to timeout on their own. + signal: AbortSignal.timeout(8000), // ms + }); if (!res.ok) { throw new Error(`failure fetching JSON ZST from ${url}`); } @@ -15,17 +21,27 @@ export async function fetchJSONZST(url) { return JSON.parse(text); } -export default function useFetchJSONZST(url, options) { - let urls = Array.isArray(url) ? url : [url]; - let results = useQueries( - urls.map((url, i) => ({ +export default function useFetchJSONZST(urls, options) { + return useQueries( + urls.map(({ url, fallbackUrls }, i) => ({ queryKey: ["fetchJSONZST", url], - queryFn: async () => fetchJSONZST(url), + queryFn: async () => { + try { + return await fetchJSONZST(url); + } catch (err) { + console.log(`error fetching ${url}`, err); + for (const fallbackUrl of fallbackUrls) { + console.log(`trying fallback ${fallbackUrl}`); + try { + return await fetchJSONZST(fallbackUrl); + } catch (err) { + console.log(`error fetching ${fallbackUrl}`, err); + } + } + throw err; + } + }, ...((Array.isArray(options) ? options[i] : options) || {}), })) ); - if (!Array.isArray(url)) { - return results[0]; - } - return results; } diff --git a/web/src/hooks/useFetchRewardSnapshots.js b/web/src/hooks/useFetchRewardSnapshots.js index e1774b1..dcb2e8b 100644 --- a/web/src/hooks/useFetchRewardSnapshots.js +++ b/web/src/hooks/useFetchRewardSnapshots.js @@ -1,16 +1,24 @@ import useFetchJSONZST from "./useFetchJSONZST"; import useSetting from "./useSetting"; +// HACK: for now, until we have a better fix for failed IPFS publications. +const fallbackBase = + "https://storage.googleapis.com/lgtm-info-dev-preview/rewards-trees"; +// NOTE: we can't just use "https://github.com/rocket-pool/rewards-trees/raw/main" +// because GitHub doesn't support CORS for raw.githubusercontent.com. + export default function useFetchRewardSnapshots({ snapshots, network = "mainnet", }) { let [ipfsBase] = useSetting("ipfs.base"); let snapshotJsons = useFetchJSONZST( - (snapshots || []).map( - ({ rewardIndex, merkleTreeCID }) => - `${ipfsBase}/ipfs/${merkleTreeCID}/rp-rewards-${network}-${rewardIndex}.json.zst` - ), + (snapshots || []).map(({ rewardIndex, merkleTreeCID }) => ({ + url: `${ipfsBase}/ipfs/${merkleTreeCID}/rp-rewards-${network}-${rewardIndex}.json.zst`, + fallbackUrls: [ + `${fallbackBase}/${network}/rp-rewards-${network}-${rewardIndex}.json`, + ], + })), { enabled: !!ipfsBase, cacheTime: Math.Infinite,