Randomize contracts in tests

This commit is contained in:
Simon Warta 2020-02-05 01:22:45 +01:00
parent 4136d5e691
commit 488dd79be7
2 changed files with 75 additions and 4 deletions

View File

@ -0,0 +1,39 @@
import { Encoding } from "@iov/encoding";
const { fromHex } = Encoding;
export function leb128Encode(uint: number): Uint8Array {
if (uint < 0) throw new Error("Only non-negative values supported");
if (uint > 0x7fffffff) throw new Error("Only values in signed int32 range allowed");
const out = new Array<number>();
let value = uint;
do {
// tslint:disable: no-bitwise
let byte = value & 0b01111111;
value >>= 7;
// more bytes to come: set high order bit of byte
if (value !== 0) byte ^= 0b10000000;
out.push(byte);
// tslint:enable: no-bitwise
} while (value !== 0);
return new Uint8Array(out);
}
describe("leb128", () => {
describe("leb128Encode", () => {
it("works for single byte values", () => {
// Values in 7 bit range are encoded as one byte
expect(leb128Encode(0)).toEqual(fromHex("00"));
expect(leb128Encode(20)).toEqual(fromHex("14"));
expect(leb128Encode(127)).toEqual(fromHex("7f"));
});
it("works for multi byte values", () => {
// from external souce (wasm-objdump)
expect(leb128Encode(145)).toEqual(fromHex("9101"));
expect(leb128Encode(1539)).toEqual(fromHex("830c"));
});
});
});

View File

@ -4,6 +4,7 @@ import { Encoding } from "@iov/encoding";
import { HdPaths, Secp256k1HdWallet } from "@iov/keycontrol";
import { encodeSecp256k1Signature, makeSignBytes, marshalTx } from "./encoding";
import { leb128Encode } from "./leb128.spec";
import { Log, parseLogs } from "./logs";
import { RestClient } from "./restclient";
import contract from "./testdata/contract.json";
@ -19,7 +20,7 @@ import {
StdTx,
} from "./types";
const { fromBase64 } = Encoding;
const { fromBase64, toBase64 } = Encoding;
const httpUrl = "http://localhost:1317";
const defaultNetworkId = "testing";
@ -49,6 +50,32 @@ function makeSignedTx(firstMsg: Msg, fee: StdFee, memo: string, firstSignature:
};
}
function getRandomizedContract(): Uint8Array {
const data = fromBase64(contract.data);
// The return value of the export function cosmwasm_api_0_6 is unused and
// can be randomized for testing.
//
// Find position of mutable bytes as follows:
// $ wasm-objdump -d contract.wasm | grep -F "cosmwasm_api_0_6" -A 1
// 00e67c func[149] <cosmwasm_api_0_6>:
// 00e67d: 41 83 0c | i32.const 1539
//
// In the last line, the addresses 00e67d-00e67f hold a one byte instruction
// (https://github.com/WebAssembly/design/blob/master/BinaryEncoding.md#constants-described-here)
// and a two byte value (leb128 encoded 1539)
// Any unsigned integer from 128 to 16383 is encoded to two leb128 bytes
const min = 128;
const max = 16383;
const random = Math.floor(Math.random() * (max - min)) + min;
const bytes = leb128Encode(random);
data[0x00e67d + 1] = bytes[0];
data[0x00e67d + 2] = bytes[1];
return data;
}
describe("RestClient", () => {
it("can be constructed", () => {
const client = new RestClient(httpUrl);
@ -133,6 +160,8 @@ describe("RestClient", () => {
const signer = await wallet.createIdentity("abc" as ChainId, faucetPath);
const client = new RestClient(httpUrl);
let codeId: number;
// upload
{
const memo = "My first contract on chain";
@ -140,7 +169,7 @@ describe("RestClient", () => {
type: "wasm/store-code",
value: {
sender: faucetAddress,
wasm_byte_code: contract.data,
wasm_byte_code: toBase64(getRandomizedContract()),
source: "https://github.com/confio/cosmwasm/raw/0.7/lib/vm/testdata/contract_0.6.wasm",
builder: "cosmwasm-opt:0.6.2",
},
@ -165,7 +194,10 @@ describe("RestClient", () => {
expect(result.code).toBeFalsy();
const [firstLog] = parseSuccess(result.raw_log);
const codeIdAttr = firstLog.events[0].attributes.find(attr => attr.key === "code_id");
expect(codeIdAttr).toEqual({ key: "code_id", value: "1" });
if (!codeIdAttr) throw new Error("Could not find code_id attribute");
codeId = Number.parseInt(codeIdAttr.value, 10);
expect(codeId).toBeGreaterThanOrEqual(1);
expect(codeId).toBeLessThanOrEqual(200);
}
let contractAddress: string;
@ -187,7 +219,7 @@ describe("RestClient", () => {
type: "wasm/instantiate",
value: {
sender: faucetAddress,
code_id: "1",
code_id: codeId.toString(),
init_msg: {
verifier: "cosmos1ltkhnmdcqemmd2tkhnx7qx66tq7e0wykw2j85k",
beneficiary: "cosmos1ltkhnmdcqemmd2tkhnx7qx66tq7e0wykw2j85k",