diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cb8302cdc..8f538b1a1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,9 +40,13 @@ and this project adheres to - all: Upgrade cosmjs-types to 0.5 ([#1131]). - @cosmjs/stargate: Change `packetCommitment` parameter `sequence` type from `Long` to `number` ([#1168]). +- @cosmjs/tendermint-rpc: The type of `votingPower` fields was changed from + `number` to `bigint` as those values can exceed the safe integer range + ([#1133]). [#1131]: https://github.com/cosmos/cosmjs/pull/1131 [#1168]: https://github.com/cosmos/cosmjs/pull/1168 +[#1133]: https://github.com/cosmos/cosmjs/issues/1133 ## [0.28.9] - 2022-06-21 diff --git a/packages/tendermint-rpc/src/inthelpers.spec.ts b/packages/tendermint-rpc/src/inthelpers.spec.ts new file mode 100644 index 0000000000..3c2a065e94 --- /dev/null +++ b/packages/tendermint-rpc/src/inthelpers.spec.ts @@ -0,0 +1,40 @@ +import { apiToBigInt } from "./inthelpers"; + +describe("inthelpers", () => { + describe("apiToBigInt", () => { + it("works for positive an negative ints", () => { + expect(apiToBigInt("0")).toEqual(BigInt(0)); + expect(apiToBigInt("1")).toEqual(BigInt(1)); + expect(apiToBigInt("100")).toEqual(BigInt(100)); + expect(apiToBigInt("-1")).toEqual(BigInt(-1)); + expect(apiToBigInt("-100")).toEqual(BigInt(-100)); + expect(apiToBigInt("9007199254740991")).toEqual(BigInt(9007199254740991)); + expect(apiToBigInt("-9007199254740991")).toEqual(BigInt(-9007199254740991)); + // uint64 max + expect(apiToBigInt("18446744073709551615")).toEqual(BigInt("18446744073709551615")); + // int64 min/max + expect(apiToBigInt("-9223372036854775808")).toEqual(BigInt("-9223372036854775808")); + expect(apiToBigInt("9223372036854775807")).toEqual(BigInt("9223372036854775807")); + }); + + it("throws for ill-formatted inputs", () => { + // empty + expect(() => apiToBigInt("")).toThrowError(/invalid string format/i); + expect(() => apiToBigInt("-")).toThrowError(/invalid string format/i); + + // non decimal representation + expect(() => apiToBigInt("0x0")).toThrowError(/invalid string format/i); + expect(() => apiToBigInt("0x01")).toThrowError(/invalid string format/i); + expect(() => apiToBigInt("0x")).toThrowError(/invalid string format/i); + + // decimal points + expect(() => apiToBigInt("1.0")).toThrowError(/invalid string format/i); + + // Invalid dashes + expect(() => apiToBigInt("1-")).toThrowError(/invalid string format/i); + expect(() => apiToBigInt("--1")).toThrowError(/invalid string format/i); + expect(() => apiToBigInt("1-1")).toThrowError(/invalid string format/i); + expect(() => apiToBigInt("-1-1")).toThrowError(/invalid string format/i); + }); + }); +}); diff --git a/packages/tendermint-rpc/src/inthelpers.ts b/packages/tendermint-rpc/src/inthelpers.ts new file mode 100644 index 0000000000..77be2e2e2f --- /dev/null +++ b/packages/tendermint-rpc/src/inthelpers.ts @@ -0,0 +1,36 @@ +import { Int53 } from "@cosmjs/math"; + +import { assertString } from "./tendermint34/encodings"; + +/** + * Takes an integer value from the Tendermint RPC API and + * returns it as number. + * + * Only works within the safe integer range. + */ +export function apiToSmallInt(input: string | number): number { + const asInt = typeof input === "number" ? new Int53(input) : Int53.fromString(input); + return asInt.toNumber(); +} + +/** + * Takes an integer value from the Tendermint RPC API and + * returns it as BigInt. + * + * This supports the full uint64 and int64 ranges. + */ +export function apiToBigInt(input: string): bigint { + assertString(input); // Runtime check on top of TypeScript just to be safe for semi-trusted API types + if (!input.match(/^-?[0-9]+$/)) { + throw new Error("Invalid string format"); + } + return BigInt(input); +} + +/** + * Takes an integer in the safe integer range and returns + * a string representation to be used in the Tendermint RPC API. + */ +export function smallIntToApi(num: number): string { + return new Int53(num).toString(); +} diff --git a/packages/tendermint-rpc/src/tendermint34/adaptor/requests.ts b/packages/tendermint-rpc/src/tendermint34/adaptor/requests.ts index 1dc959473b..ae2bd709d8 100644 --- a/packages/tendermint-rpc/src/tendermint34/adaptor/requests.ts +++ b/packages/tendermint-rpc/src/tendermint34/adaptor/requests.ts @@ -2,8 +2,9 @@ import { toBase64, toHex } from "@cosmjs/encoding"; import { JsonRpcRequest } from "@cosmjs/json-rpc"; +import { smallIntToApi } from "../../inthelpers"; import { createJsonRpcRequest } from "../../jsonrpc"; -import { assertNotEmpty, Integer, may } from "../encodings"; +import { assertNotEmpty, may } from "../encodings"; import * as requests from "../requests"; interface HeightParam { @@ -14,7 +15,7 @@ interface RpcHeightParam { } function encodeHeightParam(param: HeightParam): RpcHeightParam { return { - height: may(Integer.encode, param.height), + height: may(smallIntToApi, param.height), }; } @@ -25,8 +26,8 @@ interface RpcBlockchainRequestParams { function encodeBlockchainRequestParams(param: requests.BlockchainRequestParams): RpcBlockchainRequestParams { return { - minHeight: may(Integer.encode, param.minHeight), - maxHeight: may(Integer.encode, param.maxHeight), + minHeight: may(smallIntToApi, param.minHeight), + maxHeight: may(smallIntToApi, param.maxHeight), }; } @@ -39,8 +40,8 @@ interface RpcBlockSearchParams { function encodeBlockSearchParams(params: requests.BlockSearchParams): RpcBlockSearchParams { return { query: params.query, - page: may(Integer.encode, params.page), - per_page: may(Integer.encode, params.per_page), + page: may(smallIntToApi, params.page), + per_page: may(smallIntToApi, params.per_page), order_by: params.order_by, }; } @@ -57,7 +58,7 @@ function encodeAbciQueryParams(params: requests.AbciQueryParams): RpcAbciQueryPa return { path: assertNotEmpty(params.path), data: toHex(params.data), - height: may(Integer.encode, params.height), + height: may(smallIntToApi, params.height), prove: params.prove, }; } @@ -95,8 +96,8 @@ function encodeTxSearchParams(params: requests.TxSearchParams): RpcTxSearchParam return { query: params.query, prove: params.prove, - page: may(Integer.encode, params.page), - per_page: may(Integer.encode, params.per_page), + page: may(smallIntToApi, params.page), + per_page: may(smallIntToApi, params.per_page), order_by: params.order_by, }; } @@ -108,9 +109,9 @@ interface RpcValidatorsParams { } function encodeValidatorsParams(params: requests.ValidatorsParams): RpcValidatorsParams { return { - height: may(Integer.encode, params.height), - page: may(Integer.encode, params.page), - per_page: may(Integer.encode, params.per_page), + height: may(smallIntToApi, params.height), + page: may(smallIntToApi, params.page), + per_page: may(smallIntToApi, params.per_page), }; } diff --git a/packages/tendermint-rpc/src/tendermint34/adaptor/responses.spec.ts b/packages/tendermint-rpc/src/tendermint34/adaptor/responses.spec.ts index 0ad26490ab..7de09654d0 100644 --- a/packages/tendermint-rpc/src/tendermint34/adaptor/responses.spec.ts +++ b/packages/tendermint-rpc/src/tendermint34/adaptor/responses.spec.ts @@ -44,7 +44,7 @@ describe("Adaptor Responses", () => { }); expect(validator).toEqual({ address: fromHex("A03DC128D38DB0BC5F18AE1872F1CB2E1FD41157"), - votingPower: 169980, + votingPower: BigInt(169980), pubkey: { algorithm: "ed25519", data: fromBase64("2BX6Zuj8RmdJAkD1BAg6KB0v04liyM7jBdwOGIb9F9Q="), @@ -72,7 +72,7 @@ describe("Adaptor Responses", () => { algorithm: "ed25519", data: fromBase64("0kNlxBMpm+5WtfHIG1xsWatOXTKPLtmSqn3EiEIDZeI="), }, - votingPower: 11418237, + votingPower: BigInt(11418237), }); }); @@ -93,7 +93,7 @@ describe("Adaptor Responses", () => { algorithm: "ed25519", data: fromBase64("HjSC7VkhKih6xMhudlqfaFE8ZZnP8RKJPv4iqR7RhcE="), }, - votingPower: 0, + votingPower: BigInt(0), }); }); }); @@ -116,7 +116,7 @@ describe("Adaptor Responses", () => { algorithm: "ed25519", data: fromBase64("0kNlxBMpm+5WtfHIG1xsWatOXTKPLtmSqn3EiEIDZeI="), }, - votingPower: 11228980, + votingPower: BigInt(11228980), proposerPriority: 62870960, }); }); diff --git a/packages/tendermint-rpc/src/tendermint34/adaptor/responses.ts b/packages/tendermint-rpc/src/tendermint34/adaptor/responses.ts index 1a44a10e15..e522294442 100644 --- a/packages/tendermint-rpc/src/tendermint34/adaptor/responses.ts +++ b/packages/tendermint-rpc/src/tendermint34/adaptor/responses.ts @@ -4,6 +4,7 @@ import { JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import { assert } from "@cosmjs/utils"; import { DateWithNanoseconds, fromRfc3339WithNanoseconds } from "../../dates"; +import { apiToBigInt, apiToSmallInt } from "../../inthelpers"; import { SubscriptionEvent } from "../../rpcclients"; import { BlockIdFlag, CommitSignature, ValidatorPubkey } from "../../types"; import { @@ -15,7 +16,6 @@ import { assertSet, assertString, dictionaryToStringMap, - Integer, may, } from "../encodings"; import { hashTx } from "../hasher"; @@ -35,7 +35,7 @@ interface RpcAbciInfoResponse { function decodeAbciInfo(data: RpcAbciInfoResponse): responses.AbciInfoResponse { return { data: data.data, - lastBlockHeight: may(Integer.parse, data.last_block_height), + lastBlockHeight: may(apiToSmallInt, data.last_block_height), lastBlockAppHash: may(fromBase64, data.last_block_app_hash), }; } @@ -96,10 +96,10 @@ function decodeAbciQuery(data: RpcAbciQueryResponse): responses.AbciQueryRespons key: fromBase64(assertString(data.key ?? "")), value: fromBase64(assertString(data.value ?? "")), proof: may(decodeQueryProof, data.proofOps), - height: may(Integer.parse, data.height), - code: may(Integer.parse, data.code), + height: may(apiToSmallInt, data.height), + code: may(apiToSmallInt, data.code), codespace: assertString(data.codespace ?? ""), - index: may(Integer.parse, data.index), + index: may(apiToSmallInt, data.index), log: data.log, info: assertString(data.info ?? ""), }; @@ -153,13 +153,13 @@ interface RpcTxData { function decodeTxData(data: RpcTxData): responses.TxData { return { - code: Integer.parse(assertNumber(data.code ?? 0)), + code: apiToSmallInt(assertNumber(data.code ?? 0)), codeSpace: data.codespace, log: data.log, data: may(fromBase64, data.data), events: data.events ? decodeEvents(data.events) : [], - gasWanted: Integer.parse(data.gas_wanted ?? "0"), - gasUsed: Integer.parse(data.gas_used ?? "0"), + gasWanted: apiToSmallInt(data.gas_wanted ?? "0"), + gasUsed: apiToSmallInt(data.gas_used ?? "0"), }; } @@ -221,8 +221,8 @@ interface RpcBlockParams { */ function decodeBlockParams(data: RpcBlockParams): responses.BlockParams { return { - maxBytes: Integer.parse(assertNotEmpty(data.max_bytes)), - maxGas: Integer.parse(assertNotEmpty(data.max_gas)), + maxBytes: apiToSmallInt(assertNotEmpty(data.max_bytes)), + maxGas: apiToSmallInt(assertNotEmpty(data.max_gas)), }; } @@ -233,8 +233,8 @@ interface RpcEvidenceParams { function decodeEvidenceParams(data: RpcEvidenceParams): responses.EvidenceParams { return { - maxAgeNumBlocks: Integer.parse(assertNotEmpty(data.max_age_num_blocks)), - maxAgeDuration: Integer.parse(assertNotEmpty(data.max_age_duration)), + maxAgeNumBlocks: apiToSmallInt(assertNotEmpty(data.max_age_num_blocks)), + maxAgeDuration: apiToSmallInt(assertNotEmpty(data.max_age_duration)), }; } @@ -279,7 +279,7 @@ interface RpcValidatorUpdate { export function decodeValidatorUpdate(data: RpcValidatorUpdate): responses.ValidatorUpdate { return { pubkey: decodePubkey(assertObject(data.pub_key)), - votingPower: Integer.parse(data.power ?? 0), + votingPower: apiToBigInt(data.power ?? "0"), }; } @@ -294,7 +294,7 @@ interface RpcBlockResultsResponse { function decodeBlockResults(data: RpcBlockResultsResponse): responses.BlockResultsResponse { return { - height: Integer.parse(assertNotEmpty(data.height)), + height: apiToSmallInt(assertNotEmpty(data.height)), results: (data.txs_results || []).map(decodeTxData), validatorUpdates: (data.validator_updates || []).map(decodeValidatorUpdate), consensusUpdates: may(decodeConsensusParams, data.consensus_param_updates), @@ -330,8 +330,8 @@ interface RpcBlockVersion { function decodeBlockVersion(data: RpcBlockVersion): responses.Version { return { - block: Integer.parse(data.block), - app: Integer.parse(data.app ?? 0), + block: apiToSmallInt(data.block), + app: apiToSmallInt(data.app ?? 0), }; } @@ -369,7 +369,7 @@ function decodeHeader(data: RpcHeader): responses.Header { return { version: decodeBlockVersion(data.version), chainId: assertNotEmpty(data.chain_id), - height: Integer.parse(assertNotEmpty(data.height)), + height: apiToSmallInt(assertNotEmpty(data.height)), time: fromRfc3339WithNanoseconds(assertNotEmpty(data.time)), // When there is no last block ID (i.e. this block's height is 1), we get an empty structure like this: @@ -400,9 +400,9 @@ interface RpcBlockMeta { function decodeBlockMeta(data: RpcBlockMeta): responses.BlockMeta { return { blockId: decodeBlockId(data.block_id), - blockSize: Integer.parse(assertNotEmpty(data.block_size)), + blockSize: apiToSmallInt(assertNotEmpty(data.block_size)), header: decodeHeader(data.header), - numTxs: Integer.parse(assertNotEmpty(data.num_txs)), + numTxs: apiToSmallInt(assertNotEmpty(data.num_txs)), }; } @@ -413,7 +413,7 @@ interface RpcBlockchainResponse { function decodeBlockchain(data: RpcBlockchainResponse): responses.BlockchainResponse { return { - lastHeight: Integer.parse(assertNotEmpty(data.last_height)), + lastHeight: apiToSmallInt(assertNotEmpty(data.last_height)), blockMetas: assertArray(data.block_metas).map(decodeBlockMeta), }; } @@ -440,7 +440,7 @@ interface RpcBroadcastTxCommitResponse { function decodeBroadcastTxCommit(data: RpcBroadcastTxCommitResponse): responses.BroadcastTxCommitResponse { return { - height: Integer.parse(data.height), + height: apiToSmallInt(data.height), hash: fromHex(assertNotEmpty(data.hash)), checkTx: decodeTxData(assertObject(data.check_tx)), deliverTx: may(decodeTxData, data.deliver_tx), @@ -494,8 +494,8 @@ interface RpcCommit { function decodeCommit(data: RpcCommit): responses.Commit { return { blockId: decodeBlockId(assertObject(data.block_id)), - height: Integer.parse(assertNotEmpty(data.height)), - round: Integer.parse(data.round), + height: apiToSmallInt(assertNotEmpty(data.height)), + round: apiToSmallInt(data.round), signatures: assertArray(data.signatures).map(decodeCommitSignature), }; } @@ -528,7 +528,7 @@ export function decodeValidatorGenesis(data: RpcValidatorGenesis): responses.Val return { address: fromHex(assertNotEmpty(data.address)), pubkey: decodePubkey(assertObject(data.pub_key)), - votingPower: Integer.parse(assertNotEmpty(data.power)), + votingPower: apiToBigInt(assertNotEmpty(data.power)), }; } @@ -571,9 +571,9 @@ interface RpcValidatorInfo { export function decodeValidatorInfo(data: RpcValidatorInfo): responses.Validator { return { pubkey: decodePubkey(assertObject(data.pub_key)), - votingPower: Integer.parse(assertNotEmpty(data.voting_power)), + votingPower: apiToBigInt(assertNotEmpty(data.voting_power)), address: fromHex(assertNotEmpty(data.address)), - proposerPriority: data.proposer_priority ? Integer.parse(data.proposer_priority) : undefined, + proposerPriority: data.proposer_priority ? apiToSmallInt(data.proposer_priority) : undefined, }; } @@ -611,9 +611,9 @@ function decodeNodeInfo(data: RpcNodeInfo): responses.NodeInfo { moniker: assertNotEmpty(data.moniker), other: dictionaryToStringMap(data.other), protocolVersion: { - app: Integer.parse(assertNotEmpty(data.protocol_version.app)), - block: Integer.parse(assertNotEmpty(data.protocol_version.block)), - p2p: Integer.parse(assertNotEmpty(data.protocol_version.p2p)), + app: apiToSmallInt(assertNotEmpty(data.protocol_version.app)), + block: apiToSmallInt(assertNotEmpty(data.protocol_version.block)), + p2p: apiToSmallInt(assertNotEmpty(data.protocol_version.p2p)), }, }; } @@ -633,7 +633,7 @@ function decodeSyncInfo(data: RpcSyncInfo): responses.SyncInfo { latestBlockHash: fromHex(assertNotEmpty(data.latest_block_hash)), latestAppHash: fromHex(assertNotEmpty(data.latest_app_hash)), latestBlockTime: fromRfc3339WithNanoseconds(assertNotEmpty(data.latest_block_time)), - latestBlockHeight: Integer.parse(assertNotEmpty(data.latest_block_height)), + latestBlockHeight: apiToSmallInt(assertNotEmpty(data.latest_block_height)), catchingUp: assertBoolean(data.catching_up), }; } @@ -685,8 +685,8 @@ function decodeTxProof(data: RpcTxProof): responses.TxProof { data: fromBase64(assertNotEmpty(data.data)), rootHash: fromHex(assertNotEmpty(data.root_hash)), proof: { - total: Integer.parse(assertNotEmpty(data.proof.total)), - index: Integer.parse(assertNotEmpty(data.proof.index)), + total: apiToSmallInt(assertNotEmpty(data.proof.total)), + index: apiToSmallInt(assertNotEmpty(data.proof.index)), leafHash: fromBase64(assertNotEmpty(data.proof.leaf_hash)), aunts: assertArray(data.proof.aunts).map(fromBase64), }, @@ -708,8 +708,8 @@ function decodeTxResponse(data: RpcTxResponse): responses.TxResponse { return { tx: fromBase64(assertNotEmpty(data.tx)), result: decodeTxData(assertObject(data.tx_result)), - height: Integer.parse(assertNotEmpty(data.height)), - index: Integer.parse(assertNumber(data.index)), + height: apiToSmallInt(assertNotEmpty(data.height)), + index: apiToSmallInt(assertNumber(data.index)), hash: fromHex(assertNotEmpty(data.hash)), proof: may(decodeTxProof, data.proof), }; @@ -722,7 +722,7 @@ interface RpcTxSearchResponse { function decodeTxSearch(data: RpcTxSearchResponse): responses.TxSearchResponse { return { - totalCount: Integer.parse(assertNotEmpty(data.total_count)), + totalCount: apiToSmallInt(assertNotEmpty(data.total_count)), txs: assertArray(data.txs).map(decodeTxResponse), }; } @@ -742,8 +742,8 @@ function decodeTxEvent(data: RpcTxEvent): responses.TxEvent { tx: tx, hash: hashTx(tx), result: decodeTxData(data.result), - height: Integer.parse(assertNotEmpty(data.height)), - index: may(Integer.parse, data.index), + height: apiToSmallInt(assertNotEmpty(data.height)), + index: may(apiToSmallInt, data.index), }; } @@ -756,10 +756,10 @@ interface RpcValidatorsResponse { function decodeValidators(data: RpcValidatorsResponse): responses.ValidatorsResponse { return { - blockHeight: Integer.parse(assertNotEmpty(data.block_height)), + blockHeight: apiToSmallInt(assertNotEmpty(data.block_height)), validators: assertArray(data.validators).map(decodeValidatorInfo), - count: Integer.parse(assertNotEmpty(data.count)), - total: Integer.parse(assertNotEmpty(data.total)), + count: apiToSmallInt(assertNotEmpty(data.count)), + total: apiToSmallInt(assertNotEmpty(data.total)), }; } @@ -813,7 +813,7 @@ interface RpcBlockSearchResponse { function decodeBlockSearch(data: RpcBlockSearchResponse): responses.BlockSearchResponse { return { - totalCount: Integer.parse(assertNotEmpty(data.total_count)), + totalCount: apiToSmallInt(assertNotEmpty(data.total_count)), blocks: assertArray(data.blocks).map(decodeBlockResponse), }; } @@ -825,8 +825,8 @@ interface RpcNumUnconfirmedTxsResponse { function decodeNumUnconfirmedTxs(data: RpcNumUnconfirmedTxsResponse): responses.NumUnconfirmedTxsResponse { return { - total: Integer.parse(assertNotEmpty(data.total)), - totalBytes: Integer.parse(assertNotEmpty(data.total_bytes)), + total: apiToSmallInt(assertNotEmpty(data.total)), + totalBytes: apiToSmallInt(assertNotEmpty(data.total_bytes)), }; } diff --git a/packages/tendermint-rpc/src/tendermint34/encodings.spec.ts b/packages/tendermint-rpc/src/tendermint34/encodings.spec.ts index afea0600d3..b4921d3b73 100644 --- a/packages/tendermint-rpc/src/tendermint34/encodings.spec.ts +++ b/packages/tendermint-rpc/src/tendermint34/encodings.spec.ts @@ -1,6 +1,13 @@ import { ReadonlyDate } from "readonly-date"; -import { encodeBlockId, encodeBytes, encodeInt, encodeString, encodeTime, encodeVersion } from "./encodings"; +import { + encodeBlockId, + encodeBytes, + encodeString, + encodeTime, + encodeUvarint, + encodeVersion, +} from "./encodings"; describe("encodings", () => { describe("encodeString", () => { @@ -13,14 +20,14 @@ describe("encodings", () => { }); }); - describe("encodeInt", () => { + describe("encodeUvarint", () => { it("works", () => { - expect(encodeInt(0)).toEqual(Uint8Array.from([0])); - expect(encodeInt(1)).toEqual(Uint8Array.from([1])); - expect(encodeInt(127)).toEqual(Uint8Array.from([127])); - expect(encodeInt(128)).toEqual(Uint8Array.from([128, 1])); - expect(encodeInt(255)).toEqual(Uint8Array.from([255, 1])); - expect(encodeInt(256)).toEqual(Uint8Array.from([128, 2])); + expect(encodeUvarint(0)).toEqual(Uint8Array.from([0])); + expect(encodeUvarint(1)).toEqual(Uint8Array.from([1])); + expect(encodeUvarint(127)).toEqual(Uint8Array.from([127])); + expect(encodeUvarint(128)).toEqual(Uint8Array.from([128, 1])); + expect(encodeUvarint(255)).toEqual(Uint8Array.from([255, 1])); + expect(encodeUvarint(256)).toEqual(Uint8Array.from([128, 2])); }); }); diff --git a/packages/tendermint-rpc/src/tendermint34/encodings.ts b/packages/tendermint-rpc/src/tendermint34/encodings.ts index ec5b072775..037b506898 100644 --- a/packages/tendermint-rpc/src/tendermint34/encodings.ts +++ b/packages/tendermint-rpc/src/tendermint34/encodings.ts @@ -1,5 +1,4 @@ import { toUtf8 } from "@cosmjs/encoding"; -import { Int53 } from "@cosmjs/math"; import { ReadonlyDateWithNanoseconds } from "../dates"; import { BlockId, Version } from "./responses"; @@ -140,17 +139,6 @@ export function dictionaryToStringMap(obj: Record): Map= 0x80 ? Uint8Array.from([(n & 0xff) | 0x80, ...encodeInt(n >> 7)]) : Uint8Array.from([n & 0xff]); +export function encodeUvarint(n: number): Uint8Array { + return n >= 0x80 + ? // eslint-disable-next-line no-bitwise + Uint8Array.from([(n & 0xff) | 0x80, ...encodeUvarint(n >> 7)]) + : // eslint-disable-next-line no-bitwise + Uint8Array.from([n & 0xff]); } // See https://github.com/tendermint/go-amino/blob/v0.15.0/encoder.go#L134-L178 export function encodeTime(time: ReadonlyDateWithNanoseconds): Uint8Array { const milliseconds = time.getTime(); const seconds = Math.floor(milliseconds / 1000); - const secondsArray = seconds ? [0x08, ...encodeInt(seconds)] : new Uint8Array(); + const secondsArray = seconds ? [0x08, ...encodeUvarint(seconds)] : new Uint8Array(); const nanoseconds = (time.nanoseconds || 0) + (milliseconds % 1000) * 1e6; - const nanosecondsArray = nanoseconds ? [0x10, ...encodeInt(nanoseconds)] : new Uint8Array(); + const nanosecondsArray = nanoseconds ? [0x10, ...encodeUvarint(nanoseconds)] : new Uint8Array(); return Uint8Array.from([...secondsArray, ...nanosecondsArray]); } @@ -184,8 +175,10 @@ export function encodeBytes(bytes: Uint8Array): Uint8Array { } export function encodeVersion(version: Version): Uint8Array { - const blockArray = version.block ? Uint8Array.from([0x08, ...encodeInt(version.block)]) : new Uint8Array(); - const appArray = version.app ? Uint8Array.from([0x10, ...encodeInt(version.app)]) : new Uint8Array(); + const blockArray = version.block + ? Uint8Array.from([0x08, ...encodeUvarint(version.block)]) + : new Uint8Array(); + const appArray = version.app ? Uint8Array.from([0x10, ...encodeUvarint(version.app)]) : new Uint8Array(); return Uint8Array.from([...blockArray, ...appArray]); } diff --git a/packages/tendermint-rpc/src/tendermint34/hasher.ts b/packages/tendermint-rpc/src/tendermint34/hasher.ts index 65ba6627be..a02d2f814f 100644 --- a/packages/tendermint-rpc/src/tendermint34/hasher.ts +++ b/packages/tendermint-rpc/src/tendermint34/hasher.ts @@ -1,6 +1,13 @@ import { Sha256, sha256 } from "@cosmjs/crypto"; -import { encodeBlockId, encodeBytes, encodeInt, encodeString, encodeTime, encodeVersion } from "./encodings"; +import { + encodeBlockId, + encodeBytes, + encodeString, + encodeTime, + encodeUvarint, + encodeVersion, +} from "./encodings"; import { Header } from "./responses"; // hash is sha256 @@ -55,7 +62,7 @@ export function hashBlock(header: Header): Uint8Array { const encodedFields: readonly Uint8Array[] = [ encodeVersion(header.version), encodeString(header.chainId), - encodeInt(header.height), + encodeUvarint(header.height), encodeTime(header.time), encodeBlockId(header.lastBlockId), diff --git a/packages/tendermint-rpc/src/tendermint34/responses.ts b/packages/tendermint-rpc/src/tendermint34/responses.ts index 0e82dcb3db..70a3516fb3 100644 --- a/packages/tendermint-rpc/src/tendermint34/responses.ts +++ b/packages/tendermint-rpc/src/tendermint34/responses.ts @@ -352,13 +352,13 @@ export interface SyncInfo { export interface Validator { readonly address: Uint8Array; readonly pubkey?: ValidatorPubkey; - readonly votingPower: number; + readonly votingPower: bigint; readonly proposerPriority?: number; } export interface ValidatorUpdate { readonly pubkey: ValidatorPubkey; - readonly votingPower: number; + readonly votingPower: bigint; } export interface ConsensusParams { diff --git a/packages/tendermint-rpc/src/tendermint35/adaptor/requests.ts b/packages/tendermint-rpc/src/tendermint35/adaptor/requests.ts index 441a4aa7a0..52a06a2932 100644 --- a/packages/tendermint-rpc/src/tendermint35/adaptor/requests.ts +++ b/packages/tendermint-rpc/src/tendermint35/adaptor/requests.ts @@ -2,8 +2,9 @@ import { toBase64, toHex } from "@cosmjs/encoding"; import { JsonRpcRequest } from "@cosmjs/json-rpc"; +import { smallIntToApi } from "../../inthelpers"; import { createJsonRpcRequest } from "../../jsonrpc"; -import { assertNotEmpty, Integer, may } from "../encodings"; +import { assertNotEmpty, may } from "../encodings"; import * as requests from "../requests"; interface HeightParam { @@ -14,7 +15,7 @@ interface RpcHeightParam { } function encodeHeightParam(param: HeightParam): RpcHeightParam { return { - height: may(Integer.encode, param.height), + height: may(smallIntToApi, param.height), }; } @@ -25,8 +26,8 @@ interface RpcBlockchainRequestParams { function encodeBlockchainRequestParams(param: requests.BlockchainRequestParams): RpcBlockchainRequestParams { return { - minHeight: may(Integer.encode, param.minHeight), - maxHeight: may(Integer.encode, param.maxHeight), + minHeight: may(smallIntToApi, param.minHeight), + maxHeight: may(smallIntToApi, param.maxHeight), }; } @@ -39,8 +40,8 @@ interface RpcBlockSearchParams { function encodeBlockSearchParams(params: requests.BlockSearchParams): RpcBlockSearchParams { return { query: params.query, - page: may(Integer.encode, params.page), - per_page: may(Integer.encode, params.per_page), + page: may(smallIntToApi, params.page), + per_page: may(smallIntToApi, params.per_page), order_by: params.order_by, }; } @@ -57,7 +58,7 @@ function encodeAbciQueryParams(params: requests.AbciQueryParams): RpcAbciQueryPa return { path: assertNotEmpty(params.path), data: toHex(params.data), - height: may(Integer.encode, params.height), + height: may(smallIntToApi, params.height), prove: params.prove, }; } @@ -95,8 +96,8 @@ function encodeTxSearchParams(params: requests.TxSearchParams): RpcTxSearchParam return { query: params.query, prove: params.prove, - page: may(Integer.encode, params.page), - per_page: may(Integer.encode, params.per_page), + page: may(smallIntToApi, params.page), + per_page: may(smallIntToApi, params.per_page), order_by: params.order_by, }; } @@ -108,9 +109,9 @@ interface RpcValidatorsParams { } function encodeValidatorsParams(params: requests.ValidatorsParams): RpcValidatorsParams { return { - height: may(Integer.encode, params.height), - page: may(Integer.encode, params.page), - per_page: may(Integer.encode, params.per_page), + height: may(smallIntToApi, params.height), + page: may(smallIntToApi, params.page), + per_page: may(smallIntToApi, params.per_page), }; } diff --git a/packages/tendermint-rpc/src/tendermint35/adaptor/responses.spec.ts b/packages/tendermint-rpc/src/tendermint35/adaptor/responses.spec.ts index 35e86679ea..c85b753328 100644 --- a/packages/tendermint-rpc/src/tendermint35/adaptor/responses.spec.ts +++ b/packages/tendermint-rpc/src/tendermint35/adaptor/responses.spec.ts @@ -44,7 +44,7 @@ describe("Adaptor Responses", () => { }); expect(validator).toEqual({ address: fromHex("A03DC128D38DB0BC5F18AE1872F1CB2E1FD41157"), - votingPower: 169980, + votingPower: BigInt(169980), pubkey: { algorithm: "ed25519", data: fromBase64("2BX6Zuj8RmdJAkD1BAg6KB0v04liyM7jBdwOGIb9F9Q="), @@ -72,7 +72,7 @@ describe("Adaptor Responses", () => { algorithm: "ed25519", data: fromBase64("0kNlxBMpm+5WtfHIG1xsWatOXTKPLtmSqn3EiEIDZeI="), }, - votingPower: 11418237, + votingPower: BigInt(11418237), }); }); @@ -93,7 +93,7 @@ describe("Adaptor Responses", () => { algorithm: "ed25519", data: fromBase64("HjSC7VkhKih6xMhudlqfaFE8ZZnP8RKJPv4iqR7RhcE="), }, - votingPower: 0, + votingPower: BigInt(0), }); }); }); @@ -116,7 +116,7 @@ describe("Adaptor Responses", () => { algorithm: "ed25519", data: fromBase64("0kNlxBMpm+5WtfHIG1xsWatOXTKPLtmSqn3EiEIDZeI="), }, - votingPower: 11228980, + votingPower: BigInt(11228980), proposerPriority: 62870960, }); }); diff --git a/packages/tendermint-rpc/src/tendermint35/adaptor/responses.ts b/packages/tendermint-rpc/src/tendermint35/adaptor/responses.ts index 811f113520..30aad6efba 100644 --- a/packages/tendermint-rpc/src/tendermint35/adaptor/responses.ts +++ b/packages/tendermint-rpc/src/tendermint35/adaptor/responses.ts @@ -4,6 +4,7 @@ import { JsonRpcSuccessResponse } from "@cosmjs/json-rpc"; import { assert } from "@cosmjs/utils"; import { DateWithNanoseconds, fromRfc3339WithNanoseconds } from "../../dates"; +import { apiToBigInt, apiToSmallInt } from "../../inthelpers"; import { SubscriptionEvent } from "../../rpcclients"; import { BlockIdFlag, CommitSignature, ValidatorPubkey } from "../../types"; import { @@ -15,7 +16,6 @@ import { assertSet, assertString, dictionaryToStringMap, - Integer, may, } from "../encodings"; import { hashTx } from "../hasher"; @@ -35,7 +35,7 @@ interface RpcAbciInfoResponse { function decodeAbciInfo(data: RpcAbciInfoResponse): responses.AbciInfoResponse { return { data: data.data, - lastBlockHeight: may(Integer.parse, data.last_block_height), + lastBlockHeight: may(apiToSmallInt, data.last_block_height), lastBlockAppHash: may(fromBase64, data.last_block_app_hash), }; } @@ -95,10 +95,10 @@ function decodeAbciQuery(data: RpcAbciQueryResponse): responses.AbciQueryRespons key: fromBase64(assertString(data.key ?? "")), value: fromBase64(assertString(data.value ?? "")), proof: may(decodeQueryProof, data.proofOps), - height: may(Integer.parse, data.height), - code: may(Integer.parse, data.code), + height: may(apiToSmallInt, data.height), + code: may(apiToSmallInt, data.code), codespace: assertString(data.codespace ?? ""), - index: may(Integer.parse, data.index), + index: may(apiToSmallInt, data.index), log: data.log, info: assertString(data.info ?? ""), }; @@ -154,13 +154,13 @@ interface RpcTxData { function decodeTxData(data: RpcTxData): responses.TxData { return { - code: Integer.parse(assertNumber(data.code ?? 0)), + code: apiToSmallInt(assertNumber(data.code ?? 0)), codeSpace: data.codespace, log: data.log, data: may(fromBase64, data.data), events: data.events ? decodeEvents(data.events) : [], - gasWanted: Integer.parse(data.gas_wanted ?? "0"), - gasUsed: Integer.parse(data.gas_used ?? "0"), + gasWanted: apiToSmallInt(data.gas_wanted ?? "0"), + gasUsed: apiToSmallInt(data.gas_used ?? "0"), }; } @@ -222,8 +222,8 @@ interface RpcBlockParams { */ function decodeBlockParams(data: RpcBlockParams): responses.BlockParams { return { - maxBytes: Integer.parse(assertNotEmpty(data.max_bytes)), - maxGas: Integer.parse(assertNotEmpty(data.max_gas)), + maxBytes: apiToSmallInt(assertNotEmpty(data.max_bytes)), + maxGas: apiToSmallInt(assertNotEmpty(data.max_gas)), }; } @@ -234,8 +234,8 @@ interface RpcEvidenceParams { function decodeEvidenceParams(data: RpcEvidenceParams): responses.EvidenceParams { return { - maxAgeNumBlocks: Integer.parse(assertNotEmpty(data.max_age_num_blocks)), - maxAgeDuration: Integer.parse(assertNotEmpty(data.max_age_duration)), + maxAgeNumBlocks: apiToSmallInt(assertNotEmpty(data.max_age_num_blocks)), + maxAgeDuration: apiToSmallInt(assertNotEmpty(data.max_age_duration)), }; } @@ -280,7 +280,7 @@ interface RpcValidatorUpdate { export function decodeValidatorUpdate(data: RpcValidatorUpdate): responses.ValidatorUpdate { return { pubkey: decodePubkey(assertObject(data.pub_key)), - votingPower: Integer.parse(data.power ?? 0), + votingPower: apiToBigInt(data.power ?? "0"), }; } @@ -295,7 +295,7 @@ interface RpcBlockResultsResponse { function decodeBlockResults(data: RpcBlockResultsResponse): responses.BlockResultsResponse { return { - height: Integer.parse(assertNotEmpty(data.height)), + height: apiToSmallInt(assertNotEmpty(data.height)), results: (data.txs_results || []).map(decodeTxData), validatorUpdates: (data.validator_updates || []).map(decodeValidatorUpdate), consensusUpdates: may(decodeConsensusParams, data.consensus_param_updates), @@ -331,8 +331,8 @@ interface RpcBlockVersion { function decodeBlockVersion(data: RpcBlockVersion): responses.Version { return { - block: Integer.parse(data.block), - app: Integer.parse(data.app ?? 0), + block: apiToSmallInt(data.block), + app: apiToSmallInt(data.app ?? 0), }; } @@ -370,7 +370,7 @@ function decodeHeader(data: RpcHeader): responses.Header { return { version: decodeBlockVersion(data.version), chainId: assertNotEmpty(data.chain_id), - height: Integer.parse(assertNotEmpty(data.height)), + height: apiToSmallInt(assertNotEmpty(data.height)), time: fromRfc3339WithNanoseconds(assertNotEmpty(data.time)), // When there is no last block ID (i.e. this block's height is 1), we get an empty structure like this: @@ -401,9 +401,9 @@ interface RpcBlockMeta { function decodeBlockMeta(data: RpcBlockMeta): responses.BlockMeta { return { blockId: decodeBlockId(data.block_id), - blockSize: Integer.parse(assertNotEmpty(data.block_size)), + blockSize: apiToSmallInt(assertNotEmpty(data.block_size)), header: decodeHeader(data.header), - numTxs: Integer.parse(assertNotEmpty(data.num_txs)), + numTxs: apiToSmallInt(assertNotEmpty(data.num_txs)), }; } @@ -414,7 +414,7 @@ interface RpcBlockchainResponse { function decodeBlockchain(data: RpcBlockchainResponse): responses.BlockchainResponse { return { - lastHeight: Integer.parse(assertNotEmpty(data.last_height)), + lastHeight: apiToSmallInt(assertNotEmpty(data.last_height)), blockMetas: assertArray(data.block_metas).map(decodeBlockMeta), }; } @@ -441,7 +441,7 @@ interface RpcBroadcastTxCommitResponse { function decodeBroadcastTxCommit(data: RpcBroadcastTxCommitResponse): responses.BroadcastTxCommitResponse { return { - height: Integer.parse(data.height), + height: apiToSmallInt(data.height), hash: fromHex(assertNotEmpty(data.hash)), checkTx: decodeTxData(assertObject(data.check_tx)), deliverTx: may(decodeTxData, data.deliver_tx), @@ -495,8 +495,8 @@ interface RpcCommit { function decodeCommit(data: RpcCommit): responses.Commit { return { blockId: decodeBlockId(assertObject(data.block_id)), - height: Integer.parse(assertNotEmpty(data.height)), - round: Integer.parse(data.round), + height: apiToSmallInt(assertNotEmpty(data.height)), + round: apiToSmallInt(data.round), signatures: assertArray(data.signatures).map(decodeCommitSignature), }; } @@ -529,7 +529,7 @@ export function decodeValidatorGenesis(data: RpcValidatorGenesis): responses.Val return { address: fromHex(assertNotEmpty(data.address)), pubkey: decodePubkey(assertObject(data.pub_key)), - votingPower: Integer.parse(assertNotEmpty(data.power)), + votingPower: apiToBigInt(assertNotEmpty(data.power)), }; } @@ -572,9 +572,9 @@ interface RpcValidatorInfo { export function decodeValidatorInfo(data: RpcValidatorInfo): responses.Validator { return { pubkey: decodePubkey(assertObject(data.pub_key)), - votingPower: Integer.parse(assertNotEmpty(data.voting_power)), + votingPower: apiToBigInt(assertNotEmpty(data.voting_power)), address: fromHex(assertNotEmpty(data.address)), - proposerPriority: data.proposer_priority ? Integer.parse(data.proposer_priority) : undefined, + proposerPriority: data.proposer_priority ? apiToSmallInt(data.proposer_priority) : undefined, }; } @@ -612,9 +612,9 @@ function decodeNodeInfo(data: RpcNodeInfo): responses.NodeInfo { moniker: assertNotEmpty(data.moniker), other: dictionaryToStringMap(data.other), protocolVersion: { - app: Integer.parse(assertNotEmpty(data.protocol_version.app)), - block: Integer.parse(assertNotEmpty(data.protocol_version.block)), - p2p: Integer.parse(assertNotEmpty(data.protocol_version.p2p)), + app: apiToSmallInt(assertNotEmpty(data.protocol_version.app)), + block: apiToSmallInt(assertNotEmpty(data.protocol_version.block)), + p2p: apiToSmallInt(assertNotEmpty(data.protocol_version.p2p)), }, }; } @@ -634,7 +634,7 @@ function decodeSyncInfo(data: RpcSyncInfo): responses.SyncInfo { latestBlockHash: fromHex(assertNotEmpty(data.latest_block_hash)), latestAppHash: fromHex(assertNotEmpty(data.latest_app_hash)), latestBlockTime: fromRfc3339WithNanoseconds(assertNotEmpty(data.latest_block_time)), - latestBlockHeight: Integer.parse(assertNotEmpty(data.latest_block_height)), + latestBlockHeight: apiToSmallInt(assertNotEmpty(data.latest_block_height)), catchingUp: assertBoolean(data.catching_up), }; } @@ -686,8 +686,8 @@ function decodeTxProof(data: RpcTxProof): responses.TxProof { data: fromBase64(assertNotEmpty(data.data)), rootHash: fromHex(assertNotEmpty(data.root_hash)), proof: { - total: Integer.parse(assertNotEmpty(data.proof.total)), - index: Integer.parse(assertNotEmpty(data.proof.index)), + total: apiToSmallInt(assertNotEmpty(data.proof.total)), + index: apiToSmallInt(assertNotEmpty(data.proof.index)), leafHash: fromBase64(assertNotEmpty(data.proof.leaf_hash)), aunts: assertArray(data.proof.aunts).map(fromBase64), }, @@ -709,8 +709,8 @@ function decodeTxResponse(data: RpcTxResponse): responses.TxResponse { return { tx: fromBase64(assertNotEmpty(data.tx)), result: decodeTxData(assertObject(data.tx_result)), - height: Integer.parse(assertNotEmpty(data.height)), - index: Integer.parse(assertNumber(data.index)), + height: apiToSmallInt(assertNotEmpty(data.height)), + index: apiToSmallInt(assertNumber(data.index)), hash: fromHex(assertNotEmpty(data.hash)), proof: may(decodeTxProof, data.proof), }; @@ -723,7 +723,7 @@ interface RpcTxSearchResponse { function decodeTxSearch(data: RpcTxSearchResponse): responses.TxSearchResponse { return { - totalCount: Integer.parse(assertNotEmpty(data.total_count)), + totalCount: apiToSmallInt(assertNotEmpty(data.total_count)), txs: assertArray(data.txs).map(decodeTxResponse), }; } @@ -743,8 +743,8 @@ function decodeTxEvent(data: RpcTxEvent): responses.TxEvent { tx: tx, hash: hashTx(tx), result: decodeTxData(data.result), - height: Integer.parse(assertNotEmpty(data.height)), - index: may(Integer.parse, data.index), + height: apiToSmallInt(assertNotEmpty(data.height)), + index: may(apiToSmallInt, data.index), }; } @@ -757,10 +757,10 @@ interface RpcValidatorsResponse { function decodeValidators(data: RpcValidatorsResponse): responses.ValidatorsResponse { return { - blockHeight: Integer.parse(assertNotEmpty(data.block_height)), + blockHeight: apiToSmallInt(assertNotEmpty(data.block_height)), validators: assertArray(data.validators).map(decodeValidatorInfo), - count: Integer.parse(assertNotEmpty(data.count)), - total: Integer.parse(assertNotEmpty(data.total)), + count: apiToSmallInt(assertNotEmpty(data.count)), + total: apiToSmallInt(assertNotEmpty(data.total)), }; } @@ -814,7 +814,7 @@ interface RpcBlockSearchResponse { function decodeBlockSearch(data: RpcBlockSearchResponse): responses.BlockSearchResponse { return { - totalCount: Integer.parse(assertNotEmpty(data.total_count)), + totalCount: apiToSmallInt(assertNotEmpty(data.total_count)), blocks: assertArray(data.blocks).map(decodeBlockResponse), }; } @@ -826,8 +826,8 @@ interface RpcNumUnconfirmedTxsResponse { function decodeNumUnconfirmedTxs(data: RpcNumUnconfirmedTxsResponse): responses.NumUnconfirmedTxsResponse { return { - total: Integer.parse(assertNotEmpty(data.total)), - totalBytes: Integer.parse(assertNotEmpty(data.total_bytes)), + total: apiToSmallInt(assertNotEmpty(data.total)), + totalBytes: apiToSmallInt(assertNotEmpty(data.total_bytes)), }; } diff --git a/packages/tendermint-rpc/src/tendermint35/encodings.spec.ts b/packages/tendermint-rpc/src/tendermint35/encodings.spec.ts index afea0600d3..b4921d3b73 100644 --- a/packages/tendermint-rpc/src/tendermint35/encodings.spec.ts +++ b/packages/tendermint-rpc/src/tendermint35/encodings.spec.ts @@ -1,6 +1,13 @@ import { ReadonlyDate } from "readonly-date"; -import { encodeBlockId, encodeBytes, encodeInt, encodeString, encodeTime, encodeVersion } from "./encodings"; +import { + encodeBlockId, + encodeBytes, + encodeString, + encodeTime, + encodeUvarint, + encodeVersion, +} from "./encodings"; describe("encodings", () => { describe("encodeString", () => { @@ -13,14 +20,14 @@ describe("encodings", () => { }); }); - describe("encodeInt", () => { + describe("encodeUvarint", () => { it("works", () => { - expect(encodeInt(0)).toEqual(Uint8Array.from([0])); - expect(encodeInt(1)).toEqual(Uint8Array.from([1])); - expect(encodeInt(127)).toEqual(Uint8Array.from([127])); - expect(encodeInt(128)).toEqual(Uint8Array.from([128, 1])); - expect(encodeInt(255)).toEqual(Uint8Array.from([255, 1])); - expect(encodeInt(256)).toEqual(Uint8Array.from([128, 2])); + expect(encodeUvarint(0)).toEqual(Uint8Array.from([0])); + expect(encodeUvarint(1)).toEqual(Uint8Array.from([1])); + expect(encodeUvarint(127)).toEqual(Uint8Array.from([127])); + expect(encodeUvarint(128)).toEqual(Uint8Array.from([128, 1])); + expect(encodeUvarint(255)).toEqual(Uint8Array.from([255, 1])); + expect(encodeUvarint(256)).toEqual(Uint8Array.from([128, 2])); }); }); diff --git a/packages/tendermint-rpc/src/tendermint35/encodings.ts b/packages/tendermint-rpc/src/tendermint35/encodings.ts index ec5b072775..037b506898 100644 --- a/packages/tendermint-rpc/src/tendermint35/encodings.ts +++ b/packages/tendermint-rpc/src/tendermint35/encodings.ts @@ -1,5 +1,4 @@ import { toUtf8 } from "@cosmjs/encoding"; -import { Int53 } from "@cosmjs/math"; import { ReadonlyDateWithNanoseconds } from "../dates"; import { BlockId, Version } from "./responses"; @@ -140,17 +139,6 @@ export function dictionaryToStringMap(obj: Record): Map= 0x80 ? Uint8Array.from([(n & 0xff) | 0x80, ...encodeInt(n >> 7)]) : Uint8Array.from([n & 0xff]); +export function encodeUvarint(n: number): Uint8Array { + return n >= 0x80 + ? // eslint-disable-next-line no-bitwise + Uint8Array.from([(n & 0xff) | 0x80, ...encodeUvarint(n >> 7)]) + : // eslint-disable-next-line no-bitwise + Uint8Array.from([n & 0xff]); } // See https://github.com/tendermint/go-amino/blob/v0.15.0/encoder.go#L134-L178 export function encodeTime(time: ReadonlyDateWithNanoseconds): Uint8Array { const milliseconds = time.getTime(); const seconds = Math.floor(milliseconds / 1000); - const secondsArray = seconds ? [0x08, ...encodeInt(seconds)] : new Uint8Array(); + const secondsArray = seconds ? [0x08, ...encodeUvarint(seconds)] : new Uint8Array(); const nanoseconds = (time.nanoseconds || 0) + (milliseconds % 1000) * 1e6; - const nanosecondsArray = nanoseconds ? [0x10, ...encodeInt(nanoseconds)] : new Uint8Array(); + const nanosecondsArray = nanoseconds ? [0x10, ...encodeUvarint(nanoseconds)] : new Uint8Array(); return Uint8Array.from([...secondsArray, ...nanosecondsArray]); } @@ -184,8 +175,10 @@ export function encodeBytes(bytes: Uint8Array): Uint8Array { } export function encodeVersion(version: Version): Uint8Array { - const blockArray = version.block ? Uint8Array.from([0x08, ...encodeInt(version.block)]) : new Uint8Array(); - const appArray = version.app ? Uint8Array.from([0x10, ...encodeInt(version.app)]) : new Uint8Array(); + const blockArray = version.block + ? Uint8Array.from([0x08, ...encodeUvarint(version.block)]) + : new Uint8Array(); + const appArray = version.app ? Uint8Array.from([0x10, ...encodeUvarint(version.app)]) : new Uint8Array(); return Uint8Array.from([...blockArray, ...appArray]); } diff --git a/packages/tendermint-rpc/src/tendermint35/hasher.ts b/packages/tendermint-rpc/src/tendermint35/hasher.ts index 65ba6627be..a02d2f814f 100644 --- a/packages/tendermint-rpc/src/tendermint35/hasher.ts +++ b/packages/tendermint-rpc/src/tendermint35/hasher.ts @@ -1,6 +1,13 @@ import { Sha256, sha256 } from "@cosmjs/crypto"; -import { encodeBlockId, encodeBytes, encodeInt, encodeString, encodeTime, encodeVersion } from "./encodings"; +import { + encodeBlockId, + encodeBytes, + encodeString, + encodeTime, + encodeUvarint, + encodeVersion, +} from "./encodings"; import { Header } from "./responses"; // hash is sha256 @@ -55,7 +62,7 @@ export function hashBlock(header: Header): Uint8Array { const encodedFields: readonly Uint8Array[] = [ encodeVersion(header.version), encodeString(header.chainId), - encodeInt(header.height), + encodeUvarint(header.height), encodeTime(header.time), encodeBlockId(header.lastBlockId), diff --git a/packages/tendermint-rpc/src/tendermint35/responses.ts b/packages/tendermint-rpc/src/tendermint35/responses.ts index f03cabcac8..7440d8d927 100644 --- a/packages/tendermint-rpc/src/tendermint35/responses.ts +++ b/packages/tendermint-rpc/src/tendermint35/responses.ts @@ -357,13 +357,13 @@ export interface SyncInfo { export interface Validator { readonly address: Uint8Array; readonly pubkey?: ValidatorPubkey; - readonly votingPower: number; + readonly votingPower: bigint; readonly proposerPriority?: number; } export interface ValidatorUpdate { readonly pubkey: ValidatorPubkey; - readonly votingPower: number; + readonly votingPower: bigint; } export interface ConsensusParams {