diff --git a/packages/cli/src/render-solidity/common.ts b/packages/cli/src/render-solidity/common.ts index 1098e58aba..6756e59fc9 100644 --- a/packages/cli/src/render-solidity/common.ts +++ b/packages/cli/src/render-solidity/common.ts @@ -100,7 +100,7 @@ export function renderWithStore( } export function renderTableId(staticResourceData: StaticResourceData) { - const hardcodedTableId = `uint256(bytes32(abi.encodePacked(bytes16("${staticResourceData.namespace}"), bytes16("${staticResourceData.fileSelector}"))))`; + const hardcodedTableId = `uint256(bytes32(abi.encodePacked(bytes16("${staticResourceData.namespace}"), bytes16("${staticResourceData.name}"))))`; const tableIdDefinition = ` uint256 constant _tableId = ${hardcodedTableId}; diff --git a/packages/cli/src/render-solidity/tableOptions.ts b/packages/cli/src/render-solidity/tableOptions.ts index 667812ceb8..6a344d9f13 100644 --- a/packages/cli/src/render-solidity/tableOptions.ts +++ b/packages/cli/src/render-solidity/tableOptions.ts @@ -80,7 +80,7 @@ export function getTableOptions(config: StoreConfig): TableOptions[] { return { tableIdName: tableName + "TableId", namespace: config.namespace, - fileSelector: tableData.fileSelector, + name: tableData.name, }; } })(); diff --git a/packages/cli/src/render-solidity/types.ts b/packages/cli/src/render-solidity/types.ts index e04b53f12c..6f199511ee 100644 --- a/packages/cli/src/render-solidity/types.ts +++ b/packages/cli/src/render-solidity/types.ts @@ -29,7 +29,7 @@ export interface StaticResourceData { /** Name of the table id constant to render. */ tableIdName: string; namespace: string; - fileSelector: string; + name: string; } export interface RenderTableType { diff --git a/packages/cli/src/render-solidity/worldgen.ts b/packages/cli/src/render-solidity/worldgen.ts index 1e6f02fc34..d08c1d9c77 100644 --- a/packages/cli/src/render-solidity/worldgen.ts +++ b/packages/cli/src/render-solidity/worldgen.ts @@ -27,10 +27,10 @@ export async function worldgen( })); const systemInterfaceName = `I${system.basename}`; // create an interface using the external functions and imports - const { fileSelector } = config.systems[system.basename]; + const { name } = config.systems[system.basename]; const output = renderSystemInterface({ name: systemInterfaceName, - functionPrefix: config.namespace === "" ? "" : `${config.namespace}_${fileSelector}_`, + functionPrefix: config.namespace === "" ? "" : `${config.namespace}_${name}_`, functions, imports, }); diff --git a/packages/cli/src/render-ts/recsV1TableOptions.ts b/packages/cli/src/render-ts/recsV1TableOptions.ts index 4fb5fad912..d21ad49043 100644 --- a/packages/cli/src/render-ts/recsV1TableOptions.ts +++ b/packages/cli/src/render-ts/recsV1TableOptions.ts @@ -24,7 +24,7 @@ export function getRecsV1TableOptions(config: StoreConfig): RecsV1TableOptions { if (tableData.tableIdArgument) continue; const staticResourceData = { namespace: config.namespace, - fileSelector: tableData.fileSelector, + name: tableData.name, }; tableOptions.push({ diff --git a/packages/cli/src/render-ts/renderRecsV1Tables.ts b/packages/cli/src/render-ts/renderRecsV1Tables.ts index 578bb13857..574e6c6304 100644 --- a/packages/cli/src/render-ts/renderRecsV1Tables.ts +++ b/packages/cli/src/render-ts/renderRecsV1Tables.ts @@ -17,10 +17,10 @@ export function defineContractComponents(world: World) { } function renderDefineComponent(table: RecsV1TableOptions["tables"][number]) { - const { namespace, fileSelector } = table.staticResourceData; + const { namespace, name } = table.staticResourceData; return ` (() => { - const tableId = new TableId("${namespace}", "${fileSelector}"); + const tableId = new TableId("${namespace}", "${name}"); return defineComponent(world, { ${table.fields.map(({ name, recsTypeString }) => `${name}: ${recsTypeString},`).join("")} }, { diff --git a/packages/cli/src/render-ts/types.ts b/packages/cli/src/render-ts/types.ts index 43c812aa5e..85746e2655 100644 --- a/packages/cli/src/render-ts/types.ts +++ b/packages/cli/src/render-ts/types.ts @@ -7,7 +7,7 @@ export interface RecsV1TableOptions { }[]; staticResourceData: { namespace: string; - fileSelector: string; + name: string; }; }[]; } diff --git a/packages/cli/src/utils/deploy-v2.ts b/packages/cli/src/utils/deploy-v2.ts index d5b128312f..5ad96e38ca 100644 --- a/packages/cli/src/utils/deploy-v2.ts +++ b/packages/cli/src/utils/deploy-v2.ts @@ -122,11 +122,11 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig): const tableIds: { [tableName: string]: Uint8Array } = {}; promises = [ ...promises, - ...Object.entries(mudConfig.tables).map(async ([tableName, { fileSelector, schema, primaryKeys }]) => { - console.log(chalk.blue(`Registering table ${tableName} at ${namespace}/${fileSelector}`)); + ...Object.entries(mudConfig.tables).map(async ([tableName, { name, schema, primaryKeys }]) => { + console.log(chalk.blue(`Registering table ${tableName} at ${namespace}/${name}`)); // Store the tableId for later use - tableIds[tableName] = toResourceSelector(namespace, fileSelector); + tableIds[tableName] = toResourceSelector(namespace, name); // Register table const schemaTypes = Object.values(schema).map((abiOrUserType) => { @@ -141,7 +141,7 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig): await fastTxExecute(WorldContract, "registerTable", [ toBytes16(namespace), - toBytes16(fileSelector), + toBytes16(name), encodeSchema(schemaTypes), encodeSchema(keyTypes), ]); @@ -149,69 +149,67 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig): // Register table metadata await fastTxExecute(WorldContract, "setMetadata(bytes16,bytes16,string,string[])", [ toBytes16(namespace), - toBytes16(fileSelector), + toBytes16(name), tableName, Object.keys(schema), ]); - console.log(chalk.green(`Registered table ${tableName} at ${fileSelector}`)); + console.log(chalk.green(`Registered table ${tableName} at ${name}`)); }), ]; // Register systems (using forEach instead of for..of to avoid blocking on async calls) promises = [ ...promises, - ...Object.entries(mudConfig.systems).map( - async ([systemName, { fileSelector, openAccess, registerFunctionSelectors }]) => { - // Register system at route - console.log(chalk.blue(`Registering system ${systemName} at ${namespace}/${fileSelector}`)); - await fastTxExecute(WorldContract, "registerSystem", [ - toBytes16(namespace), - toBytes16(fileSelector), - await contractPromises[systemName], - openAccess, - ]); - console.log(chalk.green(`Registered system ${systemName} at ${namespace}/${fileSelector}`)); - - // Register function selectors for the system - if (registerFunctionSelectors) { - const functionSignatures: FunctionSignature[] = await loadFunctionSignatures(systemName); - const isRoot = namespace === ""; - // Using Promise.all to avoid blocking on async calls - await Promise.all( - functionSignatures.map(async ({ functionName, functionArgs }) => { - const functionSignature = isRoot - ? functionName + functionArgs - : `${namespace}_${fileSelector}_${functionName}${functionArgs}`; - - console.log(chalk.blue(`Registering function "${functionSignature}"`)); - if (isRoot) { - const worldFunctionSelector = toFunctionSelector( - functionSignature === "" - ? { functionName: systemName, functionArgs } // Register the system's fallback function as `()` - : { functionName, functionArgs } - ); - const systemFunctionSelector = toFunctionSelector({ functionName, functionArgs }); - await fastTxExecute(WorldContract, "registerRootFunctionSelector", [ - toBytes16(namespace), - toBytes16(fileSelector), - worldFunctionSelector, - systemFunctionSelector, - ]); - } else { - await fastTxExecute(WorldContract, "registerFunctionSelector", [ - toBytes16(namespace), - toBytes16(fileSelector), - functionName, - functionArgs, - ]); - } - console.log(chalk.green(`Registered function "${functionSignature}"`)); - }) - ); - } + ...Object.entries(mudConfig.systems).map(async ([systemName, { name, openAccess, registerFunctionSelectors }]) => { + // Register system at route + console.log(chalk.blue(`Registering system ${systemName} at ${namespace}/${name}`)); + await fastTxExecute(WorldContract, "registerSystem", [ + toBytes16(namespace), + toBytes16(name), + await contractPromises[systemName], + openAccess, + ]); + console.log(chalk.green(`Registered system ${systemName} at ${namespace}/${name}`)); + + // Register function selectors for the system + if (registerFunctionSelectors) { + const functionSignatures: FunctionSignature[] = await loadFunctionSignatures(systemName); + const isRoot = namespace === ""; + // Using Promise.all to avoid blocking on async calls + await Promise.all( + functionSignatures.map(async ({ functionName, functionArgs }) => { + const functionSignature = isRoot + ? functionName + functionArgs + : `${namespace}_${name}_${functionName}${functionArgs}`; + + console.log(chalk.blue(`Registering function "${functionSignature}"`)); + if (isRoot) { + const worldFunctionSelector = toFunctionSelector( + functionSignature === "" + ? { functionName: systemName, functionArgs } // Register the system's fallback function as `()` + : { functionName, functionArgs } + ); + const systemFunctionSelector = toFunctionSelector({ functionName, functionArgs }); + await fastTxExecute(WorldContract, "registerRootFunctionSelector", [ + toBytes16(namespace), + toBytes16(name), + worldFunctionSelector, + systemFunctionSelector, + ]); + } else { + await fastTxExecute(WorldContract, "registerFunctionSelector", [ + toBytes16(namespace), + toBytes16(name), + functionName, + functionArgs, + ]); + } + console.log(chalk.green(`Registered function "${functionSignature}"`)); + }) + ); } - ), + }), ]; // Wait for resources to be registered before granting access to them @@ -219,10 +217,8 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig): promises = []; // Grant access to systems - for (const [systemName, { fileSelector, accessListAddresses, accessListSystems }] of Object.entries( - mudConfig.systems - )) { - const resourceSelector = `${namespace}/${fileSelector}`; + for (const [systemName, { name, accessListAddresses, accessListSystems }] of Object.entries(mudConfig.systems)) { + const resourceSelector = `${namespace}/${name}`; // Grant access to addresses promises = [ @@ -231,10 +227,10 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig): console.log(chalk.blue(`Grant ${address} access to ${systemName} (${resourceSelector})`)); await fastTxExecute(WorldContract, "grantAccess(bytes16,bytes16,address)", [ toBytes16(namespace), - toBytes16(fileSelector), + toBytes16(name), address, ]); - console.log(chalk.green(`Granted ${address} access to ${systemName} (${namespace}/${fileSelector})`)); + console.log(chalk.green(`Granted ${address} access to ${systemName} (${namespace}/${name})`)); }), ]; @@ -245,7 +241,7 @@ export async function deploy(mudConfig: MUDConfig, deployConfig: DeployConfig): console.log(chalk.blue(`Grant ${granteeSystem} access to ${systemName} (${resourceSelector})`)); await fastTxExecute(WorldContract, "grantAccess(bytes16,bytes16,address)", [ toBytes16(namespace), - toBytes16(fileSelector), + toBytes16(name), await contractPromises[granteeSystem], ]); console.log(chalk.green(`Granted ${granteeSystem} access to ${systemName} (${resourceSelector})`)); diff --git a/packages/config/src/store/parseStoreConfig.ts b/packages/config/src/store/parseStoreConfig.ts index 35756a4af4..eca059b27f 100644 --- a/packages/config/src/store/parseStoreConfig.ts +++ b/packages/config/src/store/parseStoreConfig.ts @@ -59,11 +59,11 @@ export interface TableConfig< /** Output directory path for the file. Default is "tables" */ directory?: string; /** - * The fileSelector is used with the namespace to register the table and construct its id. - * The table id will be uint256(bytes32(abi.encodePacked(bytes16(namespace), bytes16(fileSelector)))). + * The name is used with the namespace to register the table and construct its id. + * The table id will be uint256(bytes32(abi.encodePacked(bytes16(namespace), bytes16(name)))). * Default is "" * */ - fileSelector?: string; + name?: string; /** Make methods accept `tableId` argument instead of it being a hardcoded constant. Default is false */ tableIdArgument?: boolean; /** Include methods that accept a manual `IStore` argument. Default is true. */ @@ -79,7 +79,7 @@ export interface TableConfig< const zFullTableConfig = z .object({ directory: z.string().default("tables"), - fileSelector: zSelector.optional(), + name: zSelector.optional(), tableIdArgument: z.boolean().default(false), storeArgument: z.boolean().default(true), primaryKeys: zPrimaryKeys, @@ -118,14 +118,14 @@ export type TablesConfig< > = Record | FieldData>; export const zTablesConfig = z.record(zTableName, zTableConfig).transform((tables) => { - // default fileSelector depends on tableName + // default name depends on tableName for (const tableName of Object.keys(tables)) { const table = tables[tableName]; - table.fileSelector ??= tableName; + table.name ??= tableName; tables[tableName] = table; } - return tables as Record>; + return tables as Record>; }); /************************************************************************ diff --git a/packages/config/src/world/parseWorldConfig.ts b/packages/config/src/world/parseWorldConfig.ts index a20ee763f1..b8b0482074 100644 --- a/packages/config/src/world/parseWorldConfig.ts +++ b/packages/config/src/world/parseWorldConfig.ts @@ -6,10 +6,10 @@ const zSystemName = zObjectName; const zModuleName = zObjectName; const zSystemAccessList = z.array(zSystemName.or(zEthereumAddress)).default([]); -// The system config is a combination of a fileSelector config and access config +// The system config is a combination of a name config and access config const zSystemConfig = z.intersection( z.object({ - fileSelector: zSelector, + name: zSelector, registerFunctionSelectors: z.boolean().default(true), }), z.discriminatedUnion("openAccess", [ diff --git a/packages/config/src/world/resolveWorldConfig.ts b/packages/config/src/world/resolveWorldConfig.ts index 1012ff3575..2c6f048c88 100644 --- a/packages/config/src/world/resolveWorldConfig.ts +++ b/packages/config/src/world/resolveWorldConfig.ts @@ -49,14 +49,14 @@ export function resolveWorldConfig(config: ParsedWorldConfig, existingContracts? * @param config optional SystemConfig object, if none is provided the default config is used * @param existingContracts optional list of existing contract names, used to validate system names in the access list. If not provided, no validation is performed. * @returns ResolvedSystemConfig object - * Default value for fileSelector is `systemName` + * Default value for name is `systemName` * Default value for registerFunctionSelectors is true * Default value for openAccess is true * Default value for accessListAddresses is [] * Default value for accessListSystems is [] */ export function resolveSystemConfig(systemName: string, config?: SystemUserConfig, existingContracts?: string[]) { - const fileSelector = config?.fileSelector ?? systemName; + const name = config?.name ?? systemName; const registerFunctionSelectors = config?.registerFunctionSelectors ?? true; const openAccess = config?.openAccess ?? true; const accessListAddresses: string[] = []; @@ -76,5 +76,5 @@ export function resolveSystemConfig(systemName: string, config?: SystemUserConfi } } - return { fileSelector, registerFunctionSelectors, openAccess, accessListAddresses, accessListSystems }; + return { name, registerFunctionSelectors, openAccess, accessListAddresses, accessListSystems }; } diff --git a/packages/config/src/world/userTypes.ts b/packages/config/src/world/userTypes.ts index 7c155f10d4..04576792c1 100644 --- a/packages/config/src/world/userTypes.ts +++ b/packages/config/src/world/userTypes.ts @@ -3,8 +3,8 @@ import { DynamicResolution } from "../dynamicResolution.js"; // zod doesn't preserve doc comments export type SystemUserConfig = | { - /** The full resource selector consists of namespace and fileSelector */ - fileSelector?: string; + /** The full resource selector consists of namespace and name */ + name?: string; /** * Register function selectors for the system in the World. * Defaults to true. diff --git a/packages/std-client/src/mud-definitions/world/contractComponents.ts b/packages/std-client/src/mud-definitions/world/contractComponents.ts index a6e426a2a6..4647ba097b 100644 --- a/packages/std-client/src/mud-definitions/world/contractComponents.ts +++ b/packages/std-client/src/mud-definitions/world/contractComponents.ts @@ -87,7 +87,7 @@ export function defineContractComponents(world: World) { world, { namespace: RecsType.String, - file: RecsType.String, + name: RecsType.String, systemFunctionSelector: RecsType.String, }, { diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index c3ea08f8b4..165024adae 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -26,7 +26,7 @@ { "source": "test/KeysWithValueModule.t.sol", "name": "set a record on a table with KeysWithValueModule installed", - "functionCall": "world.setRecord(namespace, sourceFile, keyTuple1, abi.encodePacked(value))", + "functionCall": "world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value))", "gasUsed": 169574 }, { @@ -38,13 +38,13 @@ { "source": "test/KeysWithValueModule.t.sol", "name": "change a record on a table with KeysWithValueModule installed", - "functionCall": "world.setRecord(namespace, sourceFile, keyTuple1, abi.encodePacked(value2))", + "functionCall": "world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value2))", "gasUsed": 135571 }, { "source": "test/KeysWithValueModule.t.sol", "name": "delete a record on a table with KeysWithValueModule installed", - "functionCall": "world.deleteRecord(namespace, sourceFile, keyTuple1)", + "functionCall": "world.deleteRecord(namespace, sourceName, keyTuple1)", "gasUsed": 58023 }, { @@ -56,13 +56,13 @@ { "source": "test/KeysWithValueModule.t.sol", "name": "set a field on a table with KeysWithValueModule installed", - "functionCall": "world.setField(namespace, sourceFile, keyTuple1, 0, abi.encodePacked(value1))", + "functionCall": "world.setField(namespace, sourceName, keyTuple1, 0, abi.encodePacked(value1))", "gasUsed": 177719 }, { "source": "test/KeysWithValueModule.t.sol", "name": "change a field on a table with KeysWithValueModule installed", - "functionCall": "world.setField(namespace, sourceFile, keyTuple1, 0, abi.encodePacked(value2))", + "functionCall": "world.setField(namespace, sourceName, keyTuple1, 0, abi.encodePacked(value2))", "gasUsed": 142065 }, { @@ -92,31 +92,31 @@ { "source": "test/World.t.sol", "name": "Delete record", - "functionCall": "world.deleteRecord(namespace, file, singletonKey)", + "functionCall": "world.deleteRecord(namespace, name, singletonKey)", "gasUsed": 16187 }, { "source": "test/World.t.sol", "name": "Push data to the table", - "functionCall": "world.pushToField(namespace, file, keyTuple, 0, encodedData)", + "functionCall": "world.pushToField(namespace, name, keyTuple, 0, encodedData)", "gasUsed": 96573 }, { "source": "test/World.t.sol", "name": "Register a fallback system", - "functionCall": "bytes4 funcSelector1 = world.registerFunctionSelector(namespace, file, \"\", \"\")", + "functionCall": "bytes4 funcSelector1 = world.registerFunctionSelector(namespace, name, \"\", \"\")", "gasUsed": 81249 }, { "source": "test/World.t.sol", "name": "Register a root fallback system", - "functionCall": "bytes4 funcSelector2 = world.registerRootFunctionSelector(namespace, file, worldFunc, 0)", + "functionCall": "bytes4 funcSelector2 = world.registerRootFunctionSelector(namespace, name, worldFunc, 0)", "gasUsed": 72482 }, { "source": "test/World.t.sol", "name": "Register a function selector", - "functionCall": "bytes4 functionSelector = world.registerFunctionSelector(namespace, file, \"msgSender\", \"()\")", + "functionCall": "bytes4 functionSelector = world.registerFunctionSelector(namespace, name, \"msgSender\", \"()\")", "gasUsed": 101846 }, { @@ -128,7 +128,7 @@ { "source": "test/World.t.sol", "name": "Register a root function selector", - "functionCall": "bytes4 functionSelector = world.registerRootFunctionSelector(namespace, file, worldFunc, sysFunc)", + "functionCall": "bytes4 functionSelector = world.registerRootFunctionSelector(namespace, name, worldFunc, sysFunc)", "gasUsed": 88388 }, { @@ -140,13 +140,13 @@ { "source": "test/World.t.sol", "name": "Write data to a table field", - "functionCall": "world.setField(namespace, file, singletonKey, 0, abi.encodePacked(true))", + "functionCall": "world.setField(namespace, name, singletonKey, 0, abi.encodePacked(true))", "gasUsed": 44866 }, { "source": "test/World.t.sol", "name": "Set metadata", - "functionCall": "world.setMetadata(namespace, file, tableName, fieldNames)", + "functionCall": "world.setMetadata(namespace, name, tableName, fieldNames)", "gasUsed": 277483 }, { diff --git a/packages/world/mud.config.mts b/packages/world/mud.config.mts index 649f23a2c0..9c539dc5db 100644 --- a/packages/world/mud.config.mts +++ b/packages/world/mud.config.mts @@ -52,13 +52,13 @@ export default mudConfig({ }, }, FunctionSelectors: { - fileSelector: "funcSelectors", + name: "funcSelectors", primaryKeys: { functionSelector: "bytes4", }, schema: { namespace: "bytes16", - file: "bytes16", + name: "bytes16", systemFunctionSelector: "bytes4", }, dataStruct: false, diff --git a/packages/world/src/AccessControl.sol b/packages/world/src/AccessControl.sol index d7a08604c0..e7b2aec660 100644 --- a/packages/world/src/AccessControl.sol +++ b/packages/world/src/AccessControl.sol @@ -11,39 +11,39 @@ library AccessControl { using ResourceSelector for bytes32; /** - * Returns true if the caller has access to the namespace or file, false otherwise. + * Returns true if the caller has access to the namespace or name, false otherwise. */ - function hasAccess(bytes16 namespace, bytes16 file, address caller) internal view returns (bool) { + function hasAccess(bytes16 namespace, bytes16 name, address caller) internal view returns (bool) { return address(this) == caller || // First check if the World is calling itself ResourceAccess.get(ResourceSelector.from(namespace, 0), caller) || // Then check access based on the namespace - ResourceAccess.get(ResourceSelector.from(namespace, file), caller); // If caller has no namespace access, check access on the file + ResourceAccess.get(ResourceSelector.from(namespace, name), caller); // If caller has no namespace access, check access on the name } /** - * Check for access at the given namespace or file. + * Check for access at the given namespace or name. * Returns the resourceSelector if the caller has access. * Reverts with AccessDenied if the caller has no access. */ function requireAccess( bytes16 namespace, - bytes16 file, + bytes16 name, address caller ) internal view returns (bytes32 resourceSelector) { - resourceSelector = ResourceSelector.from(namespace, file); + resourceSelector = ResourceSelector.from(namespace, name); - // Check if the given caller has access to the given namespace or file - if (!hasAccess(namespace, file, caller)) { + // Check if the given caller has access to the given namespace or name + if (!hasAccess(namespace, name, caller)) { revert IErrors.AccessDenied(resourceSelector.toString(), caller); } } function requireOwnerOrSelf( bytes16 namespace, - bytes16 file, + bytes16 name, address caller ) internal view returns (bytes32 resourceSelector) { - resourceSelector = ResourceSelector.from(namespace, file); + resourceSelector = ResourceSelector.from(namespace, name); if (address(this) != caller && NamespaceOwner.get(namespace) != caller) { revert IErrors.AccessDenied(resourceSelector.toString(), caller); diff --git a/packages/world/src/ResourceSelector.sol b/packages/world/src/ResourceSelector.sol index ebb5dc2909..a5fbcf7bfe 100644 --- a/packages/world/src/ResourceSelector.sol +++ b/packages/world/src/ResourceSelector.sol @@ -1,24 +1,24 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { ROOT_NAMESPACE, ROOT_FILE } from "./constants.sol"; +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_FILE_STRING = bytes16("ROOT_FILE"); +bytes16 constant ROOT_NAME_STRING = bytes16("ROOT_NAME"); library ResourceSelector { /** - * Create a 32-byte resource selector from a namespace and a file. + * 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 file. + * The first 16 bytes represent the namespace, the last 16 bytes represent the name. */ - function from(bytes16 namespace, bytes16 file) internal pure returns (bytes32) { - return bytes32(namespace) | (bytes32(file) >> 128); + 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 file. + * 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); @@ -39,9 +39,9 @@ library ResourceSelector { } /** - * Get the file of a ResourceSelector. + * Get the name of a ResourceSelector. */ - function getFile(bytes32 resourceSelector) internal pure returns (bytes16) { + function getName(bytes32 resourceSelector) internal pure returns (bytes16) { return bytes16(resourceSelector << 128); } @@ -50,13 +50,13 @@ library ResourceSelector { */ function toString(bytes32 resourceSelector) internal pure returns (string memory) { bytes16 namespace = getNamespace(resourceSelector); - bytes16 file = getFile(resourceSelector); + bytes16 name = getName(resourceSelector); return string( abi.encodePacked( namespace == ROOT_NAMESPACE ? ROOT_NAMESPACE_STRING : namespace, "/", - file == ROOT_FILE ? ROOT_FILE_STRING : file + name == ROOT_NAME ? ROOT_NAME_STRING : name ) ); } diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index 52b293675c..5f7e04e152 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -9,7 +9,7 @@ import { Bytes } from "@latticexyz/store/src/Bytes.sol"; import { System } from "./System.sol"; import { ResourceSelector } from "./ResourceSelector.sol"; import { Resource } from "./Types.sol"; -import { ROOT_NAMESPACE, ROOT_FILE, REGISTRATION_SYSTEM_NAME } from "./constants.sol"; +import { ROOT_NAMESPACE, ROOT_NAME, REGISTRATION_SYSTEM_NAME } from "./constants.sol"; import { AccessControl } from "./AccessControl.sol"; import { Call } from "./Call.sol"; @@ -59,7 +59,7 @@ contract World is Store, IWorldCore { * The module is delegatecalled and installed in the root namespace. */ function installRootModule(IModule module, bytes memory args) public { - AccessControl.requireOwnerOrSelf(ROOT_NAMESPACE, ROOT_FILE, msg.sender); + AccessControl.requireOwnerOrSelf(ROOT_NAMESPACE, ROOT_NAME, msg.sender); Call.withSender({ msgSender: msg.sender, @@ -84,27 +84,27 @@ contract World is Store, IWorldCore { * Requires the caller to own the namespace. */ function grantAccess(bytes16 namespace, address grantee) public virtual { - grantAccess(namespace, ROOT_FILE, grantee); + grantAccess(namespace, ROOT_NAME, grantee); } /** - * Grant access to the resource at the given namespace and file. + * Grant access to the resource at the given namespace and name. * Requires the caller to own the namespace. */ - function grantAccess(bytes16 namespace, bytes16 file, address grantee) public virtual { + function grantAccess(bytes16 namespace, bytes16 name, address grantee) public virtual { // Require the caller to own the namespace - bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, file, msg.sender); + bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, name, msg.sender); // Grant access to the given resource ResourceAccess.set(resourceSelector, grantee, true); } /** - * Retract access from the resource at the given namespace and file. + * Retract access from the resource at the given namespace and name. */ - function retractAccess(bytes16 namespace, bytes16 file, address grantee) public virtual { + function retractAccess(bytes16 namespace, bytes16 name, address grantee) public virtual { // Require the caller to own the namespace - bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, file, msg.sender); + bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, name, msg.sender); // Retract access from the given resource ResourceAccess.deleteRecord(resourceSelector, grantee); @@ -117,79 +117,79 @@ contract World is Store, IWorldCore { ************************************************************************/ /** - * Write a record in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Write a record in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ - function setRecord(bytes16 namespace, bytes16 file, bytes32[] calldata key, bytes calldata data) public virtual { - // Require access to the namespace or file - bytes32 resourceSelector = AccessControl.requireAccess(namespace, file, msg.sender); + function setRecord(bytes16 namespace, bytes16 name, bytes32[] calldata key, bytes calldata data) public virtual { + // Require access to the namespace or name + bytes32 resourceSelector = AccessControl.requireAccess(namespace, name, msg.sender); // Set the record StoreCore.setRecord(resourceSelector.toTableId(), key, data); } /** - * Write a field in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Write a field in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ function setField( bytes16 namespace, - bytes16 file, + bytes16 name, bytes32[] calldata key, uint8 schemaIndex, bytes calldata data ) public virtual { - // Require access to namespace or file - bytes32 resourceSelector = AccessControl.requireAccess(namespace, file, msg.sender); + // Require access to namespace or name + bytes32 resourceSelector = AccessControl.requireAccess(namespace, name, msg.sender); // Set the field StoreCore.setField(resourceSelector.toTableId(), key, schemaIndex, data); } /** - * Push data to the end of a field in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Push data to the end of a field in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ function pushToField( bytes16 namespace, - bytes16 file, + bytes16 name, bytes32[] calldata key, uint8 schemaIndex, bytes calldata dataToPush ) public virtual { - // Require access to namespace or file - bytes32 resourceSelector = AccessControl.requireAccess(namespace, file, msg.sender); + // Require access to namespace or name + bytes32 resourceSelector = AccessControl.requireAccess(namespace, name, msg.sender); // Push to the field StoreCore.pushToField(resourceSelector.toTableId(), key, schemaIndex, dataToPush); } /** - * Update data at `startByteIndex` of a field in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Update data at `startByteIndex` of a field in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ function updateInField( bytes16 namespace, - bytes16 file, + bytes16 name, bytes32[] calldata key, uint8 schemaIndex, uint256 startByteIndex, bytes calldata dataToSet ) public virtual { - // Require access to namespace or file - bytes32 resourceSelector = AccessControl.requireAccess(namespace, file, msg.sender); + // Require access to namespace or name + bytes32 resourceSelector = AccessControl.requireAccess(namespace, name, msg.sender); // Update data in the field StoreCore.updateInField(resourceSelector.toTableId(), key, schemaIndex, startByteIndex, dataToSet); } /** - * Delete a record in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Delete a record in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ - function deleteRecord(bytes16 namespace, bytes16 file, bytes32[] calldata key) public virtual { - // Require access to namespace or file - bytes32 resourceSelector = AccessControl.requireAccess(namespace, file, msg.sender); + function deleteRecord(bytes16 namespace, bytes16 name, bytes32[] calldata key) public virtual { + // Require access to namespace or name + bytes32 resourceSelector = AccessControl.requireAccess(namespace, name, msg.sender); // Delete the record StoreCore.deleteRecord(resourceSelector.toTableId(), key); @@ -204,7 +204,7 @@ contract World is Store, IWorldCore { /** * Register the given schema for the given table id. * This overload exists to conform with the IStore interface. - * The tableId is converted to a resourceSelector, and access is checked based on the namespace or file. + * The tableId is converted to a resourceSelector, and access is checked based on the namespace or name. */ function registerSchema(uint256 tableId, Schema valueSchema, Schema keySchema) public virtual { bytes32 tableSelector = ResourceSelector.from(tableId); @@ -218,7 +218,7 @@ contract World is Store, IWorldCore { funcSelectorAndArgs: abi.encodeWithSelector( IRegistrationSystem.registerTable.selector, tableSelector.getNamespace(), - tableSelector.getFile(), + tableSelector.getName(), valueSchema, keySchema ), @@ -230,7 +230,7 @@ contract World is Store, IWorldCore { /** * Register metadata (tableName, fieldNames) for the table at the given tableId. * This overload exists to conform with the `IStore` interface. - * The tableId is converted to a resourceSelector, and access is checked based on the namespace or file. + * The tableId is converted to a resourceSelector, and access is checked based on the namespace or name. */ function setMetadata(uint256 tableId, string calldata tableName, string[] calldata fieldNames) public virtual { bytes32 resourceSelector = ResourceSelector.from(tableId); @@ -244,7 +244,7 @@ contract World is Store, IWorldCore { funcSelectorAndArgs: abi.encodeWithSelector( IRegistrationSystem.setMetadata.selector, resourceSelector.getNamespace(), - resourceSelector.getFile(), + resourceSelector.getName(), tableName, fieldNames ), @@ -269,7 +269,7 @@ contract World is Store, IWorldCore { funcSelectorAndArgs: abi.encodeWithSelector( IRegistrationSystem.registerTableHook.selector, resourceSelector.getNamespace(), - resourceSelector.getFile(), + resourceSelector.getName(), hook ), delegate: false, @@ -280,17 +280,17 @@ contract World is Store, IWorldCore { /** * Write a record in the table at the given tableId. * This overload exists to conform with the `IStore` interface. - * The tableId is converted to a resourceSelector, and access is checked based on the namespace or file. + * The tableId is converted to a resourceSelector, and access is checked based on the namespace or name. */ function setRecord(uint256 tableId, bytes32[] calldata key, bytes calldata data) public virtual { bytes32 resourceSelector = ResourceSelector.from(tableId); - setRecord(resourceSelector.getNamespace(), resourceSelector.getFile(), key, data); + setRecord(resourceSelector.getNamespace(), resourceSelector.getName(), key, data); } /** * Write a field in the table at the given tableId. * This overload exists to conform with the `IStore` interface. - * The tableId is converted to a resourceSelector, and access is checked based on the namespace or file. + * The tableId is converted to a resourceSelector, and access is checked based on the namespace or name. */ function setField( uint256 tableId, @@ -299,13 +299,13 @@ contract World is Store, IWorldCore { bytes calldata data ) public virtual override { bytes32 resourceSelector = ResourceSelector.from(tableId); - setField(resourceSelector.getNamespace(), resourceSelector.getFile(), key, schemaIndex, data); + setField(resourceSelector.getNamespace(), resourceSelector.getName(), key, schemaIndex, data); } /** * Push data to the end of a field in the table at the given tableId. * This overload exists to conform with the `IStore` interface. - * The tableId is converted to a resourceSelector, and access is checked based on the namespace or file. + * The tableId is converted to a resourceSelector, and access is checked based on the namespace or name. */ function pushToField( uint256 tableId, @@ -314,13 +314,13 @@ contract World is Store, IWorldCore { bytes calldata dataToPush ) public override { bytes32 resourceSelector = ResourceSelector.from(tableId); - pushToField(resourceSelector.getNamespace(), resourceSelector.getFile(), key, schemaIndex, dataToPush); + pushToField(resourceSelector.getNamespace(), resourceSelector.getName(), key, schemaIndex, dataToPush); } /** * Update data at `startByteIndex` of a field in the table at the given tableId. * This overload exists to conform with the `IStore` interface. - * The tableId is converted to a resourceSelector, and access is checked based on the namespace or file. + * The tableId is converted to a resourceSelector, and access is checked based on the namespace or name. */ function updateInField( uint256 tableId, @@ -332,7 +332,7 @@ contract World is Store, IWorldCore { bytes32 resourceSelector = ResourceSelector.from(tableId); updateInField( resourceSelector.getNamespace(), - resourceSelector.getFile(), + resourceSelector.getName(), key, schemaIndex, startByteIndex, @@ -343,11 +343,11 @@ contract World is Store, IWorldCore { /** * Delete a record in the table at the given tableId. * This overload exists to conform with the `IStore` interface. - * The tableId is converted to a resourceSelector, and access is checked based on the namespace or file. + * The tableId is converted to a resourceSelector, and access is checked based on the namespace or name. */ function deleteRecord(uint256 tableId, bytes32[] calldata key) public virtual override { bytes32 resourceSelector = ResourceSelector.from(tableId); - deleteRecord(resourceSelector.getNamespace(), resourceSelector.getFile(), key); + deleteRecord(resourceSelector.getNamespace(), resourceSelector.getName(), key); } /************************************************************************ @@ -357,36 +357,36 @@ contract World is Store, IWorldCore { ************************************************************************/ /** - * Call the system at the given namespace and file. - * If the system is not public, the caller must have access to the namespace or file. + * Call the system at the given namespace and name. + * If the system is not public, the caller must have access to the namespace or name. */ function call( bytes16 namespace, - bytes16 file, + bytes16 name, bytes memory funcSelectorAndArgs ) external payable virtual returns (bytes memory) { - return _call(namespace, file, funcSelectorAndArgs, msg.value); + return _call(namespace, name, funcSelectorAndArgs, msg.value); } /** - * Call the system at the given namespace and file and pass the given value. - * If the system is not public, the caller must have access to the namespace or file. + * Call the system at the given namespace and name and pass the given value. + * If the system is not public, the caller must have access to the namespace or name. */ function _call( bytes16 namespace, - bytes16 file, + bytes16 name, bytes memory funcSelectorAndArgs, uint256 value ) internal virtual returns (bytes memory) { // Load the system data - bytes32 resourceSelector = ResourceSelector.from(namespace, file); + bytes32 resourceSelector = ResourceSelector.from(namespace, name); (address systemAddress, bool publicAccess) = Systems.get(resourceSelector); // Check if the system exists if (systemAddress == address(0)) revert ResourceNotFound(resourceSelector.toString()); - // Allow access if the system is public or the caller has access to the namespace or file - if (!publicAccess) AccessControl.requireAccess(namespace, file, msg.sender); + // Allow access if the system is public or the caller has access to the namespace or name + if (!publicAccess) AccessControl.requireAccess(namespace, name, msg.sender); // Call the system and forward any return data return @@ -414,15 +414,15 @@ contract World is Store, IWorldCore { * Fallback function to call registered function selectors */ fallback() external payable { - (bytes16 namespace, bytes16 file, bytes4 systemFunctionSelector) = FunctionSelectors.get(msg.sig); + (bytes16 namespace, bytes16 name, bytes4 systemFunctionSelector) = FunctionSelectors.get(msg.sig); - if (namespace == 0 && file == 0) revert FunctionSelectorNotFound(msg.sig); + if (namespace == 0 && name == 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 value - bytes memory returnData = _call(namespace, file, callData, msg.value); + bytes memory returnData = _call(namespace, name, callData, msg.value); assembly { return(add(returnData, 0x20), mload(returnData)) } diff --git a/packages/world/src/constants.sol b/packages/world/src/constants.sol index 7bbaa930a3..b68eb815c0 100644 --- a/packages/world/src/constants.sol +++ b/packages/world/src/constants.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; bytes16 constant ROOT_NAMESPACE = 0; -bytes16 constant ROOT_FILE = 0; +bytes16 constant ROOT_NAME = 0; // World modules bytes16 constant CORE_MODULE_NAME = bytes16("core.m"); diff --git a/packages/world/src/interfaces/IRegistrationSystem.sol b/packages/world/src/interfaces/IRegistrationSystem.sol index 934ab4afb0..d782442a1b 100644 --- a/packages/world/src/interfaces/IRegistrationSystem.sol +++ b/packages/world/src/interfaces/IRegistrationSystem.sol @@ -10,41 +10,41 @@ interface IRegistrationSystem { function registerTable( bytes16 namespace, - bytes16 file, + bytes16 name, Schema valueSchema, Schema keySchema ) external returns (bytes32 resourceSelector); function setMetadata( bytes16 namespace, - bytes16 file, + bytes16 name, string calldata tableName, string[] calldata fieldNames ) external; - function registerHook(bytes16 namespace, bytes16 file, address hook) external; + function registerHook(bytes16 namespace, bytes16 name, address hook) external; - function registerTableHook(bytes16 namespace, bytes16 file, IStoreHook hook) external; + function registerTableHook(bytes16 namespace, bytes16 name, IStoreHook hook) external; - function registerSystemHook(bytes16 namespace, bytes16 file, ISystemHook hook) external; + function registerSystemHook(bytes16 namespace, bytes16 name, ISystemHook hook) external; function registerSystem( bytes16 namespace, - bytes16 file, + bytes16 name, System system, bool publicAccess ) external returns (bytes32 resourceSelector); function registerFunctionSelector( bytes16 namespace, - bytes16 file, + bytes16 name, string memory systemFunctionName, string memory systemFunctionArguments ) external returns (bytes4 worldFunctionSelector); function registerRootFunctionSelector( bytes16 namespace, - bytes16 file, + bytes16 name, bytes4 worldFunctionSelector, bytes4 systemFunctionSelector ) external returns (bytes4); diff --git a/packages/world/src/interfaces/IWorldCore.sol b/packages/world/src/interfaces/IWorldCore.sol index 593b9d6570..d5185ec66e 100644 --- a/packages/world/src/interfaces/IWorldCore.sol +++ b/packages/world/src/interfaces/IWorldCore.sol @@ -38,15 +38,15 @@ interface IWorldCore is IErrors { function grantAccess(bytes16 namespace, address grantee) external; /** - * Grant access to the resource at the given namespace and file. + * Grant access to the resource at the given namespace and name. * Requires the caller to own the namespace. */ - function grantAccess(bytes16 namespace, bytes16 file, address grantee) external; + function grantAccess(bytes16 namespace, bytes16 name, address grantee) external; /** - * Retract access from the resource at the given namespace and file. + * Retract access from the resource at the given namespace and name. */ - function retractAccess(bytes16 namespace, bytes16 file, address grantee) external; + function retractAccess(bytes16 namespace, bytes16 name, address grantee) external; /************************************************************************ * @@ -55,42 +55,42 @@ interface IWorldCore is IErrors { ************************************************************************/ /** - * Write a record in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Write a record in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ - function setRecord(bytes16 namespace, bytes16 file, bytes32[] calldata key, bytes calldata data) external; + function setRecord(bytes16 namespace, bytes16 name, bytes32[] calldata key, bytes calldata data) external; /** - * Write a field in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Write a field in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ function setField( bytes16 namespace, - bytes16 file, + bytes16 name, bytes32[] calldata key, uint8 schemaIndex, bytes calldata data ) external; /** - * Push data to the end of a field in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Push data to the end of a field in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ function pushToField( bytes16 namespace, - bytes16 file, + bytes16 name, bytes32[] calldata key, uint8 schemaIndex, bytes calldata dataToPush ) external; /** - * Update data at `startByteIndex` of a field in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Update data at `startByteIndex` of a field in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ function updateInField( bytes16 namespace, - bytes16 file, + bytes16 name, bytes32[] calldata key, uint8 schemaIndex, uint256 startByteIndex, @@ -98,10 +98,10 @@ interface IWorldCore is IErrors { ) external; /** - * Delete a record in the table at the given namespace and file. - * Requires the caller to have access to the namespace or file. + * Delete a record in the table at the given namespace and name. + * Requires the caller to have access to the namespace or name. */ - function deleteRecord(bytes16 namespace, bytes16 file, bytes32[] calldata key) external; + function deleteRecord(bytes16 namespace, bytes16 name, bytes32[] calldata key) external; /************************************************************************ * @@ -110,12 +110,12 @@ interface IWorldCore is IErrors { ************************************************************************/ /** - * Call the system at the given namespace and file. - * If the system is not public, the caller must have access to the namespace or file. + * Call the system at the given namespace and name. + * If the system is not public, the caller must have access to the namespace or name. */ function call( bytes16 namespace, - bytes16 file, + bytes16 name, bytes memory funcSelectorAndArgs ) external payable returns (bytes memory); } diff --git a/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol b/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol index 0a19737827..f68e341d64 100644 --- a/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol +++ b/packages/world/src/modules/keyswithvalue/KeysWithValueModule.sol @@ -44,7 +44,7 @@ contract KeysWithValueModule is IModule, WorldContext { // Register the target table IBaseWorld(_world()).registerTable( targetTableSelector.getNamespace(), - targetTableSelector.getFile(), + targetTableSelector.getName(), KeysWithValue.getSchema(), KeysWithValue.getKeySchema() ); @@ -53,13 +53,13 @@ contract KeysWithValueModule is IModule, WorldContext { (string memory tableName, string[] memory fieldNames) = KeysWithValue.getMetadata(); IBaseWorld(_world()).setMetadata( targetTableSelector.getNamespace(), - targetTableSelector.getFile(), + targetTableSelector.getName(), tableName, fieldNames ); // Grant the hook access to the target table - IBaseWorld(_world()).grantAccess(targetTableSelector.getNamespace(), targetTableSelector.getFile(), address(hook)); + IBaseWorld(_world()).grantAccess(targetTableSelector.getNamespace(), targetTableSelector.getName(), address(hook)); // Register a hook that is called when a value is set in the source table StoreSwitch.registerStoreHook(sourceTableId, hook); diff --git a/packages/world/src/modules/registration/RegistrationSystem.sol b/packages/world/src/modules/registration/RegistrationSystem.sol index 38ddd1666a..7ac7bd43c3 100644 --- a/packages/world/src/modules/registration/RegistrationSystem.sol +++ b/packages/world/src/modules/registration/RegistrationSystem.sol @@ -11,7 +11,7 @@ import { SystemRegistry } from "./tables/SystemRegistry.sol"; import { System } from "../../System.sol"; import { ResourceSelector } from "../../ResourceSelector.sol"; import { Resource } from "../../Types.sol"; -import { ROOT_NAMESPACE, ROOT_FILE } from "../../constants.sol"; +import { ROOT_NAMESPACE, ROOT_NAME } from "../../constants.sol"; import { AccessControl } from "../../AccessControl.sol"; import { NamespaceOwner } from "../../tables/NamespaceOwner.sol"; @@ -49,19 +49,19 @@ contract RegistrationSystem is System, IErrors { */ function registerTable( bytes16 namespace, - bytes16 file, + bytes16 name, Schema valueSchema, Schema keySchema ) public virtual returns (bytes32 resourceSelector) { - resourceSelector = ResourceSelector.from(namespace, file); + resourceSelector = ResourceSelector.from(namespace, name); - // Require the file selector to not be the namespace's root file - if (file == ROOT_FILE) revert InvalidSelector(resourceSelector.toString()); + // Require the name to not be the namespace's root name + if (name == ROOT_NAME) revert InvalidSelector(resourceSelector.toString()); // If the namespace doesn't exist yet, register it // otherwise require caller to own the namespace if (ResourceType.get(namespace) == Resource.NONE) registerNamespace(namespace); - else AccessControl.requireOwnerOrSelf(namespace, ROOT_FILE, _msgSender()); + else AccessControl.requireOwnerOrSelf(namespace, ROOT_NAME, _msgSender()); // Require no resource to exist at this selector yet if (ResourceType.get(resourceSelector) != Resource.NONE) { @@ -76,57 +76,57 @@ contract RegistrationSystem is System, IErrors { } /** - * Register metadata (tableName, fieldNames) for the table at the given namespace and file. + * Register metadata (tableName, fieldNames) for the table at the given namespace and name. * Requires the caller to own the namespace. */ function setMetadata( bytes16 namespace, - bytes16 file, + bytes16 name, string calldata tableName, string[] calldata fieldNames ) public virtual { // Require caller to own the namespace - bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, file, _msgSender()); + bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, name, _msgSender()); // Set the metadata StoreCore.setMetadata(resourceSelector.toTableId(), tableName, fieldNames); } /** - * Register the given store hook for the table at the given namespace and file. - * Hooks on table files must implement the IStoreHook interface, - * and hooks on system files must implement the ISystemHook interface. + * Register the given store hook for the table at the given namespace and name. + * Hooks on table names must implement the IStoreHook interface, + * and hooks on system names must implement the ISystemHook interface. */ - function registerHook(bytes16 namespace, bytes16 file, address hook) public virtual { - Resource resourceType = ResourceType.get(ResourceSelector.from(namespace, file)); + function registerHook(bytes16 namespace, bytes16 name, address hook) public virtual { + Resource resourceType = ResourceType.get(ResourceSelector.from(namespace, name)); if (resourceType == Resource.TABLE) { - return registerTableHook(namespace, file, IStoreHook(hook)); + return registerTableHook(namespace, name, IStoreHook(hook)); } if (resourceType == Resource.SYSTEM) { - return registerSystemHook(namespace, file, ISystemHook(hook)); + return registerSystemHook(namespace, name, ISystemHook(hook)); } - revert InvalidSelector(ResourceSelector.from(namespace, file).toString()); + revert InvalidSelector(ResourceSelector.from(namespace, name).toString()); } /** - * Register a hook for the table at the given namepace and file. + * Register a hook for the table at the given namepace and name. * Requires the caller to own the namespace. */ - function registerTableHook(bytes16 namespace, bytes16 file, IStoreHook hook) public virtual { + function registerTableHook(bytes16 namespace, bytes16 name, IStoreHook hook) public virtual { // Require caller to own the namespace - bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, file, _msgSender()); + bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, name, _msgSender()); // Register the hook StoreCore.registerStoreHook(resourceSelector.toTableId(), hook); } /** - * Register a hook for the system at the given namespace and file + * Register a hook for the system at the given namespace and name */ - function registerSystemHook(bytes16 namespace, bytes16 file, ISystemHook hook) public virtual { + function registerSystemHook(bytes16 namespace, bytes16 name, ISystemHook hook) public virtual { // TODO implement (see https://github.com/latticexyz/mud/issues/444) } @@ -138,14 +138,14 @@ contract RegistrationSystem is System, IErrors { */ function registerSystem( bytes16 namespace, - bytes16 file, + bytes16 name, System system, bool publicAccess ) public virtual returns (bytes32 resourceSelector) { - resourceSelector = ResourceSelector.from(namespace, file); + resourceSelector = ResourceSelector.from(namespace, name); - // Require the file selector to not be the namespace's root file - if (file == ROOT_FILE) revert InvalidSelector(resourceSelector.toString()); + // Require the name to not be the namespace's root name + if (name == ROOT_NAME) revert InvalidSelector(resourceSelector.toString()); // Require the system to not exist yet if (SystemRegistry.get(address(system)) != 0) revert SystemExists(address(system)); @@ -153,7 +153,7 @@ contract RegistrationSystem is System, IErrors { // If the namespace doesn't exist yet, register it // otherwise require caller to own the namespace if (ResourceType.get(namespace) == Resource.NONE) registerNamespace(namespace); - else AccessControl.requireOwnerOrSelf(namespace, ROOT_FILE, _msgSender()); + else AccessControl.requireOwnerOrSelf(namespace, ROOT_NAME, _msgSender()); // Require no resource to exist at this selector yet if (ResourceType.get(resourceSelector) != Resource.NONE) { @@ -174,43 +174,43 @@ contract RegistrationSystem is System, IErrors { } /** - * Register a World function selector for the given namespace, file and system function. + * Register a World function selector for the given namespace, name and system function. * TODO: instead of mapping to a resource, the function selector could map direcly to a system function, * which would save one sload per call, but add some complexity to upgrading systems. TBD. * (see https://github.com/latticexyz/mud/issues/444) */ function registerFunctionSelector( bytes16 namespace, - bytes16 file, + bytes16 name, string memory systemFunctionName, string memory systemFunctionArguments ) public returns (bytes4 worldFunctionSelector) { // Require the caller to own the namespace - AccessControl.requireOwnerOrSelf(namespace, file, _msgSender()); + AccessControl.requireOwnerOrSelf(namespace, name, _msgSender()); // Compute global function selector string memory namespaceString = ResourceSelector.toTrimmedString(namespace); - string memory fileString = ResourceSelector.toTrimmedString(file); + string memory nameString = ResourceSelector.toTrimmedString(name); worldFunctionSelector = bytes4( - keccak256(abi.encodePacked(namespaceString, "_", fileString, "_", systemFunctionName, systemFunctionArguments)) + keccak256(abi.encodePacked(namespaceString, "_", nameString, "_", systemFunctionName, systemFunctionArguments)) ); // Require the function selector to be globally unique bytes16 existingNamespace = FunctionSelectors.getNamespace(worldFunctionSelector); - bytes16 existingFile = FunctionSelectors.getFile(worldFunctionSelector); + bytes16 existingName = FunctionSelectors.getName(worldFunctionSelector); - if (existingNamespace != 0 || existingFile != 0) revert FunctionSelectorExists(worldFunctionSelector); + if (existingNamespace != 0 || existingName != 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, namespace, file, systemFunctionSelector); + FunctionSelectors.set(worldFunctionSelector, namespace, name, systemFunctionSelector); } /** - * Register a root World function selector (without namespace / file prefix). + * Register a root World function selector (without namespace / name prefix). * Requires the caller to own the root namespace. * TODO: instead of mapping to a resource, the function selector could map direcly to a system function, * which would save one sload per call, but add some complexity to upgrading systems. TBD. @@ -218,21 +218,21 @@ contract RegistrationSystem is System, IErrors { */ function registerRootFunctionSelector( bytes16 namespace, - bytes16 file, + bytes16 name, bytes4 worldFunctionSelector, bytes4 systemFunctionSelector ) public returns (bytes4) { // Require the caller to own the root namespace - AccessControl.requireOwnerOrSelf(ROOT_NAMESPACE, ROOT_FILE, _msgSender()); + AccessControl.requireOwnerOrSelf(ROOT_NAMESPACE, ROOT_NAME, _msgSender()); // Require the function selector to be globally unique bytes16 existingNamespace = FunctionSelectors.getNamespace(worldFunctionSelector); - bytes16 existingFile = FunctionSelectors.getFile(worldFunctionSelector); + bytes16 existingName = FunctionSelectors.getName(worldFunctionSelector); - if (!(existingNamespace == 0 && existingFile == 0)) revert FunctionSelectorExists(worldFunctionSelector); + if (!(existingNamespace == 0 && existingName == 0)) revert FunctionSelectorExists(worldFunctionSelector); // Register the function selector - FunctionSelectors.set(worldFunctionSelector, namespace, file, systemFunctionSelector); + FunctionSelectors.set(worldFunctionSelector, namespace, name, systemFunctionSelector); return worldFunctionSelector; } diff --git a/packages/world/src/modules/utils/getTargetTableSelector.sol b/packages/world/src/modules/utils/getTargetTableSelector.sol index 70f9a417ec..bfba37eac0 100644 --- a/packages/world/src/modules/utils/getTargetTableSelector.sol +++ b/packages/world/src/modules/utils/getTargetTableSelector.sol @@ -12,7 +12,7 @@ import { ResourceSelector } from "../../ResourceSelector.sol"; * - The last 16 bytes are the source table name */ function getTargetTableSelector(bytes8 moduleNamespace, uint256 sourceTableId) pure returns (bytes32) { - bytes16 tableName = ResourceSelector.getFile(bytes32(sourceTableId)); + bytes16 tableName = ResourceSelector.getName(bytes32(sourceTableId)); bytes8 sourceTableNamespace = bytes8(bytes32(sourceTableId)); return bytes32(moduleNamespace) | (bytes32(sourceTableNamespace) >> 64) | (bytes32(tableName) >> 128); } diff --git a/packages/world/src/tables/FunctionSelectors.sol b/packages/world/src/tables/FunctionSelectors.sol index 41c8974ce6..0ffddf7374 100644 --- a/packages/world/src/tables/FunctionSelectors.sol +++ b/packages/world/src/tables/FunctionSelectors.sol @@ -42,7 +42,7 @@ library FunctionSelectors { function getMetadata() internal pure returns (string memory, string[] memory) { string[] memory _fieldNames = new string[](3); _fieldNames[0] = "namespace"; - _fieldNames[1] = "file"; + _fieldNames[1] = "name"; _fieldNames[2] = "systemFunctionSelector"; return ("FunctionSelectors", _fieldNames); } @@ -103,8 +103,8 @@ library FunctionSelectors { _store.setField(_tableId, _primaryKeys, 0, abi.encodePacked((namespace))); } - /** Get file */ - function getFile(bytes4 functionSelector) internal view returns (bytes16 file) { + /** Get name */ + function getName(bytes4 functionSelector) internal view returns (bytes16 name) { bytes32[] memory _primaryKeys = new bytes32[](1); _primaryKeys[0] = bytes32((functionSelector)); @@ -112,8 +112,8 @@ library FunctionSelectors { return (Bytes.slice16(_blob, 0)); } - /** Get file (using the specified store) */ - function getFile(IStore _store, bytes4 functionSelector) internal view returns (bytes16 file) { + /** Get name (using the specified store) */ + function getName(IStore _store, bytes4 functionSelector) internal view returns (bytes16 name) { bytes32[] memory _primaryKeys = new bytes32[](1); _primaryKeys[0] = bytes32((functionSelector)); @@ -121,20 +121,20 @@ library FunctionSelectors { return (Bytes.slice16(_blob, 0)); } - /** Set file */ - function setFile(bytes4 functionSelector, bytes16 file) internal { + /** Set name */ + function setName(bytes4 functionSelector, bytes16 name) internal { bytes32[] memory _primaryKeys = new bytes32[](1); _primaryKeys[0] = bytes32((functionSelector)); - StoreSwitch.setField(_tableId, _primaryKeys, 1, abi.encodePacked((file))); + StoreSwitch.setField(_tableId, _primaryKeys, 1, abi.encodePacked((name))); } - /** Set file (using the specified store) */ - function setFile(IStore _store, bytes4 functionSelector, bytes16 file) internal { + /** Set name (using the specified store) */ + function setName(IStore _store, bytes4 functionSelector, bytes16 name) internal { bytes32[] memory _primaryKeys = new bytes32[](1); _primaryKeys[0] = bytes32((functionSelector)); - _store.setField(_tableId, _primaryKeys, 1, abi.encodePacked((file))); + _store.setField(_tableId, _primaryKeys, 1, abi.encodePacked((name))); } /** Get systemFunctionSelector */ @@ -177,7 +177,7 @@ library FunctionSelectors { /** Get the full data */ function get( bytes4 functionSelector - ) internal view returns (bytes16 namespace, bytes16 file, bytes4 systemFunctionSelector) { + ) internal view returns (bytes16 namespace, bytes16 name, bytes4 systemFunctionSelector) { bytes32[] memory _primaryKeys = new bytes32[](1); _primaryKeys[0] = bytes32((functionSelector)); @@ -189,7 +189,7 @@ library FunctionSelectors { function get( IStore _store, bytes4 functionSelector - ) internal view returns (bytes16 namespace, bytes16 file, bytes4 systemFunctionSelector) { + ) internal view returns (bytes16 namespace, bytes16 name, bytes4 systemFunctionSelector) { bytes32[] memory _primaryKeys = new bytes32[](1); _primaryKeys[0] = bytes32((functionSelector)); @@ -198,8 +198,8 @@ library FunctionSelectors { } /** Set the full data using individual values */ - function set(bytes4 functionSelector, bytes16 namespace, bytes16 file, bytes4 systemFunctionSelector) internal { - bytes memory _data = encode(namespace, file, systemFunctionSelector); + function set(bytes4 functionSelector, bytes16 namespace, bytes16 name, bytes4 systemFunctionSelector) internal { + bytes memory _data = encode(namespace, name, systemFunctionSelector); bytes32[] memory _primaryKeys = new bytes32[](1); _primaryKeys[0] = bytes32((functionSelector)); @@ -212,10 +212,10 @@ library FunctionSelectors { IStore _store, bytes4 functionSelector, bytes16 namespace, - bytes16 file, + bytes16 name, bytes4 systemFunctionSelector ) internal { - bytes memory _data = encode(namespace, file, systemFunctionSelector); + bytes memory _data = encode(namespace, name, systemFunctionSelector); bytes32[] memory _primaryKeys = new bytes32[](1); _primaryKeys[0] = bytes32((functionSelector)); @@ -226,17 +226,17 @@ library FunctionSelectors { /** Decode the tightly packed blob using this table's schema */ function decode( bytes memory _blob - ) internal pure returns (bytes16 namespace, bytes16 file, bytes4 systemFunctionSelector) { + ) internal pure returns (bytes16 namespace, bytes16 name, bytes4 systemFunctionSelector) { namespace = (Bytes.slice16(_blob, 0)); - file = (Bytes.slice16(_blob, 16)); + name = (Bytes.slice16(_blob, 16)); systemFunctionSelector = (Bytes.slice4(_blob, 32)); } /** Tightly pack full data using this table's schema */ - function encode(bytes16 namespace, bytes16 file, bytes4 systemFunctionSelector) internal view returns (bytes memory) { - return abi.encodePacked(namespace, file, systemFunctionSelector); + function encode(bytes16 namespace, bytes16 name, bytes4 systemFunctionSelector) internal view returns (bytes memory) { + return abi.encodePacked(namespace, name, systemFunctionSelector); } /* Delete all data for given keys */ diff --git a/packages/world/test/AccessControl.t.sol b/packages/world/test/AccessControl.t.sol index 78014f1b0f..522ba9f79f 100644 --- a/packages/world/test/AccessControl.t.sol +++ b/packages/world/test/AccessControl.t.sol @@ -13,7 +13,7 @@ import { NamespaceOwner } from "../src/tables/NamespaceOwner.sol"; contract AccessControlTest is Test, StoreView { bytes16 namespace = "namespace"; - bytes16 file = "file"; + bytes16 name = "name"; address caller = address(0x01); function setUp() public { @@ -25,31 +25,31 @@ contract AccessControlTest is Test, StoreView { } function testAccessControl() public { - // Check that the caller has no access to the namespace or file - assertFalse(AccessControl.hasAccess(namespace, file, caller)); + // Check that the caller has no access to the namespace or name + assertFalse(AccessControl.hasAccess(namespace, name, caller)); // Grant access to the namespace ResourceAccess.set(ResourceSelector.from(namespace, 0), caller, true); - // Check that the caller has access to the namespace or file - assertTrue(AccessControl.hasAccess(namespace, file, caller)); + // Check that the caller has access to the namespace or name + assertTrue(AccessControl.hasAccess(namespace, name, caller)); // Revoke access to the namespace ResourceAccess.set(ResourceSelector.from(namespace, 0), caller, false); - // Check that the caller has no access to the namespace or file - assertFalse(AccessControl.hasAccess(namespace, file, caller)); + // Check that the caller has no access to the namespace or name + assertFalse(AccessControl.hasAccess(namespace, name, caller)); - // Grant access to the file - ResourceAccess.set(ResourceSelector.from(namespace, file), caller, true); + // Grant access to the name + ResourceAccess.set(ResourceSelector.from(namespace, name), caller, true); - // Check that the caller has access to the file - assertTrue(AccessControl.hasAccess(namespace, file, caller)); + // Check that the caller has access to the name + assertTrue(AccessControl.hasAccess(namespace, name, caller)); - // Revoke access to the file - ResourceAccess.set(ResourceSelector.from(namespace, file), caller, false); + // Revoke access to the name + ResourceAccess.set(ResourceSelector.from(namespace, name), caller, false); - // Check that the caller has no access to the namespace or file - assertFalse(AccessControl.hasAccess(namespace, file, caller)); + // Check that the caller has no access to the namespace or name + assertFalse(AccessControl.hasAccess(namespace, name, caller)); } } diff --git a/packages/world/test/KeysWithValueModule.t.sol b/packages/world/test/KeysWithValueModule.t.sol index 0796936208..32bebcb4ed 100644 --- a/packages/world/test/KeysWithValueModule.t.sol +++ b/packages/world/test/KeysWithValueModule.t.sol @@ -25,7 +25,7 @@ contract KeysWithValueModuleTest is Test { KeysWithValueModule keysWithValueModule = new KeysWithValueModule(); // Modules can be deployed once and installed multiple times bytes16 namespace = ROOT_NAMESPACE; - bytes16 sourceFile = bytes16("source"); + bytes16 sourceName = bytes16("source"); bytes32 key1 = keccak256("test"); bytes32[] keyTuple1; bytes32 key2 = keccak256("test2"); @@ -46,13 +46,13 @@ contract KeysWithValueModuleTest is Test { keyTuple1[0] = key1; keyTuple2 = new bytes32[](1); keyTuple2[0] = key2; - sourceTableId = ResourceSelector.from(namespace, sourceFile).toTableId(); + sourceTableId = ResourceSelector.from(namespace, sourceName).toTableId(); targetTableId = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId).toTableId(); } function _installKeysWithValueModule() internal { // Register source table - sourceTableId = uint256(world.registerTable(namespace, sourceFile, sourceTableSchema, sourceTableKeySchema)); + sourceTableId = uint256(world.registerTable(namespace, sourceName, sourceTableSchema, sourceTableKeySchema)); // Install the index module // TODO: add support for installing this via installModule @@ -67,7 +67,7 @@ contract KeysWithValueModuleTest is Test { uint256 value = 1; // !gasreport set a record on a table with KeysWithValueModule installed - world.setRecord(namespace, sourceFile, keyTuple1, abi.encodePacked(value)); + world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value)); // Get the list of entities with this value from the target table bytes32[] memory keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value))); @@ -83,7 +83,7 @@ contract KeysWithValueModuleTest is Test { // Set a value in the source table uint256 value1 = 1; - world.setRecord(namespace, sourceFile, keyTuple1, abi.encodePacked(value1)); + world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value1)); // Get the list of entities with value1 from the target table bytes32[] memory keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); @@ -93,7 +93,7 @@ contract KeysWithValueModuleTest is Test { assertEq(keysWithValue[0], key1, "2"); // Set a another key with the same value - world.setRecord(namespace, sourceFile, keyTuple2, abi.encodePacked(value1)); + world.setRecord(namespace, sourceName, keyTuple2, abi.encodePacked(value1)); // Get the list of entities with value2 from the target table keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); @@ -107,7 +107,7 @@ contract KeysWithValueModuleTest is Test { uint256 value2 = 2; // !gasreport change a record on a table with KeysWithValueModule installed - world.setRecord(namespace, sourceFile, keyTuple1, abi.encodePacked(value2)); + world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value2)); // Get the list of entities with value1 from the target table keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); @@ -125,7 +125,7 @@ contract KeysWithValueModuleTest is Test { // Delete the first key // !gasreport delete a record on a table with KeysWithValueModule installed - world.deleteRecord(namespace, sourceFile, keyTuple1); + world.deleteRecord(namespace, sourceName, keyTuple1); // Get the list of entities with value2 from the target table keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value2))); @@ -141,7 +141,7 @@ contract KeysWithValueModuleTest is Test { uint256 value1 = 1; // !gasreport set a field on a table with KeysWithValueModule installed - world.setField(namespace, sourceFile, keyTuple1, 0, abi.encodePacked(value1)); + world.setField(namespace, sourceName, keyTuple1, 0, abi.encodePacked(value1)); // Get the list of entities with value1 from the target table bytes32[] memory keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); @@ -154,7 +154,7 @@ contract KeysWithValueModuleTest is Test { // Change the value using setField // !gasreport change a field on a table with KeysWithValueModule installed - world.setField(namespace, sourceFile, keyTuple1, 0, abi.encodePacked(value2)); + world.setField(namespace, sourceName, keyTuple1, 0, abi.encodePacked(value2)); // Get the list of entities with value1 from the target table keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); @@ -180,8 +180,8 @@ contract KeysWithValueModuleTest is Test { // followed by the first 4 bytes of the source table namespace assertEq(bytes8(targetTableSelector << 64), bytes8(namespace)); - // The last 16 bytes are the source file - assertEq(targetTableSelector.getFile(), sourceFile); + // The last 16 bytes are the source name + assertEq(targetTableSelector.getName(), sourceName); } function testGetKeysWithValue() public { @@ -190,7 +190,7 @@ contract KeysWithValueModuleTest is Test { // Set a value in the source table uint256 value1 = 1; - world.setRecord(namespace, sourceFile, keyTuple1, abi.encodePacked(value1)); + world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value1)); // !gasreport Get list of keys with a given value bytes32[] memory keysWithValue = getKeysWithValue(world, sourceTableId, abi.encode(value1)); @@ -200,7 +200,7 @@ contract KeysWithValueModuleTest is Test { assertEq(keysWithValue[0], key1); // Set a another key with the same value - world.setRecord(namespace, sourceFile, keyTuple2, abi.encodePacked(value1)); + world.setRecord(namespace, sourceName, keyTuple2, abi.encodePacked(value1)); // Get the list of keys with value2 from the target table keysWithValue = getKeysWithValue(world, sourceTableId, abi.encode(value1)); diff --git a/packages/world/test/World.t.sol b/packages/world/test/World.t.sol index a5b571fec0..39a4dbcaaf 100644 --- a/packages/world/test/World.t.sol +++ b/packages/world/test/World.t.sol @@ -14,7 +14,7 @@ import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; import { World } from "../src/World.sol"; import { System } from "../src/System.sol"; import { ResourceSelector } from "../src/ResourceSelector.sol"; -import { ROOT_NAMESPACE, ROOT_FILE } from "../src/constants.sol"; +import { ROOT_NAMESPACE, ROOT_NAME } from "../src/constants.sol"; import { NamespaceOwner } from "../src/tables/NamespaceOwner.sol"; import { ResourceAccess } from "../src/tables/ResourceAccess.sol"; @@ -66,14 +66,14 @@ contract WorldTestSystem is System { return returndata; } - function writeData(bytes16 namespace, bytes16 file, bool data) public { + function writeData(bytes16 namespace, bytes16 name, bool data) public { bytes32[] memory key = new bytes32[](0); if (StoreSwitch.isDelegateCall()) { - uint256 tableId = uint256(ResourceSelector.from(namespace, file)); + uint256 tableId = uint256(ResourceSelector.from(namespace, name)); StoreCore.setRecord(tableId, key, abi.encodePacked(data)); } else { - IBaseWorld(msg.sender).setRecord(namespace, file, key, abi.encodePacked(data)); + IBaseWorld(msg.sender).setRecord(namespace, name, key, abi.encodePacked(data)); } } @@ -141,10 +141,10 @@ contract WorldTest is Test { } // Expect an error when trying to write from an address that doesn't have access - function _expectAccessDenied(address caller, bytes16 namespace, bytes16 file) internal { + function _expectAccessDenied(address caller, bytes16 namespace, bytes16 name) internal { vm.prank(caller); vm.expectRevert( - abi.encodeWithSelector(IErrors.AccessDenied.selector, ResourceSelector.from(namespace, file).toString(), caller) + abi.encodeWithSelector(IErrors.AccessDenied.selector, ResourceSelector.from(namespace, name).toString(), caller) ); } @@ -209,8 +209,8 @@ contract WorldTest is Test { function testSetMetadata() public { string memory tableName = "testTable"; bytes16 namespace = "testNamespace"; - bytes16 file = "tableName"; - bytes32 resourceSelector = ResourceSelector.from(namespace, file); + bytes16 name = "tableName"; + bytes32 resourceSelector = ResourceSelector.from(namespace, name); uint256 tableId = uint256(resourceSelector); Schema schema = SchemaLib.encode(SchemaType.UINT8, SchemaType.UINT8); @@ -223,10 +223,10 @@ contract WorldTest is Test { world.setMetadata("invalid", "invalid", tableName, fieldNames); // Register a table - world.registerTable(namespace, file, schema, defaultKeySchema); + world.registerTable(namespace, name, schema, defaultKeySchema); // !gasreport Set metadata - world.setMetadata(namespace, file, tableName, fieldNames); + world.setMetadata(namespace, name, tableName, fieldNames); // Expect the metadata to be set StoreMetadataData memory metadata = StoreMetadata.get(world, tableId); @@ -234,27 +234,27 @@ contract WorldTest is Test { assertEq(metadata.abiEncodedFieldNames, abi.encode(fieldNames)); // Expect it to be possible to change metadata - world.setMetadata(namespace, file, "newTableName", fieldNames); + world.setMetadata(namespace, name, "newTableName", fieldNames); metadata = StoreMetadata.get(world, tableId); assertEq(metadata.tableName, "newTableName"); assertEq(metadata.abiEncodedFieldNames, abi.encode(fieldNames)); // Expect an error when setting metadata on a route that is not owned by the caller - _expectAccessDenied(address(1), namespace, file); - world.setMetadata(namespace, file, tableName, fieldNames); + _expectAccessDenied(address(1), namespace, name); + world.setMetadata(namespace, name, tableName, fieldNames); // Expect the World to be allowed to set metadata vm.prank(address(world)); - world.setMetadata(namespace, file, tableName, fieldNames); + world.setMetadata(namespace, name, tableName, fieldNames); } function testRegisterSystem() public { System system = new System(); bytes16 namespace = ""; - bytes16 file = "testSystem"; + bytes16 name = "testSystem"; // !gasrepot Register a new system - bytes32 resourceSelector = world.registerSystem(namespace, file, system, false); + bytes32 resourceSelector = world.registerSystem(namespace, name, system, false); // Expect the system to be registered (address registeredAddress, bool publicAccess) = Systems.get(world, resourceSelector); @@ -304,21 +304,21 @@ contract WorldTest is Test { function testDuplicateSelectors() public { // Register a new table - bytes32 resourceSelector = world.registerTable("namespace", "file", Bool.getSchema(), defaultKeySchema); + bytes32 resourceSelector = world.registerTable("namespace", "name", Bool.getSchema(), defaultKeySchema); // 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(IErrors.ResourceExists.selector, resourceSelector.toString())); - world.registerSystem("namespace", "file", system, false); + world.registerSystem("namespace", "name", system, false); // Register a new system - resourceSelector = world.registerSystem("namespace2", "file", new System(), false); + resourceSelector = world.registerSystem("namespace2", "name", new System(), false); // Expect an error when trying to register a table at the same selector vm.expectRevert(abi.encodeWithSelector(IErrors.ResourceExists.selector, resourceSelector.toString())); - world.registerTable("namespace2", "file", Bool.getSchema(), defaultKeySchema); + world.registerTable("namespace2", "name", Bool.getSchema(), defaultKeySchema); } function testGrantAccess() public { @@ -351,14 +351,14 @@ contract WorldTest is Test { function testSetField() public { bytes16 namespace = "testSetField"; - bytes16 file = "testTable"; + bytes16 name = "testTable"; // Register a new table - bytes32 resourceSelector = world.registerTable(namespace, file, Bool.getSchema(), defaultKeySchema); + bytes32 resourceSelector = world.registerTable(namespace, name, Bool.getSchema(), defaultKeySchema); uint256 tableId = uint256(resourceSelector); // !gasreport Write data to a table field - world.setField(namespace, file, singletonKey, 0, abi.encodePacked(true)); + world.setField(namespace, name, singletonKey, 0, abi.encodePacked(true)); // Expect the data to be written assertTrue(Bool.get(world, tableId)); @@ -384,10 +384,10 @@ contract WorldTest is Test { function testPushToField() public { bytes16 namespace = "testPushToField"; - bytes16 file = "testTable"; + bytes16 name = "testTable"; // Register a new table - bytes32 resourceSelector = world.registerTable(namespace, file, AddressArray.getSchema(), defaultKeySchema); + bytes32 resourceSelector = world.registerTable(namespace, name, AddressArray.getSchema(), defaultKeySchema); uint256 tableId = uint256(resourceSelector); // Create data @@ -398,13 +398,13 @@ contract WorldTest is Test { bytes memory encodedData = EncodeArray.encode(dataToPush); // !gasreport Push data to the table - world.pushToField(namespace, file, keyTuple, 0, encodedData); + world.pushToField(namespace, name, keyTuple, 0, encodedData); // Expect the data to be written assertEq(AddressArray.get(world, tableId, key), dataToPush); // Delete the data - world.deleteRecord(namespace, file, keyTuple); + world.deleteRecord(namespace, name, keyTuple); // Push data to the table via direct access world.pushToField(tableId, keyTuple, 0, encodedData); @@ -412,25 +412,25 @@ contract WorldTest is Test { // Expect the data to be written assertEq(AddressArray.get(world, tableId, key), dataToPush); - // Expect an error when trying to write from an address that doesn't have access (via namespace/file) - _expectAccessDenied(address(0x01), namespace, file); - world.pushToField(namespace, file, keyTuple, 0, encodedData); + // Expect an error when trying to write from an address that doesn't have access (via namespace/name) + _expectAccessDenied(address(0x01), namespace, name); + world.pushToField(namespace, name, keyTuple, 0, encodedData); // Expect an error when trying to write from an address that doesn't have access (via tableId) - _expectAccessDenied(address(0x01), namespace, file); + _expectAccessDenied(address(0x01), namespace, name); world.pushToField(tableId, keyTuple, 0, encodedData); // Expect the World to have access vm.prank(address(world)); - world.pushToField(namespace, file, keyTuple, 0, encodedData); + world.pushToField(namespace, name, keyTuple, 0, encodedData); } function testUpdateInField() public { bytes16 namespace = "testUpdInField"; - bytes16 file = "testTable"; + bytes16 name = "testTable"; // Register a new table - bytes32 resourceSelector = world.registerTable(namespace, file, AddressArray.getSchema(), defaultKeySchema); + bytes32 resourceSelector = world.registerTable(namespace, name, AddressArray.getSchema(), defaultKeySchema); uint256 tableId = uint256(resourceSelector); // Create data @@ -440,7 +440,7 @@ contract WorldTest is Test { initData[2] = address(bytes20(keccak256("another address"))); bytes memory encodedData = EncodeArray.encode(initData); - world.setField(namespace, file, keyTuple, 0, encodedData); + world.setField(namespace, name, keyTuple, 0, encodedData); // Expect the data to be written assertEq(AddressArray.get(world, tableId, key), initData); @@ -448,7 +448,7 @@ contract WorldTest is Test { // Update index 0 address[] memory dataForUpdate = new address[](1); dataForUpdate[0] = address(bytes20(keccak256("address for update"))); - world.updateInField(namespace, file, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate)); + world.updateInField(namespace, name, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate)); // Expect the data to be updated initData[0] = dataForUpdate[0]; @@ -461,33 +461,33 @@ contract WorldTest is Test { initData[1] = dataForUpdate[0]; assertEq(AddressArray.get(world, tableId, key), initData); - // Expect an error when trying to write from an address that doesn't have access (via namespace/file) - _expectAccessDenied(address(0x01), namespace, file); - world.updateInField(namespace, file, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate)); + // Expect an error when trying to write from an address that doesn't have access (via namespace/name) + _expectAccessDenied(address(0x01), namespace, name); + world.updateInField(namespace, name, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate)); // Expect an error when trying to write from an address that doesn't have access (via tableId) - _expectAccessDenied(address(0x01), namespace, file); + _expectAccessDenied(address(0x01), namespace, name); world.updateInField(tableId, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate)); // Expect the World to have access vm.prank(address(world)); - world.updateInField(namespace, file, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate)); + world.updateInField(namespace, name, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate)); } function testDeleteRecord() public { bytes16 namespace = "testDeleteRecord"; - bytes16 file = "testTable"; + bytes16 name = "testTable"; // Register a new table - bytes32 resourceSelector = world.registerTable(namespace, file, Bool.getSchema(), defaultKeySchema); + bytes32 resourceSelector = world.registerTable(namespace, name, Bool.getSchema(), defaultKeySchema); uint256 tableId = uint256(resourceSelector); // Write data to the table via the namespace and expect it to be written - world.setRecord(namespace, file, singletonKey, abi.encodePacked(true)); + world.setRecord(namespace, name, singletonKey, abi.encodePacked(true)); assertTrue(Bool.get(world, tableId)); // !gasreport Delete record - world.deleteRecord(namespace, file, singletonKey); + world.deleteRecord(namespace, name, singletonKey); // expect it to be deleted assertFalse(Bool.get(world, tableId)); @@ -676,14 +676,14 @@ contract WorldTest is Test { function testRegisterFunctionSelector() public { bytes16 namespace = "testNamespace"; - bytes16 file = "testSystem"; + bytes16 name = "testSystem"; // Register a new system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(namespace, file, system, true); + world.registerSystem(namespace, name, system, true); // !gasreport Register a function selector - bytes4 functionSelector = world.registerFunctionSelector(namespace, file, "msgSender", "()"); + bytes4 functionSelector = world.registerFunctionSelector(namespace, name, "msgSender", "()"); string memory expectedWorldFunctionSignature = "testNamespace_testSystem_msgSender()"; bytes4 expectedWorldFunctionSelector = bytes4(keccak256(abi.encodePacked(expectedWorldFunctionSignature))); @@ -696,7 +696,7 @@ contract WorldTest is Test { assertEq(abi.decode(data, (address)), address(this), "wrong address returned"); // Register a function selector to the error function - functionSelector = world.registerFunctionSelector(namespace, file, "err", "(string)"); + functionSelector = world.registerFunctionSelector(namespace, name, "err", "(string)"); // Expect errors to be passed through vm.expectRevert(abi.encodeWithSelector(WorldTestSystem.WorldTestSystemError.selector, "test error")); @@ -705,25 +705,25 @@ contract WorldTest is Test { function testRegisterRootFunctionSelector() public { bytes16 namespace = "testNamespace"; - bytes16 file = "testSystem"; + bytes16 name = "testSystem"; // Register a new system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(namespace, file, system, true); + world.registerSystem(namespace, name, 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(namespace, file, worldFunc, sysFunc); + world.registerRootFunctionSelector(namespace, name, worldFunc, sysFunc); // Expect the World to be able to register a root function selector vm.prank(address(world)); - world.registerRootFunctionSelector(namespace, file, "smth", "smth"); + world.registerRootFunctionSelector(namespace, name, "smth", "smth"); // !gasreport Register a root function selector - bytes4 functionSelector = world.registerRootFunctionSelector(namespace, file, worldFunc, sysFunc); + bytes4 functionSelector = world.registerRootFunctionSelector(namespace, name, worldFunc, sysFunc); assertEq(functionSelector, worldFunc, "wrong function selector returned"); @@ -736,7 +736,7 @@ contract WorldTest is Test { // Register a function selector to the error function functionSelector = world.registerRootFunctionSelector( namespace, - file, + name, WorldTestSystem.err.selector, WorldTestSystem.err.selector ); @@ -748,14 +748,14 @@ contract WorldTest is Test { function testRegisterFallbackSystem() public { bytes16 namespace = "testNamespace"; - bytes16 file = "testSystem"; + bytes16 name = "testSystem"; // Register a new system WorldTestSystem system = new WorldTestSystem(); - world.registerSystem(namespace, file, system, true); + world.registerSystem(namespace, name, system, true); // !gasreport Register a fallback system - bytes4 funcSelector1 = world.registerFunctionSelector(namespace, file, "", ""); + bytes4 funcSelector1 = world.registerFunctionSelector(namespace, name, "", ""); // Call the system's fallback function vm.expectEmit(true, true, true, true); @@ -766,7 +766,7 @@ contract WorldTest is Test { bytes4 worldFunc = bytes4(abi.encodeWithSignature("testSelector()")); // !gasreport Register a root fallback system - bytes4 funcSelector2 = world.registerRootFunctionSelector(namespace, file, worldFunc, 0); + bytes4 funcSelector2 = world.registerRootFunctionSelector(namespace, name, worldFunc, 0); assertEq(funcSelector2, worldFunc, "wrong function selector returned"); // Call the system's fallback function @@ -801,11 +801,11 @@ contract WorldTest is Test { // Register a root system with a payable function in the world WorldTestSystem system = new WorldTestSystem(); bytes16 namespace = "noroot"; - bytes16 file = "testSystem"; - world.registerSystem(namespace, file, system, true); + bytes16 name = "testSystem"; + world.registerSystem(namespace, name, system, true); world.registerRootFunctionSelector( namespace, - file, + name, WorldTestSystem.receiveEther.selector, WorldTestSystem.receiveEther.selector ); @@ -833,11 +833,11 @@ contract WorldTest is Test { // Register a root system with a non-payable function in the world WorldTestSystem system = new WorldTestSystem(); bytes16 namespace = "noroot"; - bytes16 file = "testSystem"; - world.registerSystem(namespace, file, system, true); + bytes16 name = "testSystem"; + world.registerSystem(namespace, name, system, true); world.registerRootFunctionSelector( namespace, - file, + name, WorldTestSystem.msgSender.selector, WorldTestSystem.msgSender.selector ); @@ -865,11 +865,11 @@ contract WorldTest is Test { // Register a root system with a non-payable function in the world WorldTestSystem system = new WorldTestSystem(); bytes16 namespace = "noroot"; - bytes16 file = "testSystem"; - world.registerSystem(namespace, file, system, true); + bytes16 name = "testSystem"; + world.registerSystem(namespace, name, system, true); world.registerRootFunctionSelector( namespace, - file, + name, bytes4(abi.encodeWithSignature("systemFallback()")), bytes4("") ); @@ -895,11 +895,11 @@ contract WorldTest is Test { // Register a root system with a non-payable function in the world PayableFallbackSystem system = new PayableFallbackSystem(); bytes16 namespace = "noroot"; - bytes16 file = "testSystem"; - world.registerSystem(namespace, file, system, true); + bytes16 name = "testSystem"; + world.registerSystem(namespace, name, system, true); world.registerRootFunctionSelector( namespace, - file, + name, bytes4(abi.encodeWithSignature("systemFallback()")), bytes4("") ); @@ -925,11 +925,11 @@ contract WorldTest is Test { // Register a root system with a payable function in the world WorldTestSystem system = new WorldTestSystem(); bytes16 namespace = ""; - bytes16 file = "testSystem"; - world.registerSystem(namespace, file, system, true); + bytes16 name = "testSystem"; + world.registerSystem(namespace, name, system, true); world.registerRootFunctionSelector( namespace, - file, + name, WorldTestSystem.receiveEther.selector, WorldTestSystem.receiveEther.selector );