diff --git a/packages/stargate/package.json b/packages/stargate/package.json index 58f477c7..16f7eb00 100644 --- a/packages/stargate/package.json +++ b/packages/stargate/package.json @@ -50,6 +50,7 @@ "@cosmjs/launchpad": "^0.22.2", "@cosmjs/math": "^0.22.2", "@cosmjs/proto-signing": "^0.22.2", + "@cosmjs/stream": "^0.22.2", "@cosmjs/tendermint-rpc": "^0.22.2", "@cosmjs/utils": "^0.22.2", "protobufjs": "~6.10.0" diff --git a/packages/stargate/src/queries/queryclient.ts b/packages/stargate/src/queries/queryclient.ts index fbf1de91..7b0085e6 100644 --- a/packages/stargate/src/queries/queryclient.ts +++ b/packages/stargate/src/queries/queryclient.ts @@ -1,6 +1,7 @@ /* eslint-disable no-dupe-class-members, @typescript-eslint/ban-types, @typescript-eslint/naming-convention */ import { ics23, verifyExistence, verifyNonExistence } from "@confio/ics23"; -import { fromAscii, toHex } from "@cosmjs/encoding"; +import { fromAscii, toAscii, toHex } from "@cosmjs/encoding"; +import { firstEvent } from "@cosmjs/stream"; import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; import { arrayContentEquals, assert, isNonNullObject } from "@cosmjs/utils"; @@ -241,17 +242,18 @@ export class QueryClient { verifyExistence(subProof.exist, IavlSpec, storeProof.exist.value, key, response.value); } - // make sure we have a valid height to get the headers + // the storeproof must map it's declared value (root of subProof) to the appHash of the next block assert(response.height); - assert(response.height > 0); + if (response.height == 0) { + throw new Error("Query returned height 0, cannot prove it"); + } + // get the header for height+1 + const header = await firstEvent(this.tmClient.subscribeNewBlockHeader()); + if (header.height !== response.height + 1) { + throw new Error(`Query returned height ${response.height}, but next header was ${header.height}`); + } - // the storeproof must may it's declared value (root of subProof) to the appHash - // TODO - // // get the header for height + 1 - // await sleep(5000); // TODO: we can do better - // // TODO: why don't we expose the header query, just height? - // const header = await this.tmClient.block(response.height+1); - // verifyExistence(storeProof.exist, TendermintSpec, header.block.header.appHash, toAscii(store), storeProof.exist.value!); + verifyExistence(storeProof.exist, TendermintSpec, header.appHash, toAscii(store), storeProof.exist.value); return response.value; } diff --git a/yarn.lock b/yarn.lock index 3220ddc9..3e8bf204 100644 --- a/yarn.lock +++ b/yarn.lock @@ -186,6 +186,13 @@ ripemd160 "^2.0.2" sha.js "^2.4.11" +"@cosmjs/stream@^0.22.2": + version "0.22.2" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.22.2.tgz#060c00374d06586a23b53f1f3a7f0bd4aa98557d" + integrity sha512-X3EG8HNn3nW+2iXjff6r8a77crermJ/aSijLxzw1in9+hipF6hG4UmSxN14knSPF6lfqSp80oFoKR6GT1/2r5w== + dependencies: + xstream "^11.10.0" + "@evocateur/libnpmaccess@^3.1.2": version "3.1.2" resolved "https://registry.yarnpkg.com/@evocateur/libnpmaccess/-/libnpmaccess-3.1.2.tgz#ecf7f6ce6b004e9f942b098d92200be4a4b1c845"