Skip to content

Commit

Permalink
feat(world): remove system name from function signatures/selectors [M…
Browse files Browse the repository at this point in the history
…-05] (#2160)

Co-authored-by: alvrs <alvarius@lattice.xyz>
  • Loading branch information
holic and alvrs committed Jan 22, 2024
1 parent 52c37b5 commit 0f27afd
Show file tree
Hide file tree
Showing 9 changed files with 19 additions and 21 deletions.
8 changes: 8 additions & 0 deletions .changeset/bright-kangaroos-battle.md
@@ -0,0 +1,8 @@
---
"@latticexyz/world-modules": patch
"@latticexyz/world": major
---

World function signatures for namespaced systems have changed from `{namespace}_{systemName}_{functionName}` to `{namespace}__{functionName}` (double underscore, no system name). This is more ergonomic and is more consistent with namespaced resources in other parts of the codebase (e.g. MUD config types, table names in the schemaful indexer).

If you have a project using the `namespace` key in your `mud.config.ts` or are manually registering systems and function selectors on a namespace, you will likely need to codegen your system interfaces (`pnpm build`) and update any calls to these systems through the world's namespaced function signatures.
@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.21;

// TODO allow overriding namespace per-system
interface IChatNamespacedSystem {
function namespace_ChatNamespaced_sendMessage(string memory message) external;
function namespace__sendMessage(string memory message) external;
}
Expand Up @@ -22,6 +22,6 @@ contract ChatNamespacedTest is MudTest {
MessageTable.encodeLengths(value),
MessageTable.encodeDynamic(value)
);
IChatNamespacedSystem(worldAddress).namespace_ChatNamespaced_sendMessage(value);
IChatNamespacedSystem(worldAddress).namespace__sendMessage(value);
}
}
4 changes: 2 additions & 2 deletions packages/world-modules/gas-report.json
Expand Up @@ -303,7 +303,7 @@
"file": "test/UniqueEntityModule.t.sol",
"test": "testInstall",
"name": "install unique entity module",
"gasUsed": 703658
"gasUsed": 701756
},
{
"file": "test/UniqueEntityModule.t.sol",
Expand All @@ -315,7 +315,7 @@
"file": "test/UniqueEntityModule.t.sol",
"test": "testInstallRoot",
"name": "installRoot unique entity module",
"gasUsed": 672525
"gasUsed": 670623
},
{
"file": "test/UniqueEntityModule.t.sol",
Expand Down
2 changes: 1 addition & 1 deletion packages/world/gas-report.json
Expand Up @@ -105,7 +105,7 @@
"file": "test/World.t.sol",
"test": "testRegisterFunctionSelector",
"name": "Register a function selector",
"gasUsed": 84542
"gasUsed": 81992
},
{
"file": "test/World.t.sol",
Expand Down
Expand Up @@ -195,14 +195,7 @@ contract WorldRegistrationSystem is System, IWorldErrors, LimitedCallContext {

// Compute global function selector
string memory namespaceString = WorldResourceIdLib.toTrimmedString(systemId.getNamespace());
string memory nameString = WorldResourceIdLib.toTrimmedString(systemId.getName());
bytes memory worldFunctionSignature = abi.encodePacked(
namespaceString,
"_",
nameString,
"_",
systemFunctionSignature
);
bytes memory worldFunctionSignature = abi.encodePacked(namespaceString, "__", systemFunctionSignature);
worldFunctionSelector = bytes4(keccak256(worldFunctionSignature));

// Require the function selector to be globally unique
Expand Down
6 changes: 3 additions & 3 deletions packages/world/test/World.t.sol
Expand Up @@ -57,7 +57,7 @@ import { DelegationControlMock } from "./DelegationControlMock.sol";
import { createCoreModule } from "./createCoreModule.sol";

interface IWorldTestSystem {
function testNamespace_testSystem_err(string memory input) external pure;
function testNamespace__err(string memory input) external pure;
}

struct WorldTestSystemReturn {
Expand Down Expand Up @@ -1580,7 +1580,7 @@ contract WorldTest is Test, GasReporter {
bytes4 functionSelector = world.registerFunctionSelector(systemId, "msgSender()");
endGasReport();

string memory expectedWorldFunctionSignature = "testNamespace_testSystem_msgSender()";
string memory expectedWorldFunctionSignature = "testNamespace__msgSender()";
bytes4 expectedWorldFunctionSelector = bytes4(keccak256(abi.encodePacked(expectedWorldFunctionSignature)));
assertEq(functionSelector, expectedWorldFunctionSelector, "wrong function selector returned");

Expand All @@ -1595,7 +1595,7 @@ contract WorldTest is Test, GasReporter {

// Expect errors to be passed through
vm.expectRevert(abi.encodeWithSelector(WorldTestSystem.WorldTestSystemError.selector, "test error"));
IWorldTestSystem(address(world)).testNamespace_testSystem_err("test error");
IWorldTestSystem(address(world)).testNamespace__err("test error");
}

function testRegisterRootFunctionSelector() public {
Expand Down
2 changes: 1 addition & 1 deletion packages/world/test/WorldBalance.t.sol
Expand Up @@ -126,7 +126,7 @@ contract WorldBalanceTest is Test, GasReporter {
// Call a function on a non-root system with value
vm.deal(caller, value);
vm.prank(caller);
(success, data) = address(world).call{ value: value }(abi.encodeWithSignature("namespace_testSystem_echoValue()"));
(success, data) = address(world).call{ value: value }(abi.encodeWithSignature("namespace__echoValue()"));
assertTrue(success);
assertEq(abi.decode(data, (uint256)), value);

Expand Down
4 changes: 1 addition & 3 deletions packages/world/ts/node/render-solidity/worldgen.ts
Expand Up @@ -42,11 +42,9 @@ export async function worldgen(
}
});
const systemInterfaceName = `I${system.basename}`;
// create an interface using the external functions and imports
const { name } = resolvedConfig.systems[system.basename];
const output = renderSystemInterface({
name: systemInterfaceName,
functionPrefix: config.namespace === "" ? "" : `${config.namespace}_${name}_`,
functionPrefix: config.namespace === "" ? "" : `${config.namespace}__`,
functions,
errors,
imports,
Expand Down

0 comments on commit 0f27afd

Please sign in to comment.