From 93390d8994bac0ad7c4a66ba00bc9783899b8cff Mon Sep 17 00:00:00 2001 From: yonada Date: Thu, 21 Mar 2024 12:55:46 +0000 Subject: [PATCH] refactor(store): add StoreWrite and Store abstract contracts (#2411) Co-authored-by: alvrs Co-authored-by: Kevin Ingersoll --- .changeset/silly-mirrors-marry.md | 6 + docs/pages/store/reference/store-core.mdx | 32 +-- docs/pages/store/reference/store.mdx | 31 +-- docs/pages/world/reference/world-external.mdx | 18 +- docs/pages/world/reference/world.mdx | 4 +- packages/store/src/IStore.sol | 18 +- packages/store/src/IStoreData.sol | 19 -- packages/store/src/IStoreKernel.sol | 31 +++ packages/store/src/Store.sol | 18 ++ .../src/{StoreData.sol => StoreKernel.sol} | 14 +- packages/store/test/StoreCore.t.sol | 261 ++++++++---------- packages/store/test/StoreCoreGas.t.sol | 10 +- packages/store/test/StoreMock.sol | 4 +- packages/world/src/World.sol | 6 +- scripts/render-api-docs.ts | 5 +- 15 files changed, 208 insertions(+), 269 deletions(-) create mode 100644 .changeset/silly-mirrors-marry.md delete mode 100644 packages/store/src/IStoreData.sol create mode 100644 packages/store/src/IStoreKernel.sol create mode 100644 packages/store/src/Store.sol rename packages/store/src/{StoreData.sol => StoreKernel.sol} (64%) diff --git a/.changeset/silly-mirrors-marry.md b/.changeset/silly-mirrors-marry.md new file mode 100644 index 0000000000..130fbf959c --- /dev/null +++ b/.changeset/silly-mirrors-marry.md @@ -0,0 +1,6 @@ +--- +"@latticexyz/store": minor +"@latticexyz/world": patch +--- + +Added an `abstract` `StoreKernel` contract, which includes all Store interfaces except for registration, and implements write methods, `protocolVersion` and initializes `StoreCore`. `Store` extends `StoreKernel` with the `IStoreRegistration` interface. `StoreData` is removed as a separate interface/contract. `World` now extends `StoreKernel` (since the registration methods are added via the `InitModule`). diff --git a/docs/pages/store/reference/store-core.mdx b/docs/pages/store/reference/store-core.mdx index ad3e19af03..4d2ab99e2c 100644 --- a/docs/pages/store/reference/store-core.mdx +++ b/docs/pages/store/reference/store-core.mdx @@ -1015,44 +1015,18 @@ function _loadEncodedDynamicDataLength( | -------- | ---------------- | ----------------------------------------------------------------------------------------- | | `` | `EncodedLengths` | The loaded encoded dynamic data length from storage for the given table ID and key tuple. | -## StoreData +## Store -[Git Source](https://github.com/latticexyz/mud/blob/main/packages/store/src/StoreData.sol) +[Git Source](https://github.com/latticexyz/mud/blob/main/packages/store/src/Store.sol) **Inherits:** -[IStoreData](/store/reference/store#istoredata), [StoreRead](/store/reference/store-core#storeread) +[IStore](/src/IStore.sol/interface.IStore.md), [StoreKernel](/src/StoreKernel.sol/abstract.StoreKernel.md) This contract integrates the core storage functionalities and provides an interface for data storage. _This abstract contract initializes `StoreCore`, implements `storeVersion`, and read methods, but not write methods._ -### Functions - -#### constructor - -Constructs the StoreData contract and initializes the StoreCore. - -_Emits a HelloStore event upon creation._ - -```solidity -constructor(); -``` - -#### storeVersion - -Retrieves the protocol version of the Store. - -```solidity -function storeVersion() public pure returns (bytes32); -``` - -**Returns** - -| Name | Type | Description | -| -------- | --------- | ---------------------------------- | -| `` | `bytes32` | The protocol version of the Store. | - ## StoreRead [Git Source](https://github.com/latticexyz/mud/blob/main/packages/store/src/StoreRead.sol) diff --git a/docs/pages/store/reference/store.mdx b/docs/pages/store/reference/store.mdx index adfbec8fe8..ef3f4d5d8a 100644 --- a/docs/pages/store/reference/store.mdx +++ b/docs/pages/store/reference/store.mdx @@ -5,9 +5,7 @@ [Git Source](https://github.com/latticexyz/mud/blob/main/packages/store/src/IStore.sol) **Inherits:** -[IStoreData](/store/reference/store#istoredata), [IStoreRegistration](/store/reference/store#istoreregistration), [IStoreErrors](/store/reference/store#istoreerrors), [IFieldLayoutErrors](/src/IFieldLayoutErrors.sol/interface.IFieldLayoutErrors.md), [IEncodedLengthsErrors](/src/IEncodedLengthsErrors.sol/interface.IEncodedLengthsErrors.md), [ISchemaErrors](/src/ISchemaErrors.sol/interface.ISchemaErrors.md), [ISliceErrors](/src/ISliceErrors.sol/interface.ISliceErrors.md) - -IStore implements the error interfaces for each library that it uses. +[IStoreKernel](/src/IStoreKernel.sol/interface.IStoreKernel.md), [IStoreRegistration](/store/reference/store#istoreregistration) ## IStoreEvents @@ -313,33 +311,6 @@ error Store_InvalidSplice(uint40 startWithinField, uint40 deleteCount, uint40 fi | `deleteCount` | `uint40` | The number of bytes to delete in the splice operation. | | `fieldLength` | `uint40` | The field length for the splice operation. | -## IStoreData - -[Git Source](https://github.com/latticexyz/mud/blob/main/packages/store/src/IStoreData.sol) - -**Inherits:** -[IStoreRead](/store/reference/store#istoreread), [IStoreWrite](/store/reference/store#istorewrite) - -The IStoreData interface includes methods for reading and writing table values. - -_These methods are frequently invoked during runtime, so it is essential to prioritize optimizing their gas cost._ - -### Functions - -#### storeVersion - -Returns the version of the Store contract. - -```solidity -function storeVersion() external view returns (bytes32 version); -``` - -**Returns** - -| Name | Type | Description | -| --------- | --------- | ---------------------------------- | -| `version` | `bytes32` | The version of the Store contract. | - ## IStoreRead [Git Source](https://github.com/latticexyz/mud/blob/main/packages/store/src/IStoreRead.sol) diff --git a/docs/pages/world/reference/world-external.mdx b/docs/pages/world/reference/world-external.mdx index 5e39647f00..c6fa2f96d4 100644 --- a/docs/pages/world/reference/world-external.mdx +++ b/docs/pages/world/reference/world-external.mdx @@ -12,21 +12,17 @@ that are dynamically registered in the World during deployment. _._ -### Functions - -#### storeVersion +## Store -Retrieves the protocol version of the Store. +[Git Source](https://github.com/latticexyz/mud/blob/main/packages/world/src/Store.sol) -```solidity -function storeVersion() public pure returns (bytes32); -``` +**Inherits:** +[IStore](/src/IStore.sol/interface.IStore.md), [StoreKernel](/src/StoreKernel.sol/abstract.StoreKernel.md) -**Returns** +This contract integrates the core storage functionalities and provides an interface for data storage. -| Name | Type | Description | -| -------- | --------- | ---------------------------------- | -| `` | `bytes32` | The protocol version of the Store. | +_This abstract contract initializes `StoreCore`, implements `storeVersion`, and read methods, +but not write methods._ #### registerTable diff --git a/docs/pages/world/reference/world.mdx b/docs/pages/world/reference/world.mdx index 9fd7e16b06..87f249c938 100644 --- a/docs/pages/world/reference/world.mdx +++ b/docs/pages/world/reference/world.mdx @@ -5,11 +5,13 @@ [Git Source](https://github.com/latticexyz/mud/blob/main/packages/world/src/World.sol) **Inherits:** -[StoreData](/store/reference/store-core#storedata), [IWorldKernel](/world/reference/world-external#iworldkernel) +StoreKernel, [IWorldKernel](/world/reference/world-external#iworldkernel) _This contract is the core "World" contract containing various methods for data manipulation, system calls, and dynamic function selector handling._ +_World doesn't inherit `Store` because the `IStoreRegistration` methods are added via the `InitModule`._ + ### State Variables #### creator diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index 86d820e90f..48d1a12a76 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -1,25 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.24; -import { IStoreErrors } from "./IStoreErrors.sol"; -import { IStoreData } from "./IStoreData.sol"; +import { IStoreKernel } from "./IStoreKernel.sol"; import { IStoreRegistration } from "./IStoreRegistration.sol"; -import { IFieldLayoutErrors } from "./IFieldLayoutErrors.sol"; -import { IEncodedLengthsErrors } from "./IEncodedLengthsErrors.sol"; -import { ISchemaErrors } from "./ISchemaErrors.sol"; -import { ISliceErrors } from "./ISliceErrors.sol"; /** * @title IStore * @author MUD (https://mud.dev) by Lattice (https://lattice.xyz) - * @notice IStore implements the error interfaces for each library that it uses. */ -interface IStore is - IStoreData, - IStoreRegistration, - IStoreErrors, - IFieldLayoutErrors, - IEncodedLengthsErrors, - ISchemaErrors, - ISliceErrors -{} +interface IStore is IStoreKernel, IStoreRegistration {} diff --git a/packages/store/src/IStoreData.sol b/packages/store/src/IStoreData.sol deleted file mode 100644 index 95059765df..0000000000 --- a/packages/store/src/IStoreData.sol +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.24; - -import { IStoreRead } from "./IStoreRead.sol"; -import { IStoreWrite } from "./IStoreWrite.sol"; - -/** - * @title IStoreData - * @author MUD (https://mud.dev) by Lattice (https://lattice.xyz) - * @notice The IStoreData interface includes methods for reading and writing table values. - * @dev These methods are frequently invoked during runtime, so it is essential to prioritize optimizing their gas cost. - */ -interface IStoreData is IStoreRead, IStoreWrite { - /** - * @notice Returns the version of the Store contract. - * @return version The version of the Store contract. - */ - function storeVersion() external view returns (bytes32 version); -} diff --git a/packages/store/src/IStoreKernel.sol b/packages/store/src/IStoreKernel.sol new file mode 100644 index 0000000000..c88da4714f --- /dev/null +++ b/packages/store/src/IStoreKernel.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +import { IStoreRead } from "./IStoreRead.sol"; +import { IStoreWrite } from "./IStoreWrite.sol"; +import { IStoreErrors } from "./IStoreErrors.sol"; +import { IFieldLayoutErrors } from "./IFieldLayoutErrors.sol"; +import { IEncodedLengthsErrors } from "./IEncodedLengthsErrors.sol"; +import { ISchemaErrors } from "./ISchemaErrors.sol"; +import { ISliceErrors } from "./ISliceErrors.sol"; + +/** + * @title IStoreKernel + * @author MUD (https://mud.dev) by Lattice (https://lattice.xyz) + * @notice IStoreKernel includes the error interfaces for each library that it uses. + */ +interface IStoreKernel is + IStoreRead, + IStoreWrite, + IStoreErrors, + IFieldLayoutErrors, + IEncodedLengthsErrors, + ISchemaErrors, + ISliceErrors +{ + /** + * @notice Returns the protocol version of the Store contract. + * @return version The protocol version of the Store contract. + */ + function storeVersion() external view returns (bytes32 version); +} diff --git a/packages/store/src/Store.sol b/packages/store/src/Store.sol new file mode 100644 index 0000000000..4e787c4a87 --- /dev/null +++ b/packages/store/src/Store.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.8.24; + +import { STORE_VERSION } from "./version.sol"; +import { IStore } from "./IStore.sol"; +import { StoreKernel } from "./StoreKernel.sol"; +import { StoreRead } from "./StoreRead.sol"; +import { StoreCore } from "./StoreCore.sol"; +import { IStoreEvents } from "./IStoreEvents.sol"; + +/** + * @title Store Contract + * @author MUD (https://mud.dev) by Lattice (https://lattice.xyz) + * @notice This contract integrates the core storage functionalities and provides an interface for data storage. + * @dev This abstract contract initializes `StoreCore`, implements `storeVersion`, and read methods, + * but not write methods. + */ +abstract contract Store is IStore, StoreKernel {} diff --git a/packages/store/src/StoreData.sol b/packages/store/src/StoreKernel.sol similarity index 64% rename from packages/store/src/StoreData.sol rename to packages/store/src/StoreKernel.sol index e2002563b4..e68142c639 100644 --- a/packages/store/src/StoreData.sol +++ b/packages/store/src/StoreKernel.sol @@ -2,21 +2,21 @@ pragma solidity >=0.8.24; import { STORE_VERSION } from "./version.sol"; -import { IStoreData } from "./IStoreData.sol"; +import { IStore } from "./IStore.sol"; import { StoreRead } from "./StoreRead.sol"; import { StoreCore } from "./StoreCore.sol"; import { IStoreEvents } from "./IStoreEvents.sol"; +import { IStoreKernel } from "./IStoreKernel.sol"; /** - * @title Store Data Contract + * @title StoreKernel Contract * @author MUD (https://mud.dev) by Lattice (https://lattice.xyz) - * @notice This contract integrates the core storage functionalities and provides an interface for data storage. - * @dev This abstract contract initializes `StoreCore`, implements `storeVersion`, and read methods, - * but not write methods. + * @notice This contract integrates the storage functionalities except registration and provides an interface for data storage. + * @dev This abstract contract initializes `StoreCore`, implements `storeVersion`, and read methods. */ -abstract contract StoreData is IStoreData, StoreRead { +abstract contract StoreKernel is IStoreKernel, StoreRead { /** - * @notice Constructs the StoreData contract and initializes the StoreCore. + * @notice Constructs the StoreKernel contract and initializes the StoreCore. * @dev Emits a HelloStore event upon creation. */ constructor() { diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index 4d046ef8b9..27a38b54cd 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -89,11 +89,11 @@ contract StoreCoreTest is Test, StoreMock { Tables.encodeLengths(abi.encode(keyNames), abi.encode(fieldNames)), Tables.encodeDynamic(abi.encode(keyNames), abi.encode(fieldNames)) ); - IStore(this).registerTable(tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); + this.registerTable(tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); - assertEq(IStore(this).getFieldLayout(tableId).unwrap(), fieldLayout.unwrap()); - assertEq(IStore(this).getValueSchema(tableId).unwrap(), valueSchema.unwrap()); - assertEq(IStore(this).getKeySchema(tableId).unwrap(), keySchema.unwrap()); + assertEq(this.getFieldLayout(tableId).unwrap(), fieldLayout.unwrap()); + assertEq(this.getValueSchema(tableId).unwrap(), valueSchema.unwrap()); + assertEq(this.getKeySchema(tableId).unwrap(), keySchema.unwrap()); bytes memory loadedKeyNames = Tables.getAbiEncodedKeyNames(tableId); assertEq(loadedKeyNames, abi.encode(keyNames)); @@ -113,13 +113,13 @@ contract StoreCoreTest is Test, StoreMock { string[] memory keyNames = new string[](1); string[] memory fieldNames = new string[](1); - IStore(this).registerTable(tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); + this.registerTable(tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); // Expect a revert when registering a table that already exists vm.expectRevert( abi.encodeWithSelector(IStoreErrors.Store_TableAlreadyExists.selector, tableId, string(abi.encodePacked(tableId))) ); - IStore(this).registerTable(tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); + this.registerTable(tableId, fieldLayout, keySchema, valueSchema, keyNames, fieldNames); } function testRevertRegisterInvalidFieldLayout() public { @@ -136,7 +136,7 @@ contract StoreCoreTest is Test, StoreMock { 5 ) ); - IStore(this).registerTable( + this.registerTable( tableId, FieldLayout.wrap(keccak256("random bytes as value field layout")), Schema.wrap(keccak256("random bytes as key schema")), @@ -158,7 +158,7 @@ contract StoreCoreTest is Test, StoreMock { string(abi.encodePacked(invalidTableId)) ) ); - IStore(this).registerTable( + this.registerTable( invalidTableId, FieldLayoutEncodeHelper.encode(1, 0), SchemaEncodeHelper.encode(SchemaType.UINT8), @@ -181,26 +181,26 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT8, SchemaType.UINT16 ); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, keyNames, fieldNames); assertTrue(ResourceIds._getExists(tableId)); assertFalse(ResourceIds._getExists(tableId2)); - assertEq(FieldLayout.unwrap(IStore(this).getFieldLayout(tableId)), FieldLayout.unwrap(fieldLayout)); - assertEq(Schema.unwrap(IStore(this).getValueSchema(tableId)), Schema.unwrap(valueSchema)); - assertEq(Schema.unwrap(IStore(this).getKeySchema(tableId)), Schema.unwrap(defaultKeySchema)); + assertEq(FieldLayout.unwrap(this.getFieldLayout(tableId)), FieldLayout.unwrap(fieldLayout)); + assertEq(Schema.unwrap(this.getValueSchema(tableId)), Schema.unwrap(valueSchema)); + assertEq(Schema.unwrap(this.getKeySchema(tableId)), Schema.unwrap(defaultKeySchema)); - assertTrue(IStore(this).getFieldLayout(tableId2).isEmpty()); + assertTrue(this.getFieldLayout(tableId2).isEmpty()); vm.expectRevert( abi.encodeWithSelector(IStoreErrors.Store_TableNotFound.selector, tableId2, string(abi.encodePacked(tableId2))) ); - IStore(this).getValueSchema(tableId2); + this.getValueSchema(tableId2); vm.expectRevert( abi.encodeWithSelector(IStoreErrors.Store_TableNotFound.selector, tableId2, string(abi.encodePacked(tableId2))) ); - IStore(this).getKeySchema(tableId2); + this.getKeySchema(tableId2); } function testRegisterTableRevertNames() public { @@ -219,11 +219,11 @@ contract StoreCoreTest is Test, StoreMock { // Register table with invalid key names vm.expectRevert(abi.encodeWithSelector(IStoreErrors.Store_InvalidKeyNamesLength.selector, 4, 1)); - IStore(this).registerTable(tableId, fieldLayout, keySchema, valueSchema, oneName, oneName); + this.registerTable(tableId, fieldLayout, keySchema, valueSchema, oneName, oneName); // Register table with invalid value names vm.expectRevert(abi.encodeWithSelector(IStoreErrors.Store_InvalidFieldNamesLength.selector, 1, 4)); - IStore(this).registerTable(tableId, fieldLayout, keySchema, valueSchema, fourNames, fourNames); + this.registerTable(tableId, fieldLayout, keySchema, valueSchema, fourNames, fourNames); } function testSetAndGetDynamicDataLength() public { @@ -239,7 +239,7 @@ contract StoreCoreTest is Test, StoreMock { ); // Register table - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](5)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](5)); // Create some keyTuple bytes32[] memory keyTuple = new bytes32[](1); @@ -282,7 +282,7 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT16 ); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); // Set data bytes memory staticData = abi.encodePacked(bytes1(0x01), bytes2(0x0203), bytes1(0x04), bytes2(0x0506)); @@ -294,10 +294,10 @@ contract StoreCoreTest is Test, StoreMock { vm.expectEmit(true, true, true, true); emit Store_SetRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); - IStore(this).setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); + this.setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); // Get data - (bytes memory loadedStaticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = IStore(this).getRecord( + (bytes memory loadedStaticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = this.getRecord( tableId, keyTuple, fieldLayout @@ -315,7 +315,7 @@ contract StoreCoreTest is Test, StoreMock { FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 32, 0); { Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT128, SchemaType.UINT256); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); } // Set data @@ -331,10 +331,10 @@ contract StoreCoreTest is Test, StoreMock { vm.expectEmit(true, true, true, true); emit Store_SetRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); - IStore(this).setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); + this.setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); // Get data - (bytes memory loadedStaticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = IStore(this).getRecord( + (bytes memory loadedStaticData, EncodedLengths _encodedLengths, bytes memory _dynamicData) = this.getRecord( tableId, keyTuple, fieldLayout @@ -356,7 +356,7 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT32_ARRAY, SchemaType.UINT32_ARRAY ); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); } bytes16 firstDataBytes = bytes16(0x0102030405060708090a0b0c0d0e0f10); @@ -396,10 +396,10 @@ contract StoreCoreTest is Test, StoreMock { emit Store_SetRecord(tableId, keyTuple, staticData, encodedDynamicLength, dynamicData); // Set data - IStore(this).setRecord(tableId, keyTuple, staticData, encodedDynamicLength, dynamicData); + this.setRecord(tableId, keyTuple, staticData, encodedDynamicLength, dynamicData); // Get data - (bytes memory loadedStaticData, EncodedLengths loadedEncodedLengths, bytes memory loadedDynamicData) = IStore(this) + (bytes memory loadedStaticData, EncodedLengths loadedEncodedLengths, bytes memory loadedDynamicData) = this .getRecord(tableId, keyTuple, fieldLayout); assertEq(loadedStaticData, staticData); @@ -446,7 +446,7 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT32_ARRAY, SchemaType.UINT32_ARRAY ); - IStore(this).registerTable( + this.registerTable( _data.tableId, _data.fieldLayout, defaultKeySchema, @@ -473,17 +473,17 @@ contract StoreCoreTest is Test, StoreMock { emit Store_SpliceStaticData(_data.tableId, keyTuple, 0, _data.firstDataPacked); // Set first field - IStore(this).setField(_data.tableId, keyTuple, 0, _data.firstDataPacked, _data.fieldLayout); + this.setField(_data.tableId, keyTuple, 0, _data.firstDataPacked, _data.fieldLayout); // Get first field - bytes memory loadedData = IStore(this).getField(_data.tableId, keyTuple, 0, _data.fieldLayout); + bytes memory loadedData = this.getField(_data.tableId, keyTuple, 0, _data.fieldLayout); // Verify loaded data is correct assertEq(loadedData.length, 16); assertEq(bytes16(loadedData), bytes16(_data.firstDataBytes)); // Verify the second index is not set yet - assertEq(uint256(bytes32(IStore(this).getField(_data.tableId, keyTuple, 1, _data.fieldLayout))), 0); + assertEq(uint256(bytes32(this.getField(_data.tableId, keyTuple, 1, _data.fieldLayout))), 0); // Set second field _data.secondDataBytes = keccak256("some data"); @@ -494,26 +494,23 @@ contract StoreCoreTest is Test, StoreMock { vm.expectEmit(true, true, true, true); emit Store_SpliceStaticData(_data.tableId, keyTuple, uint48(_data.firstDataPacked.length), _data.secondDataPacked); - IStore(this).setField(_data.tableId, keyTuple, 1, _data.secondDataPacked, _data.fieldLayout); + this.setField(_data.tableId, keyTuple, 1, _data.secondDataPacked, _data.fieldLayout); // Get second field - loadedData = IStore(this).getField(_data.tableId, keyTuple, 1, _data.fieldLayout); + loadedData = this.getField(_data.tableId, keyTuple, 1, _data.fieldLayout); // Verify loaded data is correct assertEq(loadedData.length, 32); assertEq(bytes32(loadedData), _data.secondDataBytes); // Verify the first field didn't change - assertEq( - bytes16(IStore(this).getField(_data.tableId, keyTuple, 0, _data.fieldLayout)), - bytes16(_data.firstDataBytes) - ); + assertEq(bytes16(this.getField(_data.tableId, keyTuple, 0, _data.fieldLayout)), bytes16(_data.firstDataBytes)); // Verify the full static data is correct - (bytes memory loadedStaticData, EncodedLengths loadedEncodedLengths, bytes memory loadedDynamicData) = IStore(this) + (bytes memory loadedStaticData, EncodedLengths loadedEncodedLengths, bytes memory loadedDynamicData) = this .getRecord(_data.tableId, keyTuple, _data.fieldLayout); - assertEq(IStore(this).getFieldLayout(_data.tableId).staticDataLength(), 48); - assertEq(IStore(this).getValueSchema(_data.tableId).staticDataLength(), 48); + assertEq(this.getFieldLayout(_data.tableId).staticDataLength(), 48); + assertEq(this.getValueSchema(_data.tableId).staticDataLength(), 48); assertEq(Bytes.getBytes16(loadedStaticData, 0), _data.firstDataBytes); assertEq(Bytes.getBytes32(loadedStaticData, 16), _data.secondDataBytes); assertEq( @@ -553,10 +550,10 @@ contract StoreCoreTest is Test, StoreMock { ); // Set third field - IStore(this).setField(_data.tableId, keyTuple, 2, _data.thirdDataBytes, _data.fieldLayout); + this.setField(_data.tableId, keyTuple, 2, _data.thirdDataBytes, _data.fieldLayout); // Get third field - loadedData = IStore(this).getField(_data.tableId, keyTuple, 2, _data.fieldLayout); + loadedData = this.getField(_data.tableId, keyTuple, 2, _data.fieldLayout); // Verify loaded data is correct assertEq(SliceLib.fromBytes(loadedData).decodeArray_uint32().length, 2); @@ -564,17 +561,11 @@ contract StoreCoreTest is Test, StoreMock { assertEq(keccak256(loadedData), keccak256(_data.thirdDataBytes)); // Verify the fourth field is not set yet - assertEq(IStore(this).getField(_data.tableId, keyTuple, 3, _data.fieldLayout).length, 0); + assertEq(this.getField(_data.tableId, keyTuple, 3, _data.fieldLayout).length, 0); // Verify none of the previous fields were impacted - assertEq( - bytes16(IStore(this).getField(_data.tableId, keyTuple, 0, _data.fieldLayout)), - bytes16(_data.firstDataBytes) - ); - assertEq( - bytes32(IStore(this).getField(_data.tableId, keyTuple, 1, _data.fieldLayout)), - bytes32(_data.secondDataBytes) - ); + assertEq(bytes16(this.getField(_data.tableId, keyTuple, 0, _data.fieldLayout)), bytes16(_data.firstDataBytes)); + assertEq(bytes32(this.getField(_data.tableId, keyTuple, 1, _data.fieldLayout)), bytes32(_data.secondDataBytes)); // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); @@ -589,10 +580,10 @@ contract StoreCoreTest is Test, StoreMock { ); // Set fourth field - IStore(this).setField(_data.tableId, keyTuple, 3, _data.fourthDataBytes, _data.fieldLayout); + this.setField(_data.tableId, keyTuple, 3, _data.fourthDataBytes, _data.fieldLayout); // Get fourth field - loadedData = IStore(this).getField(_data.tableId, keyTuple, 3, _data.fieldLayout); + loadedData = this.getField(_data.tableId, keyTuple, 3, _data.fieldLayout); // Verify loaded data is correct assertEq(loadedData.length, _data.fourthDataBytes.length); @@ -603,7 +594,7 @@ contract StoreCoreTest is Test, StoreMock { uint40(_data.thirdDataBytes.length), uint40(_data.fourthDataBytes.length) ); - (loadedStaticData, loadedEncodedLengths, loadedDynamicData) = IStore(this).getRecord( + (loadedStaticData, loadedEncodedLengths, loadedDynamicData) = this.getRecord( _data.tableId, keyTuple, _data.fieldLayout @@ -635,10 +626,10 @@ contract StoreCoreTest is Test, StoreMock { ); // Set fourth field - IStore(this).setField(_data.tableId, keyTuple, 3, _data.thirdDataBytes, _data.fieldLayout); + this.setField(_data.tableId, keyTuple, 3, _data.thirdDataBytes, _data.fieldLayout); // Get fourth field - loadedData = IStore(this).getField(_data.tableId, keyTuple, 3, _data.fieldLayout); + loadedData = this.getField(_data.tableId, keyTuple, 3, _data.fieldLayout); // Verify loaded data is correct assertEq(loadedData.length, _data.thirdDataBytes.length); @@ -656,7 +647,7 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT32_ARRAY, SchemaType.UINT32_ARRAY ); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); } bytes16 firstDataBytes = bytes16(0x0102030405060708090a0b0c0d0e0f10); @@ -698,10 +689,10 @@ contract StoreCoreTest is Test, StoreMock { keyTuple[0] = bytes32("some key"); // Set data - IStore(this).setRecord(tableId, keyTuple, staticData, encodedDynamicLength, dynamicData); + this.setRecord(tableId, keyTuple, staticData, encodedDynamicLength, dynamicData); // Get data - (bytes memory loadedStaticData, EncodedLengths loadedEncodedLengths, bytes memory loadedDynamicData) = IStore(this) + (bytes memory loadedStaticData, EncodedLengths loadedEncodedLengths, bytes memory loadedDynamicData) = this .getRecord(tableId, keyTuple, fieldLayout); assertEq(abi.encodePacked(loadedStaticData, loadedEncodedLengths, loadedDynamicData), data); @@ -711,14 +702,10 @@ contract StoreCoreTest is Test, StoreMock { emit Store_DeleteRecord(tableId, keyTuple); // Delete data - IStore(this).deleteRecord(tableId, keyTuple); + this.deleteRecord(tableId, keyTuple); // Verify data is deleted - (loadedStaticData, loadedEncodedLengths, loadedDynamicData) = IStore(this).getRecord( - tableId, - keyTuple, - fieldLayout - ); + (loadedStaticData, loadedEncodedLengths, loadedDynamicData) = this.getRecord(tableId, keyTuple, fieldLayout); assertEq(loadedStaticData, new bytes(fieldLayout.staticDataLength())); assertEq(loadedEncodedLengths.unwrap(), bytes32(0)); assertEq(loadedDynamicData, ""); @@ -760,14 +747,7 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT32_ARRAY, SchemaType.UINT32_ARRAY ); - IStore(this).registerTable( - data.tableId, - fieldLayout, - defaultKeySchema, - valueSchema, - new string[](1), - new string[](3) - ); + this.registerTable(data.tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); // Create keyTuple data.keyTuple = new bytes32[](1); @@ -791,10 +771,10 @@ contract StoreCoreTest is Test, StoreMock { } // Set fields - IStore(this).setField(data.tableId, data.keyTuple, 0, abi.encodePacked(data.firstDataBytes), fieldLayout); - IStore(this).setField(data.tableId, data.keyTuple, 1, data.secondDataBytes, fieldLayout); + this.setField(data.tableId, data.keyTuple, 0, abi.encodePacked(data.firstDataBytes), fieldLayout); + this.setField(data.tableId, data.keyTuple, 1, data.secondDataBytes, fieldLayout); // Initialize a field with push - IStore(this).pushToDynamicField(data.tableId, data.keyTuple, 1, data.thirdDataBytes); + this.pushToDynamicField(data.tableId, data.keyTuple, 1, data.thirdDataBytes); // Create data to push { @@ -817,10 +797,10 @@ contract StoreCoreTest is Test, StoreMock { ); // Push to second field - IStore(this).pushToDynamicField(data.tableId, data.keyTuple, 0, data.secondDataToPush); + this.pushToDynamicField(data.tableId, data.keyTuple, 0, data.secondDataToPush); // Get second field - data.loadedData = IStore(this).getField(data.tableId, data.keyTuple, 1, fieldLayout); + data.loadedData = this.getField(data.tableId, data.keyTuple, 1, fieldLayout); // Verify loaded data is correct assertEq(SliceLib.fromBytes(data.loadedData).decodeArray_uint32().length, 2 + 1, "1"); @@ -828,8 +808,8 @@ contract StoreCoreTest is Test, StoreMock { assertEq(data.loadedData, data.newSecondDataBytes, "3"); // Verify none of the other fields were impacted - assertEq(bytes32(IStore(this).getField(data.tableId, data.keyTuple, 0, fieldLayout)), data.firstDataBytes, "4"); - assertEq(IStore(this).getField(data.tableId, data.keyTuple, 2, fieldLayout), data.thirdDataBytes, "5"); + assertEq(bytes32(this.getField(data.tableId, data.keyTuple, 0, fieldLayout)), data.firstDataBytes, "4"); + assertEq(this.getField(data.tableId, data.keyTuple, 2, fieldLayout), data.thirdDataBytes, "5"); // Create data to push { @@ -861,10 +841,10 @@ contract StoreCoreTest is Test, StoreMock { ); // Push to third field - IStore(this).pushToDynamicField(data.tableId, data.keyTuple, 1, data.thirdDataToPush); + this.pushToDynamicField(data.tableId, data.keyTuple, 1, data.thirdDataToPush); // Get third field - data.loadedData = IStore(this).getField(data.tableId, data.keyTuple, 2, fieldLayout); + data.loadedData = this.getField(data.tableId, data.keyTuple, 2, fieldLayout); // Verify loaded data is correct assertEq(SliceLib.fromBytes(data.loadedData).decodeArray_uint32().length, 3 + 10, "6"); @@ -872,8 +852,8 @@ contract StoreCoreTest is Test, StoreMock { assertEq(data.loadedData, data.newThirdDataBytes, "8"); // Verify none of the other fields were impacted - assertEq(bytes32(IStore(this).getField(data.tableId, data.keyTuple, 0, fieldLayout)), data.firstDataBytes, "9"); - assertEq(IStore(this).getField(data.tableId, data.keyTuple, 1, fieldLayout), data.newSecondDataBytes, "10"); + assertEq(bytes32(this.getField(data.tableId, data.keyTuple, 0, fieldLayout)), data.firstDataBytes, "9"); + assertEq(this.getField(data.tableId, data.keyTuple, 1, fieldLayout), data.newSecondDataBytes, "10"); } struct TestSpliceDynamicDataData { @@ -916,14 +896,7 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT32_ARRAY, SchemaType.UINT64_ARRAY ); - IStore(this).registerTable( - data.tableId, - fieldLayout, - defaultKeySchema, - valueSchema, - new string[](1), - new string[](3) - ); + this.registerTable(data.tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); // Create keyTuple data.keyTuple = new bytes32[](1); @@ -946,9 +919,9 @@ contract StoreCoreTest is Test, StoreMock { data.thirdDataBytes = EncodeArray.encode(data.thirdData); // Set fields - IStore(this).setField(data.tableId, data.keyTuple, 0, abi.encodePacked(data.firstDataBytes), fieldLayout); - IStore(this).setField(data.tableId, data.keyTuple, 1, data.secondDataBytes, fieldLayout); - IStore(this).setField(data.tableId, data.keyTuple, 2, data.thirdDataBytes, fieldLayout); + this.setField(data.tableId, data.keyTuple, 0, abi.encodePacked(data.firstDataBytes), fieldLayout); + this.setField(data.tableId, data.keyTuple, 1, data.secondDataBytes, fieldLayout); + this.setField(data.tableId, data.keyTuple, 2, data.thirdDataBytes, fieldLayout); // Create data to use for the update { @@ -972,7 +945,7 @@ contract StoreCoreTest is Test, StoreMock { ); // Update index 1 in second field (4 = byte length of uint32) - IStore(this).spliceDynamicData( + this.spliceDynamicData( data.tableId, data.keyTuple, 0, @@ -982,7 +955,7 @@ contract StoreCoreTest is Test, StoreMock { ); // Get second field - data.loadedData = IStore(this).getField(data.tableId, data.keyTuple, 1, fieldLayout); + data.loadedData = this.getField(data.tableId, data.keyTuple, 1, fieldLayout); // Verify loaded data is correct assertEq(SliceLib.fromBytes(data.loadedData).decodeArray_uint32().length, data.secondData.length); @@ -990,8 +963,8 @@ contract StoreCoreTest is Test, StoreMock { assertEq(data.loadedData, data.newSecondDataBytes); // Verify none of the other fields were impacted - assertEq(bytes32(IStore(this).getField(data.tableId, data.keyTuple, 0, fieldLayout)), data.firstDataBytes); - assertEq(IStore(this).getField(data.tableId, data.keyTuple, 2, fieldLayout), data.thirdDataBytes); + assertEq(bytes32(this.getField(data.tableId, data.keyTuple, 0, fieldLayout)), data.firstDataBytes); + assertEq(this.getField(data.tableId, data.keyTuple, 2, fieldLayout), data.thirdDataBytes); // Create data for update { @@ -1025,7 +998,7 @@ contract StoreCoreTest is Test, StoreMock { ); // Update indexes 1,2,3,4 in third field (8 = byte length of uint64) - IStore(this).spliceDynamicData( + this.spliceDynamicData( data.tableId, data.keyTuple, 1, @@ -1035,7 +1008,7 @@ contract StoreCoreTest is Test, StoreMock { ); // Get third field - data.loadedData = IStore(this).getField(data.tableId, data.keyTuple, 2, fieldLayout); + data.loadedData = this.getField(data.tableId, data.keyTuple, 2, fieldLayout); // Verify loaded data is correct assertEq(SliceLib.fromBytes(data.loadedData).decodeArray_uint64().length, data.thirdData.length); @@ -1043,8 +1016,8 @@ contract StoreCoreTest is Test, StoreMock { assertEq(data.loadedData, data.newThirdDataBytes); // Verify none of the other fields were impacted - assertEq(bytes32(IStore(this).getField(data.tableId, data.keyTuple, 0, fieldLayout)), data.firstDataBytes); - assertEq(IStore(this).getField(data.tableId, data.keyTuple, 1, fieldLayout), data.newSecondDataBytes); + assertEq(bytes32(this.getField(data.tableId, data.keyTuple, 0, fieldLayout)), data.firstDataBytes); + assertEq(this.getField(data.tableId, data.keyTuple, 1, fieldLayout), data.newSecondDataBytes); // startByteIndex must not overflow vm.expectRevert( @@ -1054,7 +1027,7 @@ contract StoreCoreTest is Test, StoreMock { uint40(type(uint56).max) ) ); - IStore(this).spliceDynamicData( + this.spliceDynamicData( data.tableId, data.keyTuple, 1, @@ -1070,26 +1043,26 @@ contract StoreCoreTest is Test, StoreMock { FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(4, 1); Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT32, SchemaType.UINT32_ARRAY); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); // Create keyTuple bytes32[] memory keyTuple = new bytes32[](1); keyTuple[0] = bytes32("some key"); - (bytes memory data1, , ) = IStore(this).getRecord(tableId, keyTuple, fieldLayout); + (bytes memory data1, , ) = this.getRecord(tableId, keyTuple, fieldLayout); assertEq(data1.length, fieldLayout.staticDataLength()); - bytes memory data2 = IStore(this).getField(tableId, keyTuple, 0, fieldLayout); + bytes memory data2 = this.getField(tableId, keyTuple, 0, fieldLayout); assertEq(data2.length, fieldLayout.staticDataLength()); - bytes memory data3 = IStore(this).getField(tableId, keyTuple, 1, fieldLayout); + bytes memory data3 = this.getField(tableId, keyTuple, 1, fieldLayout); assertEq(data3.length, 0); - uint256 data3Length = IStore(this).getFieldLength(tableId, keyTuple, 1, fieldLayout); + uint256 data3Length = this.getFieldLength(tableId, keyTuple, 1, fieldLayout); assertEq(data3Length, 0); vm.expectRevert(abi.encodeWithSelector(IStoreErrors.Store_IndexOutOfBounds.selector, 0, 0)); - bytes memory data3Slice = IStore(this).getDynamicFieldSlice(tableId, keyTuple, 0, 0, 0); + bytes memory data3Slice = this.getDynamicFieldSlice(tableId, keyTuple, 0, 0, 0); assertEq(data3Slice.length, 0); } @@ -1102,7 +1075,7 @@ contract StoreCoreTest is Test, StoreMock { // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 0); Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT128); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](1)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](1)); // Create subscriber MirrorSubscriber subscriber = new MirrorSubscriber( @@ -1114,28 +1087,28 @@ contract StoreCoreTest is Test, StoreMock { new string[](1) ); - IStore(this).registerStoreHook(tableId, subscriber, BEFORE_ALL); + this.registerStoreHook(tableId, subscriber, BEFORE_ALL); bytes memory staticData = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); - IStore(this).setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); + this.setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); // Get data from indexed table - the indexer should have mirrored the data there - (bytes memory indexedData, , ) = IStore(this).getRecord(indexerTableId, keyTuple, fieldLayout); + (bytes memory indexedData, , ) = this.getRecord(indexerTableId, keyTuple, fieldLayout); assertEq(keccak256(staticData), keccak256(indexedData)); staticData = abi.encodePacked(bytes16(0x1112131415161718191a1b1c1d1e1f20)); - IStore(this).setField(tableId, keyTuple, 0, staticData, fieldLayout); + this.setField(tableId, keyTuple, 0, staticData, fieldLayout); // Get data from indexed table - the indexer should have mirrored the data there - (indexedData, , ) = IStore(this).getRecord(indexerTableId, keyTuple, fieldLayout); + (indexedData, , ) = this.getRecord(indexerTableId, keyTuple, fieldLayout); assertEq(keccak256(staticData), keccak256(indexedData)); - IStore(this).deleteRecord(tableId, keyTuple); + this.deleteRecord(tableId, keyTuple); // Get data from indexed table - the indexer should have mirrored the data there - (indexedData, , ) = IStore(this).getRecord(indexerTableId, keyTuple, fieldLayout); + (indexedData, , ) = this.getRecord(indexerTableId, keyTuple, fieldLayout); assertEq(keccak256(indexedData), keccak256(abi.encodePacked(bytes16(0)))); } @@ -1162,7 +1135,7 @@ contract StoreCoreTest is Test, StoreMock { vm.expectRevert( abi.encodeWithSelector(IStoreErrors.Store_TableNotFound.selector, tableId, string(abi.encodePacked(tableId))) ); - IStore(this).registerStoreHook(tableId, subscriber, BEFORE_ALL); + this.registerStoreHook(tableId, subscriber, BEFORE_ALL); } function testUnregisterHook() public { @@ -1174,16 +1147,16 @@ contract StoreCoreTest is Test, StoreMock { // Register table's value schema FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 1); Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT128, SchemaType.STRING); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); // Create a RevertSubscriber and an EchoSubscriber RevertSubscriber revertSubscriber = new RevertSubscriber(); EchoSubscriber echoSubscriber = new EchoSubscriber(); // Register both subscribers - IStore(this).registerStoreHook(tableId, revertSubscriber, ALL); + this.registerStoreHook(tableId, revertSubscriber, ALL); // Register both subscribers - IStore(this).registerStoreHook(tableId, echoSubscriber, ALL); + this.registerStoreHook(tableId, echoSubscriber, ALL); bytes memory staticData = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); bytes memory dynamicData = abi.encodePacked(bytes("some string")); @@ -1191,22 +1164,22 @@ contract StoreCoreTest is Test, StoreMock { // Expect a revert when the RevertSubscriber's onBeforeSetRecord hook is called vm.expectRevert(bytes("onBeforeSetRecord")); - IStore(this).setRecord(tableId, keyTuple, staticData, encodedLengths, dynamicData); + this.setRecord(tableId, keyTuple, staticData, encodedLengths, dynamicData); // Expect a revert when the RevertSubscriber's onBeforeSpliceStaticData hook is called vm.expectRevert(bytes("onBeforeSpliceStaticData")); - IStore(this).setField(tableId, keyTuple, 0, staticData, fieldLayout); + this.setField(tableId, keyTuple, 0, staticData, fieldLayout); // Expect a revert when the RevertSubscriber's hook onBeforeSpliceDynamicData is called vm.expectRevert(bytes("onBeforeSpliceDynamicData")); - IStore(this).setField(tableId, keyTuple, 1, dynamicData, fieldLayout); + this.setField(tableId, keyTuple, 1, dynamicData, fieldLayout); // Expect a revert when the RevertSubscriber's onBeforeDeleteRecord hook is called vm.expectRevert(bytes("onBeforeDeleteRecord")); - IStore(this).deleteRecord(tableId, keyTuple); + this.deleteRecord(tableId, keyTuple); // Unregister the RevertSubscriber - IStore(this).unregisterStoreHook(tableId, revertSubscriber); + this.unregisterStoreHook(tableId, revertSubscriber); // Expect a HookCalled event to be emitted when the EchoSubscriber's onBeforeSetRecord hook is called vm.expectEmit(true, true, true, true); @@ -1226,7 +1199,7 @@ contract StoreCoreTest is Test, StoreMock { ) ); - IStore(this).setRecord(tableId, keyTuple, staticData, encodedLengths, dynamicData); + this.setRecord(tableId, keyTuple, staticData, encodedLengths, dynamicData); // Expect a HookCalled event to be emitted when the EchoSubscriber's onBeforeSpliceStaticData hook is called vm.expectEmit(true, true, true, true); @@ -1236,7 +1209,7 @@ contract StoreCoreTest is Test, StoreMock { vm.expectEmit(true, true, true, true); emit HookCalled(abi.encodeCall(IStoreHook.onAfterSpliceStaticData, (tableId, keyTuple, 0, staticData))); - IStore(this).setField(tableId, keyTuple, 0, staticData, fieldLayout); + this.setField(tableId, keyTuple, 0, staticData, fieldLayout); // Expect a HookCalled event to be emitted when the EchoSubscriber's onBeforeSpliceDynamicData hook is called vm.expectEmit(true, true, true, true); @@ -1256,7 +1229,7 @@ contract StoreCoreTest is Test, StoreMock { ) ); - IStore(this).setField(tableId, keyTuple, 1, dynamicData, fieldLayout); + this.setField(tableId, keyTuple, 1, dynamicData, fieldLayout); // TODO: add tests for hooks being called for all other dynamic operations @@ -1268,7 +1241,7 @@ contract StoreCoreTest is Test, StoreMock { vm.expectEmit(true, true, true, true); emit HookCalled(abi.encodeCall(IStoreHook.onAfterDeleteRecord, (tableId, keyTuple, fieldLayout))); - IStore(this).deleteRecord(tableId, keyTuple); + this.deleteRecord(tableId, keyTuple); } struct RecordData { @@ -1286,7 +1259,7 @@ contract StoreCoreTest is Test, StoreMock { // Register table FieldLayout fieldLayout = FieldLayoutEncodeHelper.encode(16, 1); Schema valueSchema = SchemaEncodeHelper.encode(SchemaType.UINT128, SchemaType.UINT32_ARRAY); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](2)); // Create subscriber MirrorSubscriber subscriber = new MirrorSubscriber( @@ -1298,7 +1271,7 @@ contract StoreCoreTest is Test, StoreMock { new string[](2) ); - IStore(this).registerStoreHook(tableId, subscriber, BEFORE_ALL); + this.registerStoreHook(tableId, subscriber, BEFORE_ALL); uint32[] memory arrayData = new uint32[](1); arrayData[0] = 0x01020304; @@ -1309,11 +1282,11 @@ contract StoreCoreTest is Test, StoreMock { dynamicData: arrayDataBytes }); - IStore(this).setRecord(tableId, keyTuple, recordData.staticData, recordData.encodedLengths, recordData.dynamicData); + this.setRecord(tableId, keyTuple, recordData.staticData, recordData.encodedLengths, recordData.dynamicData); // Get data from indexed table - the indexer should have mirrored the data there RecordData memory loadedData; - (loadedData.staticData, loadedData.encodedLengths, loadedData.dynamicData) = IStore(this).getRecord( + (loadedData.staticData, loadedData.encodedLengths, loadedData.dynamicData) = this.getRecord( indexerTableId, keyTuple, fieldLayout @@ -1327,10 +1300,10 @@ contract StoreCoreTest is Test, StoreMock { arrayDataBytes = EncodeArray.encode(arrayData); recordData.dynamicData = arrayDataBytes; - IStore(this).setField(tableId, keyTuple, 1, arrayDataBytes, fieldLayout); + this.setField(tableId, keyTuple, 1, arrayDataBytes, fieldLayout); // Get data from indexed table - the indexer should have mirrored the data there - (loadedData.staticData, loadedData.encodedLengths, loadedData.dynamicData) = IStore(this).getRecord( + (loadedData.staticData, loadedData.encodedLengths, loadedData.dynamicData) = this.getRecord( indexerTableId, keyTuple, fieldLayout @@ -1339,10 +1312,10 @@ contract StoreCoreTest is Test, StoreMock { assertEq(loadedData.encodedLengths.unwrap(), recordData.encodedLengths.unwrap()); assertEq(loadedData.dynamicData, recordData.dynamicData); - IStore(this).deleteRecord(tableId, keyTuple); + this.deleteRecord(tableId, keyTuple); // Get data from indexed table - the indexer should have mirrored the data there - (loadedData.staticData, loadedData.encodedLengths, loadedData.dynamicData) = IStore(this).getRecord( + (loadedData.staticData, loadedData.encodedLengths, loadedData.dynamicData) = this.getRecord( indexerTableId, keyTuple, fieldLayout @@ -1364,7 +1337,7 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT16 ); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); // Set data bytes memory staticData = abi.encodePacked(bytes1(0x01), bytes2(0x0203), bytes1(0x04), bytes2(0x0506)); @@ -1376,7 +1349,7 @@ contract StoreCoreTest is Test, StoreMock { vm.expectEmit(true, true, true, true); emit Store_SetRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); - IStore(this).setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); + this.setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); } function testDeleteDataOffchainTable() public { @@ -1390,7 +1363,7 @@ contract StoreCoreTest is Test, StoreMock { SchemaType.UINT32_ARRAY, SchemaType.UINT32_ARRAY ); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); } bytes16 firstDataBytes = bytes16(0x0102030405060708090a0b0c0d0e0f10); @@ -1426,13 +1399,13 @@ contract StoreCoreTest is Test, StoreMock { keyTuple[0] = bytes32("some key"); // Set data - IStore(this).setRecord(tableId, keyTuple, staticData, encodedDynamicLength, dynamicData); + this.setRecord(tableId, keyTuple, staticData, encodedDynamicLength, dynamicData); // Expect a Store_DeleteRecord event to be emitted vm.expectEmit(true, true, true, true); emit Store_DeleteRecord(tableId, keyTuple); // Delete data - IStore(this).deleteRecord(tableId, keyTuple); + this.deleteRecord(tableId, keyTuple); } } diff --git a/packages/store/test/StoreCoreGas.t.sol b/packages/store/test/StoreCoreGas.t.sol index b3e4684714..506d6549a1 100644 --- a/packages/store/test/StoreCoreGas.t.sol +++ b/packages/store/test/StoreCoreGas.t.sol @@ -738,7 +738,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { SchemaType.UINT16 ); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](4)); // Set data bytes memory staticData = abi.encodePacked(bytes1(0x01), bytes2(0x0203), bytes1(0x04), bytes2(0x0506)); @@ -751,7 +751,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { emit Store_SetRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); startGasReport("StoreCore: set record in offchain table"); - IStore(this).setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); + this.setRecord(tableId, keyTuple, staticData, EncodedLengths.wrap(bytes32(0)), new bytes(0)); endGasReport(); } @@ -766,7 +766,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { SchemaType.UINT32_ARRAY, SchemaType.UINT32_ARRAY ); - IStore(this).registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); + this.registerTable(tableId, fieldLayout, defaultKeySchema, valueSchema, new string[](1), new string[](3)); } bytes16 firstDataBytes = bytes16(0x0102030405060708090a0b0c0d0e0f10); @@ -802,7 +802,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { keyTuple[0] = bytes32("some key"); // Set data - IStore(this).setRecord(tableId, keyTuple, staticData, encodedDynamicLength, dynamicData); + this.setRecord(tableId, keyTuple, staticData, encodedDynamicLength, dynamicData); // Expect a Store_DeleteRecord event to be emitted vm.expectEmit(true, true, true, true); @@ -810,7 +810,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { // Delete data startGasReport("StoreCore: delete record in offchain table"); - IStore(this).deleteRecord(tableId, keyTuple); + this.deleteRecord(tableId, keyTuple); endGasReport(); } } diff --git a/packages/store/test/StoreMock.sol b/packages/store/test/StoreMock.sol index 0a3ec7c60a..17fe8ee6ba 100644 --- a/packages/store/test/StoreMock.sol +++ b/packages/store/test/StoreMock.sol @@ -4,7 +4,7 @@ pragma solidity >=0.8.24; import { IStore } from "../src/IStore.sol"; import { IStoreHook } from "../src/IStoreHook.sol"; import { StoreSwitch } from "../src/StoreSwitch.sol"; -import { StoreData } from "../src/StoreData.sol"; +import { Store } from "../src/Store.sol"; import { EncodedLengths } from "../src/EncodedLengths.sol"; import { StoreCore } from "../src/StoreCore.sol"; import { Schema } from "../src/Schema.sol"; @@ -15,7 +15,7 @@ import { ResourceId } from "../src/ResourceId.sol"; /** * StoreMock is a contract wrapper around the StoreCore library for testing purposes. */ -contract StoreMock is IStore, StoreData { +contract StoreMock is Store { constructor() { StoreCore.initialize(); StoreCore.registerInternalTables(); diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index fad51c61dc..b3e73d1a9b 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.24; -import { StoreData } from "@latticexyz/store/src/StoreData.sol"; import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; import { Bytes } from "@latticexyz/store/src/Bytes.sol"; import { EncodedLengths } from "@latticexyz/store/src/EncodedLengths.sol"; import { FieldLayout } from "@latticexyz/store/src/FieldLayout.sol"; +import { StoreKernel } from "@latticexyz/store/src/StoreKernel.sol"; import { WORLD_VERSION } from "./version.sol"; import { ResourceId, WorldResourceIdInstance } from "./WorldResourceId.sol"; @@ -33,8 +33,10 @@ import { Balances } from "./codegen/tables/Balances.sol"; * @author MUD (https://mud.dev) by Lattice (https://lattice.xyz) * @dev This contract is the core "World" contract containing various methods for * data manipulation, system calls, and dynamic function selector handling. + * + * @dev World doesn't inherit `Store` because the `IStoreRegistration` methods are added via the `InitModule`. */ -contract World is StoreData, IWorldKernel { +contract World is StoreKernel, IWorldKernel { using WorldResourceIdInstance for ResourceId; /// @notice Address of the contract's creator. diff --git a/scripts/render-api-docs.ts b/scripts/render-api-docs.ts index aa1e9220cd..8ae48ff7f3 100644 --- a/scripts/render-api-docs.ts +++ b/scripts/render-api-docs.ts @@ -15,7 +15,7 @@ const PUBLIC_APIS: PublicApis = { "store/reference/store-core.mdx": { inputFiles: [ { source: "store/src/StoreCore.sol" }, - { source: "store/src/StoreData.sol" }, + { source: "store/src/Store.sol" }, { source: "store/src/StoreRead.sol" }, { source: "store/src/StoreSwitch.sol" }, ], @@ -37,7 +37,6 @@ const PUBLIC_APIS: PublicApis = { { source: "store/src/IStore.sol" }, { source: "store/src/IStoreEvents.sol" }, { source: "store/src/IStoreErrors.sol" }, - { source: "store/src/IStoreData.sol" }, { source: "store/src/IStoreRead.sol" }, { source: "store/src/IStoreWrite.sol" }, { source: "store/src/IStoreRegistration.sol" }, @@ -248,7 +247,7 @@ const PUBLIC_APIS: PublicApis = { // After IBaseWorld we have all the things it inherits from. // We delete their headings, and leave the functions, errors, etc. { source: "world/src/codegen/interfaces/IBaseWorld.sol" }, - { source: "store/src/StoreData.sol" }, + { source: "store/src/Store.sol" }, { source: "store/src/IStoreRegistration.sol" }, { source: "world/src/modules/init/implementations/AccessManagementSystem.sol" }, { source: "world/src/modules/init/implementations/BalanceTransferSystem.sol" },