Merge pull request #848 from cosmos/copy-isValidBuilder

Remove dependencies on @cosmjs/cosmwasm-launchpad
This commit is contained in:
Simon Warta 2021-07-22 12:20:20 +02:00 committed by GitHub
commit fcb017d83d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 149 additions and 26 deletions

1
.pnp.js generated
View File

@ -3398,7 +3398,6 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) {
"packageDependencies": [
["@cosmjs/cosmwasm-stargate", "workspace:packages/cosmwasm-stargate"],
["@cosmjs/amino", "workspace:packages/amino"],
["@cosmjs/cosmwasm-launchpad", "workspace:packages/cosmwasm-launchpad"],
["@cosmjs/crypto", "workspace:packages/crypto"],
["@cosmjs/encoding", "workspace:packages/encoding"],
["@cosmjs/math", "workspace:packages/math"],

View File

@ -17,6 +17,11 @@ and this project adheres to
available under `tendermint33`.
- @cosmjs/proto-signing and @cosmjs/stargate: Create a Stargate-ready
`parseCoins` that replaces the `parseCoins` re-export from `@cosmjs/amino`.
- @cosmjs/cosmwasm-stargate: Export `isValidBuilder`, which is a clone of
`isValidBuilder` from @cosmjs/cosmwasm-launchpad.
- @cosmjs/cosmwasm-stargate: Copy symbols `Code`, `CodeDetails`, `Contract`,
`ContractCodeHistoryEntry` and `JsonObject` from @cosmjs/cosmwasm-launchpad
and remove dependency on @cosmjs/cosmwasm-launchpad.
### Changed

View File

@ -95,7 +95,7 @@ export interface Code {
}
export interface CodeDetails extends Code {
/** The original wasm bytes */
/** The original Wasm bytes */
readonly data: Uint8Array;
}

View File

@ -38,7 +38,6 @@
},
"dependencies": {
"@cosmjs/amino": "workspace:packages/amino",
"@cosmjs/cosmwasm-launchpad": "workspace:packages/cosmwasm-launchpad",
"@cosmjs/crypto": "workspace:packages/crypto",
"@cosmjs/encoding": "workspace:packages/encoding",
"@cosmjs/math": "workspace:packages/math",

View File

@ -0,0 +1,63 @@
import { isValidBuilder } from "./builder";
describe("builder", () => {
describe("isValidBuilder", () => {
// Valid cases
it("returns true for simple examples", () => {
expect(isValidBuilder("myorg/super-optimizer:0.1.2")).toEqual(true);
expect(isValidBuilder("myorg/super-optimizer:42")).toEqual(true);
});
it("supports images with multi level names", () => {
expect(isValidBuilder("myorg/department-x/office-y/technology-z/super-optimizer:0.1.2")).toEqual(true);
});
it("returns true for tags with lower and upper chars", () => {
expect(isValidBuilder("myorg/super-optimizer:0.1.2-alpha")).toEqual(true);
expect(isValidBuilder("myorg/super-optimizer:0.1.2-Alpha")).toEqual(true);
});
// Invalid cases
it("returns false for missing or empty tag", () => {
expect(isValidBuilder("myorg/super-optimizer")).toEqual(false);
expect(isValidBuilder("myorg/super-optimizer:")).toEqual(false);
});
it("returns false for name components starting or ending with a separator", () => {
expect(isValidBuilder(".myorg/super-optimizer:42")).toEqual(false);
expect(isValidBuilder("-myorg/super-optimizer:42")).toEqual(false);
expect(isValidBuilder("_myorg/super-optimizer:42")).toEqual(false);
expect(isValidBuilder("myorg./super-optimizer:42")).toEqual(false);
expect(isValidBuilder("myorg-/super-optimizer:42")).toEqual(false);
expect(isValidBuilder("myorg_/super-optimizer:42")).toEqual(false);
expect(isValidBuilder("myorg/.super-optimizer:42")).toEqual(false);
expect(isValidBuilder("myorg/-super-optimizer:42")).toEqual(false);
expect(isValidBuilder("myorg/_super-optimizer:42")).toEqual(false);
expect(isValidBuilder("myorg/super-optimizer.:42")).toEqual(false);
expect(isValidBuilder("myorg/super-optimizer-:42")).toEqual(false);
expect(isValidBuilder("myorg/super-optimizer_:42")).toEqual(false);
});
it("returns false for upper case character in name component", () => {
expect(isValidBuilder("mYorg/super-optimizer:42")).toEqual(false);
expect(isValidBuilder("myorg/super-Optimizer:42")).toEqual(false);
});
it("returns false for long images", () => {
expect(
isValidBuilder(
"myorgisnicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenicenice/super-optimizer:42",
),
).toEqual(false);
});
it("returns false for images with no organization", () => {
// Those are valid dockerhub images from https://hub.docker.com/_/ubuntu and https://hub.docker.com/_/rust
// but not valid in the context of CosmWasm Verify
expect(isValidBuilder("ubuntu:xenial-20200212")).toEqual(false);
expect(isValidBuilder("rust:1.40.0")).toEqual(false);
});
});
});

View File

@ -0,0 +1,20 @@
// A docker image regexp. We remove support for non-standard registries for simplicity.
// https://docs.docker.com/engine/reference/commandline/tag/#extended-description
//
// An image name is made up of slash-separated name components (optionally prefixed by a registry hostname).
// Name components may contain lowercase characters, digits and separators.
// A separator is defined as a period, one or two underscores, or one or more dashes. A name component may not start or end with a separator.
//
// A tag name must be valid ASCII and may contain lowercase and uppercase letters, digits, underscores, periods and dashes.
// A tag name may not start with a period or a dash and may contain a maximum of 128 characters.
const dockerImagePattern = new RegExp(
"^[a-z0-9][a-z0-9._-]*[a-z0-9](/[a-z0-9][a-z0-9._-]*[a-z0-9])+:[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$",
);
/** Max length in bytes/characters (regexp enforces all ASCII, even if that is not required by the standard) */
const builderMaxLength = 128;
export function isValidBuilder(builder: string): boolean {
if (builder.length > builderMaxLength) return false;
return !!builder.match(dockerImagePattern);
}

View File

@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { Code } from "@cosmjs/cosmwasm-launchpad";
import { sha256 } from "@cosmjs/crypto";
import { fromAscii, fromBase64, fromHex, toAscii } from "@cosmjs/encoding";
import { Int53 } from "@cosmjs/math";
@ -16,7 +15,7 @@ import { assert, sleep } from "@cosmjs/utils";
import { TxRaw } from "cosmjs-types/cosmos/tx/v1beta1/tx";
import { ReadonlyDate } from "readonly-date";
import { CosmWasmClient, PrivateCosmWasmClient } from "./cosmwasmclient";
import { Code, CosmWasmClient, PrivateCosmWasmClient } from "./cosmwasmclient";
import { SigningCosmWasmClient } from "./signingcosmwasmclient";
import {
alice,

View File

@ -1,11 +1,4 @@
/* eslint-disable @typescript-eslint/naming-convention */
import {
Code,
CodeDetails,
Contract,
ContractCodeHistoryEntry,
JsonObject,
} from "@cosmjs/cosmwasm-launchpad";
import { fromAscii, toHex } from "@cosmjs/encoding";
import { Uint53 } from "@cosmjs/math";
import {
@ -33,18 +26,56 @@ import { assert, sleep } from "@cosmjs/utils";
import { CodeInfoResponse } from "cosmjs-types/cosmwasm/wasm/v1beta1/query";
import { ContractCodeHistoryOperationType } from "cosmjs-types/cosmwasm/wasm/v1beta1/types";
import { setupWasmExtension, WasmExtension } from "./queries";
import { JsonObject, setupWasmExtension, WasmExtension } from "./queries";
// Those types can be copied over to allow them to evolve independently of @cosmjs/cosmwasm-launchpad.
// For now just re-export them such that they can be imported via @cosmjs/cosmwasm-stargate.
// Re-exports that belong to public CosmWasmClient interfaces
export {
Code, // returned by CosmWasmClient.getCode
CodeDetails, // returned by CosmWasmClient.getCodeDetails
Contract, // returned by CosmWasmClient.getContract
ContractCodeHistoryEntry, // returned by CosmWasmClient.getContractCodeHistory
JsonObject, // returned by CosmWasmClient.queryContractSmart
};
export interface Code {
readonly id: number;
/** Bech32 account address */
readonly creator: string;
/** Hex-encoded sha256 hash of the code stored here */
readonly checksum: string;
/**
* An URL to a .tar.gz archive of the source code of the contract, which can be used to reproducibly build the Wasm bytecode.
*
* @see https://github.com/CosmWasm/cosmwasm-verify
*/
readonly source?: string;
/**
* A docker image (including version) to reproducibly build the Wasm bytecode from the source code.
*
* @example ```cosmwasm/rust-optimizer:0.8.0```
* @see https://github.com/CosmWasm/cosmwasm-verify
*/
readonly builder?: string;
}
export interface CodeDetails extends Code {
/** The original Wasm bytes */
readonly data: Uint8Array;
}
export interface Contract {
readonly address: string;
readonly codeId: number;
/** Bech32 account address */
readonly creator: string;
/** Bech32-encoded admin address */
readonly admin: string | undefined;
readonly label: string;
}
export interface ContractCodeHistoryEntry {
/** The source of this history entry */
readonly operation: "Genesis" | "Init" | "Migrate";
readonly codeId: number;
readonly msg: Record<string, unknown>;
}
/** Use for testing only */
export interface PrivateCosmWasmClient {
readonly tmClient: Tendermint34Client | undefined;

View File

@ -1,4 +1,5 @@
export { cosmWasmTypes } from "./aminotypes";
export { isValidBuilder } from "./builder";
export {
Code,
CodeDetails,

View File

@ -1 +1 @@
export { setupWasmExtension, WasmExtension } from "./wasm";
export { setupWasmExtension, JsonObject, WasmExtension } from "./wasm";

View File

@ -1,5 +1,4 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { JsonObject } from "@cosmjs/cosmwasm-launchpad";
import { fromUtf8, toAscii } from "@cosmjs/encoding";
import { createPagination, createProtobufRpcClient, QueryClient } from "@cosmjs/stargate";
import {
@ -14,6 +13,14 @@ import {
} from "cosmjs-types/cosmwasm/wasm/v1beta1/query";
import Long from "long";
/**
* An object containing a parsed JSON document. The result of JSON.parse().
* This doesn't provide any type safety over `any` but expresses intent in the code.
*
* This type is returned by `queryContractSmart`.
*/
export type JsonObject = any;
export interface WasmExtension {
readonly wasm: {
readonly listCodeInfo: (paginationKey?: Uint8Array) => Promise<QueryCodesResponse>;

View File

@ -1,6 +1,5 @@
/* eslint-disable @typescript-eslint/naming-convention */
import { encodeSecp256k1Pubkey, makeSignDoc as makeSignDocAmino } from "@cosmjs/amino";
import { isValidBuilder } from "@cosmjs/cosmwasm-launchpad";
import { sha256 } from "@cosmjs/crypto";
import { fromBase64, toHex, toUtf8 } from "@cosmjs/encoding";
import { Int53, Uint53 } from "@cosmjs/math";
@ -47,6 +46,7 @@ import Long from "long";
import pako from "pako";
import { cosmWasmTypes } from "./aminotypes";
import { isValidBuilder } from "./builder";
import { CosmWasmClient } from "./cosmwasmclient";
import {
MsgClearAdminEncodeObject,
@ -57,9 +57,9 @@ import {
MsgUpdateAdminEncodeObject,
} from "./encodeobjects";
function prepareBuilder(builder: string | undefined): string {
if (builder === undefined) {
return ""; // normalization needed by backend
function prepareBuilder(builder: string | undefined): string | undefined {
if (!builder) {
return undefined;
} else {
if (!isValidBuilder(builder)) throw new Error("The builder (Docker Hub image with tag) is not valid");
return builder;

View File

@ -446,7 +446,6 @@ __metadata:
resolution: "@cosmjs/cosmwasm-stargate@workspace:packages/cosmwasm-stargate"
dependencies:
"@cosmjs/amino": "workspace:packages/amino"
"@cosmjs/cosmwasm-launchpad": "workspace:packages/cosmwasm-launchpad"
"@cosmjs/crypto": "workspace:packages/crypto"
"@cosmjs/encoding": "workspace:packages/encoding"
"@cosmjs/math": "workspace:packages/math"