Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Tendermint 0.34 support #430

Merged
merged 8 commits into from
Sep 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,9 @@
- @cosmjs/tendermint-rpc: Remove trivial helpers `getTxEventHeight`,
`getHeaderEventHeight` and `getBlockEventHeight` because they don't do
anything else than accessing an object member.
- @cosmjs/tendermint-rpc: Add support for connecting to Tendermint RPC 0.34.
- @cosmjs/tendermint-rpc: Make `TxEvent.index` optional and deprecate it because
it is not set anymore in Tendermint 0.34.
- @cosmjs/utils: Add `assertDefined`.
- @cosmjs/faucet: Rename binary from `cosmwasm-faucet` to `cosmos-faucet`.

Expand Down
2 changes: 1 addition & 1 deletion packages/tendermint-rpc/src/adaptorforversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { v0_33 } from "./v0-33";
* @param version full Tendermint version string, e.g. "0.20.1"
*/
export function adaptorForVersion(version: string): Adaptor {
if (version.startsWith("0.33.")) {
if (version.startsWith("0.33.") || version.startsWith("0.34.")) {
return v0_33;
} else {
throw new Error(`Unsupported tendermint version: ${version}`);
Expand Down
38 changes: 24 additions & 14 deletions packages/tendermint-rpc/src/client.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Stream } from "xstream";
import { Adaptor } from "./adaptor";
import { adaptorForVersion } from "./adaptorforversion";
import { Client } from "./client";
import { tendermintInstances } from "./config.spec";
import { ExpectedValues, tendermintInstances } from "./config.spec";
import { buildQuery } from "./requests";
import * as responses from "./responses";
import { HttpClient, RpcClient, WebsocketClient } from "./rpcclients";
Expand Down Expand Up @@ -41,7 +41,7 @@ function randomString(): string {
.join("");
}

function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor): void {
function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expected: ExpectedValues): void {
it("can connect to tendermint with known version", async () => {
pendingWithoutTendermint();
const client = new Client(rpcFactory(), adaptor);
Expand Down Expand Up @@ -133,13 +133,25 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor): void {
const client = new Client(rpcFactory(), adaptor);

const status = await client.status();

// node info
expect(status.nodeInfo.protocolVersion).toEqual({
p2p: expected.p2pVersion,
block: expected.blockVersion,
app: expected.appVersion,
});
expect(status.nodeInfo.network).toMatch(chainIdMatcher);
expect(status.nodeInfo.other.size).toBeGreaterThanOrEqual(2);
expect(status.nodeInfo.other.get("tx_index")).toEqual("on");
expect(status.validatorInfo.pubkey).toBeTruthy();
expect(status.validatorInfo.votingPower).toBeGreaterThan(0);

// sync info
expect(status.syncInfo.catchingUp).toEqual(false);
expect(status.syncInfo.latestBlockHeight).toBeGreaterThanOrEqual(1);

// validator info
expect(status.validatorInfo.pubkey).toBeTruthy();
expect(status.validatorInfo.votingPower).toBeGreaterThan(0);

client.disconnect();
});
});
Expand Down Expand Up @@ -238,8 +250,8 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor): void {
// num_txs: jasmine.stringMatching(nonNegativeIntegerMatcher),
header: jasmine.objectContaining({
version: {
block: 10,
app: 1,
block: expected.blockVersion,
app: expected.appVersion,
},
chainId: jasmine.stringMatching(chainIdMatcher),
}),
Expand Down Expand Up @@ -371,7 +383,7 @@ function defaultTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor): void {
});
}

function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, appCreator: string): void {
function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, expected: ExpectedValues): void {
it("can subscribe to block header events", (done) => {
pendingWithoutTendermint();

Expand Down Expand Up @@ -498,7 +510,6 @@ function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, appCr
const subscription = stream.subscribe({
next: (event) => {
expect(event.height).toBeGreaterThan(0);
expect(event.index).toEqual(0);
expect(event.result).toBeTruthy();
expect(event.result.events.length).toBeGreaterThanOrEqual(1);

Expand Down Expand Up @@ -539,13 +550,12 @@ function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, appCr

const events: responses.TxEvent[] = [];
const client = new Client(rpcFactory(), adaptor);
const query = buildQuery({ tags: [{ key: "app.creator", value: appCreator }] });
const query = buildQuery({ tags: [{ key: "app.creator", value: expected.appCreator }] });
const stream = client.subscribeTx(query);
expect(stream).toBeTruthy();
const subscription = stream.subscribe({
next: (event) => {
expect(event.height).toBeGreaterThan(0);
expect(event.index).toEqual(0);
expect(event.result).toBeTruthy();
expect(event.result.events.length).toBeGreaterThanOrEqual(1);
events.push(event);
Expand Down Expand Up @@ -622,7 +632,7 @@ function websocketTestSuite(rpcFactory: () => RpcClient, adaptor: Adaptor, appCr
});
}

for (const { url, version, appCreator } of tendermintInstances) {
for (const { url, version, expected } of tendermintInstances) {
describe(`Client ${version}`, () => {
it("can connect to a given url", async () => {
pendingWithoutTendermint();
Expand Down Expand Up @@ -654,16 +664,16 @@ for (const { url, version, appCreator } of tendermintInstances) {

describe("With HttpClient", () => {
const adaptor = adaptorForVersion(version);
defaultTestSuite(() => new HttpClient(url), adaptor);
defaultTestSuite(() => new HttpClient(url), adaptor, expected);
});

describe("With WebsocketClient", () => {
// don't print out WebSocket errors if marked pending
const onError = process.env.TENDERMINT_ENABLED ? console.error : () => 0;
const factory = (): WebsocketClient => new WebsocketClient(url, onError);
const adaptor = adaptorForVersion(version);
defaultTestSuite(factory, adaptor);
websocketTestSuite(factory, adaptor, appCreator);
defaultTestSuite(factory, adaptor, expected);
websocketTestSuite(factory, adaptor, expected);
});
});
}
31 changes: 29 additions & 2 deletions packages/tendermint-rpc/src/config.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
export interface ExpectedValues {
readonly appCreator: string;
readonly p2pVersion: number;
readonly blockVersion: number;
readonly appVersion: number;
}

export interface TendermintInstance {
readonly url: string;
readonly version: string;
readonly appCreator: string;
/** rough block time in ms */
readonly blockTime: number;
/** Values we expect in the backend */
readonly expected: ExpectedValues;
}

/**
Expand All @@ -20,7 +30,24 @@ export const tendermintInstances: readonly TendermintInstance[] = [
{
url: "localhost:11133",
version: "0.33.x",
appCreator: "Cosmoshi Netowoko",
blockTime: 1000,
expected: {
appCreator: "Cosmoshi Netowoko",
p2pVersion: 7,
blockVersion: 10,
appVersion: 1,
},
},
{
url: "localhost:11134",
version: "0.34.x",
blockTime: 500,
expected: {
appCreator: "Cosmoshi Netowoko",
p2pVersion: 8,
blockVersion: 11,
appVersion: 1,
},
},
];

Expand Down
3 changes: 2 additions & 1 deletion packages/tendermint-rpc/src/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,8 @@ export interface TxEvent {
readonly tx: TxBytes;
readonly hash: TxHash;
readonly height: number;
readonly index: number;
/** @deprecated this value is not set in Tendermint 0.34+ */
readonly index?: number;
readonly result: TxData;
}

Expand Down
32 changes: 16 additions & 16 deletions packages/tendermint-rpc/src/rpcclients/websocketclient.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function pendingWithoutTendermint(): void {
}

describe("WebsocketClient", () => {
const tendermintUrl = defaultInstance.url;
const { blockTime, url: tendermintUrl } = defaultInstance;

it("can make a simple call", async () => {
pendingWithoutTendermint();
Expand Down Expand Up @@ -48,27 +48,27 @@ describe("WebsocketClient", () => {

const events: SubscriptionEvent[] = [];

const sub = headers.subscribe({
const subscription = headers.subscribe({
error: done.fail,
complete: () => done.fail("subscription should not complete"),
next: (evt: SubscriptionEvent) => {
events.push(evt);
expect(evt.query).toEqual(query);
next: (event: SubscriptionEvent) => {
events.push(event);
expect(event.query).toEqual(query);

if (events.length === 2) {
// make sure they are consequtive heights
const height = (i: number): number => Integer.parse(events[i].data.value.header.height);
expect(height(1)).toEqual(height(0) + 1);

sub.unsubscribe();
subscription.unsubscribe();

// wait 1.5s and check we did not get more events
// wait 1.5 * blockTime and check we did not get more events
setTimeout(() => {
expect(events.length).toEqual(2);

client.disconnect();
done();
}, 1500);
}, 1.5 * blockTime);
}
},
});
Expand Down Expand Up @@ -110,23 +110,23 @@ describe("WebsocketClient", () => {

const events: SubscriptionEvent[] = [];

const sub = headers.subscribe({
const subscription = headers.subscribe({
error: done.fail,
complete: () => done.fail("subscription should not complete"),
next: (evt: SubscriptionEvent) => {
events.push(evt);
expect(evt.query).toEqual(query);
next: (event: SubscriptionEvent) => {
events.push(event);
expect(event.query).toEqual(query);

if (events.length === 2) {
sub.unsubscribe();
subscription.unsubscribe();

// wait 1.5s and check we did not get more events
// wait 1.5 * blockTime and check we did not get more events
setTimeout(() => {
expect(events.length).toEqual(2);

client.disconnect();
done();
}, 1500);
}, 1.5 * blockTime);
}
},
});
Expand All @@ -148,7 +148,7 @@ describe("WebsocketClient", () => {

const receivedEvents: SubscriptionEvent[] = [];

setTimeout(() => client.disconnect(), 1500);
setTimeout(() => client.disconnect(), blockTime);

headers.subscribe({
error: done.fail,
Expand Down
5 changes: 3 additions & 2 deletions packages/tendermint-rpc/src/v0-33/responses.ts
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,8 @@ interface RpcTxEvent {
readonly tx: Base64String;
readonly result: RpcTxData;
readonly height: IntegerString;
readonly index: number;
/** Not set since Tendermint 0.34 */
readonly index?: number;
}

function decodeTxEvent(data: RpcTxEvent): responses.TxEvent {
Expand All @@ -629,7 +630,7 @@ function decodeTxEvent(data: RpcTxEvent): responses.TxEvent {
hash: hashTx(tx),
result: decodeTxData(data.result),
height: Integer.parse(assertNotEmpty(data.height)),
index: Integer.parse(assertNumber(data.index)),
index: may(Integer.parse, data.index),
};
}

Expand Down
3 changes: 2 additions & 1 deletion packages/tendermint-rpc/types/responses.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ export interface TxEvent {
readonly tx: TxBytes;
readonly hash: TxHash;
readonly height: number;
readonly index: number;
/** @deprecated this value is not set in Tendermint 0.34+ */
readonly index?: number;
readonly result: TxData;
}
/** An event attribute */
Expand Down
3 changes: 2 additions & 1 deletion scripts/tendermint/all_start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ command -v shellcheck > /dev/null && shellcheck "$0"

# Find latest patch releases at https://hub.docker.com/r/tendermint/tendermint/tags/
declare -a TM_VERSIONS
TM_VERSIONS[33]=v0.33.5
TM_VERSIONS[33]=v0.33.8
TM_VERSIONS[34]=latest

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Expand Down
3 changes: 2 additions & 1 deletion scripts/tendermint/all_stop.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ set -o errexit -o nounset -o pipefail
command -v shellcheck > /dev/null && shellcheck "$0"

declare -a TM_VERSIONS
TM_VERSIONS[33]=v0.33.5
TM_VERSIONS[33]=v0.33.8
TM_VERSIONS[34]=latest

SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

Expand Down
5 changes: 3 additions & 2 deletions scripts/tendermint/start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ if [ -n "${CI:-}" ]; then
# Give process some time to come alive. No idea why this helps. Needed for CI.
sleep 0.5

# Follow the logs in CI's background job
tail -f "$LOGFILE"
# Debug start
sleep 3
cat "$LOGFILE"
fi