Skip to content

Commit

Permalink
feat(store,world): more granularity for onchain hooks (#1399)
Browse files Browse the repository at this point in the history
  • Loading branch information
alvrs committed Sep 7, 2023
1 parent 5408f61 commit c4d5eb4
Show file tree
Hide file tree
Showing 88 changed files with 2,881 additions and 431 deletions.
70 changes: 70 additions & 0 deletions .changeset/fuzzy-cars-stare.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
---
"@latticexyz/store": major
"@latticexyz/world": major
---

- The `onSetRecord` hook is split into `onBeforeSetRecord` and `onAfterSetRecord` and the `onDeleteRecord` hook is split into `onBeforeDeleteRecord` and `onAfterDeleteRecord`.
The purpose of this change is to allow more fine-grained control over the point in the lifecycle at which hooks are executed.

The previous hooks were executed before modifying data, so they can be replaced with the respective `onBefore` hooks.

```diff
- function onSetRecord(
+ function onBeforeSetRecord(
bytes32 table,
bytes32[] memory key,
bytes memory data,
Schema valueSchema
) public;

- function onDeleteRecord(
+ function onBeforeDeleteRecord(
bytes32 table,
bytes32[] memory key,
Schema valueSchema
) public;
```

- It is now possible to specify which methods of a hook contract should be called when registering a hook. The purpose of this change is to save gas by avoiding to call no-op hook methods.

```diff
function registerStoreHook(
bytes32 tableId,
- IStoreHook hookAddress
+ IStoreHook hookAddress,
+ uint8 enabledHooksBitmap
) public;

function registerSystemHook(
bytes32 systemId,
- ISystemHook hookAddress
+ ISystemHook hookAddress,
+ uint8 enabledHooksBitmap
) public;
```

There are `StoreHookLib` and `SystemHookLib` with helper functions to encode the bitmap of enabled hooks.

```solidity
import { StoreHookLib } from "@latticexyz/store/src/StoreHook.sol";
uint8 storeHookBitmap = StoreBookLib.encodeBitmap({
onBeforeSetRecord: true,
onAfterSetRecord: true,
onBeforeSetField: true,
onAfterSetField: true,
onBeforeDeleteRecord: true,
onAfterDeleteRecord: true
});
```

```solidity
import { SystemHookLib } from "@latticexyz/world/src/SystemHook.sol";
uint8 systemHookBitmap = SystemHookLib.encodeBitmap({
onBeforeCallSystem: true,
onAfterCallSystem: true
});
```

- The `onSetRecord` hook call for `emitEphemeralRecord` has been removed to save gas and to more clearly distinguish ephemeral tables as offchain tables.
183 changes: 183 additions & 0 deletions packages/store/abi/EchoSubscriber.sol/EchoSubscriber.abi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "HookCalled",
"type": "event"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "table",
"type": "bytes32"
},
{
"internalType": "bytes32[]",
"name": "key",
"type": "bytes32[]"
},
{
"internalType": "Schema",
"name": "valueSchema",
"type": "bytes32"
}
],
"name": "onAfterDeleteRecord",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "table",
"type": "bytes32"
},
{
"internalType": "bytes32[]",
"name": "key",
"type": "bytes32[]"
},
{
"internalType": "uint8",
"name": "schemaIndex",
"type": "uint8"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
},
{
"internalType": "Schema",
"name": "valueSchem",
"type": "bytes32"
}
],
"name": "onAfterSetField",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "table",
"type": "bytes32"
},
{
"internalType": "bytes32[]",
"name": "key",
"type": "bytes32[]"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
},
{
"internalType": "Schema",
"name": "valueSchema",
"type": "bytes32"
}
],
"name": "onAfterSetRecord",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "table",
"type": "bytes32"
},
{
"internalType": "bytes32[]",
"name": "key",
"type": "bytes32[]"
},
{
"internalType": "Schema",
"name": "valueSchema",
"type": "bytes32"
}
],
"name": "onBeforeDeleteRecord",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "table",
"type": "bytes32"
},
{
"internalType": "bytes32[]",
"name": "key",
"type": "bytes32[]"
},
{
"internalType": "uint8",
"name": "schemaIndex",
"type": "uint8"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
},
{
"internalType": "Schema",
"name": "valueSchema",
"type": "bytes32"
}
],
"name": "onBeforeSetField",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "table",
"type": "bytes32"
},
{
"internalType": "bytes32[]",
"name": "key",
"type": "bytes32[]"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
},
{
"internalType": "Schema",
"name": "valueSchema",
"type": "bytes32"
}
],
"name": "onBeforeSetRecord",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
Loading

0 comments on commit c4d5eb4

Please sign in to comment.