From 453f634662cc27b01187124575cd7fd1db52afab Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 18 Nov 2020 14:06:12 +0100 Subject: [PATCH 1/9] Internalize Client.detectVersion and add Client.create --- CHANGELOG.md | 4 ++++ packages/tendermint-rpc/src/client.spec.ts | 18 ++++++++++-------- packages/tendermint-rpc/src/client.ts | 22 +++++++++++++++++----- packages/tendermint-rpc/types/client.d.ts | 11 ++++++++++- 4 files changed, 41 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cae3f29..b15d26cb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,10 @@ - @cosmjs/proto-signing: Add new package for handling transaction signing with protobuf encoding. - @cosmjs/stargate: Add new package for Cosmos SDK Stargate support. +- @cosmjs/tendermint-rpc: Make `Client.detectVersion` private and let it return + a version instead of a client. +- @cosmjs/tendermint-rpc: Add `Client.create` for creating a Tendermint client + given an RPC client. ## 0.23.1 (2020-10-27) diff --git a/packages/tendermint-rpc/src/client.spec.ts b/packages/tendermint-rpc/src/client.spec.ts index 8c1c1a37..b8d02353 100644 --- a/packages/tendermint-rpc/src/client.spec.ts +++ b/packages/tendermint-rpc/src/client.spec.ts @@ -42,6 +42,16 @@ function randomString(): string { } function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expected: ExpectedValues): void { + describe("create", () => { + it("can auto-discover Tendermint version and communicate", async () => { + pendingWithoutTendermint(); + const client = await Client.create(rpcFactory()); + const info = await client.abciInfo(); + expect(info).toBeTruthy(); + client.disconnect(); + }); + }); + it("can connect to tendermint with known version", async () => { pendingWithoutTendermint(); const client = new Client(rpcFactory(), adaptor); @@ -49,14 +59,6 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte client.disconnect(); }); - it("can auto-discover tendermint version and connect", async () => { - pendingWithoutTendermint(); - const client = await Client.detectVersion(rpcFactory()); - const info = await client.abciInfo(); - expect(info).toBeTruthy(); - client.disconnect(); - }); - it("can get genesis", async () => { pendingWithoutTendermint(); const client = new Client(rpcFactory(), adaptor); diff --git a/packages/tendermint-rpc/src/client.ts b/packages/tendermint-rpc/src/client.ts index b5845a75..0b158c1e 100644 --- a/packages/tendermint-rpc/src/client.ts +++ b/packages/tendermint-rpc/src/client.ts @@ -14,13 +14,26 @@ import { } from "./rpcclients"; export class Client { + /** + * Creates a new Tendermint client for the given endpoint. + * + * Uses HTTP when the URL schema is http or https. Uses WebSockets otherwise. + */ public static async connect(url: string): Promise { const useHttp = url.startsWith("http://") || url.startsWith("https://"); - const client = useHttp ? new HttpClient(url) : new WebsocketClient(url); - return this.detectVersion(client); + const rpcClient = useHttp ? new HttpClient(url) : new WebsocketClient(url); + return Client.create(rpcClient); } - public static async detectVersion(client: RpcClient): Promise { + /** + * Creates a new Tendermint client given an RPC client. + */ + public static async create(rpcClient: RpcClient): Promise { + const version = await this.detectVersion(rpcClient); + return new Client(rpcClient, adaptorForVersion(version)); + } + + private static async detectVersion(client: RpcClient): Promise { const req = createJsonRpcRequest(requests.Method.Status); const response = await client.execute(req); const result = response.result; @@ -33,8 +46,7 @@ export class Client { if (typeof version !== "string") { throw new Error("Unrecognized version format: must be string"); } - - return new Client(client, adaptorForVersion(version)); + return version; } private readonly client: RpcClient; diff --git a/packages/tendermint-rpc/types/client.d.ts b/packages/tendermint-rpc/types/client.d.ts index 92606f94..5612c853 100644 --- a/packages/tendermint-rpc/types/client.d.ts +++ b/packages/tendermint-rpc/types/client.d.ts @@ -4,8 +4,17 @@ import * as requests from "./requests"; import * as responses from "./responses"; import { RpcClient } from "./rpcclients"; export declare class Client { + /** + * Creates a new Tendermint client for the given endpoint. + * + * Uses HTTP when the URL schema is http or https. Uses WebSockets otherwise. + */ static connect(url: string): Promise; - static detectVersion(client: RpcClient): Promise; + /** + * Creates a new Tendermint client given an RPC client. + */ + static create(rpcClient: RpcClient): Promise; + private static detectVersion; private readonly client; private readonly p; private readonly r; From 3576bcd332a04821e61e22f674068a41cf5d180c Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 18 Nov 2020 14:35:10 +0100 Subject: [PATCH 2/9] Make Client constructor private, add adaptor to create --- CHANGELOG.md | 5 +- packages/tendermint-rpc/src/client.spec.ts | 56 +++++++++++----------- packages/tendermint-rpc/src/client.ts | 19 ++++++-- packages/tendermint-rpc/types/client.d.ts | 9 +++- 4 files changed, 53 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b15d26cb..768e8da0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,9 @@ - @cosmjs/stargate: Add new package for Cosmos SDK Stargate support. - @cosmjs/tendermint-rpc: Make `Client.detectVersion` private and let it return a version instead of a client. -- @cosmjs/tendermint-rpc: Add `Client.create` for creating a Tendermint client - given an RPC client. +- @cosmjs/tendermint-rpc: Make the constructor of `Client` private. Add + `Client.create` for creating a Tendermint client given an RPC client and an + optional adaptor. ## 0.23.1 (2020-10-27) diff --git a/packages/tendermint-rpc/src/client.spec.ts b/packages/tendermint-rpc/src/client.spec.ts index b8d02353..95d790a8 100644 --- a/packages/tendermint-rpc/src/client.spec.ts +++ b/packages/tendermint-rpc/src/client.spec.ts @@ -50,18 +50,18 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte expect(info).toBeTruthy(); client.disconnect(); }); - }); - it("can connect to tendermint with known version", async () => { - pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); - expect(await client.abciInfo()).toBeTruthy(); - client.disconnect(); + it("can connect to Tendermint with known version", async () => { + pendingWithoutTendermint(); + const client = await Client.create(rpcFactory(), adaptor); + expect(await client.abciInfo()).toBeTruthy(); + client.disconnect(); + }); }); it("can get genesis", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const genesis = await client.genesis(); expect(genesis).toBeTruthy(); client.disconnect(); @@ -69,7 +69,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("can broadcast a transaction", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const tx = buildKvTx(randomString(), randomString()); const response = await client.broadcastTxCommit({ tx: tx }); @@ -87,7 +87,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("gets the same tx hash from backend as calculated locally", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const tx = buildKvTx(randomString(), randomString()); const calculatedTxHash = adaptor.hashTx(tx); @@ -99,7 +99,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("can query the state", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const key = randomString(); const value = randomString(); @@ -118,7 +118,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("can call a bunch of methods", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); expect(await client.block()).toBeTruthy(); expect(await client.commit(4)).toBeTruthy(); @@ -132,7 +132,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte describe("status", () => { it("works", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const status = await client.status(); @@ -161,7 +161,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte describe("blockResults", () => { it("works", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const height = 3; const results = await client.blockResults(height); @@ -177,7 +177,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte describe("blockchain", () => { it("returns latest in descending order by default", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); // Run in parallel to increase chance there is no block between the calls const [status, blockchain] = await Promise.all([client.status(), client.blockchain()]); @@ -194,7 +194,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("can limit by maxHeight", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const height = (await client.status()).syncInfo.latestBlockHeight; const blockchain = await client.blockchain(undefined, height - 1); @@ -208,7 +208,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("works with maxHeight in the future", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const height = (await client.status()).syncInfo.latestBlockHeight; const blockchain = await client.blockchain(undefined, height + 20); @@ -222,7 +222,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("can limit by minHeight and maxHeight", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const height = (await client.status()).syncInfo.latestBlockHeight; const blockchain = await client.blockchain(height - 2, height - 1); @@ -236,7 +236,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("contains all the info", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const height = (await client.status()).syncInfo.latestBlockHeight; const blockchain = await client.blockchain(height - 1, height - 1); @@ -266,7 +266,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte describe("tx", () => { it("can query a tx properly", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const find = randomString(); const me = randomString(); @@ -323,7 +323,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte beforeAll(async () => { if (tendermintEnabled()) { - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); // eslint-disable-next-line no-inner-declarations async function sendTx(): Promise { @@ -349,7 +349,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("can paginate over txSearch results", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const query = buildQuery({ tags: [{ key: "app.key", value: key }] }); @@ -368,7 +368,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expecte it("can get all search results in one call", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const query = buildQuery({ tags: [{ key: "app.key", value: key }] }); @@ -393,7 +393,7 @@ function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expec (async () => { const events: responses.NewBlockHeaderEvent[] = []; - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const stream = client.subscribeNewBlockHeader(); expect(stream).toBeTruthy(); const subscription = stream.subscribe({ @@ -451,7 +451,7 @@ function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expec const transactionData2 = buildKvTx(randomString(), randomString()); const events: responses.NewBlockEvent[] = []; - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const stream = client.subscribeNewBlock(); const subscription = stream.subscribe({ next: (event) => { @@ -507,7 +507,7 @@ function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expec pendingWithoutTendermint(); const events: responses.TxEvent[] = []; - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const stream = client.subscribeTx(); const subscription = stream.subscribe({ next: (event) => { @@ -551,7 +551,7 @@ function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expec const transactionData2 = buildKvTx(randomString(), randomString()); const events: responses.TxEvent[] = []; - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const query = buildQuery({ tags: [{ key: "app.creator", value: expected.appCreator }] }); const stream = client.subscribeTx(query); expect(stream).toBeTruthy(); @@ -589,7 +589,7 @@ function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expec it("can unsubscribe and re-subscribe to the same stream", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const stream = client.subscribeNewBlockHeader(); const event1 = await firstEvent(stream); @@ -622,7 +622,7 @@ function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expec it("can subscribe twice", async () => { pendingWithoutTendermint(); - const client = new Client(rpcFactory(), adaptor); + const client = await Client.create(rpcFactory(), adaptor); const stream1 = client.subscribeNewBlockHeader(); const stream2 = client.subscribeNewBlockHeader(); diff --git a/packages/tendermint-rpc/src/client.ts b/packages/tendermint-rpc/src/client.ts index 0b158c1e..76862189 100644 --- a/packages/tendermint-rpc/src/client.ts +++ b/packages/tendermint-rpc/src/client.ts @@ -27,10 +27,18 @@ export class Client { /** * Creates a new Tendermint client given an RPC client. + * + * If the adaptor is not set, an auto-detection is performed. */ - public static async create(rpcClient: RpcClient): Promise { - const version = await this.detectVersion(rpcClient); - return new Client(rpcClient, adaptorForVersion(version)); + public static async create(rpcClient: RpcClient, adaptor?: Adaptor): Promise { + let usedAdaptor: Adaptor; + if (adaptor) { + usedAdaptor = adaptor; + } else { + const version = await this.detectVersion(rpcClient); + usedAdaptor = adaptorForVersion(version); + } + return new Client(rpcClient, usedAdaptor); } private static async detectVersion(client: RpcClient): Promise { @@ -53,7 +61,10 @@ export class Client { private readonly p: Params; private readonly r: Responses; - public constructor(client: RpcClient, adaptor: Adaptor) { + /** + * Use `Client.connect` or `Client.create` to create an instance. + */ + private constructor(client: RpcClient, adaptor: Adaptor) { this.client = client; this.p = adaptor.params; this.r = adaptor.responses; diff --git a/packages/tendermint-rpc/types/client.d.ts b/packages/tendermint-rpc/types/client.d.ts index 5612c853..ab3d3ec8 100644 --- a/packages/tendermint-rpc/types/client.d.ts +++ b/packages/tendermint-rpc/types/client.d.ts @@ -12,13 +12,18 @@ export declare class Client { static connect(url: string): Promise; /** * Creates a new Tendermint client given an RPC client. + * + * If the adaptor is not set, an auto-detection is performed. */ - static create(rpcClient: RpcClient): Promise; + static create(rpcClient: RpcClient, adaptor?: Adaptor): Promise; private static detectVersion; private readonly client; private readonly p; private readonly r; - constructor(client: RpcClient, adaptor: Adaptor); + /** + * Use `Client.connect` or `Client.create` to create an instance. + */ + private constructor(); disconnect(): void; abciInfo(): Promise; abciQuery(params: requests.AbciQueryParams): Promise; From e4d1fd14259fbfc59db29b2b006ff1eca6312aff Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 18 Nov 2020 14:41:07 +0100 Subject: [PATCH 3/9] Add an optional adaptor argument to Client.connect --- CHANGELOG.md | 2 ++ packages/tendermint-rpc/src/client.ts | 6 ++++-- packages/tendermint-rpc/types/client.d.ts | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 768e8da0..bc1e3044 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ - @cosmjs/tendermint-rpc: Make the constructor of `Client` private. Add `Client.create` for creating a Tendermint client given an RPC client and an optional adaptor. +- @cosmjs/tendermint-rpc: Add an optional adaptor argument to `Client.connect` + which allows skipping the auto-detection. ## 0.23.1 (2020-10-27) diff --git a/packages/tendermint-rpc/src/client.ts b/packages/tendermint-rpc/src/client.ts index 76862189..c34b0d55 100644 --- a/packages/tendermint-rpc/src/client.ts +++ b/packages/tendermint-rpc/src/client.ts @@ -18,11 +18,13 @@ export class Client { * Creates a new Tendermint client for the given endpoint. * * Uses HTTP when the URL schema is http or https. Uses WebSockets otherwise. + * + * If the adaptor is not set an auto-detection is performed. */ - public static async connect(url: string): Promise { + public static async connect(url: string, adaptor?: Adaptor): Promise { const useHttp = url.startsWith("http://") || url.startsWith("https://"); const rpcClient = useHttp ? new HttpClient(url) : new WebsocketClient(url); - return Client.create(rpcClient); + return Client.create(rpcClient, adaptor); } /** diff --git a/packages/tendermint-rpc/types/client.d.ts b/packages/tendermint-rpc/types/client.d.ts index ab3d3ec8..836c3058 100644 --- a/packages/tendermint-rpc/types/client.d.ts +++ b/packages/tendermint-rpc/types/client.d.ts @@ -8,8 +8,10 @@ export declare class Client { * Creates a new Tendermint client for the given endpoint. * * Uses HTTP when the URL schema is http or https. Uses WebSockets otherwise. + * + * If the adaptor is not set an auto-detection is performed. */ - static connect(url: string): Promise; + static connect(url: string, adaptor?: Adaptor): Promise; /** * Creates a new Tendermint client given an RPC client. * From bfd9ebeeed26cfa8cabb063a95e07671d7501126 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 18 Nov 2020 14:47:59 +0100 Subject: [PATCH 4/9] Organize adaptor exports --- CHANGELOG.md | 2 + .../tendermint-rpc/src/adaptorforversion.ts | 26 ---------- packages/tendermint-rpc/src/adaptors/index.ts | 50 +++++++++++++++++++ .../src/{ => adaptors}/v0-33/hasher.spec.ts | 4 +- .../src/{ => adaptors}/v0-33/hasher.ts | 13 +++-- .../src/{ => adaptors}/v0-33/index.ts | 2 +- .../src/{ => adaptors}/v0-33/requests.ts | 14 ++++-- .../src/{ => adaptors}/v0-33/responses.ts | 8 +-- packages/tendermint-rpc/src/client.spec.ts | 2 +- packages/tendermint-rpc/src/client.ts | 2 +- packages/tendermint-rpc/src/index.ts | 6 +-- .../types/adaptorforversion.d.ts | 8 --- .../tendermint-rpc/types/adaptors/index.d.ts | 32 ++++++++++++ .../types/{ => adaptors}/v0-33/hasher.d.ts | 4 +- .../types/adaptors/v0-33/hasher.spec.d.ts | 1 + .../types/adaptors/v0-33/index.d.ts | 2 + .../types/{ => adaptors}/v0-33/requests.d.ts | 2 +- .../types/{ => adaptors}/v0-33/responses.d.ts | 6 +-- packages/tendermint-rpc/types/index.d.ts | 3 +- .../tendermint-rpc/types/v0-33/index.d.ts | 2 - 20 files changed, 127 insertions(+), 62 deletions(-) delete mode 100644 packages/tendermint-rpc/src/adaptorforversion.ts create mode 100644 packages/tendermint-rpc/src/adaptors/index.ts rename packages/tendermint-rpc/src/{ => adaptors}/v0-33/hasher.spec.ts (97%) rename packages/tendermint-rpc/src/{ => adaptors}/v0-33/hasher.ts (90%) rename packages/tendermint-rpc/src/{ => adaptors}/v0-33/index.ts (88%) rename packages/tendermint-rpc/src/{ => adaptors}/v0-33/requests.ts (95%) rename packages/tendermint-rpc/src/{ => adaptors}/v0-33/responses.ts (99%) delete mode 100644 packages/tendermint-rpc/types/adaptorforversion.d.ts create mode 100644 packages/tendermint-rpc/types/adaptors/index.d.ts rename packages/tendermint-rpc/types/{ => adaptors}/v0-33/hasher.d.ts (53%) create mode 100644 packages/tendermint-rpc/types/adaptors/v0-33/hasher.spec.d.ts create mode 100644 packages/tendermint-rpc/types/adaptors/v0-33/index.d.ts rename packages/tendermint-rpc/types/{ => adaptors}/v0-33/requests.d.ts (96%) rename packages/tendermint-rpc/types/{ => adaptors}/v0-33/responses.d.ts (92%) delete mode 100644 packages/tendermint-rpc/types/v0-33/index.d.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index bc1e3044..b2b4903c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,8 @@ optional adaptor. - @cosmjs/tendermint-rpc: Add an optional adaptor argument to `Client.connect` which allows skipping the auto-detection. +- @cosmjs/tendermint-rpc: Remove export `v0_33` in favour of `adaptor33` and + `adaptor34`. Export the `Adaptor` type. ## 0.23.1 (2020-10-27) diff --git a/packages/tendermint-rpc/src/adaptorforversion.ts b/packages/tendermint-rpc/src/adaptorforversion.ts deleted file mode 100644 index d991c3cd..00000000 --- a/packages/tendermint-rpc/src/adaptorforversion.ts +++ /dev/null @@ -1,26 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -// This module exposes translators for multiple tendermint versions -// Pick a version that matches the server to properly encode the data types -import { Adaptor } from "./adaptor"; -import { v0_33 } from "./v0-33"; - -const hashes = { - v0_34: [ - "ca2c9df", // v0.34.0-rc6 - "", // See https://github.com/cosmos/cosmos-sdk/issues/7963 - ], -}; - -/** - * Returns an Adaptor implementation for a given tendermint version. - * Throws when version is not supported. - * - * @param version full Tendermint version string, e.g. "0.20.1" - */ -export function adaptorForVersion(version: string): Adaptor { - if (version.startsWith("0.33.") || version.startsWith("0.34.") || hashes.v0_34.includes(version)) { - return v0_33; - } else { - throw new Error(`Unsupported tendermint version: ${version}`); - } -} diff --git a/packages/tendermint-rpc/src/adaptors/index.ts b/packages/tendermint-rpc/src/adaptors/index.ts new file mode 100644 index 00000000..eb74c9c6 --- /dev/null +++ b/packages/tendermint-rpc/src/adaptors/index.ts @@ -0,0 +1,50 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { Adaptor } from "../adaptor"; +import { v0_33 } from "./v0-33"; + +/** + * Adaptor for Tendermint 0.33. + * + * Use this to skip auto-detection: + * + * ``` + * import { adaptor33, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; + * // ... + * const client = await TendermintClient.connect(url, adaptor33); + * ``` + */ +export const adaptor33 = v0_33; + +/** + * Adaptor for Tendermint 0.34. + * + * Use this to skip auto-detection: + * + * ``` + * import { adaptor34, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; + * // ... + * const client = await TendermintClient.connect(url, adaptor34); + * ``` + */ +export const adaptor34 = v0_33; // With this alias we can swap out the implementation without affecting caller code. + +const hashes = { + v0_34: [ + "ca2c9df", // v0.34.0-rc6 + "", // See https://github.com/cosmos/cosmos-sdk/issues/7963 + ], +}; + +/** + * Returns an Adaptor implementation for a given tendermint version. + * Throws when version is not supported. + * + * @param version full Tendermint version string, e.g. "0.20.1" + */ +export function adaptorForVersion(version: string): Adaptor { + if (version.startsWith("0.33.") || version.startsWith("0.34.") || hashes.v0_34.includes(version)) { + return v0_33; + } else { + throw new Error(`Unsupported tendermint version: ${version}`); + } +} diff --git a/packages/tendermint-rpc/src/v0-33/hasher.spec.ts b/packages/tendermint-rpc/src/adaptors/v0-33/hasher.spec.ts similarity index 97% rename from packages/tendermint-rpc/src/v0-33/hasher.spec.ts rename to packages/tendermint-rpc/src/adaptors/v0-33/hasher.spec.ts index 96d9feb0..6793f8b3 100644 --- a/packages/tendermint-rpc/src/v0-33/hasher.spec.ts +++ b/packages/tendermint-rpc/src/adaptors/v0-33/hasher.spec.ts @@ -1,8 +1,8 @@ import { fromBase64, fromHex } from "@cosmjs/encoding"; import { ReadonlyDate } from "readonly-date"; -import { ReadonlyDateWithNanoseconds } from "../responses"; -import { TxBytes } from "../types"; +import { ReadonlyDateWithNanoseconds } from "../../responses"; +import { TxBytes } from "../../types"; import { hashBlock, hashTx } from "./hasher"; describe("Hasher", () => { diff --git a/packages/tendermint-rpc/src/v0-33/hasher.ts b/packages/tendermint-rpc/src/adaptors/v0-33/hasher.ts similarity index 90% rename from packages/tendermint-rpc/src/v0-33/hasher.ts rename to packages/tendermint-rpc/src/adaptors/v0-33/hasher.ts index 4401053b..3fc0c6ce 100644 --- a/packages/tendermint-rpc/src/v0-33/hasher.ts +++ b/packages/tendermint-rpc/src/adaptors/v0-33/hasher.ts @@ -1,8 +1,15 @@ import { Sha256 } from "@cosmjs/crypto"; -import { encodeBlockId, encodeBytes, encodeInt, encodeString, encodeTime, encodeVersion } from "../encodings"; -import { Header } from "../responses"; -import { BlockHash, TxBytes, TxHash } from "../types"; +import { + encodeBlockId, + encodeBytes, + encodeInt, + encodeString, + encodeTime, + encodeVersion, +} from "../../encodings"; +import { Header } from "../../responses"; +import { BlockHash, TxBytes, TxHash } from "../../types"; // hash is sha256 // https://github.com/tendermint/tendermint/blob/master/UPGRADING.md#v0260 diff --git a/packages/tendermint-rpc/src/v0-33/index.ts b/packages/tendermint-rpc/src/adaptors/v0-33/index.ts similarity index 88% rename from packages/tendermint-rpc/src/v0-33/index.ts rename to packages/tendermint-rpc/src/adaptors/v0-33/index.ts index af38b9cf..fb1e8a76 100644 --- a/packages/tendermint-rpc/src/v0-33/index.ts +++ b/packages/tendermint-rpc/src/adaptors/v0-33/index.ts @@ -1,5 +1,5 @@ /* eslint-disable @typescript-eslint/naming-convention */ -import { Adaptor } from "../adaptor"; +import { Adaptor } from "../../adaptor"; import { hashBlock, hashTx } from "./hasher"; import { Params } from "./requests"; import { Responses } from "./responses"; diff --git a/packages/tendermint-rpc/src/v0-33/requests.ts b/packages/tendermint-rpc/src/adaptors/v0-33/requests.ts similarity index 95% rename from packages/tendermint-rpc/src/v0-33/requests.ts rename to packages/tendermint-rpc/src/adaptors/v0-33/requests.ts index 0e6b71c3..f9501bff 100644 --- a/packages/tendermint-rpc/src/v0-33/requests.ts +++ b/packages/tendermint-rpc/src/adaptors/v0-33/requests.ts @@ -2,9 +2,17 @@ import { toHex } from "@cosmjs/encoding"; import { JsonRpcRequest } from "@cosmjs/json-rpc"; -import { assertNotEmpty, Base64, Base64String, HexString, Integer, IntegerString, may } from "../encodings"; -import { createJsonRpcRequest } from "../jsonrpc"; -import * as requests from "../requests"; +import { + assertNotEmpty, + Base64, + Base64String, + HexString, + Integer, + IntegerString, + may, +} from "../../encodings"; +import { createJsonRpcRequest } from "../../jsonrpc"; +import * as requests from "../../requests"; interface HeightParam { readonly height?: number; diff --git a/packages/tendermint-rpc/src/v0-33/responses.ts b/packages/tendermint-rpc/src/adaptors/v0-33/responses.ts similarity index 99% rename from packages/tendermint-rpc/src/v0-33/responses.ts rename to packages/tendermint-rpc/src/adaptors/v0-33/responses.ts index d3dd6814..6bfe82dc 100644 --- a/packages/tendermint-rpc/src/v0-33/responses.ts +++ b/packages/tendermint-rpc/src/adaptors/v0-33/responses.ts @@ -20,10 +20,10 @@ import { IntegerString, may, optional, -} from "../encodings"; -import * as responses from "../responses"; -import { SubscriptionEvent } from "../rpcclients"; -import { IpPortString, TxBytes, TxHash, ValidatorPubkey, ValidatorSignature } from "../types"; +} from "../../encodings"; +import * as responses from "../../responses"; +import { SubscriptionEvent } from "../../rpcclients"; +import { IpPortString, TxBytes, TxHash, ValidatorPubkey, ValidatorSignature } from "../../types"; import { hashTx } from "./hasher"; interface AbciInfoResult { diff --git a/packages/tendermint-rpc/src/client.spec.ts b/packages/tendermint-rpc/src/client.spec.ts index 95d790a8..55ea3107 100644 --- a/packages/tendermint-rpc/src/client.spec.ts +++ b/packages/tendermint-rpc/src/client.spec.ts @@ -6,7 +6,7 @@ import { ReadonlyDate } from "readonly-date"; import { Stream } from "xstream"; import { Adaptor } from "./adaptor"; -import { adaptorForVersion } from "./adaptorforversion"; +import { adaptorForVersion } from "./adaptors"; import { Client } from "./client"; import { ExpectedValues, tendermintInstances } from "./config.spec"; import { buildQuery } from "./requests"; diff --git a/packages/tendermint-rpc/src/client.ts b/packages/tendermint-rpc/src/client.ts index c34b0d55..f666d800 100644 --- a/packages/tendermint-rpc/src/client.ts +++ b/packages/tendermint-rpc/src/client.ts @@ -1,7 +1,7 @@ import { Stream } from "xstream"; import { Adaptor, Decoder, Encoder, Params, Responses } from "./adaptor"; -import { adaptorForVersion } from "./adaptorforversion"; +import { adaptorForVersion } from "./adaptors"; import { createJsonRpcRequest } from "./jsonrpc"; import * as requests from "./requests"; import * as responses from "./responses"; diff --git a/packages/tendermint-rpc/src/index.ts b/packages/tendermint-rpc/src/index.ts index 011deb0c..eb72f812 100644 --- a/packages/tendermint-rpc/src/index.ts +++ b/packages/tendermint-rpc/src/index.ts @@ -1,7 +1,5 @@ -/* eslint-disable @typescript-eslint/naming-convention */ -// exported to access version-specific hashing -export { v0_33 } from "./v0-33"; - +export { Adaptor } from "./adaptor"; +export { adaptor33, adaptor34 } from "./adaptors"; export { Client } from "./client"; export { AbciInfoRequest, diff --git a/packages/tendermint-rpc/types/adaptorforversion.d.ts b/packages/tendermint-rpc/types/adaptorforversion.d.ts deleted file mode 100644 index caf42fd7..00000000 --- a/packages/tendermint-rpc/types/adaptorforversion.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Adaptor } from "./adaptor"; -/** - * Returns an Adaptor implementation for a given tendermint version. - * Throws when version is not supported. - * - * @param version full Tendermint version string, e.g. "0.20.1" - */ -export declare function adaptorForVersion(version: string): Adaptor; diff --git a/packages/tendermint-rpc/types/adaptors/index.d.ts b/packages/tendermint-rpc/types/adaptors/index.d.ts new file mode 100644 index 00000000..7cf00005 --- /dev/null +++ b/packages/tendermint-rpc/types/adaptors/index.d.ts @@ -0,0 +1,32 @@ +import { Adaptor } from "../adaptor"; +/** + * Adaptor for Tendermint 0.33. + * + * Use this to skip auto-detection: + * + * ``` + * import { adaptor33, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; + * // ... + * const client = await TendermintClient.connect(url, adaptor33); + * ``` + */ +export declare const adaptor33: Adaptor; +/** + * Adaptor for Tendermint 0.34. + * + * Use this to skip auto-detection: + * + * ``` + * import { adaptor34, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; + * // ... + * const client = await TendermintClient.connect(url, adaptor34); + * ``` + */ +export declare const adaptor34: Adaptor; +/** + * Returns an Adaptor implementation for a given tendermint version. + * Throws when version is not supported. + * + * @param version full Tendermint version string, e.g. "0.20.1" + */ +export declare function adaptorForVersion(version: string): Adaptor; diff --git a/packages/tendermint-rpc/types/v0-33/hasher.d.ts b/packages/tendermint-rpc/types/adaptors/v0-33/hasher.d.ts similarity index 53% rename from packages/tendermint-rpc/types/v0-33/hasher.d.ts rename to packages/tendermint-rpc/types/adaptors/v0-33/hasher.d.ts index de2e7e90..f89426d8 100644 --- a/packages/tendermint-rpc/types/v0-33/hasher.d.ts +++ b/packages/tendermint-rpc/types/adaptors/v0-33/hasher.d.ts @@ -1,4 +1,4 @@ -import { Header } from "../responses"; -import { BlockHash, TxBytes, TxHash } from "../types"; +import { Header } from "../../responses"; +import { BlockHash, TxBytes, TxHash } from "../../types"; export declare function hashTx(tx: TxBytes): TxHash; export declare function hashBlock(header: Header): BlockHash; diff --git a/packages/tendermint-rpc/types/adaptors/v0-33/hasher.spec.d.ts b/packages/tendermint-rpc/types/adaptors/v0-33/hasher.spec.d.ts new file mode 100644 index 00000000..cb0ff5c3 --- /dev/null +++ b/packages/tendermint-rpc/types/adaptors/v0-33/hasher.spec.d.ts @@ -0,0 +1 @@ +export {}; diff --git a/packages/tendermint-rpc/types/adaptors/v0-33/index.d.ts b/packages/tendermint-rpc/types/adaptors/v0-33/index.d.ts new file mode 100644 index 00000000..d4c71fcd --- /dev/null +++ b/packages/tendermint-rpc/types/adaptors/v0-33/index.d.ts @@ -0,0 +1,2 @@ +import { Adaptor } from "../../adaptor"; +export declare const v0_33: Adaptor; diff --git a/packages/tendermint-rpc/types/v0-33/requests.d.ts b/packages/tendermint-rpc/types/adaptors/v0-33/requests.d.ts similarity index 96% rename from packages/tendermint-rpc/types/v0-33/requests.d.ts rename to packages/tendermint-rpc/types/adaptors/v0-33/requests.d.ts index bdfaa960..ad142450 100644 --- a/packages/tendermint-rpc/types/v0-33/requests.d.ts +++ b/packages/tendermint-rpc/types/adaptors/v0-33/requests.d.ts @@ -1,5 +1,5 @@ import { JsonRpcRequest } from "@cosmjs/json-rpc"; -import * as requests from "../requests"; +import * as requests from "../../requests"; export declare class Params { static encodeAbciInfo(req: requests.AbciInfoRequest): JsonRpcRequest; static encodeAbciQuery(req: requests.AbciQueryRequest): JsonRpcRequest; diff --git a/packages/tendermint-rpc/types/v0-33/responses.d.ts b/packages/tendermint-rpc/types/adaptors/v0-33/responses.d.ts similarity index 92% rename from packages/tendermint-rpc/types/v0-33/responses.d.ts rename to packages/tendermint-rpc/types/adaptors/v0-33/responses.d.ts index 5aee6a64..0024c2ce 100644 --- a/packages/tendermint-rpc/types/v0-33/responses.d.ts +++ b/packages/tendermint-rpc/types/adaptors/v0-33/responses.d.ts @@ -1,7 +1,7 @@ import { JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; -import { Base64String } from "../encodings"; -import * as responses from "../responses"; -import { SubscriptionEvent } from "../rpcclients"; +import { Base64String } from "../../encodings"; +import * as responses from "../../responses"; +import { SubscriptionEvent } from "../../rpcclients"; export interface RpcProofOp { readonly type: string; readonly key: Base64String; diff --git a/packages/tendermint-rpc/types/index.d.ts b/packages/tendermint-rpc/types/index.d.ts index 08ed5bf3..6b0ca746 100644 --- a/packages/tendermint-rpc/types/index.d.ts +++ b/packages/tendermint-rpc/types/index.d.ts @@ -1,4 +1,5 @@ -export { v0_33 } from "./v0-33"; +export { Adaptor } from "./adaptor"; +export { adaptor33, adaptor34 } from "./adaptors"; export { Client } from "./client"; export { AbciInfoRequest, diff --git a/packages/tendermint-rpc/types/v0-33/index.d.ts b/packages/tendermint-rpc/types/v0-33/index.d.ts deleted file mode 100644 index f5b2b014..00000000 --- a/packages/tendermint-rpc/types/v0-33/index.d.ts +++ /dev/null @@ -1,2 +0,0 @@ -import { Adaptor } from "../adaptor"; -export declare const v0_33: Adaptor; From dc8c58081c11566bf2052681d1759d67debdea65 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 18 Nov 2020 14:53:28 +0100 Subject: [PATCH 5/9] Specify Tendermint version explicitly in stargate --- packages/stargate/src/queries/auth.spec.ts | 4 ++-- packages/stargate/src/queries/bank.spec.ts | 4 ++-- packages/stargate/src/queries/ibc.spec.ts | 4 ++-- packages/stargate/src/queries/queryclient.spec.ts | 4 ++-- packages/stargate/src/signingstargateclient.ts | 4 ++-- packages/stargate/src/stargateclient.ts | 9 +++++++-- packages/tendermint-rpc/src/adaptors/index.ts | 1 - .../tendermint-rpc/src/adaptors/v0-33/responses.ts | 5 ++--- packages/tendermint-rpc/src/encodings.ts | 14 ++++++++++++++ packages/tendermint-rpc/types/encodings.d.ts | 7 +++++++ 10 files changed, 40 insertions(+), 16 deletions(-) diff --git a/packages/stargate/src/queries/auth.spec.ts b/packages/stargate/src/queries/auth.spec.ts index 4285c19e..602b8f29 100644 --- a/packages/stargate/src/queries/auth.spec.ts +++ b/packages/stargate/src/queries/auth.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { encodePubkey } from "@cosmjs/proto-signing"; -import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; +import { adaptor34, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; import { assert } from "@cosmjs/utils"; import Long from "long"; @@ -12,7 +12,7 @@ import { QueryClient } from "./queryclient"; const { Any } = google.protobuf; async function makeClientWithAuth(rpcUrl: string): Promise<[QueryClient & AuthExtension, TendermintClient]> { - const tmClient = await TendermintClient.connect(rpcUrl); + const tmClient = await TendermintClient.connect(rpcUrl, adaptor34); return [QueryClient.withExtensions(tmClient, setupAuthExtension), tmClient]; } diff --git a/packages/stargate/src/queries/bank.spec.ts b/packages/stargate/src/queries/bank.spec.ts index b45ed5eb..17ebf62e 100644 --- a/packages/stargate/src/queries/bank.spec.ts +++ b/packages/stargate/src/queries/bank.spec.ts @@ -1,4 +1,4 @@ -import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; +import { adaptor34, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; import { nonExistentAddress, @@ -11,7 +11,7 @@ import { BankExtension, setupBankExtension } from "./bank"; import { QueryClient } from "./queryclient"; async function makeClientWithBank(rpcUrl: string): Promise<[QueryClient & BankExtension, TendermintClient]> { - const tmClient = await TendermintClient.connect(rpcUrl); + const tmClient = await TendermintClient.connect(rpcUrl, adaptor34); return [QueryClient.withExtensions(tmClient, setupBankExtension), tmClient]; } diff --git a/packages/stargate/src/queries/ibc.spec.ts b/packages/stargate/src/queries/ibc.spec.ts index 6d9fecd2..75bdba1f 100644 --- a/packages/stargate/src/queries/ibc.spec.ts +++ b/packages/stargate/src/queries/ibc.spec.ts @@ -1,4 +1,4 @@ -import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; +import { adaptor34, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; import Long from "long"; import { cosmos, ibc } from "../codec"; @@ -8,7 +8,7 @@ import * as ibcTest from "./ibctestdata.spec"; import { QueryClient } from "./queryclient"; async function makeClientWithIbc(rpcUrl: string): Promise<[QueryClient & IbcExtension, TendermintClient]> { - const tmClient = await TendermintClient.connect(rpcUrl); + const tmClient = await TendermintClient.connect(rpcUrl, adaptor34); return [QueryClient.withExtensions(tmClient, setupIbcExtension), tmClient]; } diff --git a/packages/stargate/src/queries/queryclient.spec.ts b/packages/stargate/src/queries/queryclient.spec.ts index 6955c622..2f75e4e4 100644 --- a/packages/stargate/src/queries/queryclient.spec.ts +++ b/packages/stargate/src/queries/queryclient.spec.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/naming-convention */ import { toAscii } from "@cosmjs/encoding"; -import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; +import { adaptor34, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; import { cosmos } from "../codec"; import { nonNegativeIntegerMatcher, pendingWithoutSimapp, simapp, unused } from "../testutils.spec"; @@ -11,7 +11,7 @@ const { Coin } = cosmos.base.v1beta1; const { QueryAllBalancesRequest, QueryAllBalancesResponse } = cosmos.bank.v1beta1; async function makeClient(rpcUrl: string): Promise<[QueryClient, TendermintClient]> { - const tmClient = await TendermintClient.connect(rpcUrl); + const tmClient = await TendermintClient.connect(rpcUrl, adaptor34); return [QueryClient.withExtensions(tmClient), tmClient]; } diff --git a/packages/stargate/src/signingstargateclient.ts b/packages/stargate/src/signingstargateclient.ts index d4bd344a..c93c822b 100644 --- a/packages/stargate/src/signingstargateclient.ts +++ b/packages/stargate/src/signingstargateclient.ts @@ -21,7 +21,7 @@ import { OfflineSigner, Registry, } from "@cosmjs/proto-signing"; -import { Client as TendermintClient } from "@cosmjs/tendermint-rpc"; +import { adaptor34, Client as TendermintClient } from "@cosmjs/tendermint-rpc"; import { cosmos } from "./codec"; import { getMsgType } from "./encoding"; @@ -54,7 +54,7 @@ export class SigningStargateClient extends StargateClient { signer: OfflineSigner, options: SigningStargateClientOptions = {}, ): Promise { - const tmClient = await TendermintClient.connect(endpoint); + const tmClient = await TendermintClient.connect(endpoint, adaptor34); return new SigningStargateClient(tmClient, signer, options); } diff --git a/packages/stargate/src/stargateclient.ts b/packages/stargate/src/stargateclient.ts index f482d820..c4726fd9 100644 --- a/packages/stargate/src/stargateclient.ts +++ b/packages/stargate/src/stargateclient.ts @@ -13,7 +13,12 @@ import { } from "@cosmjs/launchpad"; import { Uint53, Uint64 } from "@cosmjs/math"; import { decodePubkey } from "@cosmjs/proto-signing"; -import { broadcastTxCommitSuccess, Client as TendermintClient, QueryString } from "@cosmjs/tendermint-rpc"; +import { + adaptor34, + broadcastTxCommitSuccess, + Client as TendermintClient, + QueryString, +} from "@cosmjs/tendermint-rpc"; import { assert, assertDefined } from "@cosmjs/utils"; import Long from "long"; @@ -121,7 +126,7 @@ export class StargateClient { private chainId: string | undefined; public static async connect(endpoint: string): Promise { - const tmClient = await TendermintClient.connect(endpoint); + const tmClient = await TendermintClient.connect(endpoint, adaptor34); return new StargateClient(tmClient); } diff --git a/packages/tendermint-rpc/src/adaptors/index.ts b/packages/tendermint-rpc/src/adaptors/index.ts index eb74c9c6..4a164f48 100644 --- a/packages/tendermint-rpc/src/adaptors/index.ts +++ b/packages/tendermint-rpc/src/adaptors/index.ts @@ -31,7 +31,6 @@ export const adaptor34 = v0_33; // With this alias we can swap out the implement const hashes = { v0_34: [ "ca2c9df", // v0.34.0-rc6 - "", // See https://github.com/cosmos/cosmos-sdk/issues/7963 ], }; diff --git a/packages/tendermint-rpc/src/adaptors/v0-33/responses.ts b/packages/tendermint-rpc/src/adaptors/v0-33/responses.ts index 6bfe82dc..81af176e 100644 --- a/packages/tendermint-rpc/src/adaptors/v0-33/responses.ts +++ b/packages/tendermint-rpc/src/adaptors/v0-33/responses.ts @@ -9,6 +9,7 @@ import { assertNumber, assertObject, assertSet, + assertString, Base64, Base64String, DateTime, @@ -502,9 +503,7 @@ function decodeNodeInfo(data: RpcNodeInfo): responses.NodeInfo { id: fromHex(assertNotEmpty(data.id)), listenAddr: assertNotEmpty(data.listen_addr), network: assertNotEmpty(data.network), - // TODO: Reactivate check when https://github.com/cosmos/cosmos-sdk/issues/7963 is resolved - // version: assertNotEmpty(data.version), - version: data.version, + version: assertString(data.version), // Can be empty (https://github.com/cosmos/cosmos-sdk/issues/7963) channels: assertNotEmpty(data.channels), moniker: assertNotEmpty(data.moniker), other: dictionaryToStringMap(data.other), diff --git a/packages/tendermint-rpc/src/encodings.ts b/packages/tendermint-rpc/src/encodings.ts index 9b48761a..9266fcc1 100644 --- a/packages/tendermint-rpc/src/encodings.ts +++ b/packages/tendermint-rpc/src/encodings.ts @@ -40,6 +40,20 @@ export function assertBoolean(value: boolean): boolean { return value; } +/** + * A runtime checker that ensures a given value is a string. + * + * This is used when you want to verify that data at runtime matches the expected type. + * This implies assertSet. + */ +export function assertString(value: string): string { + assertSet(value); + if (typeof (value as unknown) !== "string") { + throw new Error("Value must be a string"); + } + return value; +} + /** * A runtime checker that ensures a given value is a number * diff --git a/packages/tendermint-rpc/types/encodings.d.ts b/packages/tendermint-rpc/types/encodings.d.ts index 151d7af5..cd004f17 100644 --- a/packages/tendermint-rpc/types/encodings.d.ts +++ b/packages/tendermint-rpc/types/encodings.d.ts @@ -17,6 +17,13 @@ export declare function assertSet(value: T): T; * This implies assertSet. */ export declare function assertBoolean(value: boolean): boolean; +/** + * A runtime checker that ensures a given value is a string. + * + * This is used when you want to verify that data at runtime matches the expected type. + * This implies assertSet. + */ +export declare function assertString(value: string): string; /** * A runtime checker that ensures a given value is a number * From 2c26011e9b896d7734c457cf10e229fdc2c4aa42 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Wed, 18 Nov 2020 18:40:04 +0100 Subject: [PATCH 6/9] Add missing disconnects in StargateClient tests --- packages/stargate/src/stargateclient.spec.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/packages/stargate/src/stargateclient.spec.ts b/packages/stargate/src/stargateclient.spec.ts index 857c1f01..6cc6877b 100644 --- a/packages/stargate/src/stargateclient.spec.ts +++ b/packages/stargate/src/stargateclient.spec.ts @@ -40,6 +40,7 @@ describe("StargateClient", () => { pendingWithoutSimapp(); const client = await StargateClient.connect(simapp.tendermintUrl); expect(await client.getChainId()).toEqual(simapp.chainId); + client.disconnect(); }); it("caches chain ID", async () => { @@ -52,6 +53,8 @@ describe("StargateClient", () => { expect(await client.getChainId()).toEqual(simapp.chainId); // from cache expect(getCodeSpy).toHaveBeenCalledTimes(1); + + client.disconnect(); }); }); @@ -66,6 +69,8 @@ describe("StargateClient", () => { const height2 = await client.getHeight(); expect(height2).toBeGreaterThanOrEqual(height1 + 1); expect(height2).toBeLessThanOrEqual(height1 + 2); + + client.disconnect(); }); }); @@ -160,6 +165,8 @@ describe("StargateClient", () => { expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( ReadonlyDate.now() - 5_000, ); + + client.disconnect(); }); it("works for block by height", async () => { @@ -183,6 +190,8 @@ describe("StargateClient", () => { expect(new ReadonlyDate(response.header.time).getTime()).toBeGreaterThanOrEqual( ReadonlyDate.now() - 5_000, ); + + client.disconnect(); }); }); @@ -242,13 +251,18 @@ describe("StargateClient", () => { denom: simapp.denomStaking, }, ]); + + client.disconnect(); }); it("returns an empty list for non-existent account", async () => { pendingWithoutSimapp(); const client = await StargateClient.connect(simapp.tendermintUrl); + const balances = await client.getAllBalancesUnverified(nonExistentAddress); expect(balances).toEqual([]); + + client.disconnect(); }); }); @@ -309,6 +323,8 @@ describe("StargateClient", () => { const { rawLog, transactionHash } = txResult; expect(rawLog).toMatch(/{"key":"amount","value":"1234567ucosm"}/); expect(transactionHash).toMatch(/^[0-9A-F]{64}$/); + + client.disconnect(); }); }); }); From 10206550d832f2de7411f8af5d3e9d2fef2f3189 Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Thu, 19 Nov 2020 09:43:39 +0100 Subject: [PATCH 7/9] Give up and just to the version query in any case --- packages/tendermint-rpc/src/client.ts | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/packages/tendermint-rpc/src/client.ts b/packages/tendermint-rpc/src/client.ts index f666d800..1eb06444 100644 --- a/packages/tendermint-rpc/src/client.ts +++ b/packages/tendermint-rpc/src/client.ts @@ -33,14 +33,12 @@ export class Client { * If the adaptor is not set, an auto-detection is performed. */ public static async create(rpcClient: RpcClient, adaptor?: Adaptor): Promise { - let usedAdaptor: Adaptor; - if (adaptor) { - usedAdaptor = adaptor; - } else { - const version = await this.detectVersion(rpcClient); - usedAdaptor = adaptorForVersion(version); - } - return new Client(rpcClient, usedAdaptor); + // For some very strange reason I don't understand, tests start to fail on some systems + // (our CI) when skipping the status call before doing other queries. Sleeping a little + // while did not help. Thus we query the version as a way to say "hi" to the backend, + // even in cases where we don't use the result. + const version = await this.detectVersion(rpcClient); + return new Client(rpcClient, adaptor || adaptorForVersion(version)); } private static async detectVersion(client: RpcClient): Promise { From 36a9d2d454638962bb4019cf013bfe4be7b62aab Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 24 Nov 2020 11:55:21 +0100 Subject: [PATCH 8/9] Improve doc comment text --- packages/tendermint-rpc/src/client.ts | 4 ++-- packages/tendermint-rpc/types/client.d.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/tendermint-rpc/src/client.ts b/packages/tendermint-rpc/src/client.ts index 1eb06444..1878b6e0 100644 --- a/packages/tendermint-rpc/src/client.ts +++ b/packages/tendermint-rpc/src/client.ts @@ -19,7 +19,7 @@ export class Client { * * Uses HTTP when the URL schema is http or https. Uses WebSockets otherwise. * - * If the adaptor is not set an auto-detection is performed. + * If the adaptor is not set an auto-detection is attempted. */ public static async connect(url: string, adaptor?: Adaptor): Promise { const useHttp = url.startsWith("http://") || url.startsWith("https://"); @@ -30,7 +30,7 @@ export class Client { /** * Creates a new Tendermint client given an RPC client. * - * If the adaptor is not set, an auto-detection is performed. + * If the adaptor is not set an auto-detection is attempted. */ public static async create(rpcClient: RpcClient, adaptor?: Adaptor): Promise { // For some very strange reason I don't understand, tests start to fail on some systems diff --git a/packages/tendermint-rpc/types/client.d.ts b/packages/tendermint-rpc/types/client.d.ts index 836c3058..f6a4830a 100644 --- a/packages/tendermint-rpc/types/client.d.ts +++ b/packages/tendermint-rpc/types/client.d.ts @@ -9,13 +9,13 @@ export declare class Client { * * Uses HTTP when the URL schema is http or https. Uses WebSockets otherwise. * - * If the adaptor is not set an auto-detection is performed. + * If the adaptor is not set an auto-detection is attempted. */ static connect(url: string, adaptor?: Adaptor): Promise; /** * Creates a new Tendermint client given an RPC client. * - * If the adaptor is not set, an auto-detection is performed. + * If the adaptor is not set an auto-detection is attempted. */ static create(rpcClient: RpcClient, adaptor?: Adaptor): Promise; private static detectVersion; From 635c2e70811592c006be144ac30becc402e2027f Mon Sep 17 00:00:00 2001 From: Simon Warta Date: Tue, 24 Nov 2020 11:55:47 +0100 Subject: [PATCH 9/9] Delete another level of spec types --- packages/tendermint-rpc/package.json | 2 +- packages/tendermint-rpc/types/adaptors/v0-33/hasher.spec.d.ts | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 100644 packages/tendermint-rpc/types/adaptors/v0-33/hasher.spec.d.ts diff --git a/packages/tendermint-rpc/package.json b/packages/tendermint-rpc/package.json index 59075d7b..7448c04b 100644 --- a/packages/tendermint-rpc/package.json +++ b/packages/tendermint-rpc/package.json @@ -37,7 +37,7 @@ "test-safari": "yarn pack-web && karma start --single-run --browsers Safari", "test": "yarn build-or-skip && yarn test-node", "coverage": "nyc --reporter=text --reporter=lcov yarn test --quiet", - "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts && shx rm ./types/**/*.spec.d.ts", + "move-types": "shx rm -rf ./types/* && shx mv build/types/* ./types && rm -rf ./types/testdata && shx rm -f ./types/*.spec.d.ts ./types/*/*.spec.d.ts ./types/*/*/*.spec.d.ts", "format-types": "prettier --write --loglevel warn \"./types/**/*.d.ts\"", "prebuild": "shx rm -rf ./build", "build": "tsc", diff --git a/packages/tendermint-rpc/types/adaptors/v0-33/hasher.spec.d.ts b/packages/tendermint-rpc/types/adaptors/v0-33/hasher.spec.d.ts deleted file mode 100644 index cb0ff5c3..00000000 --- a/packages/tendermint-rpc/types/adaptors/v0-33/hasher.spec.d.ts +++ /dev/null @@ -1 +0,0 @@ -export {};