Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(store): rename events for readability and consistency with errors #1577

Merged
merged 6 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .changeset/stale-schools-wait.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
"@latticexyz/block-logs-stream": patch
"@latticexyz/dev-tools": patch
"@latticexyz/store-sync": patch
"@latticexyz/store": major
---

`Store` events have been renamed for consistency and readability.
If you're parsing `Store` events manually, you need to update your ABI.
If you're using the MUD sync stack, the new events are already integrated and no further changes are necessary.

```diff
- event StoreSetRecord(
+ event Store_SetRecord(
ResourceId indexed tableId,
bytes32[] keyTuple,
bytes staticData,
bytes32 encodedLengths,
bytes dynamicData
);
- event StoreSpliceStaticData(
+ event Store_SpliceStaticData(
ResourceId indexed tableId,
bytes32[] keyTuple,
uint48 start,
uint40 deleteCount,
bytes data
);
- event StoreSpliceDynamicData(
+ event Store_SpliceDynamicData(
ResourceId indexed tableId,
bytes32[] keyTuple,
uint48 start,
uint40 deleteCount,
bytes data,
bytes32 encodedLengths
);
- event StoreDeleteRecord(
+ event Store_DeleteRecord(
ResourceId indexed tableId,
bytes32[] keyTuple
);
```
9 changes: 5 additions & 4 deletions docs/pages/store/spec.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ import { Aside } from "../../components/Aside";
When a record or a single field is edited, or when a record is deleted, Store emits a standard event with enough information for off-chain actors to reconstruct the new version of the Store with event-sourcing.

```solidity
event StoreSetRecord(uint256 tableId, bytes32[] keyTuple, bytes data);
event StoreSetField(uint256 tableId, bytes32[] keyTuple, uint8 schemaIndex, bytes data);
event StoreDeleteRecord(uint256 tableId, bytes32[] keyTuple);
event Store_SetRecord(bytes32 indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData),
event Store_SpliceStaticData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data),
event Store_SpliceDynamicData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths),
event Store_DeleteRecord(bytes32 indexed tableId, bytes32[] keyTuple),
```

Each event includes the table ID and each key encoded as `bytes32`.
Expand All @@ -22,7 +23,7 @@ MUD comes with many libraries and services in order to reconstruct the state of
### Data encoding

`bytes data` uses custom encoding, which MUD networking stack decodes.
Each event carries only data. To get a table's schema (information on how to decode it), use `IStore.getSchema(tableId)` or listen to `StoreSetRecord` updates of the schema table.
Each event carries only data. To get a table's schema (information on how to decode it), use `IStore.getSchema(tableId)` or listen to `Store_SetRecord` updates of the schema table.

Schema is a way to dynamically store solidity types.
Use the [schema-type package](https://github.com/latticexyz/mud/tree/main/packages/schema-type) to work with it directly.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ contract ChatNamespacedTest is MudTest {
bytes32[] memory keyTuple;
string memory value = "test";
vm.expectEmit(true, true, true, true);
emit StoreCore.StoreSetRecord(
emit StoreCore.Store_SetRecord(
MessageTableTableId,
keyTuple,
new bytes(0),
Expand Down
7 changes: 4 additions & 3 deletions packages/block-logs-stream/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ latestBlockNumber$
publicClient,
address,
events: parseAbi([
"event StoreDeleteRecord(bytes32 tableId, bytes32[] keyTuple)",
"event StoreSetField(bytes32 tableId, bytes32[] keyTuple, uint8 schemaIndex, bytes data)",
"event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes data)",
"event Store_SetRecord(bytes32 indexed tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData)",
"event Store_SpliceStaticData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data)",
"event Store_SpliceDynamicData(bytes32 indexed tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths)",
"event Store_DeleteRecord(bytes32 indexed tableId, bytes32[] keyTuple)",
]),
}),
mergeMap(({ logs }) => from(groupLogsByBlockNumber(logs)))
Expand Down
8 changes: 5 additions & 3 deletions packages/dev-tools/src/actions/WriteSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,11 @@ export function WriteSummary({ write }: Props) {
{table.namespace}:{table.name}
</td>
<td className="whitespace-nowrap">
{eventName === "StoreSetRecord" ? <span className="text-green-500 font-bold">=</span> : null}
{eventName === "StoreSetField" ? <span className="text-green-500 font-bold">+</span> : null}
{eventName === "StoreDeleteRecord" ? <span className="text-red-500 font-bold">-</span> : null}
{eventName === "Store_SetRecord" ? <span className="text-green-500 font-bold">=</span> : null}
{eventName === "Store_SpliceStaticData" || eventName === "Store_SpliceDynamicData" ? (
<span className="text-green-500 font-bold">+</span>
) : null}
{eventName === "Store_DeleteRecord" ? <span className="text-red-500 font-bold">-</span> : null}
</td>
<td className="whitespace-nowrap overflow-hidden text-ellipsis">
{hexKeyTupleToEntity((args as any).keyTuple)}
Expand Down
8 changes: 4 additions & 4 deletions packages/dev-tools/src/events/EventIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ type Props = {

export function EventIcon({ type }: Props) {
switch (type) {
case "StoreSetRecord":
case "Store_SetRecord":
return <span className="text-green-500 font-bold">=</span>;
case "StoreSpliceStaticData":
case "StoreSpliceDynamicData":
case "Store_SpliceStaticData":
case "Store_SpliceDynamicData":
return <span className="text-cyan-500 font-bold">+</span>;
case "StoreDeleteRecord":
case "Store_DeleteRecord":
return <span className="text-red-500 font-bold">-</span>;
default:
return assertExhaustive(type, `Unexpected event type: ${type}`);
Expand Down
6 changes: 3 additions & 3 deletions packages/dev-tools/src/events/LogsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,17 +44,17 @@ export function LogsTable({ logs }: Props) {
</td>
<td className="px-1 whitespace-nowrap overflow-hidden text-ellipsis">
{/* TODO: decode these values if we can */}
{log.eventName === "StoreSetRecord"
{log.eventName === "Store_SetRecord"
? JSON.stringify({
staticData: log.args.staticData,
encodedLengths: log.args.encodedLengths,
dynamicData: log.args.dynamicData,
})
: null}
{log.eventName === "StoreSpliceStaticData"
{log.eventName === "Store_SpliceStaticData"
? JSON.stringify({ start: log.args.start, deleteCount: log.args.deleteCount, data: log.args.data })
: null}
{log.eventName === "StoreSpliceDynamicData"
{log.eventName === "Store_SpliceDynamicData"
? JSON.stringify({
start: log.args.start,
deleteCount: log.args.deleteCount,
Expand Down
2 changes: 1 addition & 1 deletion packages/store-sync/src/createStoreSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export async function createStoreSync<TConfig extends StoreConfig = StoreConfig>
const logs: StorageAdapterLog[] = tables.flatMap((table) =>
table.records.map(
(record): StorageAdapterLog => ({
eventName: "StoreSetRecord",
eventName: "Store_SetRecord",
address: table.address,
args: {
tableId: table.tableId,
Expand Down
4 changes: 2 additions & 2 deletions packages/store-sync/src/isTableRegistrationLog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ import { StorageAdapterLog, schemasTableId } from "./common";

export function isTableRegistrationLog(
log: StorageAdapterLog
): log is StorageAdapterLog & { eventName: "StoreSetRecord" } {
return log.eventName === "StoreSetRecord" && log.args.tableId === schemasTableId;
): log is StorageAdapterLog & { eventName: "Store_SetRecord" } {
return log.eventName === "Store_SetRecord" && log.args.tableId === schemasTableId;
}
2 changes: 1 addition & 1 deletion packages/store-sync/src/logToTable.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ describe("logToTable", () => {
expect(
logToTable({
address: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c",
eventName: "StoreSetRecord",
eventName: "Store_SetRecord",
args: {
tableId: "0x74626d756473746f72650000000000005461626c657300000000000000000000",
keyTuple: ["0x74626d756473746f72650000000000005461626c657300000000000000000000"],
Expand Down
2 changes: 1 addition & 1 deletion packages/store-sync/src/logToTable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { hexToResourceId } from "@latticexyz/common";

// TODO: add tableToLog

export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord" }): Table {
export function logToTable(log: StorageAdapterLog & { eventName: "Store_SetRecord" }): Table {
const [tableId, ...otherKeys] = log.args.keyTuple;
if (otherKeys.length) {
console.warn("registerSchema event is expected to have only one key in key tuple, but got multiple", log);
Expand Down
8 changes: 4 additions & 4 deletions packages/store-sync/src/postgres/postgresStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ describe("postgresStorage", async () => {
{
"chainId": 31337,
"lastError": null,
"lastUpdatedBlockNumber": 5n,
"lastUpdatedBlockNumber": 6n,
"schemaVersion": 1,
},
]
Expand All @@ -74,7 +74,7 @@ describe("postgresStorage", async () => {
"key": "0x5FbDB2315678afecb367f032d93F642f64180aa3::NumberList",
"keySchema": {},
"lastError": null,
"lastUpdatedBlockNumber": 5n,
"lastUpdatedBlockNumber": 6n,
"name": "NumberList",
"namespace": "",
"schemaVersion": 1,
Expand All @@ -94,7 +94,7 @@ describe("postgresStorage", async () => {
"key": "0x5FbDB2315678afecb367f032d93F642f64180aa3::NumberList",
"keySchema": {},
"lastError": null,
"lastUpdatedBlockNumber": 5n,
"lastUpdatedBlockNumber": 6n,
"name": "NumberList",
"namespace": "",
"schemaVersion": 1,
Expand All @@ -114,7 +114,7 @@ describe("postgresStorage", async () => {
"__encodedLengths": "0x0000000000000000000000000000000000000000000000000800000000000008",
"__isDeleted": false,
"__key": "0x",
"__lastUpdatedBlockNumber": 5n,
"__lastUpdatedBlockNumber": 6n,
"__staticData": null,
"value": [
420,
Expand Down
8 changes: 4 additions & 4 deletions packages/store-sync/src/postgres/postgresStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export async function postgresStorage<TConfig extends StoreConfig = StoreConfig>

debug(log.eventName, log);

if (log.eventName === "StoreSetRecord") {
if (log.eventName === "Store_SetRecord") {
const value = decodeValueArgs(table.valueSchema, log.args);
debug("upserting record", {
namespace: table.namespace,
Expand Down Expand Up @@ -128,7 +128,7 @@ export async function postgresStorage<TConfig extends StoreConfig = StoreConfig>
},
})
.execute();
} else if (log.eventName === "StoreSpliceStaticData") {
} else if (log.eventName === "Store_SpliceStaticData") {
// TODO: verify that this returns what we expect (doesn't error/undefined on no record)
const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0];
const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x";
Expand Down Expand Up @@ -167,7 +167,7 @@ export async function postgresStorage<TConfig extends StoreConfig = StoreConfig>
},
})
.execute();
} else if (log.eventName === "StoreSpliceDynamicData") {
} else if (log.eventName === "Store_SpliceDynamicData") {
// TODO: verify that this returns what we expect (doesn't error/undefined on no record)
const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0];
const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x";
Expand Down Expand Up @@ -211,7 +211,7 @@ export async function postgresStorage<TConfig extends StoreConfig = StoreConfig>
},
})
.execute();
} else if (log.eventName === "StoreDeleteRecord") {
} else if (log.eventName === "Store_DeleteRecord") {
// TODO: should we upsert so we at least have a DB record of when a thing was created/deleted within the same block?
debug("deleting record", {
namespace: table.namespace,
Expand Down
8 changes: 4 additions & 4 deletions packages/store-sync/src/recs/recsStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ export function recsStorage<TConfig extends StoreConfig = StoreConfig>({

const entity = hexKeyTupleToEntity(log.args.keyTuple);

if (log.eventName === "StoreSetRecord") {
if (log.eventName === "Store_SetRecord") {
const value = decodeValueArgs(table.valueSchema, log.args);
debug("setting component", {
namespace: table.namespace,
Expand All @@ -94,7 +94,7 @@ export function recsStorage<TConfig extends StoreConfig = StoreConfig>({
__encodedLengths: log.args.encodedLengths,
__dynamicData: log.args.dynamicData,
});
} else if (log.eventName === "StoreSpliceStaticData") {
} else if (log.eventName === "Store_SpliceStaticData") {
// TODO: add tests that this works when no record had been set before
const previousValue = getComponentValue(component, entity);
const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x";
Expand All @@ -117,7 +117,7 @@ export function recsStorage<TConfig extends StoreConfig = StoreConfig>({
...newValue,
__staticData: newStaticData,
});
} else if (log.eventName === "StoreSpliceDynamicData") {
} else if (log.eventName === "Store_SpliceDynamicData") {
// TODO: add tests that this works when no record had been set before
const previousValue = getComponentValue(component, entity);
const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x";
Expand All @@ -142,7 +142,7 @@ export function recsStorage<TConfig extends StoreConfig = StoreConfig>({
__encodedLengths: log.args.encodedLengths,
__dynamicData: newDynamicData,
});
} else if (log.eventName === "StoreDeleteRecord") {
} else if (log.eventName === "Store_DeleteRecord") {
debug("deleting component", {
namespace: table.namespace,
name: table.name,
Expand Down
8 changes: 4 additions & 4 deletions packages/store-sync/src/sqlite/sqliteStorage.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ describe("sqliteStorage", async () => {
{
"chainId": 31337,
"lastError": null,
"lastUpdatedBlockNumber": 5n,
"lastUpdatedBlockNumber": 6n,
"schemaVersion": 1,
},
]
Expand All @@ -77,7 +77,7 @@ describe("sqliteStorage", async () => {
"id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____NumberList",
"keySchema": {},
"lastError": null,
"lastUpdatedBlockNumber": 5n,
"lastUpdatedBlockNumber": 6n,
"name": "NumberList",
"namespace": "",
"schemaVersion": 1,
Expand All @@ -97,7 +97,7 @@ describe("sqliteStorage", async () => {
"id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____NumberList",
"keySchema": {},
"lastError": null,
"lastUpdatedBlockNumber": 5n,
"lastUpdatedBlockNumber": 6n,
"name": "NumberList",
"namespace": "",
"schemaVersion": 1,
Expand All @@ -117,7 +117,7 @@ describe("sqliteStorage", async () => {
"__encodedLengths": "0x0000000000000000000000000000000000000000000000000800000000000008",
"__isDeleted": false,
"__key": "0x",
"__lastUpdatedBlockNumber": 5n,
"__lastUpdatedBlockNumber": 6n,
"__staticData": null,
"value": [
420,
Expand Down
8 changes: 4 additions & 4 deletions packages/store-sync/src/sqlite/sqliteStorage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export async function sqliteStorage<TConfig extends StoreConfig = StoreConfig>({
const uniqueKey = concatHex(log.args.keyTuple as Hex[]);
const key = decodeKey(table.keySchema, log.args.keyTuple);

if (log.eventName === "StoreSetRecord") {
if (log.eventName === "Store_SetRecord") {
const value = decodeValueArgs(table.valueSchema, log.args);
debug("upserting record", {
namespace: table.namespace,
Expand Down Expand Up @@ -127,7 +127,7 @@ export async function sqliteStorage<TConfig extends StoreConfig = StoreConfig>({
},
})
.run();
} else if (log.eventName === "StoreSpliceStaticData") {
} else if (log.eventName === "Store_SpliceStaticData") {
// TODO: verify that this returns what we expect (doesn't error/undefined on no record)
const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0];
const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x";
Expand Down Expand Up @@ -165,7 +165,7 @@ export async function sqliteStorage<TConfig extends StoreConfig = StoreConfig>({
},
})
.run();
} else if (log.eventName === "StoreSpliceDynamicData") {
} else if (log.eventName === "Store_SpliceDynamicData") {
const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0];
const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x";
const newDynamicData = spliceHex(previousDynamicData, log.args.start, log.args.deleteCount, log.args.data);
Expand Down Expand Up @@ -207,7 +207,7 @@ export async function sqliteStorage<TConfig extends StoreConfig = StoreConfig>({
},
})
.run();
} else if (log.eventName === "StoreDeleteRecord") {
} else if (log.eventName === "Store_DeleteRecord") {
// TODO: should we upsert so we at least have a DB record of when a thing was created/deleted within the same block?
debug("deleting record", {
namespace: table.namespace,
Expand Down
8 changes: 4 additions & 4 deletions packages/store/src/IStore.sol
Original file line number Diff line number Diff line change
Expand Up @@ -85,29 +85,29 @@ interface IStoreRead {
}

interface IStoreWrite {
event StoreSetRecord(
event Store_SetRecord(
ResourceId indexed tableId,
bytes32[] keyTuple,
bytes staticData,
bytes32 encodedLengths,
bytes dynamicData
);
event StoreSpliceStaticData(
event Store_SpliceStaticData(
ResourceId indexed tableId,
bytes32[] keyTuple,
uint48 start,
uint40 deleteCount,
bytes data
);
event StoreSpliceDynamicData(
event Store_SpliceDynamicData(
ResourceId indexed tableId,
bytes32[] keyTuple,
uint48 start,
uint40 deleteCount,
bytes data,
bytes32 encodedLengths
);
event StoreDeleteRecord(ResourceId indexed tableId, bytes32[] keyTuple);
event Store_DeleteRecord(ResourceId indexed tableId, bytes32[] keyTuple);

// Set full record (including full dynamic data)
function setRecord(
Expand Down
Loading
Loading