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 ResourceType table with ResourceId table and corresponding checks #1557

Merged
merged 5 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
25 changes: 25 additions & 0 deletions .changeset/mean-seals-nail.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
"@latticexyz/world": patch
"@latticexyz/store": patch
---

The `ResourceType` table is removed.
It was previously used to store the resource type for each resource ID in a `World`. This is no longer necessary as the [resource type is now encoded in the resource ID](https://github.com/latticexyz/mud/pull/1544).

To still be able to determine whether a given resource ID exists, a `ResourceIds` table has been added.
The previous `ResourceType` table was part of `World` and missed tables that were registered directly via `StoreCore.registerTable` instead of via `World.registerTable` (e.g. when a table was registered as part of a root module).
This problem is solved by the new table `ResourceIds` being part of `Store`.

`StoreCore`'s `hasTable` function was removed in favor of using `ResourceIds.getExists(tableId)` directly.

```diff
- import { ResourceType } from "@latticexyz/world/src/tables/ResourceType.sol";
- import { StoreCore } from "@latticexyz/store/src/StoreCore.sol";
+ import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol";

- bool tableExists = StoreCore.hasTable(tableId);
+ bool tableExists = ResourceIds.getExists(tableId);

- bool systemExists = ResourceType.get(systemId) != Resource.NONE;
+ bool systemExists = ResourceIds.getExists(systemId);
```
88 changes: 44 additions & 44 deletions packages/store/gas-report.json
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@
"file": "test/KeyEncoding.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "register KeyEncoding table",
"gasUsed": 720470
"gasUsed": 720430
},
{
"file": "test/Mixed.t.sol",
Expand All @@ -363,7 +363,7 @@
"file": "test/Mixed.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "register Mixed table",
"gasUsed": 582295
"gasUsed": 582255
},
{
"file": "test/Mixed.t.sol",
Expand Down Expand Up @@ -651,145 +651,145 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testAccessEmptyData",
"name": "access non-existing record",
"gasUsed": 7142
"gasUsed": 7042
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testAccessEmptyData",
"name": "access static field of non-existing record",
"gasUsed": 1418
"gasUsed": 1318
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testAccessEmptyData",
"name": "access dynamic field of non-existing record",
"gasUsed": 2134
"gasUsed": 2034
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testAccessEmptyData",
"name": "access length of dynamic field of non-existing record",
"gasUsed": 1208
"gasUsed": 1108
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testAccessEmptyData",
"name": "access slice of dynamic field of non-existing record",
"gasUsed": 1584
"gasUsed": 1484
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testDeleteData",
"name": "delete record (complex data, 3 slots)",
"gasUsed": 6800
"gasUsed": 6700
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHasFieldLayout",
"name": "Check for existence of table (existent)",
"gasUsed": 1349
"gasUsed": 1249
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHasFieldLayout",
"name": "check for existence of table (non-existent)",
"gasUsed": 5349
"gasUsed": 3249
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHooks",
"name": "register subscriber",
"gasUsed": 58799
"gasUsed": 58696
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHooks",
"name": "set record on table with subscriber",
"gasUsed": 71368
"gasUsed": 71265
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHooks",
"name": "set static field on table with subscriber",
"gasUsed": 20846
"gasUsed": 20746
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHooks",
"name": "delete record on table with subscriber",
"gasUsed": 16836
"gasUsed": 16736
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHooksDynamicData",
"name": "register subscriber",
"gasUsed": 58799
"gasUsed": 58696
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHooksDynamicData",
"name": "set (dynamic) record on table with subscriber",
"gasUsed": 164486
"gasUsed": 164386
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHooksDynamicData",
"name": "set (dynamic) field on table with subscriber",
"gasUsed": 24613
"gasUsed": 24513
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHooksDynamicData",
"name": "delete (dynamic) record on table with subscriber",
"gasUsed": 17821
"gasUsed": 17721
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testPushToField",
"name": "push to field (1 slot, 1 uint32 item)",
"gasUsed": 10364
"gasUsed": 10264
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testPushToField",
"name": "push to field (2 slots, 10 uint32 items)",
"gasUsed": 33040
"gasUsed": 32940
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "StoreCore: register table",
"gasUsed": 644532
"gasUsed": 642392
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "StoreCore: get field layout (warm)",
"gasUsed": 1393
"gasUsed": 1293
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "StoreCore: get value schema (warm)",
"gasUsed": 1904
"gasUsed": 1804
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "StoreCore: get key schema (warm)",
"gasUsed": 2927
"gasUsed": 2827
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetDynamicData",
"name": "set complex record with dynamic data (4 slots)",
"gasUsed": 101940
"gasUsed": 101840
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetDynamicData",
"name": "get complex record with dynamic data (4 slots)",
"gasUsed": 4303
"gasUsed": 4203
},
{
"file": "test/StoreCoreGas.t.sol",
Expand All @@ -807,103 +807,103 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetDynamicDataLength",
"name": "set dynamic length of dynamic index 0",
"gasUsed": 22970
"gasUsed": 22870
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetDynamicDataLength",
"name": "set dynamic length of dynamic index 1",
"gasUsed": 1071
"gasUsed": 971
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetDynamicDataLength",
"name": "reduce dynamic length of dynamic index 0",
"gasUsed": 1061
"gasUsed": 961
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "set static field (1 slot)",
"gasUsed": 31701
"gasUsed": 31601
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "get static field (1 slot)",
"gasUsed": 1418
"gasUsed": 1318
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "set static field (overlap 2 slot)",
"gasUsed": 30341
"gasUsed": 30241
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "get static field (overlap 2 slot)",
"gasUsed": 1945
"gasUsed": 1845
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "set dynamic field (1 slot, first dynamic field)",
"gasUsed": 54066
"gasUsed": 53966
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "get dynamic field (1 slot, first dynamic field)",
"gasUsed": 2301
"gasUsed": 2201
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "set dynamic field (1 slot, second dynamic field)",
"gasUsed": 32292
"gasUsed": 32192
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "get dynamic field (1 slot, second dynamic field)",
"gasUsed": 2304
"gasUsed": 2204
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetStaticData",
"name": "set static record (1 slot)",
"gasUsed": 32248
"gasUsed": 32145
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetStaticData",
"name": "get static record (1 slot)",
"gasUsed": 1624
"gasUsed": 1524
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetStaticDataSpanningWords",
"name": "set static record (2 slots)",
"gasUsed": 54753
"gasUsed": 54650
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetStaticDataSpanningWords",
"name": "get static record (2 slots)",
"gasUsed": 1811
"gasUsed": 1711
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testUpdateInField",
"name": "update in field (1 slot, 1 uint32 item)",
"gasUsed": 9708
"gasUsed": 9608
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testUpdateInField",
"name": "push to field (2 slots, 6 uint64 items)",
"gasUsed": 10145
"gasUsed": 10045
},
{
"file": "test/StoreHook.t.sol",
Expand Down Expand Up @@ -1113,7 +1113,7 @@
"file": "test/Vector2.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "register Vector2 field layout",
"gasUsed": 443738
"gasUsed": 443698
},
{
"file": "test/Vector2.t.sol",
Expand Down
8 changes: 8 additions & 0 deletions packages/store/mud.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ export default mudConfig({
abiEncodedFieldNames: "bytes",
},
},
ResourceIds: {
keySchema: {
resourceId: "bytes32",
},
valueSchema: {
exists: "bool",
},
},
// The Hooks table is a generic table used by the `filterFromList` util in `Hook.sol`
Hooks: {
valueSchema: "bytes21[]",
Expand Down
1 change: 1 addition & 0 deletions packages/store/src/IStoreErrors.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ interface IStoreErrors {
// Errors include a stringified version of the tableId for easier debugging if cleartext tableIds are used
error StoreCore_TableAlreadyExists(ResourceId tableId, string tableIdString);
error StoreCore_TableNotFound(ResourceId tableId, string tableIdString);
Copy link
Member

@holic holic Sep 20, 2023

Choose a reason for hiding this comment

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

nice, we already had this pattern for table errors (ID + human readable string)

error StoreCore_InvalidResourceType(string resourceType);

error StoreCore_NotImplemented();
error StoreCore_NotDynamicField();
Expand Down
Loading