Skip to content

Commit

Permalink
feat: add StoreMetadata table for table name and field names to Store…
Browse files Browse the repository at this point in the history
… and World (#428)

* feat(store): add metadata table for table and column names

* feat(world): add setMetadata method

* chore(store): remove unused Route table
  • Loading branch information
alvrs authored Feb 28, 2023
1 parent cb731e0 commit ae39ace
Show file tree
Hide file tree
Showing 13 changed files with 396 additions and 203 deletions.
16 changes: 8 additions & 8 deletions packages/store/gas-report.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
(test/PackedCounter.t.sol) | set value at index of PackedCounter [packedCounter = packedCounter.setAtIndex(2, 5)]: 830
(test/PackedCounter.t.sol) | pack uint16 array into PackedCounter [PackedCounter packedCounter = PackedCounterLib.pack(counters)]: 2148
(test/PackedCounter.t.sol) | get total of PackedCounter [packedCounter.total()]: 33
(test/Route.t.sol) | register Route schema [Route.registerSchema()]: 33867
(test/Route.t.sol) | set Route record [Route.set(key, addr, selector, executionMode)]: 37691
(test/Route.t.sol) | get Route record [RouteData memory systemEntry = Route.get(key)]: 6077
(test/Schema.t.sol) | encode schema with 6 entries [SchemaLib.encode]: 6044
(test/Schema.t.sol) | get schema type at index [SchemaType schemaType1 = schema.atIndex(0)]: 200
(test/Schema.t.sol) | get number of dynamic fields from schema [uint256 num = schema.numDynamicFields()]: 80
Expand Down Expand Up @@ -55,12 +52,12 @@
(test/StoreCore.t.sol) | check for existence of table (non-existent) [StoreCore.hasTable(table2)]: 2963
(test/StoreCore.t.sol) | register subscriber [StoreCore.registerStoreHook(table, subscriber)]: 69041
(test/StoreCore.t.sol) | set record on table with subscriber [StoreCore.setRecord(table, key, data)]: 72422
(test/StoreCore.t.sol) | set static field on table with subscriber [StoreCore.setField(table, key, 0, data)]: 28099
(test/StoreCore.t.sol) | delete record on table with subscriber [StoreCore.deleteRecord(table, key)]: 22869
(test/StoreCore.t.sol) | set static field on table with subscriber [StoreCore.setField(table, key, 0, data)]: 28121
(test/StoreCore.t.sol) | delete record on table with subscriber [StoreCore.deleteRecord(table, key)]: 22891
(test/StoreCore.t.sol) | register subscriber [StoreCore.registerStoreHook(table, subscriber)]: 69041
(test/StoreCore.t.sol) | set (dynamic) record on table with subscriber [StoreCore.setRecord(table, key, data)]: 165867
(test/StoreCore.t.sol) | set (dynamic) field on table with subscriber [StoreCore.setField(table, key, 1, arrayDataBytes)]: 30942
(test/StoreCore.t.sol) | delete (dynamic) record on table with subscriber [StoreCore.deleteRecord(table, key)]: 24517
(test/StoreCore.t.sol) | set (dynamic) field on table with subscriber [StoreCore.setField(table, key, 1, arrayDataBytes)]: 30964
(test/StoreCore.t.sol) | delete (dynamic) record on table with subscriber [StoreCore.deleteRecord(table, key)]: 24539
(test/StoreCore.t.sol) | StoreCore: register schema [StoreCore.registerSchema(table, schema)]: 30019
(test/StoreCore.t.sol) | StoreCore: get schema (warm) [Schema loadedSchema = StoreCore.getSchema(table)]: 909
(test/StoreCore.t.sol) | set complex record with dynamic data (4 slots) [StoreCore.setRecord(table, key, data)]: 106949
Expand All @@ -82,7 +79,10 @@
(test/StoreCore.t.sol) | get static record (1 slot) [bytes memory loadedData = StoreCore.getRecord(table, key, schema)]: 1324
(test/StoreCore.t.sol) | set static record (2 slots) [StoreCore.setRecord(table, key, data)]: 59182
(test/StoreCore.t.sol) | get static record (2 slots) [bytes memory loadedData = StoreCore.getRecord(table, key, schema)]: 1574
(test/StoreSwitch.t.sol) | check if delegatecall [isDelegate = StoreSwitch.isDelegateCall()]: 671
(test/StoreCore.t.sol) | StoreCore: set table metadata [StoreCore.setMetadata(table, tableName, fieldNames)]: 250504
(test/StoreMetadata.t.sol) | set record in StoreMetadataTable [StoreMetadata.set({ tableId: tableId, tableName: tableName, abiEncodedFieldNames: abi.encode(fieldNames) })]: 249219
(test/StoreMetadata.t.sol) | get record from StoreMetadataTable [StoreMetadataData memory metadata = StoreMetadata.get(tableId)]: 12045
(test/StoreSwitch.t.sol) | check if delegatecall [isDelegate = StoreSwitch.isDelegateCall()]: 693
(test/StoreSwitch.t.sol) | check if delegatecall [isDelegate = StoreSwitch.isDelegateCall()]: 627
(test/Vector2.t.sol) | register Vector2 schema [Vector2.registerSchema()]: 31876
(test/Vector2.t.sol) | set Vector2 record [Vector2.set({ key: key, x: 1, y: 2 })]: 37637
Expand Down
17 changes: 10 additions & 7 deletions packages/store/mud.config.mts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,16 @@ const config: StoreUserConfig = {
tables: {
Hooks: SchemaType.ADDRESS_ARRAY,
Callbacks: SchemaType.BYTES24_ARRAY,
StoreMetadata: {
primaryKeys: {
tableId: SchemaType.UINT256,
},
schema: {
tableName: SchemaType.STRING,
abiEncodedFieldNames: SchemaType.BYTES,
},
storeArgument: true,
},
Mixed: {
schema: {
u32: SchemaType.UINT32,
Expand All @@ -16,13 +26,6 @@ const config: StoreUserConfig = {
s: SchemaType.STRING,
},
},
Route: {
schema: {
addr: SchemaType.ADDRESS,
selector: SchemaType.BYTES4,
executionMode: SchemaType.UINT8,
},
},
Vector2: {
schema: {
x: SchemaType.UINT32,
Expand Down
6 changes: 6 additions & 0 deletions packages/store/src/IStore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ interface IStore {

function getSchema(uint256 table) external view returns (Schema schema);

function setMetadata(
uint256 table,
string calldata tableName,
string[] calldata fieldNames
) external;

// Set full record (including full dynamic data)
function setRecord(
uint256 table,
Expand Down
7 changes: 7 additions & 0 deletions packages/store/src/Schema.sol
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,13 @@ library SchemaLib {
return uint8(Bytes.slice1(Schema.unwrap(schema), 2));
}

/**
* Get the total number of fields for the given schema
*/
function numFields(Schema schema) internal pure returns (uint8) {
return numStaticFields(schema) + numDynamicFields(schema);
}

/**
* Check if the given schema is empty
*/
Expand Down
28 changes: 27 additions & 1 deletion packages/store/src/StoreCore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { Schema, SchemaLib } from "./Schema.sol";
import { PackedCounter } from "./PackedCounter.sol";
import { Slice } from "./Slice.sol";
import { Hooks, HooksTableId } from "./tables/Hooks.sol";
import { StoreMetadata } from "./tables/StoreMetadata.sol";
import { IStoreHook } from "./IStore.sol";

library StoreCore {
Expand All @@ -22,6 +23,7 @@ library StoreCore {
error StoreCore_NotImplemented();
error StoreCore_InvalidDataLength(uint256 expected, uint256 received);
error StoreCore_NoDynamicField();
error StoreCore_InvalidFieldNamesLength(uint256 expected, uint256 received);

/**
* Initialize internal tables.
Expand All @@ -30,8 +32,12 @@ library StoreCore {
* (see https://github.com/latticexyz/mud/issues/444)
*/
function initialize() internal {
// Register internal schema table
registerSchema(StoreCoreInternal.SCHEMA_TABLE, SchemaLib.encode(SchemaType.BYTES32));
registerSchema(HooksTableId, Hooks.getSchema());

// Register other internal tables
Hooks.registerSchema();
StoreMetadata.registerSchema();
}

/************************************************************************
Expand Down Expand Up @@ -70,6 +76,26 @@ library StoreCore {
return StoreCoreInternal._getSchema(table);
}

/**
* Set metadata for a given table
*/
function setMetadata(
uint256 table,
string memory tableName,
string[] memory fieldNames
) internal {
// Get schema of the given table
Schema schema = getSchema(table);

// Verify the number of field names corresponds to the schema length
if (!(fieldNames.length == 0 || fieldNames.length == schema.numFields())) {
revert StoreCore_InvalidFieldNamesLength(schema.numFields(), fieldNames.length);
}

// Set metadata
StoreMetadata.set(table, tableName, abi.encode(fieldNames));
}

/************************************************************************
*
* REGISTER HOOKS
Expand Down
11 changes: 11 additions & 0 deletions packages/store/src/StoreView.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ contract StoreView is Store {
revert StoreView_NotImplemented();
}

/**
* Not implemented in StoreView
*/
function setMetadata(
uint256,
string calldata,
string[] calldata
) public virtual {
revert StoreView_NotImplemented();
}

/**
* Not implemented in StoreView
*/
Expand Down
146 changes: 0 additions & 146 deletions packages/store/src/tables/Route.sol

This file was deleted.

Loading

0 comments on commit ae39ace

Please sign in to comment.