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(store,world): replace ResourceSelector with ResourceId and WorldResourceId #1544

Merged
merged 48 commits into from
Sep 21, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
436f814
feat(store,world): add ResourceType, ResourceId
alvrs Sep 19, 2023
ead0f46
create ResourceId user type
alvrs Sep 19, 2023
6e478cd
refactor(store): use ResourceId instead of bytes32
alvrs Sep 19, 2023
b26630a
intermediate commit just in case
alvrs Sep 19, 2023
bbf982c
refactor world to use ResourceId instead of bytes32
alvrs Sep 19, 2023
c8421f0
rebuild artifacts
alvrs Sep 19, 2023
9d6e28a
gas report
alvrs Sep 19, 2023
2f80cd7
self-review
alvrs Sep 19, 2023
4bc95a2
self-review
alvrs Sep 19, 2023
896a275
Create stale-seahorses-pay.md
alvrs Sep 19, 2023
9eaf761
improve storeEventsAbi test for accuracy and clarity
holic Sep 20, 2023
9ad7956
fix missing indexed arg
holic Sep 20, 2023
2ce2905
table ID -> resource ID
holic Sep 20, 2023
8ed3a75
refactor resource ID utils
holic Sep 20, 2023
8b794df
add world resource types
holic Sep 20, 2023
b5efe9f
migrate most things
holic Sep 20, 2023
fd87f7b
fix logToTable test
holic Sep 20, 2023
010e08e
kick ci
holic Sep 20, 2023
d96262c
Merge branch 'main' into alvrs/resourcetype
alvrs Sep 20, 2023
b964236
replace hasOwn usage for now
holic Sep 20, 2023
4b92f09
prettier
alvrs Sep 20, 2023
437002f
rename config constants from SELECTOR to NAME
alvrs Sep 20, 2023
1c1d774
move tableId back to memory in tests to make gas reports comparable
alvrs Sep 20, 2023
711cb00
Update .changeset/stale-seahorses-pay.md
alvrs Sep 20, 2023
6fa3e89
Update .changeset/stale-seahorses-pay.md
alvrs Sep 20, 2023
f317806
Update .changeset/stale-seahorses-pay.md
alvrs Sep 20, 2023
64664af
Update packages/world/src/interfaces/IModule.sol
alvrs Sep 20, 2023
85590fa
rename errors
alvrs Sep 20, 2023
3509850
fix braces
alvrs Sep 20, 2023
43ad722
Update packages/world/src/modules/keyswithvalue/constants.sol
alvrs Sep 20, 2023
c0e39f8
Update packages/world/src/modules/keyswithvalue/getTargetTableId.sol
alvrs Sep 20, 2023
25ea104
Update packages/world/src/modules/keyswithvalue/getTargetTableId.sol
alvrs Sep 20, 2023
202c042
run prettier
alvrs Sep 20, 2023
01e6a64
update gas-report
alvrs Sep 20, 2023
c7030fa
feat(world): use `ResourceId namespaceId` for all methods acting on t…
alvrs Sep 20, 2023
4e2dcd5
remove isType
alvrs Sep 20, 2023
dccf072
feat: use named args for WorldResourceIdLib and ResourceIdLib
alvrs Sep 21, 2023
4cfadea
reorder arguments in WorldResourceIdLib and ResourceIdLib
alvrs Sep 21, 2023
cd90e05
change encoding order
alvrs Sep 21, 2023
33b4f89
update parser
alvrs Sep 21, 2023
53ad81b
rebuild artifacts
alvrs Sep 21, 2023
8db70ac
Apply suggestions from code review
alvrs Sep 21, 2023
41d3e12
Apply suggestions from code review
alvrs Sep 21, 2023
ee4f8c7
update test data
alvrs Sep 21, 2023
3b76172
Merge branch 'main' into alvrs/resourcetype
alvrs Sep 21, 2023
e4d97bc
Apply suggestions from code review
alvrs Sep 21, 2023
18aac90
update test data
alvrs Sep 21, 2023
de9124e
run prettier
alvrs Sep 21, 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
69 changes: 69 additions & 0 deletions .changeset/stale-seahorses-pay.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
"@latticexyz/cli": major
"@latticexyz/common": major
"@latticexyz/config": major
"@latticexyz/store": major
---
- `ResourceSelector` is replaced with `ResourceId`, `ResourceIdLib`, `ResourceIdInstance`, `WorldResourceIdLib` and `WorldResourceIdInstance`.
alvrs marked this conversation as resolved.
Show resolved Hide resolved

Previously a "resource selector" was a `bytes32` value with the first 16 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name.
Now a "resource ID" is a `bytes32` value with the first 14 bytes reserved for the resource's namespace, the next 16 bytes reserved for the resource's name, and the last 2 bytes reserved for the resource type.
alvrs marked this conversation as resolved.
Show resolved Hide resolved

Previously `ResouceSelector` was a library and the resource selector type was a plain `bytes32`.
Now `ResourceId` is a user type, and the functionality is implemented in the `ResourceIdInstance` (for type) and `WorldResourceIdInstance` (for namespace and name) libraries.
We split the logic into two libraries, because `Store` also uses `ResourceId` now and needs awareness of resource types, but not of namespaces/names.
alvrs marked this conversation as resolved.
Show resolved Hide resolved

```diff
- import { ResourceSelector } from "@latticexyz/world/src/ResourceSelector.sol";
+ import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol";
+ import { WorldResourceIdLib, WorldResourceIdInstance } from "@latticexyz/world/src/WorldResourceId.sol";
+ import { RESOURCE_SYSTEM } from "@latticexyz/world/src/worldResourceTypes.sol";

- bytes32 systemId = ResourceSelector.from("namespace", "name");
+ ResourceId systemId = WorldResourceIdLib.encode("namespace", "name", RESOURCE_SYSTEM);
alvrs marked this conversation as resolved.
Show resolved Hide resolved

- using ResourceSelector for bytes32;
+ using WorldResourceIdInstance for ResourceId;
+ using ResourceIdInstance for ResourceId;

systemId.getName();
systemId.getNamespace();
+ systemId.getType();

```

- All `Store` and `World` methods now use the `ResourceId` type for `tableId`, `systemId`, `moduleId` and `namespaceId`.
All mentions of `resourceSelector` were renamed to `resourceId` or the more specific type (e.g. `tableId`, `systemId`)

```diff
import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";

IStore {
function setRecord(
- bytes32 tableId,
+ ResourceId tableId,
bytes32[] calldata keyTuple,
bytes calldata staticData,
PackedCounter encodedLengths,
bytes calldata dynamicData,
FieldLayout fieldLayout
) external;

// Same for all other methods
}
```

```diff
import { ResourceId } from "@latticexyz/store/src/ResourceId.sol";

IBaseWorld {
function callFrom(
address delegator,
- bytes32 resourceSelector,
+ ResourceId systemId,
bytes memory callData
) external payable returns (bytes memory);

// Same for all other methods
}
```
Copy link
Member

Choose a reason for hiding this comment

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

the whitespace alignment on these two diffs looks weird

Copy link
Member

Choose a reason for hiding this comment

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

ugh gihub messed up my attempt at suggesting a chance, but I think for diffs you want a "gutter" where the + and - live

so basically everything in the code block should indent one level then dedent the +- to be at the left edge
(see your diff above)

Copy link
Member Author

Choose a reason for hiding this comment

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

oof yes that's what i did, i think prettier keeps messing this up again

8 changes: 6 additions & 2 deletions e2e/packages/contracts/src/codegen/tables/Multi.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions e2e/packages/contracts/src/codegen/tables/Number.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions e2e/packages/contracts/src/codegen/tables/NumberList.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions e2e/packages/contracts/src/codegen/tables/Vector.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 5 additions & 11 deletions examples/minimal/packages/contracts/script/PostDeploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ pragma solidity >=0.8.0;

import { Script } from "forge-std/Script.sol";
import { console } from "forge-std/console.sol";
import { ResourceSelector } from "@latticexyz/world/src/ResourceSelector.sol";
import { ResourceId, WorldResourceIdLib } from "@latticexyz/world/src/WorldResourceId.sol";
import { RESOURCE_SYSTEM } from "@latticexyz/world/src/worldResourceTypes.sol";
import { IWorld } from "../src/codegen/world/IWorld.sol";

import { MessageTable, MessageTableTableId } from "../src/codegen/index.sol";
Expand All @@ -19,16 +20,9 @@ contract PostDeploy is Script {

// Manually deploy a system with another namespace
ChatNamespacedSystem chatNamespacedSystem = new ChatNamespacedSystem();
IWorld(worldAddress).registerSystem(
ResourceSelector.from("namespace", "ChatNamespaced"),
chatNamespacedSystem,
true
);
IWorld(worldAddress).registerFunctionSelector(
ResourceSelector.from("namespace", "ChatNamespaced"),
"sendMessage",
"(string)"
);
ResourceId systemId = WorldResourceIdLib.encode("namespace", "ChatNamespaced", RESOURCE_SYSTEM);
IWorld(worldAddress).registerSystem(systemId, chatNamespacedSystem, true);
IWorld(worldAddress).registerFunctionSelector(systemId, "sendMessage", "(string)");
// Grant this system access to MessageTable
IWorld(worldAddress).grantAccess(MessageTableTableId, address(chatNamespacedSystem));

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions packages/cli/contracts/src/codegen/tables/Dynamics1.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions packages/cli/contracts/src/codegen/tables/Dynamics2.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions packages/cli/contracts/src/codegen/tables/Ephemeral.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions packages/cli/contracts/src/codegen/tables/Singleton.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions packages/cli/contracts/src/codegen/tables/Statics.sol

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions packages/common/src/codegen/render-solidity/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function renderCommonData({
} {
// static resource means static tableId as well, and no tableId arguments
const _tableId = staticResourceData ? "" : "_tableId";
const _typedTableId = staticResourceData ? "" : "bytes32 _tableId";
const _typedTableId = staticResourceData ? "" : "ResourceId _tableId";

const _keyArgs = renderArguments(keyTuple.map(({ name }) => name));
const _typedKeyArgs = renderArguments(keyTuple.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`));
Expand Down Expand Up @@ -150,11 +150,11 @@ export function renderTableId(staticResourceData: StaticResourceData): {
hardcodedTableId: string;
tableIdDefinition: string;
} {
const hardcodedTableId = `bytes32(abi.encodePacked(bytes16("${staticResourceData.namespace}"), bytes16("${staticResourceData.name}")))`;
const hardcodedTableId = `ResourceId.wrap(bytes32(abi.encodePacked(bytes14("${staticResourceData.namespace}"), bytes16("${staticResourceData.name}"), RESOURCE_TABLE)))`;
alvrs marked this conversation as resolved.
Show resolved Hide resolved

const tableIdDefinition = `
bytes32 constant _tableId = ${hardcodedTableId};
bytes32 constant ${staticResourceData.tableIdName} = _tableId;
ResourceId constant _tableId = ${hardcodedTableId};
ResourceId constant ${staticResourceData.tableIdName} = _tableId;
`;
return {
hardcodedTableId,
Expand Down
6 changes: 5 additions & 1 deletion packages/config/src/library/commonSchemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
validateSingleLevelRoute,
validateUncapitalizedName,
validateSelector,
validateNamespace,
} from "./validation";

/** Capitalized names of objects, like tables and systems */
Expand All @@ -30,5 +31,8 @@ export const zBaseRoute = z.string().superRefine(validateBaseRoute);
/** A valid Ethereum address */
export const zEthereumAddress = z.string().superRefine(validateEthereumAddress);

/** A selector for namespace/file/resource */
/** A selector for file/resource */
export const zSelector = z.string().superRefine(validateSelector);

/** A namespace */
export const zNamespace = z.string().superRefine(validateNamespace);
16 changes: 16 additions & 0 deletions packages/config/src/library/validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { utils } from "ethers";
import { ZodIssueCode, RefinementCtx } from "zod";

export const STORE_SELECTOR_MAX_LENGTH = 16;
holic marked this conversation as resolved.
Show resolved Hide resolved
export const STORE_NAMESPACE_MAX_LENGTH = 14;

export function validateName(name: string, ctx: RefinementCtx) {
if (!/^\w+$/.test(name)) {
Expand Down Expand Up @@ -139,6 +140,21 @@ export function getDuplicates<T>(array: T[]) {
return [...duplicates];
}

export function validateNamespace(name: string, ctx: RefinementCtx) {
if (name.length > STORE_NAMESPACE_MAX_LENGTH) {
ctx.addIssue({
code: ZodIssueCode.custom,
message: `Namespace must be <= ${STORE_NAMESPACE_MAX_LENGTH} characters`,
});
}
if (!/^\w*$/.test(name)) {
ctx.addIssue({
code: ZodIssueCode.custom,
message: `Selector must contain only alphanumeric & underscore characters`,
});
}
}

export function validateSelector(name: string, ctx: RefinementCtx) {
if (name.length > STORE_SELECTOR_MAX_LENGTH) {
ctx.addIssue({
Expand Down
Loading