Skip to content

Commit

Permalink
continue refactoring namespace+name to resource selector
Browse files Browse the repository at this point in the history
  • Loading branch information
alvrs committed Aug 16, 2023
1 parent a317d93 commit 0dc4a2b
Show file tree
Hide file tree
Showing 12 changed files with 153 additions and 141 deletions.
4 changes: 2 additions & 2 deletions packages/world/src/interfaces/IAccessManagementSystem.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pragma solidity >=0.8.0;
/* Autogenerated file. Do not edit manually. */

interface IAccessManagementSystem {
function grantAccess(bytes16 namespace, bytes16 name, address grantee) external;
function grantAccess(bytes32 resourceSelector, address grantee) external;

function revokeAccess(bytes16 namespace, bytes16 name, address grantee) external;
function revokeAccess(bytes32 resourceSelector, address grantee) external;
}
6 changes: 2 additions & 4 deletions packages/world/src/interfaces/IBaseWorld.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@ pragma solidity >=0.8.0;

import { IStore } from "@latticexyz/store/src/IStore.sol";
import { IWorldKernel } from "../interfaces/IWorldKernel.sol";
import { IWorldEphemeral } from "../interfaces/IWorldEphemeral.sol";

import { ICoreSystem } from "./ICoreSystem.sol";
import { IAccessManagementSystem } from "./IAccessManagementSystem.sol";
import { IModuleInstallationSystem } from "./IModuleInstallationSystem.sol";
import { IRegistrationSystem } from "./IRegistrationSystem.sol";
import { IWorldRegistrationSystem } from "./IWorldRegistrationSystem.sol";

/**
* The IBaseWorld interface includes all systems dynamically added to the World
Expand All @@ -19,11 +18,10 @@ import { IRegistrationSystem } from "./IRegistrationSystem.sol";
interface IBaseWorld is
IStore,
IWorldKernel,
IWorldEphemeral,
ICoreSystem,
IAccessManagementSystem,
IModuleInstallationSystem,
IRegistrationSystem
IWorldRegistrationSystem
{

}
22 changes: 0 additions & 22 deletions packages/world/src/interfaces/IWorldEphemeral.sol

This file was deleted.

27 changes: 27 additions & 0 deletions packages/world/src/interfaces/IWorldRegistrationSystem.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

/* Autogenerated file. Do not edit manually. */

import { ISystemHook } from "./ISystemHook.sol";
import { System } from "./../System.sol";

interface IWorldRegistrationSystem {
function registerNamespace(bytes16 namespace) external;

function registerSystemHook(bytes32 resourceSelector, ISystemHook hook) external;

function registerSystem(bytes32 resourceSelector, System system, bool publicAccess) external;

function registerFunctionSelector(
bytes32 resourceSelector,
string memory systemFunctionName,
string memory systemFunctionArguments
) external returns (bytes4 worldFunctionSelector);

function registerRootFunctionSelector(
bytes32 resourceSelector,
bytes4 worldFunctionSelector,
bytes4 systemFunctionSelector
) external returns (bytes4);
}
31 changes: 15 additions & 16 deletions packages/world/src/modules/core/CoreModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { IBaseWorld } from "../../interfaces/IBaseWorld.sol";
import { IModule } from "../../interfaces/IModule.sol";

import { IStoreEphemeral } from "@latticexyz/store/src/IStore.sol";
import { IWorldEphemeral } from "../../interfaces/IWorldEphemeral.sol";
import { ResourceSelector } from "../../ResourceSelector.sol";

import { NamespaceOwner } from "../../tables/NamespaceOwner.sol";
Expand All @@ -26,7 +25,8 @@ import { ResourceType } from "./tables/ResourceType.sol";
import { SystemHooks } from "./tables/SystemHooks.sol";
import { SystemRegistry } from "./tables/SystemRegistry.sol";

import { RegistrationSystem } from "./implementations/RegistrationSystem.sol";
import { WorldRegistrationSystem } from "./implementations/WorldRegistrationSystem.sol";
import { StoreRegistrationSystem } from "./implementations/StoreRegistrationSystem.sol";
import { ModuleInstallationSystem } from "./implementations/ModuleInstallationSystem.sol";
import { AccessManagementSystem } from "./implementations/AccessManagementSystem.sol";
import { EphemeralRecordSystem } from "./implementations/EphemeralRecordSystem.sol";
Expand Down Expand Up @@ -80,7 +80,7 @@ contract CoreModule is IModule, WorldContext {
delegate: true,
value: 0,
funcSelectorAndArgs: abi.encodeWithSelector(
RegistrationSystem.registerSystem.selector,
WorldRegistrationSystem.registerSystem.selector,
ROOT_NAMESPACE,
CORE_SYSTEM_NAME,
coreSystem,
Expand All @@ -93,24 +93,23 @@ contract CoreModule is IModule, WorldContext {
* Register function selectors for all CoreSystem functions in the World
*/
function _registerFunctionSelectors() internal {
bytes4[13] memory functionSelectors = [
// --- RegistrationSystem ---
RegistrationSystem.registerNamespace.selector,
RegistrationSystem.registerTable.selector,
RegistrationSystem.registerHook.selector,
RegistrationSystem.registerStoreHook.selector,
RegistrationSystem.registerSystemHook.selector,
RegistrationSystem.registerSystem.selector,
RegistrationSystem.registerFunctionSelector.selector,
RegistrationSystem.registerRootFunctionSelector.selector,
bytes4[11] memory functionSelectors = [
// --- WorldRegistrationSystem ---
WorldRegistrationSystem.registerNamespace.selector,
WorldRegistrationSystem.registerSystemHook.selector,
WorldRegistrationSystem.registerSystem.selector,
WorldRegistrationSystem.registerFunctionSelector.selector,
WorldRegistrationSystem.registerRootFunctionSelector.selector,
// --- StoreRegistrationSystem ---
StoreRegistrationSystem.registerTable.selector,
StoreRegistrationSystem.registerStoreHook.selector,
// --- ModuleInstallationSystem ---
ModuleInstallationSystem.installModule.selector,
// --- AccessManagementSystem ---
AccessManagementSystem.grantAccess.selector,
AccessManagementSystem.revokeAccess.selector,
// --- EphemeralRecordSystem ---
IStoreEphemeral.emitEphemeralRecord.selector,
IWorldEphemeral.emitEphemeralRecord.selector
IStoreEphemeral.emitEphemeralRecord.selector
];

for (uint256 i = 0; i < functionSelectors.length; i++) {
Expand All @@ -122,7 +121,7 @@ contract CoreModule is IModule, WorldContext {
delegate: true,
value: 0,
funcSelectorAndArgs: abi.encodeWithSelector(
RegistrationSystem.registerRootFunctionSelector.selector,
WorldRegistrationSystem.registerRootFunctionSelector.selector,
ResourceSelector.from(ROOT_NAMESPACE, CORE_SYSTEM_NAME),
functionSelectors[i],
functionSelectors[i]
Expand Down
6 changes: 4 additions & 2 deletions packages/world/src/modules/core/CoreSystem.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ pragma solidity >=0.8.0;

import { IWorldErrors } from "../../interfaces/IWorldErrors.sol";

import { RegistrationSystem } from "./implementations/RegistrationSystem.sol";
import { StoreRegistrationSystem } from "./implementations/StoreRegistrationSystem.sol";
import { WorldRegistrationSystem } from "./implementations/WorldRegistrationSystem.sol";
import { ModuleInstallationSystem } from "./implementations/ModuleInstallationSystem.sol";
import { AccessManagementSystem } from "./implementations/AccessManagementSystem.sol";
import { EphemeralRecordSystem } from "./implementations/EphemeralRecordSystem.sol";
Expand All @@ -14,7 +15,8 @@ import { EphemeralRecordSystem } from "./implementations/EphemeralRecordSystem.s
*/
contract CoreSystem is
IWorldErrors,
RegistrationSystem,
StoreRegistrationSystem,
WorldRegistrationSystem,
ModuleInstallationSystem,
AccessManagementSystem,
EphemeralRecordSystem
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ pragma solidity >=0.8.0;
import { IModule } from "../../../interfaces/IModule.sol";
import { System } from "../../../System.sol";
import { AccessControl } from "../../../AccessControl.sol";
import { ResourceSelector } from "../../../ResourceSelector.sol";
import { Call } from "../../../Call.sol";
import { ResourceAccess } from "../../../tables/ResourceAccess.sol";
import { InstalledModules } from "../../../tables/InstalledModules.sol";
Expand All @@ -16,9 +17,9 @@ contract AccessManagementSystem is System {
* Grant access to the resource at the given namespace and name.
* Requires the caller to own the namespace.
*/
function grantAccess(bytes16 namespace, bytes16 name, address grantee) public virtual {
function grantAccess(bytes32 resourceSelector, address grantee) public virtual {
// Require the caller to own the namespace
bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, name, _msgSender());
AccessControl.requireOwnerOrSelf(resourceSelector, _msgSender());

// Grant access to the given resource
ResourceAccess.set(resourceSelector, grantee, true);
Expand All @@ -28,9 +29,9 @@ contract AccessManagementSystem is System {
* Revoke access from the resource at the given namespace and name.
* Requires the caller to own the namespace.
*/
function revokeAccess(bytes16 namespace, bytes16 name, address grantee) public virtual {
function revokeAccess(bytes32 resourceSelector, address grantee) public virtual {
// Require the caller to own the namespace
bytes32 resourceSelector = AccessControl.requireOwnerOrSelf(namespace, name, _msgSender());
AccessControl.requireOwnerOrSelf(resourceSelector, _msgSender());

// Revoke access from the given resource
ResourceAccess.deleteRecord(resourceSelector, grantee);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ pragma solidity >=0.8.0;
import { IStoreEphemeral } from "@latticexyz/store/src/IStore.sol";
import { Schema } from "@latticexyz/store/src/Schema.sol";
import { IModule } from "../../../interfaces/IModule.sol";
import { IWorldEphemeral } from "../../../interfaces/IWorldEphemeral.sol";
import { System } from "../../../System.sol";
import { ResourceSelector } from "../../../ResourceSelector.sol";
import { AccessControl } from "../../../AccessControl.sol";
Expand All @@ -13,38 +12,23 @@ import { ResourceAccess } from "../../../tables/ResourceAccess.sol";
import { InstalledModules } from "../../../tables/InstalledModules.sol";
import { StoreCore } from "@latticexyz/store/src/StoreCore.sol";

contract EphemeralRecordSystem is IStoreEphemeral, IWorldEphemeral, System {
contract EphemeralRecordSystem is IStoreEphemeral, System {
using ResourceSelector for bytes32;

/**
* Emit the ephemeral event without modifying storage at the given namespace and name.
* Requires the caller to have access to the namespace or name.
* Requires the caller to have access to the namespace or name (encoded in the resource selector)
*/
function emitEphemeralRecord(
bytes16 namespace,
bytes16 name,
bytes32 resourceSelector,
bytes32[] calldata key,
bytes calldata data,
Schema valueSchema
) public virtual {
// Require access to the namespace or name
bytes32 resourceSelector = AccessControl.requireAccess(namespace, name, msg.sender);
AccessControl.requireAccess(resourceSelector, msg.sender);

// Set the record
StoreCore.emitEphemeralRecord(resourceSelector, key, data, valueSchema);
}

/**
* Emit the ephemeral event without modifying storage at the given tableId.
* This overload exists to conform with the `IStore` interface.
* Access is checked based on the namespace or name (encoded in the tableId).
*/
function emitEphemeralRecord(
bytes32 tableId,
bytes32[] calldata key,
bytes calldata data,
Schema valueSchema
) public virtual {
emitEphemeralRecord(tableId.getNamespace(), tableId.getName(), key, data, valueSchema);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import { IStoreHook } from "@latticexyz/store/src/IStore.sol";
import { StoreCore } from "@latticexyz/store/src/StoreCore.sol";
import { Schema } from "@latticexyz/store/src/Schema.sol";

import { System } from "../../../System.sol";
import { ResourceSelector } from "../../../ResourceSelector.sol";
import { Resource } from "../../../Types.sol";
import { ROOT_NAMESPACE, ROOT_NAME } from "../../../constants.sol";
import { AccessControl } from "../../../AccessControl.sol";
import { Call } from "../../../Call.sol";
import { NamespaceOwner } from "../../../tables/NamespaceOwner.sol";
import { ResourceAccess } from "../../../tables/ResourceAccess.sol";
import { ISystemHook } from "../../../interfaces/ISystemHook.sol";
import { IWorldErrors } from "../../../interfaces/IWorldErrors.sol";

import { ResourceType } from "../tables/ResourceType.sol";
import { SystemHooks } from "../tables/SystemHooks.sol";
import { SystemRegistry } from "../tables/SystemRegistry.sol";
import { Systems } from "../tables/Systems.sol";
import { FunctionSelectors } from "../tables/FunctionSelectors.sol";

import { CORE_SYSTEM_NAME } from "../constants.sol";

import { WorldRegistrationSystem } from "./WorldRegistrationSystem.sol";

/**
* Functions related to registering table resources in the World.
*/
contract StoreRegistrationSystem is System, IWorldErrors {
using ResourceSelector for bytes32;

/**
* Register a table with given schema in the given namespace
*/
function registerTable(
bytes32 resourceSelector,
Schema keySchema,
Schema valueSchema,
string[] calldata keyNames,
string[] calldata fieldNames
) public virtual {
// Require the name to not be the namespace's root name
if (resourceSelector.getName() == ROOT_NAME) revert InvalidSelector(resourceSelector.toString());

// If the namespace doesn't exist yet, register it
bytes16 namespace = resourceSelector.getNamespace();
if (ResourceType.get(namespace) == Resource.NONE) {
// We can't call IBaseWorld(this).registerSchema directly because it would be handled like
// an external call, so msg.sender would be the address of the World contract
(address systemAddress, ) = Systems.get(ResourceSelector.from(ROOT_NAMESPACE, CORE_SYSTEM_NAME));
Call.withSender({
msgSender: _msgSender(),
target: systemAddress,
funcSelectorAndArgs: abi.encodeWithSelector(WorldRegistrationSystem.registerNamespace.selector, namespace),
delegate: true,
value: 0
});
} else {
// otherwise require caller to own the namespace
AccessControl.requireOwnerOrSelf(namespace, _msgSender());
}

// Require no resource to exist at this selector yet
if (ResourceType.get(resourceSelector) != Resource.NONE) {
revert ResourceExists(resourceSelector.toString());
}

// Store the table resource type
ResourceType.set(resourceSelector, Resource.TABLE);

// Register the table's schema
StoreCore.registerTable(resourceSelector, keySchema, valueSchema, keyNames, fieldNames);
}

/**
* Register a hook for the table at the given namepace and name.
* Requires the caller to own the namespace.
*/
function registerStoreHook(bytes32 tableId, IStoreHook hook) public virtual {
// Require caller to own the namespace
AccessControl.requireOwnerOrSelf(tableId, _msgSender());

// Register the hook
StoreCore.registerStoreHook(tableId, hook);
}
}
Loading

0 comments on commit 0dc4a2b

Please sign in to comment.