From 47ac3da0a7b775e17486c67a54936fb8f0d2d013 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Thu, 20 Oct 2022 23:26:43 +0100 Subject: [PATCH 01/15] WIP Batch RPC requests --- .../src/rpcclients/httpclient.ts | 48 ++++++++++++++++--- 1 file changed, 42 insertions(+), 6 deletions(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpclient.ts b/packages/tendermint-rpc/src/rpcclients/httpclient.ts index 0b7dedacb4..f44015f732 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpclient.ts @@ -65,11 +65,25 @@ export interface HttpEndpoint { readonly headers: Record; } +export interface HttpClientOptions { + dispatchInterval: number; +} + +export const defaultHttpClientOptions: HttpClientOptions = { dispatchInterval: 0 }; + export class HttpClient implements RpcClient { protected readonly url: string; protected readonly headers: Record | undefined; + private stack: { + request: JsonRpcRequest; + resolve: (a: JsonRpcSuccessResponse) => void; + reject: (a: Error) => void; + }[] = []; - public constructor(endpoint: string | HttpEndpoint) { + public constructor( + endpoint: string | HttpEndpoint, + protected readonly options: HttpClientOptions = defaultHttpClientOptions, + ) { if (typeof endpoint === "string") { // accept host.name:port and assume http protocol this.url = hasProtocol(endpoint) ? endpoint : "http://" + endpoint; @@ -77,6 +91,7 @@ export class HttpClient implements RpcClient { this.url = endpoint.url; this.headers = endpoint.headers; } + setInterval(() => this.tick(), options.dispatchInterval); } public disconnect(): void { @@ -84,10 +99,31 @@ export class HttpClient implements RpcClient { } public async execute(request: JsonRpcRequest): Promise { - const response = parseJsonRpcResponse(await http("POST", this.url, this.headers, request)); - if (isJsonRpcErrorResponse(response)) { - throw new Error(JSON.stringify(response.error)); - } - return response; + return new Promise((resolve, reject) => { + this.stack.push({ request, resolve, reject }); + }); + } + + private async tick() { + // Avoid race conditions + const stack = this.stack; + this.stack = []; + + if (!stack.length) return; + + const request = stack.map((s) => s.request); + const raw = await http("POST", this.url, this.headers, request); + // Requests with a single entry return as an object + const arr = Array.isArray(raw) ? raw : [raw]; + + arr.forEach((el, idx) => { + const { reject, resolve } = stack[idx]; + const response = parseJsonRpcResponse(el); + if (isJsonRpcErrorResponse(response)) { + reject(new Error(JSON.stringify(response.error))); + return; + } + resolve(response); + }); } } From 39437c5cac618ca334645b946260432905125e4b Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Thu, 20 Oct 2022 23:46:18 +0100 Subject: [PATCH 02/15] Lint warnings --- .../src/rpcclients/httpclient.ts | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpclient.ts b/packages/tendermint-rpc/src/rpcclients/httpclient.ts index f44015f732..62ab651757 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpclient.ts @@ -74,16 +74,16 @@ export const defaultHttpClientOptions: HttpClientOptions = { dispatchInterval: 0 export class HttpClient implements RpcClient { protected readonly url: string; protected readonly headers: Record | undefined; - private stack: { + protected readonly options: HttpClientOptions; + + private stack: Array<{ request: JsonRpcRequest; resolve: (a: JsonRpcSuccessResponse) => void; reject: (a: Error) => void; - }[] = []; + }> = []; - public constructor( - endpoint: string | HttpEndpoint, - protected readonly options: HttpClientOptions = defaultHttpClientOptions, - ) { + public constructor(endpoint: string | HttpEndpoint, options: HttpClientOptions = defaultHttpClientOptions) { + this.options = options; if (typeof endpoint === "string") { // accept host.name:port and assume http protocol this.url = hasProtocol(endpoint) ? endpoint : "http://" + endpoint; @@ -104,7 +104,7 @@ export class HttpClient implements RpcClient { }); } - private async tick() { + private async tick(): Promise { // Avoid race conditions const stack = this.stack; this.stack = []; @@ -121,9 +121,9 @@ export class HttpClient implements RpcClient { const response = parseJsonRpcResponse(el); if (isJsonRpcErrorResponse(response)) { reject(new Error(JSON.stringify(response.error))); - return; + } else { + resolve(response); } - resolve(response); }); } } From b3fa6bedfcfc81a7543df09e693eadc78cd6f198 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Thu, 20 Oct 2022 23:51:00 +0100 Subject: [PATCH 03/15] Match responses by ID --- packages/tendermint-rpc/src/rpcclients/httpclient.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpclient.ts b/packages/tendermint-rpc/src/rpcclients/httpclient.ts index 62ab651757..a41b28bc78 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpclient.ts @@ -116,8 +116,10 @@ export class HttpClient implements RpcClient { // Requests with a single entry return as an object const arr = Array.isArray(raw) ? raw : [raw]; - arr.forEach((el, idx) => { - const { reject, resolve } = stack[idx]; + arr.forEach((el) => { + const req = stack.find((s) => s.request.id === el.id); + if (!req) return; + const { reject, resolve } = req; const response = parseJsonRpcResponse(el); if (isJsonRpcErrorResponse(response)) { reject(new Error(JSON.stringify(response.error))); From 67168f1325f67f6ed50ffbae071b6414abbe8990 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Fri, 21 Oct 2022 10:13:59 +0100 Subject: [PATCH 04/15] Review Comments --- .../src/rpcclients/httpbatchclient.spec.ts | 91 +++++++++++++++++++ .../src/rpcclients/httpbatchclient.ts | 74 +++++++++++++++ .../src/rpcclients/httpclient.ts | 50 ++-------- 3 files changed, 171 insertions(+), 44 deletions(-) create mode 100644 packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts create mode 100644 packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts diff --git a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts new file mode 100644 index 0000000000..de481d30dc --- /dev/null +++ b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts @@ -0,0 +1,91 @@ +/* eslint-disable @typescript-eslint/naming-convention */ +import { createJsonRpcRequest } from "../jsonrpc"; +import { defaultInstance } from "../testutil.spec"; +import { HttpBatchClient } from "./httpbatchclient"; +import { http } from "./httpclient"; + +function pendingWithoutTendermint(): void { + if (!process.env.TENDERMINT_ENABLED) { + pending("Set TENDERMINT_ENABLED to enable Tendermint RPC tests"); + } +} + +function pendingWithoutHttpServer(): void { + if (!process.env.HTTPSERVER_ENABLED) { + pending("Set HTTPSERVER_ENABLED to enable HTTP tests"); + } +} + +const tendermintUrl = defaultInstance.url; +const echoUrl = "http://localhost:5555/echo_headers"; + +describe("http", () => { + it("can send a health request", async () => { + pendingWithoutTendermint(); + const response = await http("POST", `http://${tendermintUrl}`, undefined, createJsonRpcRequest("health")); + expect(response).toEqual(jasmine.objectContaining({ jsonrpc: "2.0" })); + }); + + it("errors for non-open port", async () => { + await expectAsync( + http("POST", `http://localhost:56745`, undefined, createJsonRpcRequest("health")), + ).toBeRejectedWithError(/(ECONNREFUSED|Failed to fetch)/i); + }); + + it("can send custom headers", async () => { + pendingWithoutHttpServer(); + // Without custom headers + const response1 = await http("POST", echoUrl, undefined, createJsonRpcRequest("health")); + expect(response1).toEqual({ + request_headers: jasmine.objectContaining({ + // Basic headers from http client + Accept: jasmine.any(String), + "Content-Length": jasmine.any(String), + "Content-Type": "application/json", + Host: jasmine.any(String), + "User-Agent": jasmine.any(String), + }), + }); + + // With custom headers + const response2 = await http( + "POST", + echoUrl, + { foo: "bar123", Authorization: "Basic Z3Vlc3Q6bm9QYXNzMTIz" }, + createJsonRpcRequest("health"), + ); + expect(response2).toEqual({ + request_headers: jasmine.objectContaining({ + // Basic headers from http client + "Content-Length": jasmine.any(String), + "Content-Type": "application/json", + Host: jasmine.any(String), + "User-Agent": jasmine.any(String), + // Custom headers + foo: "bar123", + Authorization: "Basic Z3Vlc3Q6bm9QYXNzMTIz", + }), + }); + }); +}); + +describe("HttpClient", () => { + it("can make a simple call", async () => { + pendingWithoutTendermint(); + const client = new HttpBatchClient(tendermintUrl); + + const healthResponse = await client.execute(createJsonRpcRequest("health")); + expect(healthResponse.result).toEqual({}); + + const statusResponse = await client.execute(createJsonRpcRequest("status")); + expect(statusResponse.result).toBeTruthy(); + expect(statusResponse.result.node_info).toBeTruthy(); + + await client + .execute(createJsonRpcRequest("no-such-method")) + .then(() => fail("must not resolve")) + .catch((error) => expect(error).toBeTruthy()); + + client.disconnect(); + }); +}); diff --git a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts new file mode 100644 index 0000000000..2d44e4f281 --- /dev/null +++ b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts @@ -0,0 +1,74 @@ +import { + isJsonRpcErrorResponse, + JsonRpcRequest, + JsonRpcSuccessResponse, + parseJsonRpcResponse, +} from "@cosmjs/json-rpc"; +import { http, HttpEndpoint } from "./httpclient"; + +import { hasProtocol, RpcClient } from "./rpcclient"; + +export interface HttpClientOptions { + dispatchInterval: number; + batchSizeLimit: number; +} + +export const defaultHttpClientOptions: HttpClientOptions = { dispatchInterval: 20, batchSizeLimit: 20 }; + +export class HttpBatchClient implements RpcClient { + protected readonly url: string; + protected readonly headers: Record | undefined; + protected readonly options: HttpClientOptions; + + private queue: Array<{ + request: JsonRpcRequest; + resolve: (a: JsonRpcSuccessResponse) => void; + reject: (a: Error) => void; + }> = []; + + public constructor(endpoint: string | HttpEndpoint, options: HttpClientOptions = defaultHttpClientOptions) { + this.options = options; + if (typeof endpoint === "string") { + // accept host.name:port and assume http protocol + this.url = hasProtocol(endpoint) ? endpoint : "http://" + endpoint; + } else { + this.url = endpoint.url; + this.headers = endpoint.headers; + } + setInterval(() => this.tick(), options.dispatchInterval); + } + + public disconnect(): void { + // nothing to be done + } + + public async execute(request: JsonRpcRequest): Promise { + return new Promise((resolve, reject) => { + this.queue.push({ request, resolve, reject }); + }); + } + + private async tick(): Promise { + // Avoid race conditions + const queue = this.queue.splice(0, this.options.batchSizeLimit); + + if (!queue.length) return; + + const request = queue.map((s) => s.request); + const raw = await http("POST", this.url, this.headers, request); + // Requests with a single entry return as an object + const arr = Array.isArray(raw) ? raw : [raw]; + + arr.forEach((el) => { + const req = queue.find((s) => s.request.id === el.id); + if (!req) return; + const { reject, resolve } = req; + const response = parseJsonRpcResponse(el); + if (isJsonRpcErrorResponse(response)) { + reject(new Error(JSON.stringify(response.error))); + } else { + resolve(response); + } + }); + } +} diff --git a/packages/tendermint-rpc/src/rpcclients/httpclient.ts b/packages/tendermint-rpc/src/rpcclients/httpclient.ts index a41b28bc78..0b7dedacb4 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpclient.ts @@ -65,25 +65,11 @@ export interface HttpEndpoint { readonly headers: Record; } -export interface HttpClientOptions { - dispatchInterval: number; -} - -export const defaultHttpClientOptions: HttpClientOptions = { dispatchInterval: 0 }; - export class HttpClient implements RpcClient { protected readonly url: string; protected readonly headers: Record | undefined; - protected readonly options: HttpClientOptions; - private stack: Array<{ - request: JsonRpcRequest; - resolve: (a: JsonRpcSuccessResponse) => void; - reject: (a: Error) => void; - }> = []; - - public constructor(endpoint: string | HttpEndpoint, options: HttpClientOptions = defaultHttpClientOptions) { - this.options = options; + public constructor(endpoint: string | HttpEndpoint) { if (typeof endpoint === "string") { // accept host.name:port and assume http protocol this.url = hasProtocol(endpoint) ? endpoint : "http://" + endpoint; @@ -91,7 +77,6 @@ export class HttpClient implements RpcClient { this.url = endpoint.url; this.headers = endpoint.headers; } - setInterval(() => this.tick(), options.dispatchInterval); } public disconnect(): void { @@ -99,33 +84,10 @@ export class HttpClient implements RpcClient { } public async execute(request: JsonRpcRequest): Promise { - return new Promise((resolve, reject) => { - this.stack.push({ request, resolve, reject }); - }); - } - - private async tick(): Promise { - // Avoid race conditions - const stack = this.stack; - this.stack = []; - - if (!stack.length) return; - - const request = stack.map((s) => s.request); - const raw = await http("POST", this.url, this.headers, request); - // Requests with a single entry return as an object - const arr = Array.isArray(raw) ? raw : [raw]; - - arr.forEach((el) => { - const req = stack.find((s) => s.request.id === el.id); - if (!req) return; - const { reject, resolve } = req; - const response = parseJsonRpcResponse(el); - if (isJsonRpcErrorResponse(response)) { - reject(new Error(JSON.stringify(response.error))); - } else { - resolve(response); - } - }); + const response = parseJsonRpcResponse(await http("POST", this.url, this.headers, request)); + if (isJsonRpcErrorResponse(response)) { + throw new Error(JSON.stringify(response.error)); + } + return response; } } From 1ca47ae929d32c1259ebdc74c9a3caf76fe06067 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Fri, 21 Oct 2022 10:28:13 +0100 Subject: [PATCH 05/15] Lint --- packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts index 2d44e4f281..a9bdaed62a 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts @@ -4,8 +4,8 @@ import { JsonRpcSuccessResponse, parseJsonRpcResponse, } from "@cosmjs/json-rpc"; -import { http, HttpEndpoint } from "./httpclient"; +import { http, HttpEndpoint } from "./httpclient"; import { hasProtocol, RpcClient } from "./rpcclient"; export interface HttpClientOptions { @@ -20,7 +20,7 @@ export class HttpBatchClient implements RpcClient { protected readonly headers: Record | undefined; protected readonly options: HttpClientOptions; - private queue: Array<{ + private readonly queue: Array<{ request: JsonRpcRequest; resolve: (a: JsonRpcSuccessResponse) => void; reject: (a: Error) => void; From e0f1f835507881c345c92597f26bc80278815fcc Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:10:56 +0100 Subject: [PATCH 06/15] Update packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts index de481d30dc..c03628340c 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.spec.ts @@ -69,7 +69,7 @@ describe("http", () => { }); }); -describe("HttpClient", () => { +describe("HttpBatchClient", () => { it("can make a simple call", async () => { pendingWithoutTendermint(); const client = new HttpBatchClient(tendermintUrl); From 09b8623a49a3c7a79fcd76c03d8f62ad21b3cbd1 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:11:07 +0100 Subject: [PATCH 07/15] Update packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts index a9bdaed62a..8bb07fb7b0 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts @@ -8,7 +8,7 @@ import { import { http, HttpEndpoint } from "./httpclient"; import { hasProtocol, RpcClient } from "./rpcclient"; -export interface HttpClientOptions { +export interface HttpBatchClientOptions { dispatchInterval: number; batchSizeLimit: number; } From 00f0fd4ff3756c2d0b3740e5283950b4ec2e0151 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:11:36 +0100 Subject: [PATCH 08/15] Update packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts index 8bb07fb7b0..de925b5ba2 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts @@ -13,7 +13,7 @@ export interface HttpBatchClientOptions { batchSizeLimit: number; } -export const defaultHttpClientOptions: HttpClientOptions = { dispatchInterval: 20, batchSizeLimit: 20 }; +export const defaultHttpBatchClientOptions: HttpClientOptions = { dispatchInterval: 20, batchSizeLimit: 20 }; export class HttpBatchClient implements RpcClient { protected readonly url: string; From cf7887a0908104e180972e8957672fc5d1169ab7 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:15:25 +0100 Subject: [PATCH 09/15] review updates --- .../src/rpcclients/httpbatchclient.ts | 23 +++++++++++++++---- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts index de925b5ba2..69f709a499 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts @@ -13,12 +13,16 @@ export interface HttpBatchClientOptions { batchSizeLimit: number; } -export const defaultHttpBatchClientOptions: HttpClientOptions = { dispatchInterval: 20, batchSizeLimit: 20 }; +export const defaultHttpBatchClientOptions: HttpBatchClientOptions = { + dispatchInterval: 20, + batchSizeLimit: 20, +}; export class HttpBatchClient implements RpcClient { protected readonly url: string; protected readonly headers: Record | undefined; - protected readonly options: HttpClientOptions; + protected readonly options: HttpBatchClientOptions; + private timer?: NodeJS.Timer; private readonly queue: Array<{ request: JsonRpcRequest; @@ -26,7 +30,10 @@ export class HttpBatchClient implements RpcClient { reject: (a: Error) => void; }> = []; - public constructor(endpoint: string | HttpEndpoint, options: HttpClientOptions = defaultHttpClientOptions) { + public constructor( + endpoint: string | HttpEndpoint, + options: HttpBatchClientOptions = defaultHttpBatchClientOptions, + ) { this.options = options; if (typeof endpoint === "string") { // accept host.name:port and assume http protocol @@ -35,11 +42,13 @@ export class HttpBatchClient implements RpcClient { this.url = endpoint.url; this.headers = endpoint.headers; } - setInterval(() => this.tick(), options.dispatchInterval); + this.timer = setInterval(() => this.tick(), options.dispatchInterval); + this.validate(); } public disconnect(): void { - // nothing to be done + this.timer && clearInterval(this.timer); + this.timer = undefined; } public async execute(request: JsonRpcRequest): Promise { @@ -48,6 +57,10 @@ export class HttpBatchClient implements RpcClient { }); } + private validate() { + if (this.options.batchSizeLimit < 1) throw new Error("batchSizeLimit < 1"); + } + private async tick(): Promise { // Avoid race conditions const queue = this.queue.splice(0, this.options.batchSizeLimit); From 2b6782b879f73a7488be07beed8caeeff1a5fa82 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:16:11 +0100 Subject: [PATCH 10/15] lint --- packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts index 69f709a499..5e64868211 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts @@ -57,7 +57,7 @@ export class HttpBatchClient implements RpcClient { }); } - private validate() { + private validate(): void { if (this.options.batchSizeLimit < 1) throw new Error("batchSizeLimit < 1"); } From 21695f2932fd9ef4dcc3ea639a714f2c7d7f59a9 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:45:56 +0100 Subject: [PATCH 11/15] check falsy values --- packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts index 5e64868211..3da0ff0ac5 100644 --- a/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts +++ b/packages/tendermint-rpc/src/rpcclients/httpbatchclient.ts @@ -58,7 +58,8 @@ export class HttpBatchClient implements RpcClient { } private validate(): void { - if (this.options.batchSizeLimit < 1) throw new Error("batchSizeLimit < 1"); + if (!this.options.batchSizeLimit || this.options.batchSizeLimit < 1) + throw new Error("batchSizeLimit < 1"); } private async tick(): Promise { From e654c0391b0f34f9feec9b05ded43e78c6aea4df Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:48:52 +0100 Subject: [PATCH 12/15] CHANGELOG & export --- CHANGELOG.md | 5 ++++- packages/tendermint-rpc/src/rpcclients/index.ts | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fa478c2a2..dc68b59354 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,10 @@ and this project adheres to - @cosmjs/utils: Add `isDefined` which checks for `undefined` in a TypeScript-friendly way. - @cosmjs/stargate: Add missing `{is,}MsgBeginRedelegateEncodeObject`, - `{is,MsgCreateValidatorEncodeObject}` and `{is,MsgEditValidatorEncodeObject}`. + `{is,MsgCreateValidatorEncodeObject}` and + `{is,MsgEditValidatorEncodeObject}`.\ +- @cosmjs/tendermint-rpc: Add `HttpBatchClient`, which implements `RpcClient`, + supporting batch RPC requests ### Fixed diff --git a/packages/tendermint-rpc/src/rpcclients/index.ts b/packages/tendermint-rpc/src/rpcclients/index.ts index bff2953116..81aa34c776 100644 --- a/packages/tendermint-rpc/src/rpcclients/index.ts +++ b/packages/tendermint-rpc/src/rpcclients/index.ts @@ -1,5 +1,6 @@ // This folder contains Tendermint-specific RPC clients export { HttpClient, HttpEndpoint } from "./httpclient"; +export { HttpBatchClient, defaultHttpBatchClientOptions } from "./httpbatchclient"; export { instanceOfRpcStreamingClient, RpcClient, RpcStreamingClient, SubscriptionEvent } from "./rpcclient"; export { WebsocketClient } from "./websocketclient"; From 7d19089a731e655bc7050de729d2df5c8436ddcd Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:55:18 +0100 Subject: [PATCH 13/15] Update CHANGELOG.md Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc68b59354..91b11db47c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,9 @@ and this project adheres to `{is,MsgCreateValidatorEncodeObject}` and `{is,MsgEditValidatorEncodeObject}`.\ - @cosmjs/tendermint-rpc: Add `HttpBatchClient`, which implements `RpcClient`, - supporting batch RPC requests + supporting batch RPC requests ([#1300]). + +[#1300]: https://github.com/cosmos/cosmjs/pull/1300 ### Fixed From 78c60f9d31a6fca1e8908a194d8637a8419d058d Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 10:55:32 +0100 Subject: [PATCH 14/15] Update CHANGELOG.md Co-authored-by: Simon Warta <2603011+webmaster128@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91b11db47c..3ffe45c3ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ and this project adheres to TypeScript-friendly way. - @cosmjs/stargate: Add missing `{is,}MsgBeginRedelegateEncodeObject`, `{is,MsgCreateValidatorEncodeObject}` and - `{is,MsgEditValidatorEncodeObject}`.\ + `{is,MsgEditValidatorEncodeObject}`. - @cosmjs/tendermint-rpc: Add `HttpBatchClient`, which implements `RpcClient`, supporting batch RPC requests ([#1300]). From 4404a39e97c560b112fcf53d8e694f7df5571c17 Mon Sep 17 00:00:00 2001 From: codehans <94654388+codehans@users.noreply.github.com> Date: Mon, 24 Oct 2022 11:06:06 +0100 Subject: [PATCH 15/15] yarn format-text --- CHANGELOG.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ffe45c3ea..13bcba54f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,11 +17,10 @@ and this project adheres to - @cosmjs/utils: Add `isDefined` which checks for `undefined` in a TypeScript-friendly way. - @cosmjs/stargate: Add missing `{is,}MsgBeginRedelegateEncodeObject`, - `{is,MsgCreateValidatorEncodeObject}` and - `{is,MsgEditValidatorEncodeObject}`. + `{is,MsgCreateValidatorEncodeObject}` and `{is,MsgEditValidatorEncodeObject}`. - @cosmjs/tendermint-rpc: Add `HttpBatchClient`, which implements `RpcClient`, supporting batch RPC requests ([#1300]). - + [#1300]: https://github.com/cosmos/cosmjs/pull/1300 ### Fixed