Open tuloski opened 1 year ago
agreed that feature would be awesome. posted a similar issue here https://github.com/osmosis-labs/telescope/issues/356
I myself very often query smart contracts but get outdated data without knowing.
I've also run into this problem, though for my use case I'd prefer just knowing the height a query was actually made at, instead of specifying what it should be made at. That way I can do something like "if query height is less than or equal to the last height I got, sleep and try again"
Will open a PR to address this and take it from there... I think it's across a couple different packages
This is a very valid request. The problem with this is that it affects ALL queries of ALL query extensions. Not being able to provide a hight and not getting the query height is a limitation of the API.
I started hacking around, but it would require coordination between cosmjs-types
and packages here. Also didn't have permission to push a branch to cosmjs-types
@webmaster128 - this "monkey patch" is horribly ugly, but it's illustrative and does work in a pinch. Can you please advise on next steps if I can help relieve the burden of getting something like this in, if possible?
In other words, instead of doing what I did here (patching queryAbci()
), I'm thinking there could be a brand new queryContractSmartAndHeight()
which won't break any existing code in the wild, and passes the height all the way through - i.e. the Rpc
interface would also have a new requestAndHeight()
or something. Please let me know if that's unclear.
Here's my current patch, which I wouldn't advise others to do, hehe:
// client is a `SigningCosmWasmClient` or `CosmWasmClient`
// `forceGetQueryClient()` is `protected`, so bypass the type safety
monkeyPatchQuerier((client as any).forceGetQueryClient());
// this throttles stale queries
function monkeyPatchQuerier(querier: Querier) {
const MAX_ATTEMPTS = 5
const SLEEP_TIME_MS = 200
const originalQueryAbci = querier.queryAbci
let lastQueryHeight: number = -1
querier.queryAbci = async (
path: string,
request: Uint8Array,
desiredHeight?: number
): Promise<QueryAbciResponse> => {
let attempts = MAX_ATTEMPTS
while (attempts--) {
// yes, eww
const resp = await originalQueryAbci.bind(
querier,
path,
request,
desiredHeight
)()
if (desiredHeight != undefined) {
return resp
} else if (resp.height >= lastQueryHeight) {
// console.log(
// `LOG: Querying abci at height ${resp.height} succeeded in ${
// MAX_ATTEMPTS - attempts
// } attempts.`
// )
lastQueryHeight = resp.height
return resp
} else {
// console.log(
// `LOG: QUERY abci is backwards at height ${
// resp.height
// }, last height was ${lastQueryHeight}. Attempt #${
// MAX_ATTEMPTS - attempts
// } attempts.`
// )
await new Promise((resolve) => setTimeout(resolve, SLEEP_TIME_MS))
}
}
throw new Error("Failed to query abci, stuck in historical block")
}
}
type Querier = QueryClient &
AuthExtension &
BankExtension &
TxExtension &
WasmExtension
With the WasmExtension for QueryClient is not possible to make a query with a specific height as it can be done with ABCIquery. And I think it's a very useful feature. I myself very often query smart contracts but get outdated data without knowing.