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

feat: v2 - add store, world and schema-type, cli table code generation #422

Merged
merged 20 commits into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
9ed6f2a
feat(store): add foundation for v2 data model (#352)
alvrs Feb 7, 2023
e5d1195
ci: add v2 to github test action
alvrs Feb 7, 2023
3b58a1f
fix(store): emit store events before early return (#381)
alvrs Feb 8, 2023
217e817
refactor(store): optimize storage library (#386)
dk1a Feb 9, 2023
53b2b62
fix(store): emit MudStoreSetRecord event when registering a new schem…
alvrs Feb 9, 2023
4e04c00
Merge remote-tracking branch 'origin/main' into v2
holic Feb 13, 2023
3a3a18a
test(store): avoid fuzzy storage slot clash with test assertion failu…
dk1a Feb 13, 2023
3c7fb35
refactor(store): rename events (#398)
holic Feb 14, 2023
ede04c3
feat(store): replace Buffer with Slice and reorganize custom coders (…
dk1a Feb 15, 2023
25fc99f
feat(store): add missing schema types (#395)
dk1a Feb 17, 2023
a7adbbb
refactor(store): change tableId type from bytes32 to uint256 (#416)
alvrs Feb 17, 2023
7cce250
chore: merge main into v2 (#430)
alvrs Feb 22, 2023
b686e08
feat(store): add codegen for all types for tightcoder (#396)
dk1a Feb 22, 2023
32a56f7
feat(schema-type): create schema-type package (#429)
dk1a Feb 22, 2023
8998ae4
refactor(cli): refactor to esm (#417)
dk1a Feb 22, 2023
c4ea97b
feat(world): add World prototype (#405)
alvrs Feb 22, 2023
78c197d
feat(cli): add store config parser and basic schema generator (#402)
dk1a Feb 24, 2023
4777719
feat(cli): refactor tablegen and add more advanced features (#437)
dk1a Feb 28, 2023
7534096
chore: v2 polishes
alvrs Feb 28, 2023
5aa602d
Merge branch 'main' into v2
alvrs Feb 28, 2023
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
34 changes: 34 additions & 0 deletions .github/workflows/gasreport.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# .github/workflows/gasreport.yml
name: Gas report

on:
pull_request:
paths:
- packages/store/**
- packages/world/**

jobs:
gas-report:
runs-on: ubuntu-22.04
name: Generate gas report
steps:
- uses: actions/setup-node@v3
with:
node-version: 16

- name: git-checkout
uses: actions/checkout@v3

- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
with:
version: nightly

- name: Install dependencies
run: yarn install --network-concurrency 1

- name: Install local CLI
run: cd packages/cli && yarn build && npm link && cd ../..

- name: Verify that gas report is up to date
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: fix gas report action (right now it just passes even if the gas report is out of date)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run: yarn workspace @latticexyz/store run gasreport && yarn workspace @latticexyz/world run gasreport && if [ -n "$(git status --porcelain)" ]; then exit 0; fi
1 change: 1 addition & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
push:
branches:
- main
- v2
pull_request:
merge_group:

Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"ds-test/=node_modules/ds-test/src/",
"solecs/=node_modules/@latticexyz/solecs/src/",
"royalty-registry/=node_modules/@manifoldxzy/royalty-registry/contracts/",
"std-contracts/=node_modules/@latticexyz/std-contracts/src/"
"std-contracts/=node_modules/@latticexyz/std-contracts/src/",
"@latticexyz/=node_modules/@latticexyz/"
]
}
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@
"workspaces": {
"packages": [
"packages/utils",
"packages/schema-type",
"packages/solecs",
"packages/store",
"packages/world",
"packages/cli",
"packages/recs",
"packages/react",
Expand Down Expand Up @@ -44,7 +47,7 @@
"retypeapp": "^2.4.0",
"rimraf": "^3.0.2",
"run-pty": "^3.0.0",
"typescript": ">=3.0.0"
"typescript": "^4.9.5"
},
"config": {
"commitizen": {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/modules.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
declare module "netlify";
declare module "inquirer-prompt-suggest";
declare module "prettier-plugin-solidity";
declare module "long";
46 changes: 19 additions & 27 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
"name": "@latticexyz/cli",
"version": "1.39.0",
"description": "Command line interface for mud",
"main": "src/index.ts",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"type": "module",
"license": "MIT",
"bin": {
"mud": "./dist/index.js"
"mud": "./dist/mud.js"
},
"repository": {
"type": "git",
Expand All @@ -14,64 +16,54 @@
},
"scripts": {
"prepare": "yarn build && chmod u+x git-install.sh",
"build": "rimraf dist && esbuild ./src/index.ts ./src/commands/* --bundle --platform=node --outdir=dist --external:fsevents && chmod u+x dist/index.js",
"lint": "eslint . --ext .ts",
"dev": "tsup --watch",
"build": "tsup",
"link": "yarn link",
"test": "tsc && echo 'todo: add tests'",
"test": "vitest typecheck --run && echo 'todo: add tests'",
"git:install": "bash git-install.sh",
"release": "npm publish || echo 'version already published'"
},
"devDependencies": {
"@types/clear": "^0.1.2",
"@types/ejs": "^3.1.1",
"@types/figlet": "^1.5.4",
"@types/glob": "^7.2.0",
"@types/inquirer": "^8.2.1",
"@types/node": "^17.0.34",
"@types/openurl": "^1.0.0",
"@types/yargs": "^17.0.10",
"esbuild": "^0.15.16",
"nodemon": "^2.0.16",
"pkg": "^5.7.0",
"rimraf": "^3.0.2",
"ts-node": "^10.7.0",
"typescript": "^4.6.4"
"tsup": "^6.6.3",
"vitest": "^0.29.1"
},
"dependencies": {
"@improbable-eng/grpc-web": "^0.15.0",
"@improbable-eng/grpc-web-node-http-transport": "^0.15.0",
"@latticexyz/schema-type": "^1.34.0",
"@latticexyz/services": "^1.39.0",
"@latticexyz/solecs": "^1.39.0",
"@latticexyz/std-contracts": "^1.39.0",
"@latticexyz/utils": "^1.39.0",
"@typechain/ethers-v5": "^10.1.1",
"chalk": "^5.0.1",
"chokidar": "^3.5.3",
"clear": "^0.1.0",
"commander": "^9.2.0",
"ds-test": "https://github.com/dapphub/ds-test.git#c9ce3f25bde29fc5eb9901842bf02850dfd2d084",
"ejs": "^3.1.8",
"esm": "^3.2.25",
"ethers": "^5.7.2",
"execa": "^6.1.0",
"figlet": "^1.5.2",
"find-up": "^6.3.0",
"forge-std": "https://github.com/foundry-rs/forge-std.git#b4f121555729b3afb3c5ffccb62ff4b6e2818fd3",
"glob": "^8.0.3",
"inquirer": "^8.2.4",
"inquirer-prompt-suggest": "^0.1.0",
"listr2": "^4.0.5",
"netlify": "^11.0.1",
"nice-grpc-web": "^2.0.1",
"node-fetch": "^3.2.6",
"openurl": "^1.1.1",
"path": "^0.12.7",
"prettier": "^2.8.4",
"prettier-plugin-solidity": "^1.1.2",
"solmate": "https://github.com/Rari-Capital/solmate.git#9cf1428245074e39090dceacb0c28b1f684f584c",
"table": "^6.8.1",
"ts-node": "^10.9.1",
"typechain": "^8.1.1",
"uuid": "^8.3.2",
"yargs": "^17.5.1"
},
"pkg": {
"scripts": "build/**/*.js"
"typescript": "^4.9.5",
"yargs": "^17.7.1",
"zod": "^3.20.6",
"zod-validation-error": "^0.3.2"
},
"gitHead": "218f56893d268b0c5157a3e4c603b859e287a343"
}
76 changes: 41 additions & 35 deletions packages/cli/src/commands/bulkupload.ts
Original file line number Diff line number Diff line change
@@ -1,44 +1,50 @@
import { Arguments, CommandBuilder } from "yargs";
import { execa } from "execa";
import path from "path";
import type { CommandModule } from "yargs";

const importExeca = eval('import("execa")') as Promise<typeof import("execa")>;
const contractsDirectory = new URL("../src/contracts", import.meta.url).pathname;

type Options = {
statePath: string;
worldAddress: string;
rpc: string;
};

export const command = "bulkupload";
export const desc = "Uploads the provided ECS state to the provided World";

export const builder: CommandBuilder<Options, Options> = (yargs) =>
yargs.options({
statePath: { type: "string", demandOption: true, desc: "Path to the ECS state to upload" },
worldAddress: { type: "string", demandOption: true, desc: "Contract address of the World to upload to" },
rpc: { type: "string", demandOption: true, desc: "JSON RPC endpoint" },
});

export const handler = async (argv: Arguments<Options>): Promise<void> => {
const { execa } = await importExeca;
const { statePath, worldAddress, rpc } = argv;
console.log("Uploading state at ", statePath, "to", worldAddress, "on", rpc);
const url = __dirname + "/../../src/contracts/BulkUpload.sol";
console.log("Using BulkUpload script from", url);

try {
await execa("forge", [
"script",
"--sig",
'"run(string, address)"',
"--rpc-url",
rpc,
`${url}:BulkUpload`,
statePath,
worldAddress,
]);
} catch (e) {
console.error(e);
}

process.exit(0);
const commandModule: CommandModule<Options, Options> = {
command: "bulkupload",

describe: "Uploads the provided ECS state to the provided World",

builder(yargs) {
return yargs.options({
statePath: { type: "string", demandOption: true, desc: "Path to the ECS state to upload" },
worldAddress: { type: "string", demandOption: true, desc: "Contract address of the World to upload to" },
rpc: { type: "string", demandOption: true, desc: "JSON RPC endpoint" },
});
},

async handler({ statePath, worldAddress, rpc }) {
console.log("Uploading state at ", statePath, "to", worldAddress, "on", rpc);
const url = path.join(contractsDirectory, "BulkUpload.sol");
console.log("Using BulkUpload script from", url);

try {
await execa("forge", [
"script",
"--sig",
'"run(string, address)"',
"--rpc-url",
rpc,
`${url}:BulkUpload`,
statePath,
worldAddress,
]);
} catch (e) {
console.error(e);
}

process.exit(0);
},
};

export default commandModule;
98 changes: 51 additions & 47 deletions packages/cli/src/commands/call-system.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,70 @@
import { defaultAbiCoder as abi } from "ethers/lib/utils";
import { defaultAbiCoder as abi } from "ethers/lib/utils.js";
import path from "path";
import { Arguments, CommandBuilder } from "yargs";
import { execLog } from "../utils";
import { getTestDirectory } from "../utils/forgeConfig";
import type { CommandModule } from "yargs";
import { execLog } from "../utils/index.js";
import { getTestDirectory } from "../utils/forgeConfig.js";

type Options = {
rpc?: string;
caller?: string;
world: string;
systemId?: string;
systemAddress?: string;
argTypes?: any[];
args?: any[];
argTypes?: string[];
args?: (string | number)[];
calldata?: string;
broadcast?: boolean;
callerPrivateKey?: string;
debug?: boolean;
};

export const command = "call-system";
export const desc = "Execute a mud system";
const commandModule: CommandModule<Options, Options> = {
command: "call-system",

export const builder: CommandBuilder<Options, Options> = (yargs) =>
yargs.options({
rpc: { type: "string", description: "json rpc endpoint, defaults to http://localhost:8545" },
caller: { type: "string", description: "caller address" },
world: { type: "string", required: true, description: "world contract address" },
systemId: { type: "string", description: "system id preimage (eg mud.system.Move)" },
systemAddress: { type: "string", description: "system address (alternative to system id)" },
argTypes: { type: "array", description: "system argument types for abi encoding" },
args: { type: "array", description: "system arguments" },
calldata: { type: "string", description: "abi encoded system arguments (instead of args/argTypes)" },
broadcast: { type: "boolean", description: "send txs to the chain" },
callerPrivateKey: {
type: "string",
description: "must be set if broadcast is set, must correspond to caller address",
},
debug: { type: "boolean", description: "open debugger" },
});
describe: "Execute a mud system",

export const handler = async (argv: Arguments<Options>): Promise<void> => {
const { rpc, caller, world, systemId, argTypes, args, calldata, broadcast, callerPrivateKey, debug } = argv;
const encodedArgs = calldata ?? (argTypes && args && abi.encode(argTypes, args)) ?? "";
const testDir = await getTestDirectory();
builder(yargs) {
return yargs.options({
rpc: { type: "string", description: "json rpc endpoint, defaults to http://localhost:8545" },
caller: { type: "string", description: "caller address" },
world: { type: "string", required: true, description: "world contract address" },
systemId: { type: "string", description: "system id preimage (eg mud.system.Move)" },
systemAddress: { type: "string", description: "system address (alternative to system id)" },
argTypes: { type: "array", string: true, description: "system argument types for abi encoding" },
args: { type: "array", description: "system arguments" },
calldata: { type: "string", description: "abi encoded system arguments (instead of args/argTypes)" },
broadcast: { type: "boolean", description: "send txs to the chain" },
callerPrivateKey: {
type: "string",
description: "must be set if broadcast is set, must correspond to caller address",
},
debug: { type: "boolean", description: "open debugger" },
});
},

await execLog("forge", [
"script",
"--fork-url",
rpc ?? "http://localhost:8545", // default anvil rpc
"--sig",
"debug(address,address,string,bytes,bool)",
path.join(testDir, "utils/Debug.sol"), // the cli expects the Debug.sol file at this path
caller ?? "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", // default anvil deployer
world,
systemId || "",
encodedArgs,
broadcast ? "true" : "false",
"-vvvvv",
broadcast ? "--broadcast" : "",
callerPrivateKey ? `--private-key ${callerPrivateKey}` : "",
debug ? "--debug" : "",
]);
async handler({ rpc, caller, world, systemId, argTypes, args, calldata, broadcast, callerPrivateKey, debug }) {
const encodedArgs = calldata ?? (argTypes && args && abi.encode(argTypes, args)) ?? "";
const testDir = await getTestDirectory();
await execLog("forge", [
"script",
"--fork-url",
rpc ?? "http://localhost:8545", // default anvil rpc
"--sig",
"debug(address,address,string,bytes,bool)",
path.join(testDir, "utils/Debug.sol"), // the cli expects the Debug.sol file at this path
caller ?? "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266", // default anvil deployer
world,
systemId || "",
encodedArgs,
broadcast ? "true" : "false",
"-vvvvv",
broadcast ? "--broadcast" : "",
callerPrivateKey ? `--private-key ${callerPrivateKey}` : "",
debug ? "--debug" : "",
]);

process.exit(0);
process.exit(0);
},
};

export default commandModule;
Loading