Skip to content

Commit

Permalink
feat(store,world): replace ResourceType table with ResourceId tab…
Browse files Browse the repository at this point in the history
…le and corresponding checks (#1557)

Co-authored-by: Kevin Ingersoll <kingersoll@gmail.com>
  • Loading branch information
alvrs and holic committed Sep 20, 2023
1 parent d73a4fc commit dec9af7
Show file tree
Hide file tree
Showing 26 changed files with 496 additions and 329 deletions.
25 changes: 25 additions & 0 deletions .changeset/mean-seals-nail.md
@@ -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);
```
3 changes: 2 additions & 1 deletion .prettierignore
@@ -1,4 +1,5 @@
dist
**/.next
.next
templates/phaser/packages/art
CODEOWNERS
out
76 changes: 38 additions & 38 deletions packages/store/gas-report.json
Expand Up @@ -351,7 +351,7 @@
"file": "test/KeyEncoding.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "register KeyEncoding table",
"gasUsed": 687862
"gasUsed": 720275
},
{
"file": "test/Mixed.t.sol",
Expand All @@ -363,19 +363,19 @@
"file": "test/Mixed.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "register Mixed table",
"gasUsed": 549680
"gasUsed": 582100
},
{
"file": "test/Mixed.t.sol",
"test": "testSetAndGet",
"name": "set record in Mixed",
"gasUsed": 103940
"gasUsed": 103942
},
{
"file": "test/Mixed.t.sol",
"test": "testSetAndGet",
"name": "get record from Mixed",
"gasUsed": 7023
"gasUsed": 7025
},
{
"file": "test/PackedCounter.t.sol",
Expand Down Expand Up @@ -627,31 +627,31 @@
"file": "test/StoreCoreDynamic.t.sol",
"test": "testPopFromSecondField",
"name": "pop from field (cold, 1 slot, 1 uint32 item)",
"gasUsed": 19429
"gasUsed": 19440
},
{
"file": "test/StoreCoreDynamic.t.sol",
"test": "testPopFromSecondField",
"name": "pop from field (warm, 1 slot, 1 uint32 item)",
"gasUsed": 13439
"gasUsed": 13450
},
{
"file": "test/StoreCoreDynamic.t.sol",
"test": "testPopFromThirdField",
"name": "pop from field (cold, 2 slots, 10 uint32 items)",
"gasUsed": 17197
"gasUsed": 17208
},
{
"file": "test/StoreCoreDynamic.t.sol",
"test": "testPopFromThirdField",
"name": "pop from field (warm, 2 slots, 10 uint32 items)",
"gasUsed": 13208
"gasUsed": 13219
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testAccessEmptyData",
"name": "access non-existing record",
"gasUsed": 7041
"gasUsed": 7042
},
{
"file": "test/StoreCoreGas.t.sol",
Expand All @@ -663,7 +663,7 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testAccessEmptyData",
"name": "access dynamic field of non-existing record",
"gasUsed": 2033
"gasUsed": 2034
},
{
"file": "test/StoreCoreGas.t.sol",
Expand All @@ -675,25 +675,25 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testAccessEmptyData",
"name": "access slice of dynamic field of non-existing record",
"gasUsed": 1483
"gasUsed": 1484
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testDeleteData",
"name": "delete record (complex data, 3 slots)",
"gasUsed": 6699
"gasUsed": 6700
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHasFieldLayout",
"name": "Check for existence of table (existent)",
"gasUsed": 1281
"gasUsed": 1249
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testHasFieldLayout",
"name": "check for existence of table (non-existent)",
"gasUsed": 3282
"gasUsed": 3249
},
{
"file": "test/StoreCoreGas.t.sol",
Expand Down Expand Up @@ -747,19 +747,19 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testPushToField",
"name": "push to field (1 slot, 1 uint32 item)",
"gasUsed": 10262
"gasUsed": 10264
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testPushToField",
"name": "push to field (2 slots, 10 uint32 items)",
"gasUsed": 32939
"gasUsed": 32940
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "StoreCore: register table",
"gasUsed": 609810
"gasUsed": 642237
},
{
"file": "test/StoreCoreGas.t.sol",
Expand All @@ -771,19 +771,19 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "StoreCore: get value schema (warm)",
"gasUsed": 1803
"gasUsed": 1804
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "StoreCore: get key schema (warm)",
"gasUsed": 2858
"gasUsed": 2827
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetDynamicData",
"name": "set complex record with dynamic data (4 slots)",
"gasUsed": 101839
"gasUsed": 101840
},
{
"file": "test/StoreCoreGas.t.sol",
Expand All @@ -801,7 +801,7 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetDynamicData",
"name": "compare: Set complex record with dynamic data using abi.encode",
"gasUsed": 267368
"gasUsed": 267369
},
{
"file": "test/StoreCoreGas.t.sol",
Expand All @@ -813,19 +813,19 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetDynamicDataLength",
"name": "set dynamic length of dynamic index 1",
"gasUsed": 970
"gasUsed": 971
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetDynamicDataLength",
"name": "reduce dynamic length of dynamic index 0",
"gasUsed": 960
"gasUsed": 961
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "set static field (1 slot)",
"gasUsed": 31600
"gasUsed": 31601
},
{
"file": "test/StoreCoreGas.t.sol",
Expand All @@ -837,19 +837,19 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "set static field (overlap 2 slot)",
"gasUsed": 30240
"gasUsed": 30241
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "get static field (overlap 2 slot)",
"gasUsed": 1844
"gasUsed": 1845
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "set dynamic field (1 slot, first dynamic field)",
"gasUsed": 53963
"gasUsed": 53966
},
{
"file": "test/StoreCoreGas.t.sol",
Expand All @@ -861,13 +861,13 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "set dynamic field (1 slot, second dynamic field)",
"gasUsed": 32190
"gasUsed": 32192
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetField",
"name": "get dynamic field (1 slot, second dynamic field)",
"gasUsed": 2203
"gasUsed": 2204
},
{
"file": "test/StoreCoreGas.t.sol",
Expand All @@ -885,25 +885,25 @@
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetStaticDataSpanningWords",
"name": "set static record (2 slots)",
"gasUsed": 54649
"gasUsed": 54650
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testSetAndGetStaticDataSpanningWords",
"name": "get static record (2 slots)",
"gasUsed": 1709
"gasUsed": 1711
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testUpdateInField",
"name": "update in field (1 slot, 1 uint32 item)",
"gasUsed": 9606
"gasUsed": 9608
},
{
"file": "test/StoreCoreGas.t.sol",
"test": "testUpdateInField",
"name": "push to field (2 slots, 6 uint64 items)",
"gasUsed": 10043
"gasUsed": 10045
},
{
"file": "test/StoreHook.t.sol",
Expand Down Expand Up @@ -945,7 +945,7 @@
"file": "test/tables/Callbacks.t.sol",
"test": "testSetAndGet",
"name": "Callbacks: set field",
"gasUsed": 57050
"gasUsed": 57052
},
{
"file": "test/tables/Callbacks.t.sol",
Expand All @@ -957,7 +957,7 @@
"file": "test/tables/Callbacks.t.sol",
"test": "testSetAndGet",
"name": "Callbacks: push 1 element",
"gasUsed": 33334
"gasUsed": 33337
},
{
"file": "test/tables/StoreHooks.t.sol",
Expand Down Expand Up @@ -987,7 +987,7 @@
"file": "test/tables/StoreHooks.t.sol",
"test": "testTable",
"name": "StoreHooks: pop 1 element (warm)",
"gasUsed": 10728
"gasUsed": 10739
},
{
"file": "test/tables/StoreHooks.t.sol",
Expand Down Expand Up @@ -1113,7 +1113,7 @@
"file": "test/Vector2.t.sol",
"test": "testRegisterAndGetFieldLayout",
"name": "register Vector2 field layout",
"gasUsed": 411103
"gasUsed": 443543
},
{
"file": "test/Vector2.t.sol",
Expand All @@ -1125,6 +1125,6 @@
"file": "test/Vector2.t.sol",
"test": "testSetAndGet",
"name": "get Vector2 record",
"gasUsed": 2513
"gasUsed": 2514
}
]
8 changes: 8 additions & 0 deletions packages/store/mud.config.ts
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
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);
error StoreCore_InvalidResourceType(string resourceType);

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

0 comments on commit dec9af7

Please sign in to comment.