Skip to content

Commit

Permalink
revert change of namespacing KeysInTable module tables
Browse files Browse the repository at this point in the history
  • Loading branch information
alvrs committed Sep 12, 2023
1 parent 6820bf8 commit 51b7b05
Show file tree
Hide file tree
Showing 10 changed files with 203 additions and 278 deletions.
38 changes: 19 additions & 19 deletions packages/world/gas-report.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,61 +39,61 @@
"file": "test/KeysInTableModule.t.sol",
"test": "testInstallComposite",
"name": "install keys in table module",
"gasUsed": 1536430
"gasUsed": 1433865
},
{
"file": "test/KeysInTableModule.t.sol",
"test": "testInstallGas",
"name": "install keys in table module",
"gasUsed": 1536430
"gasUsed": 1433865
},
{
"file": "test/KeysInTableModule.t.sol",
"test": "testInstallGas",
"name": "set a record on a table with keysInTableModule installed",
"gasUsed": 182582
"gasUsed": 182589
},
{
"file": "test/KeysInTableModule.t.sol",
"test": "testInstallSingleton",
"name": "install keys in table module",
"gasUsed": 1536430
"gasUsed": 1433865
},
{
"file": "test/KeysInTableModule.t.sol",
"test": "testSetAndDeleteRecordHookCompositeGas",
"name": "install keys in table module",
"gasUsed": 1536430
"gasUsed": 1433865
},
{
"file": "test/KeysInTableModule.t.sol",
"test": "testSetAndDeleteRecordHookCompositeGas",
"name": "change a composite record on a table with keysInTableModule installed",
"gasUsed": 26181
"gasUsed": 26174
},
{
"file": "test/KeysInTableModule.t.sol",
"test": "testSetAndDeleteRecordHookCompositeGas",
"name": "delete a composite record on a table with keysInTableModule installed",
"gasUsed": 251130
"gasUsed": 251091
},
{
"file": "test/KeysInTableModule.t.sol",
"test": "testSetAndDeleteRecordHookGas",
"name": "install keys in table module",
"gasUsed": 1536430
"gasUsed": 1433865
},
{
"file": "test/KeysInTableModule.t.sol",
"test": "testSetAndDeleteRecordHookGas",
"name": "change a record on a table with keysInTableModule installed",
"gasUsed": 24901
"gasUsed": 24894
},
{
"file": "test/KeysInTableModule.t.sol",
"test": "testSetAndDeleteRecordHookGas",
"name": "delete a record on a table with keysInTableModule installed",
"gasUsed": 129413
"gasUsed": 129380
},
{
"file": "test/KeysWithValueModule.t.sol",
Expand Down Expand Up @@ -165,31 +165,31 @@
"file": "test/query.t.sol",
"test": "testCombinedHasHasValueNotQuery",
"name": "CombinedHasHasValueNotQuery",
"gasUsed": 165462
"gasUsed": 165699
},
{
"file": "test/query.t.sol",
"test": "testCombinedHasHasValueQuery",
"name": "CombinedHasHasValueQuery",
"gasUsed": 75917
"gasUsed": 75996
},
{
"file": "test/query.t.sol",
"test": "testCombinedHasNotQuery",
"name": "CombinedHasNotQuery",
"gasUsed": 229431
"gasUsed": 229855
},
{
"file": "test/query.t.sol",
"test": "testCombinedHasQuery",
"name": "CombinedHasQuery",
"gasUsed": 151359
"gasUsed": 151588
},
{
"file": "test/query.t.sol",
"test": "testCombinedHasValueNotQuery",
"name": "CombinedHasValueNotQuery",
"gasUsed": 143233
"gasUsed": 143470
},
{
"file": "test/query.t.sol",
Expand All @@ -201,19 +201,19 @@
"file": "test/query.t.sol",
"test": "testHasQuery",
"name": "HasQuery",
"gasUsed": 34833
"gasUsed": 34883
},
{
"file": "test/query.t.sol",
"test": "testHasQuery1000Keys",
"name": "HasQuery with 1000 keys",
"gasUsed": 9243653
"gasUsed": 9272645
},
{
"file": "test/query.t.sol",
"test": "testHasQuery100Keys",
"name": "HasQuery with 100 keys",
"gasUsed": 858486
"gasUsed": 861378
},
{
"file": "test/query.t.sol",
Expand All @@ -225,7 +225,7 @@
"file": "test/query.t.sol",
"test": "testNotValueQuery",
"name": "NotValueQuery",
"gasUsed": 69511
"gasUsed": 69590
},
{
"file": "test/StandardDelegationsModule.t.sol",
Expand Down
2 changes: 0 additions & 2 deletions packages/world/mud.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ export default mudConfig({
keys3: "bytes32[]",
keys4: "bytes32[]",
},
tableIdArgument: true,
},
UsedKeysIndex: {
directory: "modules/keysintable/tables",
Expand All @@ -142,7 +141,6 @@ export default mudConfig({
},
schema: { has: "bool", index: "uint40" },
dataStruct: false,
tableIdArgument: true,
},
UniqueEntity: {
directory: "modules/uniqueentity/tables",
Expand Down
4 changes: 2 additions & 2 deletions packages/world/src/Tables.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import { SystemHooks, SystemHooksTableId } from "./modules/core/tables/SystemHoo
import { ResourceType, ResourceTypeTableId } from "./modules/core/tables/ResourceType.sol";
import { FunctionSelectors, FunctionSelectorsTableId } from "./modules/core/tables/FunctionSelectors.sol";
import { KeysWithValue } from "./modules/keyswithvalue/tables/KeysWithValue.sol";
import { KeysInTable, KeysInTableData } from "./modules/keysintable/tables/KeysInTable.sol";
import { UsedKeysIndex } from "./modules/keysintable/tables/UsedKeysIndex.sol";
import { KeysInTable, KeysInTableData, KeysInTableTableId } from "./modules/keysintable/tables/KeysInTable.sol";
import { UsedKeysIndex, UsedKeysIndexTableId } from "./modules/keysintable/tables/UsedKeysIndex.sol";
import { UniqueEntity } from "./modules/uniqueentity/tables/UniqueEntity.sol";
import { CallboundDelegations, CallboundDelegationsTableId } from "./modules/std-delegations/tables/CallboundDelegations.sol";
import { TimeboundDelegations, TimeboundDelegationsTableId } from "./modules/std-delegations/tables/TimeboundDelegations.sol";
Expand Down
57 changes: 28 additions & 29 deletions packages/world/src/modules/keysintable/KeysInTableHook.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { Schema } from "@latticexyz/store/src/Schema.sol";

import { KeysInTable } from "./tables/KeysInTable.sol";
import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol";
import { KeysInTableTableId, UsedKeysIndexTableId } from "./constants.sol";

/**
* Note: if a table with composite keys is used, only the first key is indexed
Expand All @@ -16,28 +15,28 @@ contract KeysInTableHook is IStoreHook {
bytes32 keysHash = keccak256(abi.encode(key));

// If the key has not yet been set in the table...
if (!UsedKeysIndex.getHas(UsedKeysIndexTableId, tableId, keysHash)) {
uint40 length = uint40(KeysInTable.lengthKeys0(KeysInTableTableId, tableId));
if (!UsedKeysIndex.getHas(tableId, keysHash)) {
uint40 length = uint40(KeysInTable.lengthKeys0(tableId));

// Push the key to the list of keys in this table
if (key.length > 0) {
KeysInTable.pushKeys0(KeysInTableTableId, tableId, key[0]);
KeysInTable.pushKeys0(tableId, key[0]);
if (key.length > 1) {
KeysInTable.pushKeys1(KeysInTableTableId, tableId, key[1]);
KeysInTable.pushKeys1(tableId, key[1]);
if (key.length > 2) {
KeysInTable.pushKeys2(KeysInTableTableId, tableId, key[2]);
KeysInTable.pushKeys2(tableId, key[2]);
if (key.length > 3) {
KeysInTable.pushKeys3(KeysInTableTableId, tableId, key[3]);
KeysInTable.pushKeys3(tableId, key[3]);
if (key.length > 4) {
KeysInTable.pushKeys4(KeysInTableTableId, tableId, key[4]);
KeysInTable.pushKeys4(tableId, key[4]);
}
}
}
}
}

// Update the index to avoid duplicating this key in the array
UsedKeysIndex.set(UsedKeysIndexTableId, tableId, keysHash, true, length);
UsedKeysIndex.set(tableId, keysHash, true, length);
}
}

Expand All @@ -59,68 +58,68 @@ contract KeysInTableHook is IStoreHook {

function onBeforeDeleteRecord(bytes32 tableId, bytes32[] memory key, Schema) public {
bytes32 keysHash = keccak256(abi.encode(key));
(bool has, uint40 index) = UsedKeysIndex.get(UsedKeysIndexTableId, tableId, keysHash);
(bool has, uint40 index) = UsedKeysIndex.get(tableId, keysHash);

// If the key was part of the table...
if (has) {
// Delete the index as the key is not in the table
UsedKeysIndex.deleteRecord(UsedKeysIndexTableId, tableId, keysHash);
UsedKeysIndex.deleteRecord(tableId, keysHash);

uint40 length = uint40(KeysInTable.lengthKeys0(KeysInTableTableId, tableId));
uint40 length = uint40(KeysInTable.lengthKeys0(tableId));

if (length == 1) {
// Delete the list of keys in this table
KeysInTable.deleteRecord(KeysInTableTableId, tableId);
KeysInTable.deleteRecord(tableId);
} else {
if (key.length > 0) {
bytes32[] memory lastKeyTuple = new bytes32[](key.length);

bytes32 lastKey = KeysInTable.getItemKeys0(KeysInTableTableId, tableId, length - 1);
bytes32 lastKey = KeysInTable.getItemKeys0(tableId, length - 1);
lastKeyTuple[0] = lastKey;

// Remove the key from the list of keys in this table
KeysInTable.updateKeys0(KeysInTableTableId, tableId, index, lastKey);
KeysInTable.popKeys0(KeysInTableTableId, tableId);
KeysInTable.updateKeys0(tableId, index, lastKey);
KeysInTable.popKeys0(tableId);

if (key.length > 1) {
lastKey = KeysInTable.getItemKeys1(KeysInTableTableId, tableId, length - 1);
lastKey = KeysInTable.getItemKeys1(tableId, length - 1);
lastKeyTuple[1] = lastKey;

// Remove the key from the list of keys in this table
KeysInTable.updateKeys1(KeysInTableTableId, tableId, index, lastKey);
KeysInTable.popKeys1(KeysInTableTableId, tableId);
KeysInTable.updateKeys1(tableId, index, lastKey);
KeysInTable.popKeys1(tableId);

if (key.length > 2) {
lastKey = KeysInTable.getItemKeys2(KeysInTableTableId, tableId, length - 1);
lastKey = KeysInTable.getItemKeys2(tableId, length - 1);
lastKeyTuple[2] = lastKey;

// Swap and pop the key from the list of keys in this table
KeysInTable.updateKeys2(KeysInTableTableId, tableId, index, lastKey);
KeysInTable.popKeys2(KeysInTableTableId, tableId);
KeysInTable.updateKeys2(tableId, index, lastKey);
KeysInTable.popKeys2(tableId);

if (key.length > 3) {
lastKey = KeysInTable.getItemKeys3(KeysInTableTableId, tableId, length - 1);
lastKey = KeysInTable.getItemKeys3(tableId, length - 1);
lastKeyTuple[3] = lastKey;

// Remove the key from the list of keys in this table
KeysInTable.updateKeys3(KeysInTableTableId, tableId, index, lastKey);
KeysInTable.popKeys3(KeysInTableTableId, tableId);
KeysInTable.updateKeys3(tableId, index, lastKey);
KeysInTable.popKeys3(tableId);

if (key.length > 4) {
lastKey = KeysInTable.getItemKeys4(KeysInTableTableId, tableId, length - 1);
lastKey = KeysInTable.getItemKeys4(tableId, length - 1);
lastKeyTuple[4] = lastKey;

// Remove the key from the list of keys in this table
KeysInTable.updateKeys4(KeysInTableTableId, tableId, index, lastKey);
KeysInTable.popKeys4(KeysInTableTableId, tableId);
KeysInTable.updateKeys4(tableId, index, lastKey);
KeysInTable.popKeys4(tableId);
}
}
}
}

// Update the index of lastKey after swapping it with the deleted key
bytes32 lastKeyHash = keccak256(abi.encode(lastKeyTuple));
UsedKeysIndex.setIndex(UsedKeysIndexTableId, tableId, lastKeyHash, index);
UsedKeysIndex.setIndex(tableId, lastKeyHash, index);
}
}
}
Expand Down
45 changes: 38 additions & 7 deletions packages/world/src/modules/keysintable/KeysInTableModule.sol
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import { ResourceSelector } from "../../ResourceSelector.sol";
import { revertWithBytes } from "../../revertWithBytes.sol";

import { KeysInTableHook } from "./KeysInTableHook.sol";
import { KeysInTable } from "./tables/KeysInTable.sol";
import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol";
import { KeysInTableTableId, UsedKeysIndexTableId } from "./constants.sol";
import { KeysInTable, KeysInTableTableId } from "./tables/KeysInTable.sol";
import { UsedKeysIndex, UsedKeysIndexTableId } from "./tables/UsedKeysIndex.sol";

/**
* This module deploys a hook that is called when a value is set in the `sourceTableId`
Expand Down Expand Up @@ -51,12 +50,44 @@ contract KeysInTableModule is IModule, WorldContextConsumer {

if (ResourceType.get(KeysInTableTableId) == Resource.NONE) {
// Register the tables
KeysInTable.register(world, KeysInTableTableId);
UsedKeysIndex.register(world, UsedKeysIndexTableId);
(success, returnData) = address(world).delegatecall(
abi.encodeCall(
world.registerTable,
(
KeysInTableTableId,
KeysInTable.getKeySchema(),
KeysInTable.getValueSchema(),
KeysInTable.getKeyNames(),
KeysInTable.getFieldNames()
)
)
);
if (!success) revertWithBytes(returnData);

(success, returnData) = address(world).delegatecall(
abi.encodeCall(
world.registerTable,
(
UsedKeysIndexTableId,
UsedKeysIndex.getKeySchema(),
UsedKeysIndex.getValueSchema(),
UsedKeysIndex.getKeyNames(),
UsedKeysIndex.getFieldNames()
)
)
);
if (!success) revertWithBytes(returnData);

// Grant the hook access to the tables
world.grantAccess(KeysInTableTableId, address(hook));
world.grantAccess(UsedKeysIndexTableId, address(hook));
(success, returnData) = address(world).delegatecall(
abi.encodeCall(world.grantAccess, (KeysInTableTableId, address(hook)))
);
if (!success) revertWithBytes(returnData);

(success, returnData) = address(world).delegatecall(
abi.encodeCall(world.grantAccess, (UsedKeysIndexTableId, address(hook)))
);
if (!success) revertWithBytes(returnData);
}

// Register a hook that is called when a value is set in the source table
Expand Down
4 changes: 0 additions & 4 deletions packages/world/src/modules/keysintable/constants.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,3 @@ pragma solidity >=0.8.0;
// can be used for an identifier of the source table namespace to avoid
// collisions between tables with the same name in different namespaces
bytes8 constant MODULE_NAMESPACE = "keystab";

// TODO: once the config supports multiple namespaces, we don't have to manually construct the table id here
bytes32 constant KeysInTableTableId = bytes32(abi.encodePacked(bytes16(MODULE_NAMESPACE), bytes16("KeysInTable")));
bytes32 constant UsedKeysIndexTableId = bytes32(abi.encodePacked(bytes16(MODULE_NAMESPACE), bytes16("UsedKeysIndex")));
Loading

0 comments on commit 51b7b05

Please sign in to comment.