fetch from last block in localStorage

Fetches StorageRequested events after the events already stored in localStorage.
Creates `loadingRecent` ref to track when partial updates are occurring
This commit is contained in:
Eric 2024-06-20 10:54:25 +10:00
parent 1ce47a1f22
commit 73e7e0e5c9
No known key found for this signature in database

View File

@ -45,6 +45,7 @@ export const useRequestsStore = defineStore(
// const requestFailedEvents = ref([]) // {blockNumber, requestId} // const requestFailedEvents = ref([]) // {blockNumber, requestId}
// const requestFinishedEvents = ref([]) // {blockNumber, requestId} // const requestFinishedEvents = ref([]) // {blockNumber, requestId}
const loading = ref(false) const loading = ref(false)
const loadingRecent = ref(false)
const fetched = ref(false) // indicates if past events were fetched const fetched = ref(false) // indicates if past events were fetched
const blocks = ref({}) const blocks = ref({})
// const request = computed(() => count.value * 2) // const request = computed(() => count.value * 2)
@ -97,27 +98,26 @@ export const useRequestsStore = defineStore(
} }
console.log(`fetched ${numSlots} slots in ${(Date.now() - start) / 1000}s`) console.log(`fetched ${numSlots} slots in ${(Date.now() - start) / 1000}s`)
return slots return slots
// blockNumbers.value.add(blockNumber)
} }
const getBlock = async (blockHash) => { const getBlock = async (blockHash) => {
if (Object.keys(blocks.value).includes(blockHash)) { if (Object.keys(blocks.value).includes(blockHash)) {
return blocks.value[blockHash] return blocks.value[blockHash]
} else { } else {
let block = await ethProvider.getBlock(blockHash) let { number, timestamp } = await ethProvider.getBlock(blockHash)
blocks.value[blockHash] = block blocks.value[blockHash] = { number, timestamp }
return block return { number, timestamp }
} }
} }
async function addRequest(requestId, blockHash) { async function addRequest(requestId, blockHash) {
let state = await getRequestState(requestId) let state = await getRequestState(requestId)
let block = await getBlock(blockHash) let { timestamp } = await getBlock(blockHash)
let reqExisting = requests.value[requestId] || {} // just in case it already exists let reqExisting = requests.value[requestId] || {} // just in case it already exists
let request = { let request = {
...reqExisting, ...reqExisting,
state, state,
requestedAt: block.timestamp, requestedAt: timestamp,
requestFinishedId: null, requestFinishedId: null,
detailsFetched: false, detailsFetched: false,
moderated: 'pending' moderated: 'pending'
@ -126,43 +126,60 @@ export const useRequestsStore = defineStore(
return request return request
} }
async function fetchPastRequests() { async function handleStorageRequestEvent(event) {
// query past events let { requestId, ask, expiry } = event.args
if (fetched.value) { let { blockHash, blockNumber } = event
console.log('skipping fetching past requests, already fetched') await addRequest(requestId, blockHash)
return }
}
console.log('fetching past requests') // Returns an array of Promises, where each Promise represents the fetching
loading.value = true // of one StorageRequested event
async function fetchPastRequestsFrom(fromBlock = null) {
console.log(`fetching past requests from ${fromBlock ? `block ${fromBlock}` : 'all time'}`)
try { try {
let events = await marketplace.queryFilter(StorageRequested) let events = await marketplace.queryFilter(StorageRequested, fromBlock)
console.log('got ', events.length, ' StorageRequested events') console.log('got ', events.length, ' StorageRequested events')
events.forEach(async (event, i) => {
console.log('getting details for StorageRequested event ', i)
let start = Date.now()
let { requestId, ask, expiry } = event.args
let { blockHash, blockNumber } = event
await addRequest(requestId, blockHash)
console.log(`got details for ${i} in ${(Date.now() - start) / 1000} seconds`)
if (i === events.length - 1) {
loading.value = false
fetched.value = true
}
})
if (events.length === 0) { if (events.length === 0) {
loading.value = false return []
fetched.value = true
} }
return events.map((event, i) => handleStorageRequestEvent(event)) //{
} catch (error) { } catch (error) {
console.error(`failed to load past contract events: ${error.message}`) console.error(`failed to load past contract events: ${error.message}`)
return []
} }
} }
async function fetchRequest(requestId) { async function fetchPastRequests() {
// query past events
const blocksSorted = Object.values(blocks.value).sort(
(blkA, blkB) => blkB.number - blkA.number
)
const lastBlockNumber = blocksSorted.length ? blocksSorted[0].number : null
if (lastBlockNumber) {
loadingRecent.value = true
} else {
loading.value = true
}
await Promise.all(await fetchPastRequestsFrom(lastBlockNumber + 1))
if (lastBlockNumber) {
loadingRecent.value = false
} else {
loading.value = false
fetched.value = true
}
}
async function fetchRequestDetails(requestId) {
let start = Date.now() let start = Date.now()
console.log('fetching request ', requestId) console.log('fetching request', requestId)
const preFetched = requests.value[requestId] || {} const preFetched = requests.value[requestId] || {}
if (preFetched?.detailsFetched) { if (preFetched?.detailsFetched) {
console.log('request', requestId, 'already fetched')
return return
} }
loading.value = true loading.value = true
@ -224,7 +241,7 @@ export const useRequestsStore = defineStore(
updateRequestFinishedId(requestId, null) updateRequestFinishedId(requestId, null)
} catch (error) { } catch (error) {
if (error instanceof RequestNotFoundError) { if (error instanceof RequestNotFoundError) {
await fetchRequest(requestId) await fetchRequestDetails(requestId)
} }
} }
if (onRequestFinished) { if (onRequestFinished) {
@ -284,7 +301,7 @@ export const useRequestsStore = defineStore(
updateRequestState(requestId, 'Cancelled') updateRequestState(requestId, 'Cancelled')
} catch (error) { } catch (error) {
if (error instanceof RequestNotFoundError) { if (error instanceof RequestNotFoundError) {
await fetchRequest(requestId) await fetchRequestDetails(requestId)
} }
} }
@ -299,7 +316,7 @@ export const useRequestsStore = defineStore(
cancelWaitForRequestFinished(requestId) cancelWaitForRequestFinished(requestId)
} catch (error) { } catch (error) {
if (error instanceof RequestNotFoundError) { if (error instanceof RequestNotFoundError) {
await fetchRequest(requestId) await fetchRequestDetails(requestId)
} }
} }
@ -313,7 +330,7 @@ export const useRequestsStore = defineStore(
updateRequestSlotState(requestId, slotIdx, 'Freed') updateRequestSlotState(requestId, slotIdx, 'Freed')
} catch (error) { } catch (error) {
if (error instanceof RequestNotFoundError) { if (error instanceof RequestNotFoundError) {
await fetchRequest(requestId) await fetchRequestDetails(requestId)
} }
} }
@ -327,7 +344,7 @@ export const useRequestsStore = defineStore(
updateRequestSlotState(requestId, slotIdx, 'Filled') updateRequestSlotState(requestId, slotIdx, 'Filled')
} catch (error) { } catch (error) {
if (error instanceof RequestNotFoundError) { if (error instanceof RequestNotFoundError) {
await fetchRequest(requestId) await fetchRequestDetails(requestId)
} }
} }
@ -340,6 +357,7 @@ export const useRequestsStore = defineStore(
return { return {
requests, requests,
blocks,
// slots, // slots,
// blockNumbers, // blockNumbers,
// storageRequestedEvents, // storageRequestedEvents,
@ -350,7 +368,7 @@ export const useRequestsStore = defineStore(
// requestFailedEvents, // requestFailedEvents,
// requestFinishedEvents, // requestFinishedEvents,
fetchPastRequests, fetchPastRequests,
fetchRequest, fetchRequestDetails,
listenForNewEvents, listenForNewEvents,
loading, loading,
fetched fetched
@ -360,7 +378,11 @@ export const useRequestsStore = defineStore(
persist: { persist: {
serializer: { serializer: {
serialize: (state) => { serialize: (state) => {
return JSON.stringify(state, (_, v) => (typeof v === 'bigint' ? v.toString() : v)) try {
return JSON.stringify(state, (_, v) => (typeof v === 'bigint' ? v.toString() : v))
} catch (e) {
console.error(`failure serializing state`, e)
}
}, },
deserialize: (serialized) => { deserialize: (serialized) => {
// TODO: deserialize bigints properly // TODO: deserialize bigints properly