Add minHeight/maxHeight support to searchTx

This commit is contained in:
Simon Warta 2020-02-18 10:36:58 +01:00
parent 404db28f6f
commit 2f41f93d96
3 changed files with 229 additions and 12 deletions

View File

@ -496,7 +496,7 @@ describe("CosmWasmConnection", () => {
});
});
describe("integration tests", () => {
describe("searchTx", () => {
it("can post and search for a transaction", async () => {
pendingWithoutWasmd();
const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig);
@ -587,6 +587,215 @@ describe("CosmWasmConnection", () => {
connection.disconnect();
});
it("can search by minHeight and maxHeight", async () => {
pendingWithoutWasmd();
const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig);
const profile = new UserProfile();
const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucet.mnemonic));
const sender = await profile.createIdentity(wallet.id, defaultChainId, faucet.path);
const senderAddress = connection.codec.identityToAddress(sender);
const recipient = makeRandomAddress();
const unsigned = await connection.withDefaultFee<SendTransaction>({
kind: "bcp/send",
chainId: defaultChainId,
sender: senderAddress,
recipient: recipient,
memo: "My first payment",
amount: {
quantity: "75000",
fractionalDigits: 6,
tokenTicker: cosm,
},
});
const nonce = await connection.getNonce({ address: senderAddress });
const signed = await profile.signTransaction(sender, unsigned, connection.codec, nonce);
const postableBytes = connection.codec.bytesToPost(signed);
const response = await connection.postTx(postableBytes);
const { transactionId } = response;
const blockInfo = await response.blockInfo.waitFor(info => !isBlockInfoPending(info));
assert(isBlockInfoSucceeded(blockInfo));
const { height } = blockInfo;
// search by ID
{
const results = await connection.searchTx({ id: transactionId });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ id: transactionId, minHeight: height });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ id: transactionId, minHeight: height - 2 });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ id: transactionId, maxHeight: height });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ id: transactionId, maxHeight: height + 2 });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({
id: transactionId,
minHeight: height,
maxHeight: height,
});
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ id: transactionId, minHeight: height + 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({ id: transactionId, maxHeight: height - 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({
id: transactionId,
minHeight: height + 1,
maxHeight: Number.MAX_SAFE_INTEGER,
});
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({ id: transactionId, minHeight: 0, maxHeight: height - 1 });
expect(results.length).toEqual(0);
}
// search by recipient
{
const results = await connection.searchTx({ sentFromOrTo: recipient });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ sentFromOrTo: recipient, minHeight: height });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ sentFromOrTo: recipient, minHeight: height - 2 });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ sentFromOrTo: recipient, maxHeight: height });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ sentFromOrTo: recipient, maxHeight: height + 2 });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ sentFromOrTo: recipient, minHeight: height + 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({ sentFromOrTo: recipient, maxHeight: height - 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({
sentFromOrTo: recipient,
minHeight: height,
maxHeight: height,
});
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ sentFromOrTo: recipient, minHeight: height + 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({ sentFromOrTo: recipient, maxHeight: height - 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({
sentFromOrTo: recipient,
minHeight: height + 1,
maxHeight: Number.MAX_SAFE_INTEGER,
});
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({
sentFromOrTo: recipient,
minHeight: 0,
maxHeight: height - 1,
});
expect(results.length).toEqual(0);
}
// search by height
{
const results = await connection.searchTx({ height: height });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ height: height, minHeight: height });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ height: height, minHeight: height - 2 });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ height: height, maxHeight: height });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ height: height, maxHeight: height + 2 });
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ height: height, minHeight: height + 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({ height: height, maxHeight: height - 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({
height: height,
minHeight: height,
maxHeight: height,
});
expect(results.length).toEqual(1);
}
{
const results = await connection.searchTx({ height: height, minHeight: height + 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({ height: height, maxHeight: height - 1 });
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({
height: height,
minHeight: height + 1,
maxHeight: Number.MAX_SAFE_INTEGER,
});
expect(results.length).toEqual(0);
}
{
const results = await connection.searchTx({
height: height,
minHeight: 0,
maxHeight: height - 1,
});
expect(results.length).toEqual(0);
}
connection.disconnect();
});
});
describe("integration tests", () => {
it("can send ERC20 tokens", async () => {
pendingWithoutWasmd();
const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig);

View File

@ -304,8 +304,8 @@ export class CosmWasmConnection implements BlockchainConnection {
public async searchTx({
height,
id,
maxHeight,
minHeight,
maxHeight: maxHeightOptional,
minHeight: minHeightOptional,
sentFromOrTo,
signedBy,
tags,
@ -314,30 +314,38 @@ export class CosmWasmConnection implements BlockchainConnection {
throw new Error("Transaction query by signedBy or tags not yet supported");
}
if ([maxHeight, minHeight].some(isDefined)) {
throw new Error(
"Transaction query by minHeight/maxHeight not yet supported. This is due to missing flexibility of the Gaia REST API, see https://github.com/cosmos/gaia/issues/75",
);
}
if ([id, height, sentFromOrTo].filter(isDefined).length !== 1) {
throw new Error(
"Transaction query by id, height and sentFromOrTo is mutually exclusive. Exactly one must be set.",
);
}
const minHeight = minHeightOptional || 0;
const maxHeight = maxHeightOptional || Number.MAX_SAFE_INTEGER;
if (maxHeight < minHeight) return []; // optional optimization
let txs: readonly TxsResponse[];
if (id) {
txs = await this.cosmWasmClient.searchTx({ id: id });
} else if (height) {
if (height < minHeight) return []; // optional optimization
if (height > maxHeight) return []; // optional optimization
txs = await this.cosmWasmClient.searchTx({ height: height });
} else if (sentFromOrTo) {
// TODO: pass minHeight/maxHeight to server once we have
// https://github.com/cosmwasm/wasmd/issues/73
txs = await this.cosmWasmClient.searchTx({ sentFromOrTo: sentFromOrTo });
} else {
throw new Error("Unsupported query");
}
return txs.map(tx => this.parseAndPopulateTxResponseUnsigned(tx));
const filtered = txs.filter(tx => {
const txHeight = parseInt(tx.height, 10);
return txHeight >= minHeight && txHeight <= maxHeight;
});
return filtered.map(tx => this.parseAndPopulateTxResponseUnsigned(tx));
}
public listenTx(

View File

@ -74,8 +74,8 @@ export declare class CosmWasmConnection implements BlockchainConnection {
searchTx({
height,
id,
maxHeight,
minHeight,
maxHeight: maxHeightOptional,
minHeight: minHeightOptional,
sentFromOrTo,
signedBy,
tags,