From b18d49171bf1750da9d659ac71a6152592e57193 Mon Sep 17 00:00:00 2001 From: Ori Pomerantz Date: Thu, 21 Sep 2023 09:59:45 -0500 Subject: [PATCH 1/4] docs: explain the key schema is restricted to static types (#1562) --- docs/pages/tutorials/minimal/add-table.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/pages/tutorials/minimal/add-table.mdx b/docs/pages/tutorials/minimal/add-table.mdx index 800f9b0267..404804ae06 100644 --- a/docs/pages/tutorials/minimal/add-table.mdx +++ b/docs/pages/tutorials/minimal/add-table.mdx @@ -48,6 +48,8 @@ A MUD table has two schemas: - `valueSchema`, the value in the entry Each schema is represented as a structure with field names as keys, and the appropriate [Solidity data types](https://docs.soliditylang.org/en/latest/types.html) as their values. +Note that the data types in the key schema are limited to those that are fixed length such at `bytes`. +You cannot use strings, arrays, etc. In this case, the counter value is represented as a 32 bit unsigned integer, because that is what `Counter` uses. Block numbers and timestamps can be values up to `uint256`, so we'll use this type for these fields. From 5e723b90e6b18bc70d357ff4b0a1b217611236ae Mon Sep 17 00:00:00 2001 From: alvarius Date: Thu, 21 Sep 2023 17:02:08 +0100 Subject: [PATCH 2/4] feat(store,world): replace `ResourceSelector` with `ResourceId` and `WorldResourceId` (#1544) Co-authored-by: Kevin Ingersoll Co-authored-by: dk1a --- .changeset/mean-seals-nail.md | 25 + .changeset/real-students-exercise.md | 25 + .changeset/stale-seahorses-pay.md | 70 ++ .prettierignore | 3 +- .../contracts/src/codegen/tables/Multi.sol | 8 +- .../contracts/src/codegen/tables/Number.sol | 8 +- .../src/codegen/tables/NumberList.sol | 8 +- .../contracts/src/codegen/tables/Vector.sol | 8 +- .../sync-test/data/setContractData.ts | 4 +- .../contracts/script/PostDeploy.s.sol | 20 +- .../src/codegen/tables/CounterTable.sol | 8 +- .../src/codegen/tables/Inventory.sol | 8 +- .../src/codegen/tables/MessageTable.sol | 8 +- .../src/codegen/tables/Dynamics1.sol | 8 +- .../src/codegen/tables/Dynamics2.sol | 8 +- .../src/codegen/tables/Ephemeral.sol | 8 +- .../src/codegen/tables/Singleton.sol | 8 +- .../contracts/src/codegen/tables/Statics.sol | 8 +- packages/cli/src/commands/trace.ts | 10 +- .../utils/systems/getGrantAccessCallData.ts | 4 +- .../getRegisterFunctionSelectorsCallData.ts | 6 +- .../systems/getRegisterSystemCallData.ts | 4 +- .../utils/tables/getRegisterTableCallData.ts | 5 +- .../src/codegen/render-solidity/common.ts | 8 +- packages/common/src/common.ts | 7 + packages/common/src/hexToResourceId.test.ts | 11 + packages/common/src/hexToResourceId.ts | 30 + packages/common/src/hexToTableId.test.ts | 10 - packages/common/src/hexToTableId.ts | 7 - packages/common/src/index.ts | 6 +- packages/common/src/resourceIdToHex.test.ts | 69 ++ packages/common/src/resourceIdToHex.ts | 23 + packages/common/src/resourceTypes.ts | 3 + packages/common/src/tableIdToHex.test.ts | 24 - packages/common/src/tableIdToHex.ts | 9 - packages/common/src/type-utils/common.ts | 5 + packages/config/src/library/commonSchemas.ts | 10 +- packages/config/src/library/validation.ts | 9 +- .../dev-tools/src/actions/WriteSummary.tsx | 4 +- packages/dev-tools/src/events/LogsTable.tsx | 4 +- packages/store-sync/src/common.ts | 8 +- packages/store-sync/src/logToTable.test.ts | 6 +- packages/store-sync/src/logToTable.ts | 4 +- .../src/postgres/buildInternalTables.ts | 4 +- .../store-sync/src/postgres/getTableKey.ts | 4 +- packages/store-sync/src/postgres/getTables.ts | 11 +- .../src/postgres/postgresStorage.test.ts | 7 +- .../src/postgres/postgresStorage.ts | 21 +- .../src/recs/configToRecsComponents.ts | 9 +- .../store-sync/src/recs/recsStorage.test.ts | 2 +- packages/store-sync/src/recs/recsStorage.ts | 4 +- packages/store-sync/src/sqlite/columnTypes.ts | 12 +- packages/store-sync/src/sqlite/getTables.ts | 15 +- .../store-sync/src/sqlite/internalTables.ts | 4 +- .../src/sqlite/sqliteStorage.test.ts | 6 +- .../store-sync/src/sqlite/sqliteStorage.ts | 21 +- packages/store/gas-report.json | 144 ++-- packages/store/mud.config.ts | 8 + packages/store/src/Hook.sol | 11 +- packages/store/src/IStore.sol | 53 +- packages/store/src/IStoreErrors.sol | 7 +- packages/store/src/IStoreHook.sol | 17 +- packages/store/src/ResourceId.sol | 22 + packages/store/src/StoreCore.sol | 125 +-- packages/store/src/StoreHook.sol | 17 +- packages/store/src/StoreRead.sol | 19 +- packages/store/src/StoreSwitch.sol | 43 +- packages/store/src/codegen/index.sol | 1 + .../store/src/codegen/tables/Callbacks.sol | 8 +- packages/store/src/codegen/tables/Hooks.sol | 103 +-- .../store/src/codegen/tables/KeyEncoding.sol | 8 +- packages/store/src/codegen/tables/Mixed.sol | 8 +- .../store/src/codegen/tables/ResourceIds.sol | 235 ++++++ .../store/src/codegen/tables/StoreHooks.sol | 8 +- packages/store/src/codegen/tables/Tables.sol | 8 +- packages/store/src/codegen/tables/Vector2.sol | 8 +- packages/store/src/storeResourceTypes.sol | 5 + packages/store/test/EchoSubscriber.sol | 21 +- packages/store/test/MirrorSubscriber.sol | 34 +- packages/store/test/ResourceId.t.sol | 35 + packages/store/test/RevertSubscriber.sol | 17 +- packages/store/test/StoreCore.t.sol | 146 +++- packages/store/test/StoreCoreDynamic.t.sol | 6 +- packages/store/test/StoreCoreGas.t.sol | 46 +- packages/store/test/StoreHook.t.sol | 10 +- packages/store/test/StoreMock.sol | 25 +- .../test/setDynamicDataLengthAtIndex.sol | 3 +- packages/store/ts/codegen/renderTable.ts | 2 + packages/store/ts/config/storeConfig.ts | 11 +- packages/store/ts/storeEventsAbi.test.ts | 39 +- packages/world/gas-report.json | 150 ++-- packages/world/mud.config.ts | 29 +- packages/world/src/AccessControl.sol | 24 +- packages/world/src/Delegation.sol | 7 +- packages/world/src/ResourceSelector.sol | 66 -- packages/world/src/SystemCall.sol | 41 +- packages/world/src/Utils.sol | 8 +- packages/world/src/World.sol | 65 +- packages/world/src/WorldResourceId.sol | 95 +++ packages/world/src/common.sol | 10 - packages/world/src/constants.sol | 17 +- packages/world/src/factories/WorldFactory.sol | 4 +- packages/world/src/index.sol | 1 - .../interfaces/IAccessManagementSystem.sol | 8 +- .../src/interfaces/IBalanceTransferSystem.sol | 6 +- .../src/interfaces/IDelegationControl.sol | 3 +- packages/world/src/interfaces/IModule.sol | 1 - packages/world/src/interfaces/ISystemHook.sol | 5 +- .../world/src/interfaces/IWorldErrors.sol | 9 +- .../world/src/interfaces/IWorldKernel.sol | 13 +- .../interfaces/IWorldRegistrationSystem.sol | 15 +- .../world/src/modules/core/CoreModule.sol | 27 +- .../AccessManagementSystem.sol | 28 +- .../implementations/BalanceTransferSystem.sol | 35 +- .../implementations/EphemeralRecordSystem.sol | 12 +- .../StoreRegistrationSystem.sol | 47 +- .../WorldRegistrationSystem.sol | 151 ++-- .../src/modules/core/tables/Balances.sol | 76 +- .../modules/core/tables/FunctionSelectors.sol | 88 +-- .../src/modules/core/tables/ResourceType.sol | 228 ------ .../src/modules/core/tables/SystemHooks.sol | 194 ++--- .../modules/core/tables/SystemRegistry.sol | 78 +- .../world/src/modules/core/tables/Systems.sol | 98 +-- .../modules/keysintable/KeysInTableHook.sol | 67 +- .../modules/keysintable/KeysInTableModule.sol | 11 +- .../modules/keysintable/getKeysInTable.sol | 29 +- .../world/src/modules/keysintable/hasKey.sol | 9 +- .../world/src/modules/keysintable/query.sol | 3 +- .../keysintable/tables/KeysInTable.sol | 8 +- .../keysintable/tables/UsedKeysIndex.sol | 8 +- .../keyswithvalue/KeysWithValueHook.sol | 42 +- .../keyswithvalue/KeysWithValueModule.sol | 10 +- .../src/modules/keyswithvalue/constants.sol | 4 +- .../keyswithvalue/getKeysWithValue.sol | 11 +- .../keyswithvalue/getTargetTableId.sol | 33 + .../keyswithvalue/tables/KeysWithValue.sol | 111 +-- .../CallboundDelegationControl.sol | 15 +- .../StandardDelegationsModule.sol | 1 - .../TimeboundDelegationControl.sol | 5 +- .../src/modules/std-delegations/constants.sol | 11 +- .../tables/CallboundDelegations.sol | 79 +- .../tables/TimeboundDelegations.sol | 8 +- .../uniqueentity/UniqueEntityModule.sol | 9 +- .../uniqueentity/UniqueEntitySystem.sol | 10 +- .../src/modules/uniqueentity/constants.sol | 10 +- .../uniqueentity/tables/UniqueEntity.sol | 38 +- .../modules/utils/getTargetTableSelector.sol | 18 - packages/world/src/tables/Delegations.sol | 8 +- .../world/src/tables/InstalledModules.sol | 8 +- packages/world/src/tables/NamespaceOwner.sol | 76 +- packages/world/src/tables/ResourceAccess.sol | 74 +- packages/world/src/worldResourceTypes.sol | 12 + packages/world/test/AccessControl.t.sol | 64 +- packages/world/test/Factories.t.sol | 5 +- packages/world/test/KeysInTableModule.t.sol | 22 +- packages/world/test/KeysWithValueModule.t.sol | 53 +- .../test/StandardDelegationsModule.t.sol | 39 +- packages/world/test/UniqueEntityModule.t.sol | 15 +- packages/world/test/Utils.t.sol | 20 +- packages/world/test/World.t.sol | 610 ++++++++++----- packages/world/test/WorldBalance.t.sol | 154 ++-- packages/world/test/WorldDynamicUpdate.t.sol | 15 +- packages/world/test/WorldResourceId.t.sol | 100 +++ packages/world/test/query.t.sol | 15 +- packages/world/test/tables/AddressArray.sol | 103 +-- packages/world/test/tables/Bool.sol | 38 +- .../ts/library/config/resolveWorldConfig.ts | 4 +- .../world/ts/library/config/worldConfig.ts | 4 +- .../contracts/src/codegen/tables/Counter.sol | 8 +- .../contracts/src/codegen/tables/Counter.sol | 8 +- .../contracts/src/codegen/tables/Position.sol | 8 +- .../contracts/src/codegen/tables/Counter.sol | 8 +- test-data/world-logs.json | 735 +++++++++++------- 173 files changed, 3762 insertions(+), 2535 deletions(-) create mode 100644 .changeset/mean-seals-nail.md create mode 100644 .changeset/real-students-exercise.md create mode 100644 .changeset/stale-seahorses-pay.md create mode 100644 packages/common/src/common.ts create mode 100644 packages/common/src/hexToResourceId.test.ts create mode 100644 packages/common/src/hexToResourceId.ts delete mode 100644 packages/common/src/hexToTableId.test.ts delete mode 100644 packages/common/src/hexToTableId.ts create mode 100644 packages/common/src/resourceIdToHex.test.ts create mode 100644 packages/common/src/resourceIdToHex.ts create mode 100644 packages/common/src/resourceTypes.ts delete mode 100644 packages/common/src/tableIdToHex.test.ts delete mode 100644 packages/common/src/tableIdToHex.ts create mode 100644 packages/store/src/ResourceId.sol create mode 100644 packages/store/src/codegen/tables/ResourceIds.sol create mode 100644 packages/store/src/storeResourceTypes.sol create mode 100644 packages/store/test/ResourceId.t.sol delete mode 100644 packages/world/src/ResourceSelector.sol create mode 100644 packages/world/src/WorldResourceId.sol delete mode 100644 packages/world/src/common.sol delete mode 100644 packages/world/src/modules/core/tables/ResourceType.sol create mode 100644 packages/world/src/modules/keyswithvalue/getTargetTableId.sol delete mode 100644 packages/world/src/modules/utils/getTargetTableSelector.sol create mode 100644 packages/world/src/worldResourceTypes.sol create mode 100644 packages/world/test/WorldResourceId.t.sol diff --git a/.changeset/mean-seals-nail.md b/.changeset/mean-seals-nail.md new file mode 100644 index 0000000000..7ac373d827 --- /dev/null +++ b/.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); +``` diff --git a/.changeset/real-students-exercise.md b/.changeset/real-students-exercise.md new file mode 100644 index 0000000000..25ac8a1a75 --- /dev/null +++ b/.changeset/real-students-exercise.md @@ -0,0 +1,25 @@ +--- +"@latticexyz/world": major +--- + +All `World` methods acting on namespaces as resources have been updated to use `ResourceId namespaceId` as parameter instead of `bytes14 namespace`. +The reason for this change is to make it clearer when a namespace is used as resource, as opposed to being part of another resource's ID. + +```diff ++ import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + +IBaseWorld { +- function registerNamespace(bytes14 namespace) external; ++ function registerNamespace(ResourceId namespaceId) external; + +- function transferOwnership(bytes14 namespace, address newOwner) external; ++ function transferOwnership(ResourceId namespaceId, address newOwner) external; + +- function transferBalanceToNamespace(bytes14 fromNamespace, bytes14 toNamespace, uint256 amount) external; ++ function transferBalanceToNamespace(ResourceId fromNamespaceId, ResourceId toNamespaceId, uint256 amount) external; + +- function transferBalanceToAddress(bytes14 fromNamespace, address toAddress, uint256 amount) external; ++ function transferBalanceToAddress(ResourceId fromNamespaceId, address toAddress, uint256 amount) external; +} + +``` diff --git a/.changeset/stale-seahorses-pay.md b/.changeset/stale-seahorses-pay.md new file mode 100644 index 0000000000..8bd942565b --- /dev/null +++ b/.changeset/stale-seahorses-pay.md @@ -0,0 +1,70 @@ +--- +"@latticexyz/cli": major +"@latticexyz/common": major +"@latticexyz/config": major +"@latticexyz/store": major +--- + +- `ResourceSelector` is replaced with `ResourceId`, `ResourceIdLib`, `ResourceIdInstance`, `WorldResourceIdLib` and `WorldResourceIdInstance`. + + 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 2 bytes reserved for the resource type, the next 14 bytes reserved for the resource's namespace, and the last 16 bytes reserved for the resource's name. + + 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` now also uses `ResourceId` and needs to be aware of resource types, but not of namespaces/names. + + ```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(RESOURCE_SYSTEM, "namespace", "name"); + + - 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 + } + ``` diff --git a/.prettierignore b/.prettierignore index 6ec0121e9d..d36102008d 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,5 @@ dist -**/.next +.next templates/phaser/packages/art CODEOWNERS +out diff --git a/e2e/packages/contracts/src/codegen/tables/Multi.sol b/e2e/packages/contracts/src/codegen/tables/Multi.sol index abab8c9590..b3674887f3 100644 --- a/e2e/packages/contracts/src/codegen/tables/Multi.sol +++ b/e2e/packages/contracts/src/codegen/tables/Multi.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Multi"))); -bytes32 constant MultiTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Multi"))) +); +ResourceId constant MultiTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0021020020010000000000000000000000000000000000000000000000000000 diff --git a/e2e/packages/contracts/src/codegen/tables/Number.sol b/e2e/packages/contracts/src/codegen/tables/Number.sol index 246f60517d..db8e380f8b 100644 --- a/e2e/packages/contracts/src/codegen/tables/Number.sol +++ b/e2e/packages/contracts/src/codegen/tables/Number.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Number"))); -bytes32 constant NumberTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Number"))) +); +ResourceId constant NumberTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0004010004000000000000000000000000000000000000000000000000000000 diff --git a/e2e/packages/contracts/src/codegen/tables/NumberList.sol b/e2e/packages/contracts/src/codegen/tables/NumberList.sol index 4f0a11dccc..17d4e49daa 100644 --- a/e2e/packages/contracts/src/codegen/tables/NumberList.sol +++ b/e2e/packages/contracts/src/codegen/tables/NumberList.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("NumberList"))); -bytes32 constant NumberListTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("NumberList"))) +); +ResourceId constant NumberListTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 diff --git a/e2e/packages/contracts/src/codegen/tables/Vector.sol b/e2e/packages/contracts/src/codegen/tables/Vector.sol index ee5dd92631..8fca7ea7bb 100644 --- a/e2e/packages/contracts/src/codegen/tables/Vector.sol +++ b/e2e/packages/contracts/src/codegen/tables/Vector.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Vector"))); -bytes32 constant VectorTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Vector"))) +); +ResourceId constant VectorTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0008020004040000000000000000000000000000000000000000000000000000 diff --git a/e2e/packages/sync-test/data/setContractData.ts b/e2e/packages/sync-test/data/setContractData.ts index 323189d95c..be886c0d07 100644 --- a/e2e/packages/sync-test/data/setContractData.ts +++ b/e2e/packages/sync-test/data/setContractData.ts @@ -2,7 +2,7 @@ import { Page } from "@playwright/test"; import { Data } from "./types"; import { encodeTestData } from "./encodeTestData"; import { callWorld } from "./callWorld"; -import { tableIdToHex } from "@latticexyz/common"; +import { resourceIdToHex } from "@latticexyz/common"; /** * Writes contract data by calling `world.setRecord` via the client @@ -14,7 +14,7 @@ export async function setContractData(page: Page, data: Data) { for (const record of records) { const promise = await callWorld(page, "setRecord", [ // TODO: add support for multiple namespaces after https://github.com/latticexyz/mud/issues/994 is resolved - tableIdToHex("", table), + resourceIdToHex({ type: "table", namespace: "", name: table }), record.key, record.staticData, record.encodedLengths, diff --git a/examples/minimal/packages/contracts/script/PostDeploy.s.sol b/examples/minimal/packages/contracts/script/PostDeploy.s.sol index 059758821e..06e875346c 100644 --- a/examples/minimal/packages/contracts/script/PostDeploy.s.sol +++ b/examples/minimal/packages/contracts/script/PostDeploy.s.sol @@ -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"; @@ -19,16 +20,13 @@ 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({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "ChatNamespaced" + }); + IWorld(worldAddress).registerSystem(systemId, chatNamespacedSystem, true); + IWorld(worldAddress).registerFunctionSelector(systemId, "sendMessage", "(string)"); // Grant this system access to MessageTable IWorld(worldAddress).grantAccess(MessageTableTableId, address(chatNamespacedSystem)); diff --git a/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol b/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol index 0eee6c3ff4..fccaf9550e 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("CounterTable"))); -bytes32 constant CounterTableTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("CounterTable"))) +); +ResourceId constant CounterTableTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0004010004000000000000000000000000000000000000000000000000000000 diff --git a/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol b/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol index 7156ea2c10..046b2889d6 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Inventory"))); -bytes32 constant InventoryTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Inventory"))) +); +ResourceId constant InventoryTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0004010004000000000000000000000000000000000000000000000000000000 diff --git a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol index 48d6426ca7..872bdf5b51 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("MessageTable"))); -bytes32 constant MessageTableTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("MessageTable"))) +); +ResourceId constant MessageTableTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol index e2482100cd..76852f049e 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Dynamics1"))); -bytes32 constant Dynamics1TableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Dynamics1"))) +); +ResourceId constant Dynamics1TableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000500000000000000000000000000000000000000000000000000000000 diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol index c587e088ea..5001ff4efb 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Dynamics2"))); -bytes32 constant Dynamics2TableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Dynamics2"))) +); +ResourceId constant Dynamics2TableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000300000000000000000000000000000000000000000000000000000000 diff --git a/packages/cli/contracts/src/codegen/tables/Ephemeral.sol b/packages/cli/contracts/src/codegen/tables/Ephemeral.sol index dae46bfb71..b2edf7c856 100644 --- a/packages/cli/contracts/src/codegen/tables/Ephemeral.sol +++ b/packages/cli/contracts/src/codegen/tables/Ephemeral.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Ephemeral"))); -bytes32 constant EphemeralTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Ephemeral"))) +); +ResourceId constant EphemeralTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010020000000000000000000000000000000000000000000000000000000 diff --git a/packages/cli/contracts/src/codegen/tables/Singleton.sol b/packages/cli/contracts/src/codegen/tables/Singleton.sol index 5d8d466a6c..45d77b5356 100644 --- a/packages/cli/contracts/src/codegen/tables/Singleton.sol +++ b/packages/cli/contracts/src/codegen/tables/Singleton.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Singleton"))); -bytes32 constant SingletonTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Singleton"))) +); +ResourceId constant SingletonTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010320000000000000000000000000000000000000000000000000000000 diff --git a/packages/cli/contracts/src/codegen/tables/Statics.sol b/packages/cli/contracts/src/codegen/tables/Statics.sol index 8a911d7d46..961208a783 100644 --- a/packages/cli/contracts/src/codegen/tables/Statics.sol +++ b/packages/cli/contracts/src/codegen/tables/Statics.sol @@ -17,12 +17,16 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; // Import user types import { Enum2, Enum1 } from "./../common.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Statics"))); -bytes32 constant StaticsTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Statics"))) +); +ResourceId constant StaticsTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x004a060020041014010100000000000000000000000000000000000000000000 diff --git a/packages/cli/src/commands/trace.ts b/packages/cli/src/commands/trace.ts index 32ea227735..faca38ed3f 100644 --- a/packages/cli/src/commands/trace.ts +++ b/packages/cli/src/commands/trace.ts @@ -9,12 +9,16 @@ import { StoreConfig } from "@latticexyz/store"; import { resolveWorldConfig, WorldConfig } from "@latticexyz/world"; import IBaseWorldAbi from "@latticexyz/world/out/IBaseWorld.sol/IBaseWorld.abi.json" assert { type: "json" }; import worldConfig from "@latticexyz/world/mud.config.js"; -import { tableIdToHex } from "@latticexyz/common"; +import { resourceIdToHex } from "@latticexyz/common"; import { getExistingContracts } from "../utils/getExistingContracts"; import { getChainId } from "../utils/utils/getChainId"; // TODO account for multiple namespaces (https://github.com/latticexyz/mud/issues/994) -const systemsTableId = tableIdToHex(worldConfig.namespace, worldConfig.tables.Systems.name); +const systemsTableId = resourceIdToHex({ + type: "system", + namespace: worldConfig.namespace, + name: worldConfig.tables.Systems.name, +}); type Options = { tx: string; @@ -76,7 +80,7 @@ const commandModule: CommandModule = { const systemTableFieldLayout = await WorldContract.getFieldLayout(systemsTableId); const labels: { name: string; address: string }[] = []; for (const name of names) { - const systemSelector = tableIdToHex(namespace, name); + const systemSelector = resourceIdToHex({ type: "system", namespace, name }); // Get the first field of `Systems` table (the table maps system name to its address and other data) const address = await WorldContract.getField(systemsTableId, [systemSelector], 0, systemTableFieldLayout); labels.push({ name, address }); diff --git a/packages/cli/src/utils/systems/getGrantAccessCallData.ts b/packages/cli/src/utils/systems/getGrantAccessCallData.ts index f9cd39a1b5..e5d50b84ad 100644 --- a/packages/cli/src/utils/systems/getGrantAccessCallData.ts +++ b/packages/cli/src/utils/systems/getGrantAccessCallData.ts @@ -1,6 +1,6 @@ import { System } from "./types"; import { CallData } from "../utils/types"; -import { tableIdToHex } from "@latticexyz/common"; +import { resourceIdToHex } from "@latticexyz/common"; export async function getGrantAccessCallData(input: { systems: System[]; @@ -24,6 +24,6 @@ export async function getGrantAccessCallData(input: { function getGrantSystemAccessCallData(name: string, namespace: string, address: string): CallData { return { func: "grantAccess", - args: [tableIdToHex(namespace, name), address], + args: [resourceIdToHex({ type: "system", namespace, name }), address], }; } diff --git a/packages/cli/src/utils/systems/getRegisterFunctionSelectorsCallData.ts b/packages/cli/src/utils/systems/getRegisterFunctionSelectorsCallData.ts index 23545868fd..0af36fec4d 100644 --- a/packages/cli/src/utils/systems/getRegisterFunctionSelectorsCallData.ts +++ b/packages/cli/src/utils/systems/getRegisterFunctionSelectorsCallData.ts @@ -1,4 +1,4 @@ -import { tableIdToHex } from "@latticexyz/common"; +import { resourceIdToHex } from "@latticexyz/common"; import { System } from "./types"; import { loadFunctionSignatures, toFunctionSelector } from "./utils"; import { CallData } from "../utils/types"; @@ -57,12 +57,12 @@ function getRegisterFunctionSelectorCallData(input: { const systemFunctionSelector = toFunctionSelector({ functionName, functionArgs }); return { func: "registerRootFunctionSelector", - args: [tableIdToHex(namespace, name), worldFunctionSelector, systemFunctionSelector], + args: [resourceIdToHex({ type: "system", namespace, name }), worldFunctionSelector, systemFunctionSelector], }; } else { return { func: "registerRootFunctionSelector", - args: [tableIdToHex(namespace, name), functionName, functionArgs], + args: [resourceIdToHex({ type: "system", namespace, name }), functionName, functionArgs], }; } } diff --git a/packages/cli/src/utils/systems/getRegisterSystemCallData.ts b/packages/cli/src/utils/systems/getRegisterSystemCallData.ts index fa2d1c0e20..66243170f3 100644 --- a/packages/cli/src/utils/systems/getRegisterSystemCallData.ts +++ b/packages/cli/src/utils/systems/getRegisterSystemCallData.ts @@ -1,4 +1,4 @@ -import { tableIdToHex } from "@latticexyz/common"; +import { resourceIdToHex } from "@latticexyz/common"; import { System } from "./types"; import { CallData } from "../utils/types"; @@ -12,6 +12,6 @@ export async function getRegisterSystemCallData(input: { const systemAddress = await systemContracts[systemName]; return { func: "registerSystem", - args: [tableIdToHex(namespace, system.name), systemAddress, system.openAccess], + args: [resourceIdToHex({ type: "system", namespace, name: system.name }), systemAddress, system.openAccess], }; } diff --git a/packages/cli/src/utils/tables/getRegisterTableCallData.ts b/packages/cli/src/utils/tables/getRegisterTableCallData.ts index 7b2f80fda6..8db6cc0c43 100644 --- a/packages/cli/src/utils/tables/getRegisterTableCallData.ts +++ b/packages/cli/src/utils/tables/getRegisterTableCallData.ts @@ -1,7 +1,7 @@ import { encodeSchema, getStaticByteLength } from "@latticexyz/schema-type/deprecated"; import { StoreConfig } from "@latticexyz/store"; import { resolveAbiOrUserType } from "@latticexyz/store/codegen"; -import { tableIdToHex } from "@latticexyz/common"; +import { resourceIdToHex } from "@latticexyz/common"; import { Table } from "./types"; import { fieldLayoutToHex } from "@latticexyz/protocol-parser"; import { CallData } from "../utils/types"; @@ -29,7 +29,8 @@ export function getRegisterTableCallData(table: Table, storeConfig: StoreConfig) return { func: "registerTable", args: [ - tableIdToHex(storeConfig.namespace, name), + // TODO: add support for table namespaces (https://github.com/latticexyz/mud/issues/994) + resourceIdToHex({ type: table.ephemeral ? "offchainTable" : "table", namespace: storeConfig.namespace, name }), fieldLayoutToHex(fieldLayout), encodeSchema(keyTypes), encodeSchema(schemaTypes), diff --git a/packages/common/src/codegen/render-solidity/common.ts b/packages/common/src/codegen/render-solidity/common.ts index 1a7a95ebec..c88829706e 100644 --- a/packages/common/src/codegen/render-solidity/common.ts +++ b/packages/common/src/codegen/render-solidity/common.ts @@ -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}`)); @@ -166,11 +166,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(RESOURCE_TABLE, bytes14("${staticResourceData.namespace}"), bytes16("${staticResourceData.name}"))))`; const tableIdDefinition = ` - bytes32 constant _tableId = ${hardcodedTableId}; - bytes32 constant ${staticResourceData.tableIdName} = _tableId; + ResourceId constant _tableId = ${hardcodedTableId}; + ResourceId constant ${staticResourceData.tableIdName} = _tableId; `; return { hardcodedTableId, diff --git a/packages/common/src/common.ts b/packages/common/src/common.ts new file mode 100644 index 0000000000..dd2cdf3162 --- /dev/null +++ b/packages/common/src/common.ts @@ -0,0 +1,7 @@ +import { ResourceType } from "./resourceTypes"; + +export type ResourceId = { + namespace: string; + name: string; + type: ResourceType; +}; diff --git a/packages/common/src/hexToResourceId.test.ts b/packages/common/src/hexToResourceId.test.ts new file mode 100644 index 0000000000..56ebfecfdb --- /dev/null +++ b/packages/common/src/hexToResourceId.test.ts @@ -0,0 +1,11 @@ +import { describe, it, expect } from "vitest"; +import { hexToResourceId } from "./hexToResourceId"; + +describe("hexToResourceId", () => { + it("can convert from hex string", () => { + const resourceId = hexToResourceId("0x74626e616d65737061636500000000006e616d65000000000000000000000000"); + expect(resourceId.type).toMatchInlineSnapshot('"table"'); + expect(resourceId.namespace).toMatchInlineSnapshot('"namespace"'); + expect(resourceId.name).toMatchInlineSnapshot('"name"'); + }); +}); diff --git a/packages/common/src/hexToResourceId.ts b/packages/common/src/hexToResourceId.ts new file mode 100644 index 0000000000..2f45ac2c17 --- /dev/null +++ b/packages/common/src/hexToResourceId.ts @@ -0,0 +1,30 @@ +import { Hex, hexToString, sliceHex } from "viem"; +import { ResourceId } from "./common"; +import { ResourceType, resourceTypes } from "./resourceTypes"; +import { resourceTypeIds } from "./resourceIdToHex"; +import { ReverseMap } from "./type-utils/common"; + +const resourceTypeIdToType = Object.fromEntries( + Object.entries(resourceTypeIds).map(([key, value]) => [value, key]) +) as ReverseMap; + +function getResourceType(resourceTypeId: string): ResourceType | undefined { + // TODO: replace Partial with `noUncheckedIndexedAccess` + const type = (resourceTypeIdToType as Partial>)[resourceTypeId]; + if (resourceTypes.includes(type as ResourceType)) { + return type; + } +} + +export function hexToResourceId(hex: Hex): ResourceId { + const resourceTypeId = hexToString(sliceHex(hex, 0, 2)).replace(/\0+$/, ""); + const type = getResourceType(resourceTypeId); + const namespace = hexToString(sliceHex(hex, 2, 16)).replace(/\0+$/, ""); + const name = hexToString(sliceHex(hex, 16, 32)).replace(/\0+$/, ""); + + if (!type) { + throw new Error(`Unknown resource type: ${resourceTypeId}`); + } + + return { type, namespace, name }; +} diff --git a/packages/common/src/hexToTableId.test.ts b/packages/common/src/hexToTableId.test.ts deleted file mode 100644 index 20a43c95b0..0000000000 --- a/packages/common/src/hexToTableId.test.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { hexToTableId } from "./hexToTableId"; - -describe("hexToTableId", () => { - it("can convert from hex string", () => { - const tableId = hexToTableId("0x6e616d657370616365000000000000006e616d65000000000000000000000000"); - expect(tableId.namespace).toMatchInlineSnapshot('"namespace"'); - expect(tableId.name).toMatchInlineSnapshot('"name"'); - }); -}); diff --git a/packages/common/src/hexToTableId.ts b/packages/common/src/hexToTableId.ts deleted file mode 100644 index 8782630888..0000000000 --- a/packages/common/src/hexToTableId.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Hex, hexToString, sliceHex } from "viem"; - -export function hexToTableId(hex: Hex): { namespace: string; name: string } { - const namespace = hexToString(sliceHex(hex, 0, 16)).replace(/\0+$/, ""); - const name = hexToString(sliceHex(hex, 16, 32)).replace(/\0+$/, ""); - return { namespace, name }; -} diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index d6a59390fa..a15afa9877 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -1,9 +1,11 @@ +export * from "./common"; export * from "./createBurnerAccount"; export * from "./createContract"; export * from "./createNonceManager"; export * from "./getBurnerPrivateKey"; -export * from "./hexToTableId"; +export * from "./hexToResourceId"; export * from "./readHex"; +export * from "./resourceIdToHex"; +export * from "./resourceTypes"; export * from "./spliceHex"; -export * from "./tableIdToHex"; export * from "./transportObserver"; diff --git a/packages/common/src/resourceIdToHex.test.ts b/packages/common/src/resourceIdToHex.test.ts new file mode 100644 index 0000000000..d8a1ca026d --- /dev/null +++ b/packages/common/src/resourceIdToHex.test.ts @@ -0,0 +1,69 @@ +import { describe, it, expect } from "vitest"; +import { resourceIdToHex } from "./resourceIdToHex"; +import { hexToResourceId } from "./hexToResourceId"; + +describe("resourceIdToHex", () => { + it("can convert table resource to hex string", () => { + const hex = resourceIdToHex({ + type: "table", + namespace: "namespace", + name: "name", + }); + expect(hex).toMatchInlineSnapshot('"0x74626e616d65737061636500000000006e616d65000000000000000000000000"'); + expect(hexToResourceId(hex)).toMatchInlineSnapshot(` + { + "name": "name", + "namespace": "namespace", + "type": "table", + } + `); + }); + + it("can convert offchain table resource to hex string", () => { + const hex = resourceIdToHex({ + type: "offchainTable", + namespace: "namespace", + name: "name", + }); + expect(hex).toMatchInlineSnapshot('"0x6f746e616d65737061636500000000006e616d65000000000000000000000000"'); + expect(hexToResourceId(hex)).toMatchInlineSnapshot(` + { + "name": "name", + "namespace": "namespace", + "type": "offchainTable", + } + `); + }); + + it("truncates namespaces >14 bytes", () => { + const hex = resourceIdToHex({ + type: "table", + namespace: "AVeryLongNamespace", + name: "name", + }); + expect(hex).toMatchInlineSnapshot('"0x746241566572794c6f6e674e616d65736e616d65000000000000000000000000"'); + expect(hexToResourceId(hex)).toMatchInlineSnapshot(` + { + "name": "name", + "namespace": "AVeryLongNames", + "type": "table", + } + `); + }); + + it("truncates names >16 bytes", () => { + const hex = resourceIdToHex({ + type: "table", + namespace: "namespace", + name: "AnUnnecessarilyLongName", + }); + expect(hex).toMatchInlineSnapshot('"0x74626e616d6573706163650000000000416e556e6e65636573736172696c794c"'); + expect(hexToResourceId(hex)).toMatchInlineSnapshot(` + { + "name": "AnUnnecessarilyL", + "namespace": "namespace", + "type": "table", + } + `); + }); +}); diff --git a/packages/common/src/resourceIdToHex.ts b/packages/common/src/resourceIdToHex.ts new file mode 100644 index 0000000000..bebe682aec --- /dev/null +++ b/packages/common/src/resourceIdToHex.ts @@ -0,0 +1,23 @@ +import { Hex, stringToHex, concatHex } from "viem"; +import { ResourceId } from "./common"; +import { ResourceType } from "./resourceTypes"; + +/** @internal */ +export const resourceTypeIds = { + // keep these in sync with storeResourceTypes.sol + table: "tb", + offchainTable: "ot", + // keep these in sync with worldResourceTypes.sol + namespace: "ns", + module: "md", + system: "sy", +} as const satisfies Record; + +export function resourceIdToHex(resourceId: ResourceId): Hex { + const typeId = resourceTypeIds[resourceId.type]; + return concatHex([ + stringToHex(typeId, { size: 2 }), + stringToHex(resourceId.namespace.slice(0, 14), { size: 14 }), + stringToHex(resourceId.name.slice(0, 16), { size: 16 }), + ]); +} diff --git a/packages/common/src/resourceTypes.ts b/packages/common/src/resourceTypes.ts new file mode 100644 index 0000000000..eff7931236 --- /dev/null +++ b/packages/common/src/resourceTypes.ts @@ -0,0 +1,3 @@ +export const resourceTypes = ["table", "offchainTable", "namespace", "module", "system"] as const; + +export type ResourceType = (typeof resourceTypes)[number]; diff --git a/packages/common/src/tableIdToHex.test.ts b/packages/common/src/tableIdToHex.test.ts deleted file mode 100644 index 97fdf9476c..0000000000 --- a/packages/common/src/tableIdToHex.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { tableIdToHex } from "./tableIdToHex"; -import { hexToTableId } from "./hexToTableId"; - -describe("tableIdToHex", () => { - it("can convert to hex string", () => { - const tableIdHex = tableIdToHex("namespace", "name"); - expect(tableIdHex).toMatchInlineSnapshot('"0x6e616d657370616365000000000000006e616d65000000000000000000000000"'); - }); - - it("truncates namespaces >16 bytes", () => { - const hex = "0x41566572794c6f6e674e616d657370616e616d65000000000000000000000000"; - const tableIdHex = tableIdToHex("AVeryLongNamespace", "name"); - expect(tableIdHex).toEqual(hex); - expect(hexToTableId(tableIdHex).namespace).toMatchInlineSnapshot('"AVeryLongNamespa"'); - }); - - it("truncates names >16 bytes", () => { - const hex = "0x6e616d65737061636500000000000000416e556e6e65636573736172696c794c"; - const tableIdHex = tableIdToHex("namespace", "AnUnnecessarilyLongName"); - expect(tableIdHex).toEqual(hex); - expect(hexToTableId(tableIdHex).name).toMatchInlineSnapshot('"AnUnnecessarilyL"'); - }); -}); diff --git a/packages/common/src/tableIdToHex.ts b/packages/common/src/tableIdToHex.ts deleted file mode 100644 index f3cddef064..0000000000 --- a/packages/common/src/tableIdToHex.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { Hex, stringToHex, concatHex } from "viem"; - -// TODO: rename to `resourceIdToHex` or `resourceSelectorToHex` since it can be used with other resources than tables -export function tableIdToHex(namespace: string, name: string): Hex { - return concatHex([ - stringToHex(namespace.substring(0, 16), { size: 16 }), - stringToHex(name.substring(0, 16), { size: 16 }), - ]); -} diff --git a/packages/common/src/type-utils/common.ts b/packages/common/src/type-utils/common.ts index e75f5054dc..7694b42c28 100644 --- a/packages/common/src/type-utils/common.ts +++ b/packages/common/src/type-utils/common.ts @@ -21,3 +21,8 @@ export type OrDefaults = { export type UnionOmit = T extends any ? Omit : never; export type UnionKeys = T extends any ? keyof T : never; export type UnionPick> = T extends any ? Pick> : never; + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +export type ReverseMap> = { + [K in keyof T as T[K]]: K; +}; diff --git a/packages/config/src/library/commonSchemas.ts b/packages/config/src/library/commonSchemas.ts index 72ba06da1e..63409583ab 100644 --- a/packages/config/src/library/commonSchemas.ts +++ b/packages/config/src/library/commonSchemas.ts @@ -8,7 +8,7 @@ import { validateRoute, validateSingleLevelRoute, validateUncapitalizedName, - validateSelector, + validateNamespace, } from "./validation"; /** Capitalized names of objects, like tables and systems */ @@ -16,7 +16,10 @@ export const zObjectName = z.string().superRefine(validateCapitalizedName); /** Uncapitalized names of values, like keys and columns */ export const zValueName = z.string().superRefine(validateUncapitalizedName); /** Name that can start with any case */ -export const zAnyCaseName = z.string().superRefine(validateName); +export const zName = z.string().superRefine(validateName); +/** A namespace */ +export const zNamespace = z.string().superRefine(validateNamespace); + /** List of unique enum member names and 0 < length < 256 */ export const zUserEnum = z.array(zObjectName).superRefine(validateEnum); @@ -29,6 +32,3 @@ export const zBaseRoute = z.string().superRefine(validateBaseRoute); /** A valid Ethereum address */ export const zEthereumAddress = z.string().superRefine(validateEthereumAddress); - -/** A selector for namespace/file/resource */ -export const zSelector = z.string().superRefine(validateSelector); diff --git a/packages/config/src/library/validation.ts b/packages/config/src/library/validation.ts index 125187fa85..37609efac1 100644 --- a/packages/config/src/library/validation.ts +++ b/packages/config/src/library/validation.ts @@ -1,7 +1,8 @@ import { utils } from "ethers"; import { ZodIssueCode, RefinementCtx } from "zod"; -export const STORE_SELECTOR_MAX_LENGTH = 16; +export const STORE_NAME_MAX_LENGTH = 16; +export const STORE_NAMESPACE_MAX_LENGTH = 14; export function validateName(name: string, ctx: RefinementCtx) { if (!/^\w+$/.test(name)) { @@ -139,11 +140,11 @@ export function getDuplicates(array: T[]) { return [...duplicates]; } -export function validateSelector(name: string, ctx: RefinementCtx) { - if (name.length > STORE_SELECTOR_MAX_LENGTH) { +export function validateNamespace(name: string, ctx: RefinementCtx) { + if (name.length > STORE_NAMESPACE_MAX_LENGTH) { ctx.addIssue({ code: ZodIssueCode.custom, - message: `Selector must be <= ${STORE_SELECTOR_MAX_LENGTH} characters`, + message: `Namespace must be <= ${STORE_NAMESPACE_MAX_LENGTH} characters`, }); } if (!/^\w*$/.test(name)) { diff --git a/packages/dev-tools/src/actions/WriteSummary.tsx b/packages/dev-tools/src/actions/WriteSummary.tsx index 42aee498ec..6c65b9550f 100644 --- a/packages/dev-tools/src/actions/WriteSummary.tsx +++ b/packages/dev-tools/src/actions/WriteSummary.tsx @@ -9,7 +9,7 @@ import { getTransaction } from "./getTransaction"; import { getTransactionReceipt } from "./getTransactionReceipt"; import { getTransactionResult } from "./getTransactionResult"; import { ErrorTrace } from "../ErrorTrace"; -import { ContractWrite, hexToTableId } from "@latticexyz/common"; +import { ContractWrite, hexToResourceId } from "@latticexyz/common"; import { useDevToolsContext } from "../DevToolsContext"; import { hexKeyTupleToEntity } from "@latticexyz/store-sync/recs"; @@ -145,7 +145,7 @@ export function WriteSummary({ write }: Props) { {events.map(({ eventName, args }, i) => { - const table = hexToTableId((args as any).tableId); + const table = hexToResourceId((args as any).tableId); // TODO: dedupe this with logs table so we can get both rendering the same return ( diff --git a/packages/dev-tools/src/events/LogsTable.tsx b/packages/dev-tools/src/events/LogsTable.tsx index ac4779fb2b..5c720f1a62 100644 --- a/packages/dev-tools/src/events/LogsTable.tsx +++ b/packages/dev-tools/src/events/LogsTable.tsx @@ -1,6 +1,6 @@ import { StorageAdapterLog } from "@latticexyz/store-sync"; import { EventIcon } from "./EventIcon"; -import { hexToTableId } from "@latticexyz/common"; +import { hexToResourceId } from "@latticexyz/common"; // TODO: use react-table or similar for better perf with lots of logs @@ -22,7 +22,7 @@ export function LogsTable({ logs }: Props) { {logs.map((log) => { - const { namespace, name } = hexToTableId(log.args.tableId); + const { namespace, name } = hexToResourceId(log.args.tableId); return ( Promise; // TODO: adjust when we get namespace support (https://github.com/latticexyz/mud/issues/994) and when table has namespace key (https://github.com/latticexyz/mud/issues/1201) export const schemasTable = storeConfig.tables.Tables; -export const schemasTableId = tableIdToHex(storeConfig.namespace, schemasTable.name); +export const schemasTableId = resourceIdToHex({ + type: schemasTable.ephemeral ? "offchainTable" : "table", + namespace: storeConfig.namespace, + name: schemasTable.name, +}); diff --git a/packages/store-sync/src/logToTable.test.ts b/packages/store-sync/src/logToTable.test.ts index 53ec2a6a5e..1812ebb67f 100644 --- a/packages/store-sync/src/logToTable.test.ts +++ b/packages/store-sync/src/logToTable.test.ts @@ -8,8 +8,8 @@ describe("logToTable", () => { address: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c", eventName: "StoreSetRecord", args: { - tableId: "0x6d756473746f726500000000000000005461626c657300000000000000000000", - keyTuple: ["0x6d756473746f726500000000000000005461626c657300000000000000000000"], + tableId: "0x74626d756473746f72650000000000005461626c657300000000000000000000", + keyTuple: ["0x74626d756473746f72650000000000005461626c657300000000000000000000"], staticData: "0x0060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c40000000000000000000000000000000000000000000000", encodedLengths: "0x000000000000000000000000000000000000022000000000a0000000000002c0", // "0x00000000000000000000000000000000000000a00000000220000000000002c0", @@ -25,7 +25,7 @@ describe("logToTable", () => { }, "name": "Tables", "namespace": "mudstore", - "tableId": "0x6d756473746f726500000000000000005461626c657300000000000000000000", + "tableId": "0x74626d756473746f72650000000000005461626c657300000000000000000000", "valueSchema": { "abiEncodedFieldNames": "bytes", "abiEncodedKeyNames": "bytes", diff --git a/packages/store-sync/src/logToTable.ts b/packages/store-sync/src/logToTable.ts index 72f7f01d47..14d5b3ff75 100644 --- a/packages/store-sync/src/logToTable.ts +++ b/packages/store-sync/src/logToTable.ts @@ -1,7 +1,7 @@ import { hexToSchema, decodeValue } from "@latticexyz/protocol-parser"; import { concatHex, decodeAbiParameters, parseAbiParameters } from "viem"; import { StorageAdapterLog, Table, schemasTable } from "./common"; -import { hexToTableId } from "@latticexyz/common"; +import { hexToResourceId } from "@latticexyz/common"; // TODO: add tableToLog @@ -11,7 +11,7 @@ export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord console.warn("registerSchema event is expected to have only one key in key tuple, but got multiple", log); } - const table = hexToTableId(tableId); + const table = hexToResourceId(tableId); const value = decodeValue( schemasTable.valueSchema, diff --git a/packages/store-sync/src/postgres/buildInternalTables.ts b/packages/store-sync/src/postgres/buildInternalTables.ts index 08a4fd8b80..bd0b7372e0 100644 --- a/packages/store-sync/src/postgres/buildInternalTables.ts +++ b/packages/store-sync/src/postgres/buildInternalTables.ts @@ -1,6 +1,6 @@ import { integer, pgSchema, text } from "drizzle-orm/pg-core"; import { transformSchemaName } from "./transformSchemaName"; -import { asAddress, asBigInt, asJson, asNumber } from "./columnTypes"; +import { asAddress, asBigInt, asHex, asJson, asNumber } from "./columnTypes"; import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser"; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type @@ -19,7 +19,7 @@ export function buildInternalTables() { schemaVersion: integer("schema_version").primaryKey(), key: text("key").notNull().primaryKey(), address: asAddress("address").notNull(), - tableId: text("table_id").notNull(), + tableId: asHex("table_id").notNull(), namespace: text("namespace").notNull(), name: text("name").notNull(), keySchema: asJson("key_schema").notNull(), diff --git a/packages/store-sync/src/postgres/getTableKey.ts b/packages/store-sync/src/postgres/getTableKey.ts index 3c58cae80e..e27ce16b58 100644 --- a/packages/store-sync/src/postgres/getTableKey.ts +++ b/packages/store-sync/src/postgres/getTableKey.ts @@ -1,8 +1,8 @@ import { getAddress } from "viem"; import { Table } from "../common"; -import { hexToTableId } from "@latticexyz/common"; +import { hexToResourceId } from "@latticexyz/common"; export function getTableKey({ address, tableId }: Pick): string { - const { namespace, name } = hexToTableId(tableId); + const { namespace, name } = hexToResourceId(tableId); return `${getAddress(address)}:${namespace}:${name}`; } diff --git a/packages/store-sync/src/postgres/getTables.ts b/packages/store-sync/src/postgres/getTables.ts index c88919c54d..b3ea2ce5e4 100644 --- a/packages/store-sync/src/postgres/getTables.ts +++ b/packages/store-sync/src/postgres/getTables.ts @@ -2,7 +2,6 @@ import { PgDatabase } from "drizzle-orm/pg-core"; import { inArray } from "drizzle-orm"; import { Table } from "../common"; import { buildInternalTables } from "./buildInternalTables"; -import { tableIdToHex } from "@latticexyz/common"; export async function getTables(db: PgDatabase, keys: string[] = []): Promise { const internalTables = buildInternalTables(); @@ -12,13 +11,5 @@ export async function getTables(db: PgDatabase, keys: string[] = []): Promi .from(internalTables.tables) .where(keys.length ? inArray(internalTables.tables.key, [...new Set(keys)]) : undefined); - return tables.map((table) => ({ - address: table.address, - tableId: tableIdToHex(table.namespace, table.name), - namespace: table.namespace, - name: table.name, - keySchema: table.keySchema, - valueSchema: table.valueSchema, - lastUpdatedBlockNumber: table.lastUpdatedBlockNumber, - })); + return tables; } diff --git a/packages/store-sync/src/postgres/postgresStorage.test.ts b/packages/store-sync/src/postgres/postgresStorage.test.ts index 8aa0548082..f717c07ea8 100644 --- a/packages/store-sync/src/postgres/postgresStorage.test.ts +++ b/packages/store-sync/src/postgres/postgresStorage.test.ts @@ -78,7 +78,7 @@ describe("postgresStorage", async () => { "name": "NumberList", "namespace": "", "schemaVersion": 1, - "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", + "tableId": "0x746200000000000000000000000000004e756d6265724c697374000000000000", "valueSchema": { "value": "uint32[]", }, @@ -91,11 +91,14 @@ describe("postgresStorage", async () => { [ { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", + "key": "0x5FbDB2315678afecb367f032d93F642f64180aa3::NumberList", "keySchema": {}, + "lastError": null, "lastUpdatedBlockNumber": 5n, "name": "NumberList", "namespace": "", - "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", + "schemaVersion": 1, + "tableId": "0x746200000000000000000000000000004e756d6265724c697374000000000000", "valueSchema": { "value": "uint32[]", }, diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index 7e61e5f5d7..4246c037cc 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -7,7 +7,7 @@ import { debug } from "./debug"; import { buildInternalTables } from "./buildInternalTables"; import { getTables } from "./getTables"; import { schemaVersion } from "./schemaVersion"; -import { hexToTableId, spliceHex, tableIdToHex } from "@latticexyz/common"; +import { hexToResourceId, spliceHex } from "@latticexyz/common"; import { setupTables } from "./setupTables"; import { getTableKey } from "./getTableKey"; import { StorageAdapter, StorageAdapterBlock } from "../common"; @@ -40,15 +40,7 @@ export async function postgresStorage async function postgresStorageAdapter({ blockNumber, logs }: StorageAdapterBlock): Promise { const newTables = logs.filter(isTableRegistrationLog).map(logToTable); - const newSqlTables = newTables.map((table) => - buildTable({ - address: table.address, - namespace: table.namespace, - name: table.name, - keySchema: table.keySchema, - valueSchema: table.valueSchema, - }) - ); + const newSqlTables = newTables.map(buildTable); cleanUp.push(await setupTables(database, newSqlTables)); @@ -59,12 +51,7 @@ export async function postgresStorage .values({ schemaVersion, key: getTableKey(table), - address: table.address, - tableId: tableIdToHex(table.namespace, table.name), - namespace: table.namespace, - name: table.name, - keySchema: table.keySchema, - valueSchema: table.valueSchema, + ...table, lastUpdatedBlockNumber: blockNumber, }) .onConflictDoNothing() @@ -98,7 +85,7 @@ export async function postgresStorage (table) => getTableKey(table) === getTableKey({ address: log.address, tableId: log.args.tableId }) ); if (!table) { - const { namespace, name } = hexToTableId(log.args.tableId); + const { namespace, name } = hexToResourceId(log.args.tableId); debug(`table ${namespace}:${name} not found, skipping log`, log); continue; } diff --git a/packages/store-sync/src/recs/configToRecsComponents.ts b/packages/store-sync/src/recs/configToRecsComponents.ts index 9243f846c9..de52d113b8 100644 --- a/packages/store-sync/src/recs/configToRecsComponents.ts +++ b/packages/store-sync/src/recs/configToRecsComponents.ts @@ -1,6 +1,6 @@ import { StoreConfig } from "@latticexyz/store"; import { SchemaAbiType } from "@latticexyz/schema-type"; -import { tableIdToHex } from "@latticexyz/common"; +import { resourceIdToHex } from "@latticexyz/common"; import { World, defineComponent, Type } from "@latticexyz/recs"; import { ConfigToRecsComponents } from "./common"; import { schemaAbiTypeToRecsType } from "./schemaAbiTypeToRecsType"; @@ -26,7 +26,12 @@ export function configToRecsComponents( __dynamicData: Type.OptionalString, }, { - id: tableIdToHex(config.namespace, tableName), + // TODO: support table namespaces https://github.com/latticexyz/mud/issues/994 + id: resourceIdToHex({ + type: table.ephemeral ? "offchainTable" : "table", + namespace: config.namespace, + name: tableName, + }), metadata: { componentName: tableName, tableName: `${config.namespace}:${tableName}`, diff --git a/packages/store-sync/src/recs/recsStorage.test.ts b/packages/store-sync/src/recs/recsStorage.test.ts index 4bb747b0dc..28879f788b 100644 --- a/packages/store-sync/src/recs/recsStorage.test.ts +++ b/packages/store-sync/src/recs/recsStorage.test.ts @@ -27,7 +27,7 @@ describe("recsStorage", () => { const world = createWorld(); const { components } = recsStorage({ world, config: mudConfig }); expect(components.NumberList.id).toMatchInlineSnapshot( - '"0x000000000000000000000000000000004e756d6265724c697374000000000000"' + '"0x746200000000000000000000000000004e756d6265724c697374000000000000"' ); }); diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index 457eb88793..ce351803f7 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -3,7 +3,7 @@ import { debug } from "./debug"; import { World as RecsWorld, getComponentValue, hasComponent, removeComponent, setComponent } from "@latticexyz/recs"; import { defineInternalComponents } from "./defineInternalComponents"; import { getTableEntity } from "./getTableEntity"; -import { hexToTableId, spliceHex } from "@latticexyz/common"; +import { hexToResourceId, spliceHex } from "@latticexyz/common"; import { decodeValueArgs } from "@latticexyz/protocol-parser"; import { Hex } from "viem"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; @@ -58,7 +58,7 @@ export function recsStorage({ } for (const log of logs) { - const { namespace, name } = hexToTableId(log.args.tableId); + const { namespace, name } = hexToResourceId(log.args.tableId); const table = getComponentValue( components.RegisteredTables, getTableEntity({ address: log.address, namespace, name }) diff --git a/packages/store-sync/src/sqlite/columnTypes.ts b/packages/store-sync/src/sqlite/columnTypes.ts index 3dd4c07e9f..d94f10faee 100644 --- a/packages/store-sync/src/sqlite/columnTypes.ts +++ b/packages/store-sync/src/sqlite/columnTypes.ts @@ -1,6 +1,8 @@ import { customType } from "drizzle-orm/sqlite-core"; import superjson from "superjson"; -import { Address, getAddress } from "viem"; +import { Address, Hex, getAddress } from "viem"; + +// TODO: migrate these to same patterns in postgres/columnTypes // eslint-disable-next-line @typescript-eslint/explicit-function-return-type export const json = (name: string) => @@ -29,3 +31,11 @@ export const address = (name: string) => return getAddress(driverData); }, })(name); + +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const asHex = (name: string) => + customType<{ data: Hex; driverData: Hex }>({ + dataType() { + return "string"; + }, + })(name); diff --git a/packages/store-sync/src/sqlite/getTables.ts b/packages/store-sync/src/sqlite/getTables.ts index 9a99afacbf..f0db291ddb 100644 --- a/packages/store-sync/src/sqlite/getTables.ts +++ b/packages/store-sync/src/sqlite/getTables.ts @@ -3,7 +3,6 @@ import { inArray } from "drizzle-orm"; import { Table } from "../common"; import { getTableName } from "./getTableName"; import { mudStoreTables } from "./internalTables"; -import { tableIdToHex } from "@latticexyz/common"; export function getTables( db: BaseSQLiteDatabase<"sync", void>, @@ -18,17 +17,5 @@ export function getTables( .where(ids.length ? inArray(mudStoreTables.id, ids) : undefined) .all(); - return tables.map((table) => { - const tableId = tableIdToHex(table.namespace, table.name); - return { - id: getTableName(table.address, table.namespace, table.name), - address: table.address, - tableId, - namespace: table.namespace, - name: table.name, - keySchema: table.keySchema, - valueSchema: table.valueSchema, - lastUpdatedBlockNumber: table.lastUpdatedBlockNumber, - }; - }); + return tables; } diff --git a/packages/store-sync/src/sqlite/internalTables.ts b/packages/store-sync/src/sqlite/internalTables.ts index d2774a48e0..fe11932238 100644 --- a/packages/store-sync/src/sqlite/internalTables.ts +++ b/packages/store-sync/src/sqlite/internalTables.ts @@ -1,5 +1,5 @@ import { blob, integer, sqliteTable, text } from "drizzle-orm/sqlite-core"; -import { address, json } from "./columnTypes"; +import { address, asHex, json } from "./columnTypes"; import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser"; export const chainState = sqliteTable("__chainState", { @@ -14,7 +14,7 @@ export const mudStoreTables = sqliteTable("__mudStoreTables", { schemaVersion: integer("schema_version").primaryKey(), id: text("id").notNull().primaryKey(), address: address("address").notNull(), - tableId: text("table_id").notNull(), + tableId: asHex("table_id").notNull(), namespace: text("namespace").notNull(), name: text("name").notNull(), keySchema: json("key_schema").notNull(), diff --git a/packages/store-sync/src/sqlite/sqliteStorage.test.ts b/packages/store-sync/src/sqlite/sqliteStorage.test.ts index 1c8845f37c..06b01ce31e 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.test.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.test.ts @@ -81,7 +81,7 @@ describe("sqliteStorage", async () => { "name": "NumberList", "namespace": "", "schemaVersion": 1, - "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", + "tableId": "0x746200000000000000000000000000004e756d6265724c697374000000000000", "valueSchema": { "value": "uint32[]", }, @@ -96,10 +96,12 @@ describe("sqliteStorage", async () => { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____NumberList", "keySchema": {}, + "lastError": null, "lastUpdatedBlockNumber": 5n, "name": "NumberList", "namespace": "", - "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", + "schemaVersion": 1, + "tableId": "0x746200000000000000000000000000004e756d6265724c697374000000000000", "valueSchema": { "value": "uint32[]", }, diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 08ca78f547..180048279e 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -12,7 +12,7 @@ import { schemaVersion } from "./schemaVersion"; import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; -import { hexToTableId, spliceHex, tableIdToHex } from "@latticexyz/common"; +import { hexToResourceId, spliceHex } from "@latticexyz/common"; import { decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser"; // TODO: upgrade drizzle and use async sqlite interface for consistency @@ -38,13 +38,7 @@ export async function sqliteStorage({ for (const table of newTables) { debug(`creating table ${table.namespace}:${table.name} for world ${chainId}:${table.address}`); - const sqliteTable = buildTable({ - address: table.address, - namespace: table.namespace, - name: table.name, - keySchema: table.keySchema, - valueSchema: table.valueSchema, - }); + const sqliteTable = buildTable(table); tx.run(sql.raw(sqliteTableToSql(sqliteTable))); @@ -52,12 +46,7 @@ export async function sqliteStorage({ .values({ schemaVersion, id: getTableName(table.address, table.namespace, table.name), - address: table.address, - tableId: tableIdToHex(table.namespace, table.name), - namespace: table.namespace, - name: table.name, - keySchema: table.keySchema, - valueSchema: table.valueSchema, + ...table, lastUpdatedBlockNumber: blockNumber, }) .onConflictDoNothing() @@ -72,7 +61,7 @@ export async function sqliteStorage({ logs.map((log) => JSON.stringify({ address: getAddress(log.address), - ...hexToTableId(log.args.tableId), + ...hexToResourceId(log.args.tableId), }) ) ) @@ -98,7 +87,7 @@ export async function sqliteStorage({ (table) => table.address === getAddress(log.address) && table.tableId === log.args.tableId ); if (!table) { - const tableId = hexToTableId(log.args.tableId); + const tableId = hexToResourceId(log.args.tableId); debug(`table ${tableId.namespace}:${tableId.name} not found, skipping log`, log); continue; } diff --git a/packages/store/gas-report.json b/packages/store/gas-report.json index 765b65cbf3..6f8ba5f968 100644 --- a/packages/store/gas-report.json +++ b/packages/store/gas-report.json @@ -351,7 +351,7 @@ "file": "test/KeyEncoding.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "register KeyEncoding table", - "gasUsed": 687778 + "gasUsed": 720082 }, { "file": "test/Mixed.t.sol", @@ -363,19 +363,19 @@ "file": "test/Mixed.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "register Mixed table", - "gasUsed": 549596 + "gasUsed": 581907 }, { "file": "test/Mixed.t.sol", "test": "testSetAndGet", "name": "set record in Mixed", - "gasUsed": 103898 + "gasUsed": 103942 }, { "file": "test/Mixed.t.sol", "test": "testSetAndGet", "name": "get record from Mixed", - "gasUsed": 7015 + "gasUsed": 7025 }, { "file": "test/PackedCounter.t.sol", @@ -407,6 +407,18 @@ "name": "set value at index of PackedCounter", "gasUsed": 286 }, + { + "file": "test/ResourceId.t.sol", + "test": "testEncode", + "name": "encode table ID with name and type", + "gasUsed": 188 + }, + { + "file": "test/ResourceId.t.sol", + "test": "testGetType", + "name": "get type from a table ID", + "gasUsed": 4 + }, { "file": "test/Schema.t.sol", "test": "testEncodeDecodeSchema", @@ -609,31 +621,31 @@ "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (cold, 1 slot, 1 uint32 item)", - "gasUsed": 19408 + "gasUsed": 19440 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (warm, 1 slot, 1 uint32 item)", - "gasUsed": 13418 + "gasUsed": 13450 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (cold, 2 slots, 10 uint32 items)", - "gasUsed": 17176 + "gasUsed": 17208 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (warm, 2 slots, 10 uint32 items)", - "gasUsed": 13187 + "gasUsed": 13219 }, { "file": "test/StoreCoreGas.t.sol", "test": "testAccessEmptyData", "name": "access non-existing record", - "gasUsed": 7041 + "gasUsed": 7042 }, { "file": "test/StoreCoreGas.t.sol", @@ -645,7 +657,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", @@ -657,115 +669,115 @@ "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": 6678 + "gasUsed": 6700 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHasFieldLayout", "name": "Check for existence of table (existent)", - "gasUsed": 1260 + "gasUsed": 1249 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHasFieldLayout", "name": "check for existence of table (non-existent)", - "gasUsed": 3261 + "gasUsed": 3249 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "register subscriber", - "gasUsed": 58654 + "gasUsed": 58696 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set record on table with subscriber", - "gasUsed": 71024 + "gasUsed": 71265 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set static field on table with subscriber", - "gasUsed": 20506 + "gasUsed": 20746 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "delete record on table with subscriber", - "gasUsed": 16373 + "gasUsed": 16736 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "register subscriber", - "gasUsed": 58654 + "gasUsed": 58696 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) record on table with subscriber", - "gasUsed": 164146 + "gasUsed": 164386 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) field on table with subscriber", - "gasUsed": 24273 + "gasUsed": 24513 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "delete (dynamic) record on table with subscriber", - "gasUsed": 17358 + "gasUsed": 17721 }, { "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (1 slot, 1 uint32 item)", - "gasUsed": 10241 + "gasUsed": 10264 }, { "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (2 slots, 10 uint32 items)", - "gasUsed": 32918 + "gasUsed": 32940 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "StoreCore: register table", - "gasUsed": 609747 + "gasUsed": 642028 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "StoreCore: get field layout (warm)", - "gasUsed": 1272 + "gasUsed": 1293 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "StoreCore: get value schema (warm)", - "gasUsed": 1782 + "gasUsed": 1804 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "StoreCore: get key schema (warm)", - "gasUsed": 2816 + "gasUsed": 2827 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetDynamicData", "name": "set complex record with dynamic data (4 slots)", - "gasUsed": 101818 + "gasUsed": 101840 }, { "file": "test/StoreCoreGas.t.sol", @@ -783,7 +795,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", @@ -795,19 +807,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": 31579 + "gasUsed": 31601 }, { "file": "test/StoreCoreGas.t.sol", @@ -819,19 +831,19 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set static field (overlap 2 slot)", - "gasUsed": 30219 + "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": 53942 + "gasUsed": 53966 }, { "file": "test/StoreCoreGas.t.sol", @@ -843,19 +855,19 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set dynamic field (1 slot, second dynamic field)", - "gasUsed": 32169 + "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", "test": "testSetAndGetStaticData", "name": "set static record (1 slot)", - "gasUsed": 32124 + "gasUsed": 32145 }, { "file": "test/StoreCoreGas.t.sol", @@ -867,25 +879,25 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetStaticDataSpanningWords", "name": "set static record (2 slots)", - "gasUsed": 54628 + "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": 9585 + "gasUsed": 9608 }, { "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "push to field (2 slots, 6 uint64 items)", - "gasUsed": 10022 + "gasUsed": 10045 }, { "file": "test/StoreHook.t.sol", @@ -927,121 +939,121 @@ "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: set field", - "gasUsed": 57008 + "gasUsed": 57052 }, { "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: get field (warm)", - "gasUsed": 2881 + "gasUsed": 2902 }, { "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: push 1 element", - "gasUsed": 33292 + "gasUsed": 33337 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testOneSlot", "name": "StoreHooks: set field with one elements (cold)", - "gasUsed": 59012 + "gasUsed": 59054 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: set field (cold)", - "gasUsed": 59012 + "gasUsed": 59054 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: get field (warm)", - "gasUsed": 2883 + "gasUsed": 2904 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: push 1 element (cold)", - "gasUsed": 13389 + "gasUsed": 13431 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: pop 1 element (warm)", - "gasUsed": 10686 + "gasUsed": 10739 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: push 1 element (warm)", - "gasUsed": 11411 + "gasUsed": 11453 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: update 1 element (warm)", - "gasUsed": 30626 + "gasUsed": 30668 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: delete record (warm)", - "gasUsed": 7086 + "gasUsed": 7128 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: set field (warm)", - "gasUsed": 31173 + "gasUsed": 31215 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testThreeSlots", "name": "StoreHooks: set field with three elements (cold)", - "gasUsed": 81703 + "gasUsed": 81745 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTwoSlots", "name": "StoreHooks: set field with two elements (cold)", - "gasUsed": 81615 + "gasUsed": 81657 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testDelete", "name": "StoreHooks: delete record (cold)", - "gasUsed": 15954 + "gasUsed": 15996 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testGet", "name": "StoreHooks: get field (cold)", - "gasUsed": 8880 + "gasUsed": 8901 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testGetItem", "name": "StoreHooks: get 1 element (cold)", - "gasUsed": 6521 + "gasUsed": 6542 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testLength", "name": "StoreHooks: get length (cold)", - "gasUsed": 5840 + "gasUsed": 5861 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testPop", "name": "StoreHooks: pop 1 element (cold)", - "gasUsed": 19126 + "gasUsed": 19168 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testUpdate", "name": "StoreHooks: update 1 element (cold)", - "gasUsed": 21069 + "gasUsed": 21111 }, { "file": "test/tightcoder/DecodeSlice.t.sol", @@ -1095,18 +1107,18 @@ "file": "test/Vector2.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "register Vector2 field layout", - "gasUsed": 411019 + "gasUsed": 443350 }, { "file": "test/Vector2.t.sol", "test": "testSetAndGet", "name": "set Vector2 record", - "gasUsed": 33027 + "gasUsed": 33069 }, { "file": "test/Vector2.t.sol", "test": "testSetAndGet", "name": "get Vector2 record", - "gasUsed": 2505 + "gasUsed": 2514 } ] diff --git a/packages/store/mud.config.ts b/packages/store/mud.config.ts index 814ab527b9..e871948207 100644 --- a/packages/store/mud.config.ts +++ b/packages/store/mud.config.ts @@ -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[]", diff --git a/packages/store/src/Hook.sol b/packages/store/src/Hook.sol index d7511d4dc2..bba92c89aa 100644 --- a/packages/store/src/Hook.sol +++ b/packages/store/src/Hook.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { Hooks } from "./codegen/tables/Hooks.sol"; +import { ResourceId } from "./ResourceId.sol"; // 20 bytes address, 1 byte bitmap of enabled hooks type Hook is bytes21; @@ -20,8 +21,12 @@ library HookLib { /** * Filter the given hook from the hook list at the given key in the given hook table */ - function filterListByAddress(bytes32 hookTableId, bytes32 key, address hookAddressToRemove) internal { - bytes21[] memory currentHooks = Hooks._get(hookTableId, key); + function filterListByAddress( + ResourceId hookTableId, + ResourceId tableWithHooks, + address hookAddressToRemove + ) internal { + bytes21[] memory currentHooks = Hooks._get(hookTableId, ResourceId.unwrap(tableWithHooks)); // Initialize the new hooks array with the same length because we don't know if the hook is registered yet bytes21[] memory newHooks = new bytes21[](currentHooks.length); @@ -44,7 +49,7 @@ library HookLib { } // Set the new hooks table - Hooks._set(hookTableId, key, newHooks); + Hooks._set(hookTableId, ResourceId.unwrap(tableWithHooks), newHooks); } } diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index 0e8546acaf..f73f4f4c46 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -6,23 +6,24 @@ import { PackedCounter } from "./PackedCounter.sol"; import { FieldLayout } from "./FieldLayout.sol"; import { Schema } from "./Schema.sol"; import { IStoreHook } from "./IStoreHook.sol"; +import { ResourceId } from "./ResourceId.sol"; interface IStoreRead { event HelloStore(bytes32 indexed storeVersion); function storeVersion() external view returns (bytes32); - function getFieldLayout(bytes32 tableId) external view returns (FieldLayout fieldLayout); + function getFieldLayout(ResourceId tableId) external view returns (FieldLayout fieldLayout); - function getValueSchema(bytes32 tableId) external view returns (Schema valueSchema); + function getValueSchema(ResourceId tableId) external view returns (Schema valueSchema); - function getKeySchema(bytes32 tableId) external view returns (Schema keySchema); + function getKeySchema(ResourceId tableId) external view returns (Schema keySchema); /** * Get full record (all fields, static and dynamic data) for the given tableId and key tuple, with the given value field layout */ function getRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, FieldLayout fieldLayout ) external view returns (bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData); @@ -31,7 +32,7 @@ interface IStoreRead { * Get a single field from the given tableId and key tuple, with the given value field layout */ function getField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -43,7 +44,7 @@ interface IStoreRead { * Consumers are expected to truncate the returned value as needed. */ function getStaticField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -54,7 +55,7 @@ interface IStoreRead { * (Dynamic field index = field index - number of static fields) */ function getDynamicField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex ) external view returns (bytes memory); @@ -63,7 +64,7 @@ interface IStoreRead { * Get the byte length of a single field from the given tableId and key tuple, with the given value field layout */ function getFieldLength( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -74,7 +75,7 @@ interface IStoreRead { * The slice is unchecked and will return invalid data if `start`:`end` overflow. */ function getFieldSlice( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout, @@ -85,32 +86,32 @@ interface IStoreRead { interface IStoreWrite { event StoreSetRecord( - bytes32 indexed tableId, + ResourceId indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData ); event StoreSpliceStaticData( - bytes32 indexed tableId, + ResourceId indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data ); event StoreSpliceDynamicData( - bytes32 indexed tableId, + ResourceId indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths ); - event StoreDeleteRecord(bytes32 indexed tableId, bytes32[] keyTuple); + event StoreDeleteRecord(ResourceId indexed tableId, bytes32[] keyTuple); // Set full record (including full dynamic data) function setRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, bytes calldata staticData, PackedCounter encodedLengths, @@ -120,7 +121,7 @@ interface IStoreWrite { // Splice data in the static part of the record function spliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint48 start, uint40 deleteCount, @@ -129,7 +130,7 @@ interface IStoreWrite { // Splice data in the dynamic part of the record function spliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -139,7 +140,7 @@ interface IStoreWrite { // Set partial data at field index function setField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, bytes calldata data, @@ -148,7 +149,7 @@ interface IStoreWrite { // Push encoded items to the dynamic field at field index function pushToField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, bytes calldata dataToPush, @@ -157,7 +158,7 @@ interface IStoreWrite { // Pop byte length from the dynamic field at field index function popFromField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, uint256 byteLengthToPop, @@ -166,7 +167,7 @@ interface IStoreWrite { // Change encoded items within the dynamic field at field index function updateInField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, uint256 startByteIndex, @@ -175,12 +176,12 @@ interface IStoreWrite { ) external; // Set full record (including full dynamic data) - function deleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) external; + function deleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) external; } interface IStoreEphemeral { event StoreEphemeralRecord( - bytes32 indexed tableId, + ResourceId indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, @@ -189,7 +190,7 @@ interface IStoreEphemeral { // Emit the ephemeral event without modifying storage function emitEphemeralRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, bytes calldata staticData, PackedCounter encodedLengths, @@ -214,7 +215,7 @@ interface IStoreData is IStoreRead, IStoreWrite { */ interface IStoreRegistration { function registerTable( - bytes32 tableId, + ResourceId tableId, FieldLayout fieldLayout, Schema keySchema, Schema valueSchema, @@ -223,10 +224,10 @@ interface IStoreRegistration { ) external; // Register hook to be called when a record or field is set or deleted - function registerStoreHook(bytes32 tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) external; + function registerStoreHook(ResourceId tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) external; // Unregister a hook for the given tableId - function unregisterStoreHook(bytes32 tableId, IStoreHook hookAddress) external; + function unregisterStoreHook(ResourceId tableId, IStoreHook hookAddress) external; } interface IStore is IStoreData, IStoreRegistration, IStoreEphemeral, IStoreErrors {} diff --git a/packages/store/src/IStoreErrors.sol b/packages/store/src/IStoreErrors.sol index 5987a1d408..1b42a84107 100644 --- a/packages/store/src/IStoreErrors.sol +++ b/packages/store/src/IStoreErrors.sol @@ -1,10 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; +import { ResourceId } from "./ResourceId.sol"; + interface IStoreErrors { // Errors include a stringified version of the tableId for easier debugging if cleartext tableIds are used - error StoreCore_TableAlreadyExists(bytes32 tableId, string tableIdString); - error StoreCore_TableNotFound(bytes32 tableId, string tableIdString); + error StoreCore_TableAlreadyExists(ResourceId tableId, string tableIdString); + error StoreCore_TableNotFound(ResourceId tableId, string tableIdString); + error StoreCore_InvalidResourceType(bytes2 expected, ResourceId resourceId, string resourceIdString); error StoreCore_NotImplemented(); error StoreCore_NotDynamicField(); diff --git a/packages/store/src/IStoreHook.sol b/packages/store/src/IStoreHook.sol index a2be6d40f0..271e07ac97 100644 --- a/packages/store/src/IStoreHook.sol +++ b/packages/store/src/IStoreHook.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.0; import { FieldLayout } from "./FieldLayout.sol"; import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; import { PackedCounter } from "./PackedCounter.sol"; +import { ResourceId } from "./ResourceId.sol"; // ERC-165 Interface ID (see https://eips.ethereum.org/EIPS/eip-165) bytes4 constant STORE_HOOK_INTERFACE_ID = IStoreHook.onBeforeSetRecord.selector ^ @@ -20,7 +21,7 @@ interface IStoreHook is IERC165 { error StoreHook_NotImplemented(); function onBeforeSetRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, @@ -29,7 +30,7 @@ interface IStoreHook is IERC165 { ) external; function onAfterSetRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, @@ -38,7 +39,7 @@ interface IStoreHook is IERC165 { ) external; function onBeforeSpliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint48 start, uint40 deleteCount, @@ -46,7 +47,7 @@ interface IStoreHook is IERC165 { ) external; function onAfterSpliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint48 start, uint40 deleteCount, @@ -54,7 +55,7 @@ interface IStoreHook is IERC165 { ) external; function onBeforeSpliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -64,7 +65,7 @@ interface IStoreHook is IERC165 { ) external; function onAfterSpliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -73,7 +74,7 @@ interface IStoreHook is IERC165 { PackedCounter encodedLengths ) external; - function onBeforeDeleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) external; + function onBeforeDeleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) external; - function onAfterDeleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) external; + function onAfterDeleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) external; } diff --git a/packages/store/src/ResourceId.sol b/packages/store/src/ResourceId.sol new file mode 100644 index 0000000000..20dec4c6b8 --- /dev/null +++ b/packages/store/src/ResourceId.sol @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +type ResourceId is bytes32; + +uint256 constant TYPE_BYTES = 2; +uint256 constant NAME_BYTES = 32 - TYPE_BYTES; +uint256 constant BYTES_TO_BITS = 8; + +bytes32 constant TYPE_MASK = bytes32(hex"ffff"); + +library ResourceIdLib { + function encode(bytes2 typeId, bytes30 name) internal pure returns (ResourceId) { + return ResourceId.wrap(bytes32(typeId) | (bytes32(name) >> (TYPE_BYTES * BYTES_TO_BITS))); + } +} + +library ResourceIdInstance { + function getType(ResourceId resourceId) internal pure returns (bytes2) { + return bytes2(ResourceId.unwrap(resourceId)); + } +} diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index 7fae2a9f36..d4683aaa10 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -9,12 +9,14 @@ import { FieldLayout, FieldLayoutLib } from "./FieldLayout.sol"; import { Schema, SchemaLib } from "./Schema.sol"; import { PackedCounter } from "./PackedCounter.sol"; import { Slice, SliceLib } from "./Slice.sol"; -import { StoreHooks, Tables, StoreHooksTableId } from "./codegen/index.sol"; +import { StoreHooks, Tables, ResourceIds, StoreHooksTableId } from "./codegen/index.sol"; import { IStoreErrors } from "./IStoreErrors.sol"; import { IStoreHook } from "./IStoreHook.sol"; import { StoreSwitch } from "./StoreSwitch.sol"; import { Hook, HookLib } from "./Hook.sol"; import { BEFORE_SET_RECORD, AFTER_SET_RECORD, BEFORE_SPLICE_STATIC_DATA, AFTER_SPLICE_STATIC_DATA, BEFORE_SPLICE_DYNAMIC_DATA, AFTER_SPLICE_DYNAMIC_DATA, BEFORE_DELETE_RECORD, AFTER_DELETE_RECORD } from "./storeHookTypes.sol"; +import { ResourceId, ResourceIdInstance } from "./ResourceId.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "./storeResourceTypes.sol"; /** * StoreCore includes implementations for all IStore methods. @@ -22,32 +24,34 @@ import { BEFORE_SET_RECORD, AFTER_SET_RECORD, BEFORE_SPLICE_STATIC_DATA, AFTER_S * It's split into a separate library to make it clear that it's not intended to be outside StoreCore. */ library StoreCore { + using ResourceIdInstance for ResourceId; + event HelloStore(bytes32 indexed version); event StoreSetRecord( - bytes32 indexed tableId, + ResourceId indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData ); event StoreSpliceStaticData( - bytes32 indexed tableId, + ResourceId indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data ); event StoreSpliceDynamicData( - bytes32 indexed tableId, + ResourceId indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths ); - event StoreDeleteRecord(bytes32 indexed tableId, bytes32[] keyTuple); + event StoreDeleteRecord(ResourceId indexed tableId, bytes32[] keyTuple); event StoreEphemeralRecord( - bytes32 indexed tableId, + ResourceId indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, @@ -76,6 +80,7 @@ library StoreCore { // Register core tables Tables.register(); StoreHooks.register(); + ResourceIds.register(); } /************************************************************************ @@ -87,8 +92,8 @@ library StoreCore { /** * Get the field layout for the given tableId */ - function getFieldLayout(bytes32 tableId) internal view returns (FieldLayout fieldLayout) { - fieldLayout = FieldLayout.wrap(Tables._getFieldLayout(tableId)); + function getFieldLayout(ResourceId tableId) internal view returns (FieldLayout fieldLayout) { + fieldLayout = FieldLayout.wrap(Tables._getFieldLayout(ResourceId.unwrap(tableId))); if (fieldLayout.isEmpty()) { revert IStoreErrors.StoreCore_TableNotFound(tableId, string(abi.encodePacked(tableId))); } @@ -97,10 +102,10 @@ library StoreCore { /** * Get the key schema for the given tableId */ - function getKeySchema(bytes32 tableId) internal view returns (Schema keySchema) { - keySchema = Schema.wrap(Tables._getKeySchema(tableId)); + function getKeySchema(ResourceId tableId) internal view returns (Schema keySchema) { + keySchema = Schema.wrap(Tables._getKeySchema(ResourceId.unwrap(tableId))); // key schemas can be empty for singleton tables, so we can't depend on key schema for table check - if (!hasTable(tableId)) { + if (!ResourceIds._getExists(ResourceId.unwrap(tableId))) { revert IStoreErrors.StoreCore_TableNotFound(tableId, string(abi.encodePacked(tableId))); } } @@ -108,31 +113,29 @@ library StoreCore { /** * Get the schema for the given tableId */ - function getValueSchema(bytes32 tableId) internal view returns (Schema valueSchema) { - valueSchema = Schema.wrap(Tables._getValueSchema(tableId)); + function getValueSchema(ResourceId tableId) internal view returns (Schema valueSchema) { + valueSchema = Schema.wrap(Tables._getValueSchema(ResourceId.unwrap(tableId))); if (valueSchema.isEmpty()) { revert IStoreErrors.StoreCore_TableNotFound(tableId, string(abi.encodePacked(tableId))); } } - /** - * Check if a table with the given tableId exists - */ - function hasTable(bytes32 tableId) internal view returns (bool) { - return Tables._getFieldLayout(tableId) != bytes32(0); - } - /** * Register a new table the given config */ function registerTable( - bytes32 tableId, + ResourceId tableId, FieldLayout fieldLayout, Schema keySchema, Schema valueSchema, string[] memory keyNames, string[] memory fieldNames ) internal { + // Verify the table ID is of type RESOURCE_TABLE + if (tableId.getType() != RESOURCE_TABLE && tableId.getType() != RESOURCE_OFFCHAIN_TABLE) { + revert IStoreErrors.StoreCore_InvalidResourceType(RESOURCE_TABLE, tableId, string(abi.encodePacked(tableId))); + } + // Verify the field layout is valid fieldLayout.validate({ allowEmpty: false }); @@ -155,20 +158,23 @@ library StoreCore { revert IStoreErrors.StoreCore_InvalidValueSchemaLength(fieldLayout.numFields(), valueSchema.numFields()); } - // Verify the field layout doesn't exist yet - if (hasTable(tableId)) { + // Verify there is no resource with this ID yet + if (ResourceIds._getExists(ResourceId.unwrap(tableId))) { revert IStoreErrors.StoreCore_TableAlreadyExists(tableId, string(abi.encodePacked(tableId))); } // Register the table metadata Tables._set( - tableId, + ResourceId.unwrap(tableId), FieldLayout.unwrap(fieldLayout), Schema.unwrap(keySchema), Schema.unwrap(valueSchema), abi.encode(keyNames), abi.encode(fieldNames) ); + + // Register the table ID + ResourceIds._setExists(ResourceId.unwrap(tableId), true); } /************************************************************************ @@ -180,14 +186,14 @@ library StoreCore { /* * Register hooks to be called when a record or field is set or deleted */ - function registerStoreHook(bytes32 tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) internal { - StoreHooks.push(tableId, Hook.unwrap(HookLib.encode(address(hookAddress), enabledHooksBitmap))); + function registerStoreHook(ResourceId tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) internal { + StoreHooks.push(ResourceId.unwrap(tableId), Hook.unwrap(HookLib.encode(address(hookAddress), enabledHooksBitmap))); } /** * Unregister a hook from the given tableId */ - function unregisterStoreHook(bytes32 tableId, IStoreHook hookAddress) internal { + function unregisterStoreHook(ResourceId tableId, IStoreHook hookAddress) internal { HookLib.filterListByAddress(StoreHooksTableId, tableId, address(hookAddress)); } @@ -201,7 +207,7 @@ library StoreCore { * Set full data record for the given table ID and key tuple and field layout */ function setRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, @@ -218,7 +224,7 @@ library StoreCore { emit StoreSetRecord(tableId, keyTuple, staticData, encodedLengths.unwrap(), dynamicData); // Call onBeforeSetRecord hooks (before actually modifying the state, so observers have access to the previous state if needed) - bytes21[] memory hooks = StoreHooks._get(tableId); + bytes21[] memory hooks = StoreHooks._get(ResourceId.unwrap(tableId)); for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(BEFORE_SET_RECORD)) { @@ -288,7 +294,7 @@ library StoreCore { } function spliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint48 start, uint40 deleteCount, @@ -297,7 +303,7 @@ library StoreCore { uint256 location = StoreCoreInternal._getStaticDataLocation(tableId, keyTuple); // Call onBeforeSpliceStaticData hooks (before actually modifying the state, so observers have access to the previous state if needed) - bytes21[] memory hooks = StoreHooks._get(tableId); + bytes21[] memory hooks = StoreHooks._get(ResourceId.unwrap(tableId)); for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(BEFORE_SPLICE_STATIC_DATA)) { @@ -339,7 +345,7 @@ library StoreCore { } function spliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, // need this to compute the dynamic data location uint40 startWithinField, @@ -361,7 +367,7 @@ library StoreCore { * Set data for a field in a table with the given tableId, key tuple and value field layout */ function setField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, bytes memory data, @@ -375,7 +381,7 @@ library StoreCore { } function setStaticField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout, uint8 fieldIndex, @@ -391,7 +397,7 @@ library StoreCore { } function setDynamicField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, bytes memory data @@ -414,12 +420,12 @@ library StoreCore { /** * Delete a record for the given tableId, key tuple and value field layout */ - function deleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) internal { + function deleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) internal { // Emit event to notify indexers emit StoreDeleteRecord(tableId, keyTuple); // Call onBeforeDeleteRecord hooks (before actually modifying the state, so observers have access to the previous state if needed) - bytes21[] memory hooks = StoreHooks._get(tableId); + bytes21[] memory hooks = StoreHooks._get(ResourceId.unwrap(tableId)); for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(BEFORE_DELETE_RECORD)) { @@ -450,7 +456,7 @@ library StoreCore { * Push data to a field in a table with the given tableId, keyTuple tuple and value field layout */ function pushToField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, bytes memory dataToPush, @@ -467,7 +473,7 @@ library StoreCore { * Pop data from a field in a table with the given tableId, key tuple and value field layout */ function popFromField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, uint256 byteLengthToPop, @@ -484,7 +490,7 @@ library StoreCore { * Update data in a field in a table with the given tableId, key tuple and value field layout */ function updateInField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, uint256 startByteIndex, @@ -514,7 +520,7 @@ library StoreCore { * Emit the ephemeral event without modifying storage for the full data of the given table ID and key tuple */ function emitEphemeralRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, @@ -538,7 +544,7 @@ library StoreCore { * Get full record (all fields, static and dynamic data) for the given table ID and key tuple, with the given value field layout */ function getRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout ) internal view returns (bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData) { @@ -572,7 +578,7 @@ library StoreCore { * Get a single field from the given table ID and key tuple, with the given value field layout */ function getField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -590,7 +596,7 @@ library StoreCore { * Consumers are expected to truncate the returned value as needed. */ function getStaticField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -609,7 +615,7 @@ library StoreCore { * Get a single dynamic field from the given table ID and key tuple, with the given value field layout */ function getDynamicField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex ) internal view returns (bytes memory) { @@ -627,7 +633,7 @@ library StoreCore { * Get the byte length of a single field from the given table ID and key tuple, with the given value field layout */ function getFieldLength( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -647,7 +653,7 @@ library StoreCore { * The slice is unchecked and will return invalid data if `start`:`end` overflow. */ function getFieldSlice( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout, @@ -679,7 +685,7 @@ library StoreCoreInternal { ************************************************************************/ function _spliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -709,7 +715,7 @@ library StoreCoreInternal { PackedCounter updatedEncodedLengths = previousEncodedLengths.setAtIndex(dynamicFieldIndex, updatedFieldLength); // Call onBeforeSpliceDynamicData hooks (before actually modifying the state, so observers have access to the previous state if needed) - bytes21[] memory hooks = StoreHooks._get(tableId); + bytes21[] memory hooks = StoreHooks._get(ResourceId.unwrap(tableId)); for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(BEFORE_SPLICE_DYNAMIC_DATA)) { @@ -765,7 +771,7 @@ library StoreCoreInternal { } function _pushToDynamicField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout, uint8 fieldIndex, @@ -790,7 +796,7 @@ library StoreCoreInternal { } function _popFromDynamicField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout, uint8 fieldIndex, @@ -815,7 +821,7 @@ library StoreCoreInternal { } function _setDynamicFieldItem( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout, uint8 fieldIndex, @@ -843,7 +849,7 @@ library StoreCoreInternal { * Get full static data for the given table ID and key tuple, with the given static length */ function _getStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint256 length ) internal view returns (bytes memory) { @@ -859,7 +865,7 @@ library StoreCoreInternal { * Returns dynamic bytes memory in the size of the field. */ function _getStaticFieldBytes( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -905,7 +911,7 @@ library StoreCoreInternal { /** * Compute the storage location based on tableId id and index tuple */ - function _getStaticDataLocation(bytes32 tableId, bytes32[] memory keyTuple) internal pure returns (uint256) { + function _getStaticDataLocation(ResourceId tableId, bytes32[] memory keyTuple) internal pure returns (uint256) { return uint256(SLOT ^ keccak256(abi.encodePacked(tableId, keyTuple))); } @@ -928,7 +934,7 @@ library StoreCoreInternal { * Compute the storage location based on tableId id and index tuple */ function _getDynamicDataLocation( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex ) internal pure returns (uint256) { @@ -938,7 +944,10 @@ library StoreCoreInternal { /** * Compute the storage location for the length of the dynamic data */ - function _getDynamicDataLengthLocation(bytes32 tableId, bytes32[] memory keyTuple) internal pure returns (uint256) { + function _getDynamicDataLengthLocation( + ResourceId tableId, + bytes32[] memory keyTuple + ) internal pure returns (uint256) { return uint256(DYNAMIC_DATA_LENGTH_SLOT ^ keccak256(abi.encodePacked(tableId, keyTuple))); } @@ -946,7 +955,7 @@ library StoreCoreInternal { * Load the encoded dynamic data length from storage for the given table ID and key tuple */ function _loadEncodedDynamicDataLength( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple ) internal view returns (PackedCounter) { // Load dynamic data length from storage diff --git a/packages/store/src/StoreHook.sol b/packages/store/src/StoreHook.sol index ca854c06fa..19db392bb7 100644 --- a/packages/store/src/StoreHook.sol +++ b/packages/store/src/StoreHook.sol @@ -5,6 +5,7 @@ import { IStoreHook, STORE_HOOK_INTERFACE_ID } from "./IStoreHook.sol"; import { ERC165_INTERFACE_ID } from "./IERC165.sol"; import { PackedCounter } from "./PackedCounter.sol"; import { FieldLayout } from "./FieldLayout.sol"; +import { ResourceId } from "./ResourceId.sol"; abstract contract StoreHook is IStoreHook { // ERC-165 supportsInterface (see https://eips.ethereum.org/EIPS/eip-165) @@ -13,7 +14,7 @@ abstract contract StoreHook is IStoreHook { } function onBeforeSetRecord( - bytes32, + ResourceId, bytes32[] memory, bytes memory, PackedCounter, @@ -24,7 +25,7 @@ abstract contract StoreHook is IStoreHook { } function onAfterSetRecord( - bytes32, + ResourceId, bytes32[] memory, bytes memory, PackedCounter, @@ -34,16 +35,16 @@ abstract contract StoreHook is IStoreHook { revert StoreHook_NotImplemented(); } - function onBeforeSpliceStaticData(bytes32, bytes32[] memory, uint48, uint40, bytes memory) public virtual { + function onBeforeSpliceStaticData(ResourceId, bytes32[] memory, uint48, uint40, bytes memory) public virtual { revert StoreHook_NotImplemented(); } - function onAfterSpliceStaticData(bytes32, bytes32[] memory, uint48, uint40, bytes memory) public virtual { + function onAfterSpliceStaticData(ResourceId, bytes32[] memory, uint48, uint40, bytes memory) public virtual { revert StoreHook_NotImplemented(); } function onBeforeSpliceDynamicData( - bytes32, + ResourceId, bytes32[] memory, uint8, uint40, @@ -55,7 +56,7 @@ abstract contract StoreHook is IStoreHook { } function onAfterSpliceDynamicData( - bytes32, + ResourceId, bytes32[] memory, uint8, uint40, @@ -66,11 +67,11 @@ abstract contract StoreHook is IStoreHook { revert StoreHook_NotImplemented(); } - function onBeforeDeleteRecord(bytes32, bytes32[] memory, FieldLayout) public virtual { + function onBeforeDeleteRecord(ResourceId, bytes32[] memory, FieldLayout) public virtual { revert StoreHook_NotImplemented(); } - function onAfterDeleteRecord(bytes32, bytes32[] memory, FieldLayout) public virtual { + function onAfterDeleteRecord(ResourceId, bytes32[] memory, FieldLayout) public virtual { revert StoreHook_NotImplemented(); } } diff --git a/packages/store/src/StoreRead.sol b/packages/store/src/StoreRead.sol index 5d85bef3e6..f4925e77eb 100644 --- a/packages/store/src/StoreRead.sol +++ b/packages/store/src/StoreRead.sol @@ -7,26 +7,27 @@ import { StoreCore } from "./StoreCore.sol"; import { FieldLayout } from "./FieldLayout.sol"; import { Schema } from "./Schema.sol"; import { PackedCounter } from "./PackedCounter.sol"; +import { ResourceId } from "./ResourceId.sol"; contract StoreRead is IStoreRead { function storeVersion() public pure returns (bytes32) { return STORE_VERSION; } - function getFieldLayout(bytes32 tableId) public view virtual returns (FieldLayout fieldLayout) { + function getFieldLayout(ResourceId tableId) public view virtual returns (FieldLayout fieldLayout) { fieldLayout = StoreCore.getFieldLayout(tableId); } - function getValueSchema(bytes32 tableId) public view virtual returns (Schema valueSchema) { + function getValueSchema(ResourceId tableId) public view virtual returns (Schema valueSchema) { valueSchema = StoreCore.getValueSchema(tableId); } - function getKeySchema(bytes32 tableId) public view virtual returns (Schema keySchema) { + function getKeySchema(ResourceId tableId) public view virtual returns (Schema keySchema) { keySchema = StoreCore.getKeySchema(tableId); } function getRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, FieldLayout fieldLayout ) public view virtual returns (bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData) { @@ -34,7 +35,7 @@ contract StoreRead is IStoreRead { } function getField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -43,7 +44,7 @@ contract StoreRead is IStoreRead { } function getStaticField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -52,7 +53,7 @@ contract StoreRead is IStoreRead { } function getDynamicField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 dynamicFieldIndex ) public view virtual returns (bytes memory data) { @@ -60,7 +61,7 @@ contract StoreRead is IStoreRead { } function getFieldLength( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -69,7 +70,7 @@ contract StoreRead is IStoreRead { } function getFieldSlice( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout, diff --git a/packages/store/src/StoreSwitch.sol b/packages/store/src/StoreSwitch.sol index 396b246010..caa043ebfe 100644 --- a/packages/store/src/StoreSwitch.sol +++ b/packages/store/src/StoreSwitch.sol @@ -8,6 +8,7 @@ import { StoreCore } from "./StoreCore.sol"; import { Schema } from "./Schema.sol"; import { FieldLayout } from "./FieldLayout.sol"; import { PackedCounter } from "./PackedCounter.sol"; +import { ResourceId } from "./ResourceId.sol"; /** * Call IStore functions on self or msg.sender, depending on whether the call is a delegatecall or regular call. @@ -48,7 +49,7 @@ library StoreSwitch { _layout().storeAddress = _storeAddress; } - function registerStoreHook(bytes32 tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) internal { + function registerStoreHook(ResourceId tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { StoreCore.registerStoreHook(tableId, hookAddress, enabledHooksBitmap); @@ -57,7 +58,7 @@ library StoreSwitch { } } - function unregisterStoreHook(bytes32 tableId, IStoreHook hookAddress) internal { + function unregisterStoreHook(ResourceId tableId, IStoreHook hookAddress) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { StoreCore.unregisterStoreHook(tableId, hookAddress); @@ -66,7 +67,7 @@ library StoreSwitch { } } - function getFieldLayout(bytes32 tableId) internal view returns (FieldLayout fieldLayout) { + function getFieldLayout(ResourceId tableId) internal view returns (FieldLayout fieldLayout) { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { fieldLayout = StoreCore.getFieldLayout(tableId); @@ -75,7 +76,7 @@ library StoreSwitch { } } - function getValueSchema(bytes32 tableId) internal view returns (Schema valueSchema) { + function getValueSchema(ResourceId tableId) internal view returns (Schema valueSchema) { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { valueSchema = StoreCore.getValueSchema(tableId); @@ -84,7 +85,7 @@ library StoreSwitch { } } - function getKeySchema(bytes32 tableId) internal view returns (Schema keySchema) { + function getKeySchema(ResourceId tableId) internal view returns (Schema keySchema) { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { keySchema = StoreCore.getKeySchema(tableId); @@ -94,7 +95,7 @@ library StoreSwitch { } function registerTable( - bytes32 tableId, + ResourceId tableId, FieldLayout fieldLayout, Schema keySchema, Schema valueSchema, @@ -110,7 +111,7 @@ library StoreSwitch { } function setRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, @@ -126,7 +127,7 @@ library StoreSwitch { } function spliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint48 start, uint40 deleteCount, @@ -141,7 +142,7 @@ library StoreSwitch { } function spliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -164,7 +165,7 @@ library StoreSwitch { } function setField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, bytes memory data, @@ -179,7 +180,7 @@ library StoreSwitch { } function pushToField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, bytes memory dataToPush, @@ -194,7 +195,7 @@ library StoreSwitch { } function popFromField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, uint256 byteLengthToPop, @@ -209,7 +210,7 @@ library StoreSwitch { } function updateInField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, uint256 startByteIndex, @@ -224,7 +225,7 @@ library StoreSwitch { } } - function deleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) internal { + function deleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { StoreCore.deleteRecord(tableId, keyTuple, fieldLayout); @@ -234,7 +235,7 @@ library StoreSwitch { } function emitEphemeralRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, @@ -257,7 +258,7 @@ library StoreSwitch { } function getRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout ) internal view returns (bytes memory, PackedCounter, bytes memory) { @@ -270,7 +271,7 @@ library StoreSwitch { } function getField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -284,7 +285,7 @@ library StoreSwitch { } function getStaticField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -298,7 +299,7 @@ library StoreSwitch { } function getDynamicField( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex ) internal view returns (bytes memory) { @@ -311,7 +312,7 @@ library StoreSwitch { } function getFieldLength( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout @@ -325,7 +326,7 @@ library StoreSwitch { } function getFieldSlice( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 fieldIndex, FieldLayout fieldLayout, diff --git a/packages/store/src/codegen/index.sol b/packages/store/src/codegen/index.sol index 64381605a6..7e033ae735 100644 --- a/packages/store/src/codegen/index.sol +++ b/packages/store/src/codegen/index.sol @@ -6,6 +6,7 @@ pragma solidity >=0.8.0; import { StoreHooks, StoreHooksTableId } from "./tables/StoreHooks.sol"; import { Callbacks, CallbacksTableId } from "./tables/Callbacks.sol"; import { Tables, TablesData, TablesTableId } from "./tables/Tables.sol"; +import { ResourceIds, ResourceIdsTableId } from "./tables/ResourceIds.sol"; import { Hooks } from "./tables/Hooks.sol"; import { Mixed, MixedData, MixedTableId } from "./tables/Mixed.sol"; import { Vector2, Vector2Data, Vector2TableId } from "./tables/Vector2.sol"; diff --git a/packages/store/src/codegen/tables/Callbacks.sol b/packages/store/src/codegen/tables/Callbacks.sol index f13f8f9f9e..e7c1e00837 100644 --- a/packages/store/src/codegen/tables/Callbacks.sol +++ b/packages/store/src/codegen/tables/Callbacks.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "../../tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; +import { ResourceId } from "../../ResourceId.sol"; +import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16("mudstore"), bytes16("Callbacks"))); -bytes32 constant CallbacksTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("Callbacks"))) +); +ResourceId constant CallbacksTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 diff --git a/packages/store/src/codegen/tables/Hooks.sol b/packages/store/src/codegen/tables/Hooks.sol index 28c6a546bc..ed26828797 100644 --- a/packages/store/src/codegen/tables/Hooks.sol +++ b/packages/store/src/codegen/tables/Hooks.sol @@ -17,6 +17,8 @@ import { EncodeArray } from "../../tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; +import { ResourceId } from "../../ResourceId.sol"; +import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 @@ -57,22 +59,22 @@ library Hooks { } /** Register the table with its config */ - function register(bytes32 _tableId) internal { + function register(ResourceId _tableId) internal { StoreSwitch.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config */ - function _register(bytes32 _tableId) internal { + function _register(ResourceId _tableId) internal { StoreCore.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config (using the specified store) */ - function register(IStore _store, bytes32 _tableId) internal { + function register(IStore _store, ResourceId _tableId) internal { _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Get value */ - function getValue(bytes32 _tableId, bytes32 key) internal view returns (bytes21[] memory value) { + function getValue(ResourceId _tableId, bytes32 key) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -81,7 +83,7 @@ library Hooks { } /** Get value */ - function _getValue(bytes32 _tableId, bytes32 key) internal view returns (bytes21[] memory value) { + function _getValue(ResourceId _tableId, bytes32 key) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -90,7 +92,7 @@ library Hooks { } /** Get value (using the specified store) */ - function getValue(IStore _store, bytes32 _tableId, bytes32 key) internal view returns (bytes21[] memory value) { + function getValue(IStore _store, ResourceId _tableId, bytes32 key) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -99,7 +101,7 @@ library Hooks { } /** Get value */ - function get(bytes32 _tableId, bytes32 key) internal view returns (bytes21[] memory value) { + function get(ResourceId _tableId, bytes32 key) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -108,7 +110,7 @@ library Hooks { } /** Get value */ - function _get(bytes32 _tableId, bytes32 key) internal view returns (bytes21[] memory value) { + function _get(ResourceId _tableId, bytes32 key) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -117,7 +119,7 @@ library Hooks { } /** Get value (using the specified store) */ - function get(IStore _store, bytes32 _tableId, bytes32 key) internal view returns (bytes21[] memory value) { + function get(IStore _store, ResourceId _tableId, bytes32 key) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -126,7 +128,7 @@ library Hooks { } /** Set value */ - function setValue(bytes32 _tableId, bytes32 key, bytes21[] memory value) internal { + function setValue(ResourceId _tableId, bytes32 key, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -134,7 +136,7 @@ library Hooks { } /** Set value */ - function _setValue(bytes32 _tableId, bytes32 key, bytes21[] memory value) internal { + function _setValue(ResourceId _tableId, bytes32 key, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -142,7 +144,7 @@ library Hooks { } /** Set value (using the specified store) */ - function setValue(IStore _store, bytes32 _tableId, bytes32 key, bytes21[] memory value) internal { + function setValue(IStore _store, ResourceId _tableId, bytes32 key, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -150,7 +152,7 @@ library Hooks { } /** Set value */ - function set(bytes32 _tableId, bytes32 key, bytes21[] memory value) internal { + function set(ResourceId _tableId, bytes32 key, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -158,7 +160,7 @@ library Hooks { } /** Set value */ - function _set(bytes32 _tableId, bytes32 key, bytes21[] memory value) internal { + function _set(ResourceId _tableId, bytes32 key, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -166,7 +168,7 @@ library Hooks { } /** Set value (using the specified store) */ - function set(IStore _store, bytes32 _tableId, bytes32 key, bytes21[] memory value) internal { + function set(IStore _store, ResourceId _tableId, bytes32 key, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -174,7 +176,7 @@ library Hooks { } /** Get the length of value */ - function lengthValue(bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function lengthValue(ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -185,7 +187,7 @@ library Hooks { } /** Get the length of value */ - function _lengthValue(bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function _lengthValue(ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -196,7 +198,7 @@ library Hooks { } /** Get the length of value (using the specified store) */ - function lengthValue(IStore _store, bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function lengthValue(IStore _store, ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -207,7 +209,7 @@ library Hooks { } /** Get the length of value */ - function length(bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function length(ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -218,7 +220,7 @@ library Hooks { } /** Get the length of value */ - function _length(bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function _length(ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -229,7 +231,7 @@ library Hooks { } /** Get the length of value (using the specified store) */ - function length(IStore _store, bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function length(IStore _store, ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -243,7 +245,7 @@ library Hooks { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function getItemValue(bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { + function getItemValue(ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -264,7 +266,7 @@ library Hooks { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function _getItemValue(bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { + function _getItemValue(ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -285,7 +287,12 @@ library Hooks { * Get an item of value (using the specified store) * (unchecked, returns invalid data if index overflows) */ - function getItemValue(IStore _store, bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { + function getItemValue( + IStore _store, + ResourceId _tableId, + bytes32 key, + uint256 _index + ) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -299,7 +306,7 @@ library Hooks { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function getItem(bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { + function getItem(ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -320,7 +327,7 @@ library Hooks { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function _getItem(bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { + function _getItem(ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -341,7 +348,7 @@ library Hooks { * Get an item of value (using the specified store) * (unchecked, returns invalid data if index overflows) */ - function getItem(IStore _store, bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { + function getItem(IStore _store, ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -352,7 +359,7 @@ library Hooks { } /** Push an element to value */ - function pushValue(bytes32 _tableId, bytes32 key, bytes21 _element) internal { + function pushValue(ResourceId _tableId, bytes32 key, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -360,7 +367,7 @@ library Hooks { } /** Push an element to value */ - function _pushValue(bytes32 _tableId, bytes32 key, bytes21 _element) internal { + function _pushValue(ResourceId _tableId, bytes32 key, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -368,7 +375,7 @@ library Hooks { } /** Push an element to value (using the specified store) */ - function pushValue(IStore _store, bytes32 _tableId, bytes32 key, bytes21 _element) internal { + function pushValue(IStore _store, ResourceId _tableId, bytes32 key, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -376,7 +383,7 @@ library Hooks { } /** Push an element to value */ - function push(bytes32 _tableId, bytes32 key, bytes21 _element) internal { + function push(ResourceId _tableId, bytes32 key, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -384,7 +391,7 @@ library Hooks { } /** Push an element to value */ - function _push(bytes32 _tableId, bytes32 key, bytes21 _element) internal { + function _push(ResourceId _tableId, bytes32 key, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -392,7 +399,7 @@ library Hooks { } /** Push an element to value (using the specified store) */ - function push(IStore _store, bytes32 _tableId, bytes32 key, bytes21 _element) internal { + function push(IStore _store, ResourceId _tableId, bytes32 key, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -400,7 +407,7 @@ library Hooks { } /** Pop an element from value */ - function popValue(bytes32 _tableId, bytes32 key) internal { + function popValue(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -408,7 +415,7 @@ library Hooks { } /** Pop an element from value */ - function _popValue(bytes32 _tableId, bytes32 key) internal { + function _popValue(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -416,7 +423,7 @@ library Hooks { } /** Pop an element from value (using the specified store) */ - function popValue(IStore _store, bytes32 _tableId, bytes32 key) internal { + function popValue(IStore _store, ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -424,7 +431,7 @@ library Hooks { } /** Pop an element from value */ - function pop(bytes32 _tableId, bytes32 key) internal { + function pop(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -432,7 +439,7 @@ library Hooks { } /** Pop an element from value */ - function _pop(bytes32 _tableId, bytes32 key) internal { + function _pop(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -440,7 +447,7 @@ library Hooks { } /** Pop an element from value (using the specified store) */ - function pop(IStore _store, bytes32 _tableId, bytes32 key) internal { + function pop(IStore _store, ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -451,7 +458,7 @@ library Hooks { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function updateValue(bytes32 _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { + function updateValue(ResourceId _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -464,7 +471,7 @@ library Hooks { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function _updateValue(bytes32 _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { + function _updateValue(ResourceId _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -477,7 +484,7 @@ library Hooks { * Update an element of value (using the specified store) at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function updateValue(IStore _store, bytes32 _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { + function updateValue(IStore _store, ResourceId _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -490,7 +497,7 @@ library Hooks { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function update(bytes32 _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { + function update(ResourceId _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -503,7 +510,7 @@ library Hooks { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function _update(bytes32 _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { + function _update(ResourceId _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -516,7 +523,7 @@ library Hooks { * Update an element of value (using the specified store) at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function update(IStore _store, bytes32 _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { + function update(IStore _store, ResourceId _tableId, bytes32 key, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -556,7 +563,7 @@ library Hooks { } /* Delete all data for given keys */ - function deleteRecord(bytes32 _tableId, bytes32 key) internal { + function deleteRecord(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -564,7 +571,7 @@ library Hooks { } /* Delete all data for given keys */ - function _deleteRecord(bytes32 _tableId, bytes32 key) internal { + function _deleteRecord(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -572,7 +579,7 @@ library Hooks { } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 _tableId, bytes32 key) internal { + function deleteRecord(IStore _store, ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; diff --git a/packages/store/src/codegen/tables/KeyEncoding.sol b/packages/store/src/codegen/tables/KeyEncoding.sol index 132acd4eb1..4f5afd260d 100644 --- a/packages/store/src/codegen/tables/KeyEncoding.sol +++ b/packages/store/src/codegen/tables/KeyEncoding.sol @@ -17,12 +17,16 @@ import { EncodeArray } from "../../tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; +import { ResourceId } from "../../ResourceId.sol"; +import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; // Import user types import { ExampleEnum } from "./../common.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16("mudstore"), bytes16("KeyEncoding"))); -bytes32 constant KeyEncodingTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("KeyEncoding"))) +); +ResourceId constant KeyEncodingTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0001010001000000000000000000000000000000000000000000000000000000 diff --git a/packages/store/src/codegen/tables/Mixed.sol b/packages/store/src/codegen/tables/Mixed.sol index f4b9e76651..995a84f49c 100644 --- a/packages/store/src/codegen/tables/Mixed.sol +++ b/packages/store/src/codegen/tables/Mixed.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "../../tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; +import { ResourceId } from "../../ResourceId.sol"; +import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16("mudstore"), bytes16("Mixed"))); -bytes32 constant MixedTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("Mixed"))) +); +ResourceId constant MixedTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0014020204100000000000000000000000000000000000000000000000000000 diff --git a/packages/store/src/codegen/tables/ResourceIds.sol b/packages/store/src/codegen/tables/ResourceIds.sol new file mode 100644 index 0000000000..229d236416 --- /dev/null +++ b/packages/store/src/codegen/tables/ResourceIds.sol @@ -0,0 +1,235 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +/* Autogenerated file. Do not edit manually. */ + +// Import schema type +import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; + +// Import store internals +import { IStore } from "../../IStore.sol"; +import { StoreSwitch } from "../../StoreSwitch.sol"; +import { StoreCore } from "../../StoreCore.sol"; +import { Bytes } from "../../Bytes.sol"; +import { Memory } from "../../Memory.sol"; +import { SliceLib } from "../../Slice.sol"; +import { EncodeArray } from "../../tightcoder/EncodeArray.sol"; +import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; +import { Schema, SchemaLib } from "../../Schema.sol"; +import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; +import { ResourceId } from "../../ResourceId.sol"; +import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; + +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("ResourceIds"))) +); +ResourceId constant ResourceIdsTableId = _tableId; + +FieldLayout constant _fieldLayout = FieldLayout.wrap( + 0x0001010001000000000000000000000000000000000000000000000000000000 +); + +library ResourceIds { + /** Get the table values' field layout */ + function getFieldLayout() internal pure returns (FieldLayout) { + return _fieldLayout; + } + + /** Get the table's key schema */ + function getKeySchema() internal pure returns (Schema) { + SchemaType[] memory _keySchema = new SchemaType[](1); + _keySchema[0] = SchemaType.BYTES32; + + return SchemaLib.encode(_keySchema); + } + + /** Get the table's value schema */ + function getValueSchema() internal pure returns (Schema) { + SchemaType[] memory _valueSchema = new SchemaType[](1); + _valueSchema[0] = SchemaType.BOOL; + + return SchemaLib.encode(_valueSchema); + } + + /** Get the table's key names */ + function getKeyNames() internal pure returns (string[] memory keyNames) { + keyNames = new string[](1); + keyNames[0] = "resourceId"; + } + + /** Get the table's field names */ + function getFieldNames() internal pure returns (string[] memory fieldNames) { + fieldNames = new string[](1); + fieldNames[0] = "exists"; + } + + /** Register the table with its config */ + function register() internal { + StoreSwitch.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); + } + + /** Register the table with its config */ + function _register() internal { + StoreCore.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); + } + + /** Register the table with its config (using the specified store) */ + function register(IStore _store) internal { + _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); + } + + /** Get exists */ + function getExists(bytes32 resourceId) internal view returns (bool exists) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (_toBool(uint8(bytes1(_blob)))); + } + + /** Get exists */ + function _getExists(bytes32 resourceId) internal view returns (bool exists) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (_toBool(uint8(bytes1(_blob)))); + } + + /** Get exists (using the specified store) */ + function getExists(IStore _store, bytes32 resourceId) internal view returns (bool exists) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (_toBool(uint8(bytes1(_blob)))); + } + + /** Get exists */ + function get(bytes32 resourceId) internal view returns (bool exists) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (_toBool(uint8(bytes1(_blob)))); + } + + /** Get exists */ + function _get(bytes32 resourceId) internal view returns (bool exists) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (_toBool(uint8(bytes1(_blob)))); + } + + /** Get exists (using the specified store) */ + function get(IStore _store, bytes32 resourceId) internal view returns (bool exists) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); + return (_toBool(uint8(bytes1(_blob)))); + } + + /** Set exists */ + function setExists(bytes32 resourceId, bool exists) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((exists)), _fieldLayout); + } + + /** Set exists */ + function _setExists(bytes32 resourceId, bool exists) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((exists)), _fieldLayout); + } + + /** Set exists (using the specified store) */ + function setExists(IStore _store, bytes32 resourceId, bool exists) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((exists)), _fieldLayout); + } + + /** Set exists */ + function set(bytes32 resourceId, bool exists) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((exists)), _fieldLayout); + } + + /** Set exists */ + function _set(bytes32 resourceId, bool exists) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((exists)), _fieldLayout); + } + + /** Set exists (using the specified store) */ + function set(IStore _store, bytes32 resourceId, bool exists) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((exists)), _fieldLayout); + } + + /** Tightly pack static data using this table's schema */ + function encodeStatic(bool exists) internal pure returns (bytes memory) { + return abi.encodePacked(exists); + } + + /** Tightly pack full data using this table's field layout */ + function encode(bool exists) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(exists); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple(bytes32 resourceId) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + return _keyTuple; + } + + /* Delete all data for given keys */ + function deleteRecord(bytes32 resourceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /* Delete all data for given keys */ + function _deleteRecord(bytes32 resourceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /* Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 resourceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } +} + +function _toBool(uint8 value) pure returns (bool result) { + assembly { + result := value + } +} diff --git a/packages/store/src/codegen/tables/StoreHooks.sol b/packages/store/src/codegen/tables/StoreHooks.sol index 11c11e6c84..bba07c02cd 100644 --- a/packages/store/src/codegen/tables/StoreHooks.sol +++ b/packages/store/src/codegen/tables/StoreHooks.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "../../tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; +import { ResourceId } from "../../ResourceId.sol"; +import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16("mudstore"), bytes16("StoreHooks"))); -bytes32 constant StoreHooksTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("StoreHooks"))) +); +ResourceId constant StoreHooksTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 diff --git a/packages/store/src/codegen/tables/Tables.sol b/packages/store/src/codegen/tables/Tables.sol index dbf0de5289..3e4c7b0724 100644 --- a/packages/store/src/codegen/tables/Tables.sol +++ b/packages/store/src/codegen/tables/Tables.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "../../tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; +import { ResourceId } from "../../ResourceId.sol"; +import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16("mudstore"), bytes16("Tables"))); -bytes32 constant TablesTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("Tables"))) +); +ResourceId constant TablesTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0060030220202000000000000000000000000000000000000000000000000000 diff --git a/packages/store/src/codegen/tables/Vector2.sol b/packages/store/src/codegen/tables/Vector2.sol index 58402ad8b5..cb95a745ea 100644 --- a/packages/store/src/codegen/tables/Vector2.sol +++ b/packages/store/src/codegen/tables/Vector2.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "../../tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; +import { ResourceId } from "../../ResourceId.sol"; +import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16("mudstore"), bytes16("Vector2"))); -bytes32 constant Vector2TableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("Vector2"))) +); +ResourceId constant Vector2TableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0008020004040000000000000000000000000000000000000000000000000000 diff --git a/packages/store/src/storeResourceTypes.sol b/packages/store/src/storeResourceTypes.sol new file mode 100644 index 0000000000..5854db2429 --- /dev/null +++ b/packages/store/src/storeResourceTypes.sol @@ -0,0 +1,5 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +bytes2 constant RESOURCE_TABLE = "tb"; +bytes2 constant RESOURCE_OFFCHAIN_TABLE = "ot"; diff --git a/packages/store/test/EchoSubscriber.sol b/packages/store/test/EchoSubscriber.sol index acaf3b50ab..90e9ca592f 100644 --- a/packages/store/test/EchoSubscriber.sol +++ b/packages/store/test/EchoSubscriber.sol @@ -4,12 +4,13 @@ pragma solidity >=0.8.0; import { PackedCounter } from "../src/PackedCounter.sol"; import { FieldLayout } from "../src/FieldLayout.sol"; import { StoreHook } from "../src/StoreHook.sol"; +import { ResourceId } from "../src/ResourceId.sol"; contract EchoSubscriber is StoreHook { event HookCalled(bytes); function onBeforeSetRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, @@ -22,7 +23,7 @@ contract EchoSubscriber is StoreHook { } function onAfterSetRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, @@ -35,7 +36,7 @@ contract EchoSubscriber is StoreHook { } function onBeforeSpliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint48 start, uint40 deleteCount, @@ -45,7 +46,7 @@ contract EchoSubscriber is StoreHook { } function onAfterSpliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint48 start, uint40 deleteCount, @@ -55,7 +56,7 @@ contract EchoSubscriber is StoreHook { } function onBeforeSpliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -72,7 +73,7 @@ contract EchoSubscriber is StoreHook { } function onAfterSpliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -88,11 +89,15 @@ contract EchoSubscriber is StoreHook { ); } - function onBeforeDeleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) public override { + function onBeforeDeleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + FieldLayout fieldLayout + ) public override { emit HookCalled(abi.encodeCall(this.onBeforeDeleteRecord, (tableId, keyTuple, fieldLayout))); } - function onAfterDeleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) public override { + function onAfterDeleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) public override { emit HookCalled(abi.encodeCall(this.onAfterDeleteRecord, (tableId, keyTuple, fieldLayout))); } } diff --git a/packages/store/test/MirrorSubscriber.sol b/packages/store/test/MirrorSubscriber.sol index 3c86958cd6..e646d3634d 100644 --- a/packages/store/test/MirrorSubscriber.sol +++ b/packages/store/test/MirrorSubscriber.sol @@ -7,14 +7,18 @@ import { PackedCounter } from "../src/PackedCounter.sol"; import { StoreSwitch } from "../src/StoreSwitch.sol"; import { FieldLayout } from "../src/FieldLayout.sol"; import { Schema } from "../src/Schema.sol"; +import { ResourceId } from "../src/ResourceId.sol"; +import { RESOURCE_TABLE } from "../src/storeResourceTypes.sol"; -bytes32 constant indexerTableId = keccak256("indexer.tableId"); +ResourceId constant indexerTableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mirror"), bytes16("indexer"))) +); contract MirrorSubscriber is StoreHook { bytes32 public _tableId; constructor( - bytes32 tableId, + ResourceId tableId, FieldLayout fieldLayout, Schema keySchema, Schema valueSchema, @@ -22,34 +26,34 @@ contract MirrorSubscriber is StoreHook { string[] memory fieldNames ) { IStore(msg.sender).registerTable(indexerTableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); - _tableId = tableId; + _tableId = ResourceId.unwrap(tableId); } function onBeforeSetRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData, FieldLayout fieldLayout ) public override { - if (tableId != _tableId) revert("invalid table"); + if (ResourceId.unwrap(tableId) != _tableId) revert("invalid table"); StoreSwitch.setRecord(indexerTableId, keyTuple, staticData, encodedLengths, dynamicData, fieldLayout); } function onBeforeSpliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint48 start, uint40 deleteCount, bytes memory data ) public override { - if (tableId != _tableId) revert("invalid tableId"); + if (ResourceId.unwrap(tableId) != _tableId) revert("invalid tableId"); StoreSwitch.spliceStaticData(indexerTableId, keyTuple, start, deleteCount, data); } function onBeforeSpliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -57,12 +61,12 @@ contract MirrorSubscriber is StoreHook { bytes memory data, PackedCounter ) public override { - if (tableId != _tableId) revert("invalid tableId"); + if (ResourceId.unwrap(tableId) != _tableId) revert("invalid tableId"); StoreSwitch.spliceDynamicData(indexerTableId, keyTuple, dynamicFieldIndex, startWithinField, deleteCount, data); } function onAfterSpliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -70,12 +74,16 @@ contract MirrorSubscriber is StoreHook { bytes memory data, PackedCounter ) public override { - if (tableId != _tableId) revert("invalid tableId"); + if (ResourceId.unwrap(tableId) != _tableId) revert("invalid tableId"); StoreSwitch.spliceDynamicData(indexerTableId, keyTuple, dynamicFieldIndex, startWithinField, deleteCount, data); } - function onBeforeDeleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) public override { - if (tableId != tableId) revert("invalid tableId"); + function onBeforeDeleteRecord( + ResourceId tableId, + bytes32[] memory keyTuple, + FieldLayout fieldLayout + ) public override { + if (ResourceId.unwrap(tableId) != _tableId) revert("invalid tableId"); StoreSwitch.deleteRecord(indexerTableId, keyTuple, fieldLayout); } } diff --git a/packages/store/test/ResourceId.t.sol b/packages/store/test/ResourceId.t.sol new file mode 100644 index 0000000000..d64afe4f53 --- /dev/null +++ b/packages/store/test/ResourceId.t.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { Test, console } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; +import { ResourceId } from "../src/ResourceId.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "../src/storeResourceTypes.sol"; +import { ResourceId, ResourceIdInstance, ResourceIdLib } from "../src/ResourceId.sol"; + +contract ResourceIdTest is Test, GasReporter { + using ResourceIdInstance for ResourceId; + + function testEncode() public { + startGasReport("encode table ID with name and type"); + ResourceId tableId = ResourceIdLib.encode({ typeId: RESOURCE_TABLE, name: "name" }); + endGasReport(); + + assertEq(ResourceId.unwrap(tableId), bytes32(abi.encodePacked(RESOURCE_TABLE, bytes30("name")))); + } + + function testGetType() public { + ResourceId tableId = ResourceIdLib.encode({ typeId: RESOURCE_TABLE, name: "name" }); + + startGasReport("get type from a table ID"); + bytes2 resourceType = tableId.getType(); + endGasReport(); + + assertEq(resourceType, RESOURCE_TABLE); + } + + function testFuzz(bytes30 name, bytes2 resourceType) public { + ResourceId tableId = ResourceIdLib.encode({ typeId: resourceType, name: name }); + assertEq(tableId.getType(), resourceType); + } +} diff --git a/packages/store/test/RevertSubscriber.sol b/packages/store/test/RevertSubscriber.sol index 7d706405d4..38e6810603 100644 --- a/packages/store/test/RevertSubscriber.sol +++ b/packages/store/test/RevertSubscriber.sol @@ -4,10 +4,11 @@ pragma solidity >=0.8.0; import { StoreHook } from "../src/StoreHook.sol"; import { FieldLayout } from "../src/FieldLayout.sol"; import { PackedCounter } from "../src/PackedCounter.sol"; +import { ResourceId } from "../src/ResourceId.sol"; contract RevertSubscriber is StoreHook { function onBeforeSetRecord( - bytes32, + ResourceId, bytes32[] memory, bytes memory, PackedCounter, @@ -18,7 +19,7 @@ contract RevertSubscriber is StoreHook { } function onAfterSetRecord( - bytes32, + ResourceId, bytes32[] memory, bytes memory, PackedCounter, @@ -28,16 +29,16 @@ contract RevertSubscriber is StoreHook { revert("onAfterSetRecord"); } - function onBeforeSpliceStaticData(bytes32, bytes32[] memory, uint48, uint40, bytes memory) public pure override { + function onBeforeSpliceStaticData(ResourceId, bytes32[] memory, uint48, uint40, bytes memory) public pure override { revert("onBeforeSpliceStaticData"); } - function onAfterSpliceStaticData(bytes32, bytes32[] memory, uint48, uint40, bytes memory) public pure override { + function onAfterSpliceStaticData(ResourceId, bytes32[] memory, uint48, uint40, bytes memory) public pure override { revert("onAfterSpliceStaticData"); } function onBeforeSpliceDynamicData( - bytes32, + ResourceId, bytes32[] memory, uint8, uint40, @@ -49,7 +50,7 @@ contract RevertSubscriber is StoreHook { } function onAfterSpliceDynamicData( - bytes32, + ResourceId, bytes32[] memory, uint8, uint40, @@ -60,11 +61,11 @@ contract RevertSubscriber is StoreHook { revert("onAfterSpliceDynamicData"); } - function onBeforeDeleteRecord(bytes32, bytes32[] memory, FieldLayout) public pure override { + function onBeforeDeleteRecord(ResourceId, bytes32[] memory, FieldLayout) public pure override { revert("onBeforeDeleteRecord"); } - function onAfterDeleteRecord(bytes32, bytes32[] memory, FieldLayout) public pure override { + function onAfterDeleteRecord(ResourceId, bytes32[] memory, FieldLayout) public pure override { revert("onAfterDeleteRecord"); } } diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index 132b198940..9c96aecb80 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -7,7 +7,7 @@ import { StoreCore, StoreCoreInternal } from "../src/StoreCore.sol"; import { Bytes } from "../src/Bytes.sol"; import { SliceLib } from "../src/Slice.sol"; import { EncodeArray } from "../src/tightcoder/EncodeArray.sol"; -import { FieldLayout } from "../src/FieldLayout.sol"; +import { FieldLayout, FieldLayoutLib } from "../src/FieldLayout.sol"; import { Schema } from "../src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "../src/PackedCounter.sol"; import { StoreMock } from "../test/StoreMock.sol"; @@ -15,7 +15,9 @@ import { IStoreErrors } from "../src/IStoreErrors.sol"; import { IStore } from "../src/IStore.sol"; import { StoreSwitch } from "../src/StoreSwitch.sol"; import { IStoreHook } from "../src/IStoreHook.sol"; -import { Tables, TablesTableId } from "../src/codegen/index.sol"; +import { Tables, ResourceIds, TablesTableId } from "../src/codegen/index.sol"; +import { ResourceId, ResourceIdLib, ResourceIdInstance } from "../src/ResourceId.sol"; +import { RESOURCE_TABLE } from "../src/storeResourceTypes.sol"; import { FieldLayoutEncodeHelper } from "./FieldLayoutEncodeHelper.sol"; import { BEFORE_SET_RECORD, AFTER_SET_RECORD, BEFORE_SPLICE_STATIC_DATA, AFTER_SPLICE_STATIC_DATA, BEFORE_SPLICE_DYNAMIC_DATA, AFTER_SPLICE_DYNAMIC_DATA, BEFORE_DELETE_RECORD, AFTER_DELETE_RECORD, ALL, BEFORE_ALL, AFTER_ALL } from "../src/storeHookTypes.sol"; import { SchemaEncodeHelper } from "./SchemaEncodeHelper.sol"; @@ -32,14 +34,20 @@ struct TestStruct { } contract StoreCoreTest is Test, StoreMock { + using ResourceIdInstance for ResourceId; + TestStruct private testStruct; event HookCalled(bytes); mapping(uint256 => bytes) private testMapping; Schema defaultKeySchema = SchemaEncodeHelper.encode(SchemaType.BYTES32); string[] defaultKeyNames = new string[](1); + ResourceId _tableId = ResourceIdLib.encode({ typeId: RESOURCE_TABLE, name: "some table" }); + ResourceId _tableId2 = ResourceIdLib.encode({ typeId: RESOURCE_TABLE, name: "some other table" }); + + function testRegisterTable() public { + ResourceId tableId = _tableId; - function testRegisterAndGetFieldLayout() public { FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 2, 1, 2, 0); Schema keySchema = SchemaEncodeHelper.encode(SchemaType.UINT8, SchemaType.UINT16); Schema valueSchema = SchemaEncodeHelper.encode( @@ -57,11 +65,9 @@ contract StoreCoreTest is Test, StoreMock { fieldNames[2] = "value3"; fieldNames[3] = "value4"; - bytes32 tableId = keccak256("some.tableId"); - // Expect a StoreSetRecord event to be emitted bytes32[] memory keyTuple = new bytes32[](1); - keyTuple[0] = bytes32(tableId); + keyTuple[0] = ResourceId.unwrap(tableId); vm.expectEmit(true, true, true, true); emit StoreSetRecord( TablesTableId, @@ -76,18 +82,52 @@ contract StoreCoreTest is Test, StoreMock { assertEq(IStore(this).getValueSchema(tableId).unwrap(), valueSchema.unwrap()); assertEq(IStore(this).getKeySchema(tableId).unwrap(), keySchema.unwrap()); - bytes memory loadedKeyNames = Tables.getAbiEncodedKeyNames(IStore(this), tableId); + bytes memory loadedKeyNames = Tables.getAbiEncodedKeyNames(IStore(this), ResourceId.unwrap(tableId)); assertEq(loadedKeyNames, abi.encode(keyNames)); - bytes memory loadedFieldNames = Tables.getAbiEncodedFieldNames(IStore(this), tableId); + bytes memory loadedFieldNames = Tables.getAbiEncodedFieldNames(IStore(this), ResourceId.unwrap(tableId)); assertEq(loadedFieldNames, abi.encode(fieldNames)); + + // Expect the table ID to be registered + assertTrue(ResourceIds._getExists(ResourceId.unwrap(tableId))); } - function testFailRegisterInvalidFieldLayout() public { + function testRevertTableExists() public { + ResourceId tableId = _tableId; + FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 0); + Schema keySchema = SchemaEncodeHelper.encode(SchemaType.UINT8); + Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT8); + string[] memory keyNames = new string[](1); + string[] memory fieldNames = new string[](1); + + IStore(this).registerTable(tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); + + // Expect a revert when registering a table that already exists + vm.expectRevert( + abi.encodeWithSelector( + IStoreErrors.StoreCore_TableAlreadyExists.selector, + ResourceId.unwrap(tableId), + string(bytes.concat(ResourceId.unwrap(tableId))) + ) + ); + IStore(this).registerTable(tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); + } + + function testRevertRegisterInvalidFieldLayout() public { + ResourceId tableId = _tableId; + string[] memory keyNames = new string[](2); string[] memory fieldNames = new string[](4); + FieldLayout invalidFieldLayout = FieldLayout.wrap(keccak256("random bytes as value field layout")); + + vm.expectRevert( + abi.encodeWithSelector( + FieldLayoutLib.FieldLayoutLib_InvalidLength.selector, + invalidFieldLayout.numDynamicFields() + ) + ); IStore(this).registerTable( - keccak256("tableId"), + tableId, FieldLayout.wrap(keccak256("random bytes as value field layout")), Schema.wrap(keccak256("random bytes as key schema")), Schema.wrap(keccak256("random bytes as value schema")), @@ -96,7 +136,32 @@ contract StoreCoreTest is Test, StoreMock { ); } + function testRevertRegisterInvalidTableId() public { + bytes2 invalidType = "xx"; + ResourceId invalidTableId = ResourceIdLib.encode({ typeId: invalidType, name: "somename" }); + + vm.expectRevert( + abi.encodeWithSelector( + IStoreErrors.StoreCore_InvalidResourceType.selector, + RESOURCE_TABLE, + invalidTableId, + string(abi.encodePacked(invalidTableId)) + ) + ); + IStore(this).registerTable( + invalidTableId, + FieldLayoutEncodeHelper.encode(1, 0), + SchemaEncodeHelper.encode(SchemaType.UINT8), + SchemaEncodeHelper.encode(SchemaType.UINT8), + new string[](1), + new string[](1) + ); + } + function testHasFieldLayoutAndSchema() public { + ResourceId tableId = _tableId; + ResourceId tableId2 = _tableId2; + string[] memory keyNames = new string[](1); string[] memory fieldNames = new string[](4); FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 2, 1, 2, 0); @@ -106,12 +171,10 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT8, SchemaType.UINT16 ); - bytes32 tableId = keccak256("some.tableId"); - bytes32 tableId2 = keccak256("other.tableId"); IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); - assertTrue(StoreCore.hasTable(tableId)); - assertFalse(StoreCore.hasTable(tableId2)); + assertTrue(ResourceIds._getExists(ResourceId.unwrap(tableId))); + assertFalse(ResourceIds._getExists(ResourceId.unwrap(tableId2))); IStore(this).getFieldLayout(tableId); IStore(this).getValueSchema(tableId); @@ -121,7 +184,7 @@ contract StoreCoreTest is Test, StoreMock { abi.encodeWithSelector( IStoreErrors.StoreCore_TableNotFound.selector, tableId2, - string(abi.encodePacked(tableId2)) + string(abi.encodePacked(ResourceId.unwrap(tableId2))) ) ); IStore(this).getFieldLayout(tableId2); @@ -146,7 +209,8 @@ contract StoreCoreTest is Test, StoreMock { } function testRegisterTableRevertNames() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; + FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 0); Schema keySchema = SchemaEncodeHelper.encode( SchemaType.UINT8, @@ -168,7 +232,7 @@ contract StoreCoreTest is Test, StoreMock { } function testSetAndGetDynamicDataLength() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 2, 4, 2); Schema valueSchema = SchemaEncodeHelper.encode( @@ -212,6 +276,8 @@ contract StoreCoreTest is Test, StoreMock { } function testSetAndGetStaticData() public { + ResourceId tableId = _tableId; + // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 2, 1, 2, 0); Schema valueSchema = SchemaEncodeHelper.encode( @@ -221,7 +287,6 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT16 ); - bytes32 tableId = keccak256("some.tableId"); IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); // Set data @@ -248,7 +313,9 @@ contract StoreCoreTest is Test, StoreMock { assertEq(_dynamicData, ""); } - function testFailSetAndGetStaticData() public { + function testRevertSetAndGetStaticData() public { + ResourceId tableId = _tableId; + // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 2, 1, 2, 0); Schema valueSchema = SchemaEncodeHelper.encode( @@ -257,7 +324,6 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT8, SchemaType.UINT16 ); - bytes32 tableId = keccak256("some.tableId"); IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); // Set data @@ -267,13 +333,15 @@ contract StoreCoreTest is Test, StoreMock { keyTuple[0] = "some key"; // This should fail because the data is not 6 bytes long + vm.expectRevert(abi.encodeWithSelector(IStoreErrors.StoreCore_InvalidStaticDataLength.selector, 6, 4)); IStore(this).setRecord(tableId, keyTuple, staticData, PackedCounter.wrap(bytes32(0)), new bytes(0), fieldLayout); } function testSetAndGetStaticDataSpanningWords() public { + ResourceId tableId = _tableId; + // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 32, 0); - bytes32 tableId = keccak256("some.table"); { Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT128, SchemaType.UINT256); IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); @@ -307,7 +375,7 @@ contract StoreCoreTest is Test, StoreMock { } function testSetAndGetDynamicData() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 2); @@ -382,7 +450,7 @@ contract StoreCoreTest is Test, StoreMock { } struct SetAndGetData { - bytes32 tableId; + ResourceId tableId; FieldLayout fieldLayout; bytes16 firstDataBytes; bytes firstDataPacked; @@ -393,8 +461,10 @@ contract StoreCoreTest is Test, StoreMock { } function testSetAndGetField() public { + ResourceId tableId = _tableId; + SetAndGetData memory _data; - _data.tableId = keccak256("some.tableId"); + _data.tableId = tableId; // Register table _data.fieldLayout = FieldLayoutEncodeHelper.encode(16, 32, 2); @@ -608,7 +678,7 @@ contract StoreCoreTest is Test, StoreMock { } function testDeleteData() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 2); @@ -687,7 +757,7 @@ contract StoreCoreTest is Test, StoreMock { } struct TestPushToFieldData { - bytes32 tableId; + ResourceId tableId; bytes32[] keyTuple; bytes32 firstDataBytes; bytes secondDataBytes; @@ -700,9 +770,9 @@ contract StoreCoreTest is Test, StoreMock { } function testPushToField() public { - TestPushToFieldData memory data = TestPushToFieldData(0, new bytes32[](0), 0, "", "", "", "", "", "", ""); + ResourceId tableId = _tableId; - data.tableId = keccak256("some.tableId"); + TestPushToFieldData memory data = TestPushToFieldData(tableId, new bytes32[](0), 0, "", "", "", "", "", "", ""); // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(32, 2); @@ -826,7 +896,7 @@ contract StoreCoreTest is Test, StoreMock { } struct TestUpdateInFieldData { - bytes32 tableId; + ResourceId tableId; bytes32[] keyTuple; bytes32 firstDataBytes; uint32[] secondData; @@ -841,8 +911,10 @@ contract StoreCoreTest is Test, StoreMock { } function testUpdateInField() public { + ResourceId tableId = _tableId; + TestUpdateInFieldData memory data = TestUpdateInFieldData( - 0, + tableId, new bytes32[](0), 0, new uint32[](0), @@ -856,8 +928,6 @@ contract StoreCoreTest is Test, StoreMock { "" ); - data.tableId = keccak256("some.tableId"); - // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(32, 2); Schema valueSchema = SchemaEncodeHelper.encode( @@ -987,7 +1057,8 @@ contract StoreCoreTest is Test, StoreMock { } function testAccessEmptyData() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; + FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(4, 1); Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT32, SchemaType.UINT32_ARRAY); @@ -1014,7 +1085,8 @@ contract StoreCoreTest is Test, StoreMock { } function testRegisterHook() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; + bytes32[] memory keyTuple = new bytes32[](1); keyTuple[0] = "some key"; @@ -1059,7 +1131,8 @@ contract StoreCoreTest is Test, StoreMock { } function testUnregisterHook() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; + bytes32[] memory keyTuple = new bytes32[](1); keyTuple[0] = "some key"; @@ -1174,7 +1247,8 @@ contract StoreCoreTest is Test, StoreMock { } function testHooksDynamicData() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; + bytes32[] memory keyTuple = new bytes32[](1); keyTuple[0] = "some key"; diff --git a/packages/store/test/StoreCoreDynamic.t.sol b/packages/store/test/StoreCoreDynamic.t.sol index d5979239c3..33e1434d0d 100644 --- a/packages/store/test/StoreCoreDynamic.t.sol +++ b/packages/store/test/StoreCoreDynamic.t.sol @@ -10,6 +10,8 @@ import { EncodeArray } from "../src/tightcoder/EncodeArray.sol"; import { PackedCounterLib } from "../src/PackedCounter.sol"; import { FieldLayout } from "../src/FieldLayout.sol"; import { Schema } from "../src/Schema.sol"; +import { ResourceId, ResourceIdLib } from "../src/ResourceId.sol"; +import { RESOURCE_TABLE } from "../src/storeResourceTypes.sol"; import { StoreMock } from "../test/StoreMock.sol"; import { FieldLayoutEncodeHelper } from "./FieldLayoutEncodeHelper.sol"; import { SchemaEncodeHelper } from "./SchemaEncodeHelper.sol"; @@ -18,7 +20,7 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreMock { Schema internal defaultKeySchema = SchemaEncodeHelper.encode(SchemaType.BYTES32); bytes32[] internal _keyTuple; - bytes32 internal _tableId = keccak256("some.tableId"); + ResourceId internal _tableId = ResourceIdLib.encode({ typeId: RESOURCE_TABLE, name: "some table" }); bytes32 internal firstDataBytes; uint32[] internal secondData; @@ -28,7 +30,7 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreMock { // Expose an external popFromField function for testing purposes of indexers (see testHooks) function popFromField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, uint256 byteLengthToPop, diff --git a/packages/store/test/StoreCoreGas.t.sol b/packages/store/test/StoreCoreGas.t.sol index 219b3b8c64..31419806e6 100644 --- a/packages/store/test/StoreCoreGas.t.sol +++ b/packages/store/test/StoreCoreGas.t.sol @@ -14,6 +14,9 @@ import { PackedCounter, PackedCounterLib } from "../src/PackedCounter.sol"; import { StoreMock } from "../test/StoreMock.sol"; import { IStoreErrors } from "../src/IStoreErrors.sol"; import { IStore } from "../src/IStore.sol"; +import { ResourceId, ResourceIdLib } from "../src/ResourceId.sol"; +import { ResourceIds } from "../src/codegen/tables/ResourceIds.sol"; +import { RESOURCE_TABLE } from "../src/storeResourceTypes.sol"; import { FieldLayoutEncodeHelper } from "./FieldLayoutEncodeHelper.sol"; import { SchemaEncodeHelper } from "./SchemaEncodeHelper.sol"; import { StoreMock } from "./StoreMock.sol"; @@ -32,8 +35,12 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { mapping(uint256 => bytes) private testMapping; Schema defaultKeySchema = SchemaEncodeHelper.encode(SchemaType.BYTES32); + ResourceId _tableId = ResourceIdLib.encode({ typeId: RESOURCE_TABLE, name: "some table" }); + ResourceId _tableId2 = ResourceIdLib.encode({ typeId: RESOURCE_TABLE, name: "some other table" }); function testRegisterAndGetFieldLayout() public { + ResourceId tableId = _tableId; + FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 2, 1, 2, 0); Schema valueSchema = SchemaEncodeHelper.encode( SchemaType.UINT8, @@ -42,7 +49,6 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { SchemaType.UINT16 ); Schema keySchema = SchemaEncodeHelper.encode(SchemaType.UINT8, SchemaType.UINT16); - bytes32 tableId = keccak256("some.tableId"); string[] memory keyNames = new string[](2); keyNames[0] = "key1"; @@ -71,6 +77,9 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testHasFieldLayout() public { + ResourceId tableId = _tableId; + ResourceId tableId2 = _tableId2; + Schema valueSchema = SchemaEncodeHelper.encode( SchemaType.UINT8, SchemaType.UINT16, @@ -78,21 +87,19 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { SchemaType.UINT16 ); FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 2, 1, 2, 0); - bytes32 tableId = keccak256("some.tableId"); - bytes32 tableId2 = keccak256("other.tableId"); StoreCore.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); startGasReport("Check for existence of table (existent)"); - StoreCore.hasTable(tableId); + ResourceIds._getExists(ResourceId.unwrap(tableId)); endGasReport(); startGasReport("check for existence of table (non-existent)"); - StoreCore.hasTable(tableId2); + ResourceIds._getExists(ResourceId.unwrap(tableId2)); endGasReport(); } function testSetAndGetDynamicDataLength() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; Schema valueSchema = SchemaEncodeHelper.encode( SchemaType.UINT8, @@ -128,6 +135,8 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testSetAndGetStaticData() public { + ResourceId tableId = _tableId; + // Register table Schema valueSchema = SchemaEncodeHelper.encode( SchemaType.UINT8, @@ -136,7 +145,6 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { SchemaType.UINT16 ); FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 2, 1, 2, 0); - bytes32 tableId = keccak256("some.tableId"); StoreCore.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); // Set data @@ -156,10 +164,11 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testSetAndGetStaticDataSpanningWords() public { + ResourceId tableId = _tableId; + // Register table Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT128, SchemaType.UINT256); FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 32, 0); - bytes32 tableId = keccak256("some.tableId"); StoreCore.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); // Set data @@ -183,7 +192,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testSetAndGetDynamicData() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 2); @@ -255,7 +264,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testSetAndGetField() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 32, 2); @@ -345,7 +354,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testDeleteData() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 2); @@ -398,7 +407,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testPushToField() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(32, 2); @@ -484,9 +493,9 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testUpdateInField() public { - TestUpdateInFieldData memory data = TestUpdateInFieldData("", "", "", "", "", "", ""); - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; + TestUpdateInFieldData memory data = TestUpdateInFieldData("", "", "", "", "", "", ""); // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(32, 2); Schema valueSchema = SchemaEncodeHelper.encode( @@ -561,7 +570,8 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testAccessEmptyData() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; + FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(4, 1); Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT32, SchemaType.UINT32_ARRAY); @@ -593,7 +603,8 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testHooks() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; + bytes32[] memory keyTuple = new bytes32[](1); keyTuple[0] = keccak256("some key"); @@ -635,7 +646,8 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { } function testHooksDynamicData() public { - bytes32 tableId = keccak256("some.tableId"); + ResourceId tableId = _tableId; + bytes32[] memory keyTuple = new bytes32[](1); keyTuple[0] = keccak256("some key"); diff --git a/packages/store/test/StoreHook.t.sol b/packages/store/test/StoreHook.t.sol index 3060df585d..d9ef3615a3 100644 --- a/packages/store/test/StoreHook.t.sol +++ b/packages/store/test/StoreHook.t.sol @@ -11,6 +11,8 @@ import { Hook, HookLib } from "../src/Hook.sol"; import { IStoreHook } from "../src/IStore.sol"; import { PackedCounter } from "../src/PackedCounter.sol"; import { FieldLayout } from "../src/FieldLayout.sol"; +import { ResourceId, ResourceIdLib } from "../src/ResourceId.sol"; +import { RESOURCE_TABLE } from "../src/storeResourceTypes.sol"; import { BEFORE_SET_RECORD, AFTER_SET_RECORD, BEFORE_SPLICE_STATIC_DATA, AFTER_SPLICE_STATIC_DATA, BEFORE_SPLICE_DYNAMIC_DATA, AFTER_SPLICE_DYNAMIC_DATA, BEFORE_DELETE_RECORD, AFTER_DELETE_RECORD, ALL, BEFORE_ALL, AFTER_ALL } from "../src/storeHookTypes.sol"; contract StoreHookTest is Test, GasReporter { @@ -19,7 +21,7 @@ contract StoreHookTest is Test, GasReporter { // Testdata EchoSubscriber private echoSubscriber = new EchoSubscriber(); RevertSubscriber private revertSubscriber = new RevertSubscriber(); - bytes32 private tableId = "table"; + ResourceId private tableId; bytes32[] private key = new bytes32[](1); bytes private staticData = abi.encodePacked(bytes32(0)); PackedCounter private encodedLengths = PackedCounter.wrap(bytes32(0)); @@ -27,6 +29,10 @@ contract StoreHookTest is Test, GasReporter { uint8 private fieldIndex = 1; FieldLayout private fieldLayout = FieldLayout.wrap(0); + constructor() { + tableId = ResourceIdLib.encode({ typeId: RESOURCE_TABLE, name: "table" }); + } + function testEncodeBitmap() public { assertEq(BEFORE_SET_RECORD, uint8(0x01), "0b00000001"); assertEq(AFTER_SET_RECORD, uint8(0x02), "0b00000010"); @@ -193,7 +199,7 @@ contract StoreHookTest is Test, GasReporter { vm.expectEmit(true, true, true, true); emit HookCalled( abi.encodeCall( - echoSubscriber.onBeforeSetRecord, + IStoreHook.onBeforeSetRecord, (tableId, key, staticData, encodedLengths, emptyDynamicData, fieldLayout) ) ); diff --git a/packages/store/test/StoreMock.sol b/packages/store/test/StoreMock.sol index 761fbf282a..14eb95c89b 100644 --- a/packages/store/test/StoreMock.sol +++ b/packages/store/test/StoreMock.sol @@ -7,6 +7,7 @@ import { StoreCore } from "../src/StoreCore.sol"; import { Schema } from "../src/Schema.sol"; import { FieldLayout } from "../src/FieldLayout.sol"; import { StoreRead } from "../src/StoreRead.sol"; +import { ResourceId } from "../src/ResourceId.sol"; /** * StoreMock is a contract wrapper around the StoreCore library for testing purposes. @@ -19,7 +20,7 @@ contract StoreMock is IStore, StoreRead { // Set full record (including full dynamic data) function setRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, bytes calldata staticData, PackedCounter encodedLengths, @@ -31,7 +32,7 @@ contract StoreMock is IStore, StoreRead { // Splice data in the static part of the record function spliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint48 start, uint40 deleteCount, @@ -42,7 +43,7 @@ contract StoreMock is IStore, StoreRead { // Splice data in the dynamic part of the record function spliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -54,7 +55,7 @@ contract StoreMock is IStore, StoreRead { // Set partial data at field index function setField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, bytes calldata data, @@ -65,7 +66,7 @@ contract StoreMock is IStore, StoreRead { // Push encoded items to the dynamic field at field index function pushToField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, bytes calldata dataToPush, @@ -76,7 +77,7 @@ contract StoreMock is IStore, StoreRead { // Pop byte length from the dynamic field at field index function popFromField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, uint256 byteLengthToPop, @@ -87,7 +88,7 @@ contract StoreMock is IStore, StoreRead { // Change encoded items within the dynamic field at field index function updateInField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, uint256 startByteIndex, @@ -98,13 +99,13 @@ contract StoreMock is IStore, StoreRead { } // Set full record (including full dynamic data) - function deleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) public virtual { + function deleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) public virtual { StoreCore.deleteRecord(tableId, keyTuple, fieldLayout); } // Emit the ephemeral event without modifying storage function emitEphemeralRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, bytes calldata staticData, PackedCounter encodedLengths, @@ -115,7 +116,7 @@ contract StoreMock is IStore, StoreRead { } function registerTable( - bytes32 tableId, + ResourceId tableId, FieldLayout fieldLayout, Schema keySchema, Schema valueSchema, @@ -126,12 +127,12 @@ contract StoreMock is IStore, StoreRead { } // Register hook to be called when a record or field is set or deleted - function registerStoreHook(bytes32 tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) public virtual { + function registerStoreHook(ResourceId tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) public virtual { StoreCore.registerStoreHook(tableId, hookAddress, enabledHooksBitmap); } // Unregister hook to be called when a record or field is set or deleted - function unregisterStoreHook(bytes32 tableId, IStoreHook hookAddress) public virtual { + function unregisterStoreHook(ResourceId tableId, IStoreHook hookAddress) public virtual { StoreCore.unregisterStoreHook(tableId, hookAddress); } } diff --git a/packages/store/test/setDynamicDataLengthAtIndex.sol b/packages/store/test/setDynamicDataLengthAtIndex.sol index 10bb2c9872..146ffddfee 100644 --- a/packages/store/test/setDynamicDataLengthAtIndex.sol +++ b/packages/store/test/setDynamicDataLengthAtIndex.sol @@ -4,12 +4,13 @@ pragma solidity >=0.8.0; import { PackedCounter } from "../src/PackedCounter.sol"; import { StoreCoreInternal } from "../src/StoreCore.sol"; import { Storage } from "../src/Storage.sol"; +import { ResourceId } from "../src/ResourceId.sol"; /** * Test helper function to set the length of the dynamic data (in bytes) for the given value field layout and index */ function setDynamicDataLengthAtIndex( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8 dynamicFieldIndex, // fieldIndex - numStaticFields uint256 newLengthAtIndex diff --git a/packages/store/ts/codegen/renderTable.ts b/packages/store/ts/codegen/renderTable.ts index ad0b6d9cab..0e97775183 100644 --- a/packages/store/ts/codegen/renderTable.ts +++ b/packages/store/ts/codegen/renderTable.ts @@ -53,6 +53,8 @@ export function renderTable(options: RenderTableOptions) { import { FieldLayout, FieldLayoutLib } from "${storeImportPath}FieldLayout.sol"; import { Schema, SchemaLib } from "${storeImportPath}Schema.sol"; import { PackedCounter, PackedCounterLib } from "${storeImportPath}PackedCounter.sol"; + import { ResourceId } from "${storeImportPath}ResourceId.sol"; + import { RESOURCE_TABLE } from "${storeImportPath}storeResourceTypes.sol"; ${ imports.length > 0 diff --git a/packages/store/ts/config/storeConfig.ts b/packages/store/ts/config/storeConfig.ts index 2795a266ff..36a951b862 100644 --- a/packages/store/ts/config/storeConfig.ts +++ b/packages/store/ts/config/storeConfig.ts @@ -11,14 +11,15 @@ import { // validation utils getDuplicates, parseStaticArray, - STORE_SELECTOR_MAX_LENGTH, + STORE_NAME_MAX_LENGTH, // config MUDCoreUserConfig, // schemas zObjectName, - zSelector, zUserEnum, zValueName, + zNamespace, + zName, } from "@latticexyz/config"; import { DEFAULTS, PATH_DEFAULTS, TABLE_DEFAULTS } from "./defaults"; @@ -127,7 +128,7 @@ export interface ExpandTableConfig, TableN const zFullTableConfig = z .object({ directory: z.string().default(TABLE_DEFAULTS.directory), - name: zSelector.optional(), + name: zName.optional(), tableIdArgument: z.boolean().default(TABLE_DEFAULTS.tableIdArgument), storeArgument: z.boolean().default(TABLE_DEFAULTS.storeArgument), dataStruct: z.boolean().optional(), @@ -170,7 +171,7 @@ export const zTablesConfig = z.record(zTableName, zTableConfig).transform((table // default name depends on tableName for (const tableName of Object.keys(tables)) { const table = tables[tableName]; - table.name = tableName.slice(0, STORE_SELECTOR_MAX_LENGTH); + table.name = tableName.slice(0, STORE_NAME_MAX_LENGTH); tables[tableName] = table; } @@ -271,7 +272,7 @@ export type MUDUserConfig< const StoreConfigUnrefined = z .object({ - namespace: zSelector.default(DEFAULTS.namespace), + namespace: zNamespace.default(DEFAULTS.namespace), storeImportPath: z.string().default(PATH_DEFAULTS.storeImportPath), tables: zTablesConfig, userTypesFilename: z.string().default(PATH_DEFAULTS.userTypesFilename), diff --git a/packages/store/ts/storeEventsAbi.test.ts b/packages/store/ts/storeEventsAbi.test.ts index 17b704d341..55d23793c4 100644 --- a/packages/store/ts/storeEventsAbi.test.ts +++ b/packages/store/ts/storeEventsAbi.test.ts @@ -5,26 +5,29 @@ import { AbiEvent } from "abitype"; // Make sure `storeEvents` stays in sync with Solidity definition/events +function normalizeAbiEvents(abiEvents: readonly AbiEvent[]) { + return abiEvents + .map((item) => ({ + type: item.type, + name: item.name, + inputs: item.inputs.map((input) => ({ + type: input.type, + name: input.name, + ...(input.indexed ? { indexed: true } : null), + })), + })) + .sort((a, b) => a.name.localeCompare(b.name)); +} + describe("storeEventsAbi", () => { it("should match the store ABI", () => { - const expectedEvents = IStoreAbi.filter((item) => item.type === "event").filter( - (item) => item.name !== "HelloStore" - ) as readonly AbiEvent[]; - - const expectedAbi = expectedEvents - .map((item) => ({ - // return data in a shape that matches abitype's parseAbi - type: item.type, - name: item.name, - inputs: item.inputs.map((input) => ({ - name: input.name, - type: input.type, - ...(input.indexed ? { indexed: true } : null), - })), - })) - .sort((a, b) => a.name.localeCompare(b.name)); + const eventsDefined = normalizeAbiEvents(storeEventsAbi); + const eventsFromAbi = normalizeAbiEvents( + IStoreAbi.filter((item) => item.type === "event").filter( + (item) => item.name !== "HelloStore" + ) as readonly AbiEvent[] + ); - const sortedStoreEventsAbi = [...storeEventsAbi].sort((a, b) => a.name.localeCompare(b.name)); - expect(sortedStoreEventsAbi).toStrictEqual(expectedAbi); + expect(JSON.stringify(eventsDefined)).toEqual(JSON.stringify(eventsFromAbi)); }); }); diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index c021f1084d..1a53c2c895 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -3,31 +3,31 @@ "file": "test/AccessControl.t.sol", "test": "testAccessControl", "name": "AccessControl: hasAccess (cold)", - "gasUsed": 6924 + "gasUsed": 7179 }, { "file": "test/AccessControl.t.sol", "test": "testAccessControl", "name": "AccessControl: hasAccess (warm, namespace only)", - "gasUsed": 1534 + "gasUsed": 1727 }, { "file": "test/AccessControl.t.sol", "test": "testAccessControl", "name": "AccessControl: hasAccess (warm)", - "gasUsed": 2944 + "gasUsed": 3187 }, { "file": "test/AccessControl.t.sol", "test": "testRequireAccess", "name": "AccessControl: requireAccess (cold)", - "gasUsed": 6966 + "gasUsed": 7222 }, { "file": "test/AccessControl.t.sol", "test": "testRequireAccess", "name": "AccessControl: requireAccess (warm)", - "gasUsed": 2969 + "gasUsed": 3225 }, { "file": "test/AccessControl.t.sol", @@ -39,342 +39,366 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallComposite", "name": "install keys in table module", - "gasUsed": 1413512 + "gasUsed": 1414600 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "install keys in table module", - "gasUsed": 1413512 + "gasUsed": 1414600 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "set a record on a table with keysInTableModule installed", - "gasUsed": 157414 + "gasUsed": 158308 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallSingleton", "name": "install keys in table module", - "gasUsed": 1413512 + "gasUsed": 1414600 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "install keys in table module", - "gasUsed": 1413512 + "gasUsed": 1414600 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "change a composite record on a table with keysInTableModule installed", - "gasUsed": 22025 + "gasUsed": 22290 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "delete a composite record on a table with keysInTableModule installed", - "gasUsed": 157762 + "gasUsed": 160543 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "install keys in table module", - "gasUsed": 1413512 + "gasUsed": 1414600 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "change a record on a table with keysInTableModule installed", - "gasUsed": 20747 + "gasUsed": 21012 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "delete a record on a table with keysInTableModule installed", - "gasUsed": 84152 + "gasUsed": 85675 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "install keys with value module", - "gasUsed": 652783 + "gasUsed": 664896 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "Get list of keys with a given value", - "gasUsed": 5338 + "gasUsed": 6175 }, { "file": "test/KeysWithValueModule.t.sol", - "test": "testGetTargetTableSelector", + "test": "testGetTargetTableId", "name": "compute the target table selector", - "gasUsed": 2234 + "gasUsed": 3071 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "install keys with value module", - "gasUsed": 652783 + "gasUsed": 664896 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "set a record on a table with KeysWithValueModule installed", - "gasUsed": 134041 + "gasUsed": 135679 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "install keys with value module", - "gasUsed": 652783 + "gasUsed": 664896 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "change a record on a table with KeysWithValueModule installed", - "gasUsed": 104450 + "gasUsed": 106088 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "delete a record on a table with KeysWithValueModule installed", - "gasUsed": 33978 + "gasUsed": 35339 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "install keys with value module", - "gasUsed": 652783 + "gasUsed": 664896 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "set a field on a table with KeysWithValueModule installed", - "gasUsed": 145891 + "gasUsed": 148411 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "change a field on a table with KeysWithValueModule installed", - "gasUsed": 110650 + "gasUsed": 113170 }, { "file": "test/query.t.sol", "test": "testCombinedHasHasValueNotQuery", "name": "CombinedHasHasValueNotQuery", - "gasUsed": 101456 + "gasUsed": 104597 }, { "file": "test/query.t.sol", "test": "testCombinedHasHasValueQuery", "name": "CombinedHasHasValueQuery", - "gasUsed": 51595 + "gasUsed": 54366 }, { "file": "test/query.t.sol", "test": "testCombinedHasNotQuery", "name": "CombinedHasNotQuery", - "gasUsed": 127301 + "gasUsed": 128263 }, { "file": "test/query.t.sol", "test": "testCombinedHasQuery", "name": "CombinedHasQuery", - "gasUsed": 80857 + "gasUsed": 81486 }, { "file": "test/query.t.sol", "test": "testCombinedHasValueNotQuery", "name": "CombinedHasValueNotQuery", - "gasUsed": 82233 + "gasUsed": 83650 }, { "file": "test/query.t.sol", "test": "testCombinedHasValueQuery", "name": "CombinedHasValueQuery", - "gasUsed": 14940 + "gasUsed": 16664 }, { "file": "test/query.t.sol", "test": "testHasQuery", "name": "HasQuery", - "gasUsed": 17953 + "gasUsed": 18101 }, { "file": "test/query.t.sol", "test": "testHasQuery1000Keys", "name": "HasQuery with 1000 keys", - "gasUsed": 5901526 + "gasUsed": 5938600 }, { "file": "test/query.t.sol", "test": "testHasQuery100Keys", "name": "HasQuery with 100 keys", - "gasUsed": 550220 + "gasUsed": 553994 }, { "file": "test/query.t.sol", "test": "testHasValueQuery", "name": "HasValueQuery", - "gasUsed": 7141 + "gasUsed": 8003 }, { "file": "test/query.t.sol", "test": "testNotValueQuery", "name": "NotValueQuery", - "gasUsed": 45191 + "gasUsed": 47962 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "register a callbound delegation", - "gasUsed": 113954 + "gasUsed": 114520 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "call a system via a callbound delegation", - "gasUsed": 33517 + "gasUsed": 34023 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "register a timebound delegation", - "gasUsed": 108418 + "gasUsed": 108972 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "call a system via a timebound delegation", - "gasUsed": 26642 + "gasUsed": 27100 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "install unique entity module", - "gasUsed": 678987 + "gasUsed": 689839 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "get a unique entity nonce (non-root module)", - "gasUsed": 51263 + "gasUsed": 52112 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "installRoot unique entity module", - "gasUsed": 669072 + "gasUsed": 680105 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "get a unique entity nonce (root module)", - "gasUsed": 51263 + "gasUsed": 52112 }, { "file": "test/World.t.sol", "test": "testCall", "name": "call a system via the World", - "gasUsed": 12356 + "gasUsed": 12769 }, { "file": "test/World.t.sol", "test": "testCallFromUnlimitedDelegation", "name": "register an unlimited delegation", - "gasUsed": 50265 + "gasUsed": 50584 }, { "file": "test/World.t.sol", "test": "testCallFromUnlimitedDelegation", "name": "call a system via an unlimited delegation", - "gasUsed": 12705 + "gasUsed": 12961 }, { "file": "test/World.t.sol", "test": "testDeleteRecord", "name": "Delete record", - "gasUsed": 8888 + "gasUsed": 9120 }, { "file": "test/World.t.sol", "test": "testPushToField", "name": "Push data to the table", - "gasUsed": 86650 + "gasUsed": 86882 }, { "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a fallback system", - "gasUsed": 58852 + "gasUsed": 59355 }, { "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a root fallback system", - "gasUsed": 52169 + "gasUsed": 52902 }, { "file": "test/World.t.sol", "test": "testRegisterFunctionSelector", "name": "Register a function selector", - "gasUsed": 79446 + "gasUsed": 79949 }, { "file": "test/World.t.sol", "test": "testRegisterNamespace", "name": "Register a new namespace", - "gasUsed": 122816 + "gasUsed": 123062 }, { "file": "test/World.t.sol", "test": "testRegisterRootFunctionSelector", "name": "Register a root function selector", - "gasUsed": 74087 + "gasUsed": 74815 + }, + { + "file": "test/World.t.sol", + "test": "testRegisterSystem", + "name": "register a system", + "gasUsed": 165531 }, { "file": "test/World.t.sol", "test": "testRegisterTable", "name": "Register a new table in the namespace", - "gasUsed": 641696 + "gasUsed": 651531 }, { "file": "test/World.t.sol", "test": "testSetField", "name": "Write data to a table field", - "gasUsed": 37171 + "gasUsed": 37403 }, { "file": "test/World.t.sol", "test": "testSetRecord", "name": "Write data to the table", - "gasUsed": 35165 + "gasUsed": 35397 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (cold)", - "gasUsed": 24401 + "gasUsed": 24633 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (warm)", - "gasUsed": 13547 + "gasUsed": 13779 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (cold)", - "gasUsed": 25012 + "gasUsed": 25244 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (warm)", - "gasUsed": 14217 + "gasUsed": 14449 + }, + { + "file": "test/WorldResourceId.t.sol", + "test": "testGetNamespace", + "name": "encode namespace, name and type", + "gasUsed": 151 + }, + { + "file": "test/WorldResourceId.t.sol", + "test": "testGetNamespaceId", + "name": "get namespace ID from a resource ID", + "gasUsed": 175 + }, + { + "file": "test/WorldResourceId.t.sol", + "test": "testGetType", + "name": "get type from a resource ID", + "gasUsed": 4 } ] diff --git a/packages/world/mud.config.ts b/packages/world/mud.config.ts index 1ad535703d..1a77d8309b 100644 --- a/packages/world/mud.config.ts +++ b/packages/world/mud.config.ts @@ -13,7 +13,7 @@ export default mudConfig({ ************************************************************************/ NamespaceOwner: { keySchema: { - namespace: "bytes16", + namespaceId: "bytes32", }, valueSchema: { owner: "address", @@ -21,7 +21,7 @@ export default mudConfig({ }, ResourceAccess: { keySchema: { - resourceSelector: "bytes32", + resourceId: "bytes32", caller: "address", }, valueSchema: { @@ -54,7 +54,7 @@ export default mudConfig({ Balances: { directory: "modules/core/tables", keySchema: { - namespace: "bytes16", + namespaceId: "bytes32", }, valueSchema: { balance: "uint256", @@ -63,7 +63,7 @@ export default mudConfig({ Systems: { directory: "modules/core/tables", keySchema: { - resourceSelector: "bytes32", + systemId: "bytes32", }, valueSchema: { system: "address", @@ -77,32 +77,23 @@ export default mudConfig({ system: "address", }, valueSchema: { - resourceSelector: "bytes32", + systemId: "bytes32", }, }, SystemHooks: { directory: "modules/core/tables", keySchema: { - resourceSelector: "bytes32", + systemId: "bytes32", }, valueSchema: "bytes21[]", }, - ResourceType: { - directory: "modules/core/tables", - keySchema: { - resourceSelector: "bytes32", - }, - valueSchema: { - resourceType: "Resource", - }, - }, FunctionSelectors: { directory: "modules/core/tables", keySchema: { functionSelector: "bytes4", }, valueSchema: { - resourceSelector: "bytes32", + systemId: "bytes32", systemFunctionSelector: "bytes4", }, dataStruct: false, @@ -149,7 +140,7 @@ export default mudConfig({ keySchema: { delegator: "address", delegatee: "address", - resourceSelector: "bytes32", + systemId: "bytes32", callDataHash: "bytes32", }, valueSchema: { @@ -185,10 +176,6 @@ export default mudConfig({ tableIdArgument: true, }, }, - enums: { - Resource: ["NONE", "NAMESPACE", "TABLE", "SYSTEM"], - }, - excludeSystems: [ // IUniqueEntitySystem is not part of the root namespace and // installed separately by UniqueEntityModule. diff --git a/packages/world/src/AccessControl.sol b/packages/world/src/AccessControl.sol index d99fd415ef..6cb5cc12ce 100644 --- a/packages/world/src/AccessControl.sol +++ b/packages/world/src/AccessControl.sol @@ -1,43 +1,43 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { ResourceSelector } from "./ResourceSelector.sol"; +import { ResourceId, WorldResourceIdInstance } from "./WorldResourceId.sol"; import { IWorldErrors } from "./interfaces/IWorldErrors.sol"; import { ResourceAccess } from "./tables/ResourceAccess.sol"; import { NamespaceOwner } from "./tables/NamespaceOwner.sol"; library AccessControl { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; /** * Returns true if the caller has access to the namespace or name, false otherwise. */ - function hasAccess(bytes32 resourceSelector, address caller) internal view returns (bool) { + function hasAccess(ResourceId resourceId, address caller) internal view returns (bool) { return address(this) == caller || // First check if the World is calling itself - ResourceAccess._get(resourceSelector.getNamespace(), caller) || // Then check access based on the namespace - ResourceAccess._get(resourceSelector, caller); // If caller has no namespace access, check access on the name + ResourceAccess._get(ResourceId.unwrap(resourceId.getNamespaceId()), caller) || // Then check access based on the namespace + ResourceAccess._get(ResourceId.unwrap(resourceId), caller); // If caller has no namespace access, check access on the name } /** * Check for access at the given namespace or name. * Reverts with AccessDenied if the caller has no access. */ - function requireAccess(bytes32 resourceSelector, address caller) internal view { + function requireAccess(ResourceId resourceId, address caller) internal view { // Check if the given caller has access to the given namespace or name - if (!hasAccess(resourceSelector, caller)) { - revert IWorldErrors.AccessDenied(resourceSelector.toString(), caller); + if (!hasAccess(resourceId, caller)) { + revert IWorldErrors.AccessDenied(resourceId.toString(), caller); } } /** - * Check for ownership of the namespace of the given resource selector. + * Check for ownership of the namespace of the given resource ID. * Reverts with AccessDenied if the check fails. */ - function requireOwner(bytes32 resourceSelector, address caller) internal view { - if (NamespaceOwner._get(resourceSelector.getNamespace()) != caller) { - revert IWorldErrors.AccessDenied(resourceSelector.toString(), caller); + function requireOwner(ResourceId resourceId, address caller) internal view { + if (NamespaceOwner._get(ResourceId.unwrap(resourceId.getNamespaceId())) != caller) { + revert IWorldErrors.AccessDenied(resourceId.toString(), caller); } } } diff --git a/packages/world/src/Delegation.sol b/packages/world/src/Delegation.sol index 14855a1ae0..191142f39c 100644 --- a/packages/world/src/Delegation.sol +++ b/packages/world/src/Delegation.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.0; import { UNLIMITED_DELEGATION } from "./constants.sol"; import { IDelegationControl } from "./interfaces/IDelegationControl.sol"; import { SystemCall } from "./SystemCall.sol"; +import { ResourceId } from "./WorldResourceId.sol"; type Delegation is bytes32; @@ -15,7 +16,7 @@ library DelegationInstance { } function isUnlimited(Delegation self) internal pure returns (bool) { - return Delegation.unwrap(self) == UNLIMITED_DELEGATION; + return Delegation.unwrap(self) == ResourceId.unwrap(UNLIMITED_DELEGATION); } function isLimited(Delegation self) internal pure returns (bool) { @@ -31,7 +32,7 @@ library DelegationInstance { Delegation self, address delegator, address delegatee, - bytes32 systemId, + ResourceId systemId, bytes memory callData ) internal returns (bool) { // Early return if there is an unlimited delegation @@ -43,7 +44,7 @@ library DelegationInstance { // Call the delegation control contract to check if the delegator has granted access to the delegatee (bool success, bytes memory data) = SystemCall.call({ caller: delegatee, - resourceSelector: Delegation.unwrap(self), + systemId: ResourceId.wrap(Delegation.unwrap(self)), callData: abi.encodeCall(IDelegationControl.verify, (delegator, systemId, callData)), value: 0 }); diff --git a/packages/world/src/ResourceSelector.sol b/packages/world/src/ResourceSelector.sol deleted file mode 100644 index 8ed6b39326..0000000000 --- a/packages/world/src/ResourceSelector.sol +++ /dev/null @@ -1,66 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; -import { ROOT_NAMESPACE, ROOT_NAME } from "./constants.sol"; -import { Bytes } from "@latticexyz/store/src/Bytes.sol"; - -bytes16 constant ROOT_NAMESPACE_STRING = bytes16("ROOT_NAMESPACE"); -bytes16 constant ROOT_NAME_STRING = bytes16("ROOT_NAME"); - -library ResourceSelector { - /** - * Create a 32-byte resource selector from a namespace and a name. - * - * A ResourceSelector is a 32-byte value that uniquely identifies a resource. - * The first 16 bytes represent the namespace, the last 16 bytes represent the name. - */ - function from(bytes16 namespace, bytes16 name) internal pure returns (bytes32) { - return bytes32(namespace) | (bytes32(name) >> 128); - } - - /** - * Create a 32-byte resource selector from a namespace. The selector points to the namespace's root name. - */ - function from(bytes16 namespace) internal pure returns (bytes32) { - return bytes32(namespace); - } - - /** - * Get the namespace of a ResourceSelector. - */ - function getNamespace(bytes32 resourceSelector) internal pure returns (bytes16) { - return bytes16(resourceSelector); - } - - /** - * Get the name of a ResourceSelector. - */ - function getName(bytes32 resourceSelector) internal pure returns (bytes16) { - return bytes16(resourceSelector << 128); - } - - /** - * Convert a selector to a string for more readable logs - */ - function toString(bytes32 resourceSelector) internal pure returns (string memory) { - bytes16 namespace = getNamespace(resourceSelector); - bytes16 name = getName(resourceSelector); - return - string( - abi.encodePacked( - namespace == ROOT_NAMESPACE ? ROOT_NAMESPACE_STRING : namespace, - "/", - name == ROOT_NAME ? ROOT_NAME_STRING : name - ) - ); - } - - /** - * Convert a selector to a trimmed string (no trailing `null` ASCII characters) - */ - function toTrimmedString(bytes16 selector) internal pure returns (string memory) { - uint256 length; - for (; length < 16; length++) if (Bytes.slice1(selector, length) == 0) break; - bytes memory packedSelector = abi.encodePacked(selector); - return string(Bytes.setLength(packedSelector, length)); - } -} diff --git a/packages/world/src/SystemCall.sol b/packages/world/src/SystemCall.sol index 27241b9a6b..568f47e4ee 100644 --- a/packages/world/src/SystemCall.sol +++ b/packages/world/src/SystemCall.sol @@ -3,10 +3,9 @@ pragma solidity >=0.8.0; import { Hook } from "@latticexyz/store/src/Hook.sol"; -import { ResourceSelector } from "./ResourceSelector.sol"; +import { ResourceId, WorldResourceIdInstance } from "./WorldResourceId.sol"; import { WorldContextProvider } from "./WorldContext.sol"; import { AccessControl } from "./AccessControl.sol"; -import { ResourceSelector } from "./ResourceSelector.sol"; import { ROOT_NAMESPACE } from "./constants.sol"; import { WorldContextProvider } from "./WorldContext.sol"; import { revertWithBytes } from "./revertWithBytes.sol"; @@ -21,36 +20,36 @@ import { SystemHooks } from "./modules/core/tables/SystemHooks.sol"; import { Balances } from "./modules/core/tables/Balances.sol"; library SystemCall { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; /** - * Calls a system via its resource selector and perform access control checks. + * Calls a system via its ID and perform access control checks. * Does not revert if the call fails, but returns a `success` flag along with the returndata. */ function call( address caller, uint256 value, - bytes32 resourceSelector, + ResourceId systemId, bytes memory callData ) internal returns (bool success, bytes memory data) { // Load the system data - (address systemAddress, bool publicAccess) = Systems._get(resourceSelector); + (address systemAddress, bool publicAccess) = Systems._get(ResourceId.unwrap(systemId)); // Check if the system exists - if (systemAddress == address(0)) revert IWorldErrors.ResourceNotFound(resourceSelector.toString()); + if (systemAddress == address(0)) revert IWorldErrors.ResourceNotFound(systemId, systemId.toString()); // Allow access if the system is public or the caller has access to the namespace or name - if (!publicAccess) AccessControl.requireAccess(resourceSelector, caller); + if (!publicAccess) AccessControl.requireAccess(systemId, caller); // If the msg.value is non-zero, update the namespace's balance if (value > 0) { - bytes16 namespace = resourceSelector.getNamespace(); - uint256 currentBalance = Balances._get(namespace); - Balances._set(namespace, currentBalance + value); + ResourceId namespaceId = systemId.getNamespaceId(); + uint256 currentBalance = Balances._get(ResourceId.unwrap(namespaceId)); + Balances._set(ResourceId.unwrap(namespaceId), currentBalance + value); } // Call the system and forward any return data - (success, data) = resourceSelector.getNamespace() == ROOT_NAMESPACE // Use delegatecall for root systems (= registered in the root namespace) + (success, data) = systemId.getNamespace() == ROOT_NAMESPACE // Use delegatecall for root systems (= registered in the root namespace) ? WorldContextProvider.delegatecallWithContext({ msgSender: caller, msgValue: value, @@ -66,52 +65,52 @@ library SystemCall { } /** - * Calls a system via its resource selector, perform access control checks and trigger hooks registered for the system. + * Calls a system via its ID, perform access control checks and trigger hooks registered for the system. * Does not revert if the call fails, but returns a `success` flag along with the returndata. */ function callWithHooks( address caller, - bytes32 resourceSelector, + ResourceId systemId, bytes memory callData, uint256 value ) internal returns (bool success, bytes memory data) { // Get system hooks - bytes21[] memory hooks = SystemHooks._get(resourceSelector); + bytes21[] memory hooks = SystemHooks._get(ResourceId.unwrap(systemId)); // Call onBeforeCallSystem hooks (before calling the system) for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(BEFORE_CALL_SYSTEM)) { - ISystemHook(hook.getAddress()).onBeforeCallSystem(caller, resourceSelector, callData); + ISystemHook(hook.getAddress()).onBeforeCallSystem(caller, systemId, callData); } } // Call the system and forward any return data - (success, data) = call({ caller: caller, value: value, resourceSelector: resourceSelector, callData: callData }); + (success, data) = call({ caller: caller, value: value, systemId: systemId, callData: callData }); // Call onAfterCallSystem hooks (after calling the system) for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(AFTER_CALL_SYSTEM)) { - ISystemHook(hook.getAddress()).onAfterCallSystem(caller, resourceSelector, callData); + ISystemHook(hook.getAddress()).onAfterCallSystem(caller, systemId, callData); } } } /** - * Calls a system via its resource selector, perform access control checks and trigger hooks registered for the system. + * Calls a system via its ID, perform access control checks and trigger hooks registered for the system. * Reverts if the call fails. */ function callWithHooksOrRevert( address caller, - bytes32 resourceSelector, + ResourceId systemId, bytes memory callData, uint256 value ) internal returns (bytes memory data) { (bool success, bytes memory returnData) = callWithHooks({ caller: caller, value: value, - resourceSelector: resourceSelector, + systemId: systemId, callData: callData }); if (!success) revertWithBytes(returnData); diff --git a/packages/world/src/Utils.sol b/packages/world/src/Utils.sol index b54e5d7653..af6e23a62c 100644 --- a/packages/world/src/Utils.sol +++ b/packages/world/src/Utils.sol @@ -2,10 +2,12 @@ pragma solidity >=0.8.0; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; -import { ResourceSelector } from "./ResourceSelector.sol"; +import { ResourceId, WorldResourceIdInstance } from "./WorldResourceId.sol"; import { SystemRegistry } from "./index.sol"; library Utils { + using WorldResourceIdInstance for ResourceId; + /** * Get the namespace of this system. * Must be used within the context of a system (either directly, or within libraries called by a system). @@ -17,8 +19,8 @@ library Utils { if (StoreSwitch.getStoreAddress() == address(this)) { return ""; } else { - bytes32 resourceSelector = SystemRegistry.get(address(this)); - return ResourceSelector.getNamespace(resourceSelector); + ResourceId systemId = ResourceId.wrap(SystemRegistry.get(address(this))); + return systemId.getNamespace(); } } } diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index 73464c011b..f24bf892e1 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -12,8 +12,8 @@ import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; import { WORLD_VERSION } from "./version.sol"; import { System } from "./System.sol"; -import { ResourceSelector } from "./ResourceSelector.sol"; -import { ROOT_NAMESPACE, ROOT_NAME } from "./constants.sol"; +import { ResourceId, WorldResourceIdInstance } from "./WorldResourceId.sol"; +import { ROOT_NAMESPACE_ID, ROOT_NAMESPACE, ROOT_NAME } from "./constants.sol"; import { AccessControl } from "./AccessControl.sol"; import { SystemCall } from "./SystemCall.sol"; import { WorldContextProvider } from "./WorldContext.sol"; @@ -36,7 +36,7 @@ import { Balances } from "./modules/core/tables/Balances.sol"; import { CORE_MODULE_NAME } from "./modules/core/constants.sol"; contract World is StoreRead, IStoreData, IWorldKernel { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; address public immutable creator; function worldVersion() public pure returns (bytes32) { @@ -55,7 +55,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { function initialize(IModule coreModule) public { // Only the initial creator of the World can initialize it if (msg.sender != creator) { - revert AccessDenied(ResourceSelector.from(ROOT_NAMESPACE).toString(), msg.sender); + revert AccessDenied(ROOT_NAMESPACE_ID.toString(), msg.sender); } // The World can only be initialized once @@ -73,7 +73,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { * The module is delegatecalled and installed in the root namespace. */ function installRootModule(IModule module, bytes memory args) public { - AccessControl.requireOwner(ROOT_NAMESPACE, msg.sender); + AccessControl.requireOwner(ROOT_NAMESPACE_ID, msg.sender); _installRootModule(module, args); } @@ -103,7 +103,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { * Requires the caller to have access to the table's namespace or name (encoded in the tableId). */ function setRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, bytes calldata staticData, PackedCounter encodedLengths, @@ -118,7 +118,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { } function spliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint48 start, uint40 deleteCount, @@ -132,7 +132,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { } function spliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 dynamicFieldIndex, uint40 startWithinField, @@ -151,7 +151,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { * Requires the caller to have access to the table's namespace or name (encoded in the tableId). */ function setField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, bytes calldata data, @@ -169,7 +169,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { * Requires the caller to have access to the table's namespace or name (encoded in the tableId). */ function pushToField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, bytes calldata dataToPush, @@ -187,7 +187,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { * Requires the caller to have access to the table's namespace or name (encoded in the tableId). */ function popFromField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, uint256 byteLengthToPop, @@ -205,7 +205,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { * Requires the caller to have access to the table's namespace or name (encoded in the tableId). */ function updateInField( - bytes32 tableId, + ResourceId tableId, bytes32[] calldata keyTuple, uint8 fieldIndex, uint256 startByteIndex, @@ -223,7 +223,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { * Delete a record in the table at the given tableId. * Requires the caller to have access to the namespace or name. */ - function deleteRecord(bytes32 tableId, bytes32[] calldata keyTuple, FieldLayout fieldLayout) public virtual { + function deleteRecord(ResourceId tableId, bytes32[] calldata keyTuple, FieldLayout fieldLayout) public virtual { // Require access to namespace or name AccessControl.requireAccess(tableId, msg.sender); @@ -238,40 +238,40 @@ contract World is StoreRead, IStoreData, IWorldKernel { ************************************************************************/ /** - * Call the system at the given resourceSelector. - * If the system is not public, the caller must have access to the namespace or name (encoded in the resourceSelector). + * Call the system at the given system ID. + * If the system is not public, the caller must have access to the namespace or name (encoded in the system ID). */ - function call(bytes32 resourceSelector, bytes memory callData) external payable virtual returns (bytes memory) { - return SystemCall.callWithHooksOrRevert(msg.sender, resourceSelector, callData, msg.value); + function call(ResourceId systemId, bytes memory callData) external payable virtual returns (bytes memory) { + return SystemCall.callWithHooksOrRevert(msg.sender, systemId, callData, msg.value); } /** - * Call the system at the given resourceSelector on behalf of the given delegator. - * If the system is not public, the delegator must have access to the namespace or name (encoded in the resourceSelector). + * Call the system at the given system ID on behalf of the given delegator. + * If the system is not public, the delegator must have access to the namespace or name (encoded in the system ID). */ function callFrom( address delegator, - bytes32 resourceSelector, + ResourceId systemId, bytes memory callData ) external payable virtual returns (bytes memory) { // If the delegator is the caller, call the system directly if (delegator == msg.sender) { - return SystemCall.callWithHooksOrRevert(msg.sender, resourceSelector, callData, msg.value); + return SystemCall.callWithHooksOrRevert(msg.sender, systemId, callData, msg.value); } // Check if there is an explicit authorization for this caller to perform actions on behalf of the delegator Delegation explicitDelegation = Delegation.wrap(Delegations._get({ delegator: delegator, delegatee: msg.sender })); - if (explicitDelegation.verify(delegator, msg.sender, resourceSelector, callData)) { + if (explicitDelegation.verify(delegator, msg.sender, systemId, callData)) { // forward the call as `delegator` - return SystemCall.callWithHooksOrRevert(delegator, resourceSelector, callData, msg.value); + return SystemCall.callWithHooksOrRevert(delegator, systemId, callData, msg.value); } // Check if the delegator has a fallback delegation control set Delegation fallbackDelegation = Delegation.wrap(Delegations._get({ delegator: delegator, delegatee: address(0) })); - if (fallbackDelegation.verify(delegator, msg.sender, resourceSelector, callData)) { + if (fallbackDelegation.verify(delegator, msg.sender, systemId, callData)) { // forward the call with `from` as `msgSender` - return SystemCall.callWithHooksOrRevert(delegator, resourceSelector, callData, msg.value); + return SystemCall.callWithHooksOrRevert(delegator, systemId, callData, msg.value); } revert DelegationNotFound(delegator, msg.sender); @@ -287,23 +287,28 @@ contract World is StoreRead, IStoreData, IWorldKernel { * ETH sent to the World without calldata is added to the root namespace's balance */ receive() external payable { - uint256 rootBalance = Balances._get(ROOT_NAMESPACE); - Balances._set(ROOT_NAMESPACE, rootBalance + msg.value); + uint256 rootBalance = Balances._get(ResourceId.unwrap(ROOT_NAMESPACE_ID)); + Balances._set(ResourceId.unwrap(ROOT_NAMESPACE_ID), rootBalance + msg.value); } /** * Fallback function to call registered function selectors */ fallback() external payable { - (bytes32 resourceSelector, bytes4 systemFunctionSelector) = FunctionSelectors._get(msg.sig); + (bytes32 systemId, bytes4 systemFunctionSelector) = FunctionSelectors._get(msg.sig); - if (resourceSelector == 0) revert FunctionSelectorNotFound(msg.sig); + if (systemId == 0) revert FunctionSelectorNotFound(msg.sig); // Replace function selector in the calldata with the system function selector bytes memory callData = Bytes.setBytes4(msg.data, 0, systemFunctionSelector); // Call the function and forward the call data - bytes memory returnData = SystemCall.callWithHooksOrRevert(msg.sender, resourceSelector, callData, msg.value); + bytes memory returnData = SystemCall.callWithHooksOrRevert( + msg.sender, + ResourceId.wrap(systemId), + callData, + msg.value + ); // If the call was successful, return the return data assembly { diff --git a/packages/world/src/WorldResourceId.sol b/packages/world/src/WorldResourceId.sol new file mode 100644 index 0000000000..db24aba8b9 --- /dev/null +++ b/packages/world/src/WorldResourceId.sol @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { Bytes } from "@latticexyz/store/src/Bytes.sol"; +import { ResourceId, ResourceIdInstance, TYPE_BYTES } from "@latticexyz/store/src/ResourceId.sol"; + +import { ROOT_NAMESPACE, ROOT_NAME } from "./constants.sol"; +import { RESOURCE_NAMESPACE, MASK_RESOURCE_NAMESPACE } from "./worldResourceTypes.sol"; + +uint256 constant NAMESPACE_BYTES = 14; +uint256 constant NAME_BYTES = 16; +uint256 constant BYTES_TO_BITS = 8; + +bytes16 constant ROOT_NAMESPACE_STRING = bytes16("ROOT_NAMESPACE"); +bytes16 constant ROOT_NAME_STRING = bytes16("ROOT_NAME"); + +bytes32 constant NAMESPACE_MASK = bytes32(~bytes14("")) >> (TYPE_BYTES * BYTES_TO_BITS); + +library WorldResourceIdLib { + /** + * Create a 32-byte resource ID from a namespace, name and type. + * + * A resource ID is a 32-byte value that uniquely identifies a resource. + * The first 14 bytes represent the namespace, + * the next 16 bytes represent the name, + * the last 2 bytes represent the type. + */ + function encode(bytes2 typeId, bytes14 namespace, bytes16 name) internal pure returns (ResourceId) { + return + ResourceId.wrap( + bytes32(typeId) | + (bytes32(namespace) >> (TYPE_BYTES * BYTES_TO_BITS)) | + (bytes32(name) >> ((TYPE_BYTES + NAMESPACE_BYTES) * BYTES_TO_BITS)) + ); + } + + /** + * Create a 32-byte resource ID from a namespace. + */ + function encodeNamespace(bytes14 namespace) internal pure returns (ResourceId) { + return ResourceId.wrap(bytes32(RESOURCE_NAMESPACE) | (bytes32(namespace) >> (TYPE_BYTES * BYTES_TO_BITS))); + } + + /** + * Convert a padded string to a trimmed string (no trailing `null` ASCII characters) + */ + function toTrimmedString(bytes16 paddedString) internal pure returns (string memory) { + uint256 length; + for (; length < 16; length++) if (Bytes.slice1(paddedString, length) == 0) break; + bytes memory packedSelector = abi.encodePacked(paddedString); + return string(Bytes.setLength(packedSelector, length)); + } +} + +library WorldResourceIdInstance { + /** + * Get the namespace of a resource ID. + */ + function getNamespace(ResourceId resourceId) internal pure returns (bytes14) { + return bytes14(ResourceId.unwrap(resourceId) << (TYPE_BYTES * BYTES_TO_BITS)); + } + + /** + * Get the namespace resource ID corresponding to the namespace of a resource ID. + */ + function getNamespaceId(ResourceId resourceId) internal pure returns (ResourceId) { + return ResourceId.wrap((ResourceId.unwrap(resourceId) & NAMESPACE_MASK) | MASK_RESOURCE_NAMESPACE); + } + + /** + * Get the name of a resource ID. + */ + function getName(ResourceId resourceId) internal pure returns (bytes16) { + return bytes16(ResourceId.unwrap(resourceId) << ((TYPE_BYTES + NAMESPACE_BYTES) * BYTES_TO_BITS)); + } + + /** + * Convert a resource ID to a string for more readable logs + */ + function toString(ResourceId resourceId) internal pure returns (string memory) { + bytes2 resourceType = ResourceIdInstance.getType(resourceId); + bytes14 resourceNamespace = getNamespace(resourceId); + bytes16 resourceName = getName(resourceId); + return + string( + abi.encodePacked( + resourceType, + ":", + resourceNamespace == ROOT_NAMESPACE ? ROOT_NAMESPACE_STRING : resourceNamespace, + ":", + resourceName == ROOT_NAME ? ROOT_NAME_STRING : resourceName + ) + ); + } +} diff --git a/packages/world/src/common.sol b/packages/world/src/common.sol deleted file mode 100644 index 6c4b0ff193..0000000000 --- a/packages/world/src/common.sol +++ /dev/null @@ -1,10 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -/* Autogenerated file. Do not edit manually. */ -enum Resource { - NONE, - NAMESPACE, - TABLE, - SYSTEM -} diff --git a/packages/world/src/constants.sol b/packages/world/src/constants.sol index a4a2538803..5f7e4ff646 100644 --- a/packages/world/src/constants.sol +++ b/packages/world/src/constants.sol @@ -1,6 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -bytes16 constant ROOT_NAMESPACE = 0; -bytes16 constant ROOT_NAME = 0; -bytes32 constant UNLIMITED_DELEGATION = bytes32(abi.encodePacked(ROOT_NAMESPACE, bytes16("unlimited.d"))); +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + +import { RESOURCE_SYSTEM, RESOURCE_NAMESPACE } from "./worldResourceTypes.sol"; + +bytes14 constant ROOT_NAMESPACE = ""; +bytes16 constant ROOT_NAME = ""; + +ResourceId constant ROOT_NAMESPACE_ID = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_NAMESPACE, ROOT_NAMESPACE, ROOT_NAME)) +); + +ResourceId constant UNLIMITED_DELEGATION = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_SYSTEM, ROOT_NAMESPACE, bytes16("unlimited"))) +); diff --git a/packages/world/src/factories/WorldFactory.sol b/packages/world/src/factories/WorldFactory.sol index 752ade4ddb..87af0543ed 100644 --- a/packages/world/src/factories/WorldFactory.sol +++ b/packages/world/src/factories/WorldFactory.sol @@ -6,7 +6,7 @@ import { World } from "../World.sol"; import { IWorldFactory } from "./IWorldFactory.sol"; import { IBaseWorld } from "../interfaces/IBaseWorld.sol"; import { IModule } from "../interfaces/IModule.sol"; -import { ROOT_NAMESPACE } from "../constants.sol"; +import { ROOT_NAMESPACE_ID } from "../constants.sol"; contract WorldFactory is IWorldFactory { IModule public coreModule; @@ -27,7 +27,7 @@ contract WorldFactory is IWorldFactory { // Initialize the World and transfer ownership to the caller world.initialize(coreModule); - world.transferOwnership(ROOT_NAMESPACE, msg.sender); + world.transferOwnership(ROOT_NAMESPACE_ID, msg.sender); emit WorldDeployed(worldAddress); } diff --git a/packages/world/src/index.sol b/packages/world/src/index.sol index 021a7371bf..2e852c4973 100644 --- a/packages/world/src/index.sol +++ b/packages/world/src/index.sol @@ -11,7 +11,6 @@ import { Balances, BalancesTableId } from "./modules/core/tables/Balances.sol"; import { Systems, SystemsTableId } from "./modules/core/tables/Systems.sol"; import { SystemRegistry, SystemRegistryTableId } from "./modules/core/tables/SystemRegistry.sol"; import { SystemHooks, SystemHooksTableId } from "./modules/core/tables/SystemHooks.sol"; -import { ResourceType, ResourceTypeTableId } from "./modules/core/tables/ResourceType.sol"; import { FunctionSelectors, FunctionSelectorsTableId } from "./modules/core/tables/FunctionSelectors.sol"; import { KeysWithValue } from "./modules/keyswithvalue/tables/KeysWithValue.sol"; import { KeysInTable, KeysInTableData, KeysInTableTableId } from "./modules/keysintable/tables/KeysInTable.sol"; diff --git a/packages/world/src/interfaces/IAccessManagementSystem.sol b/packages/world/src/interfaces/IAccessManagementSystem.sol index 8f443689d5..2e2c56e5a2 100644 --- a/packages/world/src/interfaces/IAccessManagementSystem.sol +++ b/packages/world/src/interfaces/IAccessManagementSystem.sol @@ -3,10 +3,12 @@ pragma solidity >=0.8.0; /* Autogenerated file. Do not edit manually. */ +import { ResourceId } from "./../WorldResourceId.sol"; + interface IAccessManagementSystem { - function grantAccess(bytes32 resourceSelector, address grantee) external; + function grantAccess(ResourceId resourceId, address grantee) external; - function revokeAccess(bytes32 resourceSelector, address grantee) external; + function revokeAccess(ResourceId resourceId, address grantee) external; - function transferOwnership(bytes16 namespace, address newOwner) external; + function transferOwnership(ResourceId namespaceId, address newOwner) external; } diff --git a/packages/world/src/interfaces/IBalanceTransferSystem.sol b/packages/world/src/interfaces/IBalanceTransferSystem.sol index eddb986957..a00a3bc15c 100644 --- a/packages/world/src/interfaces/IBalanceTransferSystem.sol +++ b/packages/world/src/interfaces/IBalanceTransferSystem.sol @@ -3,8 +3,10 @@ pragma solidity >=0.8.0; /* Autogenerated file. Do not edit manually. */ +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + interface IBalanceTransferSystem { - function transferBalanceToNamespace(bytes16 fromNamespace, bytes16 toNamespace, uint256 amount) external; + function transferBalanceToNamespace(ResourceId fromNamespaceId, ResourceId toNamespaceId, uint256 amount) external; - function transferBalanceToAddress(bytes16 fromNamespace, address toAddress, uint256 amount) external; + function transferBalanceToAddress(ResourceId fromNamespaceId, address toAddress, uint256 amount) external; } diff --git a/packages/world/src/interfaces/IDelegationControl.sol b/packages/world/src/interfaces/IDelegationControl.sol index 6f68af9b32..ab528c291b 100644 --- a/packages/world/src/interfaces/IDelegationControl.sol +++ b/packages/world/src/interfaces/IDelegationControl.sol @@ -2,11 +2,12 @@ pragma solidity >=0.8.0; import { IWorldContextConsumer, WORLD_CONTEXT_CONSUMER_INTERFACE_ID } from "./IWorldContextConsumer.sol"; +import { ResourceId } from "../WorldResourceId.sol"; // ERC-165 Interface ID (see https://eips.ethereum.org/EIPS/eip-165) bytes4 constant DELEGATION_CONTROL_INTERFACE_ID = IDelegationControl.verify.selector ^ WORLD_CONTEXT_CONSUMER_INTERFACE_ID; interface IDelegationControl is IWorldContextConsumer { - function verify(address delegator, bytes32 systemId, bytes memory callData) external returns (bool); + function verify(address delegator, ResourceId systemId, bytes memory callData) external returns (bool); } diff --git a/packages/world/src/interfaces/IModule.sol b/packages/world/src/interfaces/IModule.sol index a4eb728608..8a79abd7db 100644 --- a/packages/world/src/interfaces/IModule.sol +++ b/packages/world/src/interfaces/IModule.sol @@ -10,7 +10,6 @@ bytes4 constant MODULE_INTERFACE_ID = IModule.getName.selector ^ ERC165_INTERFACE_ID; interface IModule is IERC165 { - error RequiredModuleNotFound(string resourceSelector); error RootInstallModeNotSupported(); error NonRootInstallNotSupported(); diff --git a/packages/world/src/interfaces/ISystemHook.sol b/packages/world/src/interfaces/ISystemHook.sol index a09c15f796..d6bde335c0 100644 --- a/packages/world/src/interfaces/ISystemHook.sol +++ b/packages/world/src/interfaces/ISystemHook.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; +import { ResourceId } from "../WorldResourceId.sol"; // ERC-165 Interface ID (see https://eips.ethereum.org/EIPS/eip-165) bytes4 constant SYSTEM_HOOK_INTERFACE_ID = ISystemHook.onBeforeCallSystem.selector ^ @@ -9,7 +10,7 @@ bytes4 constant SYSTEM_HOOK_INTERFACE_ID = ISystemHook.onBeforeCallSystem.select ERC165_INTERFACE_ID; interface ISystemHook is IERC165 { - function onBeforeCallSystem(address msgSender, bytes32 resourceSelector, bytes memory callData) external; + function onBeforeCallSystem(address msgSender, ResourceId systemId, bytes memory callData) external; - function onAfterCallSystem(address msgSender, bytes32 resourceSelector, bytes memory callData) external; + function onAfterCallSystem(address msgSender, ResourceId systemId, bytes memory callData) external; } diff --git a/packages/world/src/interfaces/IWorldErrors.sol b/packages/world/src/interfaces/IWorldErrors.sol index 8804a161e9..ef421ff6b7 100644 --- a/packages/world/src/interfaces/IWorldErrors.sol +++ b/packages/world/src/interfaces/IWorldErrors.sol @@ -1,16 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; + interface IWorldErrors { error WorldAlreadyInitialized(); - error ResourceExists(string resource); - error ResourceNotFound(string resource); + error ResourceExists(ResourceId resourceId, string resourceIdString); + error ResourceNotFound(ResourceId resourceId, string resourceIdString); error AccessDenied(string resource, address caller); - error InvalidSelector(string resource); + error InvalidResourceId(ResourceId resourceId, string resourceIdString); error SystemExists(address system); error FunctionSelectorExists(bytes4 functionSelector); error FunctionSelectorNotFound(bytes4 functionSelector); error DelegationNotFound(address delegator, address delegatee); error InsufficientBalance(uint256 balance, uint256 amount); error InterfaceNotSupported(address contractAddress, bytes4 interfaceId); + error InvalidResourceType(bytes2 expected, ResourceId resourceId, string resourceIdString); } diff --git a/packages/world/src/interfaces/IWorldKernel.sol b/packages/world/src/interfaces/IWorldKernel.sol index 72395d553d..ccb0909b11 100644 --- a/packages/world/src/interfaces/IWorldKernel.sol +++ b/packages/world/src/interfaces/IWorldKernel.sol @@ -3,6 +3,7 @@ pragma solidity >=0.8.0; import { IWorldErrors } from "./IWorldErrors.sol"; import { IModule } from "./IModule.sol"; +import { ResourceId } from "../WorldResourceId.sol"; interface IWorldModuleInstallation { /** @@ -15,18 +16,18 @@ interface IWorldModuleInstallation { interface IWorldCall { /** - * Call the system at the given resourceSelector. - * If the system is not public, the caller must have access to the namespace or name (encoded in the resourceSelector). + * Call the system at the given system ID. + * If the system is not public, the caller must have access to the namespace or name (encoded in the system ID). */ - function call(bytes32 resourceSelector, bytes memory callData) external payable returns (bytes memory); + function call(ResourceId systemId, bytes memory callData) external payable returns (bytes memory); /** - * Call the system at the given resourceSelector on behalf of the given delegator. - * If the system is not public, the delegator must have access to the namespace or name (encoded in the resourceSelector). + * Call the system at the given system ID on behalf of the given delegator. + * If the system is not public, the delegator must have access to the namespace or name (encoded in the system ID). */ function callFrom( address delegator, - bytes32 resourceSelector, + ResourceId systemId, bytes memory callData ) external payable returns (bytes memory); } diff --git a/packages/world/src/interfaces/IWorldRegistrationSystem.sol b/packages/world/src/interfaces/IWorldRegistrationSystem.sol index eda464a074..46638d3ee6 100644 --- a/packages/world/src/interfaces/IWorldRegistrationSystem.sol +++ b/packages/world/src/interfaces/IWorldRegistrationSystem.sol @@ -3,29 +3,30 @@ pragma solidity >=0.8.0; /* Autogenerated file. Do not edit manually. */ +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; import { ISystemHook } from "./ISystemHook.sol"; import { WorldContextConsumer } from "./../WorldContext.sol"; interface IWorldRegistrationSystem { - function registerNamespace(bytes16 namespace) external; + function registerNamespace(ResourceId namespaceId) external; - function registerSystemHook(bytes32 resourceSelector, ISystemHook hookAddress, uint8 enabledHooksBitmap) external; + function registerSystemHook(ResourceId systemId, ISystemHook hookAddress, uint8 enabledHooksBitmap) external; - function unregisterSystemHook(bytes32 resourceSelector, ISystemHook hookAddress) external; + function unregisterSystemHook(ResourceId systemId, ISystemHook hookAddress) external; - function registerSystem(bytes32 resourceSelector, WorldContextConsumer system, bool publicAccess) external; + function registerSystem(ResourceId systemId, WorldContextConsumer system, bool publicAccess) external; function registerFunctionSelector( - bytes32 resourceSelector, + ResourceId systemId, string memory systemFunctionName, string memory systemFunctionArguments ) external returns (bytes4 worldFunctionSelector); function registerRootFunctionSelector( - bytes32 resourceSelector, + ResourceId systemId, bytes4 worldFunctionSelector, bytes4 systemFunctionSelector ) external returns (bytes4); - function registerDelegation(address delegatee, bytes32 delegationControlId, bytes memory initCallData) external; + function registerDelegation(address delegatee, ResourceId delegationControlId, bytes memory initCallData) external; } diff --git a/packages/world/src/modules/core/CoreModule.sol b/packages/world/src/modules/core/CoreModule.sol index 9e8698d72a..bdbaca2226 100644 --- a/packages/world/src/modules/core/CoreModule.sol +++ b/packages/world/src/modules/core/CoreModule.sol @@ -2,15 +2,16 @@ pragma solidity >=0.8.0; import { WorldContextProvider } from "../../WorldContext.sol"; -import { ROOT_NAMESPACE } from "../../constants.sol"; -import { Resource } from "../../common.sol"; +import { ROOT_NAMESPACE, ROOT_NAMESPACE_ID } from "../../constants.sol"; import { Module } from "../../Module.sol"; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; import { IStoreEphemeral } from "@latticexyz/store/src/IStore.sol"; import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; -import { ResourceSelector } from "../../ResourceSelector.sol"; +import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../../WorldResourceId.sol"; +import { RESOURCE_SYSTEM } from "../../worldResourceTypes.sol"; import { NamespaceOwner } from "../../tables/NamespaceOwner.sol"; import { ResourceAccess } from "../../tables/ResourceAccess.sol"; @@ -22,7 +23,6 @@ import { CORE_MODULE_NAME, CORE_SYSTEM_NAME } from "./constants.sol"; import { Systems } from "./tables/Systems.sol"; import { FunctionSelectors } from "./tables/FunctionSelectors.sol"; -import { ResourceType } from "./tables/ResourceType.sol"; import { SystemHooks } from "./tables/SystemHooks.sol"; import { SystemRegistry } from "./tables/SystemRegistry.sol"; import { Balances } from "./tables/Balances.sol"; @@ -74,11 +74,10 @@ contract CoreModule is Module { FunctionSelectors.register(); SystemHooks.register(); SystemRegistry.register(); - ResourceType.register(); - NamespaceOwner._set(ROOT_NAMESPACE, _msgSender()); - ResourceAccess._set(ROOT_NAMESPACE, _msgSender(), true); - ResourceType._set(ROOT_NAMESPACE, Resource.NAMESPACE); + ResourceIds._setExists(ResourceId.unwrap(ROOT_NAMESPACE_ID), true); + NamespaceOwner._set(ResourceId.unwrap(ROOT_NAMESPACE_ID), _msgSender()); + ResourceAccess._set(ResourceId.unwrap(ROOT_NAMESPACE_ID), _msgSender(), true); } /** @@ -92,7 +91,11 @@ contract CoreModule is Module { target: coreSystem, callData: abi.encodeCall( WorldRegistrationSystem.registerSystem, - (ResourceSelector.from(ROOT_NAMESPACE, CORE_SYSTEM_NAME), CoreSystem(coreSystem), true) + ( + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: ROOT_NAMESPACE, name: CORE_SYSTEM_NAME }), + CoreSystem(coreSystem), + true + ) ) }); } @@ -136,7 +139,11 @@ contract CoreModule is Module { target: coreSystem, callData: abi.encodeCall( WorldRegistrationSystem.registerRootFunctionSelector, - (ResourceSelector.from(ROOT_NAMESPACE, CORE_SYSTEM_NAME), functionSelectors[i], functionSelectors[i]) + ( + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: ROOT_NAMESPACE, name: CORE_SYSTEM_NAME }), + functionSelectors[i], + functionSelectors[i] + ) ) }); } diff --git a/packages/world/src/modules/core/implementations/AccessManagementSystem.sol b/packages/world/src/modules/core/implementations/AccessManagementSystem.sol index cff47dd2db..feb058a0d9 100644 --- a/packages/world/src/modules/core/implementations/AccessManagementSystem.sol +++ b/packages/world/src/modules/core/implementations/AccessManagementSystem.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.0; import { IModule } from "../../../interfaces/IModule.sol"; import { System } from "../../../System.sol"; import { AccessControl } from "../../../AccessControl.sol"; -import { ResourceSelector } from "../../../ResourceSelector.sol"; +import { ResourceId, WorldResourceIdLib } from "../../../WorldResourceId.sol"; import { ResourceAccess } from "../../../tables/ResourceAccess.sol"; import { InstalledModules } from "../../../tables/InstalledModules.sol"; import { NamespaceOwner } from "../../../tables/NamespaceOwner.sol"; @@ -14,27 +14,27 @@ import { NamespaceOwner } from "../../../tables/NamespaceOwner.sol"; */ contract AccessManagementSystem is System { /** - * Grant access to the resource at the given namespace and name. + * Grant access to the resource at the given resource ID. * Requires the caller to own the namespace. */ - function grantAccess(bytes32 resourceSelector, address grantee) public virtual { + function grantAccess(ResourceId resourceId, address grantee) public virtual { // Require the caller to own the namespace - AccessControl.requireOwner(resourceSelector, _msgSender()); + AccessControl.requireOwner(resourceId, _msgSender()); // Grant access to the given resource - ResourceAccess._set(resourceSelector, grantee, true); + ResourceAccess._set(ResourceId.unwrap(resourceId), grantee, true); } /** - * Revoke access from the resource at the given namespace and name. + * Revoke access from the resource at the given resource ID. * Requires the caller to own the namespace. */ - function revokeAccess(bytes32 resourceSelector, address grantee) public virtual { + function revokeAccess(ResourceId resourceId, address grantee) public virtual { // Require the caller to own the namespace - AccessControl.requireOwner(resourceSelector, _msgSender()); + AccessControl.requireOwner(resourceId, _msgSender()); // Revoke access from the given resource - ResourceAccess._deleteRecord(resourceSelector, grantee); + ResourceAccess._deleteRecord(ResourceId.unwrap(resourceId), grantee); } /** @@ -42,17 +42,17 @@ contract AccessManagementSystem is System { * Revoke ResourceAccess for previous owner and grant to newOwner. * Requires the caller to own the namespace. */ - function transferOwnership(bytes16 namespace, address newOwner) public virtual { + function transferOwnership(ResourceId namespaceId, address newOwner) public virtual { // Require the caller to own the namespace - AccessControl.requireOwner(namespace, _msgSender()); + AccessControl.requireOwner(namespaceId, _msgSender()); // Set namespace new owner - NamespaceOwner._set(namespace, newOwner); + NamespaceOwner._set(ResourceId.unwrap(namespaceId), newOwner); // Revoke access from old owner - ResourceAccess._deleteRecord(namespace, _msgSender()); + ResourceAccess._deleteRecord(ResourceId.unwrap(namespaceId), _msgSender()); // Grant access to new owner - ResourceAccess._set(namespace, newOwner, true); + ResourceAccess._set(ResourceId.unwrap(namespaceId), newOwner, true); } } diff --git a/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol b/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol index 9f0fdde1cd..5cbbb5a5cf 100644 --- a/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol +++ b/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol @@ -1,50 +1,63 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; +import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; + import { System } from "../../../System.sol"; import { revertWithBytes } from "../../../revertWithBytes.sol"; -import { ResourceSelector } from "../../../ResourceSelector.sol"; +import { WorldResourceIdLib, WorldResourceIdInstance } from "../../../WorldResourceId.sol"; import { AccessControl } from "../../../AccessControl.sol"; +import { RESOURCE_NAMESPACE } from "../../../worldResourceTypes.sol"; import { IWorldErrors } from "../../../interfaces/IWorldErrors.sol"; import { Balances } from "../tables/Balances.sol"; contract BalanceTransferSystem is System, IWorldErrors { - using ResourceSelector for bytes32; + using ResourceIdInstance for ResourceId; + using WorldResourceIdInstance for ResourceId; /** * Transfer balance to another namespace in the World */ - function transferBalanceToNamespace(bytes16 fromNamespace, bytes16 toNamespace, uint256 amount) public virtual { + function transferBalanceToNamespace( + ResourceId fromNamespaceId, + ResourceId toNamespaceId, + uint256 amount + ) public virtual { + // Require the target ID to be a namespace ID + if (toNamespaceId.getType() != RESOURCE_NAMESPACE) { + revert InvalidResourceType(RESOURCE_NAMESPACE, toNamespaceId, toNamespaceId.toString()); + } + // Require caller to have access to the namespace - AccessControl.requireAccess(fromNamespace, _msgSender()); + AccessControl.requireAccess(fromNamespaceId, _msgSender()); // Get current namespace balance - uint256 balance = Balances._get(fromNamespace); + uint256 balance = Balances._get(ResourceId.unwrap(fromNamespaceId)); // Require the balance balance to be greater or equal to the amount to transfer if (amount > balance) revert InsufficientBalance(balance, amount); // Update the balances - Balances._set(fromNamespace, balance - amount); - Balances._set(toNamespace, Balances._get(toNamespace) + amount); + Balances._set(ResourceId.unwrap(fromNamespaceId), balance - amount); + Balances._set(ResourceId.unwrap(toNamespaceId), Balances._get(ResourceId.unwrap(toNamespaceId)) + amount); } /** * Transfer balance out of the World */ - function transferBalanceToAddress(bytes16 fromNamespace, address toAddress, uint256 amount) public virtual { + function transferBalanceToAddress(ResourceId fromNamespaceId, address toAddress, uint256 amount) public virtual { // Require caller to have access to the namespace - AccessControl.requireAccess(fromNamespace, _msgSender()); + AccessControl.requireAccess(fromNamespaceId, _msgSender()); // Get current namespace balance - uint256 balance = Balances._get(fromNamespace); + uint256 balance = Balances._get(ResourceId.unwrap(fromNamespaceId)); // Require the balance balance to be greater or equal to the amount to transfer if (amount > balance) revert InsufficientBalance(balance, amount); // Update the balances - Balances._set(fromNamespace, balance - amount); + Balances._set(ResourceId.unwrap(fromNamespaceId), balance - amount); // Transfer the balance to the given address, revert on failure (bool success, bytes memory data) = payable(toAddress).call{ value: amount }(""); diff --git a/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol b/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol index 35f2309d8c..e5726d495f 100644 --- a/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol +++ b/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol @@ -6,18 +6,18 @@ import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; import { System } from "../../../System.sol"; -import { ResourceSelector } from "../../../ResourceSelector.sol"; +import { ResourceId, WorldResourceIdInstance } from "../../../WorldResourceId.sol"; import { AccessControl } from "../../../AccessControl.sol"; contract EphemeralRecordSystem is IStoreEphemeral, System { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; /** * Emit the ephemeral event without modifying storage at the given namespace and name. - * Requires the caller to have access to the namespace or name (encoded in the resource selector) + * Requires the caller to have access to the namespace or name (encoded in the table ID) */ function emitEphemeralRecord( - bytes32 resourceSelector, + ResourceId tableId, bytes32[] calldata keyTuple, bytes calldata staticData, PackedCounter encodedLengths, @@ -25,9 +25,9 @@ contract EphemeralRecordSystem is IStoreEphemeral, System { FieldLayout fieldLayout ) public virtual { // Require access to the namespace or name - AccessControl.requireAccess(resourceSelector, msg.sender); + AccessControl.requireAccess(tableId, msg.sender); // Set the record - StoreCore.emitEphemeralRecord(resourceSelector, keyTuple, staticData, encodedLengths, dynamicData, fieldLayout); + StoreCore.emitEphemeralRecord(tableId, keyTuple, staticData, encodedLengths, dynamicData, fieldLayout); } } diff --git a/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol b/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol index f79d328b9c..b86a42fabe 100644 --- a/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol +++ b/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol @@ -5,19 +5,19 @@ import { IStoreHook, STORE_HOOK_INTERFACE_ID } from "@latticexyz/store/src/IStor import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; +import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol"; import { System } from "../../../System.sol"; -import { ResourceSelector } from "../../../ResourceSelector.sol"; -import { Resource } from "../../../common.sol"; +import { ResourceId, WorldResourceIdInstance } from "../../../WorldResourceId.sol"; import { ROOT_NAMESPACE, ROOT_NAME } from "../../../constants.sol"; import { AccessControl } from "../../../AccessControl.sol"; import { requireInterface } from "../../../requireInterface.sol"; +import { revertWithBytes } from "../../../revertWithBytes.sol"; import { WorldContextProvider } from "../../../WorldContext.sol"; import { NamespaceOwner } from "../../../tables/NamespaceOwner.sol"; import { ResourceAccess } from "../../../tables/ResourceAccess.sol"; import { IWorldErrors } from "../../../interfaces/IWorldErrors.sol"; -import { ResourceType } from "../tables/ResourceType.sol"; import { SystemHooks } from "../tables/SystemHooks.sol"; import { SystemRegistry } from "../tables/SystemRegistry.sol"; import { Systems } from "../tables/Systems.sol"; @@ -31,13 +31,13 @@ import { WorldRegistrationSystem } from "./WorldRegistrationSystem.sol"; * Functions related to registering table resources in the World. */ contract StoreRegistrationSystem is System, IWorldErrors { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; /** * Register a table with the given config */ function registerTable( - bytes32 resourceSelector, + ResourceId tableId, FieldLayout fieldLayout, Schema keySchema, Schema valueSchema, @@ -45,42 +45,31 @@ contract StoreRegistrationSystem is System, IWorldErrors { string[] calldata fieldNames ) public virtual { // Require the name to not be the namespace's root name - if (resourceSelector.getName() == ROOT_NAME) revert InvalidSelector(resourceSelector.toString()); + if (tableId.getName() == ROOT_NAME) revert InvalidResourceId(tableId, tableId.toString()); // If the namespace doesn't exist yet, register it - bytes16 namespace = resourceSelector.getNamespace(); - if (ResourceType._get(namespace) == Resource.NONE) { - // We can't call IBaseWorld(this).registerNamespace directly because it would be handled like - // an external call, so msg.sender would be the address of the World contract - (address systemAddress, ) = Systems._get(ResourceSelector.from(ROOT_NAMESPACE, CORE_SYSTEM_NAME)); - WorldContextProvider.delegatecallWithContextOrRevert({ - msgSender: _msgSender(), - msgValue: 0, - target: systemAddress, - callData: abi.encodeCall(WorldRegistrationSystem.registerNamespace, (namespace)) - }); + ResourceId namespaceId = tableId.getNamespaceId(); + if (!ResourceIds._getExists(ResourceId.unwrap(namespaceId))) { + // Since this is a root system, we're in the context of the World contract already, + // so we can use delegatecall to register the namespace + (bool success, bytes memory data) = address(this).delegatecall( + abi.encodeCall(WorldRegistrationSystem.registerNamespace, (namespaceId)) + ); + if (!success) revertWithBytes(data); } else { // otherwise require caller to own the namespace - AccessControl.requireOwner(namespace, _msgSender()); + AccessControl.requireOwner(namespaceId, _msgSender()); } - // Require no resource to exist at this selector yet - if (ResourceType._get(resourceSelector) != Resource.NONE) { - revert ResourceExists(resourceSelector.toString()); - } - - // Store the table resource type - ResourceType._set(resourceSelector, Resource.TABLE); - // Register the table - StoreCore.registerTable(resourceSelector, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); + StoreCore.registerTable(tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); } /** * Register a hook for the given tableId. * Requires the caller to own the namespace. */ - function registerStoreHook(bytes32 tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) public virtual { + function registerStoreHook(ResourceId tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) public virtual { // Require the hook to implement the store hook interface requireInterface(address(hookAddress), STORE_HOOK_INTERFACE_ID); @@ -95,7 +84,7 @@ contract StoreRegistrationSystem is System, IWorldErrors { * Unregister a hook for the given tableId. * Requires the caller to own the namespace. */ - function unregisterStoreHook(bytes32 tableId, IStoreHook hookAddress) public virtual { + function unregisterStoreHook(ResourceId tableId, IStoreHook hookAddress) public virtual { // Require caller to own the namespace AccessControl.requireOwner(tableId, _msgSender()); diff --git a/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol b/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol index 58ecdea46f..6e0f75971b 100644 --- a/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol +++ b/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol @@ -2,13 +2,15 @@ pragma solidity >=0.8.0; import { Hook, HookLib } from "@latticexyz/store/src/Hook.sol"; +import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; +import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol"; import { System } from "../../../System.sol"; import { WorldContextConsumer, WORLD_CONTEXT_CONSUMER_INTERFACE_ID } from "../../../WorldContext.sol"; -import { ResourceSelector } from "../../../ResourceSelector.sol"; -import { Resource } from "../../../common.sol"; +import { WorldResourceIdLib, WorldResourceIdInstance } from "../../../WorldResourceId.sol"; import { SystemCall } from "../../../SystemCall.sol"; -import { ROOT_NAMESPACE, ROOT_NAME, UNLIMITED_DELEGATION } from "../../../constants.sol"; +import { ROOT_NAMESPACE_ID, ROOT_NAME, UNLIMITED_DELEGATION } from "../../../constants.sol"; +import { RESOURCE_NAMESPACE, RESOURCE_SYSTEM } from "../../../worldResourceTypes.sol"; import { AccessControl } from "../../../AccessControl.sol"; import { requireInterface } from "../../../requireInterface.sol"; import { NamespaceOwner } from "../../../tables/NamespaceOwner.sol"; @@ -18,7 +20,6 @@ import { ISystemHook, SYSTEM_HOOK_INTERFACE_ID } from "../../../interfaces/ISyst import { IWorldErrors } from "../../../interfaces/IWorldErrors.sol"; import { IDelegationControl, DELEGATION_CONTROL_INTERFACE_ID } from "../../../interfaces/IDelegationControl.sol"; -import { ResourceType } from "../tables/ResourceType.sol"; import { SystemHooks, SystemHooksTableId } from "../tables/SystemHooks.sol"; import { SystemRegistry } from "../tables/SystemRegistry.sol"; import { Systems } from "../tables/Systems.sol"; @@ -29,54 +30,59 @@ import { FunctionSelectors } from "../tables/FunctionSelectors.sol"; * Registering tables is implemented in StoreRegistrationSystem.sol */ contract WorldRegistrationSystem is System, IWorldErrors { - using ResourceSelector for bytes32; + using ResourceIdInstance for ResourceId; + using WorldResourceIdInstance for ResourceId; /** * Register a new namespace */ - function registerNamespace(bytes16 namespace) public virtual { - bytes32 resourceSelector = ResourceSelector.from(namespace); + function registerNamespace(ResourceId namespaceId) public virtual { + // Require the provided namespace ID to have type RESOURCE_NAMESPACE + if (namespaceId.getType() != RESOURCE_NAMESPACE) { + revert InvalidResourceType(RESOURCE_NAMESPACE, namespaceId, namespaceId.toString()); + } // Require namespace to not exist yet - if (ResourceType._get(namespace) != Resource.NONE) revert ResourceExists(resourceSelector.toString()); + if (ResourceIds._getExists(ResourceId.unwrap(namespaceId))) { + revert ResourceExists(namespaceId, namespaceId.toString()); + } - // Register namespace resource - ResourceType._set(namespace, Resource.NAMESPACE); + // Register namespace resource ID + ResourceIds._setExists(ResourceId.unwrap(namespaceId), true); // Register caller as the namespace owner - NamespaceOwner._set(namespace, _msgSender()); + NamespaceOwner._set(ResourceId.unwrap(namespaceId), _msgSender()); // Give caller access to the new namespace - ResourceAccess._set(resourceSelector, _msgSender(), true); + ResourceAccess._set(ResourceId.unwrap(namespaceId), _msgSender(), true); } /** - * Register a hook for the system at the given resource selector + * Register a hook for the system at the given system ID */ - function registerSystemHook( - bytes32 resourceSelector, - ISystemHook hookAddress, - uint8 enabledHooksBitmap - ) public virtual { + function registerSystemHook(ResourceId systemId, ISystemHook hookAddress, uint8 enabledHooksBitmap) public virtual { // Require the provided address to implement the ISystemHook interface requireInterface(address(hookAddress), SYSTEM_HOOK_INTERFACE_ID); // Require caller to own the namespace - AccessControl.requireOwner(resourceSelector, _msgSender()); + AccessControl.requireOwner(systemId, _msgSender()); // Register the hook - SystemHooks.push(resourceSelector, Hook.unwrap(HookLib.encode(address(hookAddress), enabledHooksBitmap))); + SystemHooks.push( + ResourceId.unwrap(systemId), + Hook.unwrap(HookLib.encode(address(hookAddress), enabledHooksBitmap)) + ); } /** - * Unregister the given hook for the system at the given resource selector + * Unregister the given hook for the system at the given system ID */ - function unregisterSystemHook(bytes32 resourceSelector, ISystemHook hookAddress) public virtual { + function unregisterSystemHook(ResourceId systemId, ISystemHook hookAddress) public virtual { // Require caller to own the namespace - AccessControl.requireOwner(resourceSelector, _msgSender()); + AccessControl.requireOwner(systemId, _msgSender()); - // Remove the hook from the list of hooks for this resourceSelector in the system hooks table - HookLib.filterListByAddress(SystemHooksTableId, resourceSelector, address(hookAddress)); + // Remove the hook from the list of hooks for this system in the system hooks table + HookLib.filterListByAddress(SystemHooksTableId, systemId, address(hookAddress)); } /** @@ -88,54 +94,56 @@ contract WorldRegistrationSystem is System, IWorldErrors { * Note: this function doesn't check whether a system already exists at the given selector, * making it possible to upgrade systems. */ - function registerSystem(bytes32 resourceSelector, WorldContextConsumer system, bool publicAccess) public virtual { + function registerSystem(ResourceId systemId, WorldContextConsumer system, bool publicAccess) public virtual { + // Require the provided system ID to have type RESOURCE_SYSTEM + if (systemId.getType() != RESOURCE_SYSTEM) { + revert InvalidResourceType(RESOURCE_SYSTEM, systemId, systemId.toString()); + } + // Require the provided address to implement the WorldContextConsumer interface requireInterface(address(system), WORLD_CONTEXT_CONSUMER_INTERFACE_ID); // Require the name to not be the namespace's root name - if (resourceSelector.getName() == ROOT_NAME) revert InvalidSelector(resourceSelector.toString()); + if (systemId.getName() == ROOT_NAME) revert InvalidResourceId(systemId, systemId.toString()); - // Require this system to not be registered at a different resource selector yet - bytes32 existingResourceSelector = SystemRegistry._get(address(system)); - if (existingResourceSelector != 0 && existingResourceSelector != resourceSelector) { + // Require this system to not be registered at a different system ID yet + bytes32 existingSystemId = SystemRegistry._get(address(system)); + if (existingSystemId != 0 && existingSystemId != ResourceId.unwrap(systemId)) { revert SystemExists(address(system)); } // If the namespace doesn't exist yet, register it - // otherwise require caller to own the namespace - bytes16 namespace = resourceSelector.getNamespace(); - if (ResourceType._get(namespace) == Resource.NONE) registerNamespace(namespace); - else AccessControl.requireOwner(namespace, _msgSender()); - - // Require no resource other than a system to exist at this selector yet - Resource resourceType = ResourceType._get(resourceSelector); - if (resourceType != Resource.NONE && resourceType != Resource.SYSTEM) { - revert ResourceExists(resourceSelector.toString()); + ResourceId namespaceId = systemId.getNamespaceId(); + if (!ResourceIds._getExists(ResourceId.unwrap(namespaceId))) { + registerNamespace(namespaceId); + } else { + // otherwise require caller to own the namespace + AccessControl.requireOwner(namespaceId, _msgSender()); } - // Check if a system already exists at this resource selector - address existingSystem = Systems._getSystem(resourceSelector); + // Check if a system already exists at this system ID + address existingSystem = Systems._getSystem(ResourceId.unwrap(systemId)); - // If there is an existing system with this resource selector, remove it + // If there is an existing system with this system ID, remove it if (existingSystem != address(0)) { // Remove the existing system from the system registry SystemRegistry._deleteRecord(existingSystem); // Remove the existing system's access to its namespace - ResourceAccess._deleteRecord(namespace, existingSystem); + ResourceAccess._deleteRecord(ResourceId.unwrap(namespaceId), existingSystem); } else { - // Otherwise, this is a new system, so register its resource type - ResourceType._set(resourceSelector, Resource.SYSTEM); + // Otherwise, this is a new system, so register its resource ID + ResourceIds._setExists(ResourceId.unwrap(systemId), true); } - // Systems = mapping from resourceSelector to system address and publicAccess - Systems._set(resourceSelector, address(system), publicAccess); + // Systems = mapping from system ID to system address and public access flag + Systems._set(ResourceId.unwrap(systemId), address(system), publicAccess); - // SystemRegistry = mapping from system address to resourceSelector - SystemRegistry._set(address(system), resourceSelector); + // SystemRegistry = mapping from system address to system ID + SystemRegistry._set(address(system), ResourceId.unwrap(systemId)); // Grant the system access to its namespace - ResourceAccess._set(namespace, address(system), true); + ResourceAccess._set(ResourceId.unwrap(namespaceId), address(system), true); } /** @@ -146,31 +154,31 @@ contract WorldRegistrationSystem is System, IWorldErrors { * TODO: replace separate systemFunctionName and systemFunctionArguments with a signature argument */ function registerFunctionSelector( - bytes32 resourceSelector, + ResourceId systemId, string memory systemFunctionName, string memory systemFunctionArguments ) public returns (bytes4 worldFunctionSelector) { // Require the caller to own the namespace - AccessControl.requireOwner(resourceSelector, _msgSender()); + AccessControl.requireOwner(systemId, _msgSender()); // Compute global function selector - string memory namespaceString = ResourceSelector.toTrimmedString(resourceSelector.getNamespace()); - string memory nameString = ResourceSelector.toTrimmedString(resourceSelector.getName()); + string memory namespaceString = WorldResourceIdLib.toTrimmedString(systemId.getNamespace()); + string memory nameString = WorldResourceIdLib.toTrimmedString(systemId.getName()); worldFunctionSelector = bytes4( keccak256(abi.encodePacked(namespaceString, "_", nameString, "_", systemFunctionName, systemFunctionArguments)) ); // Require the function selector to be globally unique - bytes32 existingResourceSelector = FunctionSelectors._getResourceSelector(worldFunctionSelector); + bytes32 existingSystemId = FunctionSelectors._getSystemId(worldFunctionSelector); - if (existingResourceSelector != 0) revert FunctionSelectorExists(worldFunctionSelector); + if (existingSystemId != 0) revert FunctionSelectorExists(worldFunctionSelector); // Register the function selector bytes memory systemFunctionSignature = abi.encodePacked(systemFunctionName, systemFunctionArguments); bytes4 systemFunctionSelector = systemFunctionSignature.length == 0 ? bytes4(0) // Save gas by storing 0x0 for empty function signatures (= fallback function) : bytes4(keccak256(systemFunctionSignature)); - FunctionSelectors._set(worldFunctionSelector, resourceSelector, systemFunctionSelector); + FunctionSelectors._set(worldFunctionSelector, ResourceId.unwrap(systemId), systemFunctionSelector); } /** @@ -181,20 +189,20 @@ contract WorldRegistrationSystem is System, IWorldErrors { * (see https://github.com/latticexyz/mud/issues/444) */ function registerRootFunctionSelector( - bytes32 resourceSelector, + ResourceId systemId, bytes4 worldFunctionSelector, bytes4 systemFunctionSelector ) public returns (bytes4) { // Require the caller to own the root namespace - AccessControl.requireOwner(ROOT_NAMESPACE, _msgSender()); + AccessControl.requireOwner(ROOT_NAMESPACE_ID, _msgSender()); // Require the function selector to be globally unique - bytes32 existingResourceSelector = FunctionSelectors._getResourceSelector(worldFunctionSelector); + bytes32 existingSystemId = FunctionSelectors._getSystemId(worldFunctionSelector); - if (existingResourceSelector != 0) revert FunctionSelectorExists(worldFunctionSelector); + if (existingSystemId != 0) revert FunctionSelectorExists(worldFunctionSelector); // Register the function selector - FunctionSelectors._set(worldFunctionSelector, resourceSelector, systemFunctionSelector); + FunctionSelectors._set(worldFunctionSelector, ResourceId.unwrap(systemId), systemFunctionSelector); return worldFunctionSelector; } @@ -202,23 +210,22 @@ contract WorldRegistrationSystem is System, IWorldErrors { /** * Register a delegation from the caller to the given delegatee. */ - function registerDelegation(address delegatee, bytes32 delegationControlId, bytes memory initCallData) public { + function registerDelegation(address delegatee, ResourceId delegationControlId, bytes memory initCallData) public { // Store the delegation control contract address - Delegations.set({ delegator: _msgSender(), delegatee: delegatee, delegationControlId: delegationControlId }); + Delegations.set({ + delegator: _msgSender(), + delegatee: delegatee, + delegationControlId: ResourceId.unwrap(delegationControlId) + }); // If the delegation is not unlimited... - if (delegationControlId != UNLIMITED_DELEGATION && initCallData.length > 0) { + if (ResourceId.unwrap(delegationControlId) != ResourceId.unwrap(UNLIMITED_DELEGATION) && initCallData.length > 0) { // Require the delegationControl contract to implement the IDelegationControl interface - (address delegationControl, ) = Systems._get(delegationControlId); + (address delegationControl, ) = Systems._get(ResourceId.unwrap(delegationControlId)); requireInterface(delegationControl, DELEGATION_CONTROL_INTERFACE_ID); // Call the delegation control contract's init function - SystemCall.call({ - caller: _msgSender(), - resourceSelector: delegationControlId, - callData: initCallData, - value: 0 - }); + SystemCall.call({ caller: _msgSender(), systemId: delegationControlId, callData: initCallData, value: 0 }); } } } diff --git a/packages/world/src/modules/core/tables/Balances.sol b/packages/world/src/modules/core/tables/Balances.sol index d2f043c64f..abdb7903f5 100644 --- a/packages/world/src/modules/core/tables/Balances.sol +++ b/packages/world/src/modules/core/tables/Balances.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Balances"))); -bytes32 constant BalancesTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Balances"))) +); +ResourceId constant BalancesTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010020000000000000000000000000000000000000000000000000000000 @@ -34,7 +38,7 @@ library Balances { /** Get the table's key schema */ function getKeySchema() internal pure returns (Schema) { SchemaType[] memory _keySchema = new SchemaType[](1); - _keySchema[0] = SchemaType.BYTES16; + _keySchema[0] = SchemaType.BYTES32; return SchemaLib.encode(_keySchema); } @@ -50,7 +54,7 @@ library Balances { /** Get the table's key names */ function getKeyNames() internal pure returns (string[] memory keyNames) { keyNames = new string[](1); - keyNames[0] = "namespace"; + keyNames[0] = "namespaceId"; } /** Get the table's field names */ @@ -75,103 +79,103 @@ library Balances { } /** Get balance */ - function getBalance(bytes16 namespace) internal view returns (uint256 balance) { + function getBalance(bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance */ - function _getBalance(bytes16 namespace) internal view returns (uint256 balance) { + function _getBalance(bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance (using the specified store) */ - function getBalance(IStore _store, bytes16 namespace) internal view returns (uint256 balance) { + function getBalance(IStore _store, bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance */ - function get(bytes16 namespace) internal view returns (uint256 balance) { + function get(bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance */ - function _get(bytes16 namespace) internal view returns (uint256 balance) { + function _get(bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Get balance (using the specified store) */ - function get(IStore _store, bytes16 namespace) internal view returns (uint256 balance) { + function get(IStore _store, bytes32 namespaceId) internal view returns (uint256 balance) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (uint256(bytes32(_blob))); } /** Set balance */ - function setBalance(bytes16 namespace, uint256 balance) internal { + function setBalance(bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance */ - function _setBalance(bytes16 namespace, uint256 balance) internal { + function _setBalance(bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance (using the specified store) */ - function setBalance(IStore _store, bytes16 namespace, uint256 balance) internal { + function setBalance(IStore _store, bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance */ - function set(bytes16 namespace, uint256 balance) internal { + function set(bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance */ - function _set(bytes16 namespace, uint256 balance) internal { + function _set(bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } /** Set balance (using the specified store) */ - function set(IStore _store, bytes16 namespace, uint256 balance) internal { + function set(IStore _store, bytes32 namespaceId, uint256 balance) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } @@ -192,33 +196,33 @@ library Balances { } /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes16 namespace) internal pure returns (bytes32[] memory) { + function encodeKeyTuple(bytes32 namespaceId) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; return _keyTuple; } /* Delete all data for given keys */ - function deleteRecord(bytes16 namespace) internal { + function deleteRecord(bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord(bytes16 namespace) internal { + function _deleteRecord(bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes16 namespace) internal { + function deleteRecord(IStore _store, bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } diff --git a/packages/world/src/modules/core/tables/FunctionSelectors.sol b/packages/world/src/modules/core/tables/FunctionSelectors.sol index e92a0ff17b..19c200d122 100644 --- a/packages/world/src/modules/core/tables/FunctionSelectors.sol +++ b/packages/world/src/modules/core/tables/FunctionSelectors.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("FunctionSelector"))); -bytes32 constant FunctionSelectorsTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("FunctionSelector"))) +); +ResourceId constant FunctionSelectorsTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0024020020040000000000000000000000000000000000000000000000000000 @@ -57,7 +61,7 @@ library FunctionSelectors { /** Get the table's field names */ function getFieldNames() internal pure returns (string[] memory fieldNames) { fieldNames = new string[](2); - fieldNames[0] = "resourceSelector"; + fieldNames[0] = "systemId"; fieldNames[1] = "systemFunctionSelector"; } @@ -76,8 +80,8 @@ library FunctionSelectors { _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } - /** Get resourceSelector */ - function getResourceSelector(bytes4 functionSelector) internal view returns (bytes32 resourceSelector) { + /** Get systemId */ + function getSystemId(bytes4 functionSelector) internal view returns (bytes32 systemId) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); @@ -85,8 +89,8 @@ library FunctionSelectors { return (bytes32(_blob)); } - /** Get resourceSelector */ - function _getResourceSelector(bytes4 functionSelector) internal view returns (bytes32 resourceSelector) { + /** Get systemId */ + function _getSystemId(bytes4 functionSelector) internal view returns (bytes32 systemId) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); @@ -94,11 +98,8 @@ library FunctionSelectors { return (bytes32(_blob)); } - /** Get resourceSelector (using the specified store) */ - function getResourceSelector( - IStore _store, - bytes4 functionSelector - ) internal view returns (bytes32 resourceSelector) { + /** Get systemId (using the specified store) */ + function getSystemId(IStore _store, bytes4 functionSelector) internal view returns (bytes32 systemId) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); @@ -106,28 +107,28 @@ library FunctionSelectors { return (bytes32(_blob)); } - /** Set resourceSelector */ - function setResourceSelector(bytes4 functionSelector, bytes32 resourceSelector) internal { + /** Set systemId */ + function setSystemId(bytes4 functionSelector, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); - StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), _fieldLayout); + StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } - /** Set resourceSelector */ - function _setResourceSelector(bytes4 functionSelector, bytes32 resourceSelector) internal { + /** Set systemId */ + function _setSystemId(bytes4 functionSelector, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); - StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), _fieldLayout); + StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } - /** Set resourceSelector (using the specified store) */ - function setResourceSelector(IStore _store, bytes4 functionSelector, bytes32 resourceSelector) internal { + /** Set systemId (using the specified store) */ + function setSystemId(IStore _store, bytes4 functionSelector, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); - _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), _fieldLayout); + _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } /** Get systemFunctionSelector */ @@ -185,9 +186,7 @@ library FunctionSelectors { } /** Get the full data */ - function get( - bytes4 functionSelector - ) internal view returns (bytes32 resourceSelector, bytes4 systemFunctionSelector) { + function get(bytes4 functionSelector) internal view returns (bytes32 systemId, bytes4 systemFunctionSelector) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); @@ -200,9 +199,7 @@ library FunctionSelectors { } /** Get the full data */ - function _get( - bytes4 functionSelector - ) internal view returns (bytes32 resourceSelector, bytes4 systemFunctionSelector) { + function _get(bytes4 functionSelector) internal view returns (bytes32 systemId, bytes4 systemFunctionSelector) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); @@ -218,7 +215,7 @@ library FunctionSelectors { function get( IStore _store, bytes4 functionSelector - ) internal view returns (bytes32 resourceSelector, bytes4 systemFunctionSelector) { + ) internal view returns (bytes32 systemId, bytes4 systemFunctionSelector) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); @@ -231,8 +228,8 @@ library FunctionSelectors { } /** Set the full data using individual values */ - function set(bytes4 functionSelector, bytes32 resourceSelector, bytes4 systemFunctionSelector) internal { - bytes memory _staticData = encodeStatic(resourceSelector, systemFunctionSelector); + function set(bytes4 functionSelector, bytes32 systemId, bytes4 systemFunctionSelector) internal { + bytes memory _staticData = encodeStatic(systemId, systemFunctionSelector); PackedCounter _encodedLengths; bytes memory _dynamicData; @@ -244,8 +241,8 @@ library FunctionSelectors { } /** Set the full data using individual values */ - function _set(bytes4 functionSelector, bytes32 resourceSelector, bytes4 systemFunctionSelector) internal { - bytes memory _staticData = encodeStatic(resourceSelector, systemFunctionSelector); + function _set(bytes4 functionSelector, bytes32 systemId, bytes4 systemFunctionSelector) internal { + bytes memory _staticData = encodeStatic(systemId, systemFunctionSelector); PackedCounter _encodedLengths; bytes memory _dynamicData; @@ -257,13 +254,8 @@ library FunctionSelectors { } /** Set the full data using individual values (using the specified store) */ - function set( - IStore _store, - bytes4 functionSelector, - bytes32 resourceSelector, - bytes4 systemFunctionSelector - ) internal { - bytes memory _staticData = encodeStatic(resourceSelector, systemFunctionSelector); + function set(IStore _store, bytes4 functionSelector, bytes32 systemId, bytes4 systemFunctionSelector) internal { + bytes memory _staticData = encodeStatic(systemId, systemFunctionSelector); PackedCounter _encodedLengths; bytes memory _dynamicData; @@ -278,10 +270,8 @@ library FunctionSelectors { * Decode the tightly packed blob of static data using this table's field layout * Undefined behaviour for invalid blobs */ - function decodeStatic( - bytes memory _blob - ) internal pure returns (bytes32 resourceSelector, bytes4 systemFunctionSelector) { - resourceSelector = (Bytes.slice32(_blob, 0)); + function decodeStatic(bytes memory _blob) internal pure returns (bytes32 systemId, bytes4 systemFunctionSelector) { + systemId = (Bytes.slice32(_blob, 0)); systemFunctionSelector = (Bytes.slice4(_blob, 32)); } @@ -294,21 +284,21 @@ library FunctionSelectors { bytes memory _staticData, PackedCounter, bytes memory - ) internal pure returns (bytes32 resourceSelector, bytes4 systemFunctionSelector) { - (resourceSelector, systemFunctionSelector) = decodeStatic(_staticData); + ) internal pure returns (bytes32 systemId, bytes4 systemFunctionSelector) { + (systemId, systemFunctionSelector) = decodeStatic(_staticData); } /** Tightly pack static data using this table's schema */ - function encodeStatic(bytes32 resourceSelector, bytes4 systemFunctionSelector) internal pure returns (bytes memory) { - return abi.encodePacked(resourceSelector, systemFunctionSelector); + function encodeStatic(bytes32 systemId, bytes4 systemFunctionSelector) internal pure returns (bytes memory) { + return abi.encodePacked(systemId, systemFunctionSelector); } /** Tightly pack full data using this table's field layout */ function encode( - bytes32 resourceSelector, + bytes32 systemId, bytes4 systemFunctionSelector ) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(resourceSelector, systemFunctionSelector); + bytes memory _staticData = encodeStatic(systemId, systemFunctionSelector); PackedCounter _encodedLengths; bytes memory _dynamicData; diff --git a/packages/world/src/modules/core/tables/ResourceType.sol b/packages/world/src/modules/core/tables/ResourceType.sol deleted file mode 100644 index 3eede246e2..0000000000 --- a/packages/world/src/modules/core/tables/ResourceType.sol +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -/* Autogenerated file. Do not edit manually. */ - -// Import schema type -import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; - -// Import store internals -import { IStore } from "@latticexyz/store/src/IStore.sol"; -import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; -import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; -import { Bytes } from "@latticexyz/store/src/Bytes.sol"; -import { Memory } from "@latticexyz/store/src/Memory.sol"; -import { SliceLib } from "@latticexyz/store/src/Slice.sol"; -import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; -import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; -import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; -import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; - -// Import user types -import { Resource } from "./../../../common.sol"; - -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("ResourceType"))); -bytes32 constant ResourceTypeTableId = _tableId; - -FieldLayout constant _fieldLayout = FieldLayout.wrap( - 0x0001010001000000000000000000000000000000000000000000000000000000 -); - -library ResourceType { - /** Get the table values' field layout */ - function getFieldLayout() internal pure returns (FieldLayout) { - return _fieldLayout; - } - - /** Get the table's key schema */ - function getKeySchema() internal pure returns (Schema) { - SchemaType[] memory _keySchema = new SchemaType[](1); - _keySchema[0] = SchemaType.BYTES32; - - return SchemaLib.encode(_keySchema); - } - - /** Get the table's value schema */ - function getValueSchema() internal pure returns (Schema) { - SchemaType[] memory _valueSchema = new SchemaType[](1); - _valueSchema[0] = SchemaType.UINT8; - - return SchemaLib.encode(_valueSchema); - } - - /** Get the table's key names */ - function getKeyNames() internal pure returns (string[] memory keyNames) { - keyNames = new string[](1); - keyNames[0] = "resourceSelector"; - } - - /** Get the table's field names */ - function getFieldNames() internal pure returns (string[] memory fieldNames) { - fieldNames = new string[](1); - fieldNames[0] = "resourceType"; - } - - /** Register the table with its config */ - function register() internal { - StoreSwitch.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); - } - - /** Register the table with its config */ - function _register() internal { - StoreCore.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); - } - - /** Register the table with its config (using the specified store) */ - function register(IStore _store) internal { - _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); - } - - /** Get resourceType */ - function getResourceType(bytes32 resourceSelector) internal view returns (Resource resourceType) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); - return Resource(uint8(bytes1(_blob))); - } - - /** Get resourceType */ - function _getResourceType(bytes32 resourceSelector) internal view returns (Resource resourceType) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); - return Resource(uint8(bytes1(_blob))); - } - - /** Get resourceType (using the specified store) */ - function getResourceType(IStore _store, bytes32 resourceSelector) internal view returns (Resource resourceType) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); - return Resource(uint8(bytes1(_blob))); - } - - /** Get resourceType */ - function get(bytes32 resourceSelector) internal view returns (Resource resourceType) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); - return Resource(uint8(bytes1(_blob))); - } - - /** Get resourceType */ - function _get(bytes32 resourceSelector) internal view returns (Resource resourceType) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); - return Resource(uint8(bytes1(_blob))); - } - - /** Get resourceType (using the specified store) */ - function get(IStore _store, bytes32 resourceSelector) internal view returns (Resource resourceType) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); - return Resource(uint8(bytes1(_blob))); - } - - /** Set resourceType */ - function setResourceType(bytes32 resourceSelector, Resource resourceType) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked(uint8(resourceType)), _fieldLayout); - } - - /** Set resourceType */ - function _setResourceType(bytes32 resourceSelector, Resource resourceType) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked(uint8(resourceType)), _fieldLayout); - } - - /** Set resourceType (using the specified store) */ - function setResourceType(IStore _store, bytes32 resourceSelector, Resource resourceType) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - _store.setField(_tableId, _keyTuple, 0, abi.encodePacked(uint8(resourceType)), _fieldLayout); - } - - /** Set resourceType */ - function set(bytes32 resourceSelector, Resource resourceType) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked(uint8(resourceType)), _fieldLayout); - } - - /** Set resourceType */ - function _set(bytes32 resourceSelector, Resource resourceType) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked(uint8(resourceType)), _fieldLayout); - } - - /** Set resourceType (using the specified store) */ - function set(IStore _store, bytes32 resourceSelector, Resource resourceType) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - _store.setField(_tableId, _keyTuple, 0, abi.encodePacked(uint8(resourceType)), _fieldLayout); - } - - /** Tightly pack static data using this table's schema */ - function encodeStatic(Resource resourceType) internal pure returns (bytes memory) { - return abi.encodePacked(resourceType); - } - - /** Tightly pack full data using this table's field layout */ - function encode(Resource resourceType) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(resourceType); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes32 resourceSelector) internal pure returns (bytes32[] memory) { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - return _keyTuple; - } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 resourceSelector) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 resourceSelector) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 resourceSelector) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } -} diff --git a/packages/world/src/modules/core/tables/SystemHooks.sol b/packages/world/src/modules/core/tables/SystemHooks.sol index 8e7409166f..0201700a2d 100644 --- a/packages/world/src/modules/core/tables/SystemHooks.sol +++ b/packages/world/src/modules/core/tables/SystemHooks.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("SystemHooks"))); -bytes32 constant SystemHooksTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("SystemHooks"))) +); +ResourceId constant SystemHooksTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 @@ -50,7 +54,7 @@ library SystemHooks { /** Get the table's key names */ function getKeyNames() internal pure returns (string[] memory keyNames) { keyNames = new string[](1); - keyNames[0] = "resourceSelector"; + keyNames[0] = "systemId"; } /** Get the table's field names */ @@ -75,111 +79,111 @@ library SystemHooks { } /** Get value */ - function getValue(bytes32 resourceSelector) internal view returns (bytes21[] memory value) { + function getValue(bytes32 systemId) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes memory _blob = StoreSwitch.getDynamicField(_tableId, _keyTuple, 0); return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes21()); } /** Get value */ - function _getValue(bytes32 resourceSelector) internal view returns (bytes21[] memory value) { + function _getValue(bytes32 systemId) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes memory _blob = StoreCore.getDynamicField(_tableId, _keyTuple, 0); return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes21()); } /** Get value (using the specified store) */ - function getValue(IStore _store, bytes32 resourceSelector) internal view returns (bytes21[] memory value) { + function getValue(IStore _store, bytes32 systemId) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes memory _blob = _store.getDynamicField(_tableId, _keyTuple, 0); return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes21()); } /** Get value */ - function get(bytes32 resourceSelector) internal view returns (bytes21[] memory value) { + function get(bytes32 systemId) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes memory _blob = StoreSwitch.getDynamicField(_tableId, _keyTuple, 0); return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes21()); } /** Get value */ - function _get(bytes32 resourceSelector) internal view returns (bytes21[] memory value) { + function _get(bytes32 systemId) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes memory _blob = StoreCore.getDynamicField(_tableId, _keyTuple, 0); return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes21()); } /** Get value (using the specified store) */ - function get(IStore _store, bytes32 resourceSelector) internal view returns (bytes21[] memory value) { + function get(IStore _store, bytes32 systemId) internal view returns (bytes21[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes memory _blob = _store.getDynamicField(_tableId, _keyTuple, 0); return (SliceLib.getSubslice(_blob, 0, _blob.length).decodeArray_bytes21()); } /** Set value */ - function setValue(bytes32 resourceSelector, bytes21[] memory value) internal { + function setValue(bytes32 systemId, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.setField(_tableId, _keyTuple, 0, EncodeArray.encode((value)), _fieldLayout); } /** Set value */ - function _setValue(bytes32 resourceSelector, bytes21[] memory value) internal { + function _setValue(bytes32 systemId, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.setField(_tableId, _keyTuple, 0, EncodeArray.encode((value)), _fieldLayout); } /** Set value (using the specified store) */ - function setValue(IStore _store, bytes32 resourceSelector, bytes21[] memory value) internal { + function setValue(IStore _store, bytes32 systemId, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.setField(_tableId, _keyTuple, 0, EncodeArray.encode((value)), _fieldLayout); } /** Set value */ - function set(bytes32 resourceSelector, bytes21[] memory value) internal { + function set(bytes32 systemId, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.setField(_tableId, _keyTuple, 0, EncodeArray.encode((value)), _fieldLayout); } /** Set value */ - function _set(bytes32 resourceSelector, bytes21[] memory value) internal { + function _set(bytes32 systemId, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.setField(_tableId, _keyTuple, 0, EncodeArray.encode((value)), _fieldLayout); } /** Set value (using the specified store) */ - function set(IStore _store, bytes32 resourceSelector, bytes21[] memory value) internal { + function set(IStore _store, bytes32 systemId, bytes21[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.setField(_tableId, _keyTuple, 0, EncodeArray.encode((value)), _fieldLayout); } /** Get the length of value */ - function lengthValue(bytes32 resourceSelector) internal view returns (uint256) { + function lengthValue(bytes32 systemId) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 0, _fieldLayout); unchecked { @@ -188,9 +192,9 @@ library SystemHooks { } /** Get the length of value */ - function _lengthValue(bytes32 resourceSelector) internal view returns (uint256) { + function _lengthValue(bytes32 systemId) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; uint256 _byteLength = StoreCore.getFieldLength(_tableId, _keyTuple, 0, _fieldLayout); unchecked { @@ -199,9 +203,9 @@ library SystemHooks { } /** Get the length of value (using the specified store) */ - function lengthValue(IStore _store, bytes32 resourceSelector) internal view returns (uint256) { + function lengthValue(IStore _store, bytes32 systemId) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 0, _fieldLayout); unchecked { @@ -210,9 +214,9 @@ library SystemHooks { } /** Get the length of value */ - function length(bytes32 resourceSelector) internal view returns (uint256) { + function length(bytes32 systemId) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; uint256 _byteLength = StoreSwitch.getFieldLength(_tableId, _keyTuple, 0, _fieldLayout); unchecked { @@ -221,9 +225,9 @@ library SystemHooks { } /** Get the length of value */ - function _length(bytes32 resourceSelector) internal view returns (uint256) { + function _length(bytes32 systemId) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; uint256 _byteLength = StoreCore.getFieldLength(_tableId, _keyTuple, 0, _fieldLayout); unchecked { @@ -232,9 +236,9 @@ library SystemHooks { } /** Get the length of value (using the specified store) */ - function length(IStore _store, bytes32 resourceSelector) internal view returns (uint256) { + function length(IStore _store, bytes32 systemId) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; uint256 _byteLength = _store.getFieldLength(_tableId, _keyTuple, 0, _fieldLayout); unchecked { @@ -246,9 +250,9 @@ library SystemHooks { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function getItemValue(bytes32 resourceSelector, uint256 _index) internal view returns (bytes21) { + function getItemValue(bytes32 systemId, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { bytes memory _blob = StoreSwitch.getFieldSlice( @@ -267,9 +271,9 @@ library SystemHooks { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function _getItemValue(bytes32 resourceSelector, uint256 _index) internal view returns (bytes21) { + function _getItemValue(bytes32 systemId, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { bytes memory _blob = StoreCore.getFieldSlice( @@ -288,9 +292,9 @@ library SystemHooks { * Get an item of value (using the specified store) * (unchecked, returns invalid data if index overflows) */ - function getItemValue(IStore _store, bytes32 resourceSelector, uint256 _index) internal view returns (bytes21) { + function getItemValue(IStore _store, bytes32 systemId, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 0, _fieldLayout, _index * 21, (_index + 1) * 21); @@ -302,9 +306,9 @@ library SystemHooks { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function getItem(bytes32 resourceSelector, uint256 _index) internal view returns (bytes21) { + function getItem(bytes32 systemId, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { bytes memory _blob = StoreSwitch.getFieldSlice( @@ -323,9 +327,9 @@ library SystemHooks { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function _getItem(bytes32 resourceSelector, uint256 _index) internal view returns (bytes21) { + function _getItem(bytes32 systemId, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { bytes memory _blob = StoreCore.getFieldSlice( @@ -344,9 +348,9 @@ library SystemHooks { * Get an item of value (using the specified store) * (unchecked, returns invalid data if index overflows) */ - function getItem(IStore _store, bytes32 resourceSelector, uint256 _index) internal view returns (bytes21) { + function getItem(IStore _store, bytes32 systemId, uint256 _index) internal view returns (bytes21) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { bytes memory _blob = _store.getFieldSlice(_tableId, _keyTuple, 0, _fieldLayout, _index * 21, (_index + 1) * 21); @@ -355,97 +359,97 @@ library SystemHooks { } /** Push an element to value */ - function pushValue(bytes32 resourceSelector, bytes21 _element) internal { + function pushValue(bytes32 systemId, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.pushToField(_tableId, _keyTuple, 0, abi.encodePacked((_element)), _fieldLayout); } /** Push an element to value */ - function _pushValue(bytes32 resourceSelector, bytes21 _element) internal { + function _pushValue(bytes32 systemId, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.pushToField(_tableId, _keyTuple, 0, abi.encodePacked((_element)), _fieldLayout); } /** Push an element to value (using the specified store) */ - function pushValue(IStore _store, bytes32 resourceSelector, bytes21 _element) internal { + function pushValue(IStore _store, bytes32 systemId, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.pushToField(_tableId, _keyTuple, 0, abi.encodePacked((_element)), _fieldLayout); } /** Push an element to value */ - function push(bytes32 resourceSelector, bytes21 _element) internal { + function push(bytes32 systemId, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.pushToField(_tableId, _keyTuple, 0, abi.encodePacked((_element)), _fieldLayout); } /** Push an element to value */ - function _push(bytes32 resourceSelector, bytes21 _element) internal { + function _push(bytes32 systemId, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.pushToField(_tableId, _keyTuple, 0, abi.encodePacked((_element)), _fieldLayout); } /** Push an element to value (using the specified store) */ - function push(IStore _store, bytes32 resourceSelector, bytes21 _element) internal { + function push(IStore _store, bytes32 systemId, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.pushToField(_tableId, _keyTuple, 0, abi.encodePacked((_element)), _fieldLayout); } /** Pop an element from value */ - function popValue(bytes32 resourceSelector) internal { + function popValue(bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.popFromField(_tableId, _keyTuple, 0, 21, _fieldLayout); } /** Pop an element from value */ - function _popValue(bytes32 resourceSelector) internal { + function _popValue(bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.popFromField(_tableId, _keyTuple, 0, 21, _fieldLayout); } /** Pop an element from value (using the specified store) */ - function popValue(IStore _store, bytes32 resourceSelector) internal { + function popValue(IStore _store, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.popFromField(_tableId, _keyTuple, 0, 21, _fieldLayout); } /** Pop an element from value */ - function pop(bytes32 resourceSelector) internal { + function pop(bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.popFromField(_tableId, _keyTuple, 0, 21, _fieldLayout); } /** Pop an element from value */ - function _pop(bytes32 resourceSelector) internal { + function _pop(bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.popFromField(_tableId, _keyTuple, 0, 21, _fieldLayout); } /** Pop an element from value (using the specified store) */ - function pop(IStore _store, bytes32 resourceSelector) internal { + function pop(IStore _store, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.popFromField(_tableId, _keyTuple, 0, 21, _fieldLayout); } @@ -454,9 +458,9 @@ library SystemHooks { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function updateValue(bytes32 resourceSelector, uint256 _index, bytes21 _element) internal { + function updateValue(bytes32 systemId, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { StoreSwitch.updateInField(_tableId, _keyTuple, 0, _index * 21, abi.encodePacked((_element)), _fieldLayout); @@ -467,9 +471,9 @@ library SystemHooks { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function _updateValue(bytes32 resourceSelector, uint256 _index, bytes21 _element) internal { + function _updateValue(bytes32 systemId, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { StoreCore.updateInField(_tableId, _keyTuple, 0, _index * 21, abi.encodePacked((_element)), _fieldLayout); @@ -480,9 +484,9 @@ library SystemHooks { * Update an element of value (using the specified store) at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function updateValue(IStore _store, bytes32 resourceSelector, uint256 _index, bytes21 _element) internal { + function updateValue(IStore _store, bytes32 systemId, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { _store.updateInField(_tableId, _keyTuple, 0, _index * 21, abi.encodePacked((_element)), _fieldLayout); @@ -493,9 +497,9 @@ library SystemHooks { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function update(bytes32 resourceSelector, uint256 _index, bytes21 _element) internal { + function update(bytes32 systemId, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { StoreSwitch.updateInField(_tableId, _keyTuple, 0, _index * 21, abi.encodePacked((_element)), _fieldLayout); @@ -506,9 +510,9 @@ library SystemHooks { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function _update(bytes32 resourceSelector, uint256 _index, bytes21 _element) internal { + function _update(bytes32 systemId, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { StoreCore.updateInField(_tableId, _keyTuple, 0, _index * 21, abi.encodePacked((_element)), _fieldLayout); @@ -519,9 +523,9 @@ library SystemHooks { * Update an element of value (using the specified store) at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function update(IStore _store, bytes32 resourceSelector, uint256 _index, bytes21 _element) internal { + function update(IStore _store, bytes32 systemId, uint256 _index, bytes21 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; unchecked { _store.updateInField(_tableId, _keyTuple, 0, _index * 21, abi.encodePacked((_element)), _fieldLayout); @@ -551,33 +555,33 @@ library SystemHooks { } /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes32 resourceSelector) internal pure returns (bytes32[] memory) { + function encodeKeyTuple(bytes32 systemId) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; return _keyTuple; } /* Delete all data for given keys */ - function deleteRecord(bytes32 resourceSelector) internal { + function deleteRecord(bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord(bytes32 resourceSelector) internal { + function _deleteRecord(bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 resourceSelector) internal { + function deleteRecord(IStore _store, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } diff --git a/packages/world/src/modules/core/tables/SystemRegistry.sol b/packages/world/src/modules/core/tables/SystemRegistry.sol index 81a877f73d..58064ea817 100644 --- a/packages/world/src/modules/core/tables/SystemRegistry.sol +++ b/packages/world/src/modules/core/tables/SystemRegistry.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("SystemRegistry"))); -bytes32 constant SystemRegistryTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("SystemRegistry"))) +); +ResourceId constant SystemRegistryTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010020000000000000000000000000000000000000000000000000000000 @@ -56,7 +60,7 @@ library SystemRegistry { /** Get the table's field names */ function getFieldNames() internal pure returns (string[] memory fieldNames) { fieldNames = new string[](1); - fieldNames[0] = "resourceSelector"; + fieldNames[0] = "systemId"; } /** Register the table with its config */ @@ -74,8 +78,8 @@ library SystemRegistry { _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } - /** Get resourceSelector */ - function getResourceSelector(address system) internal view returns (bytes32 resourceSelector) { + /** Get systemId */ + function getSystemId(address system) internal view returns (bytes32 systemId) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); @@ -83,8 +87,8 @@ library SystemRegistry { return (bytes32(_blob)); } - /** Get resourceSelector */ - function _getResourceSelector(address system) internal view returns (bytes32 resourceSelector) { + /** Get systemId */ + function _getSystemId(address system) internal view returns (bytes32 systemId) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); @@ -92,8 +96,8 @@ library SystemRegistry { return (bytes32(_blob)); } - /** Get resourceSelector (using the specified store) */ - function getResourceSelector(IStore _store, address system) internal view returns (bytes32 resourceSelector) { + /** Get systemId (using the specified store) */ + function getSystemId(IStore _store, address system) internal view returns (bytes32 systemId) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); @@ -101,8 +105,8 @@ library SystemRegistry { return (bytes32(_blob)); } - /** Get resourceSelector */ - function get(address system) internal view returns (bytes32 resourceSelector) { + /** Get systemId */ + function get(address system) internal view returns (bytes32 systemId) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); @@ -110,8 +114,8 @@ library SystemRegistry { return (bytes32(_blob)); } - /** Get resourceSelector */ - function _get(address system) internal view returns (bytes32 resourceSelector) { + /** Get systemId */ + function _get(address system) internal view returns (bytes32 systemId) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); @@ -119,8 +123,8 @@ library SystemRegistry { return (bytes32(_blob)); } - /** Get resourceSelector (using the specified store) */ - function get(IStore _store, address system) internal view returns (bytes32 resourceSelector) { + /** Get systemId (using the specified store) */ + function get(IStore _store, address system) internal view returns (bytes32 systemId) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); @@ -128,62 +132,62 @@ library SystemRegistry { return (bytes32(_blob)); } - /** Set resourceSelector */ - function setResourceSelector(address system, bytes32 resourceSelector) internal { + /** Set systemId */ + function setSystemId(address system, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); - StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), _fieldLayout); + StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } - /** Set resourceSelector */ - function _setResourceSelector(address system, bytes32 resourceSelector) internal { + /** Set systemId */ + function _setSystemId(address system, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); - StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), _fieldLayout); + StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } - /** Set resourceSelector (using the specified store) */ - function setResourceSelector(IStore _store, address system, bytes32 resourceSelector) internal { + /** Set systemId (using the specified store) */ + function setSystemId(IStore _store, address system, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); - _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), _fieldLayout); + _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } - /** Set resourceSelector */ - function set(address system, bytes32 resourceSelector) internal { + /** Set systemId */ + function set(address system, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); - StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), _fieldLayout); + StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } - /** Set resourceSelector */ - function _set(address system, bytes32 resourceSelector) internal { + /** Set systemId */ + function _set(address system, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); - StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), _fieldLayout); + StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } - /** Set resourceSelector (using the specified store) */ - function set(IStore _store, address system, bytes32 resourceSelector) internal { + /** Set systemId (using the specified store) */ + function set(IStore _store, address system, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(uint160(system))); - _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), _fieldLayout); + _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } /** Tightly pack static data using this table's schema */ - function encodeStatic(bytes32 resourceSelector) internal pure returns (bytes memory) { - return abi.encodePacked(resourceSelector); + function encodeStatic(bytes32 systemId) internal pure returns (bytes memory) { + return abi.encodePacked(systemId); } /** Tightly pack full data using this table's field layout */ - function encode(bytes32 resourceSelector) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(resourceSelector); + function encode(bytes32 systemId) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(systemId); PackedCounter _encodedLengths; bytes memory _dynamicData; diff --git a/packages/world/src/modules/core/tables/Systems.sol b/packages/world/src/modules/core/tables/Systems.sol index 8a60905326..2da7769044 100644 --- a/packages/world/src/modules/core/tables/Systems.sol +++ b/packages/world/src/modules/core/tables/Systems.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Systems"))); -bytes32 constant SystemsTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Systems"))) +); +ResourceId constant SystemsTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0015020014010000000000000000000000000000000000000000000000000000 @@ -51,7 +55,7 @@ library Systems { /** Get the table's key names */ function getKeyNames() internal pure returns (string[] memory keyNames) { keyNames = new string[](1); - keyNames[0] = "resourceSelector"; + keyNames[0] = "systemId"; } /** Get the table's field names */ @@ -77,111 +81,111 @@ library Systems { } /** Get system */ - function getSystem(bytes32 resourceSelector) internal view returns (address system) { + function getSystem(bytes32 systemId) internal view returns (address system) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get system */ - function _getSystem(bytes32 resourceSelector) internal view returns (address system) { + function _getSystem(bytes32 systemId) internal view returns (address system) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get system (using the specified store) */ - function getSystem(IStore _store, bytes32 resourceSelector) internal view returns (address system) { + function getSystem(IStore _store, bytes32 systemId) internal view returns (address system) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Set system */ - function setSystem(bytes32 resourceSelector, address system) internal { + function setSystem(bytes32 systemId, address system) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((system)), _fieldLayout); } /** Set system */ - function _setSystem(bytes32 resourceSelector, address system) internal { + function _setSystem(bytes32 systemId, address system) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((system)), _fieldLayout); } /** Set system (using the specified store) */ - function setSystem(IStore _store, bytes32 resourceSelector, address system) internal { + function setSystem(IStore _store, bytes32 systemId, address system) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((system)), _fieldLayout); } /** Get publicAccess */ - function getPublicAccess(bytes32 resourceSelector) internal view returns (bool publicAccess) { + function getPublicAccess(bytes32 systemId) internal view returns (bool publicAccess) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 1, _fieldLayout); return (_toBool(uint8(bytes1(_blob)))); } /** Get publicAccess */ - function _getPublicAccess(bytes32 resourceSelector) internal view returns (bool publicAccess) { + function _getPublicAccess(bytes32 systemId) internal view returns (bool publicAccess) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 1, _fieldLayout); return (_toBool(uint8(bytes1(_blob)))); } /** Get publicAccess (using the specified store) */ - function getPublicAccess(IStore _store, bytes32 resourceSelector) internal view returns (bool publicAccess) { + function getPublicAccess(IStore _store, bytes32 systemId) internal view returns (bool publicAccess) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 1, _fieldLayout); return (_toBool(uint8(bytes1(_blob)))); } /** Set publicAccess */ - function setPublicAccess(bytes32 resourceSelector, bool publicAccess) internal { + function setPublicAccess(bytes32 systemId, bool publicAccess) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.setField(_tableId, _keyTuple, 1, abi.encodePacked((publicAccess)), _fieldLayout); } /** Set publicAccess */ - function _setPublicAccess(bytes32 resourceSelector, bool publicAccess) internal { + function _setPublicAccess(bytes32 systemId, bool publicAccess) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.setField(_tableId, _keyTuple, 1, abi.encodePacked((publicAccess)), _fieldLayout); } /** Set publicAccess (using the specified store) */ - function setPublicAccess(IStore _store, bytes32 resourceSelector, bool publicAccess) internal { + function setPublicAccess(IStore _store, bytes32 systemId, bool publicAccess) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.setField(_tableId, _keyTuple, 1, abi.encodePacked((publicAccess)), _fieldLayout); } /** Get the full data */ - function get(bytes32 resourceSelector) internal view returns (address system, bool publicAccess) { + function get(bytes32 systemId) internal view returns (address system, bool publicAccess) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; (bytes memory _staticData, PackedCounter _encodedLengths, bytes memory _dynamicData) = StoreSwitch.getRecord( _tableId, @@ -192,9 +196,9 @@ library Systems { } /** Get the full data */ - function _get(bytes32 resourceSelector) internal view returns (address system, bool publicAccess) { + function _get(bytes32 systemId) internal view returns (address system, bool publicAccess) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; (bytes memory _staticData, PackedCounter _encodedLengths, bytes memory _dynamicData) = StoreCore.getRecord( _tableId, @@ -205,9 +209,9 @@ library Systems { } /** Get the full data (using the specified store) */ - function get(IStore _store, bytes32 resourceSelector) internal view returns (address system, bool publicAccess) { + function get(IStore _store, bytes32 systemId) internal view returns (address system, bool publicAccess) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; (bytes memory _staticData, PackedCounter _encodedLengths, bytes memory _dynamicData) = _store.getRecord( _tableId, @@ -218,40 +222,40 @@ library Systems { } /** Set the full data using individual values */ - function set(bytes32 resourceSelector, address system, bool publicAccess) internal { + function set(bytes32 systemId, address system, bool publicAccess) internal { bytes memory _staticData = encodeStatic(system, publicAccess); PackedCounter _encodedLengths; bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); } /** Set the full data using individual values */ - function _set(bytes32 resourceSelector, address system, bool publicAccess) internal { + function _set(bytes32 systemId, address system, bool publicAccess) internal { bytes memory _staticData = encodeStatic(system, publicAccess); PackedCounter _encodedLengths; bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); } /** Set the full data using individual values (using the specified store) */ - function set(IStore _store, bytes32 resourceSelector, address system, bool publicAccess) internal { + function set(IStore _store, bytes32 systemId, address system, bool publicAccess) internal { bytes memory _staticData = encodeStatic(system, publicAccess); PackedCounter _encodedLengths; bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); } @@ -294,33 +298,33 @@ library Systems { } /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes32 resourceSelector) internal pure returns (bytes32[] memory) { + function encodeKeyTuple(bytes32 systemId) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; return _keyTuple; } /* Delete all data for given keys */ - function deleteRecord(bytes32 resourceSelector) internal { + function deleteRecord(bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord(bytes32 resourceSelector) internal { + function _deleteRecord(bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 resourceSelector) internal { + function deleteRecord(IStore _store, bytes32 systemId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = systemId; _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } diff --git a/packages/world/src/modules/keysintable/KeysInTableHook.sol b/packages/world/src/modules/keysintable/KeysInTableHook.sol index 69113cc5a8..0d8681456d 100644 --- a/packages/world/src/modules/keysintable/KeysInTableHook.sol +++ b/packages/world/src/modules/keysintable/KeysInTableHook.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.0; import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; import { StoreHook } from "@latticexyz/store/src/StoreHook.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; import { KeysInTable } from "./tables/KeysInTable.sol"; import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol"; @@ -12,24 +13,24 @@ import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol"; * Note: if a table with composite keys is used, only the first five keys of the tuple are indexed */ contract KeysInTableHook is StoreHook { - function handleSet(bytes32 tableId, bytes32[] memory keyTuple) internal { + function handleSet(ResourceId tableId, bytes32[] memory keyTuple) internal { bytes32 keysHash = keccak256(abi.encode(keyTuple)); // If the keyTuple has not yet been set in the table... - if (!UsedKeysIndex.getHas(tableId, keysHash)) { - uint40 length = uint40(KeysInTable.lengthKeys0(tableId)); + if (!UsedKeysIndex.getHas(ResourceId.unwrap(tableId), keysHash)) { + uint40 length = uint40(KeysInTable.lengthKeys0(ResourceId.unwrap(tableId))); // Push the keyTuple to the list of keys in this table if (keyTuple.length > 0) { - KeysInTable.pushKeys0(tableId, keyTuple[0]); + KeysInTable.pushKeys0(ResourceId.unwrap(tableId), keyTuple[0]); if (keyTuple.length > 1) { - KeysInTable.pushKeys1(tableId, keyTuple[1]); + KeysInTable.pushKeys1(ResourceId.unwrap(tableId), keyTuple[1]); if (keyTuple.length > 2) { - KeysInTable.pushKeys2(tableId, keyTuple[2]); + KeysInTable.pushKeys2(ResourceId.unwrap(tableId), keyTuple[2]); if (keyTuple.length > 3) { - KeysInTable.pushKeys3(tableId, keyTuple[3]); + KeysInTable.pushKeys3(ResourceId.unwrap(tableId), keyTuple[3]); if (keyTuple.length > 4) { - KeysInTable.pushKeys4(tableId, keyTuple[4]); + KeysInTable.pushKeys4(ResourceId.unwrap(tableId), keyTuple[4]); } } } @@ -37,12 +38,12 @@ contract KeysInTableHook is StoreHook { } // Update the index to avoid duplicating this keyTuple in the array - UsedKeysIndex.set(tableId, keysHash, true, length); + UsedKeysIndex.set(ResourceId.unwrap(tableId), keysHash, true, length); } } function onBeforeSetRecord( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, bytes memory, PackedCounter, @@ -53,7 +54,7 @@ contract KeysInTableHook is StoreHook { } function onAfterSpliceStaticData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint48, uint40, @@ -63,7 +64,7 @@ contract KeysInTableHook is StoreHook { } function onAfterSpliceDynamicData( - bytes32 tableId, + ResourceId tableId, bytes32[] memory keyTuple, uint8, uint40, @@ -74,58 +75,58 @@ contract KeysInTableHook is StoreHook { handleSet(tableId, keyTuple); } - function onBeforeDeleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout) public override { + function onBeforeDeleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout) public override { bytes32 keysHash = keccak256(abi.encode(keyTuple)); - (bool has, uint40 index) = UsedKeysIndex.get(tableId, keysHash); + (bool has, uint40 index) = UsedKeysIndex.get(ResourceId.unwrap(tableId), keysHash); // If the keyTuple was part of the table... if (has) { // Delete the index as the keyTuple is not in the table anymore - UsedKeysIndex.deleteRecord(tableId, keysHash); + UsedKeysIndex.deleteRecord(ResourceId.unwrap(tableId), keysHash); - uint40 length = uint40(KeysInTable.lengthKeys0(tableId)); + uint40 length = uint40(KeysInTable.lengthKeys0(ResourceId.unwrap(tableId))); if (length == 1) { // Delete the list of keys in this table - KeysInTable.deleteRecord(tableId); + KeysInTable.deleteRecord(ResourceId.unwrap(tableId)); } else { if (keyTuple.length > 0) { bytes32[] memory lastKeyTuple = new bytes32[](keyTuple.length); - bytes32 lastKey = KeysInTable.getItemKeys0(tableId, length - 1); + bytes32 lastKey = KeysInTable.getItemKeys0(ResourceId.unwrap(tableId), length - 1); lastKeyTuple[0] = lastKey; // Remove the keyTuple from the list of keys in this table - KeysInTable.updateKeys0(tableId, index, lastKey); - KeysInTable.popKeys0(tableId); + KeysInTable.updateKeys0(ResourceId.unwrap(tableId), index, lastKey); + KeysInTable.popKeys0(ResourceId.unwrap(tableId)); if (keyTuple.length > 1) { - lastKey = KeysInTable.getItemKeys1(tableId, length - 1); + lastKey = KeysInTable.getItemKeys1(ResourceId.unwrap(tableId), length - 1); lastKeyTuple[1] = lastKey; - KeysInTable.updateKeys1(tableId, index, lastKey); - KeysInTable.popKeys1(tableId); + KeysInTable.updateKeys1(ResourceId.unwrap(tableId), index, lastKey); + KeysInTable.popKeys1(ResourceId.unwrap(tableId)); if (keyTuple.length > 2) { - lastKey = KeysInTable.getItemKeys2(tableId, length - 1); + lastKey = KeysInTable.getItemKeys2(ResourceId.unwrap(tableId), length - 1); lastKeyTuple[2] = lastKey; - KeysInTable.updateKeys2(tableId, index, lastKey); - KeysInTable.popKeys2(tableId); + KeysInTable.updateKeys2(ResourceId.unwrap(tableId), index, lastKey); + KeysInTable.popKeys2(ResourceId.unwrap(tableId)); if (keyTuple.length > 3) { - lastKey = KeysInTable.getItemKeys3(tableId, length - 1); + lastKey = KeysInTable.getItemKeys3(ResourceId.unwrap(tableId), length - 1); lastKeyTuple[3] = lastKey; - KeysInTable.updateKeys3(tableId, index, lastKey); - KeysInTable.popKeys3(tableId); + KeysInTable.updateKeys3(ResourceId.unwrap(tableId), index, lastKey); + KeysInTable.popKeys3(ResourceId.unwrap(tableId)); if (keyTuple.length > 4) { - lastKey = KeysInTable.getItemKeys4(tableId, length - 1); + lastKey = KeysInTable.getItemKeys4(ResourceId.unwrap(tableId), length - 1); lastKeyTuple[4] = lastKey; - KeysInTable.updateKeys4(tableId, index, lastKey); - KeysInTable.popKeys4(tableId); + KeysInTable.updateKeys4(ResourceId.unwrap(tableId), index, lastKey); + KeysInTable.popKeys4(ResourceId.unwrap(tableId)); } } } @@ -133,7 +134,7 @@ contract KeysInTableHook is StoreHook { // Update the index of lastKeyTuple after swapping it with the deleted keyTuple bytes32 lastKeyHash = keccak256(abi.encode(lastKeyTuple)); - UsedKeysIndex.setIndex(tableId, lastKeyHash, index); + UsedKeysIndex.setIndex(ResourceId.unwrap(tableId), lastKeyHash, index); } } } diff --git a/packages/world/src/modules/keysintable/KeysInTableModule.sol b/packages/world/src/modules/keysintable/KeysInTableModule.sol index cd6d0b9f7d..b0357b7dd0 100644 --- a/packages/world/src/modules/keysintable/KeysInTableModule.sol +++ b/packages/world/src/modules/keysintable/KeysInTableModule.sol @@ -2,14 +2,13 @@ pragma solidity >=0.8.0; import { BEFORE_SET_RECORD, AFTER_SPLICE_STATIC_DATA, AFTER_SPLICE_DYNAMIC_DATA, BEFORE_DELETE_RECORD } from "@latticexyz/store/src/storeHookTypes.sol"; +import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol"; -import { ResourceType } from "../core/tables/ResourceType.sol"; -import { Resource } from "../../common.sol"; import { Module } from "../../Module.sol"; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; -import { ResourceSelector } from "../../ResourceSelector.sol"; +import { ResourceId, WorldResourceIdInstance } from "../../WorldResourceId.sol"; import { revertWithBytes } from "../../revertWithBytes.sol"; import { KeysInTableHook } from "./KeysInTableHook.sol"; @@ -27,7 +26,7 @@ import { UsedKeysIndex, UsedKeysIndexTableId } from "./tables/UsedKeysIndex.sol" * TODO: add support for `install` (via `World.installModule`) by using `callFrom` with the `msgSender()` */ contract KeysInTableModule is Module { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; // The KeysInTableHook is deployed once and infers the target table id // from the source table id (passed as argument to the hook methods) @@ -39,7 +38,7 @@ contract KeysInTableModule is Module { function installRoot(bytes memory args) public override { // Extract source table id from args - bytes32 sourceTableId = abi.decode(args, (bytes32)); + ResourceId sourceTableId = ResourceId.wrap(abi.decode(args, (bytes32))); IBaseWorld world = IBaseWorld(_world()); @@ -47,7 +46,7 @@ contract KeysInTableModule is Module { bool success; bytes memory returnData; - if (ResourceType.get(KeysInTableTableId) == Resource.NONE) { + if (!ResourceIds._getExists(ResourceId.unwrap(KeysInTableTableId))) { // Register the tables (success, returnData) = address(world).delegatecall( abi.encodeCall( diff --git a/packages/world/src/modules/keysintable/getKeysInTable.sol b/packages/world/src/modules/keysintable/getKeysInTable.sol index c6b709f5fc..06d7bcf41b 100644 --- a/packages/world/src/modules/keysintable/getKeysInTable.sol +++ b/packages/world/src/modules/keysintable/getKeysInTable.sol @@ -4,6 +4,7 @@ pragma solidity >=0.8.0; import { IStore } from "@latticexyz/store/src/IStore.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; import { KeysInTable } from "./tables/KeysInTable.sol"; @@ -13,29 +14,29 @@ import { KeysInTable } from "./tables/KeysInTable.sol"; * Note: this util can only be called within the context of a Store (e.g. from a System or Module). * For usage outside of a Store, use the overload that takes an explicit store argument. */ -function getKeysInTable(bytes32 tableId) view returns (bytes32[][] memory keyTuples) { +function getKeysInTable(ResourceId tableId) view returns (bytes32[][] memory keyTuples) { /** * Note: this module only supports up to 5 composite keys. */ Schema keySchema = StoreSwitch.getKeySchema(tableId); uint256 numFields = keySchema.numFields(); - uint256 length = KeysInTable.lengthKeys0(tableId); + uint256 length = KeysInTable.lengthKeys0(ResourceId.unwrap(tableId)); keyTuples = new bytes32[][](length); for (uint256 i; i < length; i++) { keyTuples[i] = new bytes32[](numFields); // the length of the key tuple depends on the key schema if (numFields > 0) { - keyTuples[i][0] = KeysInTable.getItemKeys0(tableId, i); + keyTuples[i][0] = KeysInTable.getItemKeys0(ResourceId.unwrap(tableId), i); if (numFields > 1) { - keyTuples[i][1] = KeysInTable.getItemKeys1(tableId, i); + keyTuples[i][1] = KeysInTable.getItemKeys1(ResourceId.unwrap(tableId), i); if (numFields > 2) { - keyTuples[i][2] = KeysInTable.getItemKeys2(tableId, i); + keyTuples[i][2] = KeysInTable.getItemKeys2(ResourceId.unwrap(tableId), i); if (numFields > 3) { - keyTuples[i][3] = KeysInTable.getItemKeys3(tableId, i); + keyTuples[i][3] = KeysInTable.getItemKeys3(ResourceId.unwrap(tableId), i); if (numFields > 4) { - keyTuples[i][4] = KeysInTable.getItemKeys4(tableId, i); + keyTuples[i][4] = KeysInTable.getItemKeys4(ResourceId.unwrap(tableId), i); } } } @@ -47,7 +48,7 @@ function getKeysInTable(bytes32 tableId) view returns (bytes32[][] memory keyTup /** * Get a list of keys in the given table for the given store. */ -function getKeysInTable(IStore store, bytes32 tableId) view returns (bytes32[][] memory keyTuples) { +function getKeysInTable(IStore store, ResourceId tableId) view returns (bytes32[][] memory keyTuples) { /** * Note: this module only supports up to 5 composite keys. */ @@ -55,22 +56,22 @@ function getKeysInTable(IStore store, bytes32 tableId) view returns (bytes32[][] Schema keySchema = store.getKeySchema(tableId); uint256 numFields = keySchema.numFields(); - uint256 length = KeysInTable.lengthKeys0(store, tableId); + uint256 length = KeysInTable.lengthKeys0(store, ResourceId.unwrap(tableId)); keyTuples = new bytes32[][](length); for (uint256 i; i < length; i++) { keyTuples[i] = new bytes32[](numFields); // the length of the key tuple depends on the key schema if (numFields > 0) { - keyTuples[i][0] = KeysInTable.getItemKeys0(store, tableId, i); + keyTuples[i][0] = KeysInTable.getItemKeys0(store, ResourceId.unwrap(tableId), i); if (numFields > 1) { - keyTuples[i][1] = KeysInTable.getItemKeys1(store, tableId, i); + keyTuples[i][1] = KeysInTable.getItemKeys1(store, ResourceId.unwrap(tableId), i); if (numFields > 2) { - keyTuples[i][2] = KeysInTable.getItemKeys2(store, tableId, i); + keyTuples[i][2] = KeysInTable.getItemKeys2(store, ResourceId.unwrap(tableId), i); if (numFields > 3) { - keyTuples[i][3] = KeysInTable.getItemKeys3(store, tableId, i); + keyTuples[i][3] = KeysInTable.getItemKeys3(store, ResourceId.unwrap(tableId), i); if (numFields > 4) { - keyTuples[i][4] = KeysInTable.getItemKeys4(store, tableId, i); + keyTuples[i][4] = KeysInTable.getItemKeys4(store, ResourceId.unwrap(tableId), i); } } } diff --git a/packages/world/src/modules/keysintable/hasKey.sol b/packages/world/src/modules/keysintable/hasKey.sol index 637439047e..0efd658135 100644 --- a/packages/world/src/modules/keysintable/hasKey.sol +++ b/packages/world/src/modules/keysintable/hasKey.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol"; @@ -11,17 +12,17 @@ import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol"; * Note: this util can only be called within the context of a Store (e.g. from a System or Module). * For usage outside of a Store, use the overload that takes an explicit store argument. */ -function hasKey(bytes32 tableId, bytes32[] memory keyTuple) view returns (bool) { +function hasKey(ResourceId tableId, bytes32[] memory keyTuple) view returns (bool) { bytes32 keysHash = keccak256(abi.encode(keyTuple)); - return UsedKeysIndex.getHas(tableId, keysHash); + return UsedKeysIndex.getHas(ResourceId.unwrap(tableId), keysHash); } /** * Get whether the keyTuple is in the given table for the given store. */ -function hasKey(IStore store, bytes32 tableId, bytes32[] memory keyTuple) view returns (bool) { +function hasKey(IStore store, ResourceId tableId, bytes32[] memory keyTuple) view returns (bool) { bytes32 keysHash = keccak256(abi.encode(keyTuple)); - return UsedKeysIndex.getHas(store, tableId, keysHash); + return UsedKeysIndex.getHas(store, ResourceId.unwrap(tableId), keysHash); } diff --git a/packages/world/src/modules/keysintable/query.sol b/packages/world/src/modules/keysintable/query.sol index 53769a113e..3dbd72bc50 100644 --- a/packages/world/src/modules/keysintable/query.sol +++ b/packages/world/src/modules/keysintable/query.sol @@ -3,6 +3,7 @@ pragma solidity >=0.8.0; import { IStore } from "@latticexyz/store/src/IStore.sol"; import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; import { getKeysInTable } from "./getKeysInTable.sol"; import { getKeysWithValue } from "../keyswithvalue/getKeysWithValue.sol"; @@ -17,7 +18,7 @@ enum QueryType { struct QueryFragment { QueryType queryType; - bytes32 tableId; + ResourceId tableId; bytes value; } diff --git a/packages/world/src/modules/keysintable/tables/KeysInTable.sol b/packages/world/src/modules/keysintable/tables/KeysInTable.sol index 7de0288cc7..b51ca0c922 100644 --- a/packages/world/src/modules/keysintable/tables/KeysInTable.sol +++ b/packages/world/src/modules/keysintable/tables/KeysInTable.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("KeysInTable"))); -bytes32 constant KeysInTableTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("KeysInTable"))) +); +ResourceId constant KeysInTableTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000500000000000000000000000000000000000000000000000000000000 diff --git a/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol b/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol index f674c7aadc..d4c75eddb8 100644 --- a/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol +++ b/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("UsedKeysIndex"))); -bytes32 constant UsedKeysIndexTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("UsedKeysIndex"))) +); +ResourceId constant UsedKeysIndexTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0006020001050000000000000000000000000000000000000000000000000000 diff --git a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol index d666a3f4fa..b945b7ec3d 100644 --- a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol +++ b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol @@ -9,12 +9,12 @@ import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { Tables } from "@latticexyz/store/src/codegen/tables/Tables.sol"; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; -import { ResourceSelector } from "../../ResourceSelector.sol"; +import { ResourceId, WorldResourceIdInstance } from "../../WorldResourceId.sol"; import { MODULE_NAMESPACE } from "./constants.sol"; import { KeysWithValue } from "./tables/KeysWithValue.sol"; import { ArrayLib } from "../utils/ArrayLib.sol"; -import { getTargetTableSelector } from "../utils/getTargetTableSelector.sol"; +import { getTargetTableId } from "./getTargetTableId.sol"; /** * This is a very naive and inefficient implementation for now. @@ -25,21 +25,21 @@ import { getTargetTableSelector } from "../utils/getTargetTableSelector.sol"; */ contract KeysWithValueHook is StoreHook { using ArrayLib for bytes32[]; - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; function _world() internal view returns (IBaseWorld) { return IBaseWorld(StoreSwitch.getStoreAddress()); } function onBeforeSetRecord( - bytes32 sourceTableId, + ResourceId sourceTableId, bytes32[] memory keyTuple, bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData, FieldLayout fieldLayout ) public override { - bytes32 targetTableId = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + ResourceId targetTableId = getTargetTableId(MODULE_NAMESPACE, sourceTableId); // Get the previous value bytes32 previousValue = _getRecordValueHash(sourceTableId, keyTuple, fieldLayout); @@ -58,35 +58,35 @@ contract KeysWithValueHook is StoreHook { } function onBeforeSpliceStaticData( - bytes32 sourceTableId, + ResourceId sourceTableId, bytes32[] memory keyTuple, uint48, uint40, bytes memory ) public override { // Remove the key from the list of keys with the previous value - FieldLayout fieldLayout = FieldLayout.wrap(Tables.getFieldLayout(sourceTableId)); + FieldLayout fieldLayout = FieldLayout.wrap(Tables.getFieldLayout(ResourceId.unwrap(sourceTableId))); bytes32 previousValue = _getRecordValueHash(sourceTableId, keyTuple, fieldLayout); - bytes32 targetTableId = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + ResourceId targetTableId = getTargetTableId(MODULE_NAMESPACE, sourceTableId); _removeKeyFromList(targetTableId, keyTuple[0], previousValue); } function onAfterSpliceStaticData( - bytes32 sourceTableId, + ResourceId sourceTableId, bytes32[] memory keyTuple, uint48, uint40, bytes memory ) public override { // Add the key to the list of keys with the new value - FieldLayout fieldLayout = FieldLayout.wrap(Tables.getFieldLayout(sourceTableId)); + FieldLayout fieldLayout = FieldLayout.wrap(Tables.getFieldLayout(ResourceId.unwrap(sourceTableId))); bytes32 newValue = _getRecordValueHash(sourceTableId, keyTuple, fieldLayout); - bytes32 targetTableId = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + ResourceId targetTableId = getTargetTableId(MODULE_NAMESPACE, sourceTableId); KeysWithValue.push(targetTableId, newValue, keyTuple[0]); } function onBeforeSpliceDynamicData( - bytes32 sourceTableId, + ResourceId sourceTableId, bytes32[] memory keyTuple, uint8, uint40, @@ -95,14 +95,14 @@ contract KeysWithValueHook is StoreHook { PackedCounter ) public override { // Remove the key from the list of keys with the previous value - FieldLayout fieldLayout = FieldLayout.wrap(Tables.getFieldLayout(sourceTableId)); + FieldLayout fieldLayout = FieldLayout.wrap(Tables.getFieldLayout(ResourceId.unwrap(sourceTableId))); bytes32 previousValue = _getRecordValueHash(sourceTableId, keyTuple, fieldLayout); - bytes32 targetTableId = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + ResourceId targetTableId = getTargetTableId(MODULE_NAMESPACE, sourceTableId); _removeKeyFromList(targetTableId, keyTuple[0], previousValue); } function onAfterSpliceDynamicData( - bytes32 sourceTableId, + ResourceId sourceTableId, bytes32[] memory keyTuple, uint8, uint40, @@ -111,25 +111,25 @@ contract KeysWithValueHook is StoreHook { PackedCounter ) public override { // Add the key to the list of keys with the new value - FieldLayout fieldLayout = FieldLayout.wrap(Tables.getFieldLayout(sourceTableId)); + FieldLayout fieldLayout = FieldLayout.wrap(Tables.getFieldLayout(ResourceId.unwrap(sourceTableId))); bytes32 newValue = _getRecordValueHash(sourceTableId, keyTuple, fieldLayout); - bytes32 targetTableId = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + ResourceId targetTableId = getTargetTableId(MODULE_NAMESPACE, sourceTableId); KeysWithValue.push(targetTableId, newValue, keyTuple[0]); } function onBeforeDeleteRecord( - bytes32 sourceTableId, + ResourceId sourceTableId, bytes32[] memory keyTuple, FieldLayout fieldLayout ) public override { // Remove the key from the list of keys with the previous value bytes32 previousValue = _getRecordValueHash(sourceTableId, keyTuple, fieldLayout); - bytes32 targetTableId = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + ResourceId targetTableId = getTargetTableId(MODULE_NAMESPACE, sourceTableId); _removeKeyFromList(targetTableId, keyTuple[0], previousValue); } function _getRecordValueHash( - bytes32 sourceTableId, + ResourceId sourceTableId, bytes32[] memory keyTuple, FieldLayout fieldLayout ) internal view returns (bytes32 valueHash) { @@ -145,7 +145,7 @@ contract KeysWithValueHook is StoreHook { } } - function _removeKeyFromList(bytes32 targetTableId, bytes32 key, bytes32 valueHash) internal { + function _removeKeyFromList(ResourceId targetTableId, bytes32 key, bytes32 valueHash) internal { // Get the keys with the previous value excluding the current key bytes32[] memory keysWithPreviousValue = KeysWithValue.get(targetTableId, valueHash).filter(key); diff --git a/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol b/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol index 65774a0093..d6b210666f 100644 --- a/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol +++ b/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol @@ -8,13 +8,13 @@ import { Module } from "../../Module.sol"; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; import { WorldContextConsumer } from "../../WorldContext.sol"; -import { ResourceSelector } from "../../ResourceSelector.sol"; +import { ResourceId, WorldResourceIdInstance } from "../../WorldResourceId.sol"; import { revertWithBytes } from "../../revertWithBytes.sol"; import { MODULE_NAMESPACE } from "./constants.sol"; import { KeysWithValueHook } from "./KeysWithValueHook.sol"; import { KeysWithValue } from "./tables/KeysWithValue.sol"; -import { getTargetTableSelector } from "../utils/getTargetTableSelector.sol"; +import { getTargetTableId } from "./getTargetTableId.sol"; /** * This module deploys a hook that is called when a value is set in the `sourceTableId` @@ -28,7 +28,7 @@ import { getTargetTableSelector } from "../utils/getTargetTableSelector.sol"; * TODO: add support for `install` (via `World.installModule`) by using `callFrom` with the `msgSender()` */ contract KeysWithValueModule is Module { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; // The KeysWithValueHook is deployed once and infers the target table id // from the source table id (passed as argument to the hook methods) @@ -40,8 +40,8 @@ contract KeysWithValueModule is Module { function installRoot(bytes memory args) public { // Extract source table id from args - bytes32 sourceTableId = abi.decode(args, (bytes32)); - bytes32 targetTableSelector = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + ResourceId sourceTableId = ResourceId.wrap(abi.decode(args, (bytes32))); + ResourceId targetTableSelector = getTargetTableId(MODULE_NAMESPACE, sourceTableId); IBaseWorld world = IBaseWorld(_world()); diff --git a/packages/world/src/modules/keyswithvalue/constants.sol b/packages/world/src/modules/keyswithvalue/constants.sol index 17528e1ec8..b239bade58 100644 --- a/packages/world/src/modules/keyswithvalue/constants.sol +++ b/packages/world/src/modules/keyswithvalue/constants.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -// Limiting the module namespace to 8 bytes so the last 8 bytes +// Limiting the module namespace to 7 bytes so the remaining 7 bytes // can be used for an identifier of the source table namespace to avoid // collisions between tables with the same name in different namespaces -bytes8 constant MODULE_NAMESPACE = "keyswval"; +bytes7 constant MODULE_NAMESPACE = "keywval"; diff --git a/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol b/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol index e47fba0d10..07cebf75cd 100644 --- a/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol +++ b/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol @@ -3,10 +3,11 @@ pragma solidity >=0.8.0; import { IStore } from "@latticexyz/store/src/IStore.sol"; import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; import { MODULE_NAMESPACE } from "./constants.sol"; import { KeysWithValue } from "./tables/KeysWithValue.sol"; -import { getTargetTableSelector } from "../utils/getTargetTableSelector.sol"; +import { getTargetTableId } from "./getTargetTableId.sol"; /** * Get a list of keys with the given value. @@ -15,13 +16,13 @@ import { getTargetTableSelector } from "../utils/getTargetTableSelector.sol"; * For usage outside of a Store, use the overload that takes an explicit store argument. */ function getKeysWithValue( - bytes32 tableId, + ResourceId tableId, bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData ) view returns (bytes32[] memory keysWithValue) { // Get the corresponding reverse mapping table - bytes32 keysWithValueTableId = getTargetTableSelector(MODULE_NAMESPACE, tableId); + ResourceId keysWithValueTableId = getTargetTableId(MODULE_NAMESPACE, tableId); // Get the keys with the given value bytes memory value; @@ -38,13 +39,13 @@ function getKeysWithValue( */ function getKeysWithValue( IStore store, - bytes32 tableId, + ResourceId tableId, bytes memory staticData, PackedCounter encodedLengths, bytes memory dynamicData ) view returns (bytes32[] memory keysWithValue) { // Get the corresponding reverse mapping table - bytes32 keysWithValueTableId = getTargetTableSelector(MODULE_NAMESPACE, tableId); + ResourceId keysWithValueTableId = getTargetTableId(MODULE_NAMESPACE, tableId); // Get the keys with the given value bytes memory value; diff --git a/packages/world/src/modules/keyswithvalue/getTargetTableId.sol b/packages/world/src/modules/keyswithvalue/getTargetTableId.sol new file mode 100644 index 0000000000..b972ff8208 --- /dev/null +++ b/packages/world/src/modules/keyswithvalue/getTargetTableId.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { TYPE_BYTES } from "@latticexyz/store/src/ResourceId.sol"; +import { ResourceId, WorldResourceIdInstance, NAME_BYTES } from "../../WorldResourceId.sol"; +import { RESOURCE_TABLE } from "../../worldResourceTypes.sol"; + +uint256 constant MODULE_NAMESPACE_BYTES = 7; +uint256 constant TABLE_NAMESPACE_BYTES = 7; +uint256 constant TABLE_NAME_BYTES = 16; +uint256 constant BYTES_TO_BITS = 8; + +/** + * Get a deterministic selector for the reverse mapping table for the given source table. + * The selector is constructed as follows: + * - The first 2 bytes are the resource type + * - The next 7 bytes are the module namespace + * - The next 7 bytes are the first 7 bytes of the source table namespace + * -- This is to avoid collisions between tables with the same name in different namespaces + * (Note that collisions are still possible if the first 7 bytes of the namespace are the same, in which case installing the module fails) + * - The last 16 bytes are the source table name + */ +function getTargetTableId(bytes7 moduleNamespace, ResourceId sourceTableId) pure returns (ResourceId) { + bytes16 tableName = WorldResourceIdInstance.getName(sourceTableId); + bytes7 sourceTableNamespace = bytes7(WorldResourceIdInstance.getNamespace(sourceTableId)); + return + ResourceId.wrap( + bytes32(RESOURCE_TABLE) | + (bytes32(moduleNamespace) >> (TYPE_BYTES * BYTES_TO_BITS)) | + (bytes32(sourceTableNamespace) >> ((TYPE_BYTES + MODULE_NAMESPACE_BYTES) * BYTES_TO_BITS)) | + (bytes32(tableName) >> ((TYPE_BYTES + MODULE_NAMESPACE_BYTES + TABLE_NAMESPACE_BYTES) * BYTES_TO_BITS)) + ); +} diff --git a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol index 3024469cc6..24fce461aa 100644 --- a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol +++ b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol @@ -17,6 +17,8 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 @@ -57,23 +59,23 @@ library KeysWithValue { } /** Register the table with its config */ - function register(bytes32 _tableId) internal { + function register(ResourceId _tableId) internal { StoreSwitch.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config */ - function _register(bytes32 _tableId) internal { + function _register(ResourceId _tableId) internal { StoreCore.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config (using the specified store) */ - function register(IStore _store, bytes32 _tableId) internal { + function register(IStore _store, ResourceId _tableId) internal { _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Get keysWithValue */ function getKeysWithValue( - bytes32 _tableId, + ResourceId _tableId, bytes32 valueHash ) internal view returns (bytes32[] memory keysWithValue) { bytes32[] memory _keyTuple = new bytes32[](1); @@ -85,7 +87,7 @@ library KeysWithValue { /** Get keysWithValue */ function _getKeysWithValue( - bytes32 _tableId, + ResourceId _tableId, bytes32 valueHash ) internal view returns (bytes32[] memory keysWithValue) { bytes32[] memory _keyTuple = new bytes32[](1); @@ -98,7 +100,7 @@ library KeysWithValue { /** Get keysWithValue (using the specified store) */ function getKeysWithValue( IStore _store, - bytes32 _tableId, + ResourceId _tableId, bytes32 valueHash ) internal view returns (bytes32[] memory keysWithValue) { bytes32[] memory _keyTuple = new bytes32[](1); @@ -109,7 +111,7 @@ library KeysWithValue { } /** Get keysWithValue */ - function get(bytes32 _tableId, bytes32 valueHash) internal view returns (bytes32[] memory keysWithValue) { + function get(ResourceId _tableId, bytes32 valueHash) internal view returns (bytes32[] memory keysWithValue) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -118,7 +120,7 @@ library KeysWithValue { } /** Get keysWithValue */ - function _get(bytes32 _tableId, bytes32 valueHash) internal view returns (bytes32[] memory keysWithValue) { + function _get(ResourceId _tableId, bytes32 valueHash) internal view returns (bytes32[] memory keysWithValue) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -129,7 +131,7 @@ library KeysWithValue { /** Get keysWithValue (using the specified store) */ function get( IStore _store, - bytes32 _tableId, + ResourceId _tableId, bytes32 valueHash ) internal view returns (bytes32[] memory keysWithValue) { bytes32[] memory _keyTuple = new bytes32[](1); @@ -140,7 +142,7 @@ library KeysWithValue { } /** Set keysWithValue */ - function setKeysWithValue(bytes32 _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { + function setKeysWithValue(ResourceId _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -148,7 +150,7 @@ library KeysWithValue { } /** Set keysWithValue */ - function _setKeysWithValue(bytes32 _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { + function _setKeysWithValue(ResourceId _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -158,7 +160,7 @@ library KeysWithValue { /** Set keysWithValue (using the specified store) */ function setKeysWithValue( IStore _store, - bytes32 _tableId, + ResourceId _tableId, bytes32 valueHash, bytes32[] memory keysWithValue ) internal { @@ -169,7 +171,7 @@ library KeysWithValue { } /** Set keysWithValue */ - function set(bytes32 _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { + function set(ResourceId _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -177,7 +179,7 @@ library KeysWithValue { } /** Set keysWithValue */ - function _set(bytes32 _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { + function _set(ResourceId _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -185,7 +187,7 @@ library KeysWithValue { } /** Set keysWithValue (using the specified store) */ - function set(IStore _store, bytes32 _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { + function set(IStore _store, ResourceId _tableId, bytes32 valueHash, bytes32[] memory keysWithValue) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -193,7 +195,7 @@ library KeysWithValue { } /** Get the length of keysWithValue */ - function lengthKeysWithValue(bytes32 _tableId, bytes32 valueHash) internal view returns (uint256) { + function lengthKeysWithValue(ResourceId _tableId, bytes32 valueHash) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -204,7 +206,7 @@ library KeysWithValue { } /** Get the length of keysWithValue */ - function _lengthKeysWithValue(bytes32 _tableId, bytes32 valueHash) internal view returns (uint256) { + function _lengthKeysWithValue(ResourceId _tableId, bytes32 valueHash) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -215,7 +217,7 @@ library KeysWithValue { } /** Get the length of keysWithValue (using the specified store) */ - function lengthKeysWithValue(IStore _store, bytes32 _tableId, bytes32 valueHash) internal view returns (uint256) { + function lengthKeysWithValue(IStore _store, ResourceId _tableId, bytes32 valueHash) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -226,7 +228,7 @@ library KeysWithValue { } /** Get the length of keysWithValue */ - function length(bytes32 _tableId, bytes32 valueHash) internal view returns (uint256) { + function length(ResourceId _tableId, bytes32 valueHash) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -237,7 +239,7 @@ library KeysWithValue { } /** Get the length of keysWithValue */ - function _length(bytes32 _tableId, bytes32 valueHash) internal view returns (uint256) { + function _length(ResourceId _tableId, bytes32 valueHash) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -248,7 +250,7 @@ library KeysWithValue { } /** Get the length of keysWithValue (using the specified store) */ - function length(IStore _store, bytes32 _tableId, bytes32 valueHash) internal view returns (uint256) { + function length(IStore _store, ResourceId _tableId, bytes32 valueHash) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -262,7 +264,11 @@ library KeysWithValue { * Get an item of keysWithValue * (unchecked, returns invalid data if index overflows) */ - function getItemKeysWithValue(bytes32 _tableId, bytes32 valueHash, uint256 _index) internal view returns (bytes32) { + function getItemKeysWithValue( + ResourceId _tableId, + bytes32 valueHash, + uint256 _index + ) internal view returns (bytes32) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -283,7 +289,11 @@ library KeysWithValue { * Get an item of keysWithValue * (unchecked, returns invalid data if index overflows) */ - function _getItemKeysWithValue(bytes32 _tableId, bytes32 valueHash, uint256 _index) internal view returns (bytes32) { + function _getItemKeysWithValue( + ResourceId _tableId, + bytes32 valueHash, + uint256 _index + ) internal view returns (bytes32) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -306,7 +316,7 @@ library KeysWithValue { */ function getItemKeysWithValue( IStore _store, - bytes32 _tableId, + ResourceId _tableId, bytes32 valueHash, uint256 _index ) internal view returns (bytes32) { @@ -323,7 +333,7 @@ library KeysWithValue { * Get an item of keysWithValue * (unchecked, returns invalid data if index overflows) */ - function getItem(bytes32 _tableId, bytes32 valueHash, uint256 _index) internal view returns (bytes32) { + function getItem(ResourceId _tableId, bytes32 valueHash, uint256 _index) internal view returns (bytes32) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -344,7 +354,7 @@ library KeysWithValue { * Get an item of keysWithValue * (unchecked, returns invalid data if index overflows) */ - function _getItem(bytes32 _tableId, bytes32 valueHash, uint256 _index) internal view returns (bytes32) { + function _getItem(ResourceId _tableId, bytes32 valueHash, uint256 _index) internal view returns (bytes32) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -365,7 +375,12 @@ library KeysWithValue { * Get an item of keysWithValue (using the specified store) * (unchecked, returns invalid data if index overflows) */ - function getItem(IStore _store, bytes32 _tableId, bytes32 valueHash, uint256 _index) internal view returns (bytes32) { + function getItem( + IStore _store, + ResourceId _tableId, + bytes32 valueHash, + uint256 _index + ) internal view returns (bytes32) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -376,7 +391,7 @@ library KeysWithValue { } /** Push an element to keysWithValue */ - function pushKeysWithValue(bytes32 _tableId, bytes32 valueHash, bytes32 _element) internal { + function pushKeysWithValue(ResourceId _tableId, bytes32 valueHash, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -384,7 +399,7 @@ library KeysWithValue { } /** Push an element to keysWithValue */ - function _pushKeysWithValue(bytes32 _tableId, bytes32 valueHash, bytes32 _element) internal { + function _pushKeysWithValue(ResourceId _tableId, bytes32 valueHash, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -392,7 +407,7 @@ library KeysWithValue { } /** Push an element to keysWithValue (using the specified store) */ - function pushKeysWithValue(IStore _store, bytes32 _tableId, bytes32 valueHash, bytes32 _element) internal { + function pushKeysWithValue(IStore _store, ResourceId _tableId, bytes32 valueHash, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -400,7 +415,7 @@ library KeysWithValue { } /** Push an element to keysWithValue */ - function push(bytes32 _tableId, bytes32 valueHash, bytes32 _element) internal { + function push(ResourceId _tableId, bytes32 valueHash, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -408,7 +423,7 @@ library KeysWithValue { } /** Push an element to keysWithValue */ - function _push(bytes32 _tableId, bytes32 valueHash, bytes32 _element) internal { + function _push(ResourceId _tableId, bytes32 valueHash, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -416,7 +431,7 @@ library KeysWithValue { } /** Push an element to keysWithValue (using the specified store) */ - function push(IStore _store, bytes32 _tableId, bytes32 valueHash, bytes32 _element) internal { + function push(IStore _store, ResourceId _tableId, bytes32 valueHash, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -424,7 +439,7 @@ library KeysWithValue { } /** Pop an element from keysWithValue */ - function popKeysWithValue(bytes32 _tableId, bytes32 valueHash) internal { + function popKeysWithValue(ResourceId _tableId, bytes32 valueHash) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -432,7 +447,7 @@ library KeysWithValue { } /** Pop an element from keysWithValue */ - function _popKeysWithValue(bytes32 _tableId, bytes32 valueHash) internal { + function _popKeysWithValue(ResourceId _tableId, bytes32 valueHash) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -440,7 +455,7 @@ library KeysWithValue { } /** Pop an element from keysWithValue (using the specified store) */ - function popKeysWithValue(IStore _store, bytes32 _tableId, bytes32 valueHash) internal { + function popKeysWithValue(IStore _store, ResourceId _tableId, bytes32 valueHash) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -448,7 +463,7 @@ library KeysWithValue { } /** Pop an element from keysWithValue */ - function pop(bytes32 _tableId, bytes32 valueHash) internal { + function pop(ResourceId _tableId, bytes32 valueHash) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -456,7 +471,7 @@ library KeysWithValue { } /** Pop an element from keysWithValue */ - function _pop(bytes32 _tableId, bytes32 valueHash) internal { + function _pop(ResourceId _tableId, bytes32 valueHash) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -464,7 +479,7 @@ library KeysWithValue { } /** Pop an element from keysWithValue (using the specified store) */ - function pop(IStore _store, bytes32 _tableId, bytes32 valueHash) internal { + function pop(IStore _store, ResourceId _tableId, bytes32 valueHash) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -475,7 +490,7 @@ library KeysWithValue { * Update an element of keysWithValue at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function updateKeysWithValue(bytes32 _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { + function updateKeysWithValue(ResourceId _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -488,7 +503,7 @@ library KeysWithValue { * Update an element of keysWithValue at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function _updateKeysWithValue(bytes32 _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { + function _updateKeysWithValue(ResourceId _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -503,7 +518,7 @@ library KeysWithValue { */ function updateKeysWithValue( IStore _store, - bytes32 _tableId, + ResourceId _tableId, bytes32 valueHash, uint256 _index, bytes32 _element @@ -520,7 +535,7 @@ library KeysWithValue { * Update an element of keysWithValue at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function update(bytes32 _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { + function update(ResourceId _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -533,7 +548,7 @@ library KeysWithValue { * Update an element of keysWithValue at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function _update(bytes32 _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { + function _update(ResourceId _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -546,7 +561,7 @@ library KeysWithValue { * Update an element of keysWithValue (using the specified store) at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function update(IStore _store, bytes32 _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { + function update(IStore _store, ResourceId _tableId, bytes32 valueHash, uint256 _index, bytes32 _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -586,7 +601,7 @@ library KeysWithValue { } /* Delete all data for given keys */ - function deleteRecord(bytes32 _tableId, bytes32 valueHash) internal { + function deleteRecord(ResourceId _tableId, bytes32 valueHash) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -594,7 +609,7 @@ library KeysWithValue { } /* Delete all data for given keys */ - function _deleteRecord(bytes32 _tableId, bytes32 valueHash) internal { + function _deleteRecord(ResourceId _tableId, bytes32 valueHash) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; @@ -602,7 +617,7 @@ library KeysWithValue { } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 _tableId, bytes32 valueHash) internal { + function deleteRecord(IStore _store, ResourceId _tableId, bytes32 valueHash) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = valueHash; diff --git a/packages/world/src/modules/std-delegations/CallboundDelegationControl.sol b/packages/world/src/modules/std-delegations/CallboundDelegationControl.sol index fbb62081ee..c089ec7d4b 100644 --- a/packages/world/src/modules/std-delegations/CallboundDelegationControl.sol +++ b/packages/world/src/modules/std-delegations/CallboundDelegationControl.sol @@ -2,20 +2,21 @@ pragma solidity >=0.8.0; import { DelegationControl } from "../../DelegationControl.sol"; +import { ResourceId } from "../../WorldResourceId.sol"; import { CallboundDelegations } from "./tables/CallboundDelegations.sol"; contract CallboundDelegationControl is DelegationControl { /** * Verify a delegation by checking if the delegator has any available calls left in the CallboundDelegations table and decrementing the available calls if so. */ - function verify(address delegator, bytes32 resourceSelector, bytes memory callData) public returns (bool) { + function verify(address delegator, ResourceId systemId, bytes memory callData) public returns (bool) { bytes32 callDataHash = keccak256(callData); - // Get the number of available calls for the given delegator, resourceSelector and callData + // Get the number of available calls for the given delegator, systemId and callData uint256 availableCalls = CallboundDelegations.get({ delegator: delegator, delegatee: _msgSender(), - resourceSelector: resourceSelector, + systemId: ResourceId.unwrap(systemId), callDataHash: callDataHash }); @@ -24,7 +25,7 @@ contract CallboundDelegationControl is DelegationControl { CallboundDelegations.deleteRecord({ delegator: delegator, delegatee: _msgSender(), - resourceSelector: resourceSelector, + systemId: ResourceId.unwrap(systemId), callDataHash: callDataHash }); return true; @@ -38,7 +39,7 @@ contract CallboundDelegationControl is DelegationControl { CallboundDelegations.set({ delegator: delegator, delegatee: _msgSender(), - resourceSelector: resourceSelector, + systemId: ResourceId.unwrap(systemId), callDataHash: callDataHash, availableCalls: availableCalls }); @@ -51,11 +52,11 @@ contract CallboundDelegationControl is DelegationControl { /** * Initialize a delegation by setting the number of available calls in the CallboundDelegations table */ - function initDelegation(address delegatee, bytes32 resourceSelector, bytes memory callData, uint256 numCalls) public { + function initDelegation(address delegatee, ResourceId systemId, bytes memory callData, uint256 numCalls) public { CallboundDelegations.set({ delegator: _msgSender(), delegatee: delegatee, - resourceSelector: resourceSelector, + systemId: ResourceId.unwrap(systemId), callDataHash: keccak256(callData), availableCalls: numCalls }); diff --git a/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol b/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol index d1ba02718d..99f341ef3a 100644 --- a/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol +++ b/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol @@ -5,7 +5,6 @@ import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; import { Module } from "../../Module.sol"; import { WorldContextConsumer } from "../../WorldContext.sol"; -import { ResourceSelector } from "../../ResourceSelector.sol"; import { revertWithBytes } from "../../revertWithBytes.sol"; import { CallboundDelegationControl } from "./CallboundDelegationControl.sol"; diff --git a/packages/world/src/modules/std-delegations/TimeboundDelegationControl.sol b/packages/world/src/modules/std-delegations/TimeboundDelegationControl.sol index efeb00663e..e9f9e6114d 100644 --- a/packages/world/src/modules/std-delegations/TimeboundDelegationControl.sol +++ b/packages/world/src/modules/std-delegations/TimeboundDelegationControl.sol @@ -2,14 +2,15 @@ pragma solidity >=0.8.0; import { DelegationControl } from "../../DelegationControl.sol"; +import { ResourceId } from "../../WorldResourceId.sol"; import { TimeboundDelegations } from "./tables/TimeboundDelegations.sol"; contract TimeboundDelegationControl is DelegationControl { /** * Verify a delegation by checking if the current block timestamp is not larger than the max valid timestamp for the delegation. - * Note: the delegation control check ignores the resourceSelector and callData parameters. + * Note: the delegation control check ignores the systemId and callData parameters. */ - function verify(address delegator, bytes32, bytes memory) public view returns (bool) { + function verify(address delegator, ResourceId, bytes memory) public view returns (bool) { // Get the max valid timestamp for the given delegator uint256 maxTimestamp = TimeboundDelegations.get({ delegator: delegator, delegatee: _msgSender() }); diff --git a/packages/world/src/modules/std-delegations/constants.sol b/packages/world/src/modules/std-delegations/constants.sol index dfe282a288..96e65ec00a 100644 --- a/packages/world/src/modules/std-delegations/constants.sol +++ b/packages/world/src/modules/std-delegations/constants.sol @@ -1,12 +1,17 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { ResourceSelector } from "../../ResourceSelector.sol"; +import { ResourceId } from "../../WorldResourceId.sol"; +import { RESOURCE_SYSTEM } from "../../worldResourceTypes.sol"; import { ROOT_NAMESPACE } from "../../constants.sol"; bytes16 constant MODULE_NAME = bytes16("stddelegations.m"); // Callbound delegation -bytes32 constant CALLBOUND_DELEGATION = bytes32(abi.encodePacked(ROOT_NAMESPACE, bytes16("callbound.d"))); +ResourceId constant CALLBOUND_DELEGATION = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_SYSTEM, ROOT_NAMESPACE, bytes16("callbound"))) +); // Timebound delegation -bytes32 constant TIMEBOUND_DELEGATION = bytes32(abi.encodePacked(ROOT_NAMESPACE, bytes16("timebound.d"))); +ResourceId constant TIMEBOUND_DELEGATION = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_SYSTEM, ROOT_NAMESPACE, bytes16("timebound"))) +); diff --git a/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol b/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol index 679c67d270..93c6ef192d 100644 --- a/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol +++ b/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("CallboundDelegat"))); -bytes32 constant CallboundDelegationsTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("CallboundDelegat"))) +); +ResourceId constant CallboundDelegationsTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010020000000000000000000000000000000000000000000000000000000 @@ -55,7 +59,7 @@ library CallboundDelegations { keyNames = new string[](4); keyNames[0] = "delegator"; keyNames[1] = "delegatee"; - keyNames[2] = "resourceSelector"; + keyNames[2] = "systemId"; keyNames[3] = "callDataHash"; } @@ -84,13 +88,13 @@ library CallboundDelegations { function getAvailableCalls( address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash ) internal view returns (uint256 availableCalls) { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -101,13 +105,13 @@ library CallboundDelegations { function _getAvailableCalls( address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash ) internal view returns (uint256 availableCalls) { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -119,13 +123,13 @@ library CallboundDelegations { IStore _store, address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash ) internal view returns (uint256 availableCalls) { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -136,13 +140,13 @@ library CallboundDelegations { function get( address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash ) internal view returns (uint256 availableCalls) { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -153,13 +157,13 @@ library CallboundDelegations { function _get( address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash ) internal view returns (uint256 availableCalls) { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -171,13 +175,13 @@ library CallboundDelegations { IStore _store, address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash ) internal view returns (uint256 availableCalls) { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -188,14 +192,14 @@ library CallboundDelegations { function setAvailableCalls( address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash, uint256 availableCalls ) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((availableCalls)), _fieldLayout); @@ -205,14 +209,14 @@ library CallboundDelegations { function _setAvailableCalls( address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash, uint256 availableCalls ) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((availableCalls)), _fieldLayout); @@ -223,14 +227,14 @@ library CallboundDelegations { IStore _store, address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash, uint256 availableCalls ) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((availableCalls)), _fieldLayout); @@ -240,14 +244,14 @@ library CallboundDelegations { function set( address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash, uint256 availableCalls ) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((availableCalls)), _fieldLayout); @@ -257,14 +261,14 @@ library CallboundDelegations { function _set( address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash, uint256 availableCalls ) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((availableCalls)), _fieldLayout); @@ -275,14 +279,14 @@ library CallboundDelegations { IStore _store, address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash, uint256 availableCalls ) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((availableCalls)), _fieldLayout); @@ -307,40 +311,35 @@ library CallboundDelegations { function encodeKeyTuple( address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash ) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; return _keyTuple; } /* Delete all data for given keys */ - function deleteRecord(address delegator, address delegatee, bytes32 resourceSelector, bytes32 callDataHash) internal { + function deleteRecord(address delegator, address delegatee, bytes32 systemId, bytes32 callDataHash) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord( - address delegator, - address delegatee, - bytes32 resourceSelector, - bytes32 callDataHash - ) internal { + function _deleteRecord(address delegator, address delegatee, bytes32 systemId, bytes32 callDataHash) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); @@ -351,13 +350,13 @@ library CallboundDelegations { IStore _store, address delegator, address delegatee, - bytes32 resourceSelector, + bytes32 systemId, bytes32 callDataHash ) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = resourceSelector; + _keyTuple[2] = systemId; _keyTuple[3] = callDataHash; _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); diff --git a/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol b/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol index 34e0f8ae48..7505e6a7c6 100644 --- a/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol +++ b/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("TimeboundDelegat"))); -bytes32 constant TimeboundDelegationsTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("TimeboundDelegat"))) +); +ResourceId constant TimeboundDelegationsTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010020000000000000000000000000000000000000000000000000000000 diff --git a/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol b/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol index f404c4b50a..1f7cb32045 100644 --- a/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol +++ b/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol @@ -5,12 +5,11 @@ import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; import { Module } from "../../Module.sol"; import { WorldContextConsumer } from "../../WorldContext.sol"; -import { ResourceSelector } from "../../ResourceSelector.sol"; import { UniqueEntity } from "./tables/UniqueEntity.sol"; import { UniqueEntitySystem } from "./UniqueEntitySystem.sol"; -import { NAMESPACE, MODULE_NAME, SYSTEM_NAME, TABLE_NAME } from "./constants.sol"; +import { MODULE_NAME, TABLE_ID, SYSTEM_ID } from "./constants.sol"; /** * This module creates a table that stores a nonce, and @@ -33,12 +32,12 @@ contract UniqueEntityModule is Module { IBaseWorld world = IBaseWorld(_world()); // Register table - UniqueEntity.register(world, ResourceSelector.from(NAMESPACE, TABLE_NAME)); + UniqueEntity.register(world, TABLE_ID); // Register system - world.registerSystem(ResourceSelector.from(NAMESPACE, SYSTEM_NAME), uniqueEntitySystem, true); + world.registerSystem(SYSTEM_ID, uniqueEntitySystem, true); // Register system's functions - world.registerFunctionSelector(ResourceSelector.from(NAMESPACE, SYSTEM_NAME), "getUniqueEntity", "()"); + world.registerFunctionSelector(SYSTEM_ID, "getUniqueEntity", "()"); } } diff --git a/packages/world/src/modules/uniqueentity/UniqueEntitySystem.sol b/packages/world/src/modules/uniqueentity/UniqueEntitySystem.sol index 3ef850f25e..35da06f17d 100644 --- a/packages/world/src/modules/uniqueentity/UniqueEntitySystem.sol +++ b/packages/world/src/modules/uniqueentity/UniqueEntitySystem.sol @@ -2,20 +2,16 @@ pragma solidity >=0.8.0; import { System } from "../../System.sol"; - +import { TABLE_ID } from "./constants.sol"; import { UniqueEntity } from "./tables/UniqueEntity.sol"; -import { NAMESPACE, TABLE_NAME } from "./constants.sol"; -import { ResourceSelector } from "../../ResourceSelector.sol"; - contract UniqueEntitySystem is System { /** * Increment and get an entity nonce. */ function getUniqueEntity() public virtual returns (bytes32) { - bytes32 tableId = ResourceSelector.from(NAMESPACE, TABLE_NAME); - uint256 uniqueEntity = UniqueEntity.get(tableId) + 1; - UniqueEntity.set(tableId, uniqueEntity); + uint256 uniqueEntity = UniqueEntity.get(TABLE_ID) + 1; + UniqueEntity.set(TABLE_ID, uniqueEntity); return bytes32(uniqueEntity); } diff --git a/packages/world/src/modules/uniqueentity/constants.sol b/packages/world/src/modules/uniqueentity/constants.sol index 772f4742e2..d35a2d1b63 100644 --- a/packages/world/src/modules/uniqueentity/constants.sol +++ b/packages/world/src/modules/uniqueentity/constants.sol @@ -1,7 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -bytes16 constant NAMESPACE = bytes16("uniqueEntity"); -bytes16 constant MODULE_NAME = bytes16("uniqueEntity.m"); +import { ResourceId } from "../../WorldResourceId.sol"; +import { RESOURCE_TABLE, RESOURCE_SYSTEM } from "../../worldResourceTypes.sol"; + +bytes14 constant NAMESPACE = bytes14("uniqueEntity"); +bytes16 constant MODULE_NAME = bytes16("uniqueEntity"); bytes16 constant SYSTEM_NAME = bytes16("system"); bytes16 constant TABLE_NAME = bytes16("table"); + +ResourceId constant TABLE_ID = ResourceId.wrap(bytes32(abi.encodePacked(RESOURCE_TABLE, NAMESPACE, TABLE_NAME))); +ResourceId constant SYSTEM_ID = ResourceId.wrap((bytes32(abi.encodePacked(RESOURCE_SYSTEM, NAMESPACE, SYSTEM_NAME)))); diff --git a/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol b/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol index 4c9032669d..2e2982e647 100644 --- a/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol +++ b/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol @@ -17,6 +17,8 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010020000000000000000000000000000000000000000000000000000000 @@ -55,22 +57,22 @@ library UniqueEntity { } /** Register the table with its config */ - function register(bytes32 _tableId) internal { + function register(ResourceId _tableId) internal { StoreSwitch.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config */ - function _register(bytes32 _tableId) internal { + function _register(ResourceId _tableId) internal { StoreCore.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config (using the specified store) */ - function register(IStore _store, bytes32 _tableId) internal { + function register(IStore _store, ResourceId _tableId) internal { _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Get value */ - function getValue(bytes32 _tableId) internal view returns (uint256 value) { + function getValue(ResourceId _tableId) internal view returns (uint256 value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -78,7 +80,7 @@ library UniqueEntity { } /** Get value */ - function _getValue(bytes32 _tableId) internal view returns (uint256 value) { + function _getValue(ResourceId _tableId) internal view returns (uint256 value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -86,7 +88,7 @@ library UniqueEntity { } /** Get value (using the specified store) */ - function getValue(IStore _store, bytes32 _tableId) internal view returns (uint256 value) { + function getValue(IStore _store, ResourceId _tableId) internal view returns (uint256 value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -94,7 +96,7 @@ library UniqueEntity { } /** Get value */ - function get(bytes32 _tableId) internal view returns (uint256 value) { + function get(ResourceId _tableId) internal view returns (uint256 value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -102,7 +104,7 @@ library UniqueEntity { } /** Get value */ - function _get(bytes32 _tableId) internal view returns (uint256 value) { + function _get(ResourceId _tableId) internal view returns (uint256 value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -110,7 +112,7 @@ library UniqueEntity { } /** Get value (using the specified store) */ - function get(IStore _store, bytes32 _tableId) internal view returns (uint256 value) { + function get(IStore _store, ResourceId _tableId) internal view returns (uint256 value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -118,42 +120,42 @@ library UniqueEntity { } /** Set value */ - function setValue(bytes32 _tableId, uint256 value) internal { + function setValue(ResourceId _tableId, uint256 value) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value */ - function _setValue(bytes32 _tableId, uint256 value) internal { + function _setValue(ResourceId _tableId, uint256 value) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value (using the specified store) */ - function setValue(IStore _store, bytes32 _tableId, uint256 value) internal { + function setValue(IStore _store, ResourceId _tableId, uint256 value) internal { bytes32[] memory _keyTuple = new bytes32[](0); _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value */ - function set(bytes32 _tableId, uint256 value) internal { + function set(ResourceId _tableId, uint256 value) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value */ - function _set(bytes32 _tableId, uint256 value) internal { + function _set(ResourceId _tableId, uint256 value) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value (using the specified store) */ - function set(IStore _store, bytes32 _tableId, uint256 value) internal { + function set(IStore _store, ResourceId _tableId, uint256 value) internal { bytes32[] memory _keyTuple = new bytes32[](0); _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); @@ -182,21 +184,21 @@ library UniqueEntity { } /* Delete all data for given keys */ - function deleteRecord(bytes32 _tableId) internal { + function deleteRecord(ResourceId _tableId) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord(bytes32 _tableId) internal { + function _deleteRecord(ResourceId _tableId) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 _tableId) internal { + function deleteRecord(IStore _store, ResourceId _tableId) internal { bytes32[] memory _keyTuple = new bytes32[](0); _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); diff --git a/packages/world/src/modules/utils/getTargetTableSelector.sol b/packages/world/src/modules/utils/getTargetTableSelector.sol deleted file mode 100644 index 84ff1035f0..0000000000 --- a/packages/world/src/modules/utils/getTargetTableSelector.sol +++ /dev/null @@ -1,18 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; -import { ResourceSelector } from "../../ResourceSelector.sol"; - -/** - * Get a deterministic selector for the reverse mapping table for the given source table. - * The selector is constructed as follows: - * - The first 8 bytes are the module namespace - * - The next 8 bytes are the first 8 bytes of the source table namespace - * -- This is to avoid collisions between tables with the same name in different namespaces - * (Note that collisions are still possible if the first 8 bytes of the namespace are the same, in which case installing the module fails) - * - The last 16 bytes are the source table name - */ -function getTargetTableSelector(bytes8 moduleNamespace, bytes32 sourceTableId) pure returns (bytes32) { - bytes16 tableName = ResourceSelector.getName(sourceTableId); - bytes8 sourceTableNamespace = bytes8(bytes32(sourceTableId)); - return bytes32(moduleNamespace) | (bytes32(sourceTableNamespace) >> 64) | (bytes32(tableName) >> 128); -} diff --git a/packages/world/src/tables/Delegations.sol b/packages/world/src/tables/Delegations.sol index 91e5be6c27..f39cb50e68 100644 --- a/packages/world/src/tables/Delegations.sol +++ b/packages/world/src/tables/Delegations.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Delegations"))); -bytes32 constant DelegationsTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Delegations"))) +); +ResourceId constant DelegationsTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010020000000000000000000000000000000000000000000000000000000 diff --git a/packages/world/src/tables/InstalledModules.sol b/packages/world/src/tables/InstalledModules.sol index 7d87929aec..babc79ad42 100644 --- a/packages/world/src/tables/InstalledModules.sol +++ b/packages/world/src/tables/InstalledModules.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("InstalledModules"))); -bytes32 constant InstalledModulesTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("InstalledModules"))) +); +ResourceId constant InstalledModulesTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0014010014000000000000000000000000000000000000000000000000000000 diff --git a/packages/world/src/tables/NamespaceOwner.sol b/packages/world/src/tables/NamespaceOwner.sol index f16a4f1b0c..6b9c4c6a99 100644 --- a/packages/world/src/tables/NamespaceOwner.sol +++ b/packages/world/src/tables/NamespaceOwner.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("NamespaceOwner"))); -bytes32 constant NamespaceOwnerTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("NamespaceOwner"))) +); +ResourceId constant NamespaceOwnerTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0014010014000000000000000000000000000000000000000000000000000000 @@ -34,7 +38,7 @@ library NamespaceOwner { /** Get the table's key schema */ function getKeySchema() internal pure returns (Schema) { SchemaType[] memory _keySchema = new SchemaType[](1); - _keySchema[0] = SchemaType.BYTES16; + _keySchema[0] = SchemaType.BYTES32; return SchemaLib.encode(_keySchema); } @@ -50,7 +54,7 @@ library NamespaceOwner { /** Get the table's key names */ function getKeyNames() internal pure returns (string[] memory keyNames) { keyNames = new string[](1); - keyNames[0] = "namespace"; + keyNames[0] = "namespaceId"; } /** Get the table's field names */ @@ -75,103 +79,103 @@ library NamespaceOwner { } /** Get owner */ - function getOwner(bytes16 namespace) internal view returns (address owner) { + function getOwner(bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner */ - function _getOwner(bytes16 namespace) internal view returns (address owner) { + function _getOwner(bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner (using the specified store) */ - function getOwner(IStore _store, bytes16 namespace) internal view returns (address owner) { + function getOwner(IStore _store, bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner */ - function get(bytes16 namespace) internal view returns (address owner) { + function get(bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner */ - function _get(bytes16 namespace) internal view returns (address owner) { + function _get(bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Get owner (using the specified store) */ - function get(IStore _store, bytes16 namespace) internal view returns (address owner) { + function get(IStore _store, bytes32 namespaceId) internal view returns (address owner) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); return (address(bytes20(_blob))); } /** Set owner */ - function setOwner(bytes16 namespace, address owner) internal { + function setOwner(bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner */ - function _setOwner(bytes16 namespace, address owner) internal { + function _setOwner(bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner (using the specified store) */ - function setOwner(IStore _store, bytes16 namespace, address owner) internal { + function setOwner(IStore _store, bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner */ - function set(bytes16 namespace, address owner) internal { + function set(bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner */ - function _set(bytes16 namespace, address owner) internal { + function _set(bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } /** Set owner (using the specified store) */ - function set(IStore _store, bytes16 namespace, address owner) internal { + function set(IStore _store, bytes32 namespaceId, address owner) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } @@ -192,33 +196,33 @@ library NamespaceOwner { } /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes16 namespace) internal pure returns (bytes32[] memory) { + function encodeKeyTuple(bytes32 namespaceId) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; return _keyTuple; } /* Delete all data for given keys */ - function deleteRecord(bytes16 namespace) internal { + function deleteRecord(bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord(bytes16 namespace) internal { + function _deleteRecord(bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes16 namespace) internal { + function deleteRecord(IStore _store, bytes32 namespaceId) internal { bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(namespace); + _keyTuple[0] = namespaceId; _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } diff --git a/packages/world/src/tables/ResourceAccess.sol b/packages/world/src/tables/ResourceAccess.sol index 8745ef7353..28613dbe6a 100644 --- a/packages/world/src/tables/ResourceAccess.sol +++ b/packages/world/src/tables/ResourceAccess.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("ResourceAccess"))); -bytes32 constant ResourceAccessTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("ResourceAccess"))) +); +ResourceId constant ResourceAccessTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0001010001000000000000000000000000000000000000000000000000000000 @@ -51,7 +55,7 @@ library ResourceAccess { /** Get the table's key names */ function getKeyNames() internal pure returns (string[] memory keyNames) { keyNames = new string[](2); - keyNames[0] = "resourceSelector"; + keyNames[0] = "resourceId"; keyNames[1] = "caller"; } @@ -77,9 +81,9 @@ library ResourceAccess { } /** Get access */ - function getAccess(bytes32 resourceSelector, address caller) internal view returns (bool access) { + function getAccess(bytes32 resourceId, address caller) internal view returns (bool access) { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -87,9 +91,9 @@ library ResourceAccess { } /** Get access */ - function _getAccess(bytes32 resourceSelector, address caller) internal view returns (bool access) { + function _getAccess(bytes32 resourceId, address caller) internal view returns (bool access) { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -97,9 +101,9 @@ library ResourceAccess { } /** Get access (using the specified store) */ - function getAccess(IStore _store, bytes32 resourceSelector, address caller) internal view returns (bool access) { + function getAccess(IStore _store, bytes32 resourceId, address caller) internal view returns (bool access) { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -107,9 +111,9 @@ library ResourceAccess { } /** Get access */ - function get(bytes32 resourceSelector, address caller) internal view returns (bool access) { + function get(bytes32 resourceId, address caller) internal view returns (bool access) { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -117,9 +121,9 @@ library ResourceAccess { } /** Get access */ - function _get(bytes32 resourceSelector, address caller) internal view returns (bool access) { + function _get(bytes32 resourceId, address caller) internal view returns (bool access) { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -127,9 +131,9 @@ library ResourceAccess { } /** Get access (using the specified store) */ - function get(IStore _store, bytes32 resourceSelector, address caller) internal view returns (bool access) { + function get(IStore _store, bytes32 resourceId, address caller) internal view returns (bool access) { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -137,54 +141,54 @@ library ResourceAccess { } /** Set access */ - function setAccess(bytes32 resourceSelector, address caller, bool access) internal { + function setAccess(bytes32 resourceId, address caller, bool access) internal { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((access)), _fieldLayout); } /** Set access */ - function _setAccess(bytes32 resourceSelector, address caller, bool access) internal { + function _setAccess(bytes32 resourceId, address caller, bool access) internal { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((access)), _fieldLayout); } /** Set access (using the specified store) */ - function setAccess(IStore _store, bytes32 resourceSelector, address caller, bool access) internal { + function setAccess(IStore _store, bytes32 resourceId, address caller, bool access) internal { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((access)), _fieldLayout); } /** Set access */ - function set(bytes32 resourceSelector, address caller, bool access) internal { + function set(bytes32 resourceId, address caller, bool access) internal { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((access)), _fieldLayout); } /** Set access */ - function _set(bytes32 resourceSelector, address caller, bool access) internal { + function _set(bytes32 resourceId, address caller, bool access) internal { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((access)), _fieldLayout); } /** Set access (using the specified store) */ - function set(IStore _store, bytes32 resourceSelector, address caller, bool access) internal { + function set(IStore _store, bytes32 resourceId, address caller, bool access) internal { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((access)), _fieldLayout); @@ -206,36 +210,36 @@ library ResourceAccess { } /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes32 resourceSelector, address caller) internal pure returns (bytes32[] memory) { + function encodeKeyTuple(bytes32 resourceId, address caller) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); return _keyTuple; } /* Delete all data for given keys */ - function deleteRecord(bytes32 resourceSelector, address caller) internal { + function deleteRecord(bytes32 resourceId, address caller) internal { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord(bytes32 resourceSelector, address caller) internal { + function _deleteRecord(bytes32 resourceId, address caller) internal { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 resourceSelector, address caller) internal { + function deleteRecord(IStore _store, bytes32 resourceId, address caller) internal { bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceSelector; + _keyTuple[0] = resourceId; _keyTuple[1] = bytes32(uint256(uint160(caller))); _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); diff --git a/packages/world/src/worldResourceTypes.sol b/packages/world/src/worldResourceTypes.sol new file mode 100644 index 0000000000..d7ec187b3a --- /dev/null +++ b/packages/world/src/worldResourceTypes.sol @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; + +bytes2 constant RESOURCE_NAMESPACE = "ns"; +bytes2 constant RESOURCE_MODULE = "md"; +bytes2 constant RESOURCE_SYSTEM = "sy"; + +bytes32 constant MASK_RESOURCE_NAMESPACE = bytes32(RESOURCE_NAMESPACE); +bytes32 constant MASK_RESOURCE_MODULE = bytes32(RESOURCE_MODULE); +bytes32 constant MASK_RESOURCE_SYSTEM = bytes32(RESOURCE_SYSTEM); diff --git a/packages/world/test/AccessControl.t.sol b/packages/world/test/AccessControl.t.sol index feddf64c67..413706328f 100644 --- a/packages/world/test/AccessControl.t.sol +++ b/packages/world/test/AccessControl.t.sol @@ -8,85 +8,95 @@ import { StoreMock } from "@latticexyz/store/test/StoreMock.sol"; import { IWorldErrors } from "../src/interfaces/IWorldErrors.sol"; import { World } from "../src/World.sol"; import { AccessControl } from "../src/AccessControl.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; +import { RESOURCE_TABLE } from "../src/worldResourceTypes.sol"; import { ResourceAccess } from "../src/tables/ResourceAccess.sol"; import { NamespaceOwner } from "../src/tables/NamespaceOwner.sol"; contract AccessControlTest is Test, GasReporter, StoreMock { - bytes16 constant namespace = "namespace"; - bytes16 constant name = "name"; - address constant presetCaller = address(0x0123); - address constant caller = address(0x01); + using WorldResourceIdInstance for ResourceId; + + bytes14 private constant namespace = "namespace"; + bytes16 private constant name = "name"; + address private constant presetCaller = address(0x0123); + address private constant caller = address(0x01); + + ResourceId private _tableId; + ResourceId private _namespaceId; function setUp() public { ResourceAccess.register(); NamespaceOwner.register(); + _tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name }); + _namespaceId = WorldResourceIdLib.encodeNamespace(namespace); NamespaceOwner.set(namespace, address(this)); - ResourceAccess.set(ResourceSelector.from(namespace, name), presetCaller, true); + ResourceAccess.set(ResourceId.unwrap(_tableId), presetCaller, true); } function testAccessControl() public { + ResourceId tableId = _tableId; + ResourceId namespaceId = _namespaceId; bool hasAccess; // Check that the caller has no access to the namespace or name startGasReport("AccessControl: hasAccess (cold)"); - hasAccess = AccessControl.hasAccess(ResourceSelector.from(namespace, name), caller); + hasAccess = AccessControl.hasAccess(tableId, caller); endGasReport(); - assertFalse(hasAccess); + assertFalse(hasAccess, "caller should not have access to the table"); // Grant access to the namespace - ResourceAccess.set(ResourceSelector.from(namespace, 0), caller, true); + ResourceAccess.set(ResourceId.unwrap(namespaceId), caller, true); // Check that the caller has access to the namespace or name startGasReport("AccessControl: hasAccess (warm, namespace only)"); - hasAccess = AccessControl.hasAccess(ResourceSelector.from(namespace, name), caller); + hasAccess = AccessControl.hasAccess(tableId, caller); endGasReport(); - assertTrue(hasAccess); + assertTrue(hasAccess, "caller should have access to the namespace"); // Revoke access to the namespace - ResourceAccess.set(ResourceSelector.from(namespace, 0), caller, false); + ResourceAccess.set(ResourceId.unwrap(namespaceId), caller, false); // Check that the caller has no access to the namespace or name startGasReport("AccessControl: hasAccess (warm)"); - hasAccess = AccessControl.hasAccess(ResourceSelector.from(namespace, name), caller); + hasAccess = AccessControl.hasAccess(tableId, caller); endGasReport(); - assertFalse(hasAccess); + assertFalse(hasAccess, "access to the namespace should have been revoked"); // Grant access to the name - ResourceAccess.set(ResourceSelector.from(namespace, name), caller, true); + ResourceAccess.set(ResourceId.unwrap(tableId), caller, true); // Check that the caller has access to the name - assertTrue(AccessControl.hasAccess(ResourceSelector.from(namespace, name), caller)); + assertTrue(AccessControl.hasAccess(tableId, caller), "access to the table should have been granted"); // Revoke access to the name - ResourceAccess.set(ResourceSelector.from(namespace, name), caller, false); + ResourceAccess.set(ResourceId.unwrap(tableId), caller, false); // Check that the caller has no access to the namespace or name - assertFalse(AccessControl.hasAccess(ResourceSelector.from(namespace, name), caller)); + assertFalse(AccessControl.hasAccess(tableId, caller), "access to the table should have been revoked"); } function testRequireAccess() public { - bytes32 resourceSelector = ResourceSelector.from(namespace, name); + ResourceId tableId = _tableId; + startGasReport("AccessControl: requireAccess (cold)"); - AccessControl.requireAccess(resourceSelector, presetCaller); + AccessControl.requireAccess(tableId, presetCaller); endGasReport(); startGasReport("AccessControl: requireAccess (warm)"); - AccessControl.requireAccess(resourceSelector, presetCaller); + AccessControl.requireAccess(tableId, presetCaller); endGasReport(); startGasReport("AccessControl: requireAccess (this address)"); - AccessControl.requireAccess(resourceSelector, address(this)); + AccessControl.requireAccess(tableId, address(this)); endGasReport(); } function testRequireAccessRevert() public { - bytes32 resourceSelector = ResourceSelector.from(namespace, name); - vm.expectRevert( - abi.encodeWithSelector(IWorldErrors.AccessDenied.selector, ResourceSelector.toString(resourceSelector), caller) - ); - AccessControl.requireAccess(resourceSelector, caller); + ResourceId tableId = _tableId; + + vm.expectRevert(abi.encodeWithSelector(IWorldErrors.AccessDenied.selector, tableId.toString(), caller)); + AccessControl.requireAccess(tableId, caller); } } diff --git a/packages/world/test/Factories.t.sol b/packages/world/test/Factories.t.sol index 5887d42ddb..a943d7a41f 100644 --- a/packages/world/test/Factories.t.sol +++ b/packages/world/test/Factories.t.sol @@ -6,13 +6,14 @@ import { Test, console } from "forge-std/Test.sol"; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { WORLD_VERSION } from "../src/version.sol"; import { World } from "../src/World.sol"; +import { ResourceId } from "../src/WorldResourceId.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { Create2Factory } from "../src/factories/Create2Factory.sol"; import { WorldFactory } from "../src/factories/WorldFactory.sol"; import { IWorldFactory } from "../src/factories/IWorldFactory.sol"; import { InstalledModules } from "../src/tables/InstalledModules.sol"; import { NamespaceOwner } from "../src/tables/NamespaceOwner.sol"; -import { ROOT_NAMESPACE } from "../src/constants.sol"; +import { ROOT_NAMESPACE_ID } from "../src/constants.sol"; contract FactoriesTest is Test { event ContractDeployed(address addr, uint256 salt); @@ -80,6 +81,6 @@ contract FactoriesTest is Test { assertEq(uint256(worldFactory.worldCount()), uint256(1)); // Confirm the msg.sender is owner of the root namespace of the new world - assertEq(NamespaceOwner.get(ROOT_NAMESPACE), address(this)); + assertEq(NamespaceOwner.get(ResourceId.unwrap(ROOT_NAMESPACE_ID)), address(this)); } } diff --git a/packages/world/test/KeysInTableModule.t.sol b/packages/world/test/KeysInTableModule.t.sol index 7789e33740..2c1061b3fb 100644 --- a/packages/world/test/KeysInTableModule.t.sol +++ b/packages/world/test/KeysInTableModule.t.sol @@ -13,8 +13,9 @@ import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol" import { World } from "../src/World.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; import { ROOT_NAMESPACE } from "../src/constants.sol"; +import { RESOURCE_TABLE } from "../src/worldResourceTypes.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { KeysInTableModule } from "../src/modules/keysintable/KeysInTableModule.sol"; @@ -22,11 +23,12 @@ import { getKeysInTable } from "../src/modules/keysintable/getKeysInTable.sol"; import { hasKey } from "../src/modules/keysintable/hasKey.sol"; contract KeysInTableModuleTest is Test, GasReporter { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; + IBaseWorld private world; KeysInTableModule private keysInTableModule = new KeysInTableModule(); // Modules can be deployed once and installed multiple times - bytes16 private namespace = ROOT_NAMESPACE; + bytes14 private namespace = ROOT_NAMESPACE; bytes16 private name = bytes16("source"); bytes16 private singletonName = bytes16("singleton"); bytes16 private compositeName = bytes16("composite"); @@ -42,9 +44,11 @@ contract KeysInTableModuleTest is Test, GasReporter { Schema private tableKeySchema; Schema private singletonKeySchema; Schema private compositeKeySchema; - bytes32 private tableId = ResourceSelector.from(namespace, name); - bytes32 private singletonTableId = ResourceSelector.from(namespace, singletonName); - bytes32 private compositeTableId = ResourceSelector.from(namespace, compositeName); + ResourceId private tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name }); + ResourceId private singletonTableId = + WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: singletonName }); + ResourceId private compositeTableId = + WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: compositeName }); uint256 private val1 = 123; uint256 private val2 = 42; @@ -205,7 +209,11 @@ contract KeysInTableModuleTest is Test, GasReporter { // Install the hook on the second table bytes16 sourceFile2 = bytes16("source2"); - bytes32 sourceTableId2 = ResourceSelector.from(namespace, sourceFile2); + ResourceId sourceTableId2 = WorldResourceIdLib.encode({ + typeId: RESOURCE_TABLE, + namespace: namespace, + name: sourceFile2 + }); world.registerTable( sourceTableId2, tableFieldLayout, diff --git a/packages/world/test/KeysWithValueModule.t.sol b/packages/world/test/KeysWithValueModule.t.sol index fa8e8e83d5..2996090f62 100644 --- a/packages/world/test/KeysWithValueModule.t.sol +++ b/packages/world/test/KeysWithValueModule.t.sol @@ -4,32 +4,36 @@ pragma solidity >=0.8.0; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; +import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; + import { Schema } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; import { SchemaEncodeHelper } from "@latticexyz/store/test/SchemaEncodeHelper.sol"; -import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; - import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; import { FieldLayoutEncodeHelper } from "@latticexyz/store/test/FieldLayoutEncodeHelper.sol"; import { World } from "../src/World.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; +import { WorldResourceIdLib, WorldResourceIdInstance, NAME_BYTES, TYPE_BYTES } from "../src/WorldResourceId.sol"; import { ROOT_NAMESPACE } from "../src/constants.sol"; +import { RESOURCE_TABLE } from "../src/worldResourceTypes.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { KeysWithValueModule } from "../src/modules/keyswithvalue/KeysWithValueModule.sol"; import { MODULE_NAMESPACE } from "../src/modules/keyswithvalue/constants.sol"; import { KeysWithValue } from "../src/modules/keyswithvalue/tables/KeysWithValue.sol"; import { getKeysWithValue } from "../src/modules/keyswithvalue/getKeysWithValue.sol"; -import { getTargetTableSelector } from "../src/modules/utils/getTargetTableSelector.sol"; +import { getTargetTableId, MODULE_NAMESPACE_BYTES, TABLE_NAMESPACE_BYTES, TYPE_BYTES } from "../src/modules/keyswithvalue/getTargetTableId.sol"; contract KeysWithValueModuleTest is Test, GasReporter { - using ResourceSelector for bytes32; + using ResourceIdInstance for ResourceId; + using WorldResourceIdInstance for ResourceId; + IBaseWorld world; KeysWithValueModule private keysWithValueModule = new KeysWithValueModule(); // Modules can be deployed once and installed multiple times - bytes16 private namespace = ROOT_NAMESPACE; + bytes14 private namespace = ROOT_NAMESPACE; bytes16 private sourceName = bytes16("source"); bytes32 private key1 = keccak256("test"); bytes32[] private keyTuple1; @@ -39,8 +43,8 @@ contract KeysWithValueModuleTest is Test, GasReporter { FieldLayout private sourceTableFieldLayout; Schema private sourceTableSchema; Schema private sourceTableKeySchema; - bytes32 private sourceTableId; - bytes32 private targetTableId; + ResourceId private sourceTableId; + ResourceId private targetTableId; function setUp() public { sourceTableFieldLayout = FieldLayoutEncodeHelper.encode(32, 0); @@ -52,8 +56,8 @@ contract KeysWithValueModuleTest is Test, GasReporter { keyTuple1[0] = key1; keyTuple2 = new bytes32[](1); keyTuple2[0] = key2; - sourceTableId = ResourceSelector.from(namespace, sourceName); - targetTableId = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + sourceTableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: sourceName }); + targetTableId = getTargetTableId(MODULE_NAMESPACE, sourceTableId); } function _installKeysWithValueModule() internal { @@ -75,6 +79,10 @@ contract KeysWithValueModuleTest is Test, GasReporter { endGasReport(); } + function testMatchingByteSizes() public { + assertEq(MODULE_NAMESPACE_BYTES + TABLE_NAMESPACE_BYTES + NAME_BYTES + TYPE_BYTES, 32); + } + function testInstall() public { _installKeysWithValueModule(); // Set a value in the source table @@ -217,19 +225,30 @@ contract KeysWithValueModuleTest is Test, GasReporter { assertEq(keysWithValue[0], key1); } - function testGetTargetTableSelector() public { + function testGetTargetTableId() public { startGasReport("compute the target table selector"); - bytes32 targetTableSelector = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + ResourceId _targetTableId = getTargetTableId(MODULE_NAMESPACE, sourceTableId); endGasReport(); - // The first 8 bytes are the module namespace - assertEq(bytes8(targetTableSelector), MODULE_NAMESPACE); + // The first 2 bytes are the resource type + assertEq(_targetTableId.getType(), RESOURCE_TABLE, "target table resource type does not match"); - // followed by the first 4 bytes of the source table namespace - assertEq(bytes8(targetTableSelector << 64), bytes8(namespace)); + // The next 7 bytes are the module namespace + assertEq( + bytes7(ResourceId.unwrap(_targetTableId) << (TYPE_BYTES * 8)), + MODULE_NAMESPACE, + "module namespace does not match" + ); + + // followed by the first 7 bytes of the source table namespace + assertEq( + bytes7(ResourceId.unwrap(_targetTableId) << ((TYPE_BYTES + MODULE_NAMESPACE_BYTES) * 8)), + bytes7(namespace), + "table namespace does not match" + ); // The last 16 bytes are the source name - assertEq(targetTableSelector.getName(), sourceName); + assertEq(_targetTableId.getName(), sourceName, "table name does not match"); } function testGetKeysWithValueGas() public { diff --git a/packages/world/test/StandardDelegationsModule.t.sol b/packages/world/test/StandardDelegationsModule.t.sol index 28006e43c4..5d1dd56e32 100644 --- a/packages/world/test/StandardDelegationsModule.t.sol +++ b/packages/world/test/StandardDelegationsModule.t.sol @@ -5,13 +5,17 @@ import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { World } from "../src/World.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; -import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; import { System } from "../src/System.sol"; +import { RESOURCE_SYSTEM } from "../src/worldResourceTypes.sol"; + +import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; import { IWorldErrors } from "../src/interfaces/IWorldErrors.sol"; import { DELEGATION_CONTROL_INTERFACE_ID } from "../src/interfaces/IDelegationControl.sol"; + import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { Systems } from "../src/modules/core/tables/Systems.sol"; + import { StandardDelegationsModule } from "../src/modules/std-delegations/StandardDelegationsModule.sol"; import { CallboundDelegationControl } from "../src/modules/std-delegations/CallboundDelegationControl.sol"; import { TimeboundDelegationControl } from "../src/modules/std-delegations/TimeboundDelegationControl.sol"; @@ -21,7 +25,8 @@ import { WorldTestSystem } from "./World.t.sol"; contract StandardDelegationsModuleTest is Test, GasReporter { IBaseWorld private world; - bytes32 private systemResourceSelector = ResourceSelector.from("namespace", "testSystem"); + ResourceId private systemId = + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "namespace", name: "testSystem" }); address private delegator = address(1); address private delegatee = address(2); @@ -32,7 +37,7 @@ contract StandardDelegationsModuleTest is Test, GasReporter { // Register a new system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(systemResourceSelector, system, true); + world.registerSystem(systemId, system, true); } function testCallFromCallboundDelegation() public { @@ -44,7 +49,7 @@ contract StandardDelegationsModuleTest is Test, GasReporter { CALLBOUND_DELEGATION, abi.encodeCall( CallboundDelegationControl.initDelegation, - (delegatee, systemResourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ()), 1) + (delegatee, systemId, abi.encodeCall(WorldTestSystem.msgSender, ()), 1) ) ); endGasReport(); @@ -52,11 +57,7 @@ contract StandardDelegationsModuleTest is Test, GasReporter { // Call a system from the delegatee on behalf of the delegator vm.prank(delegatee); startGasReport("call a system via a callbound delegation"); - bytes memory returnData = world.callFrom( - delegator, - systemResourceSelector, - abi.encodeCall(WorldTestSystem.msgSender, ()) - ); + bytes memory returnData = world.callFrom(delegator, systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); endGasReport(); address returnedAddress = abi.decode(returnData, (address)); @@ -66,7 +67,7 @@ contract StandardDelegationsModuleTest is Test, GasReporter { // Expect the delegation to have been used up vm.prank(delegatee); vm.expectRevert(abi.encodeWithSelector(IWorldErrors.DelegationNotFound.selector, delegator, delegatee)); - world.callFrom(delegator, systemResourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ())); + world.callFrom(delegator, systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); } function testCallFromTimeboundDelegation() public { @@ -88,11 +89,7 @@ contract StandardDelegationsModuleTest is Test, GasReporter { // Call a system from the delegatee on behalf of the delegator vm.prank(delegatee); startGasReport("call a system via a timebound delegation"); - bytes memory returnData = world.callFrom( - delegator, - systemResourceSelector, - abi.encodeCall(WorldTestSystem.msgSender, ()) - ); + bytes memory returnData = world.callFrom(delegator, systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); endGasReport(); address returnedAddress = abi.decode(returnData, (address)); @@ -102,19 +99,23 @@ contract StandardDelegationsModuleTest is Test, GasReporter { // Set the timestamp to maxTimestamp and expect the delegation to still be valid vm.warp(maxTimestamp); vm.prank(delegatee); - world.callFrom(delegator, systemResourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ())); + world.callFrom(delegator, systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); // Set the timestamp to maxTimestamp+1 and expect the delegation to be expired vm.warp(maxTimestamp + 1); vm.prank(delegatee); vm.expectRevert(abi.encodeWithSelector(IWorldErrors.DelegationNotFound.selector, delegator, delegatee)); - world.callFrom(delegator, systemResourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ())); + world.callFrom(delegator, systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); } function testRegisterDelegationRevertInterfaceNotSupported() public { // Register a system that is not a delegation control system System noDelegationControlSystem = new System(); - bytes32 noDelegationControlId = ResourceSelector.from("namespace", "noDelegation"); + ResourceId noDelegationControlId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "noDelegation" + }); world.registerSystem(noDelegationControlId, noDelegationControlSystem, true); // Expect the registration to revert if the system does not implement the delegation control interface diff --git a/packages/world/test/UniqueEntityModule.t.sol b/packages/world/test/UniqueEntityModule.t.sol index 22db658279..d9c24f2ec7 100644 --- a/packages/world/test/UniqueEntityModule.t.sol +++ b/packages/world/test/UniqueEntityModule.t.sol @@ -14,14 +14,15 @@ import { UniqueEntity } from "../src/modules/uniqueentity/tables/UniqueEntity.so import { getUniqueEntity } from "../src/modules/uniqueentity/getUniqueEntity.sol"; import { NAMESPACE, TABLE_NAME } from "../src/modules/uniqueentity/constants.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; +import { RESOURCE_TABLE } from "../src/worldResourceTypes.sol"; contract UniqueEntityModuleTest is Test, GasReporter { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; IBaseWorld world; UniqueEntityModule uniqueEntityModule = new UniqueEntityModule(); - bytes32 tableId = ResourceSelector.from(NAMESPACE, TABLE_NAME); + ResourceId _tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: NAMESPACE, name: TABLE_NAME }); function setUp() public { world = IBaseWorld(address(new World())); @@ -29,6 +30,8 @@ contract UniqueEntityModuleTest is Test, GasReporter { } function testInstall() public { + ResourceId tableId = _tableId; + startGasReport("install unique entity module"); world.installModule(uniqueEntityModule, new bytes(0)); endGasReport(); @@ -45,6 +48,8 @@ contract UniqueEntityModuleTest is Test, GasReporter { } function testInstallRoot() public { + ResourceId tableId = _tableId; + startGasReport("installRoot unique entity module"); world.installRootModule(uniqueEntityModule, new bytes(0)); endGasReport(); @@ -61,6 +66,8 @@ contract UniqueEntityModuleTest is Test, GasReporter { } function testPublicAccess() public { + ResourceId tableId = _tableId; + world.installModule(uniqueEntityModule, new bytes(0)); // Anyone should be able to call `getUniqueEntity` @@ -78,7 +85,7 @@ contract UniqueEntityModuleTest is Test, GasReporter { vm.expectRevert( abi.encodeWithSelector( IWorldErrors.AccessDenied.selector, - ResourceSelector.from(NAMESPACE, TABLE_NAME).toString(), + WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: NAMESPACE, name: TABLE_NAME }).toString(), alice ) ); diff --git a/packages/world/test/Utils.t.sol b/packages/world/test/Utils.t.sol index d3def80af0..98b7752ea3 100644 --- a/packages/world/test/Utils.t.sol +++ b/packages/world/test/Utils.t.sol @@ -7,7 +7,8 @@ import { Utils } from "../src/Utils.sol"; import { System } from "../src/System.sol"; import { World } from "../src/World.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; +import { RESOURCE_SYSTEM } from "../src/worldResourceTypes.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; @@ -18,7 +19,7 @@ contract UtilsTestSystem is System { } contract UtilsTest is Test { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; IBaseWorld internal world; error SomeError(uint256 someValue, string someString); @@ -28,20 +29,19 @@ contract UtilsTest is Test { world.initialize(new CoreModule()); } - function _registerAndGetNamespace(bytes16 namespace) internal returns (bytes16 returnedNamespace) { + function _registerAndGetNamespace(bytes14 namespace) internal returns (bytes16 returnedNamespace) { UtilsTestSystem testSystem = new UtilsTestSystem(); bytes16 name = "testSystem"; - world.registerSystem(ResourceSelector.from(namespace, name), testSystem, true); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); + world.registerSystem(systemId, testSystem, true); + + bytes memory data = world.call(systemId, abi.encodeCall(UtilsTestSystem.systemNamespace, ())); - bytes memory data = world.call( - ResourceSelector.from(namespace, name), - abi.encodeCall(UtilsTestSystem.systemNamespace, ()) - ); returnedNamespace = abi.decode(data, (bytes16)); } function testSystemNamespace() public { - bytes16 namespace; + bytes14 namespace; bytes16 returnedNamespace; namespace = ""; @@ -52,7 +52,7 @@ contract UtilsTest is Test { returnedNamespace = _registerAndGetNamespace(namespace); assertEq(returnedNamespace, namespace); - namespace = "maxlen_namespace"; + namespace = "max_len_nmspce"; returnedNamespace = _registerAndGetNamespace(namespace); assertEq(returnedNamespace, namespace); } diff --git a/packages/world/test/World.t.sol b/packages/world/test/World.t.sol index 9194959b2d..3b242852bc 100644 --- a/packages/world/test/World.t.sol +++ b/packages/world/test/World.t.sol @@ -8,13 +8,14 @@ import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol" import { IStoreHook, STORE_HOOK_INTERFACE_ID } from "@latticexyz/store/src/IStoreHook.sol"; import { StoreCore, StoreCoreInternal } from "@latticexyz/store/src/StoreCore.sol"; +import { IStoreErrors } from "@latticexyz/store/src/IStore.sol"; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { FieldLayoutEncodeHelper } from "@latticexyz/store/test/FieldLayoutEncodeHelper.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { SchemaEncodeHelper } from "@latticexyz/store/test/SchemaEncodeHelper.sol"; -import { Tables, TablesTableId } from "@latticexyz/store/src/codegen/index.sol"; +import { Tables, ResourceIds, TablesTableId } from "@latticexyz/store/src/codegen/index.sol"; import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { ALL, BEFORE_SET_RECORD, AFTER_SET_RECORD, BEFORE_SPLICE_STATIC_DATA, AFTER_SPLICE_STATIC_DATA, BEFORE_SPLICE_DYNAMIC_DATA, AFTER_SPLICE_DYNAMIC_DATA, BEFORE_DELETE_RECORD, AFTER_DELETE_RECORD } from "@latticexyz/store/src/storeHookTypes.sol"; import { RevertSubscriber } from "@latticexyz/store/test/RevertSubscriber.sol"; @@ -23,9 +24,9 @@ import { EchoSubscriber } from "@latticexyz/store/test/EchoSubscriber.sol"; import { WORLD_VERSION } from "../src/version.sol"; import { World } from "../src/World.sol"; import { System } from "../src/System.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; -import { ROOT_NAMESPACE, ROOT_NAME, UNLIMITED_DELEGATION } from "../src/constants.sol"; -import { Resource } from "../src/common.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; +import { ROOT_NAMESPACE, ROOT_NAME, ROOT_NAMESPACE_ID, UNLIMITED_DELEGATION } from "../src/constants.sol"; +import { RESOURCE_TABLE, RESOURCE_SYSTEM, RESOURCE_NAMESPACE } from "../src/worldResourceTypes.sol"; import { WorldContextProvider, WORLD_CONTEXT_CONSUMER_INTERFACE_ID } from "../src/WorldContext.sol"; import { SystemHook } from "../src/SystemHook.sol"; import { BEFORE_CALL_SYSTEM, AFTER_CALL_SYSTEM } from "../src/systemHookTypes.sol"; @@ -37,7 +38,6 @@ import { ResourceAccess } from "../src/tables/ResourceAccess.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { Systems } from "../src/modules/core/tables/Systems.sol"; import { SystemRegistry } from "../src/modules/core/tables/SystemRegistry.sol"; -import { ResourceType } from "../src/modules/core/tables/ResourceType.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; import { IWorldErrors } from "../src/interfaces/IWorldErrors.sol"; @@ -88,9 +88,9 @@ contract WorldTestSystem is System { return returndata; } - function writeData(bytes16 namespace, bytes16 name, bool data) public { + function writeData(bytes14 namespace, bytes16 name, bool data) public { bytes32[] memory keyTuple = new bytes32[](0); - bytes32 tableId = ResourceSelector.from(namespace, name); + ResourceId tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name }); FieldLayout fieldLayout = StoreSwitch.getFieldLayout(tableId); if (StoreSwitch.getStoreAddress() == address(this)) { @@ -136,29 +136,29 @@ contract PayableFallbackSystem is System { contract EchoSystemHook is SystemHook { event SystemHookCalled(bytes data); - function onBeforeCallSystem(address msgSender, bytes32 resourceSelector, bytes memory callData) public { - emit SystemHookCalled(abi.encode("before", msgSender, resourceSelector, callData)); + function onBeforeCallSystem(address msgSender, ResourceId systemId, bytes memory callData) public { + emit SystemHookCalled(abi.encode("before", msgSender, systemId, callData)); } - function onAfterCallSystem(address msgSender, bytes32 resourceSelector, bytes memory callData) public { - emit SystemHookCalled(abi.encode("after", msgSender, resourceSelector, callData)); + function onAfterCallSystem(address msgSender, ResourceId systemId, bytes memory callData) public { + emit SystemHookCalled(abi.encode("after", msgSender, systemId, callData)); } } contract RevertSystemHook is SystemHook { event SystemHookCalled(bytes data); - function onBeforeCallSystem(address, bytes32, bytes memory) public pure { + function onBeforeCallSystem(address, ResourceId, bytes memory) public pure { revert("onBeforeCallSystem"); } - function onAfterCallSystem(address, bytes32, bytes memory) public pure { + function onAfterCallSystem(address, ResourceId, bytes memory) public pure { revert("onAfterCallSystem"); } } contract WorldTest is Test, GasReporter { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; event HelloWorld(bytes32 indexed worldVersion); event HookCalled(bytes data); @@ -183,12 +183,12 @@ contract WorldTest is Test, GasReporter { } // Expect an error when trying to write from an address that doesn't have access - function _expectAccessDenied(address caller, bytes16 namespace, bytes16 name) internal { + function _expectAccessDenied(address caller, bytes14 namespace, bytes16 name, bytes2 resourceType) internal { vm.prank(caller); vm.expectRevert( abi.encodeWithSelector( IWorldErrors.AccessDenied.selector, - ResourceSelector.from(namespace, name).toString(), + WorldResourceIdLib.encode({ typeId: resourceType, namespace: namespace, name: name }).toString(), caller ) ); @@ -209,7 +209,7 @@ contract WorldTest is Test, GasReporter { vm.expectRevert( abi.encodeWithSelector( IWorldErrors.AccessDenied.selector, - ResourceSelector.from(ROOT_NAMESPACE).toString(), + WorldResourceIdLib.encodeNamespace(ROOT_NAMESPACE).toString(), address(0x4242) ) ); @@ -219,18 +219,30 @@ contract WorldTest is Test, GasReporter { newWorld.initialize(coreModule); // Should have registered the table data table (fka schema table) - assertEq(Tables.getFieldLayout(newWorld, TablesTableId), FieldLayout.unwrap(Tables.getFieldLayout())); - assertEq(Tables.getAbiEncodedKeyNames(newWorld, TablesTableId), abi.encode(Tables.getKeyNames())); - assertEq(Tables.getAbiEncodedFieldNames(newWorld, TablesTableId), abi.encode(Tables.getFieldNames())); + assertEq( + Tables.getFieldLayout(newWorld, ResourceId.unwrap(TablesTableId)), + FieldLayout.unwrap(Tables.getFieldLayout()) + ); + assertEq( + Tables.getAbiEncodedKeyNames(newWorld, ResourceId.unwrap(TablesTableId)), + abi.encode(Tables.getKeyNames()) + ); + assertEq( + Tables.getAbiEncodedFieldNames(newWorld, ResourceId.unwrap(TablesTableId)), + abi.encode(Tables.getFieldNames()) + ); // Should have registered the namespace owner table assertEq( - Tables.getFieldLayout(newWorld, NamespaceOwnerTableId), + Tables.getFieldLayout(newWorld, ResourceId.unwrap(NamespaceOwnerTableId)), FieldLayout.unwrap(NamespaceOwner.getFieldLayout()) ); - assertEq(Tables.getAbiEncodedKeyNames(newWorld, NamespaceOwnerTableId), abi.encode(NamespaceOwner.getKeyNames())); assertEq( - Tables.getAbiEncodedFieldNames(newWorld, NamespaceOwnerTableId), + Tables.getAbiEncodedKeyNames(newWorld, ResourceId.unwrap(NamespaceOwnerTableId)), + abi.encode(NamespaceOwner.getKeyNames()) + ); + assertEq( + Tables.getAbiEncodedFieldNames(newWorld, ResourceId.unwrap(NamespaceOwnerTableId)), abi.encode(NamespaceOwner.getFieldNames()) ); @@ -263,80 +275,135 @@ contract WorldTest is Test, GasReporter { function testRootNamespace() public { // Owner of root route should be the creator of the World - address rootOwner = NamespaceOwner.get(world, ROOT_NAMESPACE); + address rootOwner = NamespaceOwner.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)); assertEq(rootOwner, address(this)); // The creator of the World should have access to the root namespace - assertTrue(ResourceAccess.get(world, ROOT_NAMESPACE, address(this))); + assertTrue(ResourceAccess.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID), address(this))); } function testStoreAddress() public { // Register a system and use it to get storeAddress WorldTestSystem system = new WorldTestSystem(); - bytes32 resourceSelector = ResourceSelector.from("namespace", "testSystem"); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSystem" + }); - world.registerSystem(resourceSelector, system, false); - bytes memory result = world.call(resourceSelector, abi.encodeCall(WorldTestSystem.getStoreAddress, ())); + world.registerSystem(systemId, system, false); + bytes memory result = world.call(systemId, abi.encodeCall(WorldTestSystem.getStoreAddress, ())); assertEq(abi.decode(result, (address)), address(world)); } function testRegisterNamespace() public { + bytes14 namespace = "testNamespace"; + ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); startGasReport("Register a new namespace"); - world.registerNamespace("test"); + world.registerNamespace(namespaceId); endGasReport(); // Expect the caller to be the namespace owner - assertEq(NamespaceOwner.get(world, "test"), address(this), "caller should be namespace owner"); + assertEq( + NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)), + address(this), + "caller should be namespace owner" + ); // Expect the caller to have access - assertEq(ResourceAccess.get(world, "test", address(this)), true, "caller should have access"); + assertEq( + ResourceAccess.get(world, ResourceId.unwrap(namespaceId), address(this)), + true, + "caller should have access" + ); + + // Expect the resource ID to have been registered + assertTrue(ResourceIds.getExists(world, ResourceId.unwrap(namespaceId))); // Expect an error when registering an existing namespace + vm.expectRevert(abi.encodeWithSelector(IWorldErrors.ResourceExists.selector, namespaceId, namespaceId.toString())); + world.registerNamespace(namespaceId); + } + + function testRegisterNamespaceRevertInvalidType() public { + ResourceId invalidNamespaceId = WorldResourceIdLib.encode({ + typeId: RESOURCE_TABLE, + namespace: "namespace", + name: "name" + }); + + // Expect an error when trying to register a namespace with an invalid type vm.expectRevert( - abi.encodeWithSelector(IWorldErrors.ResourceExists.selector, ResourceSelector.toString(bytes16("test"))) + abi.encodeWithSelector( + IWorldErrors.InvalidResourceType.selector, + RESOURCE_NAMESPACE, + invalidNamespaceId, + invalidNamespaceId.toString() + ) ); - world.registerNamespace("test"); + world.registerNamespace(invalidNamespaceId); } function testTransferNamespace() public { - world.registerNamespace("testTransfer"); + bytes14 namespace = "testTransfer"; + ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); + + world.registerNamespace(namespaceId); // Expect the new owner to not be namespace owner before transfer assertFalse( - (NamespaceOwner.get(world, "testTransfer") == address(1)), + (NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)) == address(1)), "new owner should not be namespace owner before transfer" ); // Expect the new owner to not have access before transfer assertEq( - ResourceAccess.get(world, "testTransfer", address(1)), + ResourceAccess.get(world, ResourceId.unwrap(namespaceId), address(1)), false, "new owner should not have access before transfer" ); - world.transferOwnership("testTransfer", address(1)); + world.transferOwnership(namespaceId, address(1)); + // Expect the new owner to be namespace owner - assertEq(NamespaceOwner.get(world, "testTransfer"), address(1), "new owner should be namespace owner"); + assertEq( + NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)), + address(1), + "new owner should be namespace owner" + ); + // Expect the new owner to have access - assertEq(ResourceAccess.get(world, "testTransfer", address(1)), true, "new owner should have access"); + assertEq( + ResourceAccess.get(world, ResourceId.unwrap(namespaceId), address(1)), + true, + "new owner should have access" + ); + // Expect previous owner to no longer be owner assertFalse( - (NamespaceOwner.get(world, "testTransfer") == address(this)), + (NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)) == address(this)), "caller should no longer be namespace owner" ); + // Expect previous owner to no longer have access - assertEq(ResourceAccess.get(world, "testTransfer", address(this)), false, "caller should no longer have access"); + assertEq( + ResourceAccess.get(world, ResourceId.unwrap(namespaceId), address(this)), + false, + "caller should no longer have access" + ); + // Expect revert if caller is not the owner - _expectAccessDenied(address(this), "testTransfer", 0); - world.transferOwnership("testTransfer", address(1)); + _expectAccessDenied(address(this), namespace, 0, RESOURCE_NAMESPACE); + world.transferOwnership(namespaceId, address(1)); } function testRegisterTable() public { FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(1, 32, 1); Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.BOOL, SchemaType.UINT256, SchemaType.STRING); - bytes16 namespace = "testNamespace"; + bytes14 namespace = "testNamespace"; bytes16 tableName = "testTable"; - bytes32 tableSelector = ResourceSelector.from(namespace, tableName); + ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); + ResourceId tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: tableName }); string[] memory keyNames = new string[](1); keyNames[0] = "key1"; string[] memory fieldNames = new string[](3); @@ -345,79 +412,113 @@ contract WorldTest is Test, GasReporter { fieldNames[2] = "value3"; startGasReport("Register a new table in the namespace"); - world.registerTable(tableSelector, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); + world.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); endGasReport(); // Expect the namespace to be created and owned by the caller - assertEq(NamespaceOwner.get(world, namespace), address(this), "namespace should be created by caller"); + assertEq( + NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)), + address(this), + "namespace should be created by caller" + ); // Expect the table to be registered - assertEq(world.getFieldLayout(tableSelector).unwrap(), fieldLayout.unwrap(), "value schema should be registered"); + assertEq(world.getFieldLayout(tableId).unwrap(), fieldLayout.unwrap(), "value schema should be registered"); - bytes memory loadedKeyNames = Tables.getAbiEncodedKeyNames(world, tableSelector); + bytes memory loadedKeyNames = Tables.getAbiEncodedKeyNames(world, ResourceId.unwrap(tableId)); assertEq(loadedKeyNames, abi.encode(keyNames), "key names should be registered"); - bytes memory loadedfieldNames = Tables.getAbiEncodedFieldNames(world, tableSelector); + bytes memory loadedfieldNames = Tables.getAbiEncodedFieldNames(world, ResourceId.unwrap(tableId)); assertEq(loadedfieldNames, abi.encode(fieldNames), "value names should be registered"); // Expect an error when registering an existing table - vm.expectRevert(abi.encodeWithSelector(IWorldErrors.ResourceExists.selector, tableSelector.toString())); - world.registerTable(tableSelector, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); + vm.expectRevert( + abi.encodeWithSelector( + IStoreErrors.StoreCore_TableAlreadyExists.selector, + tableId, + string(bytes.concat(ResourceId.unwrap(tableId))) + ) + ); + world.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); // Expect an error when registering a table in a namespace that is not owned by the caller - bytes32 otherTableSelector = ResourceSelector.from(namespace, "otherTable"); - _expectAccessDenied(address(0x01), namespace, ""); - world.registerTable(otherTableSelector, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); + ResourceId otherTableId = WorldResourceIdLib.encode({ + typeId: RESOURCE_TABLE, + namespace: namespace, + name: "otherTable" + }); + _expectAccessDenied(address(0x01), namespace, "", RESOURCE_NAMESPACE); + world.registerTable(otherTableId, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); // Expect the World to not be allowed to call registerTable via an external call - _expectAccessDenied(address(world), namespace, ""); - world.registerTable(otherTableSelector, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); + _expectAccessDenied(address(world), namespace, "", RESOURCE_NAMESPACE); + world.registerTable(otherTableId, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); } function testRegisterSystem() public { System system = new System(); - bytes16 namespace = ""; + bytes14 namespace = ""; + ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); bytes16 name = "testSystem"; - bytes32 resourceSelector = ResourceSelector.from(namespace, name); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); - // !gasrepot Register a new system - world.registerSystem(resourceSelector, system, false); + startGasReport("register a system"); + world.registerSystem(systemId, system, false); + endGasReport(); // Expect the system to be registered - (address registeredAddress, bool publicAccess) = Systems.get(world, resourceSelector); + (address registeredAddress, bool publicAccess) = Systems.get(world, ResourceId.unwrap(systemId)); assertEq(registeredAddress, address(system)); + // Expect the system's resource ID to have been registered + assertTrue(ResourceIds.getExists(world, ResourceId.unwrap(systemId))); + // Expect the system namespace to be owned by the caller - address routeOwner = NamespaceOwner.get(world, ""); + address routeOwner = NamespaceOwner.get(world, ResourceId.unwrap(namespaceId)); assertEq(routeOwner, address(this)); // Expect the system to not be publicly accessible assertFalse(publicAccess); // Expect the system to be accessible by the caller - assertTrue(ResourceAccess.get({ _store: world, resourceSelector: "", caller: address(this) })); + assertTrue( + ResourceAccess.get({ _store: world, resourceId: ResourceId.unwrap(namespaceId), caller: address(this) }) + ); // Expect the system to not be accessible by another address - assertFalse(ResourceAccess.get({ _store: world, resourceSelector: "", caller: address(0x1) })); + assertFalse( + ResourceAccess.get({ _store: world, resourceId: ResourceId.unwrap(namespaceId), caller: address(0x1) }) + ); // Expect the system to have access to its own namespace - assertTrue(ResourceAccess.get({ _store: world, resourceSelector: "", caller: address(system) })); + assertTrue( + ResourceAccess.get({ _store: world, resourceId: ResourceId.unwrap(namespaceId), caller: address(system) }) + ); + ResourceId newNamespaceId = WorldResourceIdLib.encodeNamespace("newNamespace"); // Expect the namespace to be created if it doesn't exist yet - assertEq(NamespaceOwner.get(world, "newNamespace"), address(0)); - world.registerSystem(ResourceSelector.from("newNamespace", "testSystem"), new System(), false); - assertEq(NamespaceOwner.get(world, "newNamespace"), address(this)); + assertEq(NamespaceOwner.get(world, ResourceId.unwrap(newNamespaceId)), address(0)); + world.registerSystem( + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "newNamespace", name: "testSystem" }), + new System(), + false + ); + assertEq(NamespaceOwner.get(world, ResourceId.unwrap(newNamespaceId)), address(this)); - // Expect an error when registering an existing system at a new resource selector + // Expect an error when registering an existing system at a new system ID vm.expectRevert(abi.encodeWithSelector(IWorldErrors.SystemExists.selector, address(system))); - world.registerSystem(ResourceSelector.from("", "newSystem"), system, true); + world.registerSystem( + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "", name: "newSystem" }), + system, + true + ); // Don't expect an error when updating the public access of an existing system - world.registerSystem(resourceSelector, system, true); + world.registerSystem(systemId, system, true); - // Expect an error when registering a system at an existing resource selector of a different type + // Expect an error when registering a system at an existing resource ID of a different type System newSystem = new System(); - bytes32 tableId = ResourceSelector.from("", "testTable"); + ResourceId tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: "", name: "testTable" }); world.registerTable( tableId, Bool.getFieldLayout(), @@ -426,17 +527,27 @@ contract WorldTest is Test, GasReporter { new string[](1), new string[](1) ); - vm.expectRevert(abi.encodeWithSelector(IWorldErrors.ResourceExists.selector, tableId.toString())); + vm.expectRevert( + abi.encodeWithSelector(IWorldErrors.InvalidResourceType.selector, RESOURCE_SYSTEM, tableId, tableId.toString()) + ); world.registerSystem(tableId, newSystem, true); - // Expect an error when registering a system in a namespace is not owned by the caller + // Expect an error when registering a system in a namespace that is not owned by the caller System yetAnotherSystem = new System(); - _expectAccessDenied(address(0x01), "", ""); - world.registerSystem(ResourceSelector.from("", "rootSystem"), yetAnotherSystem, true); + _expectAccessDenied(address(0x01), "", "", RESOURCE_NAMESPACE); + world.registerSystem( + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "", name: "rootSystem" }), + yetAnotherSystem, + true + ); // Expect the registration to fail when coming from the World (since the World address doesn't have access) - _expectAccessDenied(address(world), "", ""); - world.registerSystem(ResourceSelector.from("", "rootSystem"), yetAnotherSystem, true); + _expectAccessDenied(address(world), "", "", RESOURCE_NAMESPACE); + world.registerSystem( + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "", name: "rootSystem" }), + yetAnotherSystem, + true + ); // Expect the registration to fail if the provided address does not implement the WorldContextConsumer interface vm.expectRevert( @@ -446,13 +557,22 @@ contract WorldTest is Test, GasReporter { WORLD_CONTEXT_CONSUMER_INTERFACE_ID ) ); - world.registerSystem(ResourceSelector.from("someNamespace", "invalidSystem"), System(address(world)), true); + world.registerSystem( + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "someNamespace", name: "invalidSystem" }), + System(address(world)), + true + ); } function testUpgradeSystem() public { - bytes16 namespace = "testNamespace"; + bytes14 namespace = "testNamespace"; + ResourceId namespaceId = WorldResourceIdLib.encodeNamespace(namespace); bytes16 systemName = "testSystem"; - bytes32 systemId = ResourceSelector.from(namespace, systemName); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: namespace, + name: systemName + }); // Register a system System oldSystem = new System(); @@ -463,33 +583,39 @@ contract WorldTest is Test, GasReporter { world.registerSystem(systemId, newSystem, false); // Expect the system address and public access to be updated in the System table - (address registeredAddress, bool publicAccess) = Systems.get(world, systemId); - assertEq(registeredAddress, address(newSystem)); - assertEq(publicAccess, false); + (address registeredAddress, bool publicAccess) = Systems.get(world, ResourceId.unwrap(systemId)); + assertEq(registeredAddress, address(newSystem), "system address should be updated"); + assertEq(publicAccess, false, "public access should be updated"); // Expect the SystemRegistry table to not have a reference to the old system anymore bytes32 registeredSystemId = SystemRegistry.get(world, address(oldSystem)); - assertEq(registeredSystemId, bytes32(0)); + assertEq(registeredSystemId, bytes32(0), "old system should be removed from SystemRegistry"); // Expect the SystemRegistry table to have a reference to the new system registeredSystemId = SystemRegistry.get(world, address(newSystem)); - assertEq(registeredSystemId, systemId); + assertEq(registeredSystemId, ResourceId.unwrap(systemId), "new system should be added to SystemRegistry"); // Expect the old system to not have access to the namespace anymore - assertFalse(ResourceAccess.get(world, namespace, address(oldSystem))); + assertFalse( + ResourceAccess.get(world, ResourceId.unwrap(namespaceId), address(oldSystem)), + "old system should not have access to the namespace" + ); // Expect the new system to have access to the namespace - assertTrue(ResourceAccess.get(world, namespace, address(newSystem))); + assertTrue( + ResourceAccess.get(world, ResourceId.unwrap(namespaceId), address(newSystem)), + "new system should have access to the namespace" + ); - // Expect the resource type to still be SYSTEM - assertEq(uint8(ResourceType.get(world, systemId)), uint8(Resource.SYSTEM)); + // Expect the resource ID to still be registered + assertTrue(ResourceIds.getExists(world, ResourceId.unwrap(systemId)), "resource type should still be SYSTEM"); } - function testDuplicateSelectors() public { + function testInvalidIds() public { // Register a new table - bytes32 resourceSelector = ResourceSelector.from("namespace", "name"); + ResourceId tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: "namespace", name: "name" }); world.registerTable( - resourceSelector, + tableId, Bool.getFieldLayout(), defaultKeySchema, Bool.getValueSchema(), @@ -500,18 +626,44 @@ contract WorldTest is Test, GasReporter { // Deploy a new system System system = new System(); - // Expect an error when trying to register a system at the same selector - vm.expectRevert(abi.encodeWithSelector(IWorldErrors.ResourceExists.selector, resourceSelector.toString())); - world.registerSystem(resourceSelector, system, false); + // Expect an error when trying to register a system at the same ID + vm.expectRevert( + abi.encodeWithSelector(IWorldErrors.InvalidResourceType.selector, RESOURCE_SYSTEM, tableId, tableId.toString()) + ); + world.registerSystem(tableId, system, false); // Register a new system - bytes32 resourceSelector2 = ResourceSelector.from("namespace2", "name"); - world.registerSystem(resourceSelector2, new System(), false); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "namespace2", name: "name" }); + world.registerSystem(systemId, new System(), false); + + // Expect an error when trying to register a table at the same ID + vm.expectRevert( + abi.encodeWithSelector( + IStoreErrors.StoreCore_InvalidResourceType.selector, + RESOURCE_TABLE, + systemId, + string(abi.encodePacked(systemId)) + ) + ); + world.registerTable( + systemId, + Bool.getFieldLayout(), + defaultKeySchema, + Bool.getValueSchema(), + new string[](1), + new string[](1) + ); - // Expect an error when trying to register a table at the same selector - vm.expectRevert(abi.encodeWithSelector(IWorldErrors.ResourceExists.selector, resourceSelector2.toString())); + // Expect an error when trying to register a new table at an existing table ID + vm.expectRevert( + abi.encodeWithSelector( + IStoreErrors.StoreCore_TableAlreadyExists.selector, + ResourceId.unwrap(tableId), + string(bytes.concat(ResourceId.unwrap(tableId))) + ) + ); world.registerTable( - resourceSelector2, + tableId, Bool.getFieldLayout(), defaultKeySchema, Bool.getValueSchema(), @@ -529,7 +681,11 @@ contract WorldTest is Test, GasReporter { } function testSetRecord() public { - bytes32 tableId = ResourceSelector.from("testSetRecord", "testTable"); + ResourceId tableId = WorldResourceIdLib.encode({ + typeId: RESOURCE_TABLE, + namespace: "testSetRecord", + name: "testTable" + }); // Register a new table world.registerTable( tableId, @@ -548,7 +704,7 @@ contract WorldTest is Test, GasReporter { assertTrue(Bool.get(world, tableId)); // Expect an error when trying to write from an address that doesn't have access - _expectAccessDenied(address(0x01), "testSetRecord", "testTable"); + _expectAccessDenied(address(0x01), "testSetRecord", "testTable", RESOURCE_TABLE); Bool.set(world, tableId, true); // Expect the World to have access @@ -557,9 +713,9 @@ contract WorldTest is Test, GasReporter { } function testSetField() public { - bytes16 namespace = "testSetField"; + bytes14 namespace = "testSetField"; bytes16 name = "testTable"; - bytes32 tableId = ResourceSelector.from(namespace, name); + ResourceId tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name }); FieldLayout fieldLayout = Bool.getFieldLayout(); Schema valueSchema = Bool.getValueSchema(); @@ -574,7 +730,7 @@ contract WorldTest is Test, GasReporter { assertTrue(Bool.get(world, tableId)); // Expect an error when trying to write from an address that doesn't have access - _expectAccessDenied(address(0x01), "testSetField", "testTable"); + _expectAccessDenied(address(0x01), "testSetField", "testTable", RESOURCE_TABLE); world.setField(tableId, singletonKey, 0, abi.encodePacked(true), fieldLayout); // Expect the World to have access @@ -583,9 +739,9 @@ contract WorldTest is Test, GasReporter { } function testPushToField() public { - bytes16 namespace = "testPushToField"; + bytes14 namespace = "testPushField"; bytes16 name = "testTable"; - bytes32 tableId = ResourceSelector.from(namespace, name); + ResourceId tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name }); FieldLayout fieldLayout = AddressArray.getFieldLayout(); Schema valueSchema = AddressArray.getValueSchema(); @@ -616,7 +772,7 @@ contract WorldTest is Test, GasReporter { assertEq(AddressArray.get(world, tableId, key), dataToPush); // Expect an error when trying to write from an address that doesn't have access - _expectAccessDenied(address(0x01), namespace, name); + _expectAccessDenied(address(0x01), namespace, name, RESOURCE_TABLE); world.pushToField(tableId, keyTuple, 0, encodedData, fieldLayout); // Expect the World to have access @@ -625,9 +781,9 @@ contract WorldTest is Test, GasReporter { } function testDeleteRecord() public { - bytes16 namespace = "testDeleteRecord"; + bytes14 namespace = "testDeleteReco"; bytes16 name = "testTable"; - bytes32 tableId = ResourceSelector.from(namespace, name); + ResourceId tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name }); FieldLayout fieldLayout = Bool.getFieldLayout(); Schema valueSchema = Bool.getValueSchema(); @@ -665,7 +821,7 @@ contract WorldTest is Test, GasReporter { assertTrue(Bool.get(world, tableId)); // Expect an error when trying to delete from an address that doesn't have access - _expectAccessDenied(address(0x02), "testDeleteRecord", "testTable"); + _expectAccessDenied(address(0x02), namespace, name, RESOURCE_TABLE); world.deleteRecord(tableId, singletonKey, fieldLayout); // Expect the World to have access @@ -676,19 +832,23 @@ contract WorldTest is Test, GasReporter { function testCall() public { // Register a new system WorldTestSystem system = new WorldTestSystem(); - bytes32 resourceSelector = ResourceSelector.from("namespace", "testSystem"); - world.registerSystem(resourceSelector, system, false); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSystem" + }); + world.registerSystem(systemId, system, false); // Call a system function without arguments via the World startGasReport("call a system via the World"); - bytes memory result = world.call(resourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ())); + bytes memory result = world.call(systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); endGasReport(); // Expect the system to have received the caller's address assertEq(address(uint160(uint256(bytes32(result)))), address(this)); // Call a system function with arguments via the World - result = world.call(resourceSelector, abi.encodeCall(WorldTestSystem.echo, (bytes32(uint256(0x123))))); + result = world.call(systemId, abi.encodeCall(WorldTestSystem.echo, (bytes32(uint256(0x123))))); // Expect the return data to be decodeable as a tuple (address returnedAddress, bytes32 returnedBytes32) = abi.decode(result, (address, bytes32)); @@ -701,33 +861,34 @@ contract WorldTest is Test, GasReporter { assertEq(returnStruct.input, bytes32(uint256(0x123))); // Expect an error when trying to call a private system from an address that doesn't have access - _expectAccessDenied(address(0x01), "namespace", "testSystem"); - world.call(resourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ())); + _expectAccessDenied(address(0x01), "namespace", "testSystem", RESOURCE_SYSTEM); + world.call(systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); // Expect the World to have access vm.prank(address(world)); - world.call(resourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ())); + world.call(systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); // Expect errors from the system to be forwarded vm.expectRevert(abi.encodeWithSelector(WorldTestSystem.WorldTestSystemError.selector, "test error")); - world.call(resourceSelector, abi.encodeCall(WorldTestSystem.err, ("test error"))); + world.call(systemId, abi.encodeCall(WorldTestSystem.err, ("test error"))); // Register another system in the same namespace WorldTestSystem subSystem = new WorldTestSystem(); - bytes32 subsystemResourceSelector = ResourceSelector.from("namespace", "testSubSystem"); - world.registerSystem(subsystemResourceSelector, subSystem, false); + ResourceId subsystemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSubSystem" + }); + world.registerSystem(subsystemId, subSystem, false); // Call the subsystem via the World (with access to the base route) - returnedAddress = abi.decode( - world.call(subsystemResourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ())), - (address) - ); + returnedAddress = abi.decode(world.call(subsystemId, abi.encodeCall(WorldTestSystem.msgSender, ())), (address)); assertEq(returnedAddress, address(this)); // Call the subsystem via delegatecall from the system // (Note: just for testing purposes, in reality systems can call subsystems directly instead of via two indirections like here) bytes memory nestedReturndata = world.call( - resourceSelector, + systemId, abi.encodeCall( WorldTestSystem.delegateCallSubSystem, // Function in system ( @@ -748,14 +909,18 @@ contract WorldTest is Test, GasReporter { function testCallFromSelf() public { // Register a new system WorldTestSystem system = new WorldTestSystem(); - bytes32 resourceSelector = ResourceSelector.from("namespace", "testSystem"); - world.registerSystem(resourceSelector, system, true); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSystem" + }); + world.registerSystem(systemId, system, true); address caller = address(1); // Call a system via callFrom with the own address vm.prank(caller); - bytes memory returnData = world.callFrom(caller, resourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ())); + bytes memory returnData = world.callFrom(caller, systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); address returnedAddress = abi.decode(returnData, (address)); // Expect the system to have received the delegator's address @@ -765,8 +930,12 @@ contract WorldTest is Test, GasReporter { function testCallFromUnlimitedDelegation() public { // Register a new system WorldTestSystem system = new WorldTestSystem(); - bytes32 resourceSelector = ResourceSelector.from("namespace", "testSystem"); - world.registerSystem(resourceSelector, system, true); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSystem" + }); + world.registerSystem(systemId, system, true); // Register an unlimited delegation address delegator = address(1); @@ -779,11 +948,7 @@ contract WorldTest is Test, GasReporter { // Call a system from the delegatee on behalf of the delegator vm.prank(delegatee); startGasReport("call a system via an unlimited delegation"); - bytes memory returnData = world.callFrom( - delegator, - resourceSelector, - abi.encodeCall(WorldTestSystem.msgSender, ()) - ); + bytes memory returnData = world.callFrom(delegator, systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); endGasReport(); address returnedAddress = abi.decode(returnData, (address)); @@ -794,8 +959,12 @@ contract WorldTest is Test, GasReporter { function testCallFromFailDelegationNotFound() public { // Register a new system WorldTestSystem system = new WorldTestSystem(); - bytes32 resourceSelector = ResourceSelector.from("namespace", "testSystem"); - world.registerSystem(resourceSelector, system, true); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSystem" + }); + world.registerSystem(systemId, system, true); // Expect a revert when attempting to perform a call on behalf of an address that doesn't have a delegation vm.expectRevert( @@ -806,14 +975,18 @@ contract WorldTest is Test, GasReporter { ) ); vm.prank(address(1)); - world.callFrom(address(2), resourceSelector, abi.encodeCall(WorldTestSystem.msgSender, ())); + world.callFrom(address(2), systemId, abi.encodeCall(WorldTestSystem.msgSender, ())); } function testCallFromLimitedDelegation() public { // Register a new system WorldTestSystem system = new WorldTestSystem(); - bytes32 resourceSelector = ResourceSelector.from("namespace", "testSystem"); - world.registerSystem(resourceSelector, system, true); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSystem" + }); + world.registerSystem(systemId, system, true); // Register a limited delegation address delegator = address(1); @@ -825,7 +998,7 @@ contract WorldTest is Test, GasReporter { function testRegisterStoreHook() public { FieldLayout fieldLayout = Bool.getFieldLayout(); Schema valueSchema = Bool.getValueSchema(); - bytes32 tableId = ResourceSelector.from("", "testTable"); + ResourceId tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: "", name: "testTable" }); // Register a new table world.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](1)); @@ -898,7 +1071,7 @@ contract WorldTest is Test, GasReporter { function testUnregisterStoreHook() public { FieldLayout fieldLayout = Bool.getFieldLayout(); Schema valueSchema = Bool.getValueSchema(); - bytes32 tableId = ResourceSelector.from("", "testTable"); + ResourceId tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: "", name: "testTable" }); // Register a new table world.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](1)); @@ -977,11 +1150,15 @@ contract WorldTest is Test, GasReporter { } function testRegisterSystemHook() public { - bytes32 systemId = ResourceSelector.from("namespace", "testTable"); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSystem" + }); // Register a new system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(systemId, system, false); + world.registerSystem(systemId, system, true); // Expect the registration to fail if the contract does not implement the system hook interface vm.expectRevert( @@ -1014,7 +1191,11 @@ contract WorldTest is Test, GasReporter { } function testUnregisterSystemHook() public { - bytes32 systemId = ResourceSelector.from("namespace", "testTable"); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testTable" + }); // Register a new system WorldTestSystem system = new WorldTestSystem(); @@ -1052,7 +1233,11 @@ contract WorldTest is Test, GasReporter { } function testWriteRootSystem() public { - bytes32 tableId = ResourceSelector.from("namespace", "testTable"); + ResourceId tableId = WorldResourceIdLib.encode({ + typeId: RESOURCE_TABLE, + namespace: "namespace", + name: "testTable" + }); // Register a new table world.registerTable( tableId, @@ -1064,22 +1249,23 @@ contract WorldTest is Test, GasReporter { ); // Register a new system - bytes32 rootSystemId = ResourceSelector.from("", "testSystem"); + ResourceId rootSystemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "", name: "testSystem" }); WorldTestSystem system = new WorldTestSystem(); world.registerSystem(rootSystemId, system, false); // Call a system function that writes data to the World - world.call( - rootSystemId, - abi.encodeCall(WorldTestSystem.writeData, (bytes16("namespace"), bytes16("testTable"), true)) - ); + world.call(rootSystemId, abi.encodeCall(WorldTestSystem.writeData, ("namespace", "testTable", true))); // Expect the data to be written assertTrue(Bool.get(world, tableId)); } - function testWriteAutonomousSystem() public { - bytes32 tableId = ResourceSelector.from("namespace", "testTable"); + function testWriteNonRootSystem() public { + ResourceId tableId = WorldResourceIdLib.encode({ + typeId: RESOURCE_TABLE, + namespace: "namespace", + name: "testTable" + }); // Register a new table world.registerTable( tableId, @@ -1091,52 +1277,60 @@ contract WorldTest is Test, GasReporter { ); // Register a new system - bytes32 systemId = ResourceSelector.from("namespace", "testSystem"); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSystem" + }); WorldTestSystem system = new WorldTestSystem(); world.registerSystem(systemId, system, false); // Call a system function that writes data to the World - world.call(systemId, abi.encodeCall(WorldTestSystem.writeData, (bytes16("namespace"), bytes16("testTable"), true))); + world.call(systemId, abi.encodeCall(WorldTestSystem.writeData, ("namespace", "testTable", true))); // Expect the data to be written assertTrue(Bool.get(world, tableId)); } function testDelegatecallRootSystem() public { - bytes32 resourceSelector = ResourceSelector.from("", "testSystem"); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: "", name: "testSystem" }); // Register a new root system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(resourceSelector, system, false); + world.registerSystem(systemId, system, false); // Call the root sysyem vm.expectEmit(true, true, true, true); emit WorldTestSystemLog("delegatecall"); - world.call(resourceSelector, abi.encodeCall(WorldTestSystem.emitCallType, ())); + world.call(systemId, abi.encodeCall(WorldTestSystem.emitCallType, ())); } function testCallAutonomousSystem() public { - bytes32 resourceSelector = ResourceSelector.from("namespace", "testSystem"); + ResourceId systemId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "testSystem" + }); // Register a new non-root system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(resourceSelector, system, false); + world.registerSystem(systemId, system, false); // Call the sysyem vm.expectEmit(true, true, true, true); emit WorldTestSystemLog("call"); - world.call(resourceSelector, abi.encodeCall(WorldTestSystem.emitCallType, ())); + world.call(systemId, abi.encodeCall(WorldTestSystem.emitCallType, ())); } function testRegisterFunctionSelector() public { - bytes16 namespace = "testNamespace"; + bytes14 namespace = "testNamespace"; bytes16 name = "testSystem"; - bytes32 resourceSelector = ResourceSelector.from(namespace, name); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); // Register a new system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(resourceSelector, system, true); + world.registerSystem(systemId, system, true); startGasReport("Register a function selector"); - bytes4 functionSelector = world.registerFunctionSelector(resourceSelector, "msgSender", "()"); + bytes4 functionSelector = world.registerFunctionSelector(systemId, "msgSender", "()"); endGasReport(); string memory expectedWorldFunctionSignature = "testNamespace_testSystem_msgSender()"; @@ -1150,7 +1344,7 @@ contract WorldTest is Test, GasReporter { assertEq(abi.decode(data, (address)), address(this), "wrong address returned"); // Register a function selector to the error function - functionSelector = world.registerFunctionSelector(resourceSelector, "err", "(string)"); + functionSelector = world.registerFunctionSelector(systemId, "err", "(string)"); // Expect errors to be passed through vm.expectRevert(abi.encodeWithSelector(WorldTestSystem.WorldTestSystemError.selector, "test error")); @@ -1158,27 +1352,27 @@ contract WorldTest is Test, GasReporter { } function testRegisterRootFunctionSelector() public { - bytes16 namespace = "testNamespace"; + bytes14 namespace = "testNamespace"; bytes16 name = "testSystem"; - bytes32 resourceSelector = ResourceSelector.from(namespace, name); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); // Register a new system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(resourceSelector, system, true); + world.registerSystem(systemId, system, true); bytes4 worldFunc = bytes4(abi.encodeWithSignature("testSelector()")); bytes4 sysFunc = WorldTestSystem.msgSender.selector; // Expect an error when trying to register a root function selector from an account without access - _expectAccessDenied(address(0x01), "", ""); - world.registerRootFunctionSelector(resourceSelector, worldFunc, sysFunc); + _expectAccessDenied(address(0x01), "", "", RESOURCE_NAMESPACE); + world.registerRootFunctionSelector(systemId, worldFunc, sysFunc); // Expect the World to not be able to register a root function selector when calling the function externally - _expectAccessDenied(address(world), "", ""); - world.registerRootFunctionSelector(resourceSelector, "smth", "smth"); + _expectAccessDenied(address(world), "", "", RESOURCE_NAMESPACE); + world.registerRootFunctionSelector(systemId, "smth", "smth"); startGasReport("Register a root function selector"); - bytes4 functionSelector = world.registerRootFunctionSelector(resourceSelector, worldFunc, sysFunc); + bytes4 functionSelector = world.registerRootFunctionSelector(systemId, worldFunc, sysFunc); endGasReport(); assertEq(functionSelector, worldFunc, "wrong function selector returned"); @@ -1191,7 +1385,7 @@ contract WorldTest is Test, GasReporter { // Register a function selector to the error function functionSelector = world.registerRootFunctionSelector( - resourceSelector, + systemId, WorldTestSystem.err.selector, WorldTestSystem.err.selector ); @@ -1202,16 +1396,16 @@ contract WorldTest is Test, GasReporter { } function testRegisterFallbackSystem() public { - bytes16 namespace = "testNamespace"; + bytes14 namespace = "testNamespace"; bytes16 name = "testSystem"; - bytes32 resourceSelector = ResourceSelector.from(namespace, name); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); // Register a new system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(resourceSelector, system, true); + world.registerSystem(systemId, system, true); startGasReport("Register a fallback system"); - bytes4 funcSelector1 = world.registerFunctionSelector(resourceSelector, "", ""); + bytes4 funcSelector1 = world.registerFunctionSelector(systemId, "", ""); endGasReport(); // Call the system's fallback function @@ -1223,7 +1417,7 @@ contract WorldTest is Test, GasReporter { bytes4 worldFunc = bytes4(abi.encodeWithSignature("testSelector()")); startGasReport("Register a root fallback system"); - bytes4 funcSelector2 = world.registerRootFunctionSelector(resourceSelector, worldFunc, 0); + bytes4 funcSelector2 = world.registerRootFunctionSelector(systemId, worldFunc, 0); endGasReport(); assertEq(funcSelector2, worldFunc, "wrong function selector returned"); @@ -1259,13 +1453,13 @@ contract WorldTest is Test, GasReporter { function testPayableSystem() public { // Register a root system with a payable function in the world WorldTestSystem system = new WorldTestSystem(); - bytes16 namespace = "noroot"; + bytes14 namespace = "noroot"; bytes16 name = "testSystem"; - bytes32 resourceSelector = ResourceSelector.from(namespace, name); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); - world.registerSystem(resourceSelector, system, true); + world.registerSystem(systemId, system, true); world.registerRootFunctionSelector( - resourceSelector, + systemId, WorldTestSystem.receiveEther.selector, WorldTestSystem.receiveEther.selector ); @@ -1290,12 +1484,12 @@ contract WorldTest is Test, GasReporter { function testNonPayableSystem() public { // Register a non-root system with a non-payable function in the world WorldTestSystem system = new WorldTestSystem(); - bytes16 namespace = "noroot"; + bytes14 namespace = "noroot"; bytes16 name = "testSystem"; - bytes32 resourceSelector = ResourceSelector.from(namespace, name); - world.registerSystem(resourceSelector, system, true); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); + world.registerSystem(systemId, system, true); world.registerRootFunctionSelector( - resourceSelector, + systemId, WorldTestSystem.msgSender.selector, WorldTestSystem.msgSender.selector ); @@ -1321,15 +1515,11 @@ contract WorldTest is Test, GasReporter { function testNonPayableFallbackSystem() public { // Register a root system with a non-payable function in the world WorldTestSystem system = new WorldTestSystem(); - bytes16 namespace = ROOT_NAMESPACE; + bytes14 namespace = ROOT_NAMESPACE; bytes16 name = "testSystem"; - bytes32 resourceSelector = ResourceSelector.from(namespace, name); - world.registerSystem(resourceSelector, system, true); - world.registerRootFunctionSelector( - resourceSelector, - bytes4(abi.encodeWithSignature("systemFallback()")), - bytes4("") - ); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); + world.registerSystem(systemId, system, true); + world.registerRootFunctionSelector(systemId, bytes4(abi.encodeWithSignature("systemFallback()")), bytes4("")); // create new funded address and impersonate address alice = makeAddr("alice"); @@ -1351,15 +1541,11 @@ contract WorldTest is Test, GasReporter { function testPayableFallbackSystem() public { // Register a root system with a payable function in the world PayableFallbackSystem system = new PayableFallbackSystem(); - bytes16 namespace = ROOT_NAMESPACE; + bytes14 namespace = ROOT_NAMESPACE; bytes16 name = "testSystem"; - bytes32 resourceSelector = ResourceSelector.from(namespace, name); - world.registerSystem(resourceSelector, system, true); - world.registerRootFunctionSelector( - resourceSelector, - bytes4(abi.encodeWithSignature("systemFallback()")), - bytes4("") - ); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); + world.registerSystem(systemId, system, true); + world.registerRootFunctionSelector(systemId, bytes4(abi.encodeWithSignature("systemFallback()")), bytes4("")); // create new funded address and impersonate address alice = makeAddr("alice"); @@ -1381,12 +1567,12 @@ contract WorldTest is Test, GasReporter { function testPayableRootSystem() public { // Register a root system with a payable function in the world WorldTestSystem system = new WorldTestSystem(); - bytes16 namespace = ROOT_NAMESPACE; + bytes14 namespace = ROOT_NAMESPACE; bytes16 name = "testSystem"; - bytes32 resourceSelector = ResourceSelector.from(namespace, name); - world.registerSystem(resourceSelector, system, true); + ResourceId systemId = WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: name }); + world.registerSystem(systemId, system, true); world.registerRootFunctionSelector( - resourceSelector, + systemId, WorldTestSystem.receiveEther.selector, WorldTestSystem.receiveEther.selector ); diff --git a/packages/world/test/WorldBalance.t.sol b/packages/world/test/WorldBalance.t.sol index f7225afde6..4f3df02a0f 100644 --- a/packages/world/test/WorldBalance.t.sol +++ b/packages/world/test/WorldBalance.t.sol @@ -6,13 +6,14 @@ import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { World } from "../src/World.sol"; import { System } from "../src/System.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; -import { ROOT_NAMESPACE } from "../src/constants.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; +import { ROOT_NAMESPACE, ROOT_NAMESPACE_ID } from "../src/constants.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { Balances } from "../src/modules/core/tables/Balances.sol"; import { IWorldErrors } from "../src/interfaces/IWorldErrors.sol"; +import { RESOURCE_SYSTEM, RESOURCE_NAMESPACE } from "../src/worldResourceTypes.sol"; -using ResourceSelector for bytes32; +using WorldResourceIdInstance for ResourceId; contract WorldBalanceTestSystem is System { function echoValue() public payable returns (uint256) { @@ -24,9 +25,12 @@ contract WorldBalanceTest is Test, GasReporter { IBaseWorld public world; WorldBalanceTestSystem public rootSystem = new WorldBalanceTestSystem(); WorldBalanceTestSystem public nonRootSystem = new WorldBalanceTestSystem(); - bytes16 public namespace = "namespace"; - bytes32 public rootSystemId = ResourceSelector.from(ROOT_NAMESPACE, "testSystem"); - bytes32 public nonRootSystemId = ResourceSelector.from(namespace, "testSystem"); + bytes14 public namespace = "namespace"; + ResourceId public namespaceId = WorldResourceIdLib.encodeNamespace(namespace); + ResourceId public rootSystemId = + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: ROOT_NAMESPACE, name: "testSystem" }); + ResourceId public nonRootSystemId = + WorldResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, namespace: namespace, name: "testSystem" }); address public caller = address(4242); function setUp() public { @@ -43,8 +47,8 @@ contract WorldBalanceTest is Test, GasReporter { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Call a function on the root system with value via call vm.deal(caller, value); @@ -53,7 +57,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Call a function on a non-root system with value via call vm.deal(caller, value); @@ -62,18 +66,18 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the non root namespace to have the value as balance - assertEq(Balances.get(world, namespace), value); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), value); // Expect the root namespace to still have the same balance as before - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); } function testCallFromWithValue() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Call a function on the root system with value via callFrom vm.deal(caller, value); @@ -82,7 +86,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Call a function on a non-root system with value via callFrom vm.deal(caller, value); @@ -91,18 +95,18 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the non root namespace to have the value as balance - assertEq(Balances.get(world, namespace), value); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), value); // Expect the root namespace to still have the same balance as before - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); } function testFallbackWithValue() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Call a function on the root system with value via the registered root function selector vm.deal(caller, value); @@ -112,7 +116,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Call a function on a non-root system with value vm.deal(caller, value); @@ -122,17 +126,17 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(abi.decode(data, (uint256)), value); // Expect the non root namespace to have the value as balance - assertEq(Balances.get(world, namespace), value); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), value); // Expect the root namespace to still have the same balance as before - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); } function testReceiveWithValue() public { uint256 value = 1 ether; // Expect the root to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); // Send value to the world without calldata vm.deal(caller, value); @@ -142,15 +146,15 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); } function testTransferBalanceToNamespace() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -160,24 +164,24 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Transfer the balance to another namespace - world.transferBalanceToNamespace(ROOT_NAMESPACE, namespace, value); + world.transferBalanceToNamespace(ROOT_NAMESPACE_ID, namespaceId, value); // Expect the root namespace to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); // Expect the non root namespace to have the value as balance - assertEq(Balances.get(world, namespace), value); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), value); } function testTransferBalanceToNamespaceRevertInsufficientBalance() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -187,25 +191,25 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect revert when attempting to transfer more than the balance vm.expectRevert(abi.encodeWithSelector(IWorldErrors.InsufficientBalance.selector, value, value + 1)); - world.transferBalanceToNamespace(ROOT_NAMESPACE, namespace, value + 1); + world.transferBalanceToNamespace(ROOT_NAMESPACE_ID, namespaceId, value + 1); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the non root namespace to have no balance - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); } function testTransferBalanceToNamespaceRevertAccessDenied() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -215,32 +219,62 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect revert when attempting to transfer from a namespace without access vm.prank(caller); + vm.expectRevert(abi.encodeWithSelector(IWorldErrors.AccessDenied.selector, ROOT_NAMESPACE_ID.toString(), caller)); + world.transferBalanceToNamespace(ROOT_NAMESPACE_ID, namespaceId, value); + + // Expect the root namespace to have the value as balance + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); + + // Expect the non root namespace to have no balance + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); + } + + function testTransferBalanceToNamespaceRevertInvalidResourceType() public { + uint256 value = 1 ether; + + // Expect the root namespace to have no balance + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + + // Send balance to root namespace + vm.deal(caller, value); + vm.prank(caller); + (bool success, bytes memory data) = address(world).call{ value: value }(""); + assertTrue(success); + assertEq(data.length, 0); + + // Expect the root namespace to have the value as balance + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); + + // Expect revert when attempting to transfer to an invalid namespace + ResourceId invalidNamespace = WorldResourceIdLib.encode({ typeId: "xx", namespace: "something", name: "invalid" }); + vm.prank(caller); vm.expectRevert( abi.encodeWithSelector( - IWorldErrors.AccessDenied.selector, - ResourceSelector.from(ROOT_NAMESPACE).toString(), - caller + IWorldErrors.InvalidResourceType.selector, + RESOURCE_NAMESPACE, + invalidNamespace, + invalidNamespace.toString() ) ); - world.transferBalanceToNamespace(ROOT_NAMESPACE, namespace, value); + world.transferBalanceToNamespace(ROOT_NAMESPACE_ID, invalidNamespace, value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the non root namespace to have no balance - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(invalidNamespace)), 0); } function testTransferBalanceToAddress() public { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -250,17 +284,17 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to not have any balance address receiver = address(1234); assertEq(receiver.balance, 0); // Transfer the balance to the receiver - world.transferBalanceToAddress(ROOT_NAMESPACE, receiver, value); + world.transferBalanceToAddress(ROOT_NAMESPACE_ID, receiver, value); // Expect the root namespace to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); // Expect the receiver to have value as balance assertEq(receiver.balance, value); @@ -270,8 +304,8 @@ contract WorldBalanceTest is Test, GasReporter { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -281,7 +315,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to not have any balance address receiver = address(1234); @@ -289,10 +323,10 @@ contract WorldBalanceTest is Test, GasReporter { // Expect revert when attempting to transfer more than the balance vm.expectRevert(abi.encodeWithSelector(IWorldErrors.InsufficientBalance.selector, value, value + 1)); - world.transferBalanceToAddress(ROOT_NAMESPACE, receiver, value + 1); + world.transferBalanceToAddress(ROOT_NAMESPACE_ID, receiver, value + 1); // Expect the root namespace to have value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to have no balance assertEq(receiver.balance, 0); @@ -302,8 +336,8 @@ contract WorldBalanceTest is Test, GasReporter { uint256 value = 1 ether; // Expect the root and non root namespaces to have no balance - assertEq(Balances.get(world, ROOT_NAMESPACE), 0); - assertEq(Balances.get(world, namespace), 0); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), 0); + assertEq(Balances.get(world, ResourceId.unwrap(namespaceId)), 0); // Send balance to root namespace vm.deal(caller, value); @@ -313,7 +347,7 @@ contract WorldBalanceTest is Test, GasReporter { assertEq(data.length, 0); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to not have any balance address receiver = address(1234); @@ -324,14 +358,14 @@ contract WorldBalanceTest is Test, GasReporter { vm.expectRevert( abi.encodeWithSelector( IWorldErrors.AccessDenied.selector, - ResourceSelector.from(ROOT_NAMESPACE).toString(), + WorldResourceIdLib.encodeNamespace(ROOT_NAMESPACE).toString(), caller ) ); - world.transferBalanceToAddress(ROOT_NAMESPACE, receiver, value); + world.transferBalanceToAddress(ROOT_NAMESPACE_ID, receiver, value); // Expect the root namespace to have the value as balance - assertEq(Balances.get(world, ROOT_NAMESPACE), value); + assertEq(Balances.get(world, ResourceId.unwrap(ROOT_NAMESPACE_ID)), value); // Expect the receiver to have no balance assertEq(receiver.balance, 0); diff --git a/packages/world/test/WorldDynamicUpdate.t.sol b/packages/world/test/WorldDynamicUpdate.t.sol index e2bea13264..409495592a 100644 --- a/packages/world/test/WorldDynamicUpdate.t.sol +++ b/packages/world/test/WorldDynamicUpdate.t.sol @@ -16,10 +16,9 @@ import { SchemaEncodeHelper } from "@latticexyz/store/test/SchemaEncodeHelper.so import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { World } from "../src/World.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; +import { RESOURCE_TABLE } from "../src/worldResourceTypes.sol"; -import { NamespaceOwner } from "../src/tables/NamespaceOwner.sol"; -import { ResourceAccess } from "../src/tables/ResourceAccess.sol"; import { AddressArray } from "./tables/AddressArray.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; @@ -28,7 +27,7 @@ import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; import { IWorldErrors } from "../src/interfaces/IWorldErrors.sol"; contract UpdateInFieldTest is Test, GasReporter { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; event HookCalled(bytes data); event WorldTestSystemLog(string log); @@ -40,9 +39,9 @@ contract UpdateInFieldTest is Test, GasReporter { bytes32[] internal keyTuple; bytes32[] internal singletonKey; - bytes16 namespace; + bytes14 namespace; bytes16 name; - bytes32 internal tableId; + ResourceId internal tableId; address[] internal initData; bytes internal encodedData; @@ -61,7 +60,7 @@ contract UpdateInFieldTest is Test, GasReporter { namespace = "DynamicUpdTest"; name = "testTable"; - tableId = ResourceSelector.from(namespace, name); + tableId = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name }); // Register a new table world.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](1)); @@ -77,7 +76,7 @@ contract UpdateInFieldTest is Test, GasReporter { } // Expect an error when trying to write from an address that doesn't have access - function _expectAccessDenied(address _caller, bytes32 _tableId) internal { + function _expectAccessDenied(address _caller, ResourceId _tableId) internal { vm.prank(_caller); vm.expectRevert(abi.encodeWithSelector(IWorldErrors.AccessDenied.selector, _tableId.toString(), _caller)); } diff --git a/packages/world/test/WorldResourceId.t.sol b/packages/world/test/WorldResourceId.t.sol new file mode 100644 index 0000000000..e249e75c9f --- /dev/null +++ b/packages/world/test/WorldResourceId.t.sol @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.0; + +import { Test, console } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; +import { ResourceId, ResourceIdLib, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; + +import { WorldResourceIdLib, WorldResourceIdInstance, NAMESPACE_BYTES, NAME_BYTES, TYPE_BYTES } from "../src/WorldResourceId.sol"; +import { RESOURCE_SYSTEM } from "../src/worldResourceTypes.sol"; + +contract WorldResourceIdTest is Test, GasReporter { + using ResourceIdInstance for ResourceId; + using WorldResourceIdInstance for ResourceId; + + function testEncode() public { + ResourceId resourceId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "name" + }); + + assertEq( + ResourceId.unwrap(resourceId), + bytes32(abi.encodePacked(RESOURCE_SYSTEM, bytes14("namespace"), bytes16("name"))) + ); + } + + function testGetNamespace() public { + ResourceId resourceId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "name" + }); + + startGasReport("encode namespace, name and type"); + bytes14 namespace = resourceId.getNamespace(); + endGasReport(); + + assertEq(namespace, "namespace"); + } + + function testGetNamespaceId() public { + ResourceId resourceId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "name" + }); + + startGasReport("get namespace ID from a resource ID"); + ResourceId namespaceId = resourceId.getNamespaceId(); + endGasReport(); + + assertEq(ResourceId.unwrap(namespaceId), ResourceId.unwrap(WorldResourceIdLib.encodeNamespace("namespace"))); + } + + function testGetType() public { + ResourceId resourceId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "name" + }); + + startGasReport("get type from a resource ID"); + bytes2 resourceType = resourceId.getType(); + endGasReport(); + + assertEq(resourceType, RESOURCE_SYSTEM); + } + + function testMatchResourceTypeEncoding() public { + ResourceId resourceId = WorldResourceIdLib.encode({ + typeId: RESOURCE_SYSTEM, + namespace: "namespace", + name: "name" + }); + bytes30 resourceIdWithoutType = bytes30(ResourceId.unwrap(resourceId) << (TYPE_BYTES * 8)); + assertEq( + ResourceId.unwrap(resourceId), + ResourceId.unwrap(ResourceIdLib.encode({ typeId: RESOURCE_SYSTEM, name: resourceIdWithoutType })) + ); + } + + function testMatchingByteSizes() public { + assertEq(NAMESPACE_BYTES + NAME_BYTES + TYPE_BYTES, 32); + } + + function testFuzz(bytes14 namespace, bytes16 name, bytes2 resourceType) public { + bytes2 NOT_TYPE = bytes2("xx"); + vm.assume(resourceType != NOT_TYPE); + ResourceId resourceId = WorldResourceIdLib.encode({ typeId: resourceType, namespace: namespace, name: name }); + assertEq(resourceId.getNamespace(), namespace); + assertEq( + ResourceId.unwrap(resourceId.getNamespaceId()), + ResourceId.unwrap(WorldResourceIdLib.encodeNamespace(namespace)) + ); + assertEq(resourceId.getNamespaceId().getNamespace(), namespace); + assertEq(resourceId.getName(), name); + assertEq(resourceId.getType(), resourceType); + } +} diff --git a/packages/world/test/query.t.sol b/packages/world/test/query.t.sol index 27f8621b9a..fd2fa7873d 100644 --- a/packages/world/test/query.t.sol +++ b/packages/world/test/query.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { Test } from "forge-std/Test.sol"; +import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; @@ -13,8 +13,9 @@ import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol" import { World } from "../src/World.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; -import { ResourceSelector } from "../src/ResourceSelector.sol"; +import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../src/WorldResourceId.sol"; import { ROOT_NAMESPACE } from "../src/constants.sol"; +import { RESOURCE_TABLE } from "../src/worldResourceTypes.sol"; import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { KeysInTableModule } from "../src/modules/keysintable/KeysInTableModule.sol"; @@ -22,12 +23,12 @@ import { KeysWithValueModule } from "../src/modules/keyswithvalue/KeysWithValueM import { query, QueryFragment, QueryType } from "../src/modules/keysintable/query.sol"; contract QueryTest is Test, GasReporter { - using ResourceSelector for bytes32; + using WorldResourceIdInstance for ResourceId; IBaseWorld private world; KeysInTableModule private keysInTableModule = new KeysInTableModule(); // Modules can be deployed once and installed multiple times KeysWithValueModule private keysWithValueModule = new KeysWithValueModule(); - bytes16 private namespace = ROOT_NAMESPACE; + bytes14 private namespace = ROOT_NAMESPACE; bytes16 private name1 = bytes16("source1"); bytes16 private name2 = bytes16("source2"); bytes16 private name3 = bytes16("source3"); @@ -35,9 +36,9 @@ contract QueryTest is Test, GasReporter { FieldLayout private tableFieldLayout; Schema private tableKeySchema; Schema private tableValueSchema; - bytes32 private table1 = ResourceSelector.from(namespace, name1); - bytes32 private table2 = ResourceSelector.from(namespace, name2); - bytes32 private table3 = ResourceSelector.from(namespace, name3); + ResourceId private table1 = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name1 }); + ResourceId private table2 = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name2 }); + ResourceId private table3 = WorldResourceIdLib.encode({ typeId: RESOURCE_TABLE, namespace: namespace, name: name3 }); uint256 private value = 1; bytes32[] private key1 = new bytes32[](1); diff --git a/packages/world/test/tables/AddressArray.sol b/packages/world/test/tables/AddressArray.sol index f702e371e4..2a0ca327d7 100644 --- a/packages/world/test/tables/AddressArray.sol +++ b/packages/world/test/tables/AddressArray.sol @@ -17,6 +17,8 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 @@ -57,22 +59,22 @@ library AddressArray { } /** Register the table with its config */ - function register(bytes32 _tableId) internal { + function register(ResourceId _tableId) internal { StoreSwitch.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config */ - function _register(bytes32 _tableId) internal { + function _register(ResourceId _tableId) internal { StoreCore.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config (using the specified store) */ - function register(IStore _store, bytes32 _tableId) internal { + function register(IStore _store, ResourceId _tableId) internal { _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Get value */ - function getValue(bytes32 _tableId, bytes32 key) internal view returns (address[] memory value) { + function getValue(ResourceId _tableId, bytes32 key) internal view returns (address[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -81,7 +83,7 @@ library AddressArray { } /** Get value */ - function _getValue(bytes32 _tableId, bytes32 key) internal view returns (address[] memory value) { + function _getValue(ResourceId _tableId, bytes32 key) internal view returns (address[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -90,7 +92,7 @@ library AddressArray { } /** Get value (using the specified store) */ - function getValue(IStore _store, bytes32 _tableId, bytes32 key) internal view returns (address[] memory value) { + function getValue(IStore _store, ResourceId _tableId, bytes32 key) internal view returns (address[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -99,7 +101,7 @@ library AddressArray { } /** Get value */ - function get(bytes32 _tableId, bytes32 key) internal view returns (address[] memory value) { + function get(ResourceId _tableId, bytes32 key) internal view returns (address[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -108,7 +110,7 @@ library AddressArray { } /** Get value */ - function _get(bytes32 _tableId, bytes32 key) internal view returns (address[] memory value) { + function _get(ResourceId _tableId, bytes32 key) internal view returns (address[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -117,7 +119,7 @@ library AddressArray { } /** Get value (using the specified store) */ - function get(IStore _store, bytes32 _tableId, bytes32 key) internal view returns (address[] memory value) { + function get(IStore _store, ResourceId _tableId, bytes32 key) internal view returns (address[] memory value) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -126,7 +128,7 @@ library AddressArray { } /** Set value */ - function setValue(bytes32 _tableId, bytes32 key, address[] memory value) internal { + function setValue(ResourceId _tableId, bytes32 key, address[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -134,7 +136,7 @@ library AddressArray { } /** Set value */ - function _setValue(bytes32 _tableId, bytes32 key, address[] memory value) internal { + function _setValue(ResourceId _tableId, bytes32 key, address[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -142,7 +144,7 @@ library AddressArray { } /** Set value (using the specified store) */ - function setValue(IStore _store, bytes32 _tableId, bytes32 key, address[] memory value) internal { + function setValue(IStore _store, ResourceId _tableId, bytes32 key, address[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -150,7 +152,7 @@ library AddressArray { } /** Set value */ - function set(bytes32 _tableId, bytes32 key, address[] memory value) internal { + function set(ResourceId _tableId, bytes32 key, address[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -158,7 +160,7 @@ library AddressArray { } /** Set value */ - function _set(bytes32 _tableId, bytes32 key, address[] memory value) internal { + function _set(ResourceId _tableId, bytes32 key, address[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -166,7 +168,7 @@ library AddressArray { } /** Set value (using the specified store) */ - function set(IStore _store, bytes32 _tableId, bytes32 key, address[] memory value) internal { + function set(IStore _store, ResourceId _tableId, bytes32 key, address[] memory value) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -174,7 +176,7 @@ library AddressArray { } /** Get the length of value */ - function lengthValue(bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function lengthValue(ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -185,7 +187,7 @@ library AddressArray { } /** Get the length of value */ - function _lengthValue(bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function _lengthValue(ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -196,7 +198,7 @@ library AddressArray { } /** Get the length of value (using the specified store) */ - function lengthValue(IStore _store, bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function lengthValue(IStore _store, ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -207,7 +209,7 @@ library AddressArray { } /** Get the length of value */ - function length(bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function length(ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -218,7 +220,7 @@ library AddressArray { } /** Get the length of value */ - function _length(bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function _length(ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -229,7 +231,7 @@ library AddressArray { } /** Get the length of value (using the specified store) */ - function length(IStore _store, bytes32 _tableId, bytes32 key) internal view returns (uint256) { + function length(IStore _store, ResourceId _tableId, bytes32 key) internal view returns (uint256) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -243,7 +245,7 @@ library AddressArray { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function getItemValue(bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (address) { + function getItemValue(ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (address) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -264,7 +266,7 @@ library AddressArray { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function _getItemValue(bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (address) { + function _getItemValue(ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (address) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -285,7 +287,12 @@ library AddressArray { * Get an item of value (using the specified store) * (unchecked, returns invalid data if index overflows) */ - function getItemValue(IStore _store, bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (address) { + function getItemValue( + IStore _store, + ResourceId _tableId, + bytes32 key, + uint256 _index + ) internal view returns (address) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -299,7 +306,7 @@ library AddressArray { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function getItem(bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (address) { + function getItem(ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (address) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -320,7 +327,7 @@ library AddressArray { * Get an item of value * (unchecked, returns invalid data if index overflows) */ - function _getItem(bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (address) { + function _getItem(ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (address) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -341,7 +348,7 @@ library AddressArray { * Get an item of value (using the specified store) * (unchecked, returns invalid data if index overflows) */ - function getItem(IStore _store, bytes32 _tableId, bytes32 key, uint256 _index) internal view returns (address) { + function getItem(IStore _store, ResourceId _tableId, bytes32 key, uint256 _index) internal view returns (address) { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -352,7 +359,7 @@ library AddressArray { } /** Push an element to value */ - function pushValue(bytes32 _tableId, bytes32 key, address _element) internal { + function pushValue(ResourceId _tableId, bytes32 key, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -360,7 +367,7 @@ library AddressArray { } /** Push an element to value */ - function _pushValue(bytes32 _tableId, bytes32 key, address _element) internal { + function _pushValue(ResourceId _tableId, bytes32 key, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -368,7 +375,7 @@ library AddressArray { } /** Push an element to value (using the specified store) */ - function pushValue(IStore _store, bytes32 _tableId, bytes32 key, address _element) internal { + function pushValue(IStore _store, ResourceId _tableId, bytes32 key, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -376,7 +383,7 @@ library AddressArray { } /** Push an element to value */ - function push(bytes32 _tableId, bytes32 key, address _element) internal { + function push(ResourceId _tableId, bytes32 key, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -384,7 +391,7 @@ library AddressArray { } /** Push an element to value */ - function _push(bytes32 _tableId, bytes32 key, address _element) internal { + function _push(ResourceId _tableId, bytes32 key, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -392,7 +399,7 @@ library AddressArray { } /** Push an element to value (using the specified store) */ - function push(IStore _store, bytes32 _tableId, bytes32 key, address _element) internal { + function push(IStore _store, ResourceId _tableId, bytes32 key, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -400,7 +407,7 @@ library AddressArray { } /** Pop an element from value */ - function popValue(bytes32 _tableId, bytes32 key) internal { + function popValue(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -408,7 +415,7 @@ library AddressArray { } /** Pop an element from value */ - function _popValue(bytes32 _tableId, bytes32 key) internal { + function _popValue(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -416,7 +423,7 @@ library AddressArray { } /** Pop an element from value (using the specified store) */ - function popValue(IStore _store, bytes32 _tableId, bytes32 key) internal { + function popValue(IStore _store, ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -424,7 +431,7 @@ library AddressArray { } /** Pop an element from value */ - function pop(bytes32 _tableId, bytes32 key) internal { + function pop(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -432,7 +439,7 @@ library AddressArray { } /** Pop an element from value */ - function _pop(bytes32 _tableId, bytes32 key) internal { + function _pop(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -440,7 +447,7 @@ library AddressArray { } /** Pop an element from value (using the specified store) */ - function pop(IStore _store, bytes32 _tableId, bytes32 key) internal { + function pop(IStore _store, ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -451,7 +458,7 @@ library AddressArray { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function updateValue(bytes32 _tableId, bytes32 key, uint256 _index, address _element) internal { + function updateValue(ResourceId _tableId, bytes32 key, uint256 _index, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -464,7 +471,7 @@ library AddressArray { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function _updateValue(bytes32 _tableId, bytes32 key, uint256 _index, address _element) internal { + function _updateValue(ResourceId _tableId, bytes32 key, uint256 _index, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -477,7 +484,7 @@ library AddressArray { * Update an element of value (using the specified store) at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function updateValue(IStore _store, bytes32 _tableId, bytes32 key, uint256 _index, address _element) internal { + function updateValue(IStore _store, ResourceId _tableId, bytes32 key, uint256 _index, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -490,7 +497,7 @@ library AddressArray { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function update(bytes32 _tableId, bytes32 key, uint256 _index, address _element) internal { + function update(ResourceId _tableId, bytes32 key, uint256 _index, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -503,7 +510,7 @@ library AddressArray { * Update an element of value at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function _update(bytes32 _tableId, bytes32 key, uint256 _index, address _element) internal { + function _update(ResourceId _tableId, bytes32 key, uint256 _index, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -516,7 +523,7 @@ library AddressArray { * Update an element of value (using the specified store) at `_index` * (checked only to prevent modifying other tables; can corrupt own data if index overflows) */ - function update(IStore _store, bytes32 _tableId, bytes32 key, uint256 _index, address _element) internal { + function update(IStore _store, ResourceId _tableId, bytes32 key, uint256 _index, address _element) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -556,7 +563,7 @@ library AddressArray { } /* Delete all data for given keys */ - function deleteRecord(bytes32 _tableId, bytes32 key) internal { + function deleteRecord(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -564,7 +571,7 @@ library AddressArray { } /* Delete all data for given keys */ - function _deleteRecord(bytes32 _tableId, bytes32 key) internal { + function _deleteRecord(ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; @@ -572,7 +579,7 @@ library AddressArray { } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 _tableId, bytes32 key) internal { + function deleteRecord(IStore _store, ResourceId _tableId, bytes32 key) internal { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; diff --git a/packages/world/test/tables/Bool.sol b/packages/world/test/tables/Bool.sol index f02424ce1c..3572977787 100644 --- a/packages/world/test/tables/Bool.sol +++ b/packages/world/test/tables/Bool.sol @@ -17,6 +17,8 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0001010001000000000000000000000000000000000000000000000000000000 @@ -55,22 +57,22 @@ library Bool { } /** Register the table with its config */ - function register(bytes32 _tableId) internal { + function register(ResourceId _tableId) internal { StoreSwitch.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config */ - function _register(bytes32 _tableId) internal { + function _register(ResourceId _tableId) internal { StoreCore.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Register the table with its config (using the specified store) */ - function register(IStore _store, bytes32 _tableId) internal { + function register(IStore _store, ResourceId _tableId) internal { _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } /** Get value */ - function getValue(bytes32 _tableId) internal view returns (bool value) { + function getValue(ResourceId _tableId) internal view returns (bool value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -78,7 +80,7 @@ library Bool { } /** Get value */ - function _getValue(bytes32 _tableId) internal view returns (bool value) { + function _getValue(ResourceId _tableId) internal view returns (bool value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -86,7 +88,7 @@ library Bool { } /** Get value (using the specified store) */ - function getValue(IStore _store, bytes32 _tableId) internal view returns (bool value) { + function getValue(IStore _store, ResourceId _tableId) internal view returns (bool value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -94,7 +96,7 @@ library Bool { } /** Get value */ - function get(bytes32 _tableId) internal view returns (bool value) { + function get(ResourceId _tableId) internal view returns (bool value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreSwitch.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -102,7 +104,7 @@ library Bool { } /** Get value */ - function _get(bytes32 _tableId) internal view returns (bool value) { + function _get(ResourceId _tableId) internal view returns (bool value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = StoreCore.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -110,7 +112,7 @@ library Bool { } /** Get value (using the specified store) */ - function get(IStore _store, bytes32 _tableId) internal view returns (bool value) { + function get(IStore _store, ResourceId _tableId) internal view returns (bool value) { bytes32[] memory _keyTuple = new bytes32[](0); bytes32 _blob = _store.getStaticField(_tableId, _keyTuple, 0, _fieldLayout); @@ -118,42 +120,42 @@ library Bool { } /** Set value */ - function setValue(bytes32 _tableId, bool value) internal { + function setValue(ResourceId _tableId, bool value) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value */ - function _setValue(bytes32 _tableId, bool value) internal { + function _setValue(ResourceId _tableId, bool value) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value (using the specified store) */ - function setValue(IStore _store, bytes32 _tableId, bool value) internal { + function setValue(IStore _store, ResourceId _tableId, bool value) internal { bytes32[] memory _keyTuple = new bytes32[](0); _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value */ - function set(bytes32 _tableId, bool value) internal { + function set(ResourceId _tableId, bool value) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value */ - function _set(bytes32 _tableId, bool value) internal { + function _set(ResourceId _tableId, bool value) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } /** Set value (using the specified store) */ - function set(IStore _store, bytes32 _tableId, bool value) internal { + function set(IStore _store, ResourceId _tableId, bool value) internal { bytes32[] memory _keyTuple = new bytes32[](0); _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); @@ -182,21 +184,21 @@ library Bool { } /* Delete all data for given keys */ - function deleteRecord(bytes32 _tableId) internal { + function deleteRecord(ResourceId _tableId) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys */ - function _deleteRecord(bytes32 _tableId) internal { + function _deleteRecord(ResourceId _tableId) internal { bytes32[] memory _keyTuple = new bytes32[](0); StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 _tableId) internal { + function deleteRecord(IStore _store, ResourceId _tableId) internal { bytes32[] memory _keyTuple = new bytes32[](0); _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); diff --git a/packages/world/ts/library/config/resolveWorldConfig.ts b/packages/world/ts/library/config/resolveWorldConfig.ts index f924e4ff04..e00fbcbe17 100644 --- a/packages/world/ts/library/config/resolveWorldConfig.ts +++ b/packages/world/ts/library/config/resolveWorldConfig.ts @@ -1,4 +1,4 @@ -import { getDuplicates, STORE_SELECTOR_MAX_LENGTH, UnrecognizedSystemErrorFactory } from "@latticexyz/config"; +import { getDuplicates, STORE_NAME_MAX_LENGTH, UnrecognizedSystemErrorFactory } from "@latticexyz/config"; import { MUDError } from "@latticexyz/common/errors"; import { StoreConfig } from "@latticexyz/store"; import { SystemConfig, WorldConfig } from "./types"; @@ -64,7 +64,7 @@ export function resolveWorldConfig(config: StoreConfig & WorldConfig, existingCo * Default value for accessListSystems is [] */ export function resolveSystemConfig(systemName: string, config?: SystemConfig, existingContracts?: string[]) { - const name = config?.name ?? systemName.slice(0, STORE_SELECTOR_MAX_LENGTH); + const name = (config?.name ?? systemName).slice(0, STORE_NAME_MAX_LENGTH); const registerFunctionSelectors = config?.registerFunctionSelectors ?? true; const openAccess = config?.openAccess ?? true; const accessListAddresses: string[] = []; diff --git a/packages/world/ts/library/config/worldConfig.ts b/packages/world/ts/library/config/worldConfig.ts index 2009c29983..ecd579ac7f 100644 --- a/packages/world/ts/library/config/worldConfig.ts +++ b/packages/world/ts/library/config/worldConfig.ts @@ -1,5 +1,5 @@ import { z } from "zod"; -import { DynamicResolutionType, zEthereumAddress, zObjectName, zSelector } from "@latticexyz/config"; +import { DynamicResolutionType, zEthereumAddress, zName, zObjectName } from "@latticexyz/config"; import { SYSTEM_DEFAULTS, WORLD_DEFAULTS } from "./defaults"; const zSystemName = zObjectName; @@ -9,7 +9,7 @@ const zSystemAccessList = z.array(zSystemName.or(zEthereumAddress)).default(SYST // The system config is a combination of a name config and access config const zSystemConfig = z.intersection( z.object({ - name: zSelector.optional(), + name: zName.optional(), registerFunctionSelectors: z.boolean().default(SYSTEM_DEFAULTS.registerFunctionSelector), }), z.discriminatedUnion("openAccess", [ diff --git a/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol b/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol index 997749a23d..f444e2aebd 100644 --- a/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Counter"))); -bytes32 constant CounterTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Counter"))) +); +ResourceId constant CounterTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0004010004000000000000000000000000000000000000000000000000000000 diff --git a/templates/react/packages/contracts/src/codegen/tables/Counter.sol b/templates/react/packages/contracts/src/codegen/tables/Counter.sol index 997749a23d..f444e2aebd 100644 --- a/templates/react/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/react/packages/contracts/src/codegen/tables/Counter.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Counter"))); -bytes32 constant CounterTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Counter"))) +); +ResourceId constant CounterTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0004010004000000000000000000000000000000000000000000000000000000 diff --git a/templates/threejs/packages/contracts/src/codegen/tables/Position.sol b/templates/threejs/packages/contracts/src/codegen/tables/Position.sol index b747e01351..d9ea2bc66b 100644 --- a/templates/threejs/packages/contracts/src/codegen/tables/Position.sol +++ b/templates/threejs/packages/contracts/src/codegen/tables/Position.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Position"))); -bytes32 constant PositionTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Position"))) +); +ResourceId constant PositionTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x000c030004040400000000000000000000000000000000000000000000000000 diff --git a/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol b/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol index 997749a23d..f444e2aebd 100644 --- a/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol @@ -17,9 +17,13 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; +import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; +import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; -bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Counter"))); -bytes32 constant CounterTableId = _tableId; +ResourceId constant _tableId = ResourceId.wrap( + bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Counter"))) +); +ResourceId constant CounterTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0004010004000000000000000000000000000000000000000000000000000000 diff --git a/test-data/world-logs.json b/test-data/world-logs.json index 01c17d0650..9ff96aa813 100644 --- a/test-data/world-logs.json +++ b/test-data/world-logs.json @@ -3,12 +3,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000022000000000a0000000000002c0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000016d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000600060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077461626c654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000b6669656c644c61796f757400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096b6579536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76616c7565536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012616269456e636f6465644b65794e616d657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014616269456e636f6465644669656c644e616d6573000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000022000000000a0000000000002c00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000174626d756473746f72650000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000600060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077461626c654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000b6669656c644c61796f757400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096b6579536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76616c7565536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012616269456e636f6465644b65794e616d657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014616269456e636f6465644669656c644e616d6573000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x0", "transactionLogIndex": "0x0", @@ -17,13 +17,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000016d756473746f7265000000000000000053746f7265486f6f6b7300000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000174626d756473746f72650000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x1", "transactionLogIndex": "0x1", @@ -33,12 +33,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000001001004f0000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d657370616365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000056f776e6572000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a0000000000001400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000174626d756473746f726500000000000053746f7265486f6f6b7300000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x2", "transactionLogIndex": "0x2", @@ -47,13 +47,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000042616c616e636573000000000000000000000000000000000000000000000000000000000000000000000000000000600020010020000000000000000000000000000000000000000000000000000000001001004f000000000000000000000000000000000000000000000000000000002001001f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d6573706163650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000762616c616e636500000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000174626d756473746f726500000000000053746f7265486f6f6b7300000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x3", "transactionLogIndex": "0x3", @@ -63,12 +63,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a00000000100000000000001a00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000003002004f5f0000000000000000000000000000000000000000000000000000001401006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a6d6f64756c654e616d6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d617267756d656e74734861736800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6d6f64756c654164647265737300000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a0000000000001400000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000174626d756473746f72650000000000005265736f75726365496473000000000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000010100600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a7265736f7572636549640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066578697374730000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x4", "transactionLogIndex": "0x4", @@ -77,13 +77,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a00000000100000000000001a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000044656c65676174696f6e730000000000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000028020061610000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000964656c656761746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000964656c6567617465650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001364656c65676174696f6e436f6e74726f6c496400000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000174626d756473746f72650000000000005265736f75726365496473000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x5", "transactionLogIndex": "0x5", @@ -93,12 +93,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a00000000100000000000001a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000003402005f610000000000000000000000000000000000000000000000000000000101006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663616c6c6572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066163636573730000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000140100610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b6e616d657370616365496400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000056f776e6572000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x6", "transactionLogIndex": "0x6", @@ -107,13 +107,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000600015020014010000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000001502006160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000673797374656d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c7075626c69634163636573730000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x7", "transactionLogIndex": "0x7", @@ -123,12 +123,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000240200200400000000000000000000000000000000000000000000000000000004010043000000000000000000000000000000000000000000000000000000002402005f43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001066756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001673797374656d46756e6374696f6e53656c6563746f7200000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000042616c616e636573000000000000000000000000000000000000000000000000000000000000000000000000000000600020010020000000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000002001001f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b6e616d6573706163654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000762616c616e636500000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x8", "transactionLogIndex": "0x8", @@ -137,13 +137,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d486f6f6b73000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000042616c616e636573000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x9", "transactionLogIndex": "0x9", @@ -153,12 +153,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d52656769737472790000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000673797374656d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a00000000100000000000001a00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000174620000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000003002004f5f0000000000000000000000000000000000000000000000000000001401006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a6d6f64756c654e616d6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d617267756d656e74734861736800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6d6f64756c654164647265737300000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0xa", "transactionLogIndex": "0xa", @@ -167,13 +167,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c7265736f75726365547970650000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000174620000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0xb", "transactionLogIndex": "0xb", @@ -182,13 +182,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000004e616d6573706163654f776e65720000" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a00000000100000000000001a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000044656c65676174696f6e730000000000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000028020061610000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000964656c656761746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000964656c6567617465650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001364656c65676174696f6e436f6e74726f6c496400000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0xc", "transactionLogIndex": "0xc", @@ -198,12 +198,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263654163636573730000" + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000044656c65676174696f6e73000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0xd", "transactionLogIndex": "0xd", @@ -212,13 +212,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263655479706500000000" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a00000000100000000000001a000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000003402005f610000000000000000000000000000000000000000000000000000000101006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a7265736f75726365496400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663616c6c6572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066163636573730000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0xe", "transactionLogIndex": "0xe", @@ -228,12 +228,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263655479706500000000" + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e730000000000000000000000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0xf", "transactionLogIndex": "0xf", @@ -243,12 +243,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000053797374656d73000000000000000000" + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e73000000000000000000000000000000000000000000000000000000000000000000000000000000000015cafac3dd18ac6c6e92c921884f9e4176737c052c0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000600015020014010000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000001502006160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000873797374656d49640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000673797374656d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c7075626c69634163636573730000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x10", "transactionLogIndex": "0x10", @@ -258,12 +258,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x0000000000000000000000000000000053797374656d52656769737472790000" + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000636f72652e7300000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x11", "transactionLogIndex": "0x11", @@ -272,13 +272,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263654163636573730000" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000240200200400000000000000000000000000000000000000000000000000000004010043000000000000000000000000000000000000000000000000000000002402005f43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001066756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000873797374656d4964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001673797374656d46756e6374696f6e53656c6563746f7200000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x12", "transactionLogIndex": "0x12", @@ -287,13 +287,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000140554c3a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000040554c3a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x13", "transactionLogIndex": "0x13", @@ -303,12 +303,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000018d53b20800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008d53b208000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000053797374656d486f6f6b73000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000873797374656d4964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x14", "transactionLogIndex": "0x14", @@ -317,13 +317,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000125f6221000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000025f62210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000053797374656d486f6f6b73000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x15", "transactionLogIndex": "0x15", @@ -333,12 +333,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000012bfaa27400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000002bfaa274000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000053797374656d52656769737472790000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000673797374656d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000873797374656d4964000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x16", "transactionLogIndex": "0x16", @@ -347,13 +347,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000121293ca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000021293ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000017462000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x17", "transactionLogIndex": "0x17", @@ -362,13 +362,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000013ea8492200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003ea84922000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000016e7300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x18", "transactionLogIndex": "0x18", @@ -377,13 +377,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x746200000000000000000000000000004e616d6573706163654f776e65720000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000018da798da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008da798da000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000016e730000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x19", "transactionLogIndex": "0x19", @@ -392,13 +392,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x746200000000000000000000000000005265736f757263654163636573730000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000010ba51f4900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000000ba51f49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000026e73000000000000000000000000000000000000000000000000000000000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x1a", "transactionLogIndex": "0x1a", @@ -407,13 +407,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001530f4b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000530f4b60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000173790000000000000000000000000000636f72652e730000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x1b", "transactionLogIndex": "0x1b", @@ -423,12 +423,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000053797374656d73000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000010560912900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000005609129000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000173790000000000000000000000000000636f72652e73000000000000000000000000000000000000000000000000000000000000000000000000000000000015cafac3dd18ac6c6e92c921884f9e4176737c052c0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x1c", "transactionLogIndex": "0x1c", @@ -437,13 +437,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x7462000000000000000000000000000053797374656d52656769737472790000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001a886545e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a886545e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c000000000000000000000000000000000000000000000000000000000000002073790000000000000000000000000000636f72652e7300000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x1d", "transactionLogIndex": "0x1d", @@ -452,13 +452,13 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x746200000000000000000000000000005265736f757263654163636573730000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001d5f8337f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000d5f8337f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000026e73000000000000000000000000000000000000000000000000000000000000000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x1e", "transactionLogIndex": "0x1e", @@ -468,12 +468,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001a92813ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a92813ad000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000140554c3a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e730000000000000000000040554c3a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x1f", "transactionLogIndex": "0x1f", @@ -483,12 +483,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000013350b6a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003350b6a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000018d53b20800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e73000000000000000000008d53b208000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x20", "transactionLogIndex": "0x20", @@ -498,12 +498,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000013c03a51c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003c03a51c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001ef5d6bbb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e7300000000000000000000ef5d6bbb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x21", "transactionLogIndex": "0x21", @@ -513,12 +513,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001b7a3c75600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000b7a3c756000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001c9c85a6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e7300000000000000000000c9c85a60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x22", "transactionLogIndex": "0x22", @@ -528,12 +528,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000011d2257ba00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000001d2257ba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000145afd19900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e730000000000000000000045afd199000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x23", "transactionLogIndex": "0x23", @@ -542,135 +542,300 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x00000000000000000000000000000000496e7374616c6c65644d6f64756c6573" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000002636f72652e6d0000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4700000000000000000000000000000000000000000000000000000000000000014e7f1725e7734ce288f8367e1bb143e90bb3f0512000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000018da798da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e73000000000000000000008da798da000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa4f8502ae902c2b982a75bee37ad2c52b7456d38cb4fdd2288dbda0d53b5db23", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", "transactionIndex": "0x0", "logIndex": "0x24", "transactionLogIndex": "0x24", "removed": false }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000010ba51f4900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e73000000000000000000000ba51f49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x25", + "transactionLogIndex": "0x25", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001530f4b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e7300000000000000000000530f4b60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x26", + "transactionLogIndex": "0x26", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000010560912900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e730000000000000000000005609129000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x27", + "transactionLogIndex": "0x27", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001b29e408900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e7300000000000000000000b29e4089000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x28", + "transactionLogIndex": "0x28", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001d5f8337f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e7300000000000000000000d5f8337f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x29", + "transactionLogIndex": "0x29", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001a92813ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e7300000000000000000000a92813ad000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x2a", + "transactionLogIndex": "0x2a", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000013350b6a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e73000000000000000000003350b6a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x2b", + "transactionLogIndex": "0x2b", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000013c03a51c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e73000000000000000000003c03a51c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x2c", + "transactionLogIndex": "0x2c", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001b7a3c75600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e7300000000000000000000b7a3c756000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x2d", + "transactionLogIndex": "0x2d", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000011d2257ba00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000636f72652e73000000000000000000001d2257ba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x2e", + "transactionLogIndex": "0x2e", + "removed": false + }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263655479706500000000" + "0x74620000000000000000000000000000496e7374616c6c65644d6f64756c6573" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000002636f72652e6d0000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4700000000000000000000000000000000000000000000000000000000000000014e7f1725e7734ce288f8367e1bb143e90bb3f0512000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x63c9c3f365b40de92c07c06e86f096433bfb2e968c3caec07df00fa2cd1a46d1", + "transactionHash": "0x7e2f055f66d3576d1f74a5b4d50612da661bc8a0aadeb4a7bab1d68ebcec2987", + "transactionIndex": "0x0", + "logIndex": "0x2f", + "transactionLogIndex": "0x2f", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x74626d756473746f72650000000000005461626c657300000000000000000000" + ], + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000004e756d626572000000000000000000000000000000000000000000000000000000000000000000000000000000000060000401000400000000000000000000000000000000000000000000000000000000040100030000000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", + "blockNumber": "0x4", + "transactionHash": "0xfee34092d2be35f9cb4747048fba17f73969fdd2bea418fdabfd123e9fccfdd3", "transactionIndex": "0x1", - "logIndex": "0x25", + "logIndex": "0x30", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d626572000000000000000000000000000000000000000000000000000000000000000000000000000000000060000401000400000000000000000000000000000000000000000000000000000000040100030000000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000004e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x63c9c3f365b40de92c07c06e86f096433bfb2e968c3caec07df00fa2cd1a46d1", + "transactionHash": "0xfee34092d2be35f9cb4747048fba17f73969fdd2bea418fdabfd123e9fccfdd3", "transactionIndex": "0x1", - "logIndex": "0x26", + "logIndex": "0x31", "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263655479706500000000" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000010000000000a0000000000001a00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000174620000000000000000000000000000566563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000006000080200040400000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000802002323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b6579000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xe1f1a922f753965be316f50e3c51c91c436aff6091710ba37cd2c2b932625a6d", + "transactionHash": "0xfdbe3cacafcfe2f5841a693f23a8cf6971ba5fd688185820eb3801cbee3a9929", "transactionIndex": "0x2", - "logIndex": "0x27", + "logIndex": "0x32", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000010000000000a0000000000001a00000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000006000080200040400000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000802002323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b6579000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000174620000000000000000000000000000566563746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xe1f1a922f753965be316f50e3c51c91c436aff6091710ba37cd2c2b932625a6d", + "transactionHash": "0xfdbe3cacafcfe2f5841a693f23a8cf6971ba5fd688185820eb3801cbee3a9929", "transactionIndex": "0x2", - "logIndex": "0x28", + "logIndex": "0x33", "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263655479706500000000" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a00000000040000000000000e000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000004e756d6265724c697374000000000000000000000000000000000000000000000000000000000000000000000000006000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x2a33d478b71e83b3075ae06f08da8260132fc8c0f8bb4e316b7c8c36b37a1fb8", + "transactionHash": "0x27e29a882fdeb2c02feeb5003780c26c767d29d19bf24a76e3b79849468fdc78", "transactionIndex": "0x3", - "logIndex": "0x29", + "logIndex": "0x34", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000a00000000040000000000000e000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c697374000000000000000000000000000000000000000000000000000000000000000000000000006000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x2a33d478b71e83b3075ae06f08da8260132fc8c0f8bb4e316b7c8c36b37a1fb8", + "transactionHash": "0x27e29a882fdeb2c02feeb5003780c26c767d29d19bf24a76e3b79849468fdc78", "transactionIndex": "0x3", - "logIndex": "0x2a", + "logIndex": "0x35", "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263655479706500000000" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", + "0x74626d756473746f72650000000000005461626c657300000000000000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c7469000000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000010000000001c0000000000002c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000004d756c74690000000000000000000000000000000000000000000000000000000000000000000000000000000000006000210200200100000000000000000000000000000000000000000000000000000034040003601f2e000000000000000000000000000000000000000000000000002102003f60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000162000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000036e756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x7f5154e28a5640217c214a2007641ccb776e5b9609101919e28aead1d8eb6352", + "transactionHash": "0x470b581c9a1cac85fda4feb069e47f881b6c6444c68ffe52385ff85f8e67f0b7", "transactionIndex": "0x4", - "logIndex": "0x2b", + "logIndex": "0x36", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x6d756473746f726500000000000000005461626c657300000000000000000000" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000010000000001c0000000000002c000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c74690000000000000000000000000000000000000000000000000000000000000000000000000000000000006000210200200100000000000000000000000000000000000000000000000000000034040003601f2e000000000000000000000000000000000000000000000000002102003f60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000162000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000036e756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001746200000000000000000000000000004d756c7469000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x7f5154e28a5640217c214a2007641ccb776e5b9609101919e28aead1d8eb6352", + "transactionHash": "0x470b581c9a1cac85fda4feb069e47f881b6c6444c68ffe52385ff85f8e67f0b7", "transactionIndex": "0x4", - "logIndex": "0x2c", + "logIndex": "0x37", "transactionLogIndex": "0x1", "removed": false }, @@ -678,14 +843,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263655479706500000000" + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000173790000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x9522e814b8b7aa55524257cfb693c2fdcb6fe1afd7aae7f0daf68c426afcbac9", + "transactionHash": "0xc7a43a7856187b487496b0246a8417e332ed34a586ce98b0bf80111dcf5387a3", "transactionIndex": "0x5", - "logIndex": "0x2d", + "logIndex": "0x38", "transactionLogIndex": "0x0", "removed": false }, @@ -693,14 +858,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000053797374656d73000000000000000000" + "0x7462000000000000000000000000000053797374656d73000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000155fc8d32690cc91d4c39d9d3abcbd16989f8757070100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000173790000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000155fc8d32690cc91d4c39d9d3abcbd16989f8757070100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x9522e814b8b7aa55524257cfb693c2fdcb6fe1afd7aae7f0daf68c426afcbac9", + "transactionHash": "0xc7a43a7856187b487496b0246a8417e332ed34a586ce98b0bf80111dcf5387a3", "transactionIndex": "0x5", - "logIndex": "0x2e", + "logIndex": "0x39", "transactionLogIndex": "0x1", "removed": false }, @@ -708,14 +873,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x0000000000000000000000000000000053797374656d52656769737472790000" + "0x7462000000000000000000000000000053797374656d52656769737472790000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000437573746f6d4572726f727353797374", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000000000000000000000000000000000000000002073790000000000000000000000000000437573746f6d4572726f727353797374", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x9522e814b8b7aa55524257cfb693c2fdcb6fe1afd7aae7f0daf68c426afcbac9", + "transactionHash": "0xc7a43a7856187b487496b0246a8417e332ed34a586ce98b0bf80111dcf5387a3", "transactionIndex": "0x5", - "logIndex": "0x2f", + "logIndex": "0x3a", "transactionLogIndex": "0x2", "removed": false }, @@ -723,14 +888,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263654163636573730000" + "0x746200000000000000000000000000005265736f757263654163636573730000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f87570700000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000026e730000000000000000000000000000000000000000000000000000000000000000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f87570700000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x9522e814b8b7aa55524257cfb693c2fdcb6fe1afd7aae7f0daf68c426afcbac9", + "transactionHash": "0xc7a43a7856187b487496b0246a8417e332ed34a586ce98b0bf80111dcf5387a3", "transactionIndex": "0x5", - "logIndex": "0x30", + "logIndex": "0x3b", "transactionLogIndex": "0x3", "removed": false }, @@ -738,14 +903,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263655479706500000000" + "0x74626d756473746f72650000000000005265736f757263654964730000000000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001737900000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x21d2bdc995fad3ad12bc649405f9c25522526bf04a2ba379fd5cb4056e9368f3", + "transactionHash": "0xe43ef0b86a52b4da0f61cdc2ea334e5b7fa66f7588983f640e5deb328f669d51", "transactionIndex": "0x6", - "logIndex": "0x31", + "logIndex": "0x3c", "transactionLogIndex": "0x0", "removed": false }, @@ -753,14 +918,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000053797374656d73000000000000000000" + "0x7462000000000000000000000000000053797374656d73000000000000000000" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000150165878a594ca255338adfa4d48449f69242eb8f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001737900000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000150165878a594ca255338adfa4d48449f69242eb8f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x21d2bdc995fad3ad12bc649405f9c25522526bf04a2ba379fd5cb4056e9368f3", + "transactionHash": "0xe43ef0b86a52b4da0f61cdc2ea334e5b7fa66f7588983f640e5deb328f669d51", "transactionIndex": "0x6", - "logIndex": "0x32", + "logIndex": "0x3d", "transactionLogIndex": "0x1", "removed": false }, @@ -768,14 +933,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x0000000000000000000000000000000053797374656d52656769737472790000" + "0x7462000000000000000000000000000053797374656d52656769737472790000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000004e756d6265724c69737453797374656d", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f0000000000000000000000000000000000000000000000000000000000000020737900000000000000000000000000004e756d6265724c69737453797374656d", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x21d2bdc995fad3ad12bc649405f9c25522526bf04a2ba379fd5cb4056e9368f3", + "transactionHash": "0xe43ef0b86a52b4da0f61cdc2ea334e5b7fa66f7588983f640e5deb328f669d51", "transactionIndex": "0x6", - "logIndex": "0x33", + "logIndex": "0x3e", "transactionLogIndex": "0x2", "removed": false }, @@ -783,14 +948,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735", - "0x000000000000000000000000000000005265736f757263654163636573730000" + "0x746200000000000000000000000000005265736f757263654163636573730000" ], - "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000026e730000000000000000000000000000000000000000000000000000000000000000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x21d2bdc995fad3ad12bc649405f9c25522526bf04a2ba379fd5cb4056e9368f3", + "transactionHash": "0xe43ef0b86a52b4da0f61cdc2ea334e5b7fa66f7588983f640e5deb328f669d51", "transactionIndex": "0x6", - "logIndex": "0x34", + "logIndex": "0x3f", "transactionLogIndex": "0x3", "removed": false }, @@ -798,14 +963,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000015f644e3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000437573746f6d4572726f7273537973745f644e3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000015f644e3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002473790000000000000000000000000000437573746f6d4572726f7273537973745f644e3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xa7b13684919b9c2f639041255d439afd3468db01f44f2699e159704399a11d5c", + "transactionHash": "0x8af9c1dc64c54b515e45eada457deeefb8c41f28a5dcd383b08e1974aba9deeb", "transactionIndex": "0x7", - "logIndex": "0x35", + "logIndex": "0x40", "transactionLogIndex": "0x0", "removed": false }, @@ -813,14 +978,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001a4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656da4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001a4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024737900000000000000000000000000004e756d6265724c69737453797374656da4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xd06d889514df379529e4231e85b2d241559dc810b765152c17047ae767b51cf0", + "transactionHash": "0x594595958fab259d43d21eff2b843d5f4a8b72eaba5bfc7d7ac57a64429baa46", "transactionIndex": "0x8", - "logIndex": "0x36", + "logIndex": "0x41", "transactionLogIndex": "0x0", "removed": false }, @@ -828,14 +993,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001f7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656df7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001f7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024737900000000000000000000000000004e756d6265724c69737453797374656df7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0x08304f1f19f128d652cf1f5b599e1c8b87e5b8164e3046e7041aabc886b7227f", + "transactionHash": "0x1ad0a4cb99bb91696c2fdc950ef8f725a033126b014ef9f8dc33fe5e60651a58", "transactionIndex": "0x9", - "logIndex": "0x37", + "logIndex": "0x42", "transactionLogIndex": "0x0", "removed": false }, @@ -843,14 +1008,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656d306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024737900000000000000000000000000004e756d6265724c69737453797374656d306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xab1ec3ac7ebed007e57666d5fbb7c5ba174c9695ea87d9cd5025f1323d5cd573", + "transactionHash": "0x74242eea32fbe3313d212eb94d4b0e9a1b41d4a3ca73b8e43409652d0d1033b4", "transactionIndex": "0xa", - "logIndex": "0x38", + "logIndex": "0x43", "transactionLogIndex": "0x0", "removed": false }, @@ -858,14 +1023,14 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f", - "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72" + "0x7462000000000000000000000000000046756e6374696f6e53656c6563746f72" ], - "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001b8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656db8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x26210b5307d8f2e8f7ce8c759d3563b48fad64b1021b2fb6100d83cd7f55a3cd", + "data": "0x000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001b8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024737900000000000000000000000000004e756d6265724c69737453797374656db8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x7704cb23795595159707f7ec7ef212f8a1727f88b980d34b605e994bb9f9e403", "blockNumber": "0x4", - "transactionHash": "0xef2202fbaac567d90f4790707035892d554dc226c0d481ffe667f1818774ad7b", + "transactionHash": "0xb7ae5d81eac3cada387ee8aa84b200810a20239fc9d28c8d88b1928b52df89fe", "transactionIndex": "0xb", - "logIndex": "0x39", + "logIndex": "0x44", "transactionLogIndex": "0x0", "removed": false }, @@ -873,12 +1038,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0x5599f2052ade9808af7738adc73853c23894a2f1e944c827f7f6b8e948c4e885", - "0x000000000000000000000000000000004e756d6265724c697374000000000000" + "0x746200000000000000000000000000004e756d6265724c697374000000000000" ], "data": "0x00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000040000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000001a400000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf77983f832702b99ab5712e6c94615f2125f82e1b279f966c49fd8c8d8bd03f1", + "blockHash": "0x59ae5d5807af461e28ea34b5c32a06c5deb94686c0039bc439cd2c5d4f000cc2", "blockNumber": "0x5", - "transactionHash": "0xe373575d25699927fbfcd0fb9eb2b48ebaed83b87d3ca1e0a30478ac2ae2be4f", + "transactionHash": "0x36889a5ee3c55bfaac027f3581de07e578bada31ae0ac3b015ce6eb8977ef084", "transactionIndex": "0x0", "logIndex": "0x0", "transactionLogIndex": "0x0", @@ -888,12 +1053,12 @@ "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ "0x5599f2052ade9808af7738adc73853c23894a2f1e944c827f7f6b8e948c4e885", - "0x000000000000000000000000000000004e756d6265724c697374000000000000" + "0x746200000000000000000000000000004e756d6265724c697374000000000000" ], "data": "0x00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000800000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000004500000000000000000000000000000000000000000000000000000000", - "blockHash": "0xf77983f832702b99ab5712e6c94615f2125f82e1b279f966c49fd8c8d8bd03f1", + "blockHash": "0x59ae5d5807af461e28ea34b5c32a06c5deb94686c0039bc439cd2c5d4f000cc2", "blockNumber": "0x5", - "transactionHash": "0xfec9e0db2f68f31109c2f8fb678f398807407b88deb1b9644f1638e0012fac7c", + "transactionHash": "0x5feacc4cdda19482f80e612fb3e7d8e3d5c9260b14a2da727f882a2f3d7dd07c", "transactionIndex": "0x1", "logIndex": "0x1", "transactionLogIndex": "0x0", From bfcb293d1931edde7f8a3e077f6f555a26fd1d2f Mon Sep 17 00:00:00 2001 From: alvarius Date: Thu, 21 Sep 2023 17:17:23 +0100 Subject: [PATCH 3/4] feat(store,world): replace `ephemeral` tables with `offchain` tables (#1558) Co-authored-by: Kevin Ingersoll Co-authored-by: dk1a --- .changeset/small-chicken-repair.md | 20 +++ docs/pages/store/advanced-features.mdx | 20 +-- docs/pages/world/internals.mdx | 2 +- .../contracts/src/codegen/tables/Multi.sol | 56 +++---- .../contracts/src/codegen/tables/Number.sol | 50 +++--- .../src/codegen/tables/NumberList.sol | 44 +++--- .../contracts/src/codegen/tables/Vector.sol | 50 +++--- .../minimal/packages/contracts/mud.config.ts | 2 +- .../src/codegen/tables/CounterTable.sol | 44 +++--- .../src/codegen/tables/Inventory.sol | 56 +++---- .../src/codegen/tables/MessageTable.sol | 71 +++++++-- .../src/systems/ChatNamespacedSystem.sol | 2 +- .../contracts/src/systems/ChatSystem.sol | 2 +- .../contracts/test/ChatNamespaced.t.sol | 4 +- packages/block-logs-stream/README.md | 1 - packages/cli/contracts/src/codegen/index.sol | 2 +- .../src/codegen/tables/Dynamics1.sol | 50 +++--- .../src/codegen/tables/Dynamics2.sol | 50 +++--- .../tables/{Ephemeral.sol => Offchain.sol} | 90 +++++++++-- .../src/codegen/tables/Singleton.sol | 44 +++--- .../contracts/src/codegen/tables/Statics.sol | 80 +++++----- packages/cli/contracts/test/Tablegen.t.sol | 8 +- packages/cli/scripts/generate-test-tables.ts | 4 +- .../utils/tables/getRegisterTableCallData.ts | 2 +- packages/cli/src/utils/tables/types.ts | 2 +- .../src/codegen/render-solidity/common.ts | 16 +- .../src/codegen/render-solidity/types.ts | 1 + packages/dev-tools/src/events/EventIcon.tsx | 2 - packages/dev-tools/src/events/LogsTable.tsx | 2 +- packages/store-sync/src/common.ts | 2 +- .../src/postgres/postgresStorage.ts | 2 +- .../src/recs/configToRecsComponents.ts | 2 +- packages/store-sync/src/recs/recsStorage.ts | 2 +- .../store-sync/src/sqlite/sqliteStorage.ts | 2 +- packages/store/gas-report.json | 86 +++++------ packages/store/src/IStore.sol | 22 +-- packages/store/src/StoreCore.sol | 97 ++++++------ packages/store/src/StoreSwitch.sol | 23 --- .../store/src/codegen/tables/Callbacks.sol | 50 +++--- packages/store/src/codegen/tables/Hooks.sol | 50 +++--- .../store/src/codegen/tables/KeyEncoding.sol | 70 ++++----- packages/store/src/codegen/tables/Mixed.sol | 50 +++--- .../store/src/codegen/tables/ResourceIds.sol | 50 +++--- .../store/src/codegen/tables/StoreHooks.sol | 50 +++--- packages/store/src/codegen/tables/Tables.sol | 50 +++--- packages/store/src/codegen/tables/Vector2.sol | 50 +++--- packages/store/test/StoreMock.sol | 12 -- packages/store/ts/codegen/ephemeral.ts | 51 ------ packages/store/ts/codegen/field.ts | 145 +++++++++--------- packages/store/ts/codegen/record.ts | 62 +++++--- packages/store/ts/codegen/renderTable.ts | 31 +--- packages/store/ts/codegen/tableOptions.ts | 11 +- packages/store/ts/codegen/types.ts | 8 +- packages/store/ts/config/defaults.ts | 2 +- packages/store/ts/config/storeConfig.ts | 8 +- packages/store/ts/storeEvents.ts | 1 - packages/world/gas-report.json | 84 +++++----- packages/world/mud.config.ts | 2 - .../world/src/modules/core/CoreModule.sol | 6 +- .../world/src/modules/core/CoreSystem.sol | 2 - .../implementations/EphemeralRecordSystem.sol | 33 ---- .../src/modules/core/tables/Balances.sol | 50 +++--- .../modules/core/tables/FunctionSelectors.sol | 50 +++--- .../src/modules/core/tables/SystemHooks.sol | 50 +++--- .../modules/core/tables/SystemRegistry.sol | 50 +++--- .../world/src/modules/core/tables/Systems.sol | 50 +++--- .../keysintable/tables/KeysInTable.sol | 50 +++--- .../keysintable/tables/UsedKeysIndex.sol | 56 +++---- .../keyswithvalue/tables/KeysWithValue.sol | 50 +++--- .../tables/CallboundDelegations.sol | 70 ++++----- .../tables/TimeboundDelegations.sol | 56 +++---- .../uniqueentity/tables/UniqueEntity.sol | 44 +++--- packages/world/src/tables/Delegations.sol | 56 +++---- .../world/src/tables/InstalledModules.sol | 56 +++---- packages/world/src/tables/NamespaceOwner.sol | 50 +++--- packages/world/src/tables/ResourceAccess.sol | 56 +++---- packages/world/test/tables/AddressArray.sol | 50 +++--- packages/world/test/tables/Bool.sol | 44 +++--- .../contracts/src/codegen/tables/Counter.sol | 44 +++--- .../contracts/src/codegen/tables/Counter.sol | 44 +++--- .../contracts/src/codegen/tables/Position.sol | 50 +++--- .../contracts/src/codegen/tables/Counter.sol | 44 +++--- 82 files changed, 1474 insertions(+), 1489 deletions(-) create mode 100644 .changeset/small-chicken-repair.md rename packages/cli/contracts/src/codegen/tables/{Ephemeral.sol => Offchain.sol} (58%) delete mode 100644 packages/store/ts/codegen/ephemeral.ts delete mode 100644 packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol diff --git a/.changeset/small-chicken-repair.md b/.changeset/small-chicken-repair.md new file mode 100644 index 0000000000..f41b8e9190 --- /dev/null +++ b/.changeset/small-chicken-repair.md @@ -0,0 +1,20 @@ +--- +"@latticexyz/block-logs-stream": patch +"@latticexyz/cli": patch +"@latticexyz/common": major +"@latticexyz/dev-tools": patch +"@latticexyz/store-sync": patch +"@latticexyz/store": major +"create-mud": minor +--- + +What used to be known as `ephemeral` table is now called `offchain` table. +The previous `ephemeral` tables only supported an `emitEphemeral` method, which emitted a `StoreSetEphemeralRecord` event. + +Now `offchain` tables support all regular table methods, except partial operations on dynamic fields (`push`, `pop`, `update`). +Unlike regular tables they don't store data on-chain but emit the same events as regular tables (`StoreSetRecord`, `StoreSpliceStaticData`, `StoreDeleteRecord`), so their data can be indexed by offchain indexers/clients. + +```diff +- EphemeralTable.emitEphemeral(value); ++ OffchainTable.set(value); +``` diff --git a/docs/pages/store/advanced-features.mdx b/docs/pages/store/advanced-features.mdx index c04efbdaa7..484c2d0020 100644 --- a/docs/pages/store/advanced-features.mdx +++ b/docs/pages/store/advanced-features.mdx @@ -34,9 +34,9 @@ uint256 value = CounterSingleton.get(); Additional documentation on Table library generation can be found in the [`tablegen`](/store/config#store-config--tablegen-tool) section. -### Ephemeral tables +### Offchain tables -Tables with the `ephemeral` property do not write to on-chain storage. +Tables with the `offchainOnly` property do not write to on-chain storage. Instead, they simply emit events when records are set. They are useful for sending data to connected clients without the gas costs associated with a storage write. @@ -52,26 +52,12 @@ export default mudConfig({ amount: "uint32", receiver: "bytes32", }, - ephemeral: true, + offchainOnly: true, }, }, }); ``` -This will slightly change the generated code for the table. The `emitEphemeral` function is the main entrypoint: - -```solidity -import { TradeExecuted, TradeExecutedData } from "./codegen/Tables.sol"; - -// Emitting an ephemeral record -TradeExecuted.emitEphemeral("0x1234", TradeExecutedData({ - amount: 10, - receiver: "0x5678", -})); -``` - -`get`, `set`, and `delete` functions are not generated for ephemeral tables. - ### Storage hooks It is possible to register hooks on tables, allowing additional logic to be executed when records or fields are updated. Use cases include: creating indices on another table (like the `ownerOf` mapping of the ERC-721 spec as an example), emitting events on a different contract, or simply additional access-control and checks by reverting in the hook. diff --git a/docs/pages/world/internals.mdx b/docs/pages/world/internals.mdx index 2205f590d8..4b501e2c19 100644 --- a/docs/pages/world/internals.mdx +++ b/docs/pages/world/internals.mdx @@ -22,7 +22,7 @@ Except `NamespaceOwner` is initialized in World's constructor, because it's need Internal systems are in `core` module's [implementations](https://github.com/latticexyz/mud/tree/main/packages/world/src/modules/core/implementations) folder, because they're installed by `CoreModule`. - `AccessManagementSystem` - grants/revokes access to/from resources -- `EphemeralRecordSystem` - has `emitEphemeralRecord` for ephemeral tables +- `BalanceTransferSystem` - handles balance transfers between namespaces and from namespaces to addresses - `ModuleInstallationSystem` - installation of (non-root) modules in the World - `StoreRegistrationSystem` - _its methods should not be used with the World framework_. Surfaces the APIs necessary to register Tables on-chain, but lacks namespaces used by World for better permission checks - `WorldRegistrationSystem` - surfaces the APIs necessary to register Systems, Tables, and Namespaces on-chain diff --git a/e2e/packages/contracts/src/codegen/tables/Multi.sol b/e2e/packages/contracts/src/codegen/tables/Multi.sol index b3674887f3..56f69dba19 100644 --- a/e2e/packages/contracts/src/codegen/tables/Multi.sol +++ b/e2e/packages/contracts/src/codegen/tables/Multi.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Multi"))) @@ -362,63 +362,63 @@ library Multi { (_table.num, _table.value) = decodeStatic(_staticData); } - /** Tightly pack static data using this table's schema */ - function encodeStatic(int256 num, bool value) internal pure returns (bytes memory) { - return abi.encodePacked(num, value); - } - - /** Tightly pack full data using this table's field layout */ - function encode(int256 num, bool value) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(num, value); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(uint32 a, bool b, uint256 c, int120 d) internal pure returns (bytes32[] memory) { + /** Delete all data for given keys */ + function deleteRecord(uint32 a, bool b, uint256 c, int120 d) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(a)); _keyTuple[1] = _boolToBytes32(b); _keyTuple[2] = bytes32(uint256(c)); _keyTuple[3] = bytes32(uint256(int256(d))); - return _keyTuple; + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ - function deleteRecord(uint32 a, bool b, uint256 c, int120 d) internal { + /** Delete all data for given keys */ + function _deleteRecord(uint32 a, bool b, uint256 c, int120 d) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(a)); _keyTuple[1] = _boolToBytes32(b); _keyTuple[2] = bytes32(uint256(c)); _keyTuple[3] = bytes32(uint256(int256(d))); - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ - function _deleteRecord(uint32 a, bool b, uint256 c, int120 d) internal { + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, uint32 a, bool b, uint256 c, int120 d) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(a)); _keyTuple[1] = _boolToBytes32(b); _keyTuple[2] = bytes32(uint256(c)); _keyTuple[3] = bytes32(uint256(int256(d))); - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, uint32 a, bool b, uint256 c, int120 d) internal { + /** Tightly pack static data using this table's schema */ + function encodeStatic(int256 num, bool value) internal pure returns (bytes memory) { + return abi.encodePacked(num, value); + } + + /** Tightly pack full data using this table's field layout */ + function encode(int256 num, bool value) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(num, value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple(uint32 a, bool b, uint256 c, int120 d) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(a)); _keyTuple[1] = _boolToBytes32(b); _keyTuple[2] = bytes32(uint256(c)); _keyTuple[3] = bytes32(uint256(int256(d))); - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + return _keyTuple; } } diff --git a/e2e/packages/contracts/src/codegen/tables/Number.sol b/e2e/packages/contracts/src/codegen/tables/Number.sol index db8e380f8b..b17b841277 100644 --- a/e2e/packages/contracts/src/codegen/tables/Number.sol +++ b/e2e/packages/contracts/src/codegen/tables/Number.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Number"))) @@ -180,6 +180,30 @@ library Number { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord(uint32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(key)); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(uint32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(key)); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, uint32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(key)); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(uint32 value) internal pure returns (bytes memory) { return abi.encodePacked(value); @@ -202,28 +226,4 @@ library Number { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(uint32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(key)); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(uint32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(key)); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, uint32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(key)); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/e2e/packages/contracts/src/codegen/tables/NumberList.sol b/e2e/packages/contracts/src/codegen/tables/NumberList.sol index 17d4e49daa..1510e27581 100644 --- a/e2e/packages/contracts/src/codegen/tables/NumberList.sol +++ b/e2e/packages/contracts/src/codegen/tables/NumberList.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("NumberList"))) @@ -474,6 +474,27 @@ library NumberList { } } + /** Delete all data for given keys */ + function deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths(uint32[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits @@ -502,25 +523,4 @@ library NumberList { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/e2e/packages/contracts/src/codegen/tables/Vector.sol b/e2e/packages/contracts/src/codegen/tables/Vector.sol index 8fca7ea7bb..cb2ef6792b 100644 --- a/e2e/packages/contracts/src/codegen/tables/Vector.sol +++ b/e2e/packages/contracts/src/codegen/tables/Vector.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Vector"))) @@ -302,6 +302,30 @@ library Vector { (_table.x, _table.y) = decodeStatic(_staticData); } + /** Delete all data for given keys */ + function deleteRecord(uint32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(key)); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(uint32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(key)); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, uint32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(key)); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(int32 x, int32 y) internal pure returns (bytes memory) { return abi.encodePacked(x, y); @@ -324,28 +348,4 @@ library Vector { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(uint32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(key)); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(uint32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(key)); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, uint32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(key)); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/examples/minimal/packages/contracts/mud.config.ts b/examples/minimal/packages/contracts/mud.config.ts index 58cf475496..dfeeaffb52 100644 --- a/examples/minimal/packages/contracts/mud.config.ts +++ b/examples/minimal/packages/contracts/mud.config.ts @@ -26,7 +26,7 @@ export default mudConfig({ valueSchema: { value: "string", }, - ephemeral: true, + offchainOnly: true, }, Inventory: { keySchema: { diff --git a/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol b/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol index fccaf9550e..963e2f4452 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("CounterTable"))) @@ -166,6 +166,27 @@ library CounterTable { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(uint32 value) internal pure returns (bytes memory) { return abi.encodePacked(value); @@ -187,25 +208,4 @@ library CounterTable { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol b/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol index 046b2889d6..d90f9a1343 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Inventory"))) @@ -213,58 +213,58 @@ library Inventory { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((amount)), _fieldLayout); } - /** Tightly pack static data using this table's schema */ - function encodeStatic(uint32 amount) internal pure returns (bytes memory) { - return abi.encodePacked(amount); - } - - /** Tightly pack full data using this table's field layout */ - function encode(uint32 amount) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(amount); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(address owner, uint32 item, uint32 itemVariant) internal pure returns (bytes32[] memory) { + /** Delete all data for given keys */ + function deleteRecord(address owner, uint32 item, uint32 itemVariant) internal { bytes32[] memory _keyTuple = new bytes32[](3); _keyTuple[0] = bytes32(uint256(uint160(owner))); _keyTuple[1] = bytes32(uint256(item)); _keyTuple[2] = bytes32(uint256(itemVariant)); - return _keyTuple; + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ - function deleteRecord(address owner, uint32 item, uint32 itemVariant) internal { + /** Delete all data for given keys */ + function _deleteRecord(address owner, uint32 item, uint32 itemVariant) internal { bytes32[] memory _keyTuple = new bytes32[](3); _keyTuple[0] = bytes32(uint256(uint160(owner))); _keyTuple[1] = bytes32(uint256(item)); _keyTuple[2] = bytes32(uint256(itemVariant)); - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ - function _deleteRecord(address owner, uint32 item, uint32 itemVariant) internal { + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, address owner, uint32 item, uint32 itemVariant) internal { bytes32[] memory _keyTuple = new bytes32[](3); _keyTuple[0] = bytes32(uint256(uint160(owner))); _keyTuple[1] = bytes32(uint256(item)); _keyTuple[2] = bytes32(uint256(itemVariant)); - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, address owner, uint32 item, uint32 itemVariant) internal { + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint32 amount) internal pure returns (bytes memory) { + return abi.encodePacked(amount); + } + + /** Tightly pack full data using this table's field layout */ + function encode(uint32 amount) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(amount); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple(address owner, uint32 item, uint32 itemVariant) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](3); _keyTuple[0] = bytes32(uint256(uint160(owner))); _keyTuple[1] = bytes32(uint256(item)); _keyTuple[2] = bytes32(uint256(itemVariant)); - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + return _keyTuple; } } diff --git a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol index 872bdf5b51..b23dd832b9 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol @@ -18,10 +18,10 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( - bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("MessageTable"))) + bytes32(abi.encodePacked(RESOURCE_OFFCHAIN_TABLE, bytes14(""), bytes16("MessageTable"))) ); ResourceId constant MessageTableTableId = _tableId; @@ -76,37 +76,86 @@ library MessageTable { _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } - /** Emit the ephemeral event using individual values */ - function emitEphemeral(string memory value) internal { + /** Set the full data using individual values */ + function set(string memory value) internal { bytes memory _staticData; PackedCounter _encodedLengths = encodeLengths(value); bytes memory _dynamicData = encodeDynamic(value); bytes32[] memory _keyTuple = new bytes32[](0); - StoreSwitch.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); } - /** Emit the ephemeral event using individual values */ - function _emitEphemeral(string memory value) internal { + /** Set the full data using individual values */ + function _set(string memory value) internal { bytes memory _staticData; PackedCounter _encodedLengths = encodeLengths(value); bytes memory _dynamicData = encodeDynamic(value); bytes32[] memory _keyTuple = new bytes32[](0); - StoreCore.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + StoreCore.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); } - /** Emit the ephemeral event using individual values (using the specified store) */ - function emitEphemeral(IStore _store, string memory value) internal { + /** Set the full data using individual values (using the specified store) */ + function set(IStore _store, string memory value) internal { bytes memory _staticData; PackedCounter _encodedLengths = encodeLengths(value); bytes memory _dynamicData = encodeDynamic(value); bytes32[] memory _keyTuple = new bytes32[](0); - _store.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + } + + /** + * Decode the tightly packed blob of static data using this table's field layout + * Undefined behaviour for invalid blobs + */ + function decodeDynamic( + PackedCounter _encodedLengths, + bytes memory _blob + ) internal pure returns (string memory value) { + uint256 _start; + uint256 _end; + unchecked { + _end = _encodedLengths.atIndex(0); + } + value = (string(SliceLib.getSubslice(_blob, _start, _end).toBytes())); + } + + /** + * Decode the tightly packed blob using this table's field layout. + * Undefined behaviour for invalid blobs. + */ + function decode( + bytes memory, + PackedCounter _encodedLengths, + bytes memory _dynamicData + ) internal pure returns (string memory value) { + (value) = decodeDynamic(_encodedLengths, _dynamicData); + } + + /** Delete all data for given keys */ + function deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /** Tightly pack dynamic data using this table's schema */ diff --git a/examples/minimal/packages/contracts/src/systems/ChatNamespacedSystem.sol b/examples/minimal/packages/contracts/src/systems/ChatNamespacedSystem.sol index 88a5958cbe..3d43d16f07 100644 --- a/examples/minimal/packages/contracts/src/systems/ChatNamespacedSystem.sol +++ b/examples/minimal/packages/contracts/src/systems/ChatNamespacedSystem.sol @@ -6,6 +6,6 @@ import { MessageTable } from "../codegen/index.sol"; // This system is supposed to have a different namespace, but otherwise be identical to ChatSystem contract ChatNamespacedSystem is System { function sendMessage(string memory message) public { - MessageTable.emitEphemeral(message); + MessageTable.set(message); } } diff --git a/examples/minimal/packages/contracts/src/systems/ChatSystem.sol b/examples/minimal/packages/contracts/src/systems/ChatSystem.sol index 6091eb92a9..e359ef4002 100644 --- a/examples/minimal/packages/contracts/src/systems/ChatSystem.sol +++ b/examples/minimal/packages/contracts/src/systems/ChatSystem.sol @@ -5,6 +5,6 @@ import { MessageTable } from "../codegen/index.sol"; contract ChatSystem is System { function sendMessage(string memory message) public { - MessageTable.emitEphemeral(message); + MessageTable.set(message); } } diff --git a/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol b/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol index 10a4675e22..122f2392f2 100644 --- a/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol +++ b/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol @@ -11,11 +11,11 @@ import { MessageTable, MessageTableTableId } from "../src/codegen/index.sol"; import { IChatNamespacedSystem } from "../src/interfaces/IChatNamespacedSystem.sol"; contract ChatNamespacedTest is MudTest { - function testEmitEphemeral() public { + function testOffchain() public { bytes32[] memory keyTuple; string memory value = "test"; vm.expectEmit(true, true, true, true); - emit StoreCore.StoreEphemeralRecord( + emit StoreCore.StoreSetRecord( MessageTableTableId, keyTuple, new bytes(0), diff --git a/packages/block-logs-stream/README.md b/packages/block-logs-stream/README.md index 14691644a6..5dae0a43a9 100644 --- a/packages/block-logs-stream/README.md +++ b/packages/block-logs-stream/README.md @@ -29,7 +29,6 @@ latestBlockNumber$ "event StoreDeleteRecord(bytes32 tableId, bytes32[] keyTuple)", "event StoreSetField(bytes32 tableId, bytes32[] keyTuple, uint8 schemaIndex, bytes data)", "event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes data)", - "event StoreEphemeralRecord(bytes32 tableId, bytes32[] keyTuple, bytes data)", ]), }), mergeMap(({ logs }) => from(groupLogsByBlockNumber(logs))) diff --git a/packages/cli/contracts/src/codegen/index.sol b/packages/cli/contracts/src/codegen/index.sol index de034e0789..49830113c3 100644 --- a/packages/cli/contracts/src/codegen/index.sol +++ b/packages/cli/contracts/src/codegen/index.sol @@ -7,4 +7,4 @@ import { Statics, StaticsData, StaticsTableId } from "./tables/Statics.sol"; import { Dynamics1, Dynamics1Data, Dynamics1TableId } from "./tables/Dynamics1.sol"; import { Dynamics2, Dynamics2Data, Dynamics2TableId } from "./tables/Dynamics2.sol"; import { Singleton, SingletonTableId } from "./tables/Singleton.sol"; -import { Ephemeral, EphemeralTableId } from "./tables/Ephemeral.sol"; +import { Offchain, OffchainTableId } from "./tables/Offchain.sol"; diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol index 76852f049e..3675d141c5 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Dynamics1"))) @@ -1416,6 +1416,30 @@ library Dynamics1 { ); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths( bytes32[1] memory staticB32, @@ -1476,30 +1500,6 @@ library Dynamics1 { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } function toStaticArray_bytes32_1(bytes32[] memory _value) pure returns (bytes32[1] memory _result) { diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol index 5001ff4efb..e233e4e5f3 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Dynamics2"))) @@ -878,6 +878,30 @@ library Dynamics2 { (_table.u64, _table.str, _table.b) = decodeDynamic(_encodedLengths, _dynamicData); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths( uint64[] memory u64, @@ -915,28 +939,4 @@ library Dynamics2 { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/cli/contracts/src/codegen/tables/Ephemeral.sol b/packages/cli/contracts/src/codegen/tables/Offchain.sol similarity index 58% rename from packages/cli/contracts/src/codegen/tables/Ephemeral.sol rename to packages/cli/contracts/src/codegen/tables/Offchain.sol index b2edf7c856..90d628f248 100644 --- a/packages/cli/contracts/src/codegen/tables/Ephemeral.sol +++ b/packages/cli/contracts/src/codegen/tables/Offchain.sol @@ -18,18 +18,18 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( - bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Ephemeral"))) + bytes32(abi.encodePacked(RESOURCE_OFFCHAIN_TABLE, bytes14(""), bytes16("Offchain"))) ); -ResourceId constant EphemeralTableId = _tableId; +ResourceId constant OffchainTableId = _tableId; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010020000000000000000000000000000000000000000000000000000000 ); -library Ephemeral { +library Offchain { /** Get the table values' field layout */ function getFieldLayout() internal pure returns (FieldLayout) { return _fieldLayout; @@ -78,8 +78,32 @@ library Ephemeral { _store.registerTable(_tableId, _fieldLayout, getKeySchema(), getValueSchema(), getKeyNames(), getFieldNames()); } - /** Emit the ephemeral event using individual values */ - function emitEphemeral(bytes32 key, uint256 value) internal { + /** Set value */ + function setValue(bytes32 key, uint256 value) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); + } + + /** Set value */ + function _setValue(bytes32 key, uint256 value) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); + } + + /** Set value (using the specified store) */ + function setValue(IStore _store, bytes32 key, uint256 value) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); + } + + /** Set the full data using individual values */ + function set(bytes32 key, uint256 value) internal { bytes memory _staticData = encodeStatic(value); PackedCounter _encodedLengths; @@ -88,11 +112,11 @@ library Ephemeral { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - StoreSwitch.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); } - /** Emit the ephemeral event using individual values */ - function _emitEphemeral(bytes32 key, uint256 value) internal { + /** Set the full data using individual values */ + function _set(bytes32 key, uint256 value) internal { bytes memory _staticData = encodeStatic(value); PackedCounter _encodedLengths; @@ -101,11 +125,11 @@ library Ephemeral { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - StoreCore.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + StoreCore.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); } - /** Emit the ephemeral event using individual values (using the specified store) */ - function emitEphemeral(IStore _store, bytes32 key, uint256 value) internal { + /** Set the full data using individual values (using the specified store) */ + function set(IStore _store, bytes32 key, uint256 value) internal { bytes memory _staticData = encodeStatic(value); PackedCounter _encodedLengths; @@ -114,7 +138,47 @@ library Ephemeral { bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - _store.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); + } + + /** + * Decode the tightly packed blob of static data using this table's field layout + * Undefined behaviour for invalid blobs + */ + function decodeStatic(bytes memory _blob) internal pure returns (uint256 value) { + value = (uint256(Bytes.slice32(_blob, 0))); + } + + /** + * Decode the tightly packed blob using this table's field layout. + * Undefined behaviour for invalid blobs. + */ + function decode(bytes memory _staticData, PackedCounter, bytes memory) internal pure returns (uint256 value) { + (value) = decodeStatic(_staticData); + } + + /** Delete all data for given keys */ + function deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } /** Tightly pack static data using this table's schema */ diff --git a/packages/cli/contracts/src/codegen/tables/Singleton.sol b/packages/cli/contracts/src/codegen/tables/Singleton.sol index 45d77b5356..f55dc19ff7 100644 --- a/packages/cli/contracts/src/codegen/tables/Singleton.sol +++ b/packages/cli/contracts/src/codegen/tables/Singleton.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Singleton"))) @@ -848,6 +848,27 @@ library Singleton { (v2, v3, v4) = decodeDynamic(_encodedLengths, _dynamicData); } + /** Delete all data for given keys */ + function deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(int256 v1) internal pure returns (bytes memory) { return abi.encodePacked(v1); @@ -900,27 +921,6 @@ library Singleton { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } function toStaticArray_uint32_2(uint32[] memory _value) pure returns (uint32[2] memory _result) { diff --git a/packages/cli/contracts/src/codegen/tables/Statics.sol b/packages/cli/contracts/src/codegen/tables/Statics.sol index 961208a783..dfb0cde25b 100644 --- a/packages/cli/contracts/src/codegen/tables/Statics.sol +++ b/packages/cli/contracts/src/codegen/tables/Statics.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; // Import user types import { Enum2, Enum1 } from "./../common.sol"; @@ -870,6 +870,45 @@ library Statics { (_table.v1, _table.v2, _table.v3, _table.v4, _table.v5, _table.v6) = decodeStatic(_staticData); } + /** Delete all data for given keys */ + function deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal { + bytes32[] memory _keyTuple = new bytes32[](6); + _keyTuple[0] = bytes32(uint256(k1)); + _keyTuple[1] = bytes32(uint256(int256(k2))); + _keyTuple[2] = bytes32(k3); + _keyTuple[3] = bytes32(uint256(uint160(k4))); + _keyTuple[4] = _boolToBytes32(k5); + _keyTuple[5] = bytes32(uint256(uint8(k6))); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal { + bytes32[] memory _keyTuple = new bytes32[](6); + _keyTuple[0] = bytes32(uint256(k1)); + _keyTuple[1] = bytes32(uint256(int256(k2))); + _keyTuple[2] = bytes32(k3); + _keyTuple[3] = bytes32(uint256(uint160(k4))); + _keyTuple[4] = _boolToBytes32(k5); + _keyTuple[5] = bytes32(uint256(uint8(k6))); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal { + bytes32[] memory _keyTuple = new bytes32[](6); + _keyTuple[0] = bytes32(uint256(k1)); + _keyTuple[1] = bytes32(uint256(int256(k2))); + _keyTuple[2] = bytes32(k3); + _keyTuple[3] = bytes32(uint256(uint160(k4))); + _keyTuple[4] = _boolToBytes32(k5); + _keyTuple[5] = bytes32(uint256(uint8(k6))); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic( uint256 v1, @@ -918,45 +957,6 @@ library Statics { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal { - bytes32[] memory _keyTuple = new bytes32[](6); - _keyTuple[0] = bytes32(uint256(k1)); - _keyTuple[1] = bytes32(uint256(int256(k2))); - _keyTuple[2] = bytes32(k3); - _keyTuple[3] = bytes32(uint256(uint160(k4))); - _keyTuple[4] = _boolToBytes32(k5); - _keyTuple[5] = bytes32(uint256(uint8(k6))); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal { - bytes32[] memory _keyTuple = new bytes32[](6); - _keyTuple[0] = bytes32(uint256(k1)); - _keyTuple[1] = bytes32(uint256(int256(k2))); - _keyTuple[2] = bytes32(k3); - _keyTuple[3] = bytes32(uint256(uint160(k4))); - _keyTuple[4] = _boolToBytes32(k5); - _keyTuple[5] = bytes32(uint256(uint8(k6))); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal { - bytes32[] memory _keyTuple = new bytes32[](6); - _keyTuple[0] = bytes32(uint256(k1)); - _keyTuple[1] = bytes32(uint256(int256(k2))); - _keyTuple[2] = bytes32(k3); - _keyTuple[3] = bytes32(uint256(uint160(k4))); - _keyTuple[4] = _boolToBytes32(k5); - _keyTuple[5] = bytes32(uint256(uint8(k6))); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } function _toBool(uint8 value) pure returns (bool result) { diff --git a/packages/cli/contracts/test/Tablegen.t.sol b/packages/cli/contracts/test/Tablegen.t.sol index d5a5cbc77b..8a71d7fb9e 100644 --- a/packages/cli/contracts/test/Tablegen.t.sol +++ b/packages/cli/contracts/test/Tablegen.t.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.0; import "forge-std/Test.sol"; import { StoreMock } from "@latticexyz/store/test/StoreMock.sol"; -import { Statics, StaticsData, Dynamics1, Dynamics1Data, Dynamics2, Dynamics2Data, Singleton, Ephemeral } from "../src/codegen/index.sol"; +import { Statics, StaticsData, Dynamics1, Dynamics1Data, Dynamics2, Dynamics2Data, Singleton, Offchain } from "../src/codegen/index.sol"; import { Enum1, Enum2 } from "../src/codegen/common.sol"; @@ -143,9 +143,9 @@ contract TablegenTest is Test, StoreMock { assertEq(Singleton.getItemV4(1), 0); } - function testEphemeral() public { - Ephemeral.register(); + function testOffchain() public { + Offchain.register(); - Ephemeral.emitEphemeral("key", 123); + Offchain.set("key", 123); } } diff --git a/packages/cli/scripts/generate-test-tables.ts b/packages/cli/scripts/generate-test-tables.ts index 74ecec0817..79d9430437 100644 --- a/packages/cli/scripts/generate-test-tables.ts +++ b/packages/cli/scripts/generate-test-tables.ts @@ -55,9 +55,9 @@ try { }, dataStruct: false, }, - Ephemeral: { + Offchain: { valueSchema: "uint256", - ephemeral: true, + offchainOnly: true, }, }, diff --git a/packages/cli/src/utils/tables/getRegisterTableCallData.ts b/packages/cli/src/utils/tables/getRegisterTableCallData.ts index 8db6cc0c43..218e89e05d 100644 --- a/packages/cli/src/utils/tables/getRegisterTableCallData.ts +++ b/packages/cli/src/utils/tables/getRegisterTableCallData.ts @@ -30,7 +30,7 @@ export function getRegisterTableCallData(table: Table, storeConfig: StoreConfig) func: "registerTable", args: [ // TODO: add support for table namespaces (https://github.com/latticexyz/mud/issues/994) - resourceIdToHex({ type: table.ephemeral ? "offchainTable" : "table", namespace: storeConfig.namespace, name }), + resourceIdToHex({ type: table.offchainOnly ? "offchainTable" : "table", namespace: storeConfig.namespace, name }), fieldLayoutToHex(fieldLayout), encodeSchema(keyTypes), encodeSchema(schemaTypes), diff --git a/packages/cli/src/utils/tables/types.ts b/packages/cli/src/utils/tables/types.ts index 2fbe66339e..21dcd8438c 100644 --- a/packages/cli/src/utils/tables/types.ts +++ b/packages/cli/src/utils/tables/types.ts @@ -4,7 +4,7 @@ export type Table = { directory: string; tableIdArgument: boolean; storeArgument: boolean; - ephemeral: boolean; + offchainOnly: boolean; name?: string | undefined; dataStruct?: boolean | undefined; }; diff --git a/packages/common/src/codegen/render-solidity/common.ts b/packages/common/src/codegen/render-solidity/common.ts index c88829706e..f956f7b658 100644 --- a/packages/common/src/codegen/render-solidity/common.ts +++ b/packages/common/src/codegen/render-solidity/common.ts @@ -162,15 +162,25 @@ export function renderWithFieldSuffix( return result; } -export function renderTableId(staticResourceData: StaticResourceData): { +export function renderTableId({ namespace, name, offchainOnly, tableIdName }: StaticResourceData): { hardcodedTableId: string; tableIdDefinition: string; } { - const hardcodedTableId = `ResourceId.wrap(bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("${staticResourceData.namespace}"), bytes16("${staticResourceData.name}"))))`; + const hardcodedTableId = ` + ResourceId.wrap( + bytes32( + abi.encodePacked( + ${offchainOnly ? "RESOURCE_OFFCHAIN_TABLE" : "RESOURCE_TABLE"}, + bytes14("${namespace}"), + bytes16("${name}") + ) + ) + ) + `; const tableIdDefinition = ` ResourceId constant _tableId = ${hardcodedTableId}; - ResourceId constant ${staticResourceData.tableIdName} = _tableId; + ResourceId constant ${tableIdName} = _tableId; `; return { hardcodedTableId, diff --git a/packages/common/src/codegen/render-solidity/types.ts b/packages/common/src/codegen/render-solidity/types.ts index cb65df5e02..833065e207 100644 --- a/packages/common/src/codegen/render-solidity/types.ts +++ b/packages/common/src/codegen/render-solidity/types.ts @@ -16,6 +16,7 @@ export interface StaticResourceData { tableIdName: string; namespace: string; name: string; + offchainOnly: boolean; } export interface RenderType { diff --git a/packages/dev-tools/src/events/EventIcon.tsx b/packages/dev-tools/src/events/EventIcon.tsx index 8b40c01690..2efbcb0d23 100644 --- a/packages/dev-tools/src/events/EventIcon.tsx +++ b/packages/dev-tools/src/events/EventIcon.tsx @@ -14,8 +14,6 @@ export function EventIcon({ type }: Props) { return +; case "StoreDeleteRecord": return -; - case "StoreEphemeralRecord": - return ~; default: return assertExhaustive(type, `Unexpected event type: ${type}`); } diff --git a/packages/dev-tools/src/events/LogsTable.tsx b/packages/dev-tools/src/events/LogsTable.tsx index 5c720f1a62..b24495a4ef 100644 --- a/packages/dev-tools/src/events/LogsTable.tsx +++ b/packages/dev-tools/src/events/LogsTable.tsx @@ -44,7 +44,7 @@ export function LogsTable({ logs }: Props) { {/* TODO: decode these values if we can */} - {log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord" + {log.eventName === "StoreSetRecord" ? JSON.stringify({ staticData: log.args.staticData, encodedLengths: log.args.encodedLengths, diff --git a/packages/store-sync/src/common.ts b/packages/store-sync/src/common.ts index c45687cca8..41caa5d2f9 100644 --- a/packages/store-sync/src/common.ts +++ b/packages/store-sync/src/common.ts @@ -78,7 +78,7 @@ export type StorageAdapter = (block: StorageAdapterBlock) => Promise; // TODO: adjust when we get namespace support (https://github.com/latticexyz/mud/issues/994) and when table has namespace key (https://github.com/latticexyz/mud/issues/1201) export const schemasTable = storeConfig.tables.Tables; export const schemasTableId = resourceIdToHex({ - type: schemasTable.ephemeral ? "offchainTable" : "table", + type: schemasTable.offchainOnly ? "offchainTable" : "table", namespace: storeConfig.namespace, name: schemasTable.name, }); diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index 4246c037cc..5b714d096c 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -96,7 +96,7 @@ export async function postgresStorage debug(log.eventName, log); - if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { + if (log.eventName === "StoreSetRecord") { const value = decodeValueArgs(table.valueSchema, log.args); debug("upserting record", { namespace: table.namespace, diff --git a/packages/store-sync/src/recs/configToRecsComponents.ts b/packages/store-sync/src/recs/configToRecsComponents.ts index de52d113b8..0e83de5a8b 100644 --- a/packages/store-sync/src/recs/configToRecsComponents.ts +++ b/packages/store-sync/src/recs/configToRecsComponents.ts @@ -28,7 +28,7 @@ export function configToRecsComponents( { // TODO: support table namespaces https://github.com/latticexyz/mud/issues/994 id: resourceIdToHex({ - type: table.ephemeral ? "offchainTable" : "table", + type: table.offchainOnly ? "offchainTable" : "table", namespace: config.namespace, name: tableName, }), diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index ce351803f7..5275ec0a58 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -80,7 +80,7 @@ export function recsStorage({ const entity = hexKeyTupleToEntity(log.args.keyTuple); - if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { + if (log.eventName === "StoreSetRecord") { const value = decodeValueArgs(table.valueSchema, log.args); debug("setting component", { namespace: table.namespace, diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 180048279e..c0e78bcdc9 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -96,7 +96,7 @@ export async function sqliteStorage({ const uniqueKey = concatHex(log.args.keyTuple as Hex[]); const key = decodeKey(table.keySchema, log.args.keyTuple); - if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { + if (log.eventName === "StoreSetRecord") { const value = decodeValueArgs(table.valueSchema, log.args); debug("upserting record", { namespace: table.namespace, diff --git a/packages/store/gas-report.json b/packages/store/gas-report.json index 6f8ba5f968..3c65f6ecb2 100644 --- a/packages/store/gas-report.json +++ b/packages/store/gas-report.json @@ -351,7 +351,7 @@ "file": "test/KeyEncoding.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "register KeyEncoding table", - "gasUsed": 720082 + "gasUsed": 720118 }, { "file": "test/Mixed.t.sol", @@ -363,13 +363,13 @@ "file": "test/Mixed.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "register Mixed table", - "gasUsed": 581907 + "gasUsed": 581944 }, { "file": "test/Mixed.t.sol", "test": "testSetAndGet", "name": "set record in Mixed", - "gasUsed": 103942 + "gasUsed": 103976 }, { "file": "test/Mixed.t.sol", @@ -621,25 +621,25 @@ "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (cold, 1 slot, 1 uint32 item)", - "gasUsed": 19440 + "gasUsed": 19449 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (warm, 1 slot, 1 uint32 item)", - "gasUsed": 13450 + "gasUsed": 13457 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (cold, 2 slots, 10 uint32 items)", - "gasUsed": 17208 + "gasUsed": 17217 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (warm, 2 slots, 10 uint32 items)", - "gasUsed": 13219 + "gasUsed": 13225 }, { "file": "test/StoreCoreGas.t.sol", @@ -675,7 +675,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testDeleteData", "name": "delete record (complex data, 3 slots)", - "gasUsed": 6700 + "gasUsed": 6735 }, { "file": "test/StoreCoreGas.t.sol", @@ -693,67 +693,67 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "register subscriber", - "gasUsed": 58696 + "gasUsed": 58766 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set record on table with subscriber", - "gasUsed": 71265 + "gasUsed": 71311 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set static field on table with subscriber", - "gasUsed": 20746 + "gasUsed": 20788 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "delete record on table with subscriber", - "gasUsed": 16736 + "gasUsed": 16784 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "register subscriber", - "gasUsed": 58696 + "gasUsed": 58766 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) record on table with subscriber", - "gasUsed": 164386 + "gasUsed": 164432 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) field on table with subscriber", - "gasUsed": 24513 + "gasUsed": 24552 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "delete (dynamic) record on table with subscriber", - "gasUsed": 17721 + "gasUsed": 17769 }, { "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (1 slot, 1 uint32 item)", - "gasUsed": 10264 + "gasUsed": 10260 }, { "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (2 slots, 10 uint32 items)", - "gasUsed": 32940 + "gasUsed": 32930 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "StoreCore: register table", - "gasUsed": 642028 + "gasUsed": 642065 }, { "file": "test/StoreCoreGas.t.sol", @@ -777,7 +777,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetDynamicData", "name": "set complex record with dynamic data (4 slots)", - "gasUsed": 101840 + "gasUsed": 101874 }, { "file": "test/StoreCoreGas.t.sol", @@ -819,7 +819,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set static field (1 slot)", - "gasUsed": 31601 + "gasUsed": 31604 }, { "file": "test/StoreCoreGas.t.sol", @@ -831,7 +831,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set static field (overlap 2 slot)", - "gasUsed": 30241 + "gasUsed": 30245 }, { "file": "test/StoreCoreGas.t.sol", @@ -843,7 +843,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set dynamic field (1 slot, first dynamic field)", - "gasUsed": 53966 + "gasUsed": 53959 }, { "file": "test/StoreCoreGas.t.sol", @@ -855,7 +855,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set dynamic field (1 slot, second dynamic field)", - "gasUsed": 32192 + "gasUsed": 32182 }, { "file": "test/StoreCoreGas.t.sol", @@ -867,7 +867,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetStaticData", "name": "set static record (1 slot)", - "gasUsed": 32145 + "gasUsed": 32179 }, { "file": "test/StoreCoreGas.t.sol", @@ -879,7 +879,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetStaticDataSpanningWords", "name": "set static record (2 slots)", - "gasUsed": 54650 + "gasUsed": 54684 }, { "file": "test/StoreCoreGas.t.sol", @@ -891,13 +891,13 @@ "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "update in field (1 slot, 1 uint32 item)", - "gasUsed": 9608 + "gasUsed": 9604 }, { "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "push to field (2 slots, 6 uint64 items)", - "gasUsed": 10045 + "gasUsed": 10043 }, { "file": "test/StoreHook.t.sol", @@ -939,7 +939,7 @@ "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: set field", - "gasUsed": 57052 + "gasUsed": 57051 }, { "file": "test/tables/Callbacks.t.sol", @@ -951,19 +951,19 @@ "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: push 1 element", - "gasUsed": 33337 + "gasUsed": 33332 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testOneSlot", "name": "StoreHooks: set field with one elements (cold)", - "gasUsed": 59054 + "gasUsed": 59057 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: set field (cold)", - "gasUsed": 59054 + "gasUsed": 59057 }, { "file": "test/tables/StoreHooks.t.sol", @@ -975,37 +975,37 @@ "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: push 1 element (cold)", - "gasUsed": 13431 + "gasUsed": 13430 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: pop 1 element (warm)", - "gasUsed": 10739 + "gasUsed": 10743 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: push 1 element (warm)", - "gasUsed": 11453 + "gasUsed": 11447 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: update 1 element (warm)", - "gasUsed": 30668 + "gasUsed": 30659 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: delete record (warm)", - "gasUsed": 7128 + "gasUsed": 7163 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: set field (warm)", - "gasUsed": 31215 + "gasUsed": 31201 }, { "file": "test/tables/StoreHooks.t.sol", @@ -1023,7 +1023,7 @@ "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testDelete", "name": "StoreHooks: delete record (cold)", - "gasUsed": 15996 + "gasUsed": 16031 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", @@ -1047,13 +1047,13 @@ "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testPop", "name": "StoreHooks: pop 1 element (cold)", - "gasUsed": 19168 + "gasUsed": 19178 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testUpdate", "name": "StoreHooks: update 1 element (cold)", - "gasUsed": 21111 + "gasUsed": 21114 }, { "file": "test/tightcoder/DecodeSlice.t.sol", @@ -1107,13 +1107,13 @@ "file": "test/Vector2.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "register Vector2 field layout", - "gasUsed": 443350 + "gasUsed": 443387 }, { "file": "test/Vector2.t.sol", "test": "testSetAndGet", "name": "set Vector2 record", - "gasUsed": 33069 + "gasUsed": 33103 }, { "file": "test/Vector2.t.sol", diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index f73f4f4c46..cae2ec6f36 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -179,26 +179,6 @@ interface IStoreWrite { function deleteRecord(ResourceId tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) external; } -interface IStoreEphemeral { - event StoreEphemeralRecord( - ResourceId indexed tableId, - bytes32[] keyTuple, - bytes staticData, - bytes32 encodedLengths, - bytes dynamicData - ); - - // Emit the ephemeral event without modifying storage - function emitEphemeralRecord( - ResourceId tableId, - bytes32[] calldata keyTuple, - bytes calldata staticData, - PackedCounter encodedLengths, - bytes calldata dynamicData, - FieldLayout fieldLayout - ) external; -} - /** * The IStoreData interface includes methods for reading and writing table values. * These methods are frequently invoked during runtime, so it is essential to prioritize @@ -230,4 +210,4 @@ interface IStoreRegistration { function unregisterStoreHook(ResourceId tableId, IStoreHook hookAddress) external; } -interface IStore is IStoreData, IStoreRegistration, IStoreEphemeral, IStoreErrors {} +interface IStore is IStoreData, IStoreRegistration, IStoreErrors {} diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index d4683aaa10..f5baaa3546 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -50,13 +50,6 @@ library StoreCore { bytes32 encodedLengths ); event StoreDeleteRecord(ResourceId indexed tableId, bytes32[] keyTuple); - event StoreEphemeralRecord( - ResourceId indexed tableId, - bytes32[] keyTuple, - bytes staticData, - bytes32 encodedLengths, - bytes dynamicData - ); /** * Intialize the store address to use in StoreSwitch. @@ -187,6 +180,11 @@ library StoreCore { * Register hooks to be called when a record or field is set or deleted */ function registerStoreHook(ResourceId tableId, IStoreHook hookAddress, uint8 enabledHooksBitmap) internal { + // Hooks are only supported for tables, not for offchain tables + if (tableId.getType() != RESOURCE_TABLE) { + revert IStoreErrors.StoreCore_InvalidResourceType(RESOURCE_TABLE, tableId, string(abi.encodePacked(tableId))); + } + StoreHooks.push(ResourceId.unwrap(tableId), Hook.unwrap(HookLib.encode(address(hookAddress), enabledHooksBitmap))); } @@ -223,6 +221,11 @@ library StoreCore { // Emit event to notify indexers emit StoreSetRecord(tableId, keyTuple, staticData, encodedLengths.unwrap(), dynamicData); + // Early return if the table is an offchain table + if (tableId.getType() != RESOURCE_TABLE) { + return; + } + // Call onBeforeSetRecord hooks (before actually modifying the state, so observers have access to the previous state if needed) bytes21[] memory hooks = StoreHooks._get(ResourceId.unwrap(tableId)); for (uint256 i; i < hooks.length; i++) { @@ -302,6 +305,20 @@ library StoreCore { ) internal { uint256 location = StoreCoreInternal._getStaticDataLocation(tableId, keyTuple); + // Emit event to notify offchain indexers + emit StoreCore.StoreSpliceStaticData({ + tableId: tableId, + keyTuple: keyTuple, + start: start, + deleteCount: deleteCount, + data: data + }); + + // Early return if the table is an offchain table + if (tableId.getType() != RESOURCE_TABLE) { + return; + } + // Call onBeforeSpliceStaticData hooks (before actually modifying the state, so observers have access to the previous state if needed) bytes21[] memory hooks = StoreHooks._get(ResourceId.unwrap(tableId)); for (uint256 i; i < hooks.length; i++) { @@ -333,15 +350,6 @@ library StoreCore { }); } } - - // Emit event to notify offchain indexers - emit StoreCore.StoreSpliceStaticData({ - tableId: tableId, - keyTuple: keyTuple, - start: start, - deleteCount: deleteCount, - data: data - }); } function spliceDynamicData( @@ -424,6 +432,11 @@ library StoreCore { // Emit event to notify indexers emit StoreDeleteRecord(tableId, keyTuple); + // Early return if the table is an offchain table + if (tableId.getType() != RESOURCE_TABLE) { + return; + } + // Call onBeforeDeleteRecord hooks (before actually modifying the state, so observers have access to the previous state if needed) bytes21[] memory hooks = StoreHooks._get(ResourceId.unwrap(tableId)); for (uint256 i; i < hooks.length; i++) { @@ -510,30 +523,6 @@ library StoreCore { StoreCoreInternal._setDynamicFieldItem(tableId, keyTuple, fieldLayout, fieldIndex, startByteIndex, dataToSet); } - /************************************************************************ - * - * EPHEMERAL SET DATA - * - ************************************************************************/ - - /** - * Emit the ephemeral event without modifying storage for the full data of the given table ID and key tuple - */ - function emitEphemeralRecord( - ResourceId tableId, - bytes32[] memory keyTuple, - bytes memory staticData, - PackedCounter encodedLengths, - bytes memory dynamicData, - FieldLayout fieldLayout - ) internal { - // Verify static data length + dynamic data length matches the given data - StoreCoreInternal._validateDataLength(fieldLayout, staticData, encodedLengths, dynamicData); - - // Emit event to notify indexers - emit StoreEphemeralRecord(tableId, keyTuple, staticData, encodedLengths.unwrap(), dynamicData); - } - /************************************************************************ * * GET DATA @@ -674,6 +663,8 @@ library StoreCore { } library StoreCoreInternal { + using ResourceIdInstance for ResourceId; + bytes32 internal constant SLOT = keccak256("mud.store"); bytes32 internal constant DYNMAIC_DATA_SLOT = keccak256("mud.store.dynamicData"); bytes32 internal constant DYNAMIC_DATA_LENGTH_SLOT = keccak256("mud.store.dynamicDataLength"); @@ -693,6 +684,12 @@ library StoreCoreInternal { bytes memory data, PackedCounter previousEncodedLengths ) internal { + // Splicing dynamic data is not supported for offchain tables, because it + // requires reading the previous encoded lengths from storage + if (tableId.getType() != RESOURCE_TABLE) { + revert IStoreErrors.StoreCore_InvalidResourceType(RESOURCE_TABLE, tableId, string(abi.encodePacked(tableId))); + } + uint256 previousFieldLength = previousEncodedLengths.atIndex(dynamicFieldIndex); uint256 updatedFieldLength = previousFieldLength - deleteCount + data.length; @@ -714,6 +711,16 @@ library StoreCoreInternal { // Update the encoded length PackedCounter updatedEncodedLengths = previousEncodedLengths.setAtIndex(dynamicFieldIndex, updatedFieldLength); + // Emit event to notify offchain indexers + emit StoreCore.StoreSpliceDynamicData({ + tableId: tableId, + keyTuple: keyTuple, + start: uint48(start), + deleteCount: deleteCount, + data: data, + encodedLengths: updatedEncodedLengths.unwrap() + }); + // Call onBeforeSpliceDynamicData hooks (before actually modifying the state, so observers have access to the previous state if needed) bytes21[] memory hooks = StoreHooks._get(ResourceId.unwrap(tableId)); for (uint256 i; i < hooks.length; i++) { @@ -758,16 +765,6 @@ library StoreCoreInternal { }); } } - - // Emit event to notify offchain indexers - emit StoreCore.StoreSpliceDynamicData({ - tableId: tableId, - keyTuple: keyTuple, - start: uint48(start), - deleteCount: deleteCount, - data: data, - encodedLengths: updatedEncodedLengths.unwrap() - }); } function _pushToDynamicField( diff --git a/packages/store/src/StoreSwitch.sol b/packages/store/src/StoreSwitch.sol index caa043ebfe..ba483f2dea 100644 --- a/packages/store/src/StoreSwitch.sol +++ b/packages/store/src/StoreSwitch.sol @@ -234,29 +234,6 @@ library StoreSwitch { } } - function emitEphemeralRecord( - ResourceId tableId, - bytes32[] memory keyTuple, - bytes memory staticData, - PackedCounter encodedLengths, - bytes memory dynamicData, - FieldLayout fieldLayout - ) internal { - address _storeAddress = getStoreAddress(); - if (_storeAddress == address(this)) { - StoreCore.emitEphemeralRecord(tableId, keyTuple, staticData, encodedLengths, dynamicData, fieldLayout); - } else { - IStore(_storeAddress).emitEphemeralRecord( - tableId, - keyTuple, - staticData, - encodedLengths, - dynamicData, - fieldLayout - ); - } - } - function getRecord( ResourceId tableId, bytes32[] memory keyTuple, diff --git a/packages/store/src/codegen/tables/Callbacks.sol b/packages/store/src/codegen/tables/Callbacks.sol index e7c1e00837..4dcbce5052 100644 --- a/packages/store/src/codegen/tables/Callbacks.sol +++ b/packages/store/src/codegen/tables/Callbacks.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; import { ResourceId } from "../../ResourceId.sol"; -import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "../../storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("Callbacks"))) @@ -532,6 +532,30 @@ library Callbacks { } } + /** Delete all data for given keys */ + function deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths(bytes24[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits @@ -561,28 +585,4 @@ library Callbacks { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/store/src/codegen/tables/Hooks.sol b/packages/store/src/codegen/tables/Hooks.sol index ed26828797..34f6c804cf 100644 --- a/packages/store/src/codegen/tables/Hooks.sol +++ b/packages/store/src/codegen/tables/Hooks.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; import { ResourceId } from "../../ResourceId.sol"; -import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "../../storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 @@ -532,6 +532,30 @@ library Hooks { } } + /** Delete all data for given keys */ + function deleteRecord(ResourceId _tableId, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(ResourceId _tableId, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, ResourceId _tableId, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths(bytes21[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits @@ -561,28 +585,4 @@ library Hooks { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(ResourceId _tableId, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(ResourceId _tableId, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, ResourceId _tableId, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/store/src/codegen/tables/KeyEncoding.sol b/packages/store/src/codegen/tables/KeyEncoding.sol index 4f5afd260d..6a198c2d27 100644 --- a/packages/store/src/codegen/tables/KeyEncoding.sol +++ b/packages/store/src/codegen/tables/KeyEncoding.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; import { ResourceId } from "../../ResourceId.sol"; -import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "../../storeResourceTypes.sol"; // Import user types import { ExampleEnum } from "./../common.sol"; @@ -315,30 +315,8 @@ library KeyEncoding { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } - /** Tightly pack static data using this table's schema */ - function encodeStatic(bool value) internal pure returns (bytes memory) { - return abi.encodePacked(value); - } - - /** Tightly pack full data using this table's field layout */ - function encode(bool value) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(value); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple( - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - ExampleEnum k6 - ) internal pure returns (bytes32[] memory) { + /** Delete all data for given keys */ + function deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, ExampleEnum k6) internal { bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); @@ -347,11 +325,11 @@ library KeyEncoding { _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - return _keyTuple; + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ - function deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, ExampleEnum k6) internal { + /** Delete all data for given keys */ + function _deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, ExampleEnum k6) internal { bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); @@ -360,11 +338,11 @@ library KeyEncoding { _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ - function _deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, ExampleEnum k6) internal { + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, ExampleEnum k6) internal { bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); @@ -373,11 +351,33 @@ library KeyEncoding { _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, ExampleEnum k6) internal { + /** Tightly pack static data using this table's schema */ + function encodeStatic(bool value) internal pure returns (bytes memory) { + return abi.encodePacked(value); + } + + /** Tightly pack full data using this table's field layout */ + function encode(bool value) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple( + uint256 k1, + int32 k2, + bytes16 k3, + address k4, + bool k5, + ExampleEnum k6 + ) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); @@ -386,7 +386,7 @@ library KeyEncoding { _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + return _keyTuple; } } diff --git a/packages/store/src/codegen/tables/Mixed.sol b/packages/store/src/codegen/tables/Mixed.sol index 995a84f49c..48c8678ba9 100644 --- a/packages/store/src/codegen/tables/Mixed.sol +++ b/packages/store/src/codegen/tables/Mixed.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; import { ResourceId } from "../../ResourceId.sol"; -import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "../../storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("Mixed"))) @@ -772,6 +772,30 @@ library Mixed { (_table.a32, _table.s) = decodeDynamic(_encodedLengths, _dynamicData); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(uint32 u32, uint128 u128) internal pure returns (bytes memory) { return abi.encodePacked(u32, u128); @@ -812,28 +836,4 @@ library Mixed { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/store/src/codegen/tables/ResourceIds.sol b/packages/store/src/codegen/tables/ResourceIds.sol index 229d236416..273a4c6fb0 100644 --- a/packages/store/src/codegen/tables/ResourceIds.sol +++ b/packages/store/src/codegen/tables/ResourceIds.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; import { ResourceId } from "../../ResourceId.sol"; -import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "../../storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("ResourceIds"))) @@ -180,6 +180,30 @@ library ResourceIds { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((exists)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 resourceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 resourceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 resourceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = resourceId; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(bool exists) internal pure returns (bytes memory) { return abi.encodePacked(exists); @@ -202,30 +226,6 @@ library ResourceIds { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 resourceId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceId; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 resourceId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceId; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 resourceId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = resourceId; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } function _toBool(uint8 value) pure returns (bool result) { diff --git a/packages/store/src/codegen/tables/StoreHooks.sol b/packages/store/src/codegen/tables/StoreHooks.sol index bba07c02cd..b900ad3640 100644 --- a/packages/store/src/codegen/tables/StoreHooks.sol +++ b/packages/store/src/codegen/tables/StoreHooks.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; import { ResourceId } from "../../ResourceId.sol"; -import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "../../storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("StoreHooks"))) @@ -532,6 +532,30 @@ library StoreHooks { } } + /** Delete all data for given keys */ + function deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths(bytes21[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits @@ -561,28 +585,4 @@ library StoreHooks { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/store/src/codegen/tables/Tables.sol b/packages/store/src/codegen/tables/Tables.sol index 3e4c7b0724..04d49cd786 100644 --- a/packages/store/src/codegen/tables/Tables.sol +++ b/packages/store/src/codegen/tables/Tables.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; import { ResourceId } from "../../ResourceId.sol"; -import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "../../storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("Tables"))) @@ -888,6 +888,30 @@ library Tables { (_table.abiEncodedKeyNames, _table.abiEncodedFieldNames) = decodeDynamic(_encodedLengths, _dynamicData); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 tableId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = tableId; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 tableId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = tableId; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 tableId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = tableId; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic( bytes32 fieldLayout, @@ -939,28 +963,4 @@ library Tables { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 tableId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = tableId; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 tableId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = tableId; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 tableId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = tableId; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/store/src/codegen/tables/Vector2.sol b/packages/store/src/codegen/tables/Vector2.sol index cb95a745ea..71f23b8be2 100644 --- a/packages/store/src/codegen/tables/Vector2.sol +++ b/packages/store/src/codegen/tables/Vector2.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "../../FieldLayout.sol"; import { Schema, SchemaLib } from "../../Schema.sol"; import { PackedCounter, PackedCounterLib } from "../../PackedCounter.sol"; import { ResourceId } from "../../ResourceId.sol"; -import { RESOURCE_TABLE } from "../../storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "../../storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14("mudstore"), bytes16("Vector2"))) @@ -302,6 +302,30 @@ library Vector2 { (_table.x, _table.y) = decodeStatic(_staticData); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(uint32 x, uint32 y) internal pure returns (bytes memory) { return abi.encodePacked(x, y); @@ -324,28 +348,4 @@ library Vector2 { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/store/test/StoreMock.sol b/packages/store/test/StoreMock.sol index 14eb95c89b..fab796a8f1 100644 --- a/packages/store/test/StoreMock.sol +++ b/packages/store/test/StoreMock.sol @@ -103,18 +103,6 @@ contract StoreMock is IStore, StoreRead { StoreCore.deleteRecord(tableId, keyTuple, fieldLayout); } - // Emit the ephemeral event without modifying storage - function emitEphemeralRecord( - ResourceId tableId, - bytes32[] calldata keyTuple, - bytes calldata staticData, - PackedCounter encodedLengths, - bytes calldata dynamicData, - FieldLayout fieldLayout - ) public { - StoreCore.emitEphemeralRecord(tableId, keyTuple, staticData, encodedLengths, dynamicData, fieldLayout); - } - function registerTable( ResourceId tableId, FieldLayout fieldLayout, diff --git a/packages/store/ts/codegen/ephemeral.ts b/packages/store/ts/codegen/ephemeral.ts deleted file mode 100644 index df57892d8a..0000000000 --- a/packages/store/ts/codegen/ephemeral.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { renderArguments, renderCommonData, renderWithStore } from "@latticexyz/common/codegen"; -import { RenderTableOptions } from "./types"; -import { renderRecordData } from "./record"; - -export function renderEphemeralMethods(options: RenderTableOptions) { - const { structName, storeArgument } = options; - const { _tableId, _typedTableId, _keyArgs, _typedKeyArgs, _keyTupleDefinition } = renderCommonData(options); - - let result = renderWithStore( - storeArgument, - (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` - /** Emit the ephemeral event using individual values${_commentSuffix} */ - function ${_methodNamePrefix}emitEphemeral(${renderArguments([ - _typedStore, - _typedTableId, - _typedKeyArgs, - renderArguments(options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)), - ])}) internal { - ${renderRecordData(options)} - - ${_keyTupleDefinition} - - ${_store}.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, _fieldLayout); - } - ` - ); - - if (structName !== undefined) { - result += renderWithStore( - storeArgument, - (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` - /** Emit the ephemeral event using the data struct${_commentSuffix} */ - function ${_methodNamePrefix}emitEphemeral(${renderArguments([ - _typedStore, - _typedTableId, - _typedKeyArgs, - `${structName} memory _table`, - ])}) internal { - emitEphemeral(${renderArguments([ - _untypedStore, - _tableId, - _keyArgs, - renderArguments(options.fields.map(({ name }) => `_table.${name}`)), - ])}); - } - ` - ); - } - - return result; -} diff --git a/packages/store/ts/codegen/field.ts b/packages/store/ts/codegen/field.ts index c65307e2f7..6fad585ca1 100644 --- a/packages/store/ts/codegen/field.ts +++ b/packages/store/ts/codegen/field.ts @@ -14,40 +14,45 @@ export function renderFieldMethods(options: RenderTableOptions) { let result = ""; for (const [schemaIndex, field] of options.fields.entries()) { - // For dynamic fields, compute the field index relative to the end of the static fields + if (!options.withDynamicFieldMethods && field.isDynamic) { + continue; + } + // For dynamic fields, compute the field index relative to the end of the static fields const _typedFieldName = `${field.typeWithLocation} ${field.name}`; - result += renderWithFieldSuffix(options.withSuffixlessFieldMethods, field.name, (_methodNameSuffix) => - renderWithStore( - storeArgument, - (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` - /** Get ${field.name}${_commentSuffix} */ - function ${_methodNamePrefix}get${_methodNameSuffix}(${renderArguments([ - _typedStore, - _typedTableId, - _typedKeyArgs, - ])}) internal view returns (${_typedFieldName}) { - ${_keyTupleDefinition} - ${ - field.isDynamic - ? `bytes memory _blob = ${_store}.getDynamicField( - _tableId, - _keyTuple, - ${schemaIndex - options.staticFields.length} - );` - : `bytes32 _blob = ${_store}.getStaticField( - _tableId, - _keyTuple, - ${schemaIndex}, - _fieldLayout - );` + if (options.withGetters) { + result += renderWithFieldSuffix(options.withSuffixlessFieldMethods, field.name, (_methodNameSuffix) => + renderWithStore( + storeArgument, + (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` + /** Get ${field.name}${_commentSuffix} */ + function ${_methodNamePrefix}get${_methodNameSuffix}(${renderArguments([ + _typedStore, + _typedTableId, + _typedKeyArgs, + ])}) internal view returns (${_typedFieldName}) { + ${_keyTupleDefinition} + ${ + field.isDynamic + ? `bytes memory _blob = ${_store}.getDynamicField( + _tableId, + _keyTuple, + ${schemaIndex - options.staticFields.length} + );` + : `bytes32 _blob = ${_store}.getStaticField( + _tableId, + _keyTuple, + ${schemaIndex}, + _fieldLayout + );` + } + return ${renderDecodeFieldSingle(field)}; } - return ${renderDecodeFieldSingle(field)}; - } ` - ) - ); + ) + ); + } result += renderWithFieldSuffix(options.withSuffixlessFieldMethods, field.name, (_methodNameSuffix) => renderWithStore( @@ -70,40 +75,41 @@ export function renderFieldMethods(options: RenderTableOptions) { if (field.isDynamic) { const portionData = fieldPortionData(field); - result += renderWithFieldSuffix(options.withSuffixlessFieldMethods, field.name, (_methodNameSuffix) => - renderWithStore( - storeArgument, - (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` - /** Get the length of ${field.name}${_commentSuffix} */ - function ${_methodNamePrefix}length${_methodNameSuffix}(${renderArguments([ - _typedStore, - _typedTableId, - _typedKeyArgs, - ])}) internal view returns (uint256) { - ${_keyTupleDefinition} - uint256 _byteLength = ${_store}.getFieldLength(_tableId, _keyTuple, ${schemaIndex}, _fieldLayout); - unchecked { - return _byteLength / ${portionData.elementLength}; + if (options.withGetters) { + result += renderWithFieldSuffix(options.withSuffixlessFieldMethods, field.name, (_methodNameSuffix) => + renderWithStore( + storeArgument, + (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` + /** Get the length of ${field.name}${_commentSuffix} */ + function ${_methodNamePrefix}length${_methodNameSuffix}(${renderArguments([ + _typedStore, + _typedTableId, + _typedKeyArgs, + ])}) internal view returns (uint256) { + ${_keyTupleDefinition} + uint256 _byteLength = ${_store}.getFieldLength(_tableId, _keyTuple, ${schemaIndex}, _fieldLayout); + unchecked { + return _byteLength / ${portionData.elementLength}; + } } - } ` - ) - ); + ) + ); - result += renderWithFieldSuffix(options.withSuffixlessFieldMethods, field.name, (_methodNameSuffix) => - renderWithStore( - storeArgument, - (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` - /** - * Get an item of ${field.name}${_commentSuffix} - * (unchecked, returns invalid data if index overflows) - */ - function ${_methodNamePrefix}getItem${_methodNameSuffix}(${renderArguments([ - _typedStore, - _typedTableId, - _typedKeyArgs, - "uint256 _index", - ])}) internal view returns (${portionData.typeWithLocation}) { + result += renderWithFieldSuffix(options.withSuffixlessFieldMethods, field.name, (_methodNameSuffix) => + renderWithStore( + storeArgument, + (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` + /** + * Get an item of ${field.name}${_commentSuffix} + * (unchecked, returns invalid data if index overflows) + */ + function ${_methodNamePrefix}getItem${_methodNameSuffix}(${renderArguments([ + _typedStore, + _typedTableId, + _typedKeyArgs, + "uint256 _index", + ])}) internal view returns (${portionData.typeWithLocation}) { ${_keyTupleDefinition} unchecked { bytes memory _blob = ${_store}.getFieldSlice( @@ -113,20 +119,21 @@ export function renderFieldMethods(options: RenderTableOptions) { _fieldLayout, _index * ${portionData.elementLength}, (_index + 1) * ${portionData.elementLength} - ); - return ${portionData.decoded}; + ); + return ${portionData.decoded}; + } } - } - ` - ) - ); + ` + ) + ); + } result += renderWithFieldSuffix(options.withSuffixlessFieldMethods, field.name, (_methodNameSuffix) => renderWithStore( storeArgument, (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` - /** Push ${portionData.title} to ${field.name}${_commentSuffix} */ - function ${_methodNamePrefix}push${_methodNameSuffix}(${renderArguments([ + /** Push ${portionData.title} to ${field.name}${_commentSuffix} */ + function ${_methodNamePrefix}push${_methodNameSuffix}(${renderArguments([ _typedStore, _typedTableId, _typedKeyArgs, @@ -135,7 +142,7 @@ export function renderFieldMethods(options: RenderTableOptions) { ${_keyTupleDefinition} ${_store}.pushToField(_tableId, _keyTuple, ${schemaIndex}, ${portionData.encoded}, _fieldLayout); } - ` + ` ) ); diff --git a/packages/store/ts/codegen/record.ts b/packages/store/ts/codegen/record.ts index 7f1636ce62..bca8884879 100644 --- a/packages/store/ts/codegen/record.ts +++ b/packages/store/ts/codegen/record.ts @@ -12,26 +12,30 @@ export function renderRecordMethods(options: RenderTableOptions) { const { structName, storeArgument } = options; const { _tableId, _typedTableId, _keyArgs, _typedKeyArgs, _keyTupleDefinition } = renderCommonData(options); - let result = renderWithStore( - storeArgument, - (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` - /** Get the full data${_commentSuffix} */ - function ${_methodNamePrefix}get(${renderArguments([ - _typedStore, - _typedTableId, - _typedKeyArgs, - ])}) internal view returns (${renderDecodedRecord(options)}) { - ${_keyTupleDefinition} + let result = ""; - ( - bytes memory _staticData, - PackedCounter _encodedLengths, - bytes memory _dynamicData - ) = ${_store}.getRecord(_tableId, _keyTuple, _fieldLayout); - return decode(_staticData, _encodedLengths, _dynamicData); - } - ` - ); + if (options.withGetters) { + result += renderWithStore( + storeArgument, + (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` + /** Get the full data${_commentSuffix} */ + function ${_methodNamePrefix}get(${renderArguments([ + _typedStore, + _typedTableId, + _typedKeyArgs, + ])}) internal view returns (${renderDecodedRecord(options)}) { + ${_keyTupleDefinition} + + ( + bytes memory _staticData, + PackedCounter _encodedLengths, + bytes memory _dynamicData + ) = ${_store}.getRecord(_tableId, _keyTuple, _fieldLayout); + return decode(_staticData, _encodedLengths, _dynamicData); + } + ` + ); + } result += renderWithStore( storeArgument, @@ -104,6 +108,26 @@ export function renderRecordData(options: RenderTableOptions) { return result; } +export function renderDeleteRecordMethods(options: RenderTableOptions) { + const { storeArgument } = options; + const { _typedTableId, _typedKeyArgs, _keyTupleDefinition } = renderCommonData(options); + + return renderWithStore( + storeArgument, + (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` + /** Delete all data for given keys${_commentSuffix} */ + function ${_methodNamePrefix}deleteRecord(${renderArguments([ + _typedStore, + _typedTableId, + _typedKeyArgs, + ])}) internal { + ${_keyTupleDefinition} + ${_store}.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + ` + ); +} + // Renders the `decode` function that parses a bytes blob into the table data function renderDecodeFunctions({ structName, fields, staticFields, dynamicFields }: RenderTableOptions) { // either set struct properties, or just variables diff --git a/packages/store/ts/codegen/renderTable.ts b/packages/store/ts/codegen/renderTable.ts index 0e97775183..e941e5c017 100644 --- a/packages/store/ts/codegen/renderTable.ts +++ b/packages/store/ts/codegen/renderTable.ts @@ -10,9 +10,8 @@ import { renderedSolidityHeader, RenderStaticField, } from "@latticexyz/common/codegen"; -import { renderEphemeralMethods } from "./ephemeral"; import { renderEncodeFieldSingle, renderFieldMethods } from "./field"; -import { renderRecordData, renderRecordMethods } from "./record"; +import { renderDeleteRecordMethods, renderRecordData, renderRecordMethods } from "./record"; import { renderFieldLayout } from "./renderFieldLayout"; import { RenderTableOptions } from "./types"; @@ -26,15 +25,12 @@ export function renderTable(options: RenderTableOptions) { fields, staticFields, dynamicFields, - withFieldMethods, withRecordMethods, - withEphemeralMethods, storeArgument, keyTuple, } = options; const { _typedTableId, _typedKeyArgs, _keyTupleDefinition } = renderCommonData(options); - const shouldRenderDelete = !withEphemeralMethods; return ` ${renderedSolidityHeader} @@ -54,7 +50,7 @@ export function renderTable(options: RenderTableOptions) { import { Schema, SchemaLib } from "${storeImportPath}Schema.sol"; import { PackedCounter, PackedCounterLib } from "${storeImportPath}PackedCounter.sol"; import { ResourceId } from "${storeImportPath}ResourceId.sol"; - import { RESOURCE_TABLE } from "${storeImportPath}storeResourceTypes.sol"; + import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "${storeImportPath}storeResourceTypes.sol"; ${ imports.length > 0 @@ -123,11 +119,11 @@ export function renderTable(options: RenderTableOptions) { ` )} - ${withFieldMethods ? renderFieldMethods(options) : ""} + ${renderFieldMethods(options)} ${withRecordMethods ? renderRecordMethods(options) : ""} - ${withEphemeralMethods ? renderEphemeralMethods(options) : ""} + ${renderDeleteRecordMethods(options)} ${renderEncodeStatic(staticFields)} @@ -149,25 +145,6 @@ export function renderTable(options: RenderTableOptions) { ${_keyTupleDefinition} return _keyTuple; } - - ${ - shouldRenderDelete - ? renderWithStore( - storeArgument, - (_typedStore, _store, _commentSuffix, _untypedStore, _methodNamePrefix) => ` - /* Delete all data for given keys${_commentSuffix} */ - function ${_methodNamePrefix}deleteRecord(${renderArguments([ - _typedStore, - _typedTableId, - _typedKeyArgs, - ])}) internal { - ${_keyTupleDefinition} - ${_store}.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - ` - ) - : "" - } } ${renderTypeHelpers(options)} diff --git a/packages/store/ts/codegen/tableOptions.ts b/packages/store/ts/codegen/tableOptions.ts index fe66118099..c1f19d91ce 100644 --- a/packages/store/ts/codegen/tableOptions.ts +++ b/packages/store/ts/codegen/tableOptions.ts @@ -26,8 +26,8 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { // struct adds methods to get/set all values at once const withStruct = tableData.dataStruct; - // operate on all fields at once; for only 1 field keep them only if struct is also kept - const withRecordMethods = withStruct || Object.keys(tableData.valueSchema).length > 1; + // operate on all fields at once; always render for offchain tables; for only 1 field keep them if struct is also kept + const withRecordMethods = withStruct || tableData.offchainOnly || Object.keys(tableData.valueSchema).length > 1; // field methods can include simply get/set if there's only 1 field and no record methods const withSuffixlessFieldMethods = !withRecordMethods && Object.keys(tableData.valueSchema).length === 1; // list of any symbols that need to be imported @@ -79,6 +79,7 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { tableIdName: tableName + "TableId", namespace: config.namespace, name: tableData.name, + offchainOnly: tableData.offchainOnly, }; } })(); @@ -96,9 +97,9 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { fields, staticFields, dynamicFields, - withFieldMethods: !tableData.ephemeral, - withRecordMethods: withRecordMethods && !tableData.ephemeral, - withEphemeralMethods: tableData.ephemeral, + withGetters: !tableData.offchainOnly, + withRecordMethods, + withDynamicFieldMethods: !tableData.offchainOnly, withSuffixlessFieldMethods, storeArgument: tableData.storeArgument, }, diff --git a/packages/store/ts/codegen/types.ts b/packages/store/ts/codegen/types.ts index ff01d2e2de..96ea355f53 100644 --- a/packages/store/ts/codegen/types.ts +++ b/packages/store/ts/codegen/types.ts @@ -22,12 +22,12 @@ export interface RenderTableOptions { fields: RenderField[]; staticFields: RenderStaticField[]; dynamicFields: RenderDynamicField[]; - /** Whether to render methods for individual fields (get/set, and more for dynamic elements) */ - withFieldMethods: boolean; + /** Whether to render getter functions */ + withGetters: boolean; + /** Whether to render dynamic field methods (push, pop, update) */ + withDynamicFieldMethods: boolean; /** Whether to render get/set methods for the whole record */ withRecordMethods: boolean; - /** Whether to render emitEphemeral methods */ - withEphemeralMethods: boolean; /** Whether to additionally render field methods without a field name suffix */ withSuffixlessFieldMethods: boolean; /** Whether to render additional methods that accept a manual `IStore` argument */ diff --git a/packages/store/ts/config/defaults.ts b/packages/store/ts/config/defaults.ts index 0393830547..be7dfd58e7 100644 --- a/packages/store/ts/config/defaults.ts +++ b/packages/store/ts/config/defaults.ts @@ -15,5 +15,5 @@ export const TABLE_DEFAULTS = { keySchema: { key: "bytes32" }, tableIdArgument: false, storeArgument: true, - ephemeral: false, + offchainOnly: false, } as const; diff --git a/packages/store/ts/config/storeConfig.ts b/packages/store/ts/config/storeConfig.ts index 36a951b862..dd0627424a 100644 --- a/packages/store/ts/config/storeConfig.ts +++ b/packages/store/ts/config/storeConfig.ts @@ -86,8 +86,8 @@ export interface TableConfig< storeArgument?: boolean; /** Include a data struct and methods for it. Default is false for 1-column tables; true for multi-column tables. */ dataStruct?: boolean; - /** Generate only `emitEphemeral` which emits an event without writing to storage. Default is false. */ - ephemeral?: boolean; + /** Offchain tables don't write to onchain storage, but only emit events for offchain clients. Default is false. */ + offchainOnly?: boolean; /** * Table's key names mapped to their types. * Default is `{ key: "bytes32" }` @@ -119,7 +119,7 @@ export interface ExpandTableConfig, TableN // dataStruct isn't expanded, because its value is conditional on the number of value schema fields dataStruct: boolean; keySchema: typeof TABLE_DEFAULTS.keySchema; - ephemeral: typeof TABLE_DEFAULTS.ephemeral; + offchainOnly: typeof TABLE_DEFAULTS.offchainOnly; } > { valueSchema: ExpandSchemaConfig; @@ -134,7 +134,7 @@ const zFullTableConfig = z dataStruct: z.boolean().optional(), keySchema: zKeySchema, valueSchema: zSchemaConfig, - ephemeral: z.boolean().default(TABLE_DEFAULTS.ephemeral), + offchainOnly: z.boolean().default(TABLE_DEFAULTS.offchainOnly), }) .transform((arg) => { // default dataStruct value depends on value schema's length diff --git a/packages/store/ts/storeEvents.ts b/packages/store/ts/storeEvents.ts index 5f1d1a23a9..67de4dd645 100644 --- a/packages/store/ts/storeEvents.ts +++ b/packages/store/ts/storeEvents.ts @@ -2,6 +2,5 @@ export const storeEvents = [ "event StoreSetRecord(bytes32 indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData)", "event StoreSpliceStaticData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data)", "event StoreSpliceDynamicData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths)", - "event StoreEphemeralRecord(bytes32 indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData)", "event StoreDeleteRecord(bytes32 indexed tableId, bytes32[] keyTuple)", ] as const; diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index 1a53c2c895..46c6292db7 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -39,67 +39,67 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallComposite", "name": "install keys in table module", - "gasUsed": 1414600 + "gasUsed": 1414806 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "install keys in table module", - "gasUsed": 1414600 + "gasUsed": 1414806 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "set a record on a table with keysInTableModule installed", - "gasUsed": 158308 + "gasUsed": 158382 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallSingleton", "name": "install keys in table module", - "gasUsed": 1414600 + "gasUsed": 1414806 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "install keys in table module", - "gasUsed": 1414600 + "gasUsed": 1414806 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "change a composite record on a table with keysInTableModule installed", - "gasUsed": 22290 + "gasUsed": 22324 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "delete a composite record on a table with keysInTableModule installed", - "gasUsed": 160543 + "gasUsed": 160664 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "install keys in table module", - "gasUsed": 1414600 + "gasUsed": 1414806 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "change a record on a table with keysInTableModule installed", - "gasUsed": 21012 + "gasUsed": 21046 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "delete a record on a table with keysInTableModule installed", - "gasUsed": 85675 + "gasUsed": 85764 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "install keys with value module", - "gasUsed": 664896 + "gasUsed": 665200 }, { "file": "test/KeysWithValueModule.t.sol", @@ -117,49 +117,49 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "install keys with value module", - "gasUsed": 664896 + "gasUsed": 665200 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "set a record on a table with KeysWithValueModule installed", - "gasUsed": 135679 + "gasUsed": 135760 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "install keys with value module", - "gasUsed": 664896 + "gasUsed": 665200 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "change a record on a table with KeysWithValueModule installed", - "gasUsed": 106088 + "gasUsed": 106140 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "delete a record on a table with KeysWithValueModule installed", - "gasUsed": 35339 + "gasUsed": 35415 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "install keys with value module", - "gasUsed": 664896 + "gasUsed": 665200 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "set a field on a table with KeysWithValueModule installed", - "gasUsed": 148411 + "gasUsed": 148511 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "change a field on a table with KeysWithValueModule installed", - "gasUsed": 113170 + "gasUsed": 113270 }, { "file": "test/query.t.sol", @@ -231,49 +231,49 @@ "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "register a callbound delegation", - "gasUsed": 114520 + "gasUsed": 114571 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "call a system via a callbound delegation", - "gasUsed": 34023 + "gasUsed": 34058 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "register a timebound delegation", - "gasUsed": 108972 + "gasUsed": 109041 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "call a system via a timebound delegation", - "gasUsed": 27100 + "gasUsed": 27106 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "install unique entity module", - "gasUsed": 689839 + "gasUsed": 690323 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "get a unique entity nonce (non-root module)", - "gasUsed": 52112 + "gasUsed": 52137 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "installRoot unique entity module", - "gasUsed": 680105 + "gasUsed": 680596 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "get a unique entity nonce (root module)", - "gasUsed": 52112 + "gasUsed": 52137 }, { "file": "test/World.t.sol", @@ -285,7 +285,7 @@ "file": "test/World.t.sol", "test": "testCallFromUnlimitedDelegation", "name": "register an unlimited delegation", - "gasUsed": 50584 + "gasUsed": 50615 }, { "file": "test/World.t.sol", @@ -297,7 +297,7 @@ "file": "test/World.t.sol", "test": "testDeleteRecord", "name": "Delete record", - "gasUsed": 9120 + "gasUsed": 9155 }, { "file": "test/World.t.sol", @@ -309,79 +309,79 @@ "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a fallback system", - "gasUsed": 59355 + "gasUsed": 59404 }, { "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a root fallback system", - "gasUsed": 52902 + "gasUsed": 52929 }, { "file": "test/World.t.sol", "test": "testRegisterFunctionSelector", "name": "Register a function selector", - "gasUsed": 79949 + "gasUsed": 79998 }, { "file": "test/World.t.sol", "test": "testRegisterNamespace", "name": "Register a new namespace", - "gasUsed": 123062 + "gasUsed": 123238 }, { "file": "test/World.t.sol", "test": "testRegisterRootFunctionSelector", "name": "Register a root function selector", - "gasUsed": 74815 + "gasUsed": 74842 }, { "file": "test/World.t.sol", "test": "testRegisterSystem", "name": "register a system", - "gasUsed": 165531 + "gasUsed": 165710 }, { "file": "test/World.t.sol", "test": "testRegisterTable", "name": "Register a new table in the namespace", - "gasUsed": 651531 + "gasUsed": 651789 }, { "file": "test/World.t.sol", "test": "testSetField", "name": "Write data to a table field", - "gasUsed": 37403 + "gasUsed": 37413 }, { "file": "test/World.t.sol", "test": "testSetRecord", "name": "Write data to the table", - "gasUsed": 35397 + "gasUsed": 35407 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (cold)", - "gasUsed": 24633 + "gasUsed": 24643 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (warm)", - "gasUsed": 13779 + "gasUsed": 13789 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (cold)", - "gasUsed": 25244 + "gasUsed": 25248 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (warm)", - "gasUsed": 14449 + "gasUsed": 14453 }, { "file": "test/WorldResourceId.t.sol", diff --git a/packages/world/mud.config.ts b/packages/world/mud.config.ts index 1a77d8309b..9a3fe83257 100644 --- a/packages/world/mud.config.ts +++ b/packages/world/mud.config.ts @@ -191,7 +191,5 @@ export default mudConfig({ // TODO: add support for inheritance to worldgen // (see: https://github.com/latticexyz/mud/issues/631) "StoreRegistrationSystem", - // Similar overlap occurs for IEphemeralRecordSystem. IWorldEphemeral is included instead. - "EphemeralRecordSystem", ], }); diff --git a/packages/world/src/modules/core/CoreModule.sol b/packages/world/src/modules/core/CoreModule.sol index bdbaca2226..9d5fc3a852 100644 --- a/packages/world/src/modules/core/CoreModule.sol +++ b/packages/world/src/modules/core/CoreModule.sol @@ -7,7 +7,6 @@ import { Module } from "../../Module.sol"; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; -import { IStoreEphemeral } from "@latticexyz/store/src/IStore.sol"; import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol"; import { ResourceId, WorldResourceIdLib, WorldResourceIdInstance } from "../../WorldResourceId.sol"; @@ -29,7 +28,6 @@ import { Balances } from "./tables/Balances.sol"; import { AccessManagementSystem } from "./implementations/AccessManagementSystem.sol"; import { BalanceTransferSystem } from "./implementations/BalanceTransferSystem.sol"; -import { EphemeralRecordSystem } from "./implementations/EphemeralRecordSystem.sol"; import { ModuleInstallationSystem } from "./implementations/ModuleInstallationSystem.sol"; import { StoreRegistrationSystem } from "./implementations/StoreRegistrationSystem.sol"; import { WorldRegistrationSystem } from "./implementations/WorldRegistrationSystem.sol"; @@ -104,7 +102,7 @@ contract CoreModule is Module { * Register function selectors for all CoreSystem functions in the World */ function _registerFunctionSelectors() internal { - bytes4[17] memory functionSelectors = [ + bytes4[16] memory functionSelectors = [ // --- AccessManagementSystem --- AccessManagementSystem.grantAccess.selector, AccessManagementSystem.revokeAccess.selector, @@ -112,8 +110,6 @@ contract CoreModule is Module { // --- BalanceTransferSystem --- BalanceTransferSystem.transferBalanceToNamespace.selector, BalanceTransferSystem.transferBalanceToAddress.selector, - // --- EphemeralRecordSystem --- - IStoreEphemeral.emitEphemeralRecord.selector, // --- ModuleInstallationSystem --- ModuleInstallationSystem.installModule.selector, // --- StoreRegistrationSystem --- diff --git a/packages/world/src/modules/core/CoreSystem.sol b/packages/world/src/modules/core/CoreSystem.sol index 1a3b5c0c1c..5372acc73d 100644 --- a/packages/world/src/modules/core/CoreSystem.sol +++ b/packages/world/src/modules/core/CoreSystem.sol @@ -5,7 +5,6 @@ import { IWorldErrors } from "../../interfaces/IWorldErrors.sol"; import { AccessManagementSystem } from "./implementations/AccessManagementSystem.sol"; import { BalanceTransferSystem } from "./implementations/BalanceTransferSystem.sol"; -import { EphemeralRecordSystem } from "./implementations/EphemeralRecordSystem.sol"; import { ModuleInstallationSystem } from "./implementations/ModuleInstallationSystem.sol"; import { StoreRegistrationSystem } from "./implementations/StoreRegistrationSystem.sol"; import { WorldRegistrationSystem } from "./implementations/WorldRegistrationSystem.sol"; @@ -18,7 +17,6 @@ contract CoreSystem is IWorldErrors, AccessManagementSystem, BalanceTransferSystem, - EphemeralRecordSystem, ModuleInstallationSystem, StoreRegistrationSystem, WorldRegistrationSystem diff --git a/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol b/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol deleted file mode 100644 index e5726d495f..0000000000 --- a/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -import { IStoreEphemeral } from "@latticexyz/store/src/IStore.sol"; -import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; -import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; -import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; -import { System } from "../../../System.sol"; -import { ResourceId, WorldResourceIdInstance } from "../../../WorldResourceId.sol"; -import { AccessControl } from "../../../AccessControl.sol"; - -contract EphemeralRecordSystem is IStoreEphemeral, System { - using WorldResourceIdInstance for ResourceId; - - /** - * Emit the ephemeral event without modifying storage at the given namespace and name. - * Requires the caller to have access to the namespace or name (encoded in the table ID) - */ - function emitEphemeralRecord( - ResourceId tableId, - bytes32[] calldata keyTuple, - bytes calldata staticData, - PackedCounter encodedLengths, - bytes calldata dynamicData, - FieldLayout fieldLayout - ) public virtual { - // Require access to the namespace or name - AccessControl.requireAccess(tableId, msg.sender); - - // Set the record - StoreCore.emitEphemeralRecord(tableId, keyTuple, staticData, encodedLengths, dynamicData, fieldLayout); - } -} diff --git a/packages/world/src/modules/core/tables/Balances.sol b/packages/world/src/modules/core/tables/Balances.sol index abdb7903f5..b1a6f276be 100644 --- a/packages/world/src/modules/core/tables/Balances.sol +++ b/packages/world/src/modules/core/tables/Balances.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Balances"))) @@ -180,6 +180,30 @@ library Balances { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((balance)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 namespaceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = namespaceId; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 namespaceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = namespaceId; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 namespaceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = namespaceId; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(uint256 balance) internal pure returns (bytes memory) { return abi.encodePacked(balance); @@ -202,28 +226,4 @@ library Balances { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 namespaceId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = namespaceId; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 namespaceId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = namespaceId; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 namespaceId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = namespaceId; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/world/src/modules/core/tables/FunctionSelectors.sol b/packages/world/src/modules/core/tables/FunctionSelectors.sol index 19c200d122..7f520a92bb 100644 --- a/packages/world/src/modules/core/tables/FunctionSelectors.sol +++ b/packages/world/src/modules/core/tables/FunctionSelectors.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("FunctionSelector"))) @@ -288,6 +288,30 @@ library FunctionSelectors { (systemId, systemFunctionSelector) = decodeStatic(_staticData); } + /** Delete all data for given keys */ + function deleteRecord(bytes4 functionSelector) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(functionSelector); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes4 functionSelector) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(functionSelector); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes4 functionSelector) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(functionSelector); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(bytes32 systemId, bytes4 systemFunctionSelector) internal pure returns (bytes memory) { return abi.encodePacked(systemId, systemFunctionSelector); @@ -313,28 +337,4 @@ library FunctionSelectors { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes4 functionSelector) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(functionSelector); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes4 functionSelector) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(functionSelector); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes4 functionSelector) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(functionSelector); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/world/src/modules/core/tables/SystemHooks.sol b/packages/world/src/modules/core/tables/SystemHooks.sol index 0201700a2d..b42a79d2eb 100644 --- a/packages/world/src/modules/core/tables/SystemHooks.sol +++ b/packages/world/src/modules/core/tables/SystemHooks.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("SystemHooks"))) @@ -532,6 +532,30 @@ library SystemHooks { } } + /** Delete all data for given keys */ + function deleteRecord(bytes32 systemId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = systemId; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 systemId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = systemId; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 systemId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = systemId; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths(bytes21[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits @@ -561,28 +585,4 @@ library SystemHooks { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 systemId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = systemId; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 systemId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = systemId; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 systemId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = systemId; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/world/src/modules/core/tables/SystemRegistry.sol b/packages/world/src/modules/core/tables/SystemRegistry.sol index 58064ea817..aaec11544d 100644 --- a/packages/world/src/modules/core/tables/SystemRegistry.sol +++ b/packages/world/src/modules/core/tables/SystemRegistry.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("SystemRegistry"))) @@ -180,6 +180,30 @@ library SystemRegistry { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((systemId)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord(address system) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(system))); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(address system) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(system))); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, address system) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = bytes32(uint256(uint160(system))); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(bytes32 systemId) internal pure returns (bytes memory) { return abi.encodePacked(systemId); @@ -202,28 +226,4 @@ library SystemRegistry { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(address system) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(uint160(system))); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(address system) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(uint160(system))); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, address system) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = bytes32(uint256(uint160(system))); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/world/src/modules/core/tables/Systems.sol b/packages/world/src/modules/core/tables/Systems.sol index 2da7769044..10c7b49a40 100644 --- a/packages/world/src/modules/core/tables/Systems.sol +++ b/packages/world/src/modules/core/tables/Systems.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Systems"))) @@ -282,6 +282,30 @@ library Systems { (system, publicAccess) = decodeStatic(_staticData); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 systemId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = systemId; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 systemId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = systemId; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 systemId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = systemId; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(address system, bool publicAccess) internal pure returns (bytes memory) { return abi.encodePacked(system, publicAccess); @@ -304,30 +328,6 @@ library Systems { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 systemId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = systemId; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 systemId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = systemId; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 systemId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = systemId; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } function _toBool(uint8 value) pure returns (bool result) { diff --git a/packages/world/src/modules/keysintable/tables/KeysInTable.sol b/packages/world/src/modules/keysintable/tables/KeysInTable.sol index b51ca0c922..7c86f97fed 100644 --- a/packages/world/src/modules/keysintable/tables/KeysInTable.sol +++ b/packages/world/src/modules/keysintable/tables/KeysInTable.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("KeysInTable"))) @@ -1406,6 +1406,30 @@ library KeysInTable { ); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 sourceTable) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = sourceTable; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 sourceTable) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = sourceTable; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 sourceTable) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = sourceTable; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths( bytes32[] memory keys0, @@ -1466,28 +1490,4 @@ library KeysInTable { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 sourceTable) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = sourceTable; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 sourceTable) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = sourceTable; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 sourceTable) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = sourceTable; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol b/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol index d4c75eddb8..ade2c06653 100644 --- a/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol +++ b/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("UsedKeysIndex"))) @@ -302,31 +302,7 @@ library UsedKeysIndex { (has, index) = decodeStatic(_staticData); } - /** Tightly pack static data using this table's schema */ - function encodeStatic(bool has, uint40 index) internal pure returns (bytes memory) { - return abi.encodePacked(has, index); - } - - /** Tightly pack full data using this table's field layout */ - function encode(bool has, uint40 index) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(has, index); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes32 sourceTable, bytes32 keysHash) internal pure returns (bytes32[] memory) { - bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = sourceTable; - _keyTuple[1] = keysHash; - - return _keyTuple; - } - - /* Delete all data for given keys */ + /** Delete all data for given keys */ function deleteRecord(bytes32 sourceTable, bytes32 keysHash) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = sourceTable; @@ -335,7 +311,7 @@ library UsedKeysIndex { StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ + /** Delete all data for given keys */ function _deleteRecord(bytes32 sourceTable, bytes32 keysHash) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = sourceTable; @@ -344,7 +320,7 @@ library UsedKeysIndex { StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys (using the specified store) */ + /** Delete all data for given keys (using the specified store) */ function deleteRecord(IStore _store, bytes32 sourceTable, bytes32 keysHash) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = sourceTable; @@ -352,6 +328,30 @@ library UsedKeysIndex { _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } + + /** Tightly pack static data using this table's schema */ + function encodeStatic(bool has, uint40 index) internal pure returns (bytes memory) { + return abi.encodePacked(has, index); + } + + /** Tightly pack full data using this table's field layout */ + function encode(bool has, uint40 index) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(has, index); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple(bytes32 sourceTable, bytes32 keysHash) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = sourceTable; + _keyTuple[1] = keysHash; + + return _keyTuple; + } } function _toBool(uint8 value) pure returns (bool result) { diff --git a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol index 24fce461aa..0cc9ed2cf8 100644 --- a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol +++ b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 @@ -570,6 +570,30 @@ library KeysWithValue { } } + /** Delete all data for given keys */ + function deleteRecord(ResourceId _tableId, bytes32 valueHash) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = valueHash; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(ResourceId _tableId, bytes32 valueHash) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = valueHash; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, ResourceId _tableId, bytes32 valueHash) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = valueHash; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths(bytes32[] memory keysWithValue) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits @@ -599,28 +623,4 @@ library KeysWithValue { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(ResourceId _tableId, bytes32 valueHash) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = valueHash; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(ResourceId _tableId, bytes32 valueHash) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = valueHash; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, ResourceId _tableId, bytes32 valueHash) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = valueHash; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol b/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol index 93c6ef192d..5bb08ebe8a 100644 --- a/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol +++ b/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("CallboundDelegat"))) @@ -292,38 +292,7 @@ library CallboundDelegations { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((availableCalls)), _fieldLayout); } - /** Tightly pack static data using this table's schema */ - function encodeStatic(uint256 availableCalls) internal pure returns (bytes memory) { - return abi.encodePacked(availableCalls); - } - - /** Tightly pack full data using this table's field layout */ - function encode(uint256 availableCalls) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(availableCalls); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple( - address delegator, - address delegatee, - bytes32 systemId, - bytes32 callDataHash - ) internal pure returns (bytes32[] memory) { - bytes32[] memory _keyTuple = new bytes32[](4); - _keyTuple[0] = bytes32(uint256(uint160(delegator))); - _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - _keyTuple[2] = systemId; - _keyTuple[3] = callDataHash; - - return _keyTuple; - } - - /* Delete all data for given keys */ + /** Delete all data for given keys */ function deleteRecord(address delegator, address delegatee, bytes32 systemId, bytes32 callDataHash) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); @@ -334,7 +303,7 @@ library CallboundDelegations { StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ + /** Delete all data for given keys */ function _deleteRecord(address delegator, address delegatee, bytes32 systemId, bytes32 callDataHash) internal { bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(uint160(delegator))); @@ -345,7 +314,7 @@ library CallboundDelegations { StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys (using the specified store) */ + /** Delete all data for given keys (using the specified store) */ function deleteRecord( IStore _store, address delegator, @@ -361,4 +330,35 @@ library CallboundDelegations { _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } + + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint256 availableCalls) internal pure returns (bytes memory) { + return abi.encodePacked(availableCalls); + } + + /** Tightly pack full data using this table's field layout */ + function encode(uint256 availableCalls) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(availableCalls); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple( + address delegator, + address delegatee, + bytes32 systemId, + bytes32 callDataHash + ) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](4); + _keyTuple[0] = bytes32(uint256(uint160(delegator))); + _keyTuple[1] = bytes32(uint256(uint160(delegatee))); + _keyTuple[2] = systemId; + _keyTuple[3] = callDataHash; + + return _keyTuple; + } } diff --git a/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol b/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol index 7505e6a7c6..f973705ea6 100644 --- a/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol +++ b/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("TimeboundDelegat"))) @@ -198,31 +198,7 @@ library TimeboundDelegations { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((maxTimestamp)), _fieldLayout); } - /** Tightly pack static data using this table's schema */ - function encodeStatic(uint256 maxTimestamp) internal pure returns (bytes memory) { - return abi.encodePacked(maxTimestamp); - } - - /** Tightly pack full data using this table's field layout */ - function encode(uint256 maxTimestamp) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(maxTimestamp); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(address delegator, address delegatee) internal pure returns (bytes32[] memory) { - bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = bytes32(uint256(uint160(delegator))); - _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - - return _keyTuple; - } - - /* Delete all data for given keys */ + /** Delete all data for given keys */ function deleteRecord(address delegator, address delegatee) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(uint256(uint160(delegator))); @@ -231,7 +207,7 @@ library TimeboundDelegations { StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ + /** Delete all data for given keys */ function _deleteRecord(address delegator, address delegatee) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(uint256(uint160(delegator))); @@ -240,7 +216,7 @@ library TimeboundDelegations { StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys (using the specified store) */ + /** Delete all data for given keys (using the specified store) */ function deleteRecord(IStore _store, address delegator, address delegatee) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(uint256(uint160(delegator))); @@ -248,4 +224,28 @@ library TimeboundDelegations { _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } + + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint256 maxTimestamp) internal pure returns (bytes memory) { + return abi.encodePacked(maxTimestamp); + } + + /** Tightly pack full data using this table's field layout */ + function encode(uint256 maxTimestamp) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(maxTimestamp); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple(address delegator, address delegatee) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(delegator))); + _keyTuple[1] = bytes32(uint256(uint160(delegatee))); + + return _keyTuple; + } } diff --git a/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol b/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol index 2e2982e647..504f52e8b4 100644 --- a/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol +++ b/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0020010020000000000000000000000000000000000000000000000000000000 @@ -161,6 +161,27 @@ library UniqueEntity { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord(ResourceId _tableId) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(ResourceId _tableId) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, ResourceId _tableId) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(uint256 value) internal pure returns (bytes memory) { return abi.encodePacked(value); @@ -182,25 +203,4 @@ library UniqueEntity { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(ResourceId _tableId) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(ResourceId _tableId) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, ResourceId _tableId) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/world/src/tables/Delegations.sol b/packages/world/src/tables/Delegations.sol index f39cb50e68..d74442d458 100644 --- a/packages/world/src/tables/Delegations.sol +++ b/packages/world/src/tables/Delegations.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Delegations"))) @@ -213,31 +213,7 @@ library Delegations { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((delegationControlId)), _fieldLayout); } - /** Tightly pack static data using this table's schema */ - function encodeStatic(bytes32 delegationControlId) internal pure returns (bytes memory) { - return abi.encodePacked(delegationControlId); - } - - /** Tightly pack full data using this table's field layout */ - function encode(bytes32 delegationControlId) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(delegationControlId); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(address delegator, address delegatee) internal pure returns (bytes32[] memory) { - bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = bytes32(uint256(uint160(delegator))); - _keyTuple[1] = bytes32(uint256(uint160(delegatee))); - - return _keyTuple; - } - - /* Delete all data for given keys */ + /** Delete all data for given keys */ function deleteRecord(address delegator, address delegatee) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(uint256(uint160(delegator))); @@ -246,7 +222,7 @@ library Delegations { StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ + /** Delete all data for given keys */ function _deleteRecord(address delegator, address delegatee) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(uint256(uint160(delegator))); @@ -255,7 +231,7 @@ library Delegations { StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys (using the specified store) */ + /** Delete all data for given keys (using the specified store) */ function deleteRecord(IStore _store, address delegator, address delegatee) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(uint256(uint160(delegator))); @@ -263,4 +239,28 @@ library Delegations { _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } + + /** Tightly pack static data using this table's schema */ + function encodeStatic(bytes32 delegationControlId) internal pure returns (bytes memory) { + return abi.encodePacked(delegationControlId); + } + + /** Tightly pack full data using this table's field layout */ + function encode(bytes32 delegationControlId) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(delegationControlId); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple(address delegator, address delegatee) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(uint256(uint160(delegator))); + _keyTuple[1] = bytes32(uint256(uint160(delegatee))); + + return _keyTuple; + } } diff --git a/packages/world/src/tables/InstalledModules.sol b/packages/world/src/tables/InstalledModules.sol index babc79ad42..378bbf8bb1 100644 --- a/packages/world/src/tables/InstalledModules.sol +++ b/packages/world/src/tables/InstalledModules.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("InstalledModules"))) @@ -198,31 +198,7 @@ library InstalledModules { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((moduleAddress)), _fieldLayout); } - /** Tightly pack static data using this table's schema */ - function encodeStatic(address moduleAddress) internal pure returns (bytes memory) { - return abi.encodePacked(moduleAddress); - } - - /** Tightly pack full data using this table's field layout */ - function encode(address moduleAddress) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(moduleAddress); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes16 moduleName, bytes32 argumentsHash) internal pure returns (bytes32[] memory) { - bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = bytes32(moduleName); - _keyTuple[1] = argumentsHash; - - return _keyTuple; - } - - /* Delete all data for given keys */ + /** Delete all data for given keys */ function deleteRecord(bytes16 moduleName, bytes32 argumentsHash) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(moduleName); @@ -231,7 +207,7 @@ library InstalledModules { StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ + /** Delete all data for given keys */ function _deleteRecord(bytes16 moduleName, bytes32 argumentsHash) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(moduleName); @@ -240,7 +216,7 @@ library InstalledModules { StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys (using the specified store) */ + /** Delete all data for given keys (using the specified store) */ function deleteRecord(IStore _store, bytes16 moduleName, bytes32 argumentsHash) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(moduleName); @@ -248,4 +224,28 @@ library InstalledModules { _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } + + /** Tightly pack static data using this table's schema */ + function encodeStatic(address moduleAddress) internal pure returns (bytes memory) { + return abi.encodePacked(moduleAddress); + } + + /** Tightly pack full data using this table's field layout */ + function encode(address moduleAddress) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(moduleAddress); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple(bytes16 moduleName, bytes32 argumentsHash) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = bytes32(moduleName); + _keyTuple[1] = argumentsHash; + + return _keyTuple; + } } diff --git a/packages/world/src/tables/NamespaceOwner.sol b/packages/world/src/tables/NamespaceOwner.sol index 6b9c4c6a99..50fc82b5aa 100644 --- a/packages/world/src/tables/NamespaceOwner.sol +++ b/packages/world/src/tables/NamespaceOwner.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("NamespaceOwner"))) @@ -180,6 +180,30 @@ library NamespaceOwner { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 namespaceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = namespaceId; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 namespaceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = namespaceId; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 namespaceId) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = namespaceId; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(address owner) internal pure returns (bytes memory) { return abi.encodePacked(owner); @@ -202,28 +226,4 @@ library NamespaceOwner { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 namespaceId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = namespaceId; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 namespaceId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = namespaceId; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 namespaceId) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = namespaceId; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/world/src/tables/ResourceAccess.sol b/packages/world/src/tables/ResourceAccess.sol index 28613dbe6a..58b9ccceb5 100644 --- a/packages/world/src/tables/ResourceAccess.sol +++ b/packages/world/src/tables/ResourceAccess.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("ResourceAccess"))) @@ -194,31 +194,7 @@ library ResourceAccess { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((access)), _fieldLayout); } - /** Tightly pack static data using this table's schema */ - function encodeStatic(bool access) internal pure returns (bytes memory) { - return abi.encodePacked(access); - } - - /** Tightly pack full data using this table's field layout */ - function encode(bool access) internal pure returns (bytes memory, PackedCounter, bytes memory) { - bytes memory _staticData = encodeStatic(access); - - PackedCounter _encodedLengths; - bytes memory _dynamicData; - - return (_staticData, _encodedLengths, _dynamicData); - } - - /** Encode keys as a bytes32 array using this table's field layout */ - function encodeKeyTuple(bytes32 resourceId, address caller) internal pure returns (bytes32[] memory) { - bytes32[] memory _keyTuple = new bytes32[](2); - _keyTuple[0] = resourceId; - _keyTuple[1] = bytes32(uint256(uint160(caller))); - - return _keyTuple; - } - - /* Delete all data for given keys */ + /** Delete all data for given keys */ function deleteRecord(bytes32 resourceId, address caller) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = resourceId; @@ -227,7 +203,7 @@ library ResourceAccess { StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys */ + /** Delete all data for given keys */ function _deleteRecord(bytes32 resourceId, address caller) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = resourceId; @@ -236,7 +212,7 @@ library ResourceAccess { StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); } - /* Delete all data for given keys (using the specified store) */ + /** Delete all data for given keys (using the specified store) */ function deleteRecord(IStore _store, bytes32 resourceId, address caller) internal { bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = resourceId; @@ -244,6 +220,30 @@ library ResourceAccess { _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); } + + /** Tightly pack static data using this table's schema */ + function encodeStatic(bool access) internal pure returns (bytes memory) { + return abi.encodePacked(access); + } + + /** Tightly pack full data using this table's field layout */ + function encode(bool access) internal pure returns (bytes memory, PackedCounter, bytes memory) { + bytes memory _staticData = encodeStatic(access); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return (_staticData, _encodedLengths, _dynamicData); + } + + /** Encode keys as a bytes32 array using this table's field layout */ + function encodeKeyTuple(bytes32 resourceId, address caller) internal pure returns (bytes32[] memory) { + bytes32[] memory _keyTuple = new bytes32[](2); + _keyTuple[0] = resourceId; + _keyTuple[1] = bytes32(uint256(uint160(caller))); + + return _keyTuple; + } } function _toBool(uint8 value) pure returns (bool result) { diff --git a/packages/world/test/tables/AddressArray.sol b/packages/world/test/tables/AddressArray.sol index 2a0ca327d7..8f658a688e 100644 --- a/packages/world/test/tables/AddressArray.sol +++ b/packages/world/test/tables/AddressArray.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0000000100000000000000000000000000000000000000000000000000000000 @@ -532,6 +532,30 @@ library AddressArray { } } + /** Delete all data for given keys */ + function deleteRecord(ResourceId _tableId, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(ResourceId _tableId, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, ResourceId _tableId, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack dynamic data using this table's schema */ function encodeLengths(address[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits @@ -561,28 +585,4 @@ library AddressArray { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(ResourceId _tableId, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(ResourceId _tableId, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, ResourceId _tableId, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/packages/world/test/tables/Bool.sol b/packages/world/test/tables/Bool.sol index 3572977787..976c3c4658 100644 --- a/packages/world/test/tables/Bool.sol +++ b/packages/world/test/tables/Bool.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; FieldLayout constant _fieldLayout = FieldLayout.wrap( 0x0001010001000000000000000000000000000000000000000000000000000000 @@ -161,6 +161,27 @@ library Bool { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord(ResourceId _tableId) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(ResourceId _tableId) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, ResourceId _tableId) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(bool value) internal pure returns (bytes memory) { return abi.encodePacked(value); @@ -182,27 +203,6 @@ library Bool { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(ResourceId _tableId) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(ResourceId _tableId) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, ResourceId _tableId) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } function _toBool(uint8 value) pure returns (bool result) { diff --git a/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol b/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol index f444e2aebd..33aeb9dba3 100644 --- a/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Counter"))) @@ -166,6 +166,27 @@ library Counter { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(uint32 value) internal pure returns (bytes memory) { return abi.encodePacked(value); @@ -187,25 +208,4 @@ library Counter { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/templates/react/packages/contracts/src/codegen/tables/Counter.sol b/templates/react/packages/contracts/src/codegen/tables/Counter.sol index f444e2aebd..33aeb9dba3 100644 --- a/templates/react/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/react/packages/contracts/src/codegen/tables/Counter.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Counter"))) @@ -166,6 +166,27 @@ library Counter { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(uint32 value) internal pure returns (bytes memory) { return abi.encodePacked(value); @@ -187,25 +208,4 @@ library Counter { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/templates/threejs/packages/contracts/src/codegen/tables/Position.sol b/templates/threejs/packages/contracts/src/codegen/tables/Position.sol index d9ea2bc66b..07ae7da4b2 100644 --- a/templates/threejs/packages/contracts/src/codegen/tables/Position.sol +++ b/templates/threejs/packages/contracts/src/codegen/tables/Position.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Position"))) @@ -358,6 +358,30 @@ library Position { (_table.x, _table.y, _table.z) = decodeStatic(_staticData); } + /** Delete all data for given keys */ + function deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord(bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store, bytes32 key) internal { + bytes32[] memory _keyTuple = new bytes32[](1); + _keyTuple[0] = key; + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(int32 x, int32 y, int32 z) internal pure returns (bytes memory) { return abi.encodePacked(x, y, z); @@ -380,28 +404,4 @@ library Position { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord(bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store, bytes32 key) internal { - bytes32[] memory _keyTuple = new bytes32[](1); - _keyTuple[0] = key; - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } diff --git a/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol b/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol index f444e2aebd..33aeb9dba3 100644 --- a/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol @@ -18,7 +18,7 @@ import { FieldLayout, FieldLayoutLib } from "@latticexyz/store/src/FieldLayout.s import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; -import { RESOURCE_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; +import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; ResourceId constant _tableId = ResourceId.wrap( bytes32(abi.encodePacked(RESOURCE_TABLE, bytes14(""), bytes16("Counter"))) @@ -166,6 +166,27 @@ library Counter { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), _fieldLayout); } + /** Delete all data for given keys */ + function deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys */ + function _deleteRecord() internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + + /** Delete all data for given keys (using the specified store) */ + function deleteRecord(IStore _store) internal { + bytes32[] memory _keyTuple = new bytes32[](0); + + _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); + } + /** Tightly pack static data using this table's schema */ function encodeStatic(uint32 value) internal pure returns (bytes memory) { return abi.encodePacked(value); @@ -187,25 +208,4 @@ library Counter { return _keyTuple; } - - /* Delete all data for given keys */ - function deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreSwitch.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys */ - function _deleteRecord() internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - StoreCore.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } - - /* Delete all data for given keys (using the specified store) */ - function deleteRecord(IStore _store) internal { - bytes32[] memory _keyTuple = new bytes32[](0); - - _store.deleteRecord(_tableId, _keyTuple, _fieldLayout); - } } From 92de59982fb9fc4e00e50c4a5232ed541f3ce71a Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 21 Sep 2023 19:11:48 +0100 Subject: [PATCH 4/4] feat: bump solidity to 0.8.21 (#1473) --- .changeset/serious-ads-trade.md | 12 + .vscode/settings.json | 3 +- e2e/packages/contracts/foundry.toml | 2 +- e2e/packages/contracts/src/CustomTypes.sol | 2 +- e2e/packages/contracts/src/codegen/index.sol | 2 +- .../contracts/src/codegen/tables/Multi.sol | 2 +- .../contracts/src/codegen/tables/Number.sol | 2 +- .../src/codegen/tables/NumberList.sol | 2 +- .../contracts/src/codegen/tables/Vector.sol | 2 +- .../src/codegen/world/ICustomErrorsSystem.sol | 2 +- .../src/codegen/world/INumberListSystem.sol | 2 +- .../contracts/src/codegen/world/IWorld.sol | 2 +- .../src/systems/CustomErrorsSystem.sol | 2 +- .../src/systems/NumberListSystem.sol | 2 +- e2e/packages/contracts/test/Worldgen.t.sol | 2 +- .../minimal/packages/contracts/foundry.toml | 2 +- .../contracts/script/PostDeploy.s.sol | 2 +- .../packages/contracts/src/codegen/index.sol | 2 +- .../src/codegen/tables/CounterTable.sol | 2 +- .../src/codegen/tables/Inventory.sol | 2 +- .../src/codegen/tables/MessageTable.sol | 2 +- .../src/codegen/world/IChatSystem.sol | 2 +- .../src/codegen/world/IIncrementSystem.sol | 2 +- .../src/codegen/world/IInventorySystem.sol | 2 +- .../src/codegen/world/IStructSystem.sol | 2 +- .../contracts/src/codegen/world/IWorld.sol | 2 +- .../src/interfaces/IChatNamespacedSystem.sol | 2 +- .../src/systems/ChatNamespacedSystem.sol | 2 +- .../contracts/src/systems/ChatSystem.sol | 2 +- .../contracts/src/systems/IncrementSystem.sol | 2 +- .../contracts/src/systems/InventorySystem.sol | 2 +- .../contracts/src/systems/StructSystem.sol | 2 +- .../contracts/src/systems/structs.sol | 2 +- .../contracts/test/ChatNamespaced.t.sol | 2 +- .../packages/contracts/test/CounterTest.t.sol | 2 +- .../packages/contracts/test/StructTest.t.sol | 2 +- packages/cli/contracts/src/codegen/common.sol | 2 +- packages/cli/contracts/src/codegen/index.sol | 2 +- .../src/codegen/tables/Dynamics1.sol | 2 +- .../src/codegen/tables/Dynamics2.sol | 2 +- .../contracts/src/codegen/tables/Offchain.sol | 2 +- .../src/codegen/tables/Singleton.sol | 2 +- .../contracts/src/codegen/tables/Statics.sol | 2 +- packages/cli/contracts/test/Tablegen.t.sol | 2 +- packages/cli/foundry.toml | 2 +- packages/cli/package.json | 3 +- .../src/codegen/render-solidity/common.ts | 2 +- packages/gas-report/foundry.toml | 2 +- packages/gas-report/src/GasReporter.sol | 2 +- packages/gas-report/test/GasReporter.t.sol | 2 +- packages/noise/contracts/Perlin.sol | 2 +- packages/noise/foundry.toml | 2 +- packages/noise/test/forge/Perlin.t.sol | 2 +- packages/schema-type/foundry.toml | 2 +- .../schema-type/src/solidity/SchemaType.sol | 2 +- .../test/solidity/SchemaType.t.sol | 2 +- packages/store/foundry.toml | 2 +- packages/store/gas-report.json | 218 +++++++++--------- packages/store/src/Bytes.sol | 2 +- packages/store/src/FieldLayout.sol | 2 +- packages/store/src/Hook.sol | 2 +- packages/store/src/IERC165.sol | 2 +- packages/store/src/IStore.sol | 2 +- packages/store/src/IStoreErrors.sol | 2 +- packages/store/src/IStoreHook.sol | 2 +- packages/store/src/Memory.sol | 2 +- packages/store/src/PackedCounter.sol | 2 +- packages/store/src/ResourceId.sol | 2 +- packages/store/src/Schema.sol | 2 +- packages/store/src/Slice.sol | 2 +- packages/store/src/Storage.sol | 2 +- packages/store/src/StoreCore.sol | 2 +- packages/store/src/StoreHook.sol | 2 +- packages/store/src/StoreRead.sol | 2 +- packages/store/src/StoreSwitch.sol | 2 +- packages/store/src/Utils.sol | 2 +- packages/store/src/codegen/common.sol | 2 +- packages/store/src/codegen/index.sol | 2 +- .../store/src/codegen/tables/Callbacks.sol | 2 +- packages/store/src/codegen/tables/Hooks.sol | 2 +- .../store/src/codegen/tables/KeyEncoding.sol | 2 +- packages/store/src/codegen/tables/Mixed.sol | 2 +- .../store/src/codegen/tables/ResourceIds.sol | 2 +- .../store/src/codegen/tables/StoreHooks.sol | 2 +- packages/store/src/codegen/tables/Tables.sol | 2 +- packages/store/src/codegen/tables/Vector2.sol | 2 +- packages/store/src/constants.sol | 2 +- packages/store/src/storeHookTypes.sol | 2 +- packages/store/src/storeResourceTypes.sol | 2 +- packages/store/src/tightcoder/DecodeSlice.sol | 2 +- packages/store/src/tightcoder/EncodeArray.sol | 2 +- packages/store/src/tightcoder/TightCoder.sol | 2 +- packages/store/src/version.sol | 2 +- packages/store/test/Bytes.t.sol | 2 +- packages/store/test/EchoSubscriber.sol | 2 +- packages/store/test/FieldLayout.t.sol | 2 +- .../store/test/FieldLayoutEncodeHelper.sol | 2 +- packages/store/test/Gas.t.sol | 2 +- packages/store/test/GasStorageLoad.t.sol | 2 +- packages/store/test/Hook.t.sol | 2 +- packages/store/test/KeyEncoding.t.sol | 2 +- packages/store/test/MirrorSubscriber.sol | 2 +- packages/store/test/Mixed.t.sol | 2 +- packages/store/test/PackedCounter.t.sol | 2 +- packages/store/test/ResourceId.t.sol | 2 +- packages/store/test/RevertSubscriber.sol | 2 +- packages/store/test/Schema.t.sol | 2 +- packages/store/test/SchemaEncodeHelper.sol | 2 +- packages/store/test/Slice.t.sol | 2 +- packages/store/test/Storage.t.sol | 2 +- packages/store/test/StoreCore.t.sol | 2 +- packages/store/test/StoreCoreDynamic.t.sol | 2 +- packages/store/test/StoreCoreGas.t.sol | 2 +- packages/store/test/StoreHook.t.sol | 2 +- packages/store/test/StoreMock.sol | 2 +- packages/store/test/StoreMock.t.sol | 2 +- packages/store/test/StoreSwitch.t.sol | 2 +- packages/store/test/Utils.t.sol | 2 +- packages/store/test/Vector2.t.sol | 2 +- .../test/setDynamicDataLengthAtIndex.sol | 2 +- packages/store/test/tables/Callbacks.t.sol | 2 +- packages/store/test/tables/StoreHooks.t.sol | 2 +- .../test/tables/StoreHooksColdLoad.t.sol | 2 +- .../store/test/tightcoder/DecodeSlice.t.sol | 2 +- .../store/test/tightcoder/EncodeArray.t.sol | 2 +- .../store/test/tightcoder/TightCoder.t.sol | 2 +- .../test/tightcoder/TightCoderAuto.t.sol | 2 +- packages/world/foundry.toml | 2 +- packages/world/gas-report.json | 130 +++++------ packages/world/src/AccessControl.sol | 2 +- packages/world/src/Delegation.sol | 2 +- packages/world/src/DelegationControl.sol | 2 +- packages/world/src/Module.sol | 2 +- packages/world/src/System.sol | 2 +- packages/world/src/SystemCall.sol | 2 +- packages/world/src/SystemHook.sol | 2 +- packages/world/src/Utils.sol | 2 +- packages/world/src/World.sol | 2 +- packages/world/src/WorldContext.sol | 2 +- packages/world/src/WorldResourceId.sol | 2 +- packages/world/src/constants.sol | 2 +- packages/world/src/factories/Create2.sol | 2 +- .../world/src/factories/Create2Factory.sol | 2 +- .../world/src/factories/IWorldFactory.sol | 2 +- packages/world/src/factories/WorldFactory.sol | 2 +- packages/world/src/index.sol | 2 +- .../interfaces/IAccessManagementSystem.sol | 2 +- .../src/interfaces/IBalanceTransferSystem.sol | 2 +- packages/world/src/interfaces/IBaseWorld.sol | 2 +- packages/world/src/interfaces/ICoreSystem.sol | 2 +- .../src/interfaces/IDelegationControl.sol | 2 +- packages/world/src/interfaces/IERC165.sol | 2 +- packages/world/src/interfaces/IModule.sol | 2 +- .../interfaces/IModuleInstallationSystem.sol | 2 +- packages/world/src/interfaces/ISystemHook.sol | 2 +- .../src/interfaces/IUniqueEntitySystem.sol | 2 +- .../src/interfaces/IWorldContextConsumer.sol | 2 +- .../world/src/interfaces/IWorldErrors.sol | 2 +- .../world/src/interfaces/IWorldKernel.sol | 2 +- .../interfaces/IWorldRegistrationSystem.sol | 2 +- .../world/src/modules/core/CoreModule.sol | 2 +- .../world/src/modules/core/CoreSystem.sol | 2 +- packages/world/src/modules/core/constants.sol | 2 +- .../AccessManagementSystem.sol | 2 +- .../implementations/BalanceTransferSystem.sol | 2 +- .../ModuleInstallationSystem.sol | 2 +- .../StoreRegistrationSystem.sol | 2 +- .../WorldRegistrationSystem.sol | 2 +- .../src/modules/core/tables/Balances.sol | 2 +- .../modules/core/tables/FunctionSelectors.sol | 2 +- .../src/modules/core/tables/SystemHooks.sol | 2 +- .../modules/core/tables/SystemRegistry.sol | 2 +- .../world/src/modules/core/tables/Systems.sol | 2 +- .../modules/keysintable/KeysInTableHook.sol | 2 +- .../modules/keysintable/KeysInTableModule.sol | 2 +- .../src/modules/keysintable/constants.sol | 2 +- .../modules/keysintable/getKeysInTable.sol | 2 +- .../world/src/modules/keysintable/hasKey.sol | 2 +- .../world/src/modules/keysintable/query.sol | 2 +- .../keysintable/tables/KeysInTable.sol | 2 +- .../keysintable/tables/UsedKeysIndex.sol | 2 +- .../keyswithvalue/KeysWithValueHook.sol | 2 +- .../keyswithvalue/KeysWithValueModule.sol | 2 +- .../src/modules/keyswithvalue/constants.sol | 2 +- .../keyswithvalue/getKeysWithValue.sol | 2 +- .../keyswithvalue/getTargetTableId.sol | 2 +- .../keyswithvalue/tables/KeysWithValue.sol | 2 +- .../CallboundDelegationControl.sol | 2 +- .../StandardDelegationsModule.sol | 2 +- .../TimeboundDelegationControl.sol | 2 +- .../src/modules/std-delegations/constants.sol | 2 +- .../tables/CallboundDelegations.sol | 2 +- .../tables/TimeboundDelegations.sol | 2 +- .../uniqueentity/UniqueEntityModule.sol | 2 +- .../uniqueentity/UniqueEntitySystem.sol | 2 +- .../src/modules/uniqueentity/constants.sol | 2 +- .../modules/uniqueentity/getUniqueEntity.sol | 2 +- .../uniqueentity/tables/UniqueEntity.sol | 2 +- packages/world/src/modules/utils/ArrayLib.sol | 2 +- packages/world/src/requireInterface.sol | 2 +- packages/world/src/revertWithBytes.sol | 2 +- packages/world/src/systemHookTypes.sol | 2 +- packages/world/src/tables/Delegations.sol | 2 +- .../world/src/tables/InstalledModules.sol | 2 +- packages/world/src/tables/NamespaceOwner.sol | 2 +- packages/world/src/tables/ResourceAccess.sol | 2 +- packages/world/src/version.sol | 2 +- packages/world/src/worldResourceTypes.sol | 2 +- packages/world/test/AccessControl.t.sol | 2 +- packages/world/test/Factories.t.sol | 2 +- packages/world/test/KeysInTableModule.t.sol | 2 +- packages/world/test/KeysWithValueModule.t.sol | 2 +- packages/world/test/MudTest.t.sol | 2 +- packages/world/test/RevertWithBytes.t.sol | 2 +- .../test/StandardDelegationsModule.t.sol | 2 +- packages/world/test/System.t.sol | 2 +- packages/world/test/SystemHook.t.sol | 2 +- packages/world/test/UniqueEntityModule.t.sol | 2 +- packages/world/test/Utils.t.sol | 2 +- packages/world/test/World.t.sol | 2 +- packages/world/test/WorldBalance.t.sol | 2 +- packages/world/test/WorldContext.t.sol | 2 +- packages/world/test/WorldDynamicUpdate.t.sol | 2 +- packages/world/test/WorldResourceId.t.sol | 2 +- packages/world/test/query.t.sol | 2 +- packages/world/test/tables/AddressArray.sol | 2 +- packages/world/test/tables/Bool.sol | 2 +- templates/phaser/.vscode/settings.json | 3 +- .../phaser/packages/contracts/foundry.toml | 2 +- .../contracts/script/PostDeploy.s.sol | 2 +- .../packages/contracts/src/codegen/index.sol | 2 +- .../contracts/src/codegen/tables/Counter.sol | 2 +- .../src/codegen/world/IIncrementSystem.sol | 2 +- .../contracts/src/codegen/world/IWorld.sol | 2 +- .../contracts/src/systems/IncrementSystem.sol | 2 +- .../packages/contracts/test/CounterTest.t.sol | 2 +- templates/react/.vscode/settings.json | 3 +- .../react/packages/contracts/foundry.toml | 2 +- .../contracts/script/PostDeploy.s.sol | 2 +- .../packages/contracts/src/codegen/index.sol | 2 +- .../contracts/src/codegen/tables/Counter.sol | 2 +- .../src/codegen/world/IIncrementSystem.sol | 2 +- .../contracts/src/codegen/world/IWorld.sol | 2 +- .../contracts/src/systems/IncrementSystem.sol | 2 +- .../packages/contracts/test/CounterTest.t.sol | 2 +- templates/threejs/.vscode/settings.json | 3 +- .../threejs/packages/contracts/foundry.toml | 2 +- .../packages/contracts/src/codegen/index.sol | 2 +- .../contracts/src/codegen/tables/Position.sol | 2 +- .../src/codegen/world/IMoveSystem.sol | 2 +- .../contracts/src/codegen/world/IWorld.sol | 2 +- .../contracts/src/systems/MoveSystem.sol | 2 +- templates/vanilla/.vscode/settings.json | 3 +- .../vanilla/packages/contracts/foundry.toml | 2 +- .../contracts/script/PostDeploy.s.sol | 2 +- .../packages/contracts/src/codegen/index.sol | 2 +- .../contracts/src/codegen/tables/Counter.sol | 2 +- .../src/codegen/world/IIncrementSystem.sol | 2 +- .../contracts/src/codegen/world/IWorld.sol | 2 +- .../contracts/src/systems/IncrementSystem.sol | 2 +- .../packages/contracts/test/CounterTest.t.sol | 2 +- 261 files changed, 450 insertions(+), 432 deletions(-) create mode 100644 .changeset/serious-ads-trade.md diff --git a/.changeset/serious-ads-trade.md b/.changeset/serious-ads-trade.md new file mode 100644 index 0000000000..256b526641 --- /dev/null +++ b/.changeset/serious-ads-trade.md @@ -0,0 +1,12 @@ +--- +"@latticexyz/cli": minor +"@latticexyz/common": minor +"@latticexyz/gas-report": major +"@latticexyz/noise": major +"@latticexyz/schema-type": major +"@latticexyz/store": major +"@latticexyz/world": major +"create-mud": minor +--- + +Bump Solidity version to 0.8.21 diff --git a/.vscode/settings.json b/.vscode/settings.json index 5a44ed867e..2cb0dd5713 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,4 @@ { - "solidity.monoRepoSupport": true + "solidity.monoRepoSupport": true, + "solidity.compileUsingRemoteVersion": "v0.8.21+commit.d9974bed" } diff --git a/e2e/packages/contracts/foundry.toml b/e2e/packages/contracts/foundry.toml index 13a401a75f..d0ed548d14 100644 --- a/e2e/packages/contracts/foundry.toml +++ b/e2e/packages/contracts/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = "0.8.13" +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/e2e/packages/contracts/src/CustomTypes.sol b/e2e/packages/contracts/src/CustomTypes.sol index 0d422e81f0..28973fd5fd 100644 --- a/e2e/packages/contracts/src/CustomTypes.sol +++ b/e2e/packages/contracts/src/CustomTypes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; struct Position { int32 x; diff --git a/e2e/packages/contracts/src/codegen/index.sol b/e2e/packages/contracts/src/codegen/index.sol index 98f8d2feb8..9350bf7b8c 100644 --- a/e2e/packages/contracts/src/codegen/index.sol +++ b/e2e/packages/contracts/src/codegen/index.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/e2e/packages/contracts/src/codegen/tables/Multi.sol b/e2e/packages/contracts/src/codegen/tables/Multi.sol index 56f69dba19..e8ba31b96c 100644 --- a/e2e/packages/contracts/src/codegen/tables/Multi.sol +++ b/e2e/packages/contracts/src/codegen/tables/Multi.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/e2e/packages/contracts/src/codegen/tables/Number.sol b/e2e/packages/contracts/src/codegen/tables/Number.sol index b17b841277..339abd0feb 100644 --- a/e2e/packages/contracts/src/codegen/tables/Number.sol +++ b/e2e/packages/contracts/src/codegen/tables/Number.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/e2e/packages/contracts/src/codegen/tables/NumberList.sol b/e2e/packages/contracts/src/codegen/tables/NumberList.sol index 1510e27581..abfad96a35 100644 --- a/e2e/packages/contracts/src/codegen/tables/NumberList.sol +++ b/e2e/packages/contracts/src/codegen/tables/NumberList.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/e2e/packages/contracts/src/codegen/tables/Vector.sol b/e2e/packages/contracts/src/codegen/tables/Vector.sol index cb2ef6792b..04f83f9775 100644 --- a/e2e/packages/contracts/src/codegen/tables/Vector.sol +++ b/e2e/packages/contracts/src/codegen/tables/Vector.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/e2e/packages/contracts/src/codegen/world/ICustomErrorsSystem.sol b/e2e/packages/contracts/src/codegen/world/ICustomErrorsSystem.sol index 96e07d1059..80029e30ab 100644 --- a/e2e/packages/contracts/src/codegen/world/ICustomErrorsSystem.sol +++ b/e2e/packages/contracts/src/codegen/world/ICustomErrorsSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/e2e/packages/contracts/src/codegen/world/INumberListSystem.sol b/e2e/packages/contracts/src/codegen/world/INumberListSystem.sol index c03f0e812e..8c99ab8a43 100644 --- a/e2e/packages/contracts/src/codegen/world/INumberListSystem.sol +++ b/e2e/packages/contracts/src/codegen/world/INumberListSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/e2e/packages/contracts/src/codegen/world/IWorld.sol b/e2e/packages/contracts/src/codegen/world/IWorld.sol index bdf7fa8603..707adb849c 100644 --- a/e2e/packages/contracts/src/codegen/world/IWorld.sol +++ b/e2e/packages/contracts/src/codegen/world/IWorld.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/e2e/packages/contracts/src/systems/CustomErrorsSystem.sol b/e2e/packages/contracts/src/systems/CustomErrorsSystem.sol index 37b4d59870..7eab852b31 100644 --- a/e2e/packages/contracts/src/systems/CustomErrorsSystem.sol +++ b/e2e/packages/contracts/src/systems/CustomErrorsSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "@latticexyz/world/src/System.sol"; import { Position } from "../CustomTypes.sol"; diff --git a/e2e/packages/contracts/src/systems/NumberListSystem.sol b/e2e/packages/contracts/src/systems/NumberListSystem.sol index 6d48adc115..9309cf5a0e 100644 --- a/e2e/packages/contracts/src/systems/NumberListSystem.sol +++ b/e2e/packages/contracts/src/systems/NumberListSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; diff --git a/e2e/packages/contracts/test/Worldgen.t.sol b/e2e/packages/contracts/test/Worldgen.t.sol index 51d59a7d7c..2db3db9226 100644 --- a/e2e/packages/contracts/test/Worldgen.t.sol +++ b/e2e/packages/contracts/test/Worldgen.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { MudTest } from "@latticexyz/world/test/MudTest.t.sol"; diff --git a/examples/minimal/packages/contracts/foundry.toml b/examples/minimal/packages/contracts/foundry.toml index 851f1b0074..8904c99c97 100644 --- a/examples/minimal/packages/contracts/foundry.toml +++ b/examples/minimal/packages/contracts/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = "0.8.13" +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/examples/minimal/packages/contracts/script/PostDeploy.s.sol b/examples/minimal/packages/contracts/script/PostDeploy.s.sol index 06e875346c..21fb3f9c2b 100644 --- a/examples/minimal/packages/contracts/script/PostDeploy.s.sol +++ b/examples/minimal/packages/contracts/script/PostDeploy.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Script } from "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; diff --git a/examples/minimal/packages/contracts/src/codegen/index.sol b/examples/minimal/packages/contracts/src/codegen/index.sol index eb7f12cff5..46a45a2b39 100644 --- a/examples/minimal/packages/contracts/src/codegen/index.sol +++ b/examples/minimal/packages/contracts/src/codegen/index.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol b/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol index 963e2f4452..9aa6a37376 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol b/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol index d90f9a1343..49f685a0b1 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol index b23dd832b9..ae3ce987db 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/examples/minimal/packages/contracts/src/codegen/world/IChatSystem.sol b/examples/minimal/packages/contracts/src/codegen/world/IChatSystem.sol index 52b9b54d87..95662f9b63 100644 --- a/examples/minimal/packages/contracts/src/codegen/world/IChatSystem.sol +++ b/examples/minimal/packages/contracts/src/codegen/world/IChatSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/examples/minimal/packages/contracts/src/codegen/world/IIncrementSystem.sol b/examples/minimal/packages/contracts/src/codegen/world/IIncrementSystem.sol index 53298f1444..1a13bc9c09 100644 --- a/examples/minimal/packages/contracts/src/codegen/world/IIncrementSystem.sol +++ b/examples/minimal/packages/contracts/src/codegen/world/IIncrementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/examples/minimal/packages/contracts/src/codegen/world/IInventorySystem.sol b/examples/minimal/packages/contracts/src/codegen/world/IInventorySystem.sol index e9ddbadad9..489ce670f6 100644 --- a/examples/minimal/packages/contracts/src/codegen/world/IInventorySystem.sol +++ b/examples/minimal/packages/contracts/src/codegen/world/IInventorySystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/examples/minimal/packages/contracts/src/codegen/world/IStructSystem.sol b/examples/minimal/packages/contracts/src/codegen/world/IStructSystem.sol index e52ee024e3..7ae77d3967 100644 --- a/examples/minimal/packages/contracts/src/codegen/world/IStructSystem.sol +++ b/examples/minimal/packages/contracts/src/codegen/world/IStructSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/examples/minimal/packages/contracts/src/codegen/world/IWorld.sol b/examples/minimal/packages/contracts/src/codegen/world/IWorld.sol index eca91d275d..dc78180f49 100644 --- a/examples/minimal/packages/contracts/src/codegen/world/IWorld.sol +++ b/examples/minimal/packages/contracts/src/codegen/world/IWorld.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/examples/minimal/packages/contracts/src/interfaces/IChatNamespacedSystem.sol b/examples/minimal/packages/contracts/src/interfaces/IChatNamespacedSystem.sol index 9177496daf..ab8bd76b81 100644 --- a/examples/minimal/packages/contracts/src/interfaces/IChatNamespacedSystem.sol +++ b/examples/minimal/packages/contracts/src/interfaces/IChatNamespacedSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; // TODO allow overriding namespace per-system interface IChatNamespacedSystem { diff --git a/examples/minimal/packages/contracts/src/systems/ChatNamespacedSystem.sol b/examples/minimal/packages/contracts/src/systems/ChatNamespacedSystem.sol index 3d43d16f07..fa42fbdada 100644 --- a/examples/minimal/packages/contracts/src/systems/ChatNamespacedSystem.sol +++ b/examples/minimal/packages/contracts/src/systems/ChatNamespacedSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "@latticexyz/world/src/System.sol"; import { MessageTable } from "../codegen/index.sol"; diff --git a/examples/minimal/packages/contracts/src/systems/ChatSystem.sol b/examples/minimal/packages/contracts/src/systems/ChatSystem.sol index e359ef4002..83b1962d08 100644 --- a/examples/minimal/packages/contracts/src/systems/ChatSystem.sol +++ b/examples/minimal/packages/contracts/src/systems/ChatSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "@latticexyz/world/src/System.sol"; import { MessageTable } from "../codegen/index.sol"; diff --git a/examples/minimal/packages/contracts/src/systems/IncrementSystem.sol b/examples/minimal/packages/contracts/src/systems/IncrementSystem.sol index 7d805b655d..7cdf5c28e0 100644 --- a/examples/minimal/packages/contracts/src/systems/IncrementSystem.sol +++ b/examples/minimal/packages/contracts/src/systems/IncrementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { console } from "forge-std/console.sol"; import { System } from "@latticexyz/world/src/System.sol"; import { CounterTable } from "../codegen/index.sol"; diff --git a/examples/minimal/packages/contracts/src/systems/InventorySystem.sol b/examples/minimal/packages/contracts/src/systems/InventorySystem.sol index 6360871dde..a22f30c3fe 100644 --- a/examples/minimal/packages/contracts/src/systems/InventorySystem.sol +++ b/examples/minimal/packages/contracts/src/systems/InventorySystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "@latticexyz/world/src/System.sol"; import { Inventory } from "../codegen/index.sol"; diff --git a/examples/minimal/packages/contracts/src/systems/StructSystem.sol b/examples/minimal/packages/contracts/src/systems/StructSystem.sol index 5fe1ad91cb..9ec22140ea 100644 --- a/examples/minimal/packages/contracts/src/systems/StructSystem.sol +++ b/examples/minimal/packages/contracts/src/systems/StructSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "@latticexyz/world/src/System.sol"; import { CounterTable } from "../codegen/index.sol"; import { BytesStruct, StringStruct } from "./structs.sol"; diff --git a/examples/minimal/packages/contracts/src/systems/structs.sol b/examples/minimal/packages/contracts/src/systems/structs.sol index 66d4e90894..c404977f9c 100644 --- a/examples/minimal/packages/contracts/src/systems/structs.sol +++ b/examples/minimal/packages/contracts/src/systems/structs.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; struct BytesStruct { bytes value; diff --git a/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol b/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol index 122f2392f2..c8599537dd 100644 --- a/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol +++ b/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { MudTest } from "@latticexyz/world/test/MudTest.t.sol"; diff --git a/examples/minimal/packages/contracts/test/CounterTest.t.sol b/examples/minimal/packages/contracts/test/CounterTest.t.sol index f731279df5..959655f295 100644 --- a/examples/minimal/packages/contracts/test/CounterTest.t.sol +++ b/examples/minimal/packages/contracts/test/CounterTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { MudTest } from "@latticexyz/world/test/MudTest.t.sol"; diff --git a/examples/minimal/packages/contracts/test/StructTest.t.sol b/examples/minimal/packages/contracts/test/StructTest.t.sol index 87b67846da..dc824e30bf 100644 --- a/examples/minimal/packages/contracts/test/StructTest.t.sol +++ b/examples/minimal/packages/contracts/test/StructTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { MudTest } from "@latticexyz/world/test/MudTest.t.sol"; diff --git a/packages/cli/contracts/src/codegen/common.sol b/packages/cli/contracts/src/codegen/common.sol index 85fa534462..6d5e7d6de5 100644 --- a/packages/cli/contracts/src/codegen/common.sol +++ b/packages/cli/contracts/src/codegen/common.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ enum Enum1 { diff --git a/packages/cli/contracts/src/codegen/index.sol b/packages/cli/contracts/src/codegen/index.sol index 49830113c3..f3298837cf 100644 --- a/packages/cli/contracts/src/codegen/index.sol +++ b/packages/cli/contracts/src/codegen/index.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol index 3675d141c5..4ffe32a5a9 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol index e233e4e5f3..86447e9503 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/cli/contracts/src/codegen/tables/Offchain.sol b/packages/cli/contracts/src/codegen/tables/Offchain.sol index 90d628f248..9400c79ef6 100644 --- a/packages/cli/contracts/src/codegen/tables/Offchain.sol +++ b/packages/cli/contracts/src/codegen/tables/Offchain.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/cli/contracts/src/codegen/tables/Singleton.sol b/packages/cli/contracts/src/codegen/tables/Singleton.sol index f55dc19ff7..1e87e6d89c 100644 --- a/packages/cli/contracts/src/codegen/tables/Singleton.sol +++ b/packages/cli/contracts/src/codegen/tables/Singleton.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/cli/contracts/src/codegen/tables/Statics.sol b/packages/cli/contracts/src/codegen/tables/Statics.sol index dfb0cde25b..695fbbf683 100644 --- a/packages/cli/contracts/src/codegen/tables/Statics.sol +++ b/packages/cli/contracts/src/codegen/tables/Statics.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/cli/contracts/test/Tablegen.t.sol b/packages/cli/contracts/test/Tablegen.t.sol index 8a71d7fb9e..204566a7a1 100644 --- a/packages/cli/contracts/test/Tablegen.t.sol +++ b/packages/cli/contracts/test/Tablegen.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { StoreMock } from "@latticexyz/store/test/StoreMock.sol"; diff --git a/packages/cli/foundry.toml b/packages/cli/foundry.toml index edd9dc7bbc..5b52f76616 100644 --- a/packages/cli/foundry.toml +++ b/packages/cli/foundry.toml @@ -1,6 +1,6 @@ [profile.default] # check all "WARNING:" comments before changing major solidity versions -solc_version = "0.8.13" +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/packages/cli/package.json b/packages/cli/package.json index 667a7d7765..4ebf52eae8 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -20,8 +20,9 @@ "build": "pnpm run build:js && pnpm run build:test-tables", "build:js": "tsup && chmod +x ./dist/mud.js", "build:test-tables": "tsx ./scripts/generate-test-tables.ts", - "clean": "pnpm run clean:js", + "clean": "pnpm run clean:js && pnpm run clean:test-tables", "clean:js": "rimraf dist", + "clean:test-tables": "rimraf src/codegen", "dev": "tsup --watch", "lint": "eslint . --ext .ts", "prepare": "mkdir -p ./dist && touch ./dist/mud.js", diff --git a/packages/common/src/codegen/render-solidity/common.ts b/packages/common/src/codegen/render-solidity/common.ts index f956f7b658..14e668c3d2 100644 --- a/packages/common/src/codegen/render-solidity/common.ts +++ b/packages/common/src/codegen/render-solidity/common.ts @@ -10,7 +10,7 @@ import { import { posixPath } from "../utils"; export const renderedSolidityHeader = `// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */`; diff --git a/packages/gas-report/foundry.toml b/packages/gas-report/foundry.toml index 99e1244225..561e05fc7b 100644 --- a/packages/gas-report/foundry.toml +++ b/packages/gas-report/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = '0.8.13' +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/packages/gas-report/src/GasReporter.sol b/packages/gas-report/src/GasReporter.sol index 60b1784697..d3ca40ccc3 100644 --- a/packages/gas-report/src/GasReporter.sol +++ b/packages/gas-report/src/GasReporter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; diff --git a/packages/gas-report/test/GasReporter.t.sol b/packages/gas-report/test/GasReporter.t.sol index 0780642d12..bc4a2107b7 100644 --- a/packages/gas-report/test/GasReporter.t.sol +++ b/packages/gas-report/test/GasReporter.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "../src/GasReporter.sol"; diff --git a/packages/noise/contracts/Perlin.sol b/packages/noise/contracts/Perlin.sol index f2a06211f2..243f7ce2f8 100644 --- a/packages/noise/contracts/Perlin.sol +++ b/packages/noise/contracts/Perlin.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; +pragma solidity >=0.8.21; import { ABDKMath64x64 as Math } from "abdk-libraries-solidity/ABDKMath64x64.sol"; diff --git a/packages/noise/foundry.toml b/packages/noise/foundry.toml index 79cd1475c4..aad1d8ec32 100644 --- a/packages/noise/foundry.toml +++ b/packages/noise/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = "0.8.13" +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/packages/noise/test/forge/Perlin.t.sol b/packages/noise/test/forge/Perlin.t.sol index 013ec96b8d..2148d22cd0 100644 --- a/packages/noise/test/forge/Perlin.t.sol +++ b/packages/noise/test/forge/Perlin.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { Perlin } from "../../contracts/Perlin.sol"; diff --git a/packages/schema-type/foundry.toml b/packages/schema-type/foundry.toml index 0653ef0221..e48d006f08 100644 --- a/packages/schema-type/foundry.toml +++ b/packages/schema-type/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = "0.8.13" +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/packages/schema-type/src/solidity/SchemaType.sol b/packages/schema-type/src/solidity/SchemaType.sol index 17536170df..d3090625c8 100644 --- a/packages/schema-type/src/solidity/SchemaType.sol +++ b/packages/schema-type/src/solidity/SchemaType.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; using { getStaticByteLength } for SchemaType global; diff --git a/packages/schema-type/test/solidity/SchemaType.t.sol b/packages/schema-type/test/solidity/SchemaType.t.sol index 3b7684e524..6a18498a9c 100644 --- a/packages/schema-type/test/solidity/SchemaType.t.sol +++ b/packages/schema-type/test/solidity/SchemaType.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { stdError } from "forge-std/StdError.sol"; diff --git a/packages/store/foundry.toml b/packages/store/foundry.toml index 99e1244225..561e05fc7b 100644 --- a/packages/store/foundry.toml +++ b/packages/store/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = '0.8.13' +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/packages/store/gas-report.json b/packages/store/gas-report.json index 3c65f6ecb2..866d3ea5a4 100644 --- a/packages/store/gas-report.json +++ b/packages/store/gas-report.json @@ -69,7 +69,7 @@ "file": "test/FieldLayout.t.sol", "test": "testEncodeDecodeFieldLayout", "name": "encode field layout with 5+1 entries", - "gasUsed": 2378 + "gasUsed": 2440 }, { "file": "test/FieldLayout.t.sol", @@ -81,7 +81,7 @@ "file": "test/FieldLayout.t.sol", "test": "testGetNumDynamicFields", "name": "get number of dynamic fields from field layout", - "gasUsed": 363 + "gasUsed": 389 }, { "file": "test/FieldLayout.t.sol", @@ -93,13 +93,13 @@ "file": "test/FieldLayout.t.sol", "test": "testGetNumStaticFields", "name": "get number of static fields from field layout", - "gasUsed": 293 + "gasUsed": 311 }, { "file": "test/FieldLayout.t.sol", "test": "testGetStaticFieldLayoutLength", "name": "get static data length from field layout", - "gasUsed": 218 + "gasUsed": 228 }, { "file": "test/FieldLayout.t.sol", @@ -117,7 +117,7 @@ "file": "test/FieldLayout.t.sol", "test": "testValidate", "name": "validate field layout", - "gasUsed": 3944 + "gasUsed": 3993 }, { "file": "test/Gas.t.sol", @@ -129,19 +129,19 @@ "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "abi encode (dynamic)", - "gasUsed": 849 + "gasUsed": 824 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "abi encode", - "gasUsed": 943 + "gasUsed": 918 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "abi decode", - "gasUsed": 1741 + "gasUsed": 1716 }, { "file": "test/Gas.t.sol", @@ -159,31 +159,31 @@ "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "custom encode (dynamic)", - "gasUsed": 1152 + "gasUsed": 1101 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "custom encode", - "gasUsed": 1571 + "gasUsed": 1520 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "custom decode", - "gasUsed": 2020 + "gasUsed": 2046 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "pass abi encoded bytes to external contract", - "gasUsed": 6562 + "gasUsed": 6549 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "pass custom encoded bytes to external contract", - "gasUsed": 1451 + "gasUsed": 1426 }, { "file": "test/Gas.t.sol", @@ -237,7 +237,7 @@ "file": "test/Gas.t.sol", "test": "testCompareStorageWriteSolidity", "name": "solidity storage write (cold, 10 words)", - "gasUsed": 199902 + "gasUsed": 200020 }, { "file": "test/Gas.t.sol", @@ -255,7 +255,7 @@ "file": "test/Gas.t.sol", "test": "testCompareStorageWriteSolidity", "name": "solidity storage write (warm, 10 words)", - "gasUsed": 1988 + "gasUsed": 2265 }, { "file": "test/GasStorageLoad.t.sol", @@ -351,31 +351,31 @@ "file": "test/KeyEncoding.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "register KeyEncoding table", - "gasUsed": 720118 + "gasUsed": 720205 }, { "file": "test/Mixed.t.sol", "test": "testCompareSolidity", "name": "store Mixed struct in storage (native solidity)", - "gasUsed": 92038 + "gasUsed": 92007 }, { "file": "test/Mixed.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "register Mixed table", - "gasUsed": 581944 + "gasUsed": 582081 }, { "file": "test/Mixed.t.sol", "test": "testSetAndGet", "name": "set record in Mixed", - "gasUsed": 103976 + "gasUsed": 103978 }, { "file": "test/Mixed.t.sol", "test": "testSetAndGet", "name": "get record from Mixed", - "gasUsed": 7025 + "gasUsed": 7091 }, { "file": "test/PackedCounter.t.sol", @@ -405,13 +405,13 @@ "file": "test/PackedCounter.t.sol", "test": "testSetAtIndex", "name": "set value at index of PackedCounter", - "gasUsed": 286 + "gasUsed": 283 }, { "file": "test/ResourceId.t.sol", "test": "testEncode", "name": "encode table ID with name and type", - "gasUsed": 188 + "gasUsed": 185 }, { "file": "test/ResourceId.t.sol", @@ -429,19 +429,19 @@ "file": "test/Schema.t.sol", "test": "testEncodeDecodeSchema", "name": "encode schema with 6 entries", - "gasUsed": 3555 + "gasUsed": 3609 }, { "file": "test/Schema.t.sol", "test": "testEncodeDecodeSchema", "name": "get schema type at index", - "gasUsed": 115 + "gasUsed": 119 }, { "file": "test/Schema.t.sol", "test": "testGetNumDynamicFields", "name": "get number of dynamic fields from schema", - "gasUsed": 363 + "gasUsed": 389 }, { "file": "test/Schema.t.sol", @@ -453,13 +453,13 @@ "file": "test/Schema.t.sol", "test": "testGetNumStaticFields", "name": "get number of static fields from schema", - "gasUsed": 293 + "gasUsed": 311 }, { "file": "test/Schema.t.sol", "test": "testGetStaticSchemaLength", "name": "get static data length from schema", - "gasUsed": 218 + "gasUsed": 228 }, { "file": "test/Schema.t.sol", @@ -477,7 +477,7 @@ "file": "test/Schema.t.sol", "test": "testValidate", "name": "validate schema", - "gasUsed": 11336 + "gasUsed": 11497 }, { "file": "test/Slice.t.sol", @@ -501,13 +501,13 @@ "file": "test/Slice.t.sol", "test": "testSubslice", "name": "subslice bytes (no copy) [1:4]", - "gasUsed": 311 + "gasUsed": 324 }, { "file": "test/Slice.t.sol", "test": "testSubslice", "name": "subslice bytes (no copy) [4:37]", - "gasUsed": 311 + "gasUsed": 324 }, { "file": "test/Slice.t.sol", @@ -573,109 +573,109 @@ "file": "test/StoreCoreDynamic.t.sol", "test": "testGetFieldSlice", "name": "get field slice (cold, 1 slot)", - "gasUsed": 8282 + "gasUsed": 8311 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testGetFieldSlice", "name": "get field slice (warm, 1 slot)", - "gasUsed": 2350 + "gasUsed": 2383 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testGetFieldSlice", "name": "get field slice (semi-cold, 1 slot)", - "gasUsed": 4353 + "gasUsed": 4386 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testGetFieldSlice", "name": "get field slice (warm, 2 slots)", - "gasUsed": 4579 + "gasUsed": 4608 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testGetSecondFieldLength", "name": "get field length (cold, 1 slot)", - "gasUsed": 7744 + "gasUsed": 7754 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testGetSecondFieldLength", "name": "get field length (warm, 1 slot)", - "gasUsed": 1739 + "gasUsed": 1749 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testGetThirdFieldLength", "name": "get field length (warm due to , 2 slots)", - "gasUsed": 7743 + "gasUsed": 7753 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testGetThirdFieldLength", "name": "get field length (warm, 2 slots)", - "gasUsed": 1739 + "gasUsed": 1749 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (cold, 1 slot, 1 uint32 item)", - "gasUsed": 19449 + "gasUsed": 19479 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (warm, 1 slot, 1 uint32 item)", - "gasUsed": 13457 + "gasUsed": 13487 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (cold, 2 slots, 10 uint32 items)", - "gasUsed": 17217 + "gasUsed": 17247 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (warm, 2 slots, 10 uint32 items)", - "gasUsed": 13225 + "gasUsed": 13255 }, { "file": "test/StoreCoreGas.t.sol", "test": "testAccessEmptyData", "name": "access non-existing record", - "gasUsed": 7042 + "gasUsed": 7077 }, { "file": "test/StoreCoreGas.t.sol", "test": "testAccessEmptyData", "name": "access static field of non-existing record", - "gasUsed": 1318 + "gasUsed": 1333 }, { "file": "test/StoreCoreGas.t.sol", "test": "testAccessEmptyData", "name": "access dynamic field of non-existing record", - "gasUsed": 2034 + "gasUsed": 2059 }, { "file": "test/StoreCoreGas.t.sol", "test": "testAccessEmptyData", "name": "access length of dynamic field of non-existing record", - "gasUsed": 1108 + "gasUsed": 1118 }, { "file": "test/StoreCoreGas.t.sol", "test": "testAccessEmptyData", "name": "access slice of dynamic field of non-existing record", - "gasUsed": 1484 + "gasUsed": 1517 }, { "file": "test/StoreCoreGas.t.sol", "test": "testDeleteData", "name": "delete record (complex data, 3 slots)", - "gasUsed": 6735 + "gasUsed": 6778 }, { "file": "test/StoreCoreGas.t.sol", @@ -693,175 +693,175 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "register subscriber", - "gasUsed": 58766 + "gasUsed": 58781 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set record on table with subscriber", - "gasUsed": 71311 + "gasUsed": 71248 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set static field on table with subscriber", - "gasUsed": 20788 + "gasUsed": 20732 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "delete record on table with subscriber", - "gasUsed": 16784 + "gasUsed": 16870 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "register subscriber", - "gasUsed": 58766 + "gasUsed": 58781 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) record on table with subscriber", - "gasUsed": 164432 + "gasUsed": 164402 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) field on table with subscriber", - "gasUsed": 24552 + "gasUsed": 24526 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "delete (dynamic) record on table with subscriber", - "gasUsed": 17769 + "gasUsed": 17855 }, { "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (1 slot, 1 uint32 item)", - "gasUsed": 10260 + "gasUsed": 10275 }, { "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (2 slots, 10 uint32 items)", - "gasUsed": 32930 + "gasUsed": 32945 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "StoreCore: register table", - "gasUsed": 642065 + "gasUsed": 642079 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "StoreCore: get field layout (warm)", - "gasUsed": 1293 + "gasUsed": 1287 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "StoreCore: get value schema (warm)", - "gasUsed": 1804 + "gasUsed": 1808 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "StoreCore: get key schema (warm)", - "gasUsed": 2827 + "gasUsed": 2826 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetDynamicData", "name": "set complex record with dynamic data (4 slots)", - "gasUsed": 101874 + "gasUsed": 101934 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetDynamicData", "name": "get complex record with dynamic data (4 slots)", - "gasUsed": 4203 + "gasUsed": 4243 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetDynamicData", "name": "compare: Set complex record with dynamic data using native solidity", - "gasUsed": 116845 + "gasUsed": 116821 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetDynamicData", "name": "compare: Set complex record with dynamic data using abi.encode", - "gasUsed": 267369 + "gasUsed": 267535 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetDynamicDataLength", "name": "set dynamic length of dynamic index 0", - "gasUsed": 22870 + "gasUsed": 22867 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetDynamicDataLength", "name": "set dynamic length of dynamic index 1", - "gasUsed": 971 + "gasUsed": 968 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetDynamicDataLength", "name": "reduce dynamic length of dynamic index 0", - "gasUsed": 961 + "gasUsed": 958 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set static field (1 slot)", - "gasUsed": 31604 + "gasUsed": 31607 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "get static field (1 slot)", - "gasUsed": 1318 + "gasUsed": 1333 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set static field (overlap 2 slot)", - "gasUsed": 30245 + "gasUsed": 30260 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "get static field (overlap 2 slot)", - "gasUsed": 1845 + "gasUsed": 1865 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set dynamic field (1 slot, first dynamic field)", - "gasUsed": 53959 + "gasUsed": 53974 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "get dynamic field (1 slot, first dynamic field)", - "gasUsed": 2201 + "gasUsed": 2226 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set dynamic field (1 slot, second dynamic field)", - "gasUsed": 32182 + "gasUsed": 32197 }, { "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "get dynamic field (1 slot, second dynamic field)", - "gasUsed": 2204 + "gasUsed": 2229 }, { "file": "test/StoreCoreGas.t.sol", @@ -873,7 +873,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetStaticData", "name": "get static record (1 slot)", - "gasUsed": 1524 + "gasUsed": 1554 }, { "file": "test/StoreCoreGas.t.sol", @@ -885,25 +885,25 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetStaticDataSpanningWords", "name": "get static record (2 slots)", - "gasUsed": 1711 + "gasUsed": 1741 }, { "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "update in field (1 slot, 1 uint32 item)", - "gasUsed": 9604 + "gasUsed": 9627 }, { "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "push to field (2 slots, 6 uint64 items)", - "gasUsed": 10043 + "gasUsed": 10073 }, { "file": "test/StoreHook.t.sol", "test": "testCallHook", "name": "call an enabled hook", - "gasUsed": 15038 + "gasUsed": 15032 }, { "file": "test/StoreHook.t.sol", @@ -939,121 +939,121 @@ "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: set field", - "gasUsed": 57051 + "gasUsed": 57069 }, { "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: get field (warm)", - "gasUsed": 2902 + "gasUsed": 2915 }, { "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: push 1 element", - "gasUsed": 33332 + "gasUsed": 33351 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testOneSlot", "name": "StoreHooks: set field with one elements (cold)", - "gasUsed": 59057 + "gasUsed": 59075 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: set field (cold)", - "gasUsed": 59057 + "gasUsed": 59075 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: get field (warm)", - "gasUsed": 2904 + "gasUsed": 2921 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: push 1 element (cold)", - "gasUsed": 13430 + "gasUsed": 13449 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: pop 1 element (warm)", - "gasUsed": 10743 + "gasUsed": 10777 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: push 1 element (warm)", - "gasUsed": 11447 + "gasUsed": 11466 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: update 1 element (warm)", - "gasUsed": 30659 + "gasUsed": 30686 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: delete record (warm)", - "gasUsed": 7163 + "gasUsed": 7210 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: set field (warm)", - "gasUsed": 31201 + "gasUsed": 31219 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testThreeSlots", "name": "StoreHooks: set field with three elements (cold)", - "gasUsed": 81745 + "gasUsed": 81763 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTwoSlots", "name": "StoreHooks: set field with two elements (cold)", - "gasUsed": 81657 + "gasUsed": 81675 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testDelete", "name": "StoreHooks: delete record (cold)", - "gasUsed": 16031 + "gasUsed": 16078 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testGet", "name": "StoreHooks: get field (cold)", - "gasUsed": 8901 + "gasUsed": 8918 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testGetItem", "name": "StoreHooks: get 1 element (cold)", - "gasUsed": 6542 + "gasUsed": 6575 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testLength", "name": "StoreHooks: get length (cold)", - "gasUsed": 5861 + "gasUsed": 5871 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testPop", "name": "StoreHooks: pop 1 element (cold)", - "gasUsed": 19178 + "gasUsed": 19212 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testUpdate", "name": "StoreHooks: update 1 element (cold)", - "gasUsed": 21114 + "gasUsed": 21141 }, { "file": "test/tightcoder/DecodeSlice.t.sol", @@ -1071,19 +1071,19 @@ "file": "test/tightcoder/EncodeArray.t.sol", "test": "testEncodeUint16Array", "name": "encode packed uint16[]", - "gasUsed": 595 + "gasUsed": 594 }, { "file": "test/tightcoder/EncodeArray.t.sol", "test": "testEncodeUint32Array", "name": "encode packed uint32[]", - "gasUsed": 504 + "gasUsed": 503 }, { "file": "test/tightcoder/EncodeArray.t.sol", "test": "testEncodeUint8Array", "name": "encode packed uint8[]", - "gasUsed": 493 + "gasUsed": 492 }, { "file": "test/tightcoder/TightCoder.t.sol", @@ -1095,7 +1095,7 @@ "file": "test/tightcoder/TightCoder.t.sol", "test": "testToAndFromBytes24Array", "name": "encode packed bytes24[]", - "gasUsed": 501 + "gasUsed": 503 }, { "file": "test/tightcoder/TightCoder.t.sol", @@ -1107,18 +1107,18 @@ "file": "test/Vector2.t.sol", "test": "testRegisterAndGetFieldLayout", "name": "register Vector2 field layout", - "gasUsed": 443387 + "gasUsed": 443558 }, { "file": "test/Vector2.t.sol", "test": "testSetAndGet", "name": "set Vector2 record", - "gasUsed": 33103 + "gasUsed": 33096 }, { "file": "test/Vector2.t.sol", "test": "testSetAndGet", "name": "get Vector2 record", - "gasUsed": 2514 + "gasUsed": 2540 } ] diff --git a/packages/store/src/Bytes.sol b/packages/store/src/Bytes.sol index 8853b52fd4..c8713703d3 100644 --- a/packages/store/src/Bytes.sol +++ b/packages/store/src/Bytes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; library Bytes { /** diff --git a/packages/store/src/FieldLayout.sol b/packages/store/src/FieldLayout.sol index 86759aa24c..80fd3d2cba 100644 --- a/packages/store/src/FieldLayout.sol +++ b/packages/store/src/FieldLayout.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { WORD_SIZE, WORD_LAST_INDEX, BYTE_TO_BITS, MAX_TOTAL_FIELDS, MAX_DYNAMIC_FIELDS, LayoutOffsets } from "./constants.sol"; diff --git a/packages/store/src/Hook.sol b/packages/store/src/Hook.sol index bba92c89aa..cbe73fe03b 100644 --- a/packages/store/src/Hook.sol +++ b/packages/store/src/Hook.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Hooks } from "./codegen/tables/Hooks.sol"; import { ResourceId } from "./ResourceId.sol"; diff --git a/packages/store/src/IERC165.sol b/packages/store/src/IERC165.sol index 4151b0a405..db080dc11f 100644 --- a/packages/store/src/IERC165.sol +++ b/packages/store/src/IERC165.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; bytes4 constant ERC165_INTERFACE_ID = IERC165.supportsInterface.selector; diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index cae2ec6f36..0a01ae2511 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStoreErrors } from "./IStoreErrors.sol"; import { PackedCounter } from "./PackedCounter.sol"; diff --git a/packages/store/src/IStoreErrors.sol b/packages/store/src/IStoreErrors.sol index 1b42a84107..239d064035 100644 --- a/packages/store/src/IStoreErrors.sol +++ b/packages/store/src/IStoreErrors.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { ResourceId } from "./ResourceId.sol"; diff --git a/packages/store/src/IStoreHook.sol b/packages/store/src/IStoreHook.sol index 271e07ac97..b8a1b70947 100644 --- a/packages/store/src/IStoreHook.sol +++ b/packages/store/src/IStoreHook.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { FieldLayout } from "./FieldLayout.sol"; import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; diff --git a/packages/store/src/Memory.sol b/packages/store/src/Memory.sol index 4872c9423a..8cea12e9ab 100644 --- a/packages/store/src/Memory.sol +++ b/packages/store/src/Memory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { leftMask } from "./Utils.sol"; diff --git a/packages/store/src/PackedCounter.sol b/packages/store/src/PackedCounter.sol index 32f0aa2a7a..20a8a7df57 100644 --- a/packages/store/src/PackedCounter.sol +++ b/packages/store/src/PackedCounter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; // - Last 7 bytes (uint56) are used for the total byte length of the dynamic data // - The next 5 byte (uint40) sections are used for the byte length of each field, indexed from right to left diff --git a/packages/store/src/ResourceId.sol b/packages/store/src/ResourceId.sol index 20dec4c6b8..39be771465 100644 --- a/packages/store/src/ResourceId.sol +++ b/packages/store/src/ResourceId.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; type ResourceId is bytes32; diff --git a/packages/store/src/Schema.sol b/packages/store/src/Schema.sol index 0d47200371..8e935196a7 100644 --- a/packages/store/src/Schema.sol +++ b/packages/store/src/Schema.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; diff --git a/packages/store/src/Slice.sol b/packages/store/src/Slice.sol index 853dfa292a..85acce0ff1 100644 --- a/packages/store/src/Slice.sol +++ b/packages/store/src/Slice.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Memory } from "./Memory.sol"; import { DecodeSlice } from "./tightcoder/DecodeSlice.sol"; diff --git a/packages/store/src/Storage.sol b/packages/store/src/Storage.sol index 427e45748f..d8745b3636 100644 --- a/packages/store/src/Storage.sol +++ b/packages/store/src/Storage.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { leftMask } from "./Utils.sol"; import { Memory } from "./Memory.sol"; diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index f5baaa3546..4db4bb6d1a 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { STORE_VERSION } from "./version.sol"; import { Bytes } from "./Bytes.sol"; diff --git a/packages/store/src/StoreHook.sol b/packages/store/src/StoreHook.sol index 19db392bb7..fae57d9cec 100644 --- a/packages/store/src/StoreHook.sol +++ b/packages/store/src/StoreHook.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStoreHook, STORE_HOOK_INTERFACE_ID } from "./IStoreHook.sol"; import { ERC165_INTERFACE_ID } from "./IERC165.sol"; diff --git a/packages/store/src/StoreRead.sol b/packages/store/src/StoreRead.sol index f4925e77eb..386e3c7f29 100644 --- a/packages/store/src/StoreRead.sol +++ b/packages/store/src/StoreRead.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { STORE_VERSION } from "./version.sol"; import { IStoreRead } from "./IStore.sol"; diff --git a/packages/store/src/StoreSwitch.sol b/packages/store/src/StoreSwitch.sol index ba483f2dea..2c540fec70 100644 --- a/packages/store/src/StoreSwitch.sol +++ b/packages/store/src/StoreSwitch.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStore } from "./IStore.sol"; import { PackedCounter } from "../src/PackedCounter.sol"; diff --git a/packages/store/src/Utils.sol b/packages/store/src/Utils.sol index 85eefd1544..16355a562b 100644 --- a/packages/store/src/Utils.sol +++ b/packages/store/src/Utils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /** * Adapted from https://github.com/dk1a/solidity-stringutils/blob/main/src/utils/mem.sol#L149-L167 diff --git a/packages/store/src/codegen/common.sol b/packages/store/src/codegen/common.sol index 8be6d938c7..4f6c334a8e 100644 --- a/packages/store/src/codegen/common.sol +++ b/packages/store/src/codegen/common.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ enum ExampleEnum { diff --git a/packages/store/src/codegen/index.sol b/packages/store/src/codegen/index.sol index 7e033ae735..62f886fe46 100644 --- a/packages/store/src/codegen/index.sol +++ b/packages/store/src/codegen/index.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/store/src/codegen/tables/Callbacks.sol b/packages/store/src/codegen/tables/Callbacks.sol index 4dcbce5052..23315c30a9 100644 --- a/packages/store/src/codegen/tables/Callbacks.sol +++ b/packages/store/src/codegen/tables/Callbacks.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/store/src/codegen/tables/Hooks.sol b/packages/store/src/codegen/tables/Hooks.sol index 34f6c804cf..e836bd9352 100644 --- a/packages/store/src/codegen/tables/Hooks.sol +++ b/packages/store/src/codegen/tables/Hooks.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/store/src/codegen/tables/KeyEncoding.sol b/packages/store/src/codegen/tables/KeyEncoding.sol index 6a198c2d27..2351d5ee75 100644 --- a/packages/store/src/codegen/tables/KeyEncoding.sol +++ b/packages/store/src/codegen/tables/KeyEncoding.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/store/src/codegen/tables/Mixed.sol b/packages/store/src/codegen/tables/Mixed.sol index 48c8678ba9..4d493762ae 100644 --- a/packages/store/src/codegen/tables/Mixed.sol +++ b/packages/store/src/codegen/tables/Mixed.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/store/src/codegen/tables/ResourceIds.sol b/packages/store/src/codegen/tables/ResourceIds.sol index 273a4c6fb0..9414ce5464 100644 --- a/packages/store/src/codegen/tables/ResourceIds.sol +++ b/packages/store/src/codegen/tables/ResourceIds.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/store/src/codegen/tables/StoreHooks.sol b/packages/store/src/codegen/tables/StoreHooks.sol index b900ad3640..63f987692c 100644 --- a/packages/store/src/codegen/tables/StoreHooks.sol +++ b/packages/store/src/codegen/tables/StoreHooks.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/store/src/codegen/tables/Tables.sol b/packages/store/src/codegen/tables/Tables.sol index 04d49cd786..f0d2954252 100644 --- a/packages/store/src/codegen/tables/Tables.sol +++ b/packages/store/src/codegen/tables/Tables.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/store/src/codegen/tables/Vector2.sol b/packages/store/src/codegen/tables/Vector2.sol index 71f23b8be2..28ccb78e42 100644 --- a/packages/store/src/codegen/tables/Vector2.sol +++ b/packages/store/src/codegen/tables/Vector2.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/store/src/constants.sol b/packages/store/src/constants.sol index a5f580b6ec..53e7ec4e79 100644 --- a/packages/store/src/constants.sol +++ b/packages/store/src/constants.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Shared constants */ diff --git a/packages/store/src/storeHookTypes.sol b/packages/store/src/storeHookTypes.sol index d6d424591a..0afa815d6a 100644 --- a/packages/store/src/storeHookTypes.sol +++ b/packages/store/src/storeHookTypes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; uint8 constant BEFORE_SET_RECORD = 1 << 0; uint8 constant AFTER_SET_RECORD = 1 << 1; diff --git a/packages/store/src/storeResourceTypes.sol b/packages/store/src/storeResourceTypes.sol index 5854db2429..0150e70d5d 100644 --- a/packages/store/src/storeResourceTypes.sol +++ b/packages/store/src/storeResourceTypes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; bytes2 constant RESOURCE_TABLE = "tb"; bytes2 constant RESOURCE_OFFCHAIN_TABLE = "ot"; diff --git a/packages/store/src/tightcoder/DecodeSlice.sol b/packages/store/src/tightcoder/DecodeSlice.sol index d1a6348f8a..b6a744ae24 100644 --- a/packages/store/src/tightcoder/DecodeSlice.sol +++ b/packages/store/src/tightcoder/DecodeSlice.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ import { TightCoder } from "./TightCoder.sol"; diff --git a/packages/store/src/tightcoder/EncodeArray.sol b/packages/store/src/tightcoder/EncodeArray.sol index 455db997b6..816e00407d 100644 --- a/packages/store/src/tightcoder/EncodeArray.sol +++ b/packages/store/src/tightcoder/EncodeArray.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ import { TightCoder } from "./TightCoder.sol"; diff --git a/packages/store/src/tightcoder/TightCoder.sol b/packages/store/src/tightcoder/TightCoder.sol index 2af4eecc0c..d47a97bcab 100644 --- a/packages/store/src/tightcoder/TightCoder.sol +++ b/packages/store/src/tightcoder/TightCoder.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Slice, SliceLib } from "../Slice.sol"; diff --git a/packages/store/src/version.sol b/packages/store/src/version.sol index 9f024319ad..796d38cea6 100644 --- a/packages/store/src/version.sol +++ b/packages/store/src/version.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; bytes32 constant STORE_VERSION = "0.0.0"; diff --git a/packages/store/test/Bytes.t.sol b/packages/store/test/Bytes.t.sol index 8ae2e11693..1c90b6bc93 100644 --- a/packages/store/test/Bytes.t.sol +++ b/packages/store/test/Bytes.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/EchoSubscriber.sol b/packages/store/test/EchoSubscriber.sol index 90e9ca592f..6612677719 100644 --- a/packages/store/test/EchoSubscriber.sol +++ b/packages/store/test/EchoSubscriber.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { PackedCounter } from "../src/PackedCounter.sol"; import { FieldLayout } from "../src/FieldLayout.sol"; diff --git a/packages/store/test/FieldLayout.t.sol b/packages/store/test/FieldLayout.t.sol index c8f302e1fa..39424c1157 100644 --- a/packages/store/test/FieldLayout.t.sol +++ b/packages/store/test/FieldLayout.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/FieldLayoutEncodeHelper.sol b/packages/store/test/FieldLayoutEncodeHelper.sol index ded71c228d..5d2e24c7d3 100644 --- a/packages/store/test/FieldLayoutEncodeHelper.sol +++ b/packages/store/test/FieldLayoutEncodeHelper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { FieldLayout, FieldLayoutLib } from "../src/FieldLayout.sol"; diff --git a/packages/store/test/Gas.t.sol b/packages/store/test/Gas.t.sol index 28233db4c6..da555ceb8a 100644 --- a/packages/store/test/Gas.t.sol +++ b/packages/store/test/Gas.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/GasStorageLoad.t.sol b/packages/store/test/GasStorageLoad.t.sol index ab13727d31..7db60617b2 100644 --- a/packages/store/test/GasStorageLoad.t.sol +++ b/packages/store/test/GasStorageLoad.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/Hook.t.sol b/packages/store/test/Hook.t.sol index d3c87e4060..8fe1a2c5dc 100644 --- a/packages/store/test/Hook.t.sol +++ b/packages/store/test/Hook.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/KeyEncoding.t.sol b/packages/store/test/KeyEncoding.t.sol index f1b91ae49b..81cda12052 100644 --- a/packages/store/test/KeyEncoding.t.sol +++ b/packages/store/test/KeyEncoding.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/MirrorSubscriber.sol b/packages/store/test/MirrorSubscriber.sol index e646d3634d..2a355201df 100644 --- a/packages/store/test/MirrorSubscriber.sol +++ b/packages/store/test/MirrorSubscriber.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStore } from "../src/IStore.sol"; import { StoreHook } from "../src/StoreHook.sol"; diff --git a/packages/store/test/Mixed.t.sol b/packages/store/test/Mixed.t.sol index cf1d376d37..00d8217ee6 100644 --- a/packages/store/test/Mixed.t.sol +++ b/packages/store/test/Mixed.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/PackedCounter.t.sol b/packages/store/test/PackedCounter.t.sol index 18b8bb14e9..e3765ac350 100644 --- a/packages/store/test/PackedCounter.t.sol +++ b/packages/store/test/PackedCounter.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/ResourceId.t.sol b/packages/store/test/ResourceId.t.sol index d64afe4f53..0fa445f7df 100644 --- a/packages/store/test/ResourceId.t.sol +++ b/packages/store/test/ResourceId.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/RevertSubscriber.sol b/packages/store/test/RevertSubscriber.sol index 38e6810603..f1a7a7d4a1 100644 --- a/packages/store/test/RevertSubscriber.sol +++ b/packages/store/test/RevertSubscriber.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { StoreHook } from "../src/StoreHook.sol"; import { FieldLayout } from "../src/FieldLayout.sol"; diff --git a/packages/store/test/Schema.t.sol b/packages/store/test/Schema.t.sol index cf967093ed..63ac46909c 100644 --- a/packages/store/test/Schema.t.sol +++ b/packages/store/test/Schema.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/SchemaEncodeHelper.sol b/packages/store/test/SchemaEncodeHelper.sol index 2fc21b70fa..3db69f0813 100644 --- a/packages/store/test/SchemaEncodeHelper.sol +++ b/packages/store/test/SchemaEncodeHelper.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { Schema, SchemaLib } from "../src/Schema.sol"; diff --git a/packages/store/test/Slice.t.sol b/packages/store/test/Slice.t.sol index c49a3b97b6..2384c1c7af 100644 --- a/packages/store/test/Slice.t.sol +++ b/packages/store/test/Slice.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/Storage.t.sol b/packages/store/test/Storage.t.sol index 9c6d13ebd9..e490a6cdb3 100644 --- a/packages/store/test/Storage.t.sol +++ b/packages/store/test/Storage.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index 9c96aecb80..f72f690876 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; diff --git a/packages/store/test/StoreCoreDynamic.t.sol b/packages/store/test/StoreCoreDynamic.t.sol index 33e1434d0d..adac018981 100644 --- a/packages/store/test/StoreCoreDynamic.t.sol +++ b/packages/store/test/StoreCoreDynamic.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/StoreCoreGas.t.sol b/packages/store/test/StoreCoreGas.t.sol index 31419806e6..50990bad79 100644 --- a/packages/store/test/StoreCoreGas.t.sol +++ b/packages/store/test/StoreCoreGas.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/StoreHook.t.sol b/packages/store/test/StoreHook.t.sol index d9ef3615a3..f4d03a7471 100644 --- a/packages/store/test/StoreHook.t.sol +++ b/packages/store/test/StoreHook.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/StoreMock.sol b/packages/store/test/StoreMock.sol index fab796a8f1..7028b83418 100644 --- a/packages/store/test/StoreMock.sol +++ b/packages/store/test/StoreMock.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStore, IStoreHook } from "../src/IStore.sol"; import { PackedCounter } from "../src/PackedCounter.sol"; diff --git a/packages/store/test/StoreMock.t.sol b/packages/store/test/StoreMock.t.sol index 641ff8f528..62a1367c47 100644 --- a/packages/store/test/StoreMock.t.sol +++ b/packages/store/test/StoreMock.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/StoreSwitch.t.sol b/packages/store/test/StoreSwitch.t.sol index 0b6f70fb53..df7890fb9e 100644 --- a/packages/store/test/StoreSwitch.t.sol +++ b/packages/store/test/StoreSwitch.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/Utils.t.sol b/packages/store/test/Utils.t.sol index 21e981862c..3d0e7962a4 100644 --- a/packages/store/test/Utils.t.sol +++ b/packages/store/test/Utils.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/Vector2.t.sol b/packages/store/test/Vector2.t.sol index 3c6fe3541a..a20bee36b9 100644 --- a/packages/store/test/Vector2.t.sol +++ b/packages/store/test/Vector2.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/setDynamicDataLengthAtIndex.sol b/packages/store/test/setDynamicDataLengthAtIndex.sol index 146ffddfee..5ca5ce2677 100644 --- a/packages/store/test/setDynamicDataLengthAtIndex.sol +++ b/packages/store/test/setDynamicDataLengthAtIndex.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { PackedCounter } from "../src/PackedCounter.sol"; import { StoreCoreInternal } from "../src/StoreCore.sol"; diff --git a/packages/store/test/tables/Callbacks.t.sol b/packages/store/test/tables/Callbacks.t.sol index e7f40e3a78..5f38d69481 100644 --- a/packages/store/test/tables/Callbacks.t.sol +++ b/packages/store/test/tables/Callbacks.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/tables/StoreHooks.t.sol b/packages/store/test/tables/StoreHooks.t.sol index e6fa64dd85..4e72e4ec89 100644 --- a/packages/store/test/tables/StoreHooks.t.sol +++ b/packages/store/test/tables/StoreHooks.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/tables/StoreHooksColdLoad.t.sol b/packages/store/test/tables/StoreHooksColdLoad.t.sol index 2943927e51..f706166a34 100644 --- a/packages/store/test/tables/StoreHooksColdLoad.t.sol +++ b/packages/store/test/tables/StoreHooksColdLoad.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/tightcoder/DecodeSlice.t.sol b/packages/store/test/tightcoder/DecodeSlice.t.sol index e3b4989f5d..36e74266e7 100644 --- a/packages/store/test/tightcoder/DecodeSlice.t.sol +++ b/packages/store/test/tightcoder/DecodeSlice.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/tightcoder/EncodeArray.t.sol b/packages/store/test/tightcoder/EncodeArray.t.sol index 2dcd24d9e1..438dae6b24 100644 --- a/packages/store/test/tightcoder/EncodeArray.t.sol +++ b/packages/store/test/tightcoder/EncodeArray.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/tightcoder/TightCoder.t.sol b/packages/store/test/tightcoder/TightCoder.t.sol index b664f80920..f852d37379 100644 --- a/packages/store/test/tightcoder/TightCoder.t.sol +++ b/packages/store/test/tightcoder/TightCoder.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/store/test/tightcoder/TightCoderAuto.t.sol b/packages/store/test/tightcoder/TightCoderAuto.t.sol index 0022bc9634..0dba3a51f7 100644 --- a/packages/store/test/tightcoder/TightCoderAuto.t.sol +++ b/packages/store/test/tightcoder/TightCoderAuto.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/foundry.toml b/packages/world/foundry.toml index 8fcf41188a..3d2a6b756b 100644 --- a/packages/world/foundry.toml +++ b/packages/world/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = '0.8.13' +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index 46c6292db7..df720c3d4d 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -3,31 +3,31 @@ "file": "test/AccessControl.t.sol", "test": "testAccessControl", "name": "AccessControl: hasAccess (cold)", - "gasUsed": 7179 + "gasUsed": 7178 }, { "file": "test/AccessControl.t.sol", "test": "testAccessControl", "name": "AccessControl: hasAccess (warm, namespace only)", - "gasUsed": 1727 + "gasUsed": 1726 }, { "file": "test/AccessControl.t.sol", "test": "testAccessControl", "name": "AccessControl: hasAccess (warm)", - "gasUsed": 3187 + "gasUsed": 3186 }, { "file": "test/AccessControl.t.sol", "test": "testRequireAccess", "name": "AccessControl: requireAccess (cold)", - "gasUsed": 7222 + "gasUsed": 7221 }, { "file": "test/AccessControl.t.sol", "test": "testRequireAccess", "name": "AccessControl: requireAccess (warm)", - "gasUsed": 3225 + "gasUsed": 3224 }, { "file": "test/AccessControl.t.sol", @@ -39,361 +39,361 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallComposite", "name": "install keys in table module", - "gasUsed": 1414806 + "gasUsed": 1414653 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "install keys in table module", - "gasUsed": 1414806 + "gasUsed": 1414653 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "set a record on a table with keysInTableModule installed", - "gasUsed": 158382 + "gasUsed": 158293 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallSingleton", "name": "install keys in table module", - "gasUsed": 1414806 + "gasUsed": 1414653 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "install keys in table module", - "gasUsed": 1414806 + "gasUsed": 1414653 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "change a composite record on a table with keysInTableModule installed", - "gasUsed": 22324 + "gasUsed": 22265 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "delete a composite record on a table with keysInTableModule installed", - "gasUsed": 160664 + "gasUsed": 160800 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "install keys in table module", - "gasUsed": 1414806 + "gasUsed": 1414653 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "change a record on a table with keysInTableModule installed", - "gasUsed": 21046 + "gasUsed": 20987 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "delete a record on a table with keysInTableModule installed", - "gasUsed": 85764 + "gasUsed": 85824 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "install keys with value module", - "gasUsed": 665200 + "gasUsed": 665378 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "Get list of keys with a given value", - "gasUsed": 6175 + "gasUsed": 6186 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetTargetTableId", "name": "compute the target table selector", - "gasUsed": 3071 + "gasUsed": 3101 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "install keys with value module", - "gasUsed": 665200 + "gasUsed": 665378 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "set a record on a table with KeysWithValueModule installed", - "gasUsed": 135760 + "gasUsed": 135704 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "install keys with value module", - "gasUsed": 665200 + "gasUsed": 665378 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "change a record on a table with KeysWithValueModule installed", - "gasUsed": 106140 + "gasUsed": 106045 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "delete a record on a table with KeysWithValueModule installed", - "gasUsed": 35415 + "gasUsed": 35455 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "install keys with value module", - "gasUsed": 665200 + "gasUsed": 665378 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "set a field on a table with KeysWithValueModule installed", - "gasUsed": 148511 + "gasUsed": 148453 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "change a field on a table with KeysWithValueModule installed", - "gasUsed": 113270 + "gasUsed": 113212 }, { "file": "test/query.t.sol", "test": "testCombinedHasHasValueNotQuery", "name": "CombinedHasHasValueNotQuery", - "gasUsed": 104597 + "gasUsed": 104642 }, { "file": "test/query.t.sol", "test": "testCombinedHasHasValueQuery", "name": "CombinedHasHasValueQuery", - "gasUsed": 54366 + "gasUsed": 54376 }, { "file": "test/query.t.sol", "test": "testCombinedHasNotQuery", "name": "CombinedHasNotQuery", - "gasUsed": 128263 + "gasUsed": 128343 }, { "file": "test/query.t.sol", "test": "testCombinedHasQuery", "name": "CombinedHasQuery", - "gasUsed": 81486 + "gasUsed": 81556 }, { "file": "test/query.t.sol", "test": "testCombinedHasValueNotQuery", "name": "CombinedHasValueNotQuery", - "gasUsed": 83650 + "gasUsed": 83695 }, { "file": "test/query.t.sol", "test": "testCombinedHasValueQuery", "name": "CombinedHasValueQuery", - "gasUsed": 16664 + "gasUsed": 16659 }, { "file": "test/query.t.sol", "test": "testHasQuery", "name": "HasQuery", - "gasUsed": 18101 + "gasUsed": 18116 }, { "file": "test/query.t.sol", "test": "testHasQuery1000Keys", "name": "HasQuery with 1000 keys", - "gasUsed": 5938600 + "gasUsed": 5938615 }, { "file": "test/query.t.sol", "test": "testHasQuery100Keys", "name": "HasQuery with 100 keys", - "gasUsed": 553994 + "gasUsed": 554009 }, { "file": "test/query.t.sol", "test": "testHasValueQuery", "name": "HasValueQuery", - "gasUsed": 8003 + "gasUsed": 7998 }, { "file": "test/query.t.sol", "test": "testNotValueQuery", "name": "NotValueQuery", - "gasUsed": 47962 + "gasUsed": 47972 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "register a callbound delegation", - "gasUsed": 114571 + "gasUsed": 114589 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "call a system via a callbound delegation", - "gasUsed": 34058 + "gasUsed": 33993 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "register a timebound delegation", - "gasUsed": 109041 + "gasUsed": 109084 }, { "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "call a system via a timebound delegation", - "gasUsed": 27106 + "gasUsed": 26998 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "install unique entity module", - "gasUsed": 690323 + "gasUsed": 690431 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "get a unique entity nonce (non-root module)", - "gasUsed": 52137 + "gasUsed": 52176 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "installRoot unique entity module", - "gasUsed": 680596 + "gasUsed": 680681 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "get a unique entity nonce (root module)", - "gasUsed": 52137 + "gasUsed": 52176 }, { "file": "test/World.t.sol", "test": "testCall", "name": "call a system via the World", - "gasUsed": 12769 + "gasUsed": 12702 }, { "file": "test/World.t.sol", "test": "testCallFromUnlimitedDelegation", "name": "register an unlimited delegation", - "gasUsed": 50615 + "gasUsed": 50629 }, { "file": "test/World.t.sol", "test": "testCallFromUnlimitedDelegation", "name": "call a system via an unlimited delegation", - "gasUsed": 12961 + "gasUsed": 12895 }, { "file": "test/World.t.sol", "test": "testDeleteRecord", "name": "Delete record", - "gasUsed": 9155 + "gasUsed": 9197 }, { "file": "test/World.t.sol", "test": "testPushToField", "name": "Push data to the table", - "gasUsed": 86882 + "gasUsed": 86871 }, { "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a fallback system", - "gasUsed": 59404 + "gasUsed": 59306 }, { "file": "test/World.t.sol", "test": "testRegisterFallbackSystem", "name": "Register a root fallback system", - "gasUsed": 52929 + "gasUsed": 52950 }, { "file": "test/World.t.sol", "test": "testRegisterFunctionSelector", "name": "Register a function selector", - "gasUsed": 79998 + "gasUsed": 79872 }, { "file": "test/World.t.sol", "test": "testRegisterNamespace", "name": "Register a new namespace", - "gasUsed": 123238 + "gasUsed": 123269 }, { "file": "test/World.t.sol", "test": "testRegisterRootFunctionSelector", "name": "Register a root function selector", - "gasUsed": 74842 + "gasUsed": 74863 }, { "file": "test/World.t.sol", "test": "testRegisterSystem", "name": "register a system", - "gasUsed": 165710 + "gasUsed": 165750 }, { "file": "test/World.t.sol", "test": "testRegisterTable", "name": "Register a new table in the namespace", - "gasUsed": 651789 + "gasUsed": 651802 }, { "file": "test/World.t.sol", "test": "testSetField", "name": "Write data to a table field", - "gasUsed": 37413 + "gasUsed": 37387 }, { "file": "test/World.t.sol", "test": "testSetRecord", "name": "Write data to the table", - "gasUsed": 35407 + "gasUsed": 35381 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (cold)", - "gasUsed": 24643 + "gasUsed": 24672 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (warm)", - "gasUsed": 13789 + "gasUsed": 13818 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (cold)", - "gasUsed": 25248 + "gasUsed": 25236 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (warm)", - "gasUsed": 14453 + "gasUsed": 14441 }, { "file": "test/WorldResourceId.t.sol", "test": "testGetNamespace", "name": "encode namespace, name and type", - "gasUsed": 151 + "gasUsed": 150 }, { "file": "test/WorldResourceId.t.sol", "test": "testGetNamespaceId", "name": "get namespace ID from a resource ID", - "gasUsed": 175 + "gasUsed": 174 }, { "file": "test/WorldResourceId.t.sol", diff --git a/packages/world/src/AccessControl.sol b/packages/world/src/AccessControl.sol index 6cb5cc12ce..4cab35d064 100644 --- a/packages/world/src/AccessControl.sol +++ b/packages/world/src/AccessControl.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { ResourceId, WorldResourceIdInstance } from "./WorldResourceId.sol"; import { IWorldErrors } from "./interfaces/IWorldErrors.sol"; diff --git a/packages/world/src/Delegation.sol b/packages/world/src/Delegation.sol index 191142f39c..78b6ba4f4e 100644 --- a/packages/world/src/Delegation.sol +++ b/packages/world/src/Delegation.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { UNLIMITED_DELEGATION } from "./constants.sol"; import { IDelegationControl } from "./interfaces/IDelegationControl.sol"; diff --git a/packages/world/src/DelegationControl.sol b/packages/world/src/DelegationControl.sol index 905a7bedb2..b5e7519518 100644 --- a/packages/world/src/DelegationControl.sol +++ b/packages/world/src/DelegationControl.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { WorldContextConsumer } from "./WorldContext.sol"; import { IDelegationControl, DELEGATION_CONTROL_INTERFACE_ID } from "./interfaces/IDelegationControl.sol"; diff --git a/packages/world/src/Module.sol b/packages/world/src/Module.sol index 5d8663129e..037b62aca6 100644 --- a/packages/world/src/Module.sol +++ b/packages/world/src/Module.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { WorldContextConsumer } from "./WorldContext.sol"; import { IModule, MODULE_INTERFACE_ID } from "./interfaces/IModule.sol"; diff --git a/packages/world/src/System.sol b/packages/world/src/System.sol index ff3769fa67..ca3e2d16d3 100644 --- a/packages/world/src/System.sol +++ b/packages/world/src/System.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { WorldContextConsumer } from "./WorldContext.sol"; diff --git a/packages/world/src/SystemCall.sol b/packages/world/src/SystemCall.sol index 568f47e4ee..50446dd14c 100644 --- a/packages/world/src/SystemCall.sol +++ b/packages/world/src/SystemCall.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Hook } from "@latticexyz/store/src/Hook.sol"; diff --git a/packages/world/src/SystemHook.sol b/packages/world/src/SystemHook.sol index ef8af9587c..ee8ba08e3b 100644 --- a/packages/world/src/SystemHook.sol +++ b/packages/world/src/SystemHook.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { ISystemHook, SYSTEM_HOOK_INTERFACE_ID } from "./interfaces/ISystemHook.sol"; import { ERC165_INTERFACE_ID } from "./interfaces/IERC165.sol"; diff --git a/packages/world/src/Utils.sol b/packages/world/src/Utils.sol index af6e23a62c..973fc8beb0 100644 --- a/packages/world/src/Utils.sol +++ b/packages/world/src/Utils.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { ResourceId, WorldResourceIdInstance } from "./WorldResourceId.sol"; diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index f24bf892e1..3b9bd8e68a 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { StoreRead } from "@latticexyz/store/src/StoreRead.sol"; import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; diff --git a/packages/world/src/WorldContext.sol b/packages/world/src/WorldContext.sol index 7c29e09f25..03fb9c1bdd 100644 --- a/packages/world/src/WorldContext.sol +++ b/packages/world/src/WorldContext.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { revertWithBytes } from "./revertWithBytes.sol"; diff --git a/packages/world/src/WorldResourceId.sol b/packages/world/src/WorldResourceId.sol index db24aba8b9..1a5b641c14 100644 --- a/packages/world/src/WorldResourceId.sol +++ b/packages/world/src/WorldResourceId.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Bytes } from "@latticexyz/store/src/Bytes.sol"; import { ResourceId, ResourceIdInstance, TYPE_BYTES } from "@latticexyz/store/src/ResourceId.sol"; diff --git a/packages/world/src/constants.sol b/packages/world/src/constants.sol index 5f7e4ff646..06a1e924fd 100644 --- a/packages/world/src/constants.sol +++ b/packages/world/src/constants.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; diff --git a/packages/world/src/factories/Create2.sol b/packages/world/src/factories/Create2.sol index 4b8dbbc6bf..36ee580a9f 100644 --- a/packages/world/src/factories/Create2.sol +++ b/packages/world/src/factories/Create2.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; library Create2 { /** diff --git a/packages/world/src/factories/Create2Factory.sol b/packages/world/src/factories/Create2Factory.sol index a763ec5418..4ac4b4986c 100644 --- a/packages/world/src/factories/Create2Factory.sol +++ b/packages/world/src/factories/Create2Factory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Create2 } from "./Create2.sol"; diff --git a/packages/world/src/factories/IWorldFactory.sol b/packages/world/src/factories/IWorldFactory.sol index c76e646153..f8c337f4b9 100644 --- a/packages/world/src/factories/IWorldFactory.sol +++ b/packages/world/src/factories/IWorldFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; interface IWorldFactory { event WorldDeployed(address indexed newContract); diff --git a/packages/world/src/factories/WorldFactory.sol b/packages/world/src/factories/WorldFactory.sol index 87af0543ed..4d2ccb88ab 100644 --- a/packages/world/src/factories/WorldFactory.sol +++ b/packages/world/src/factories/WorldFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Create2 } from "./Create2.sol"; import { World } from "../World.sol"; diff --git a/packages/world/src/index.sol b/packages/world/src/index.sol index 2e852c4973..61ccd3dda4 100644 --- a/packages/world/src/index.sol +++ b/packages/world/src/index.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/interfaces/IAccessManagementSystem.sol b/packages/world/src/interfaces/IAccessManagementSystem.sol index 2e2c56e5a2..0f7caa3e90 100644 --- a/packages/world/src/interfaces/IAccessManagementSystem.sol +++ b/packages/world/src/interfaces/IAccessManagementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/interfaces/IBalanceTransferSystem.sol b/packages/world/src/interfaces/IBalanceTransferSystem.sol index a00a3bc15c..b78d544cf0 100644 --- a/packages/world/src/interfaces/IBalanceTransferSystem.sol +++ b/packages/world/src/interfaces/IBalanceTransferSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/interfaces/IBaseWorld.sol b/packages/world/src/interfaces/IBaseWorld.sol index dcc9607777..da2939064d 100644 --- a/packages/world/src/interfaces/IBaseWorld.sol +++ b/packages/world/src/interfaces/IBaseWorld.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/interfaces/ICoreSystem.sol b/packages/world/src/interfaces/ICoreSystem.sol index f35a42392f..51315a0aa9 100644 --- a/packages/world/src/interfaces/ICoreSystem.sol +++ b/packages/world/src/interfaces/ICoreSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/interfaces/IDelegationControl.sol b/packages/world/src/interfaces/IDelegationControl.sol index ab528c291b..113a4fa6d0 100644 --- a/packages/world/src/interfaces/IDelegationControl.sol +++ b/packages/world/src/interfaces/IDelegationControl.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IWorldContextConsumer, WORLD_CONTEXT_CONSUMER_INTERFACE_ID } from "./IWorldContextConsumer.sol"; import { ResourceId } from "../WorldResourceId.sol"; diff --git a/packages/world/src/interfaces/IERC165.sol b/packages/world/src/interfaces/IERC165.sol index 4151b0a405..db080dc11f 100644 --- a/packages/world/src/interfaces/IERC165.sol +++ b/packages/world/src/interfaces/IERC165.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; bytes4 constant ERC165_INTERFACE_ID = IERC165.supportsInterface.selector; diff --git a/packages/world/src/interfaces/IModule.sol b/packages/world/src/interfaces/IModule.sol index 8a79abd7db..e94fcbfdfa 100644 --- a/packages/world/src/interfaces/IModule.sol +++ b/packages/world/src/interfaces/IModule.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; diff --git a/packages/world/src/interfaces/IModuleInstallationSystem.sol b/packages/world/src/interfaces/IModuleInstallationSystem.sol index e1de9e093f..c56b3eeebb 100644 --- a/packages/world/src/interfaces/IModuleInstallationSystem.sol +++ b/packages/world/src/interfaces/IModuleInstallationSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/interfaces/ISystemHook.sol b/packages/world/src/interfaces/ISystemHook.sol index d6bde335c0..47739051ab 100644 --- a/packages/world/src/interfaces/ISystemHook.sol +++ b/packages/world/src/interfaces/ISystemHook.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; import { ResourceId } from "../WorldResourceId.sol"; diff --git a/packages/world/src/interfaces/IUniqueEntitySystem.sol b/packages/world/src/interfaces/IUniqueEntitySystem.sol index 552337723c..d9011e2201 100644 --- a/packages/world/src/interfaces/IUniqueEntitySystem.sol +++ b/packages/world/src/interfaces/IUniqueEntitySystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; // TODO allow overriding namespace per-system (or a separate config for modules?) interface IUniqueEntitySystem { diff --git a/packages/world/src/interfaces/IWorldContextConsumer.sol b/packages/world/src/interfaces/IWorldContextConsumer.sol index 496f8c57b9..42cc7fee87 100644 --- a/packages/world/src/interfaces/IWorldContextConsumer.sol +++ b/packages/world/src/interfaces/IWorldContextConsumer.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IERC165, ERC165_INTERFACE_ID } from "./IERC165.sol"; diff --git a/packages/world/src/interfaces/IWorldErrors.sol b/packages/world/src/interfaces/IWorldErrors.sol index ef421ff6b7..d95922e393 100644 --- a/packages/world/src/interfaces/IWorldErrors.sol +++ b/packages/world/src/interfaces/IWorldErrors.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; diff --git a/packages/world/src/interfaces/IWorldKernel.sol b/packages/world/src/interfaces/IWorldKernel.sol index ccb0909b11..2c01631bc5 100644 --- a/packages/world/src/interfaces/IWorldKernel.sol +++ b/packages/world/src/interfaces/IWorldKernel.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IWorldErrors } from "./IWorldErrors.sol"; import { IModule } from "./IModule.sol"; diff --git a/packages/world/src/interfaces/IWorldRegistrationSystem.sol b/packages/world/src/interfaces/IWorldRegistrationSystem.sol index 46638d3ee6..6f2b35beee 100644 --- a/packages/world/src/interfaces/IWorldRegistrationSystem.sol +++ b/packages/world/src/interfaces/IWorldRegistrationSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/core/CoreModule.sol b/packages/world/src/modules/core/CoreModule.sol index 9d5fc3a852..cbc9f6901b 100644 --- a/packages/world/src/modules/core/CoreModule.sol +++ b/packages/world/src/modules/core/CoreModule.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { WorldContextProvider } from "../../WorldContext.sol"; import { ROOT_NAMESPACE, ROOT_NAMESPACE_ID } from "../../constants.sol"; diff --git a/packages/world/src/modules/core/CoreSystem.sol b/packages/world/src/modules/core/CoreSystem.sol index 5372acc73d..6fd79acbd7 100644 --- a/packages/world/src/modules/core/CoreSystem.sol +++ b/packages/world/src/modules/core/CoreSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IWorldErrors } from "../../interfaces/IWorldErrors.sol"; diff --git a/packages/world/src/modules/core/constants.sol b/packages/world/src/modules/core/constants.sol index 5b6a6eb734..7154756b25 100644 --- a/packages/world/src/modules/core/constants.sol +++ b/packages/world/src/modules/core/constants.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; bytes16 constant CORE_MODULE_NAME = bytes16("core.m"); bytes16 constant CORE_SYSTEM_NAME = bytes16("core.s"); diff --git a/packages/world/src/modules/core/implementations/AccessManagementSystem.sol b/packages/world/src/modules/core/implementations/AccessManagementSystem.sol index feb058a0d9..6a07d956eb 100644 --- a/packages/world/src/modules/core/implementations/AccessManagementSystem.sol +++ b/packages/world/src/modules/core/implementations/AccessManagementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IModule } from "../../../interfaces/IModule.sol"; import { System } from "../../../System.sol"; diff --git a/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol b/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol index 5cbbb5a5cf..3b1a59bbdc 100644 --- a/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol +++ b/packages/world/src/modules/core/implementations/BalanceTransferSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; diff --git a/packages/world/src/modules/core/implementations/ModuleInstallationSystem.sol b/packages/world/src/modules/core/implementations/ModuleInstallationSystem.sol index dfa2fa6fa4..c0d9c1f3ea 100644 --- a/packages/world/src/modules/core/implementations/ModuleInstallationSystem.sol +++ b/packages/world/src/modules/core/implementations/ModuleInstallationSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IModule, MODULE_INTERFACE_ID } from "../../../interfaces/IModule.sol"; import { System } from "../../../System.sol"; diff --git a/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol b/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol index b86a42fabe..05811bc8ed 100644 --- a/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol +++ b/packages/world/src/modules/core/implementations/StoreRegistrationSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStoreHook, STORE_HOOK_INTERFACE_ID } from "@latticexyz/store/src/IStoreHook.sol"; import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; diff --git a/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol b/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol index 6e0f75971b..9a08b90f29 100644 --- a/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol +++ b/packages/world/src/modules/core/implementations/WorldRegistrationSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Hook, HookLib } from "@latticexyz/store/src/Hook.sol"; import { ResourceId, ResourceIdInstance } from "@latticexyz/store/src/ResourceId.sol"; diff --git a/packages/world/src/modules/core/tables/Balances.sol b/packages/world/src/modules/core/tables/Balances.sol index b1a6f276be..a5c091c2fc 100644 --- a/packages/world/src/modules/core/tables/Balances.sol +++ b/packages/world/src/modules/core/tables/Balances.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/core/tables/FunctionSelectors.sol b/packages/world/src/modules/core/tables/FunctionSelectors.sol index 7f520a92bb..5bea8fed05 100644 --- a/packages/world/src/modules/core/tables/FunctionSelectors.sol +++ b/packages/world/src/modules/core/tables/FunctionSelectors.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/core/tables/SystemHooks.sol b/packages/world/src/modules/core/tables/SystemHooks.sol index b42a79d2eb..2f04ecde7d 100644 --- a/packages/world/src/modules/core/tables/SystemHooks.sol +++ b/packages/world/src/modules/core/tables/SystemHooks.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/core/tables/SystemRegistry.sol b/packages/world/src/modules/core/tables/SystemRegistry.sol index aaec11544d..4160e95bce 100644 --- a/packages/world/src/modules/core/tables/SystemRegistry.sol +++ b/packages/world/src/modules/core/tables/SystemRegistry.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/core/tables/Systems.sol b/packages/world/src/modules/core/tables/Systems.sol index 10c7b49a40..934122ca26 100644 --- a/packages/world/src/modules/core/tables/Systems.sol +++ b/packages/world/src/modules/core/tables/Systems.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/keysintable/KeysInTableHook.sol b/packages/world/src/modules/keysintable/KeysInTableHook.sol index 0d8681456d..3cf09d4638 100644 --- a/packages/world/src/modules/keysintable/KeysInTableHook.sol +++ b/packages/world/src/modules/keysintable/KeysInTableHook.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; diff --git a/packages/world/src/modules/keysintable/KeysInTableModule.sol b/packages/world/src/modules/keysintable/KeysInTableModule.sol index b0357b7dd0..dd10f5c8ea 100644 --- a/packages/world/src/modules/keysintable/KeysInTableModule.sol +++ b/packages/world/src/modules/keysintable/KeysInTableModule.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { BEFORE_SET_RECORD, AFTER_SPLICE_STATIC_DATA, AFTER_SPLICE_DYNAMIC_DATA, BEFORE_DELETE_RECORD } from "@latticexyz/store/src/storeHookTypes.sol"; import { ResourceIds } from "@latticexyz/store/src/codegen/tables/ResourceIds.sol"; diff --git a/packages/world/src/modules/keysintable/constants.sol b/packages/world/src/modules/keysintable/constants.sol index e39fa1032a..e27da01de4 100644 --- a/packages/world/src/modules/keysintable/constants.sol +++ b/packages/world/src/modules/keysintable/constants.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; // Limiting the module namespace to 8 bytes so the last 8 bytes // can be used for an identifier of the source table namespace to avoid diff --git a/packages/world/src/modules/keysintable/getKeysInTable.sol b/packages/world/src/modules/keysintable/getKeysInTable.sol index 06d7bcf41b..89a9b96fa2 100644 --- a/packages/world/src/modules/keysintable/getKeysInTable.sol +++ b/packages/world/src/modules/keysintable/getKeysInTable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStore } from "@latticexyz/store/src/IStore.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; diff --git a/packages/world/src/modules/keysintable/hasKey.sol b/packages/world/src/modules/keysintable/hasKey.sol index 0efd658135..7916e6f30b 100644 --- a/packages/world/src/modules/keysintable/hasKey.sol +++ b/packages/world/src/modules/keysintable/hasKey.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStore } from "@latticexyz/store/src/IStore.sol"; import { ResourceId } from "@latticexyz/store/src/ResourceId.sol"; diff --git a/packages/world/src/modules/keysintable/query.sol b/packages/world/src/modules/keysintable/query.sol index 3dbd72bc50..4299509f7b 100644 --- a/packages/world/src/modules/keysintable/query.sol +++ b/packages/world/src/modules/keysintable/query.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStore } from "@latticexyz/store/src/IStore.sol"; import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; diff --git a/packages/world/src/modules/keysintable/tables/KeysInTable.sol b/packages/world/src/modules/keysintable/tables/KeysInTable.sol index 7c86f97fed..1b8ea4ff81 100644 --- a/packages/world/src/modules/keysintable/tables/KeysInTable.sol +++ b/packages/world/src/modules/keysintable/tables/KeysInTable.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol b/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol index ade2c06653..9cd905b612 100644 --- a/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol +++ b/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol index b945b7ec3d..22e25b9d5b 100644 --- a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol +++ b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { StoreHook } from "@latticexyz/store/src/StoreHook.sol"; import { Bytes } from "@latticexyz/store/src/Bytes.sol"; diff --git a/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol b/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol index d6b210666f..41c56358a9 100644 --- a/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol +++ b/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { BEFORE_SET_RECORD, BEFORE_SPLICE_STATIC_DATA, AFTER_SPLICE_STATIC_DATA, BEFORE_SPLICE_DYNAMIC_DATA, AFTER_SPLICE_DYNAMIC_DATA, BEFORE_DELETE_RECORD } from "@latticexyz/store/src/storeHookTypes.sol"; diff --git a/packages/world/src/modules/keyswithvalue/constants.sol b/packages/world/src/modules/keyswithvalue/constants.sol index b239bade58..d558ea1c1d 100644 --- a/packages/world/src/modules/keyswithvalue/constants.sol +++ b/packages/world/src/modules/keyswithvalue/constants.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; // Limiting the module namespace to 7 bytes so the remaining 7 bytes // can be used for an identifier of the source table namespace to avoid diff --git a/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol b/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol index 07cebf75cd..07507b399e 100644 --- a/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol +++ b/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IStore } from "@latticexyz/store/src/IStore.sol"; import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; diff --git a/packages/world/src/modules/keyswithvalue/getTargetTableId.sol b/packages/world/src/modules/keyswithvalue/getTargetTableId.sol index b972ff8208..4179f8cd95 100644 --- a/packages/world/src/modules/keyswithvalue/getTargetTableId.sol +++ b/packages/world/src/modules/keyswithvalue/getTargetTableId.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { TYPE_BYTES } from "@latticexyz/store/src/ResourceId.sol"; import { ResourceId, WorldResourceIdInstance, NAME_BYTES } from "../../WorldResourceId.sol"; diff --git a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol index 0cc9ed2cf8..7621b94d5f 100644 --- a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol +++ b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/std-delegations/CallboundDelegationControl.sol b/packages/world/src/modules/std-delegations/CallboundDelegationControl.sol index c089ec7d4b..13bda72d16 100644 --- a/packages/world/src/modules/std-delegations/CallboundDelegationControl.sol +++ b/packages/world/src/modules/std-delegations/CallboundDelegationControl.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { DelegationControl } from "../../DelegationControl.sol"; import { ResourceId } from "../../WorldResourceId.sol"; diff --git a/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol b/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol index 99f341ef3a..e4834d3309 100644 --- a/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol +++ b/packages/world/src/modules/std-delegations/StandardDelegationsModule.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; diff --git a/packages/world/src/modules/std-delegations/TimeboundDelegationControl.sol b/packages/world/src/modules/std-delegations/TimeboundDelegationControl.sol index e9f9e6114d..72c908938c 100644 --- a/packages/world/src/modules/std-delegations/TimeboundDelegationControl.sol +++ b/packages/world/src/modules/std-delegations/TimeboundDelegationControl.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { DelegationControl } from "../../DelegationControl.sol"; import { ResourceId } from "../../WorldResourceId.sol"; diff --git a/packages/world/src/modules/std-delegations/constants.sol b/packages/world/src/modules/std-delegations/constants.sol index 96e65ec00a..09859c43ee 100644 --- a/packages/world/src/modules/std-delegations/constants.sol +++ b/packages/world/src/modules/std-delegations/constants.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { ResourceId } from "../../WorldResourceId.sol"; import { RESOURCE_SYSTEM } from "../../worldResourceTypes.sol"; import { ROOT_NAMESPACE } from "../../constants.sol"; diff --git a/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol b/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol index 5bb08ebe8a..1cbdff95f9 100644 --- a/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol +++ b/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol b/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol index f973705ea6..a8393b5e2f 100644 --- a/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol +++ b/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol b/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol index 1f7cb32045..981d5efb1f 100644 --- a/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol +++ b/packages/world/src/modules/uniqueentity/UniqueEntityModule.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; diff --git a/packages/world/src/modules/uniqueentity/UniqueEntitySystem.sol b/packages/world/src/modules/uniqueentity/UniqueEntitySystem.sol index 35da06f17d..c002792035 100644 --- a/packages/world/src/modules/uniqueentity/UniqueEntitySystem.sol +++ b/packages/world/src/modules/uniqueentity/UniqueEntitySystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "../../System.sol"; import { TABLE_ID } from "./constants.sol"; diff --git a/packages/world/src/modules/uniqueentity/constants.sol b/packages/world/src/modules/uniqueentity/constants.sol index d35a2d1b63..41b8d793c8 100644 --- a/packages/world/src/modules/uniqueentity/constants.sol +++ b/packages/world/src/modules/uniqueentity/constants.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { ResourceId } from "../../WorldResourceId.sol"; import { RESOURCE_TABLE, RESOURCE_SYSTEM } from "../../worldResourceTypes.sol"; diff --git a/packages/world/src/modules/uniqueentity/getUniqueEntity.sol b/packages/world/src/modules/uniqueentity/getUniqueEntity.sol index 6142514a97..cb4dd1981b 100644 --- a/packages/world/src/modules/uniqueentity/getUniqueEntity.sol +++ b/packages/world/src/modules/uniqueentity/getUniqueEntity.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; diff --git a/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol b/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol index 504f52e8b4..0d1b5db6d8 100644 --- a/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol +++ b/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/modules/utils/ArrayLib.sol b/packages/world/src/modules/utils/ArrayLib.sol index b621b41b6d..0b16c1d44b 100644 --- a/packages/world/src/modules/utils/ArrayLib.sol +++ b/packages/world/src/modules/utils/ArrayLib.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; library ArrayLib { function equal(bytes32[] memory arr1, bytes32[] memory arr2) internal pure returns (bool) { diff --git a/packages/world/src/requireInterface.sol b/packages/world/src/requireInterface.sol index fd8680f731..420d78f1b2 100644 --- a/packages/world/src/requireInterface.sol +++ b/packages/world/src/requireInterface.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { IERC165 } from "./interfaces/IERC165.sol"; import { IWorldErrors } from "./interfaces/IWorldErrors.sol"; diff --git a/packages/world/src/revertWithBytes.sol b/packages/world/src/revertWithBytes.sol index 318ef91a8e..e93de3726e 100644 --- a/packages/world/src/revertWithBytes.sol +++ b/packages/world/src/revertWithBytes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /** * Utility function to revert with raw bytes (eg. coming from a low level call or from a previously encoded error) diff --git a/packages/world/src/systemHookTypes.sol b/packages/world/src/systemHookTypes.sol index d23fb25ab5..999023f7eb 100644 --- a/packages/world/src/systemHookTypes.sol +++ b/packages/world/src/systemHookTypes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; uint8 constant BEFORE_CALL_SYSTEM = 1 << 0; uint8 constant AFTER_CALL_SYSTEM = 1 << 1; diff --git a/packages/world/src/tables/Delegations.sol b/packages/world/src/tables/Delegations.sol index d74442d458..1b241f93e0 100644 --- a/packages/world/src/tables/Delegations.sol +++ b/packages/world/src/tables/Delegations.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/tables/InstalledModules.sol b/packages/world/src/tables/InstalledModules.sol index 378bbf8bb1..5b80739eff 100644 --- a/packages/world/src/tables/InstalledModules.sol +++ b/packages/world/src/tables/InstalledModules.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/tables/NamespaceOwner.sol b/packages/world/src/tables/NamespaceOwner.sol index 50fc82b5aa..62832ecd4b 100644 --- a/packages/world/src/tables/NamespaceOwner.sol +++ b/packages/world/src/tables/NamespaceOwner.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/tables/ResourceAccess.sol b/packages/world/src/tables/ResourceAccess.sol index 58b9ccceb5..57ee1ea25e 100644 --- a/packages/world/src/tables/ResourceAccess.sol +++ b/packages/world/src/tables/ResourceAccess.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/src/version.sol b/packages/world/src/version.sol index bd7a91f4d6..f2595b7c69 100644 --- a/packages/world/src/version.sol +++ b/packages/world/src/version.sol @@ -1,4 +1,4 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; bytes32 constant WORLD_VERSION = "0.0.0"; diff --git a/packages/world/src/worldResourceTypes.sol b/packages/world/src/worldResourceTypes.sol index d7ec187b3a..5b6cc089d4 100644 --- a/packages/world/src/worldResourceTypes.sol +++ b/packages/world/src/worldResourceTypes.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { RESOURCE_TABLE, RESOURCE_OFFCHAIN_TABLE } from "@latticexyz/store/src/storeResourceTypes.sol"; diff --git a/packages/world/test/AccessControl.t.sol b/packages/world/test/AccessControl.t.sol index 413706328f..07ff0f845f 100644 --- a/packages/world/test/AccessControl.t.sol +++ b/packages/world/test/AccessControl.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/Factories.t.sol b/packages/world/test/Factories.t.sol index a943d7a41f..a0bbff1890 100644 --- a/packages/world/test/Factories.t.sol +++ b/packages/world/test/Factories.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; diff --git a/packages/world/test/KeysInTableModule.t.sol b/packages/world/test/KeysInTableModule.t.sol index 2c1061b3fb..00072be318 100644 --- a/packages/world/test/KeysInTableModule.t.sol +++ b/packages/world/test/KeysInTableModule.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/KeysWithValueModule.t.sol b/packages/world/test/KeysWithValueModule.t.sol index 2996090f62..aac01226fb 100644 --- a/packages/world/test/KeysWithValueModule.t.sol +++ b/packages/world/test/KeysWithValueModule.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/MudTest.t.sol b/packages/world/test/MudTest.t.sol index 95af8e93be..098a487ae5 100644 --- a/packages/world/test/MudTest.t.sol +++ b/packages/world/test/MudTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; diff --git a/packages/world/test/RevertWithBytes.t.sol b/packages/world/test/RevertWithBytes.t.sol index e9bda37e30..72464e96de 100644 --- a/packages/world/test/RevertWithBytes.t.sol +++ b/packages/world/test/RevertWithBytes.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { revertWithBytes } from "../src/revertWithBytes.sol"; diff --git a/packages/world/test/StandardDelegationsModule.t.sol b/packages/world/test/StandardDelegationsModule.t.sol index 5d1dd56e32..7b8b936fae 100644 --- a/packages/world/test/StandardDelegationsModule.t.sol +++ b/packages/world/test/StandardDelegationsModule.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/System.t.sol b/packages/world/test/System.t.sol index b428b45bbc..96e0faa298 100644 --- a/packages/world/test/System.t.sol +++ b/packages/world/test/System.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { World } from "../src/World.sol"; diff --git a/packages/world/test/SystemHook.t.sol b/packages/world/test/SystemHook.t.sol index f191923d93..ef8d834d44 100644 --- a/packages/world/test/SystemHook.t.sol +++ b/packages/world/test/SystemHook.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/UniqueEntityModule.t.sol b/packages/world/test/UniqueEntityModule.t.sol index d9c24f2ec7..ec150d0a0a 100644 --- a/packages/world/test/UniqueEntityModule.t.sol +++ b/packages/world/test/UniqueEntityModule.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/Utils.t.sol b/packages/world/test/Utils.t.sol index 98b7752ea3..789480666a 100644 --- a/packages/world/test/Utils.t.sol +++ b/packages/world/test/Utils.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; diff --git a/packages/world/test/World.t.sol b/packages/world/test/World.t.sol index 3b242852bc..10fb008812 100644 --- a/packages/world/test/World.t.sol +++ b/packages/world/test/World.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/WorldBalance.t.sol b/packages/world/test/WorldBalance.t.sol index 4f3df02a0f..3a6e889925 100644 --- a/packages/world/test/WorldBalance.t.sol +++ b/packages/world/test/WorldBalance.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/WorldContext.t.sol b/packages/world/test/WorldContext.t.sol index a264b510b0..5015e0968f 100644 --- a/packages/world/test/WorldContext.t.sol +++ b/packages/world/test/WorldContext.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/WorldDynamicUpdate.t.sol b/packages/world/test/WorldDynamicUpdate.t.sol index 409495592a..75d28609e6 100644 --- a/packages/world/test/WorldDynamicUpdate.t.sol +++ b/packages/world/test/WorldDynamicUpdate.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/WorldResourceId.t.sol b/packages/world/test/WorldResourceId.t.sol index e249e75c9f..fe052c0c10 100644 --- a/packages/world/test/WorldResourceId.t.sol +++ b/packages/world/test/WorldResourceId.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/query.t.sol b/packages/world/test/query.t.sol index fd2fa7873d..3b0cb7155e 100644 --- a/packages/world/test/query.t.sol +++ b/packages/world/test/query.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; diff --git a/packages/world/test/tables/AddressArray.sol b/packages/world/test/tables/AddressArray.sol index 8f658a688e..26a7d7775b 100644 --- a/packages/world/test/tables/AddressArray.sol +++ b/packages/world/test/tables/AddressArray.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/packages/world/test/tables/Bool.sol b/packages/world/test/tables/Bool.sol index 976c3c4658..425534d339 100644 --- a/packages/world/test/tables/Bool.sol +++ b/packages/world/test/tables/Bool.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/phaser/.vscode/settings.json b/templates/phaser/.vscode/settings.json index 5a44ed867e..2cb0dd5713 100644 --- a/templates/phaser/.vscode/settings.json +++ b/templates/phaser/.vscode/settings.json @@ -1,3 +1,4 @@ { - "solidity.monoRepoSupport": true + "solidity.monoRepoSupport": true, + "solidity.compileUsingRemoteVersion": "v0.8.21+commit.d9974bed" } diff --git a/templates/phaser/packages/contracts/foundry.toml b/templates/phaser/packages/contracts/foundry.toml index 6b9c911b04..d03fad8043 100644 --- a/templates/phaser/packages/contracts/foundry.toml +++ b/templates/phaser/packages/contracts/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = "0.8.13" +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/templates/phaser/packages/contracts/script/PostDeploy.s.sol b/templates/phaser/packages/contracts/script/PostDeploy.s.sol index 6218122e83..d8600bb5ed 100644 --- a/templates/phaser/packages/contracts/script/PostDeploy.s.sol +++ b/templates/phaser/packages/contracts/script/PostDeploy.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Script } from "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; diff --git a/templates/phaser/packages/contracts/src/codegen/index.sol b/templates/phaser/packages/contracts/src/codegen/index.sol index 4fa54c456d..3ac2e18d1d 100644 --- a/templates/phaser/packages/contracts/src/codegen/index.sol +++ b/templates/phaser/packages/contracts/src/codegen/index.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol b/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol index 33aeb9dba3..26d56e1b79 100644 --- a/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/phaser/packages/contracts/src/codegen/world/IIncrementSystem.sol b/templates/phaser/packages/contracts/src/codegen/world/IIncrementSystem.sol index d3a987d44e..56c6d1ac0e 100644 --- a/templates/phaser/packages/contracts/src/codegen/world/IIncrementSystem.sol +++ b/templates/phaser/packages/contracts/src/codegen/world/IIncrementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/phaser/packages/contracts/src/codegen/world/IWorld.sol b/templates/phaser/packages/contracts/src/codegen/world/IWorld.sol index e92b40b33c..0fd7430af1 100644 --- a/templates/phaser/packages/contracts/src/codegen/world/IWorld.sol +++ b/templates/phaser/packages/contracts/src/codegen/world/IWorld.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/phaser/packages/contracts/src/systems/IncrementSystem.sol b/templates/phaser/packages/contracts/src/systems/IncrementSystem.sol index db5a2673a2..fe8de1fd37 100644 --- a/templates/phaser/packages/contracts/src/systems/IncrementSystem.sol +++ b/templates/phaser/packages/contracts/src/systems/IncrementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "@latticexyz/world/src/System.sol"; import { Counter } from "../codegen/index.sol"; diff --git a/templates/phaser/packages/contracts/test/CounterTest.t.sol b/templates/phaser/packages/contracts/test/CounterTest.t.sol index efe11c5126..adcb89b4e8 100644 --- a/templates/phaser/packages/contracts/test/CounterTest.t.sol +++ b/templates/phaser/packages/contracts/test/CounterTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { MudTest } from "@latticexyz/world/test/MudTest.t.sol"; diff --git a/templates/react/.vscode/settings.json b/templates/react/.vscode/settings.json index 5a44ed867e..2cb0dd5713 100644 --- a/templates/react/.vscode/settings.json +++ b/templates/react/.vscode/settings.json @@ -1,3 +1,4 @@ { - "solidity.monoRepoSupport": true + "solidity.monoRepoSupport": true, + "solidity.compileUsingRemoteVersion": "v0.8.21+commit.d9974bed" } diff --git a/templates/react/packages/contracts/foundry.toml b/templates/react/packages/contracts/foundry.toml index 6b9c911b04..d03fad8043 100644 --- a/templates/react/packages/contracts/foundry.toml +++ b/templates/react/packages/contracts/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = "0.8.13" +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/templates/react/packages/contracts/script/PostDeploy.s.sol b/templates/react/packages/contracts/script/PostDeploy.s.sol index 6218122e83..d8600bb5ed 100644 --- a/templates/react/packages/contracts/script/PostDeploy.s.sol +++ b/templates/react/packages/contracts/script/PostDeploy.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Script } from "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; diff --git a/templates/react/packages/contracts/src/codegen/index.sol b/templates/react/packages/contracts/src/codegen/index.sol index 4fa54c456d..3ac2e18d1d 100644 --- a/templates/react/packages/contracts/src/codegen/index.sol +++ b/templates/react/packages/contracts/src/codegen/index.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/react/packages/contracts/src/codegen/tables/Counter.sol b/templates/react/packages/contracts/src/codegen/tables/Counter.sol index 33aeb9dba3..26d56e1b79 100644 --- a/templates/react/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/react/packages/contracts/src/codegen/tables/Counter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/react/packages/contracts/src/codegen/world/IIncrementSystem.sol b/templates/react/packages/contracts/src/codegen/world/IIncrementSystem.sol index d3a987d44e..56c6d1ac0e 100644 --- a/templates/react/packages/contracts/src/codegen/world/IIncrementSystem.sol +++ b/templates/react/packages/contracts/src/codegen/world/IIncrementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/react/packages/contracts/src/codegen/world/IWorld.sol b/templates/react/packages/contracts/src/codegen/world/IWorld.sol index e92b40b33c..0fd7430af1 100644 --- a/templates/react/packages/contracts/src/codegen/world/IWorld.sol +++ b/templates/react/packages/contracts/src/codegen/world/IWorld.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/react/packages/contracts/src/systems/IncrementSystem.sol b/templates/react/packages/contracts/src/systems/IncrementSystem.sol index db5a2673a2..fe8de1fd37 100644 --- a/templates/react/packages/contracts/src/systems/IncrementSystem.sol +++ b/templates/react/packages/contracts/src/systems/IncrementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "@latticexyz/world/src/System.sol"; import { Counter } from "../codegen/index.sol"; diff --git a/templates/react/packages/contracts/test/CounterTest.t.sol b/templates/react/packages/contracts/test/CounterTest.t.sol index efe11c5126..adcb89b4e8 100644 --- a/templates/react/packages/contracts/test/CounterTest.t.sol +++ b/templates/react/packages/contracts/test/CounterTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { MudTest } from "@latticexyz/world/test/MudTest.t.sol"; diff --git a/templates/threejs/.vscode/settings.json b/templates/threejs/.vscode/settings.json index 5a44ed867e..2cb0dd5713 100644 --- a/templates/threejs/.vscode/settings.json +++ b/templates/threejs/.vscode/settings.json @@ -1,3 +1,4 @@ { - "solidity.monoRepoSupport": true + "solidity.monoRepoSupport": true, + "solidity.compileUsingRemoteVersion": "v0.8.21+commit.d9974bed" } diff --git a/templates/threejs/packages/contracts/foundry.toml b/templates/threejs/packages/contracts/foundry.toml index 6b9c911b04..d03fad8043 100644 --- a/templates/threejs/packages/contracts/foundry.toml +++ b/templates/threejs/packages/contracts/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = "0.8.13" +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/templates/threejs/packages/contracts/src/codegen/index.sol b/templates/threejs/packages/contracts/src/codegen/index.sol index 08fcbdca79..6c8169da7d 100644 --- a/templates/threejs/packages/contracts/src/codegen/index.sol +++ b/templates/threejs/packages/contracts/src/codegen/index.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/threejs/packages/contracts/src/codegen/tables/Position.sol b/templates/threejs/packages/contracts/src/codegen/tables/Position.sol index 07ae7da4b2..8f4495582e 100644 --- a/templates/threejs/packages/contracts/src/codegen/tables/Position.sol +++ b/templates/threejs/packages/contracts/src/codegen/tables/Position.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/threejs/packages/contracts/src/codegen/world/IMoveSystem.sol b/templates/threejs/packages/contracts/src/codegen/world/IMoveSystem.sol index 5ff09626f2..71a587e870 100644 --- a/templates/threejs/packages/contracts/src/codegen/world/IMoveSystem.sol +++ b/templates/threejs/packages/contracts/src/codegen/world/IMoveSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/threejs/packages/contracts/src/codegen/world/IWorld.sol b/templates/threejs/packages/contracts/src/codegen/world/IWorld.sol index d66640e553..83839ef23b 100644 --- a/templates/threejs/packages/contracts/src/codegen/world/IWorld.sol +++ b/templates/threejs/packages/contracts/src/codegen/world/IWorld.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/threejs/packages/contracts/src/systems/MoveSystem.sol b/templates/threejs/packages/contracts/src/systems/MoveSystem.sol index c90fa1c107..7c9e959438 100644 --- a/templates/threejs/packages/contracts/src/systems/MoveSystem.sol +++ b/templates/threejs/packages/contracts/src/systems/MoveSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "@latticexyz/world/src/System.sol"; import { Position, PositionData } from "../codegen/index.sol"; diff --git a/templates/vanilla/.vscode/settings.json b/templates/vanilla/.vscode/settings.json index 5a44ed867e..2cb0dd5713 100644 --- a/templates/vanilla/.vscode/settings.json +++ b/templates/vanilla/.vscode/settings.json @@ -1,3 +1,4 @@ { - "solidity.monoRepoSupport": true + "solidity.monoRepoSupport": true, + "solidity.compileUsingRemoteVersion": "v0.8.21+commit.d9974bed" } diff --git a/templates/vanilla/packages/contracts/foundry.toml b/templates/vanilla/packages/contracts/foundry.toml index 6b9c911b04..d03fad8043 100644 --- a/templates/vanilla/packages/contracts/foundry.toml +++ b/templates/vanilla/packages/contracts/foundry.toml @@ -1,5 +1,5 @@ [profile.default] -solc_version = "0.8.13" +solc = "0.8.21" ffi = false fuzz_runs = 256 optimizer = true diff --git a/templates/vanilla/packages/contracts/script/PostDeploy.s.sol b/templates/vanilla/packages/contracts/script/PostDeploy.s.sol index 6218122e83..d8600bb5ed 100644 --- a/templates/vanilla/packages/contracts/script/PostDeploy.s.sol +++ b/templates/vanilla/packages/contracts/script/PostDeploy.s.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { Script } from "forge-std/Script.sol"; import { console } from "forge-std/console.sol"; diff --git a/templates/vanilla/packages/contracts/src/codegen/index.sol b/templates/vanilla/packages/contracts/src/codegen/index.sol index 4fa54c456d..3ac2e18d1d 100644 --- a/templates/vanilla/packages/contracts/src/codegen/index.sol +++ b/templates/vanilla/packages/contracts/src/codegen/index.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol b/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol index 33aeb9dba3..26d56e1b79 100644 --- a/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/vanilla/packages/contracts/src/codegen/world/IIncrementSystem.sol b/templates/vanilla/packages/contracts/src/codegen/world/IIncrementSystem.sol index d3a987d44e..56c6d1ac0e 100644 --- a/templates/vanilla/packages/contracts/src/codegen/world/IIncrementSystem.sol +++ b/templates/vanilla/packages/contracts/src/codegen/world/IIncrementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/vanilla/packages/contracts/src/codegen/world/IWorld.sol b/templates/vanilla/packages/contracts/src/codegen/world/IWorld.sol index e92b40b33c..0fd7430af1 100644 --- a/templates/vanilla/packages/contracts/src/codegen/world/IWorld.sol +++ b/templates/vanilla/packages/contracts/src/codegen/world/IWorld.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; /* Autogenerated file. Do not edit manually. */ diff --git a/templates/vanilla/packages/contracts/src/systems/IncrementSystem.sol b/templates/vanilla/packages/contracts/src/systems/IncrementSystem.sol index db5a2673a2..fe8de1fd37 100644 --- a/templates/vanilla/packages/contracts/src/systems/IncrementSystem.sol +++ b/templates/vanilla/packages/contracts/src/systems/IncrementSystem.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import { System } from "@latticexyz/world/src/System.sol"; import { Counter } from "../codegen/index.sol"; diff --git a/templates/vanilla/packages/contracts/test/CounterTest.t.sol b/templates/vanilla/packages/contracts/test/CounterTest.t.sol index efe11c5126..adcb89b4e8 100644 --- a/templates/vanilla/packages/contracts/test/CounterTest.t.sol +++ b/templates/vanilla/packages/contracts/test/CounterTest.t.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; +pragma solidity >=0.8.21; import "forge-std/Test.sol"; import { MudTest } from "@latticexyz/world/test/MudTest.t.sol";