-
Notifications
You must be signed in to change notification settings - Fork 4
feat(sortKey): allow sortKey
or blockHeight
to be provided via qu…
#76
Conversation
…ery param This allows us to evaluate a contract state up to a specified `sortKey` or `blockHeight`.
…point This will restrict the query to the blockheight provided when cross checking evaluated interactions with warp
07f10f4
to
b64fafb
Compare
b64fafb
to
b9875c6
Compare
340fa8e
to
44fa04b
Compare
This allows our interactions endpoint to sort interactions using sorts logic before we compare with their evaluation results.
1c237f2
to
1da0d01
Compare
By default, sortKeys are ordered in ascending order. We reverse this to show most recent interactinos first. We could optionally provide a query param that allows us to select what order to return them in
…date swagger docs
111f925
to
c72eb29
Compare
c72eb29
to
c52bfbe
Compare
c52bfbe
to
a454ff4
Compare
130f01c
to
9d0126b
Compare
3adcc1a
to
367dd80
Compare
…interactions have been fetched
367dd80
to
6e458d1
Compare
src/middleware/query.ts
Outdated
|
||
// Note: this takes sortKey precedence over block height | ||
if (sortKey) { | ||
// TODO: regex on sort key to match warp pattern |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new RegExp('^[0-9]{12},[0-9]{13},[0-9a-fA-F]{64}$')
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added with tests in 26ee31b
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hexidecimal string for the last sortkey segment (last set of characters after a comma) produced by warp's LexicographicalInteractionSorter only produces lowercase hex strings so you can remove A-F
from the final range set in regex.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using reusable parameter components to simplify the doc and make use of reusability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looking good!
name: blockHeight | ||
in: query | ||
required: false | ||
description: Evaluate the contract up to a specific block height. Only applicable if sortKey is not provided. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Too bad OpenAPI doesn't make it easier to specify mutual exclusivity among query parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
} while (hasNextPage); | ||
|
||
return { | ||
interactions, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something to think about - this list will eventually become untenably large and we may have to start thinking about how to handle these types of requests in a streaming fashion (e.g. some combination of generator functions, streamed responses, and pages of data at a time).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we have a ticket to add pagination, but there is more work to do for stream responses/generators - will create a ticket
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pagination is great start. There isn't yet a clear use case for a streaming version and the complexity would be way higher. You're on the right track already.
sortKey: string | undefined; | ||
blockHeight: number | undefined; | ||
}) { | ||
const hash = createHash('sha256'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the motivation for using a hash of these inputs for the cache key rather than literal strings? What are the tradeoffs? e.g. does one provide better cache key collision protection?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
eh, probably a bit of overkill but primarily to create fixed-sized/length strings for the cache keys and it matches our pattern for hashing down our evaluation options. given these are user-provided inputs they have high cardinality and can also be undefined
.
sortKey: undefined
blockHeight: undefined
resulting hash: `465039ec2625fb7eace80f9a3e9bd63dd04b0c55d971f6af1894f4b8c1b3c0ad`
vs.
undefined-undefined
(without adding some special logic to handle empties/undefineds)
as for performance - that's a good call out. i'd be interested to see what type of overhead this generates with a lot of keys created/accessed but given it's such a small amount of data being hashed I don't see a ton of waste?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That essentially confirms my assumptions. Part of me wonders if the hashing layer is worth it though given that:
- Under the hood, PromiseCache, which is built on the simple-cache library's EphemeralCache, has at its base at Map object which is benefiting from all the niceties getting the performance tradeoffs you want from customized hash tables. So, at a base level of running the cache optimally, we're doing redundant work and it may actually be hampering some of what the base implementation is trying to optimize for.
- We may be making debugging harder for ourselves if hash keys we want to inspect are then hashed again, losing some of their original context during the process of the redundant hashing.
I think what you have is ok to ship, but this might be something you want to revisit later.
…mprove readability, add `SmartWeaveAction` tag to gql search Nothing breaking here - just some readabiliity improvements and enhancements. Also updates nodemon to capture `.env` changes for when we are testing against arlocal vs. arweave.net/ar-io.dev
Warp does not create sort keys with uppercase characters
…ery param
This allows us to evaluate a contract state up to a specified
sortKey
orblockHeight
.Block Height example:
Sort Key example:
curl http://localhost:3000/v1/contract/bLAgYxAdX2Ry-nt6aH2ixgvJXbpsEYm28NgJgyqfs-U?sortKey=000001307087,0000000000000,0cbe0824cdf7ba421c49d08ebf6cd0957d0396da8ebe78107a37baa31ed5bbe4
Result: