From 3815b70f668f6ba448acd84b35c5ee6b13840669 Mon Sep 17 00:00:00 2001 From: Marco van Dijk Date: Mon, 7 Mar 2022 12:18:35 +0100 Subject: [PATCH] Fix caching for delegators Added getOrchestratorByDelegator --- backend/src/routes/livepeer.js | 111 ++++++++++++++++++++++++- src/reducers/livepeer/livepeerstate.js | 4 +- 2 files changed, 109 insertions(+), 6 deletions(-) diff --git a/backend/src/routes/livepeer.js b/backend/src/routes/livepeer.js index bc0bdb3..53971cf 100644 --- a/backend/src/routes/livepeer.js +++ b/backend/src/routes/livepeer.js @@ -63,6 +63,8 @@ let serviceUriFeeCostL2 = 0; const timeoutTheGraph = 60000; // Will contain addr, lastGet, and obj of any requested O's let orchestratorCache = []; +// Contains delegator addr and the address of the O they are bounded to +let delegatorCache = []; // Listen to smart contract emitters. Only re-syncs on boot! let eventsCache = []; @@ -411,20 +413,21 @@ const parseOrchestrator = async function (reqAddr) { let orchestratorObj = {}; // First get cached object for (var orch of orchestratorCache) { - if (orch.addr == reqAddr) { + if (orch.id == reqAddr) { wasCached = true; orchestratorObj = orch; break; } } if (wasCached) { - if (now - orch.lastGet < timeoutTheGraph) { + if (now - orchestratorObj.lastGet < timeoutTheGraph) { needsUpdate = false; } } if (!wasCached || needsUpdate) { const orchQuery = gql`{ transcoders(where: {id: "${reqAddr}"}) { + id activationRound deactivationRound active @@ -463,7 +466,9 @@ const parseOrchestrator = async function (reqAddr) { } } `; - orchestratorObj = JSON.stringify(await request("https://api.thegraph.com/subgraphs/name/livepeer/arbitrum-one", orchQuery)); + orchestratorObj = await request("https://api.thegraph.com/subgraphs/name/livepeer/arbitrum-one", orchQuery); + orchestratorObj = orchestratorObj.transcoders[0]; + orchestratorObj.lastGet = now; if (wasCached) { for (var orch of orchestratorCache) { if (orch.addr == requestedOrchestrator) { @@ -475,7 +480,7 @@ const parseOrchestrator = async function (reqAddr) { orchestratorCache.push(orchestratorObj); } } - return orchestratorObj; + return JSON.stringify(orchestratorObj); } // Exports info on a given Orchestrator @@ -508,4 +513,102 @@ apiRouter.post("/getOrchestrator", async (req, res) => { } }); + +// Gets info on a given Delegator +const parseDelegator = async function (reqAddr) { + reqAddr = reqAddr.toLowerCase(); + const now = new Date().getTime(); + // Default assume it's the first time we request this Orchestrator + let wasCached = false; + let needsUpdate = true; + let delegatorObj = {}; + // First get cached object + for (var delegator of delegatorCache) { + if (delegator.id == reqAddr) { + wasCached = true; + delegatorObj = delegator; + break; + } + } + if (wasCached) { + if (now - delegatorObj.lastGet < timeoutTheGraph) { + needsUpdate = false; + } + } + if (!wasCached || needsUpdate) { + const delegatorQuery = gql`{ + delegators(where: { + id: "${reqAddr}" + }){ + id + delegate { + id + } + } + } + `; + delegatorObj = await request("https://api.thegraph.com/subgraphs/name/livepeer/arbitrum-one", delegatorQuery); + delegatorObj = delegatorObj.delegators[0]; + delegatorObj.lastGet = now; + if (wasCached) { + for (var delegator of delegatorCache) { + if (delegator.addr == requestedOrchestrator) { + delegator = delegatorObj; + break; + } + } + } else { + delegatorCache.push(delegatorObj); + } + } + return delegatorObj; +} + +// Exports info on a given Orchestrator by the address any Delegator delegating to them +apiRouter.get("/getOrchestratorByDelegator", async (req, res) => { + try { + const reqDel = req.query.delegatorAddress; + const delObj = await parseDelegator(reqDel); + if (delObj.delegate && delObj.delegate.id) { + const reqObj = await parseOrchestrator(delObj.delegate.id); + res.send(reqObj); + } else { + res.send(JSON.stringify(delObj)); + } + } catch (err) { + console.log(err); + res.status(400).send(err); + } +}); +apiRouter.get("/getOrchestratorByDelegator/:delegatorAddress", async (req, res) => { + try { + const reqDel = req.params.delegatorAddress; + const delObj = await parseDelegator(reqDel); + if (delObj.id && delObj.delegate.id) { + const reqObj = await parseOrchestrator(delObj.delegate.id); + res.send(reqObj); + } else { + res.send(JSON.stringify(delObj)); + } + } catch (err) { + console.log(err); + res.status(400).send(err); + } +}); +apiRouter.post("/getOrchestratorByDelegator", async (req, res) => { + try { + const reqDel = req.body.delegatorAddress; + const delObj = await parseDelegator(reqDel); + if (delObj.id && delObj.delegate.id) { + const reqObj = await parseOrchestrator(delObj.delegate.id); + res.send(reqObj); + } else { + res.send(JSON.stringify(delObj)); + } + } catch (err) { + console.log(err); + res.status(400).send(err); + } +}); + export default apiRouter; \ No newline at end of file diff --git a/src/reducers/livepeer/livepeerstate.js b/src/reducers/livepeer/livepeerstate.js index 7cdc3ee..3d254e5 100644 --- a/src/reducers/livepeer/livepeerstate.js +++ b/src/reducers/livepeer/livepeerstate.js @@ -16,9 +16,9 @@ export default (state = {}, { type, message }) => { case RECEIVE_EVENTS: return { ...state, events: message }; case RECEIVE_CURRENT_ORCHESTRATOR: - return { ...state, thisOrchestrator: message.transcoders[0] }; + return { ...state, thisOrchestrator: message }; case RECEIVE_ORCHESTRATOR: - return { ...state, selectedOrchestrator: message.transcoders[0] }; + return { ...state, selectedOrchestrator: message }; default: return { ...state }; }