From 3b58a1f1d2fb028b5df173decad526a997d57b53 Mon Sep 17 00:00:00 2001 From: alvarius <89248902+alvrs@users.noreply.github.com> Date: Wed, 8 Feb 2023 16:54:25 -0500 Subject: [PATCH] fix(store): emit store events before early return (#381) * fix(store): emit store events before early return * test(store): add tests for emitting events --- packages/store/gas-report.txt | 156 ++++++++++++++-------------- packages/store/src/StoreCore.sol | 18 ++-- packages/store/test/StoreCore.t.sol | 32 ++++++ 3 files changed, 119 insertions(+), 87 deletions(-) diff --git a/packages/store/gas-report.txt b/packages/store/gas-report.txt index 8f1b868e45..8553fe9dbb 100644 --- a/packages/store/gas-report.txt +++ b/packages/store/gas-report.txt @@ -2,111 +2,111 @@ (test/Buffer.t.sol) | get buffer length [buf.length()]: 87 (test/Buffer.t.sol) | get buffer pointer [buf.ptr()]: 33 (test/Buffer.t.sol) | get buffer capacity [buf.capacity()]: 7 -(test/Buffer.t.sol) | append unchecked bytes memory (8) to buffer [buf.appendUnchecked(data1)]: 478 -(test/Buffer.t.sol) | append bytes memory (8) to buffer [buf.append(data2)]: 773 -(test/Buffer.t.sol) | append unchecked bytes8 of bytes32 to buffer [buf.appendUnchecked(data1, 8)]: 351 -(test/Buffer.t.sol) | append bytes8 of bytes32 to buffer [buf.append(data2, 8)]: 645 -(test/Buffer.t.sol) | concat 3 bytes memory (32) using buffer [Buffer buf = Buffer_.concat(data1, data2, data3)]: 2638 -(test/Buffer.t.sol) | concat 3 bytes memory (32) using bytes.concat [bytes memory concat = bytes.concat(data1, data2, data3)]: 641 -(test/Buffer.t.sol) | concat 3 bytes memory (32) using abi.encodePacked [bytes memory concat2 = abi.encodePacked(data1, data2, data3)]: 641 +(test/Buffer.t.sol) | append unchecked bytes memory (8) to buffer [buf.appendUnchecked(data1)]: 486 +(test/Buffer.t.sol) | append bytes memory (8) to buffer [buf.append(data2)]: 789 +(test/Buffer.t.sol) | append unchecked bytes8 of bytes32 to buffer [buf.appendUnchecked(data1, 8)]: 359 +(test/Buffer.t.sol) | append bytes8 of bytes32 to buffer [buf.append(data2, 8)]: 661 +(test/Buffer.t.sol) | concat 3 bytes memory (32) using buffer [Buffer buf = Buffer_.concat(data1, data2, data3)]: 2676 +(test/Buffer.t.sol) | concat 3 bytes memory (32) using bytes.concat [bytes memory concat = bytes.concat(data1, data2, data3)]: 692 +(test/Buffer.t.sol) | concat 3 bytes memory (32) using abi.encodePacked [bytes memory concat2 = abi.encodePacked(data1, data2, data3)]: 692 (test/Buffer.t.sol) | create a buffer from 8 bytes [Buffer buf = Buffer_.fromBytes(data)]: 40 (test/Buffer.t.sol) | read bytes32 from buffer [bytes32 value = buf.read32(4)]: 102 -(test/Buffer.t.sol) | read bytes8 with offset 3 from buffer [bytes8 value2 = buf.read8(3)]: 151 -(test/Buffer.t.sol) | read bytes1 with offset 7 from buffer [bytes1 value3 = buf.read1(7)]: 151 +(test/Buffer.t.sol) | read bytes8 with offset 3 from buffer [bytes8 value2 = buf.read8(3)]: 147 +(test/Buffer.t.sol) | read bytes1 with offset 7 from buffer [bytes1 value3 = buf.read1(7)]: 147 (test/Buffer.t.sol) | set buffer length unchecked [buf._setLengthUnchecked(8)]: 86 (test/Buffer.t.sol) | set buffer length [buf._setLength(16)]: 192 -(test/Buffer.t.sol) | slice 4 bytes from buffer with offset 4 [bytes memory slice = buf.slice(4, 4)]: 635 +(test/Buffer.t.sol) | slice 4 bytes from buffer with offset 4 [bytes memory slice = buf.slice(4, 4)]: 625 (test/Buffer.t.sol) | convert array pointer to uint256[] [uint256[] memory arr = Cast.toUint256Array(arrayPtr)]: 10 -(test/Buffer.t.sol) | buffer toArray with element length 4 [uint256 arrayPtr = buf.toArray(4)]: 745 +(test/Buffer.t.sol) | buffer toArray with element length 4 [uint256 arrayPtr = buf.toArray(4)]: 731 (test/Buffer.t.sol) | convert array pointer to uint32[] [uint32[] memory arr = Cast.toUint32Array(arrayPtr)]: 10 (test/Buffer.t.sol) | buffer (32 bytes) to bytes memory [bytes memory bufferData = buf.toBytes()]: 90 (test/Bytes.t.sol) | compare equal bytes [bool equals = Bytes.equals(a, b)]: 202 (test/Bytes.t.sol) | compare unequal bytes [bool equals = Bytes.equals(a, b)]: 202 -(test/Bytes.t.sol) | create uint32 array from bytes memory [uint32[] memory output = Bytes.toUint32Array(tight)]: 835 -(test/Bytes.t.sol) | create bytes from bytes array [bytes memory output = Bytes.from(input)]: 1290 -(test/Bytes.t.sol) | create bytes from uint16 array [bytes memory output = Bytes.from(input)]: 791 -(test/Bytes.t.sol) | create bytes from uint32 array [bytes memory output = Bytes.from(input)]: 695 -(test/Bytes.t.sol) | create bytes from uint8 array [bytes memory output = Bytes.from(input)]: 695 +(test/Bytes.t.sol) | create uint32 array from bytes memory [uint32[] memory output = Bytes.toUint32Array(tight)]: 825 +(test/Bytes.t.sol) | create bytes from bytes array [bytes memory output = Bytes.from(input)]: 1359 +(test/Bytes.t.sol) | create bytes from uint16 array [bytes memory output = Bytes.from(input)]: 781 +(test/Bytes.t.sol) | create bytes from uint32 array [bytes memory output = Bytes.from(input)]: 685 +(test/Bytes.t.sol) | create bytes from uint8 array [bytes memory output = Bytes.from(input)]: 685 (test/Bytes.t.sol) | set bytes1 in bytes32 [Bytes.setBytes1(input, 8, 0xff)]: 7 (test/Bytes.t.sol) | set bytes2 in bytes32 [Bytes.setBytes2(input, 8, 0xffff)]: 7 (test/Bytes.t.sol) | set bytes4 in bytes32 [Bytes.setBytes4(input, 8, 0xffffffff)]: 7 -(test/Bytes.t.sol) | slice bytes (with copying) with offset 1 and length 3 [bytes memory b = Bytes.slice(a, 1, 3)]: 516 +(test/Bytes.t.sol) | slice bytes (with copying) with offset 1 and length 3 [bytes memory b = Bytes.slice(a, 1, 3)]: 506 (test/Bytes.t.sol) | slice bytes3 with offset 1 [bytes3 b = Bytes.slice3(a, 1)]: 77 (test/Bytes.t.sol) | slice bytes32 with offset 10 [bytes32 output = Bytes.slice32(input, 10)]: 74 (test/Bytes.t.sol) | tightly pack bytes24 array into bytes array [bytes memory tight = Bytes.from(input)]: 477 (test/Bytes.t.sol) | create uint32 array from bytes memory [bytes24[] memory output = Bytes.toBytes24Array(tight)]: 614 (test/Bytes.t.sol) | create bytes32 from bytes memory with offset 0 [bytes32 output = Bytes.toBytes32(input, 0)]: 22 -(test/Bytes.t.sol) | create bytes32 array from bytes memory [bytes32[] memory output = Bytes.toBytes32Array(input)]: 1110 -(test/Bytes.t.sol) | create bytes32 array from bytes memory with uneven length [bytes32[] memory output = Bytes.toBytes32Array(input)]: 1425 +(test/Bytes.t.sol) | create bytes32 array from bytes memory [bytes32[] memory output = Bytes.toBytes32Array(input)]: 1101 +(test/Bytes.t.sol) | create bytes32 array from bytes memory with uneven length [bytes32[] memory output = Bytes.toBytes32Array(input)]: 1414 (test/Bytes.t.sol) | create bytes32 from bytes memory with offset 16 [bytes32 output = Bytes.toBytes32(input, 16)]: 22 -(test/Gas.t.sol) | abi encode [bytes memory abiEncoded = abi.encode(mixed)]: 930 -(test/Gas.t.sol) | abi decode [Mixed memory abiDecoded = abi.decode(abiEncoded, (Mixed))]: 1713 -(test/Gas.t.sol) | custom encode [bytes memory customEncoded = customEncode(mixed)]: 1393 -(test/Gas.t.sol) | custom decode [Mixed memory customDecoded = customDecode(customEncoded)]: 2772 -(test/Gas.t.sol) | pass abi encoded bytes to external contract [someContract.doSomethingWithBytes(abiEncoded)]: 6537 -(test/Gas.t.sol) | pass custom encoded bytes to external contract [someContract.doSomethingWithBytes(customEncoded)]: 1342 -(test/MixedTable.t.sol) | store Mixed struct in storage (native solidity) [testMixed = mixed]: 92016 -(test/MixedTable.t.sol) | register MixedTable schema [MixedTable.registerSchema()]: 32496 -(test/MixedTable.t.sol) | set record in MixedTable [MixedTable.set({ key: key, u32: 1, u128: 2, a32: a32, s: s })]: 114455 -(test/MixedTable.t.sol) | get record from MixedTable [Mixed memory mixed = MixedTable.get(key)]: 20471 -(test/PackedCounter.t.sol) | get value at index of PackedCounter [packedCounter.atIndex(3)]: 272 -(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/Gas.t.sol) | abi encode [bytes memory abiEncoded = abi.encode(mixed)]: 963 +(test/Gas.t.sol) | abi decode [Mixed memory abiDecoded = abi.decode(abiEncoded, (Mixed))]: 1746 +(test/Gas.t.sol) | custom encode [bytes memory customEncoded = customEncode(mixed)]: 1449 +(test/Gas.t.sol) | custom decode [Mixed memory customDecoded = customDecode(customEncoded)]: 2644 +(test/Gas.t.sol) | pass abi encoded bytes to external contract [someContract.doSomethingWithBytes(abiEncoded)]: 6552 +(test/Gas.t.sol) | pass custom encoded bytes to external contract [someContract.doSomethingWithBytes(customEncoded)]: 1378 +(test/MixedTable.t.sol) | store Mixed struct in storage (native solidity) [testMixed = mixed]: 92050 +(test/MixedTable.t.sol) | register MixedTable schema [MixedTable.registerSchema()]: 32463 +(test/MixedTable.t.sol) | set record in MixedTable [MixedTable.set({ key: key, u32: 1, u128: 2, a32: a32, s: s })]: 114307 +(test/MixedTable.t.sol) | get record from MixedTable [Mixed memory mixed = MixedTable.get(key)]: 20338 +(test/PackedCounter.t.sol) | get value at index of PackedCounter [packedCounter.atIndex(3)]: 261 +(test/PackedCounter.t.sol) | set value at index of PackedCounter [packedCounter = packedCounter.setAtIndex(2, 5)]: 799 +(test/PackedCounter.t.sol) | pack uint16 array into PackedCounter [PackedCounter packedCounter = PackedCounterLib.pack(counters)]: 2152 (test/PackedCounter.t.sol) | get total of PackedCounter [packedCounter.total()]: 33 -(test/RouteTable.t.sol) | register RouteTable schema [RouteTable.registerSchema()]: 30440 -(test/RouteTable.t.sol) | set RouteTable record [RouteTable.set(key, addr, selector, executionMode)]: 35240 -(test/RouteTable.t.sol) | get RouteTable record [Route memory systemEntry = RouteTable.get(key)]: 6554 -(test/Schema.t.sol) | encode schema with 6 entries [SchemaLib.encode]: 6172 -(test/Schema.t.sol) | get schema type at index [SchemaType schemaType1 = schema.atIndex(0)]: 200 +(test/RouteTable.t.sol) | register RouteTable schema [RouteTable.registerSchema()]: 30414 +(test/RouteTable.t.sol) | set RouteTable record [RouteTable.set(key, addr, selector, executionMode)]: 38341 +(test/RouteTable.t.sol) | get RouteTable record [Route memory systemEntry = RouteTable.get(key)]: 6536 +(test/Schema.t.sol) | encode schema with 6 entries [SchemaLib.encode]: 6195 +(test/Schema.t.sol) | get schema type at index [SchemaType schemaType1 = schema.atIndex(0)]: 191 (test/Schema.t.sol) | get number of dynamic fields from schema [uint256 num = schema.numDynamicFields()]: 80 (test/Schema.t.sol) | get number of static fields from schema [uint256 num = schema.numStaticFields()]: 91 (test/Schema.t.sol) | get static data length from schema [uint256 length = schema.staticDataLength()]: 39 (test/Schema.t.sol) | check if schema is empty (non-empty schema) [bool empty = encodedSchema.isEmpty()]: 13 (test/Schema.t.sol) | check if schema is empty (empty schema) [bool empty = encodedSchema.isEmpty()]: 13 -(test/Schema.t.sol) | validate schema [encodedSchema.validate()]: 22716 -(test/Storage.t.sol) | store 1 storage slot [Storage.store({ storagePointer: storagePointer, data: originalDataFirstSlot })]: 23449 -(test/Storage.t.sol) | store 34 bytes over 3 storage slots (with offset and safeTrail)) [Storage.store({ storagePointer: storagePointer, offset: 31, data: data1 })]: 25604 -(test/Storage.t.sol) | load 34 bytes over 3 storage slots (with offset and safeTrail)) [bytes memory data = Storage.load({ storagePointer: storagePointer, length: 34, offset: 31 })]: 4131 -(test/StoreCore.t.sol) | access non-existing record [bytes memory data1 = StoreCore.getRecord(table, key)]: 10090 -(test/StoreCore.t.sol) | access static field of non-existing record [bytes memory data2 = StoreCore.getField(table, key, 0)]: 4505 -(test/StoreCore.t.sol) | access dynamic field of non-existing record [bytes memory data3 = StoreCore.getField(table, key, 1)]: 3940 -(test/StoreCore.t.sol) | delete record (complex data, 3 slots) [StoreCore.deleteRecord(table, key)]: 10970 +(test/Schema.t.sol) | validate schema [encodedSchema.validate()]: 22314 +(test/Storage.t.sol) | store 1 storage slot [Storage.store({ storagePointer: storagePointer, data: originalDataFirstSlot })]: 23411 +(test/Storage.t.sol) | store 34 bytes over 3 storage slots (with offset and safeTrail)) [Storage.store({ storagePointer: storagePointer, offset: 31, data: data1 })]: 25518 +(test/Storage.t.sol) | load 34 bytes over 3 storage slots (with offset and safeTrail)) [bytes memory data = Storage.load({ storagePointer: storagePointer, length: 34, offset: 31 })]: 4083 +(test/StoreCore.t.sol) | access non-existing record [bytes memory data1 = StoreCore.getRecord(table, key)]: 10062 +(test/StoreCore.t.sol) | access static field of non-existing record [bytes memory data2 = StoreCore.getField(table, key, 0)]: 4466 +(test/StoreCore.t.sol) | access dynamic field of non-existing record [bytes memory data3 = StoreCore.getField(table, key, 1)]: 3923 +(test/StoreCore.t.sol) | delete record (complex data, 3 slots) [StoreCore.deleteRecord(table, key)]: 10903 (test/StoreCore.t.sol) | Check for existence of table (existent) [StoreCore.hasTable(table)]: 992 (test/StoreCore.t.sol) | check for existence of table (non-existent) [StoreCore.hasTable(table2)]: 2993 -(test/StoreCore.t.sol) | register subscriber [StoreCore.registerHook(table, subscriber)]: 70323 -(test/StoreCore.t.sol) | set record on table with subscriber [StoreCore.setRecord(table, key, data)]: 72168 -(test/StoreCore.t.sol) | set static field on table with subscriber [StoreCore.setField(table, key, 0, data)]: 34254 -(test/StoreCore.t.sol) | delete record on table with subscriber [StoreCore.deleteRecord(table, key)]: 24678 -(test/StoreCore.t.sol) | register subscriber [StoreCore.registerHook(table, subscriber)]: 70323 -(test/StoreCore.t.sol) | set (dynamic) record on table with subscriber [StoreCore.setRecord(table, key, data)]: 174918 -(test/StoreCore.t.sol) | set (dynamic) field on table with subscriber [StoreCore.setField(table, key, 1, arrayDataBytes)]: 37025 -(test/StoreCore.t.sol) | delete (dynamic) record on table with subscriber [StoreCore.deleteRecord(table, key)]: 30425 -(test/StoreCore.t.sol) | StoreCore: register schema [StoreCore.registerSchema(table, schema)]: 26419 +(test/StoreCore.t.sol) | register subscriber [StoreCore.registerHook(table, subscriber)]: 70266 +(test/StoreCore.t.sol) | set record on table with subscriber [StoreCore.setRecord(table, key, data)]: 78379 +(test/StoreCore.t.sol) | set static field on table with subscriber [StoreCore.setField(table, key, 0, data)]: 34174 +(test/StoreCore.t.sol) | delete record on table with subscriber [StoreCore.deleteRecord(table, key)]: 28719 +(test/StoreCore.t.sol) | register subscriber [StoreCore.registerHook(table, subscriber)]: 70266 +(test/StoreCore.t.sol) | set (dynamic) record on table with subscriber [StoreCore.setRecord(table, key, data)]: 174696 +(test/StoreCore.t.sol) | set (dynamic) field on table with subscriber [StoreCore.setField(table, key, 1, arrayDataBytes)]: 36910 +(test/StoreCore.t.sol) | delete (dynamic) record on table with subscriber [StoreCore.deleteRecord(table, key)]: 30269 +(test/StoreCore.t.sol) | StoreCore: register schema [StoreCore.registerSchema(table, schema)]: 26369 (test/StoreCore.t.sol) | StoreCore: get schema (warm) [Schema loadedSchema = StoreCore.getSchema(table)]: 937 -(test/StoreCore.t.sol) | set complex record with dynamic data (4 slots) [StoreCore.setRecord(table, key, data)]: 110652 -(test/StoreCore.t.sol) | get complex record with dynamic data (4 slots) [bytes memory loadedData = StoreCore.getRecord(table, key)]: 12755 -(test/StoreCore.t.sol) | compare: Set complex record with dynamic data using native solidity [testStruct = _testStruct]: 116815 -(test/StoreCore.t.sol) | compare: Set complex record with dynamic data using abi.encode [testMapping[1234] = abi.encode(_testStruct)]: 267529 -(test/StoreCore.t.sol) | set dynamic length of dynamic index 0 [StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 0, 10)]: 23676 -(test/StoreCore.t.sol) | set dynamic length of dynamic index 1 [StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 1, 99)]: 1777 -(test/StoreCore.t.sol) | reduce dynamic length of dynamic index 0 [StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 0, 5)]: 1768 -(test/StoreCore.t.sol) | set static field (1 slot) [StoreCore.setField(table, key, 0, abi.encodePacked(firstDataBytes))]: 38105 -(test/StoreCore.t.sol) | get static field (1 slot) [bytes memory loadedData = StoreCore.getField(table, key, 0)]: 4592 -(test/StoreCore.t.sol) | set static field (overlap 2 slot) [StoreCore.setField(table, key, 1, abi.encodePacked(secondDataBytes))]: 33895 -(test/StoreCore.t.sol) | get static field (overlap 2 slot) [loadedData = StoreCore.getField(table, key, 1)]: 6375 -(test/StoreCore.t.sol) | set dynamic field (1 slot, first dynamic field) [StoreCore.setField(table, key, 2, thirdDataBytes)]: 57377 -(test/StoreCore.t.sol) | get dynamic field (1 slot, first dynamic field) [loadedData = StoreCore.getField(table, key, 2)]: 5357 -(test/StoreCore.t.sol) | set dynamic field (1 slot, second dynamic field) [StoreCore.setField(table, key, 3, fourthDataBytes)]: 35511 -(test/StoreCore.t.sol) | get dynamic field (1 slot, second dynamic field) [loadedData = StoreCore.getField(table, key, 3)]: 5372 -(test/StoreCore.t.sol) | set static record (1 slot) [StoreCore.setRecord(table, key, data)]: 34136 -(test/StoreCore.t.sol) | get static record (1 slot) [bytes memory loadedData = StoreCore.getRecord(table, key, schema)]: 4102 -(test/StoreCore.t.sol) | set static record (2 slots) [StoreCore.setRecord(table, key, data)]: 56691 -(test/StoreCore.t.sol) | get static record (2 slots) [bytes memory loadedData = StoreCore.getRecord(table, key, schema)]: 4991 +(test/StoreCore.t.sol) | set complex record with dynamic data (4 slots) [StoreCore.setRecord(table, key, data)]: 110435 +(test/StoreCore.t.sol) | get complex record with dynamic data (4 slots) [bytes memory loadedData = StoreCore.getRecord(table, key)]: 12661 +(test/StoreCore.t.sol) | compare: Set complex record with dynamic data using native solidity [testStruct = _testStruct]: 116839 +(test/StoreCore.t.sol) | compare: Set complex record with dynamic data using abi.encode [testMapping[1234] = abi.encode(_testStruct)]: 267366 +(test/StoreCore.t.sol) | set dynamic length of dynamic index 0 [StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 0, 10)]: 23649 +(test/StoreCore.t.sol) | set dynamic length of dynamic index 1 [StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 1, 99)]: 1750 +(test/StoreCore.t.sol) | reduce dynamic length of dynamic index 0 [StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 0, 5)]: 1738 +(test/StoreCore.t.sol) | set static field (1 slot) [StoreCore.setField(table, key, 0, abi.encodePacked(firstDataBytes))]: 38021 +(test/StoreCore.t.sol) | get static field (1 slot) [bytes memory loadedData = StoreCore.getField(table, key, 0)]: 4557 +(test/StoreCore.t.sol) | set static field (overlap 2 slot) [StoreCore.setField(table, key, 1, abi.encodePacked(secondDataBytes))]: 33764 +(test/StoreCore.t.sol) | get static field (overlap 2 slot) [loadedData = StoreCore.getField(table, key, 1)]: 6321 +(test/StoreCore.t.sol) | set dynamic field (1 slot, first dynamic field) [StoreCore.setField(table, key, 2, thirdDataBytes)]: 57262 +(test/StoreCore.t.sol) | get dynamic field (1 slot, first dynamic field) [loadedData = StoreCore.getField(table, key, 2)]: 5317 +(test/StoreCore.t.sol) | set dynamic field (1 slot, second dynamic field) [StoreCore.setField(table, key, 3, fourthDataBytes)]: 35386 +(test/StoreCore.t.sol) | get dynamic field (1 slot, second dynamic field) [loadedData = StoreCore.getField(table, key, 3)]: 5332 +(test/StoreCore.t.sol) | set static record (1 slot) [StoreCore.setRecord(table, key, data)]: 37215 +(test/StoreCore.t.sol) | get static record (1 slot) [bytes memory loadedData = StoreCore.getRecord(table, key, schema)]: 4084 +(test/StoreCore.t.sol) | set static record (2 slots) [StoreCore.setRecord(table, key, data)]: 60072 +(test/StoreCore.t.sol) | get static record (2 slots) [bytes memory loadedData = StoreCore.getRecord(table, key, schema)]: 4968 (test/StoreSwitch.t.sol) | check if delegatecall [isDelegate = StoreSwitch.isDelegateCall()]: 671 (test/StoreSwitch.t.sol) | check if delegatecall [isDelegate = StoreSwitch.isDelegateCall()]: 627 (test/System.t.sol) | extract msg.sender from calldata [address sender = _msgSender()]: 24 -(test/Vector2Table.t.sol) | register Vector2Table schema [Vector2Table.registerSchema()]: 28673 -(test/Vector2Table.t.sol) | set Vector2Table record [Vector2Table.set({ key: key, x: 1, y: 2 })]: 35206 -(test/Vector2Table.t.sol) | get Vector2Table record [Vector2 memory vector = Vector2Table.get(key)]: 6440 -(test/World.t.sol) | call autonomous system via World contract [WorldWithWorldTestSystem(address(world)).WorldTestSystem_move(entity, 1, 2)]: 45511 -(test/World.t.sol) | call delegate system via World contract [WorldWithWorldTestSystem(address(world)).WorldTestSystem_move(entity, 1, 2)]: 43376 \ No newline at end of file +(test/Vector2Table.t.sol) | register Vector2Table schema [Vector2Table.registerSchema()]: 28654 +(test/Vector2Table.t.sol) | set Vector2Table record [Vector2Table.set({ key: key, x: 1, y: 2 })]: 38307 +(test/Vector2Table.t.sol) | get Vector2Table record [Vector2 memory vector = Vector2Table.get(key)]: 6422 +(test/World.t.sol) | call autonomous system via World contract [WorldWithWorldTestSystem(address(world)).WorldTestSystem_move(entity, 1, 2)]: 48619 +(test/World.t.sol) | call delegate system via World contract [WorldWithWorldTestSystem(address(world)).WorldTestSystem_move(entity, 1, 2)]: 46405 \ No newline at end of file diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index 9d511deabc..448e2003bb 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -114,6 +114,9 @@ library StoreCore { revert StoreCore_InvalidDataLength(expectedLength, data.length); } + // Emit event to notify indexers + emit MudStoreSetRecord(table, key, data); + // Call onSetRecord hooks (before actually modifying the state, so observers have access to the previous state if needed) address[] memory hooks = HooksTable.get(table); for (uint256 i = 0; i < hooks.length; i++) { @@ -156,9 +159,6 @@ library StoreCore { i++; } } - - // Emit event to notify indexers - emit MudStoreSetRecord(table, key, data); } function setField( @@ -169,6 +169,9 @@ library StoreCore { ) internal { Schema schema = getSchema(table); + // Emit event to notify indexers + emit MudStoreSetField(table, key, schemaIndex, data); + // Call onSetField hooks (before actually modifying the state, so observers have access to the previous state if needed) address[] memory hooks = HooksTable.get(table); for (uint256 i = 0; i < hooks.length; i++) { @@ -181,15 +184,15 @@ library StoreCore { } else { StoreCoreInternal._setDynamicField(table, key, schema, schemaIndex, data); } - - // Emit event to notify indexers - emit MudStoreSetField(table, key, schemaIndex, data); } function deleteRecord(bytes32 table, bytes32[] memory key) internal { // Get schema for this table Schema schema = getSchema(table); + // Emit event to notify indexers + emit MudStoreDeleteRecord(table, key); + // Call onDeleteRecord hooks (before actually modifying the state, so observers have access to the previous state if needed) address[] memory hooks = HooksTable.get(table); for (uint256 i = 0; i < hooks.length; i++) { @@ -207,9 +210,6 @@ library StoreCore { // Delete dynamic data length uint256 dynamicDataLengthLocation = StoreCoreInternal._getDynamicDataLengthLocation(table, key); Storage.store({ storagePointer: dynamicDataLengthLocation, data: bytes32(0) }); - - // Emit event to notify indexers - emit MudStoreDeleteRecord(table, key); } /************************************************************************ diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index 11cd247d76..d575200793 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -148,6 +148,10 @@ contract StoreCoreTest is Test, StoreView { bytes32[] memory key = new bytes32[](1); key[0] = keccak256("some.key"); + // Expect a MudStoreSetRecord event to be emitted + vm.expectEmit(true, true, true, true); + emit MudStoreSetRecord(table, key, data); + // !gasreport set static record (1 slot) StoreCore.setRecord(table, key, data); @@ -189,6 +193,10 @@ contract StoreCoreTest is Test, StoreView { bytes32[] memory key = new bytes32[](1); key[0] = keccak256("some.key"); + // Expect a MudStoreSetRecord event to be emitted + vm.expectEmit(true, true, true, true); + emit MudStoreSetRecord(table, key, data); + // !gasreport set static record (2 slots) StoreCore.setRecord(table, key, data); @@ -247,6 +255,10 @@ contract StoreCoreTest is Test, StoreView { bytes32[] memory key = new bytes32[](1); key[0] = bytes32("some.key"); + // Expect a MudStoreSetRecord event to be emitted + vm.expectEmit(true, true, true, true); + emit MudStoreSetRecord(table, key, data); + // Set data // !gasreport set complex record with dynamic data (4 slots) StoreCore.setRecord(table, key, data); @@ -294,6 +306,10 @@ contract StoreCoreTest is Test, StoreView { bytes32[] memory key = new bytes32[](1); key[0] = bytes32("some.key"); + // Expect a MudStoreSetField event to be emitted + vm.expectEmit(true, true, true, true); + emit MudStoreSetField(table, key, 0, abi.encodePacked(firstDataBytes)); + // Set first field // !gasreport set static field (1 slot) StoreCore.setField(table, key, 0, abi.encodePacked(firstDataBytes)); @@ -316,6 +332,10 @@ contract StoreCoreTest is Test, StoreView { // Set second field bytes32 secondDataBytes = keccak256("some data"); + // Expect a MudStoreSetField event to be emitted + vm.expectEmit(true, true, true, true); + emit MudStoreSetField(table, key, 1, abi.encodePacked(secondDataBytes)); + // !gasreport set static field (overlap 2 slot) StoreCore.setField(table, key, 1, abi.encodePacked(secondDataBytes)); @@ -360,6 +380,10 @@ contract StoreCoreTest is Test, StoreView { fourthDataBytes = Bytes.from(fourthData); } + // Expect a MudStoreSetField event to be emitted + vm.expectEmit(true, true, true, true); + emit MudStoreSetField(table, key, 2, thirdDataBytes); + // Set third field // !gasreport set dynamic field (1 slot, first dynamic field) StoreCore.setField(table, key, 2, thirdDataBytes); @@ -380,6 +404,10 @@ contract StoreCoreTest is Test, StoreView { assertEq(bytes16(StoreCore.getField(table, key, 0)), bytes16(firstDataBytes)); assertEq(bytes32(StoreCore.getField(table, key, 1)), bytes32(secondDataBytes)); + // Expect a MudStoreSetField event to be emitted + vm.expectEmit(true, true, true, true); + emit MudStoreSetField(table, key, 3, fourthDataBytes); + // Set fourth field // !gasreport set dynamic field (1 slot, second dynamic field) StoreCore.setField(table, key, 3, fourthDataBytes); @@ -457,6 +485,10 @@ contract StoreCoreTest is Test, StoreView { assertEq(loadedData.length, data.length); assertEq(keccak256(loadedData), keccak256(data)); + // Expect a MudStoreDeleteRecord event to be emitted + vm.expectEmit(true, true, true, true); + emit MudStoreDeleteRecord(table, key); + // Delete data // !gasreport delete record (complex data, 3 slots) StoreCore.deleteRecord(table, key);