From 305e36cbd96d170958c66ad536080c59f828c59d Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 18 Aug 2020 00:28:55 +0200 Subject: [PATCH] Pull out nextHeader logic --- packages/stargate/src/queries/queryclient.ts | 48 ++++++++++--------- .../stargate/types/queries/queryclient.d.ts | 1 + 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/packages/stargate/src/queries/queryclient.ts b/packages/stargate/src/queries/queryclient.ts index 29074a69..4321cca8 100644 --- a/packages/stargate/src/queries/queryclient.ts +++ b/packages/stargate/src/queries/queryclient.ts @@ -1,12 +1,22 @@ /* eslint-disable no-dupe-class-members, @typescript-eslint/ban-types, @typescript-eslint/naming-convention */ import { iavlSpec, ics23, tendermintSpec, verifyExistence, verifyNonExistence } from "@confio/ics23"; -import { fromAscii, toAscii, toHex } from "@cosmjs/encoding"; +import { toAscii, toHex } from "@cosmjs/encoding"; import { firstEvent } from "@cosmjs/stream"; -import { Client as TendermintClient, ProofOp } from "@cosmjs/tendermint-rpc"; +import { Client as TendermintClient, Header, ProofOp } from "@cosmjs/tendermint-rpc"; import { arrayContentEquals, assert, isNonNullObject } from "@cosmjs/utils"; type QueryExtensionSetup

= (base: QueryClient) => P; +function checkAndParseOp(op: ProofOp, kind: string, key: Uint8Array): ics23.CommitmentProof { + if (op.type !== kind) { + throw new Error(`Op expected to be ${kind}, got "${op.type}`); + } + if (!arrayContentEquals(key, op.key)) { + throw new Error(`Proven key different than queried key.\nQuery: ${toHex(key)}\nProven: ${toHex(op.key)}`); + } + return ics23.CommitmentProof.decode(op.data); +} + export class QueryClient { /** Constructs a QueryClient with 0 extensions */ public static withExtensions(tmClient: TendermintClient): QueryClient; @@ -190,16 +200,7 @@ export class QueryClient { } // the storeproof must map it's declared value (root of subProof) to the appHash of the next block - assert(response.height); - 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}`); - } - + const header = await this.getNextHeader(response.height); verifyExistence(storeProof.exist, tendermintSpec, header.appHash, toAscii(store), storeProof.exist.value); return response.value; @@ -218,16 +219,19 @@ export class QueryClient { return response.value; } -} -function checkAndParseOp(op: ProofOp, kind: string, key: Uint8Array): ics23.CommitmentProof { - if (op.type !== kind) { - throw new Error(`Op expected to be ${kind}, got "${op.type}`); + // this must return the header for height+1 + // throws an error if height is 0 or undefined + private async getNextHeader(height?: number): Promise

{ + assert(height); + if (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 !== height + 1) { + throw new Error(`Query returned height ${height}, but next header was ${header.height}`); + } + return header; } - if (!arrayContentEquals(key, op.key)) { - throw new Error( - `Proven key different than queried key.\nQuery: ${toHex(key)}\nProven: ${toHex(op.key)}`, - ); - } - return ics23.CommitmentProof.decode(op.data); } diff --git a/packages/stargate/types/queries/queryclient.d.ts b/packages/stargate/types/queries/queryclient.d.ts index c00db57b..c4af17ee 100644 --- a/packages/stargate/types/queries/queryclient.d.ts +++ b/packages/stargate/types/queries/queryclient.d.ts @@ -105,5 +105,6 @@ export declare class QueryClient { constructor(tmClient: TendermintClient); queryVerified(store: string, key: Uint8Array): Promise; queryUnverified(path: string, request: Uint8Array): Promise; + private getNextHeader; } export {};