From 884afc0614e2d57e6c4250c31f93ece83a102be2 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Mon, 19 Jun 2023 12:54:40 +0100 Subject: [PATCH] move tests to new gas report --- packages/store/gas-report.json | 708 ++++++++++++++++++ packages/store/test/Bytes.t.sol | 35 +- packages/store/test/KeyEncoding.t.sol | 8 +- packages/store/test/Mixed.t.sol | 17 +- packages/store/test/PackedCounter.t.sol | 17 +- packages/store/test/Schema.t.sol | 28 +- packages/store/test/Slice.t.sol | 41 +- packages/store/test/Storage.t.sol | 14 +- packages/store/test/StoreCoreDynamic.t.sol | 39 +- packages/store/test/StoreCoreGas.t.sol | 134 ++-- packages/store/test/StoreMetadata.t.sol | 11 +- packages/store/test/StoreSwitch.t.sol | 12 +- packages/store/test/Vector2.t.sol | 14 +- packages/store/test/tables/Callbacks.t.sol | 14 +- packages/store/test/tables/Hooks.t.sol | 14 +- .../store/test/tightcoder/DecodeSlice.t.sol | 11 +- .../store/test/tightcoder/EncodeArray.t.sol | 17 +- .../store/test/tightcoder/TightCoder.t.sol | 14 +- packages/world/gas-report.json | 316 ++++---- packages/world/package.json | 3 +- packages/world/test/KeysInTableModule.t.sol | 41 +- packages/world/test/KeysWithValueModule.t.sol | 29 +- packages/world/test/SnapSyncModule.t.sol | 23 +- packages/world/test/UniqueEntityModule.t.sol | 17 +- packages/world/test/World.t.sol | 40 +- packages/world/test/WorldDynamicUpdate.t.sol | 22 +- packages/world/test/query.t.sol | 38 +- pnpm-lock.yaml | 3 + 28 files changed, 1300 insertions(+), 380 deletions(-) diff --git a/packages/store/gas-report.json b/packages/store/gas-report.json index 8e77fb77b1..2c4286c194 100644 --- a/packages/store/gas-report.json +++ b/packages/store/gas-report.json @@ -1,4 +1,64 @@ [ + { + "file": "test/Bytes.t.sol", + "test": "testEquals", + "name": "compare equal bytes", + "gasUsed": 195 + }, + { + "file": "test/Bytes.t.sol", + "test": "testEqualsFalse", + "name": "compare unequal bytes", + "gasUsed": 195 + }, + { + "file": "test/Bytes.t.sol", + "test": "testSetBytes1", + "name": "set bytes1 in bytes32", + "gasUsed": 0 + }, + { + "file": "test/Bytes.t.sol", + "test": "testSetBytes2", + "name": "set bytes2 in bytes32", + "gasUsed": 0 + }, + { + "file": "test/Bytes.t.sol", + "test": "testSetBytes4", + "name": "set bytes4 in bytes32", + "gasUsed": 0 + }, + { + "file": "test/Bytes.t.sol", + "test": "testSetBytes4Memory", + "name": "set bytes4 in bytes memory", + "gasUsed": 36 + }, + { + "file": "test/Bytes.t.sol", + "test": "testSlice3", + "name": "slice bytes3 with offset 1", + "gasUsed": 67 + }, + { + "file": "test/Bytes.t.sol", + "test": "testSlice32", + "name": "slice bytes32 with offset 10", + "gasUsed": 67 + }, + { + "file": "test/Bytes.t.sol", + "test": "testToBytes32", + "name": "create bytes32 from bytes memory with offset 0", + "gasUsed": 24 + }, + { + "file": "test/Bytes.t.sol", + "test": "testToBytes32CrossWord", + "name": "create bytes32 from bytes memory with offset 16", + "gasUsed": 35 + }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", @@ -34,5 +94,653 @@ "test": "testCompareAbiEncodeVsCustom", "name": "pass custom encoded bytes to external contract", "gasUsed": 1375 + }, + { + "file": "test/KeyEncoding.t.sol", + "test": "testRegisterAndGetSchema", + "name": "register KeyEncoding schema", + "gasUsed": 64685 + }, + { + "file": "test/Mixed.t.sol", + "test": "testCompareSolidity", + "name": "store Mixed struct in storage (native solidity)", + "gasUsed": 92037 + }, + { + "file": "test/Mixed.t.sol", + "test": "testRegisterAndGetSchema", + "name": "register Mixed schema", + "gasUsed": 61216 + }, + { + "file": "test/Mixed.t.sol", + "test": "testSetAndGet", + "name": "set record in Mixed", + "gasUsed": 112167 + }, + { + "file": "test/Mixed.t.sol", + "test": "testSetAndGet", + "name": "get record from Mixed", + "gasUsed": 13453 + }, + { + "file": "test/PackedCounter.t.sol", + "test": "testAtIndex", + "name": "get value at index of PackedCounter", + "gasUsed": 254 + }, + { + "file": "test/PackedCounter.t.sol", + "test": "testSetAtIndex", + "name": "set value at index of PackedCounter", + "gasUsed": 792 + }, + { + "file": "test/PackedCounter.t.sol", + "test": "testTotal", + "name": "pack uint40 array into PackedCounter", + "gasUsed": 2145 + }, + { + "file": "test/PackedCounter.t.sol", + "test": "testTotal", + "name": "get total of PackedCounter", + "gasUsed": 26 + }, + { + "file": "test/Schema.t.sol", + "test": "testEncodeDecodeSchema", + "name": "get schema type at index", + "gasUsed": 184 + }, + { + "file": "test/Schema.t.sol", + "test": "testGetNumDynamicFields", + "name": "get number of dynamic fields from schema", + "gasUsed": 73 + }, + { + "file": "test/Schema.t.sol", + "test": "testGetNumStaticFields", + "name": "get number of static fields from schema", + "gasUsed": 84 + }, + { + "file": "test/Schema.t.sol", + "test": "testGetStaticSchemaLength", + "name": "get static data length from schema", + "gasUsed": 32 + }, + { + "file": "test/Schema.t.sol", + "test": "testIsEmptyFalse", + "name": "check if schema is empty (non-empty schema)", + "gasUsed": 6 + }, + { + "file": "test/Schema.t.sol", + "test": "testIsEmptyTrue", + "name": "check if schema is empty (empty schema)", + "gasUsed": 6 + }, + { + "file": "test/Schema.t.sol", + "test": "testValidate", + "name": "validate schema", + "gasUsed": 18265 + }, + { + "file": "test/Slice.t.sol", + "test": "testFromBytes", + "name": "make Slice from bytes", + "gasUsed": 30 + }, + { + "file": "test/Slice.t.sol", + "test": "testFromBytes", + "name": "get Slice length", + "gasUsed": 0 + }, + { + "file": "test/Slice.t.sol", + "test": "testFromBytes", + "name": "get Slice pointer", + "gasUsed": 26 + }, + { + "file": "test/Slice.t.sol", + "test": "testSubslice", + "name": "subslice bytes (no copy) [1:4]", + "gasUsed": 310 + }, + { + "file": "test/Slice.t.sol", + "test": "testSubslice", + "name": "subslice bytes (no copy) [4:37]", + "gasUsed": 310 + }, + { + "file": "test/Slice.t.sol", + "test": "testToBytes", + "name": "Slice (0 bytes) to bytes memory", + "gasUsed": 472 + }, + { + "file": "test/Slice.t.sol", + "test": "testToBytes", + "name": "Slice (2 bytes) to bytes memory", + "gasUsed": 507 + }, + { + "file": "test/Slice.t.sol", + "test": "testToBytes", + "name": "Slice (32 bytes) to bytes memory", + "gasUsed": 507 + }, + { + "file": "test/Slice.t.sol", + "test": "testToBytes", + "name": "Slice (34 bytes) to bytes memory", + "gasUsed": 584 + }, + { + "file": "test/Slice.t.sol", + "test": "testToBytes", + "name": "Slice (1024 bytes) to bytes memory", + "gasUsed": 4847 + }, + { + "file": "test/Slice.t.sol", + "test": "testToBytes", + "name": "Slice (1024x1024 bytes) to bytes memory", + "gasUsed": 6614841 + }, + { + "file": "test/Slice.t.sol", + "test": "testToBytes32", + "name": "Slice to bytes32", + "gasUsed": 80 + }, + { + "file": "test/Storage.t.sol", + "test": "testStoreLoad", + "name": "store 1 storage slot", + "gasUsed": 22502 + }, + { + "file": "test/Storage.t.sol", + "test": "testStoreLoad", + "name": "store 34 bytes over 3 storage slots (with offset and safeTrail))", + "gasUsed": 23157 + }, + { + "file": "test/Storage.t.sol", + "test": "testStoreLoad", + "name": "load 34 bytes over 3 storage slots (with offset and safeTrail))", + "gasUsed": 1098 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testGetFieldSlice", + "name": "get field slice (cold, 1 slot)", + "gasUsed": 8151 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testGetFieldSlice", + "name": "get field slice (warm, 1 slot)", + "gasUsed": 2179 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testGetFieldSlice", + "name": "get field slice (semi-cold, 1 slot)", + "gasUsed": 4183 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testGetFieldSlice", + "name": "get field slice (warm, 2 slots)", + "gasUsed": 4470 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testGetSecondFieldLength", + "name": "get field length (cold, 1 slot)", + "gasUsed": 7958 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testGetSecondFieldLength", + "name": "get field length (warm, 1 slot)", + "gasUsed": 1955 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testGetThirdFieldLength", + "name": "get field length (warm due to , 2 slots)", + "gasUsed": 7958 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testGetThirdFieldLength", + "name": "get field length (warm, 2 slots)", + "gasUsed": 1954 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testPopFromSecondField", + "name": "pop from field (cold, 1 slot, 1 uint32 item)", + "gasUsed": 29290 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testPopFromSecondField", + "name": "pop from field (warm, 1 slot, 1 uint32 item)", + "gasUsed": 19343 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testPopFromThirdField", + "name": "pop from field (cold, 2 slots, 10 uint32 items)", + "gasUsed": 31173 + }, + { + "file": "test/StoreCoreDynamic.t.sol", + "test": "testPopFromThirdField", + "name": "pop from field (warm, 2 slots, 10 uint32 items)", + "gasUsed": 19226 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testAccessEmptyData", + "name": "access non-existing record", + "gasUsed": 7320 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testAccessEmptyData", + "name": "access static field of non-existing record", + "gasUsed": 2972 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testAccessEmptyData", + "name": "access dynamic field of non-existing record", + "gasUsed": 3585 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testAccessEmptyData", + "name": "access length of dynamic field of non-existing record", + "gasUsed": 1326 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testAccessEmptyData", + "name": "access slice of dynamic field of non-existing record", + "gasUsed": 1322 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testDeleteData", + "name": "delete record (complex data, 3 slots)", + "gasUsed": 10993 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHasSchema", + "name": "Check for existence of table (existent)", + "gasUsed": 1127 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHasSchema", + "name": "check for existence of table (non-existent)", + "gasUsed": 3128 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHooks", + "name": "register subscriber", + "gasUsed": 65559 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHooks", + "name": "set record on table with subscriber", + "gasUsed": 73960 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHooks", + "name": "set static field on table with subscriber", + "gasUsed": 32025 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHooks", + "name": "delete record on table with subscriber", + "gasUsed": 24583 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHooksDynamicData", + "name": "register subscriber", + "gasUsed": 65559 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHooksDynamicData", + "name": "set (dynamic) record on table with subscriber", + "gasUsed": 167397 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHooksDynamicData", + "name": "set (dynamic) field on table with subscriber", + "gasUsed": 35058 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testHooksDynamicData", + "name": "delete (dynamic) record on table with subscriber", + "gasUsed": 26054 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testPushToField", + "name": "push to field (1 slot, 1 uint32 item)", + "gasUsed": 17063 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testPushToField", + "name": "push to field (2 slots, 10 uint32 items)", + "gasUsed": 39779 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testRegisterAndGetSchema", + "name": "StoreCore: register schema", + "gasUsed": 54869 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testRegisterAndGetSchema", + "name": "StoreCore: get schema (warm)", + "gasUsed": 1127 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testRegisterAndGetSchema", + "name": "StoreCore: get key schema (warm)", + "gasUsed": 2322 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetDynamicData", + "name": "set complex record with dynamic data (4 slots)", + "gasUsed": 107706 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetDynamicData", + "name": "get complex record with dynamic data (4 slots)", + "gasUsed": 6440 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetDynamicData", + "name": "compare: Set complex record with dynamic data using native solidity", + "gasUsed": 116841 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetDynamicData", + "name": "compare: Set complex record with dynamic data using abi.encode", + "gasUsed": 267368 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetDynamicDataLength", + "name": "set dynamic length of dynamic index 0", + "gasUsed": 23609 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetDynamicDataLength", + "name": "set dynamic length of dynamic index 1", + "gasUsed": 1710 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetDynamicDataLength", + "name": "reduce dynamic length of dynamic index 0", + "gasUsed": 1698 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetField", + "name": "set static field (1 slot)", + "gasUsed": 37984 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetField", + "name": "get static field (1 slot)", + "gasUsed": 2975 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetField", + "name": "set static field (overlap 2 slot)", + "gasUsed": 35005 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetField", + "name": "get static field (overlap 2 slot)", + "gasUsed": 3874 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetField", + "name": "set dynamic field (1 slot, first dynamic field)", + "gasUsed": 57383 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetField", + "name": "get dynamic field (1 slot, first dynamic field)", + "gasUsed": 3808 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetField", + "name": "set dynamic field (1 slot, second dynamic field)", + "gasUsed": 35513 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetField", + "name": "get dynamic field (1 slot, second dynamic field)", + "gasUsed": 3823 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetStaticData", + "name": "set static record (1 slot)", + "gasUsed": 37373 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetStaticData", + "name": "get static record (1 slot)", + "gasUsed": 1319 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetStaticDataSpanningWords", + "name": "set static record (2 slots)", + "gasUsed": 59940 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetAndGetStaticDataSpanningWords", + "name": "get static record (2 slots)", + "gasUsed": 1568 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testSetMetadata", + "name": "StoreCore: set table metadata", + "gasUsed": 251865 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testUpdateInField", + "name": "update in field (1 slot, 1 uint32 item)", + "gasUsed": 16600 + }, + { + "file": "test/StoreCoreGas.t.sol", + "test": "testUpdateInField", + "name": "push to field (2 slots, 6 uint64 items)", + "gasUsed": 17698 + }, + { + "file": "test/StoreMetadata.t.sol", + "test": "testSetAndGet", + "name": "set record in StoreMetadataTable", + "gasUsed": 250187 + }, + { + "file": "test/StoreMetadata.t.sol", + "test": "testSetAndGet", + "name": "get record from StoreMetadataTable", + "gasUsed": 12114 + }, + { + "file": "test/StoreSwitch.t.sol", + "test": "testIsDelegatecall", + "name": "check if delegatecall", + "gasUsed": 682 + }, + { + "file": "test/StoreSwitch.t.sol", + "test": "testIsNoDelegatecall", + "name": "check if delegatecall", + "gasUsed": 702 + }, + { + "file": "test/tables/Callbacks.t.sol", + "test": "testSetAndGet", + "name": "set field in Callbacks", + "gasUsed": 63202 + }, + { + "file": "test/tables/Callbacks.t.sol", + "test": "testSetAndGet", + "name": "get field from Callbacks (warm)", + "gasUsed": 5783 + }, + { + "file": "test/tables/Callbacks.t.sol", + "test": "testSetAndGet", + "name": "push field to Callbacks", + "gasUsed": 40883 + }, + { + "file": "test/tables/Hooks.t.sol", + "test": "testSetAndGet", + "name": "set field in Hooks", + "gasUsed": 63358 + }, + { + "file": "test/tables/Hooks.t.sol", + "test": "testSetAndGet", + "name": "get field from Hooks (warm)", + "gasUsed": 5934 + }, + { + "file": "test/tables/Hooks.t.sol", + "test": "testSetAndGet", + "name": "push field to Hooks", + "gasUsed": 40877 + }, + { + "file": "test/tightcoder/DecodeSlice.t.sol", + "test": "testToArrayUint32", + "name": "decode packed uint32[]", + "gasUsed": 784 + }, + { + "file": "test/tightcoder/DecodeSlice.t.sol", + "test": "testToBytes32Array", + "name": "decode packed bytes32[]", + "gasUsed": 610 + }, + { + "file": "test/tightcoder/EncodeArray.t.sol", + "test": "testEncodeBytesArray", + "name": "encode packed bytes[]", + "gasUsed": 1356 + }, + { + "file": "test/tightcoder/EncodeArray.t.sol", + "test": "testEncodeUint16Array", + "name": "encode packed uint16[]", + "gasUsed": 1145 + }, + { + "file": "test/tightcoder/EncodeArray.t.sol", + "test": "testEncodeUint32Array", + "name": "encode packed uint32[]", + "gasUsed": 1051 + }, + { + "file": "test/tightcoder/EncodeArray.t.sol", + "test": "testEncodeUint8Array", + "name": "encode packed uint8[]", + "gasUsed": 1037 + }, + { + "file": "test/tightcoder/TightCoder.t.sol", + "test": "testFromAndToUint32Array", + "name": "decode packed uint32[]", + "gasUsed": 787 + }, + { + "file": "test/tightcoder/TightCoder.t.sol", + "test": "testToAndFromBytes24Array", + "name": "encode packed bytes24[]", + "gasUsed": 888 + }, + { + "file": "test/tightcoder/TightCoder.t.sol", + "test": "testToAndFromBytes24Array", + "name": "decode packed uint32[]", + "gasUsed": 621 + }, + { + "file": "test/Vector2.t.sol", + "test": "testRegisterAndGetSchema", + "name": "register Vector2 schema", + "gasUsed": 57994 + }, + { + "file": "test/Vector2.t.sol", + "test": "testSetAndGet", + "name": "set Vector2 record", + "gasUsed": 38662 + }, + { + "file": "test/Vector2.t.sol", + "test": "testSetAndGet", + "name": "get Vector2 record", + "gasUsed": 5089 } ] diff --git a/packages/store/test/Bytes.t.sol b/packages/store/test/Bytes.t.sol index 8f3000abd0..ca81dbb337 100644 --- a/packages/store/test/Bytes.t.sol +++ b/packages/store/test/Bytes.t.sol @@ -1,17 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { Bytes } from "../src/Bytes.sol"; -contract BytesTest is Test { +contract BytesTest is Test, GasReporter { function testToBytes32() public { bytes memory input = new bytes(32); input[0] = 0x01; input[31] = 0x02; - // !gasreport create bytes32 from bytes memory with offset 0 + startGasReport("create bytes32 from bytes memory with offset 0"); bytes32 output = Bytes.toBytes32(input, 0); + endGasReport(); assertEq(uint256(output), 0x0100000000000000000000000000000000000000000000000000000000000002); } @@ -21,8 +23,9 @@ contract BytesTest is Test { input[0 + 16] = 0x01; input[31 + 16] = 0x02; - // !gasreport create bytes32 from bytes memory with offset 16 + startGasReport("create bytes32 from bytes memory with offset 16"); bytes32 output = Bytes.toBytes32(input, 16); + endGasReport(); assertEq(uint256(output), 0x0100000000000000000000000000000000000000000000000000000000000002); } @@ -31,8 +34,9 @@ contract BytesTest is Test { bytes memory a = bytes("a"); bytes memory b = bytes("a"); - // !gasreport compare equal bytes + startGasReport("compare equal bytes"); bool equals = Bytes.equals(a, b); + endGasReport(); assertTrue(equals); } @@ -41,8 +45,9 @@ contract BytesTest is Test { bytes memory a = bytes("a"); bytes memory b = bytes("b"); - // !gasreport compare unequal bytes + startGasReport("compare unequal bytes"); bool equals = Bytes.equals(a, b); + endGasReport(); assertFalse(equals); } @@ -62,8 +67,9 @@ contract BytesTest is Test { a[3] = 0x04; a[4] = 0x05; - // !gasreport slice bytes3 with offset 1 + startGasReport("slice bytes3 with offset 1"); bytes3 b = Bytes.slice3(a, 1); + endGasReport(); assertEq(b.length, 3); assertEq(uint256(uint8(b[0])), 0x02); @@ -75,8 +81,9 @@ contract BytesTest is Test { bytes32 original = keccak256("some data"); bytes memory input = abi.encodePacked(bytes10(keccak256("irrelevant data")), original); - // !gasreport slice bytes32 with offset 10 + startGasReport("slice bytes32 with offset 10"); bytes32 output = Bytes.slice32(input, 10); + endGasReport(); assertEq(output, original); } @@ -84,8 +91,9 @@ contract BytesTest is Test { function testSetBytes1() public { bytes32 input = bytes32(0); - // !gasreport set bytes1 in bytes32 + startGasReport("set bytes1 in bytes32"); Bytes.setBytes1(input, 8, 0xff); + endGasReport(); assertEq(Bytes.setBytes1(input, 0, 0x01), bytes32(bytes1(0x01))); assertEq(Bytes.setBytes1(input, 31, 0x01), bytes32(uint256(0x01))); @@ -94,8 +102,9 @@ contract BytesTest is Test { function testSetBytes2() public { bytes32 input = bytes32(0); - // !gasreport set bytes2 in bytes32 + startGasReport("set bytes2 in bytes32"); Bytes.setBytes2(input, 8, 0xffff); + endGasReport(); assertEq(Bytes.setBytes2(input, 0, 0xffff), bytes32(bytes2(0xffff))); assertEq(Bytes.setBytes2(input, 30, 0xffff), bytes32(uint256(0xffff))); @@ -104,8 +113,9 @@ contract BytesTest is Test { function testSetBytes4() public { bytes32 input = bytes32(0); - // !gasreport set bytes4 in bytes32 + startGasReport("set bytes4 in bytes32"); Bytes.setBytes4(input, 8, 0xffffffff); + endGasReport(); assertEq(Bytes.setBytes4(input, 0, 0xffffffff), bytes32(bytes4(0xffffffff))); assertEq(Bytes.setBytes4(input, 30, 0xffffffff), bytes32(uint256(0xffff))); @@ -127,8 +137,9 @@ contract BytesTest is Test { bytes memory input = abi.encodePacked(first, remainder); - // !gasreport set bytes4 in bytes memory + startGasReport("set bytes4 in bytes memory"); bytes memory result = Bytes.setBytes4(input, 0, overwrite); + endGasReport(); // First 4 bytes should be overwritten assertEq(bytes4(result), overwrite); diff --git a/packages/store/test/KeyEncoding.t.sol b/packages/store/test/KeyEncoding.t.sol index 52e6f67b7b..9f6c5f8c03 100644 --- a/packages/store/test/KeyEncoding.t.sol +++ b/packages/store/test/KeyEncoding.t.sol @@ -1,17 +1,19 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { KeyEncoding, KeyEncodingTableId } from "../src/codegen/Tables.sol"; import { ExampleEnum } from "../src/codegen/Types.sol"; import { StoreCore } from "../src/StoreCore.sol"; import { StoreReadWithStubs } from "../src/StoreReadWithStubs.sol"; import { Schema } from "../src/Schema.sol"; -contract KeyEncodingTest is Test, StoreReadWithStubs { +contract KeyEncodingTest is Test, GasReporter, StoreReadWithStubs { function testRegisterAndGetSchema() public { - // !gasreport register KeyEncoding schema + startGasReport("register KeyEncoding schema"); KeyEncoding.registerSchema(); + endGasReport(); Schema registeredSchema = StoreCore.getSchema(KeyEncodingTableId); Schema declaredSchema = KeyEncoding.getSchema(); diff --git a/packages/store/test/Mixed.t.sol b/packages/store/test/Mixed.t.sol index eb9c4ec2d3..93589810f3 100644 --- a/packages/store/test/Mixed.t.sol +++ b/packages/store/test/Mixed.t.sol @@ -1,19 +1,21 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { Mixed, MixedData, MixedTableId } from "../src/codegen/Tables.sol"; import { StoreCore } from "../src/StoreCore.sol"; import { StoreReadWithStubs } from "../src/StoreReadWithStubs.sol"; import { Schema } from "../src/Schema.sol"; -contract MixedTest is Test, StoreReadWithStubs { +contract MixedTest is Test, GasReporter, StoreReadWithStubs { MixedData private testMixed; function testRegisterAndGetSchema() public { - // !gasreport register Mixed schema + startGasReport("register Mixed schema"); Mixed.registerSchema(); + endGasReport(); Schema registeredSchema = StoreCore.getSchema(MixedTableId); Schema declaredSchema = Mixed.getSchema(); @@ -30,11 +32,13 @@ contract MixedTest is Test, StoreReadWithStubs { a32[1] = 4; string memory s = "some string"; - // !gasreport set record in Mixed + startGasReport("set record in Mixed"); Mixed.set({ key: key, u32: 1, u128: 2, a32: a32, s: s }); + endGasReport(); - // !gasreport get record from Mixed + startGasReport("get record from Mixed"); MixedData memory mixed = Mixed.get(key); + endGasReport(); assertEq(mixed.u32, 1); assertEq(mixed.u128, 2); @@ -48,7 +52,8 @@ contract MixedTest is Test, StoreReadWithStubs { mixed.a32[0] = 3; mixed.a32[1] = 4; - // !gasreport store Mixed struct in storage (native solidity) + startGasReport("store Mixed struct in storage (native solidity)"); testMixed = mixed; + endGasReport(); } } diff --git a/packages/store/test/PackedCounter.t.sol b/packages/store/test/PackedCounter.t.sol index 32d6b3afce..542cc55e01 100644 --- a/packages/store/test/PackedCounter.t.sol +++ b/packages/store/test/PackedCounter.t.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { PackedCounter, PackedCounterLib } from "../src/PackedCounter.sol"; -contract PackedCounterTest is Test { +contract PackedCounterTest is Test, GasReporter { function testTotal() public { uint40[] memory counters = new uint40[](4); counters[0] = 1; @@ -12,11 +13,13 @@ contract PackedCounterTest is Test { counters[2] = 3; counters[3] = 4; - // !gasreport pack uint40 array into PackedCounter + startGasReport("pack uint40 array into PackedCounter"); PackedCounter packedCounter = PackedCounterLib.pack(counters); + endGasReport(); - // !gasreport get total of PackedCounter + startGasReport("get total of PackedCounter"); packedCounter.total(); + endGasReport(); assertEq(packedCounter.total(), 10); } @@ -30,8 +33,9 @@ contract PackedCounterTest is Test { PackedCounter packedCounter = PackedCounterLib.pack(counters); - // !gasreport get value at index of PackedCounter + startGasReport("get value at index of PackedCounter"); packedCounter.atIndex(3); + endGasReport(); assertEq(packedCounter.atIndex(0), 1); assertEq(packedCounter.atIndex(1), 2); @@ -48,8 +52,9 @@ contract PackedCounterTest is Test { PackedCounter packedCounter = PackedCounterLib.pack(counters); - // !gasreport set value at index of PackedCounter + startGasReport("set value at index of PackedCounter"); packedCounter = packedCounter.setAtIndex(2, 5); + endGasReport(); assertEq(packedCounter.atIndex(0), 1); assertEq(packedCounter.atIndex(1), 2); diff --git a/packages/store/test/Schema.t.sol b/packages/store/test/Schema.t.sol index ec39e94e21..d197f60116 100644 --- a/packages/store/test/Schema.t.sol +++ b/packages/store/test/Schema.t.sol @@ -1,12 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test, console } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { Schema, SchemaLib } from "../src/Schema.sol"; // TODO add tests for all schema types -contract SchemaTest is Test { +contract SchemaTest is Test, GasReporter { function testEncodeDecodeSchema() public { uint256 gas = gasleft(); Schema schema = SchemaLib.encode( @@ -20,8 +21,9 @@ contract SchemaTest is Test { gas = gas - gasleft(); console.log("GAS REPORT: encode schema with 6 entries [SchemaLib.encode]: %s", gas); - // !gasreport get schema type at index + startGasReport("get schema type at index"); SchemaType schemaType1 = schema.atIndex(0); + endGasReport(); assertEq(uint8(schemaType1), uint8(SchemaType.UINT8)); assertEq(uint8(schema.atIndex(1)), uint8(SchemaType.UINT16)); @@ -137,8 +139,9 @@ contract SchemaTest is Test { SchemaType.UINT32_ARRAY // 0 bytes (because it's dynamic) ); - // !gasreport get static data length from schema + startGasReport("get static data length from schema"); uint256 length = schema.staticDataLength(); + endGasReport(); assertEq(length, 55); } @@ -153,8 +156,9 @@ contract SchemaTest is Test { SchemaType.UINT32_ARRAY // 0 bytes (because it's dynamic) ); - // !gasreport get number of static fields from schema + startGasReport("get number of static fields from schema"); uint256 num = schema.numStaticFields(); + endGasReport(); assertEq(num, 5); } @@ -169,13 +173,14 @@ contract SchemaTest is Test { SchemaType.UINT32_ARRAY // 0 bytes (because it's dynamic) ); - // !gasreport get number of dynamic fields from schema + startGasReport("get number of dynamic fields from schema"); uint256 num = schema.numDynamicFields(); + endGasReport(); assertEq(num, 1); } - function testValidate() public pure { + function testValidate() public { SchemaType[] memory schema = new SchemaType[](28); schema[0] = SchemaType.UINT256; schema[1] = SchemaType.UINT256; @@ -207,8 +212,9 @@ contract SchemaTest is Test { schema[27] = SchemaType.UINT32_ARRAY; Schema encodedSchema = SchemaLib.encode(schema); - // !gasreport validate schema + startGasReport("validate schema"); encodedSchema.validate({ allowEmpty: false }); + endGasReport(); } function testFailValidate() public pure { @@ -219,8 +225,9 @@ contract SchemaTest is Test { SchemaType[] memory schema = new SchemaType[](0); Schema encodedSchema = SchemaLib.encode(schema); - // !gasreport check if schema is empty (empty schema) + startGasReport("check if schema is empty (empty schema)"); bool empty = encodedSchema.isEmpty(); + endGasReport(); assertTrue(empty); } @@ -228,8 +235,9 @@ contract SchemaTest is Test { function testIsEmptyFalse() public { Schema encodedSchema = SchemaLib.encode(SchemaType.UINT256); - // !gasreport check if schema is empty (non-empty schema) + startGasReport("check if schema is empty (non-empty schema)"); bool empty = encodedSchema.isEmpty(); + endGasReport(); assertFalse(empty); } diff --git a/packages/store/test/Slice.t.sol b/packages/store/test/Slice.t.sol index 3535699dfc..e7cd28c856 100644 --- a/packages/store/test/Slice.t.sol +++ b/packages/store/test/Slice.t.sol @@ -1,22 +1,26 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { Memory } from "../src/Memory.sol"; import { Slice, SliceLib } from "../src/Slice.sol"; -contract SliceTest is Test { +contract SliceTest is Test, GasReporter { function testFromBytes() public { bytes memory data = abi.encodePacked(bytes8(0x0102030405060708)); - // !gasreport make Slice from bytes + startGasReport("make Slice from bytes"); Slice slice = SliceLib.fromBytes(data); + endGasReport(); - // !gasreport get Slice length + startGasReport("get Slice length"); slice.length(); + endGasReport(); - // !gasreport get Slice pointer + startGasReport("get Slice pointer"); slice.pointer(); + endGasReport(); assertEq(slice.length(), 8); assertEq(slice.pointer(), Memory.dataPointer(data)); @@ -36,8 +40,9 @@ contract SliceTest is Test { input[31] = 0x02; Slice slice = SliceLib.fromBytes(input); - // !gasreport Slice to bytes32 + startGasReport("Slice to bytes32"); bytes32 output = slice.toBytes32(); + endGasReport(); assertEq(uint256(output), 0x0100000000000000000000000000000000000000000000000000000000000002); } @@ -52,28 +57,34 @@ contract SliceTest is Test { bytes memory data1024x1024 = new bytes(1024 * 1024); slice = SliceLib.fromBytes(data0); - // !gasreport Slice (0 bytes) to bytes memory + startGasReport("Slice (0 bytes) to bytes memory"); bytes memory sliceData0 = slice.toBytes(); + endGasReport(); slice = SliceLib.fromBytes(data2); - // !gasreport Slice (2 bytes) to bytes memory + startGasReport("Slice (2 bytes) to bytes memory"); bytes memory sliceData2 = slice.toBytes(); + endGasReport(); slice = SliceLib.fromBytes(data32); - // !gasreport Slice (32 bytes) to bytes memory + startGasReport("Slice (32 bytes) to bytes memory"); bytes memory sliceData32 = slice.toBytes(); + endGasReport(); slice = SliceLib.fromBytes(data34); - // !gasreport Slice (34 bytes) to bytes memory + startGasReport("Slice (34 bytes) to bytes memory"); bytes memory sliceData34 = slice.toBytes(); + endGasReport(); slice = SliceLib.fromBytes(data1024); - // !gasreport Slice (1024 bytes) to bytes memory + startGasReport("Slice (1024 bytes) to bytes memory"); bytes memory sliceData1024 = slice.toBytes(); + endGasReport(); slice = SliceLib.fromBytes(data1024x1024); - // !gasreport Slice (1024x1024 bytes) to bytes memory + startGasReport("Slice (1024x1024 bytes) to bytes memory"); bytes memory sliceData1024x1024 = slice.toBytes(); + endGasReport(); assertEq(sliceData0, data0); assertEq(sliceData2, data2); @@ -88,11 +99,13 @@ contract SliceTest is Test { bytes memory data2 = hex"0405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f2021222324"; bytes memory data = abi.encodePacked(hex"00", data1, data2); - // !gasreport subslice bytes (no copy) [1:4] + startGasReport("subslice bytes (no copy) [1:4]"); Slice slice1 = SliceLib.getSubslice(data, 1, 1 + 3); + endGasReport(); - // !gasreport subslice bytes (no copy) [4:37] + startGasReport("subslice bytes (no copy) [4:37]"); Slice slice2 = SliceLib.getSubslice(data, 4, 4 + 33); + endGasReport(); assertEq(slice1.length(), 3); assertEq(slice2.length(), 33); diff --git a/packages/store/test/Storage.t.sol b/packages/store/test/Storage.t.sol index 6d98535b20..c6bbcd2908 100644 --- a/packages/store/test/Storage.t.sol +++ b/packages/store/test/Storage.t.sol @@ -1,12 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { Storage } from "../src/Storage.sol"; import { Utils } from "../src/Utils.sol"; import { Bytes } from "../src/Bytes.sol"; -contract StorageTest is Test { +contract StorageTest is Test, GasReporter { function testStoreLoad() public { bytes memory data1 = abi.encodePacked( bytes1(0x01), @@ -26,15 +27,17 @@ contract StorageTest is Test { // First store some data to storage at the target slot and two slots after the target slot - // !gasreport store 1 storage slot + startGasReport("store 1 storage slot"); Storage.store({ storagePointer: storagePointer, data: originalDataFirstSlot }); + endGasReport(); Storage.store({ storagePointer: storagePointerTwoSlotsAfter, data: originalDataLastSlot }); // Then set the target slot, partially overwriting the first and third slot, but using safeTrail and offset - // !gasreport store 34 bytes over 3 storage slots (with offset and safeTrail)) + startGasReport("store 34 bytes over 3 storage slots (with offset and safeTrail))"); Storage.store({ storagePointer: storagePointer, offset: 31, data: data1 }); + endGasReport(); // Assert the first slot has the correct value assertEq( @@ -56,8 +59,9 @@ contract StorageTest is Test { // Assert we can load the correct partial value from storage - // !gasreport load 34 bytes over 3 storage slots (with offset and safeTrail)) + startGasReport("load 34 bytes over 3 storage slots (with offset and safeTrail))"); bytes memory data = Storage.load({ storagePointer: storagePointer, length: 34, offset: 31 }); + endGasReport(); assertEq(Bytes.slice1(data, 0), bytes1(0x01)); assertEq(Bytes.slice32(data, 1), bytes32(0x0200000000000000000000000000000000000000000000000000000000000003)); diff --git a/packages/store/test/StoreCoreDynamic.t.sol b/packages/store/test/StoreCoreDynamic.t.sol index 8dd996187e..b651059ff3 100644 --- a/packages/store/test/StoreCoreDynamic.t.sol +++ b/packages/store/test/StoreCoreDynamic.t.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { Test, console } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { StoreCore } from "../src/StoreCore.sol"; import { SliceLib } from "../src/Slice.sol"; @@ -9,7 +10,7 @@ import { EncodeArray } from "../src/tightcoder/EncodeArray.sol"; import { Schema, SchemaLib } from "../src/Schema.sol"; import { StoreReadWithStubs } from "../src/StoreReadWithStubs.sol"; -contract StoreCoreDynamicTest is Test, StoreReadWithStubs { +contract StoreCoreDynamicTest is Test, GasReporter, StoreReadWithStubs { Schema internal defaultKeySchema = SchemaLib.encode(SchemaType.BYTES32); bytes32[] internal _key; @@ -84,8 +85,9 @@ contract StoreCoreDynamicTest is Test, StoreReadWithStubs { emit StoreSetField(_table, _key, 1, newDataBytes); // Pop from second field - // !gasreport pop from field (cold, 1 slot, 1 uint32 item) + startGasReport("pop from field (cold, 1 slot, 1 uint32 item)"); StoreCore.popFromField(_table, _key, 1, byteLengthToPop); + endGasReport(); // Get second field bytes memory loadedData = StoreCore.getField(_table, _key, 1); // Verify loaded data is correct @@ -93,8 +95,9 @@ contract StoreCoreDynamicTest is Test, StoreReadWithStubs { // Reset the second field and pop again (but warm this time) StoreCore.setField(_table, _key, 1, dataBytes); - // !gasreport pop from field (warm, 1 slot, 1 uint32 item) + startGasReport("pop from field (warm, 1 slot, 1 uint32 item)"); StoreCore.popFromField(_table, _key, 1, byteLengthToPop); + endGasReport(); // Get second field loadedData = StoreCore.getField(_table, _key, 1); // Verify loaded data is correct @@ -120,16 +123,18 @@ contract StoreCoreDynamicTest is Test, StoreReadWithStubs { emit StoreSetField(_table, _key, 2, dataBytes); // Pop from the field - // !gasreport pop from field (cold, 2 slots, 10 uint32 items) + startGasReport("pop from field (cold, 2 slots, 10 uint32 items)"); StoreCore.popFromField(_table, _key, 2, byteLengthToPop); + endGasReport(); // Load and verify the field bytes memory loadedData = StoreCore.getField(_table, _key, 2); assertEq(loadedData, newDataBytes); // Reset the field and pop again (but warm this time) StoreCore.setField(_table, _key, 2, dataBytes); - // !gasreport pop from field (warm, 2 slots, 10 uint32 items) + startGasReport("pop from field (warm, 2 slots, 10 uint32 items)"); StoreCore.popFromField(_table, _key, 2, byteLengthToPop); + endGasReport(); // Load and verify the field loadedData = StoreCore.getField(_table, _key, 2); assertEq(loadedData, newDataBytes); @@ -142,40 +147,48 @@ contract StoreCoreDynamicTest is Test, StoreReadWithStubs { function testGetSecondFieldLength() public { Schema schema = StoreCore.getSchema(_table); - // !gasreport get field length (cold, 1 slot) + startGasReport("get field length (cold, 1 slot)"); uint256 length = StoreCore.getFieldLength(_table, _key, 1, schema); + endGasReport(); assertEq(length, secondDataBytes.length); - // !gasreport get field length (warm, 1 slot) + startGasReport("get field length (warm, 1 slot)"); length = StoreCore.getFieldLength(_table, _key, 1, schema); + endGasReport(); assertEq(length, secondDataBytes.length); } function testGetThirdFieldLength() public { Schema schema = StoreCore.getSchema(_table); - // !gasreport get field length (warm due to , 2 slots) + startGasReport("get field length (warm due to , 2 slots)"); uint256 length = StoreCore.getFieldLength(_table, _key, 2, schema); + endGasReport(); assertEq(length, thirdDataBytes.length); - // !gasreport get field length (warm, 2 slots) + startGasReport("get field length (warm, 2 slots)"); length = StoreCore.getFieldLength(_table, _key, 2, schema); + endGasReport(); assertEq(length, thirdDataBytes.length); } function testGetFieldSlice() public { Schema schema = StoreCore.getSchema(_table); - // !gasreport get field slice (cold, 1 slot) + startGasReport("get field slice (cold, 1 slot)"); bytes memory secondFieldSlice = StoreCore.getFieldSlice(_table, _key, 1, schema, 0, 4); + endGasReport(); assertEq(secondFieldSlice, SliceLib.getSubslice(secondDataBytes, 0, 4).toBytes()); - // !gasreport get field slice (warm, 1 slot) + startGasReport("get field slice (warm, 1 slot)"); secondFieldSlice = StoreCore.getFieldSlice(_table, _key, 1, schema, 4, 8); + endGasReport(); assertEq(secondFieldSlice, SliceLib.getSubslice(secondDataBytes, 4, 8).toBytes()); - // !gasreport get field slice (semi-cold, 1 slot) + startGasReport("get field slice (semi-cold, 1 slot)"); bytes memory thirdFieldSlice = StoreCore.getFieldSlice(_table, _key, 2, schema, 4, 32); + endGasReport(); assertEq(thirdFieldSlice, SliceLib.getSubslice(thirdDataBytes, 4, 32).toBytes()); - // !gasreport get field slice (warm, 2 slots) + startGasReport("get field slice (warm, 2 slots)"); thirdFieldSlice = StoreCore.getFieldSlice(_table, _key, 2, schema, 8, 40); + endGasReport(); assertEq(thirdFieldSlice, SliceLib.getSubslice(thirdDataBytes, 8, 40).toBytes()); } } diff --git a/packages/store/test/StoreCoreGas.t.sol b/packages/store/test/StoreCoreGas.t.sol index 2dbf3d09d4..a05d7257a9 100644 --- a/packages/store/test/StoreCoreGas.t.sol +++ b/packages/store/test/StoreCoreGas.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { StoreCore, StoreCoreInternal } from "../src/StoreCore.sol"; import { Utils } from "../src/Utils.sol"; @@ -23,7 +24,7 @@ struct TestStruct { uint32[] thirdData; } -contract StoreCoreGasTest is Test, StoreMock { +contract StoreCoreGasTest is Test, GasReporter, StoreMock { TestStruct private testStruct; mapping(uint256 => bytes) private testMapping; @@ -34,14 +35,17 @@ contract StoreCoreGasTest is Test, StoreMock { Schema keySchema = SchemaLib.encode(SchemaType.UINT8, SchemaType.UINT16); bytes32 table = keccak256("some.table"); - // !gasreport StoreCore: register schema + startGasReport("StoreCore: register schema"); StoreCore.registerSchema(table, schema, keySchema); + endGasReport(); - // !gasreport StoreCore: get schema (warm) + startGasReport("StoreCore: get schema (warm)"); StoreCore.getSchema(table); + endGasReport(); - // !gasreport StoreCore: get key schema (warm) + startGasReport("StoreCore: get key schema (warm)"); StoreCore.getKeySchema(table); + endGasReport(); } function testHasSchema() public { @@ -50,11 +54,13 @@ contract StoreCoreGasTest is Test, StoreMock { bytes32 table2 = keccak256("other.table"); StoreCore.registerSchema(table, schema, defaultKeySchema); - // !gasreport Check for existence of table (existent) + startGasReport("Check for existence of table (existent)"); StoreCore.hasTable(table); + endGasReport(); - // !gasreport check for existence of table (non-existent) + startGasReport("check for existence of table (non-existent)"); StoreCore.hasTable(table2); + endGasReport(); } function testSetMetadata() public { @@ -69,8 +75,9 @@ contract StoreCoreGasTest is Test, StoreMock { // Register table StoreCore.registerSchema(table, schema, keySchema); - // !gasreport StoreCore: set table metadata + startGasReport("StoreCore: set table metadata"); StoreCore.setMetadata(table, tableName, fieldNames); + endGasReport(); } function testSetAndGetDynamicDataLength() public { @@ -92,16 +99,19 @@ contract StoreCoreGasTest is Test, StoreMock { key[0] = bytes32("some key"); // Set dynamic data length of dynamic index 0 - // !gasreport set dynamic length of dynamic index 0 + startGasReport("set dynamic length of dynamic index 0"); StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 0, 10); + endGasReport(); // Set dynamic data length of dynamic index 1 - // !gasreport set dynamic length of dynamic index 1 + startGasReport("set dynamic length of dynamic index 1"); StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 1, 99); + endGasReport(); // Reduce dynamic data length of dynamic index 0 again - // !gasreport reduce dynamic length of dynamic index 0 + startGasReport("reduce dynamic length of dynamic index 0"); StoreCoreInternal._setDynamicDataLengthAtIndex(table, key, 0, 5); + endGasReport(); } function testSetAndGetStaticData() public { @@ -115,12 +125,14 @@ contract StoreCoreGasTest is Test, StoreMock { bytes32[] memory key = new bytes32[](1); key[0] = keccak256("some.key"); - // !gasreport set static record (1 slot) + startGasReport("set static record (1 slot)"); StoreCore.setRecord(table, key, data); + endGasReport(); // Get data - // !gasreport get static record (1 slot) + startGasReport("get static record (1 slot)"); StoreCore.getRecord(table, key, schema); + endGasReport(); } function testSetAndGetStaticDataSpanningWords() public { @@ -138,12 +150,14 @@ contract StoreCoreGasTest is Test, StoreMock { bytes32[] memory key = new bytes32[](1); key[0] = keccak256("some.key"); - // !gasreport set static record (2 slots) + startGasReport("set static record (2 slots)"); StoreCore.setRecord(table, key, data); + endGasReport(); // Get data - // !gasreport get static record (2 slots) + startGasReport("get static record (2 slots)"); StoreCore.getRecord(table, key, schema); + endGasReport(); } function testSetAndGetDynamicData() public { @@ -195,12 +209,14 @@ contract StoreCoreGasTest is Test, StoreMock { key[0] = bytes32("some.key"); // Set data - // !gasreport set complex record with dynamic data (4 slots) + startGasReport("set complex record with dynamic data (4 slots)"); StoreCore.setRecord(table, key, data); + endGasReport(); // Get data - // !gasreport get complex record with dynamic data (4 slots) + startGasReport("get complex record with dynamic data (4 slots)"); StoreCore.getRecord(table, key); + endGasReport(); // Compare gas - setting the data as raw struct TestStruct memory _testStruct = TestStruct(0, new uint32[](2), new uint32[](3)); @@ -211,11 +227,13 @@ contract StoreCoreGasTest is Test, StoreMock { _testStruct.thirdData[1] = 0x1d1e1f20; _testStruct.thirdData[2] = 0x21222324; - // !gasreport compare: Set complex record with dynamic data using native solidity + startGasReport("compare: Set complex record with dynamic data using native solidity"); testStruct = _testStruct; + endGasReport(); - // !gasreport compare: Set complex record with dynamic data using abi.encode + startGasReport("compare: Set complex record with dynamic data using abi.encode"); testMapping[1234] = abi.encode(_testStruct); + endGasReport(); } function testSetAndGetField() public { @@ -241,27 +259,31 @@ contract StoreCoreGasTest is Test, StoreMock { bytes memory firstDataPacked = abi.encodePacked(firstDataBytes); // Set first field - // !gasreport set static field (1 slot) + startGasReport("set static field (1 slot)"); StoreCore.setField(table, key, 0, firstDataPacked); + endGasReport(); //////////////// // Static data //////////////// // Get first field - // !gasreport get static field (1 slot) + startGasReport("get static field (1 slot)"); StoreCore.getField(table, key, 0); + endGasReport(); // Set second field bytes32 secondDataBytes = keccak256("some data"); bytes memory secondDataPacked = abi.encodePacked(secondDataBytes); - // !gasreport set static field (overlap 2 slot) + startGasReport("set static field (overlap 2 slot)"); StoreCore.setField(table, key, 1, secondDataPacked); + endGasReport(); // Get second field - // !gasreport get static field (overlap 2 slot) + startGasReport("get static field (overlap 2 slot)"); StoreCore.getField(table, key, 1); + endGasReport(); //////////////// // Dynamic data @@ -285,20 +307,24 @@ contract StoreCoreGasTest is Test, StoreMock { } // Set third field - // !gasreport set dynamic field (1 slot, first dynamic field) + startGasReport("set dynamic field (1 slot, first dynamic field)"); StoreCore.setField(table, key, 2, thirdDataBytes); + endGasReport(); // Get third field - // !gasreport get dynamic field (1 slot, first dynamic field) + startGasReport("get dynamic field (1 slot, first dynamic field)"); StoreCore.getField(table, key, 2); + endGasReport(); // Set fourth field - // !gasreport set dynamic field (1 slot, second dynamic field) + startGasReport("set dynamic field (1 slot, second dynamic field)"); StoreCore.setField(table, key, 3, fourthDataBytes); + endGasReport(); // Get fourth field - // !gasreport get dynamic field (1 slot, second dynamic field) + startGasReport("get dynamic field (1 slot, second dynamic field)"); StoreCore.getField(table, key, 3); + endGasReport(); } function testDeleteData() public { @@ -351,8 +377,9 @@ contract StoreCoreGasTest is Test, StoreMock { StoreCore.setRecord(table, key, data); // Delete data - // !gasreport delete record (complex data, 3 slots) + startGasReport("delete record (complex data, 3 slots)"); StoreCore.deleteRecord(table, key); + endGasReport(); } function testPushToField() public { @@ -402,8 +429,9 @@ contract StoreCoreGasTest is Test, StoreMock { bytes memory newSecondDataBytes = abi.encodePacked(secondDataBytes, secondDataToPush); // Push to second field - // !gasreport push to field (1 slot, 1 uint32 item) + startGasReport("push to field (1 slot, 1 uint32 item)"); StoreCore.pushToField(table, key, 1, secondDataToPush); + endGasReport(); // Create data to push bytes memory thirdDataToPush; @@ -423,8 +451,9 @@ contract StoreCoreGasTest is Test, StoreMock { } // Push to third field - // !gasreport push to field (2 slots, 10 uint32 items) + startGasReport("push to field (2 slots, 10 uint32 items)"); StoreCore.pushToField(table, key, 2, thirdDataToPush); + endGasReport(); } function testUpdateInField() public { @@ -473,8 +502,9 @@ contract StoreCoreGasTest is Test, StoreMock { } // Update index 1 in second field (4 = byte length of uint32) - // !gasreport update in field (1 slot, 1 uint32 item) + startGasReport("update in field (1 slot, 1 uint32 item)"); StoreCore.updateInField(table, key, 1, 4 * 1, secondDataForUpdate); + endGasReport(); // Create data for update bytes memory thirdDataForUpdate; @@ -498,8 +528,9 @@ contract StoreCoreGasTest is Test, StoreMock { } // Update indexes 1,2,3,4 in third field (8 = byte length of uint64) - // !gasreport push to field (2 slots, 6 uint64 items) + startGasReport("push to field (2 slots, 6 uint64 items)"); StoreCore.updateInField(table, key, 2, 8 * 1, thirdDataForUpdate); + endGasReport(); } function testAccessEmptyData() public { @@ -512,20 +543,25 @@ contract StoreCoreGasTest is Test, StoreMock { bytes32[] memory key = new bytes32[](1); key[0] = bytes32("some.key"); - // !gasreport access non-existing record + startGasReport("access non-existing record"); StoreCore.getRecord(table, key); + endGasReport(); - // !gasreport access static field of non-existing record + startGasReport("access static field of non-existing record"); StoreCore.getField(table, key, 0); + endGasReport(); - // !gasreport access dynamic field of non-existing record + startGasReport("access dynamic field of non-existing record"); StoreCore.getField(table, key, 1); + endGasReport(); - // !gasreport access length of dynamic field of non-existing record + startGasReport("access length of dynamic field of non-existing record"); StoreCore.getFieldLength(table, key, 1, schema); + endGasReport(); - // !gasreport access slice of dynamic field of non-existing record + startGasReport("access slice of dynamic field of non-existing record"); StoreCore.getFieldSlice(table, key, 1, schema, 0, 0); + endGasReport(); } function testHooks() public { @@ -540,21 +576,25 @@ contract StoreCoreGasTest is Test, StoreMock { // Create subscriber MirrorSubscriber subscriber = new MirrorSubscriber(table, schema, defaultKeySchema); - // !gasreport register subscriber + startGasReport("register subscriber"); StoreCore.registerStoreHook(table, subscriber); + endGasReport(); bytes memory data = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); - // !gasreport set record on table with subscriber + startGasReport("set record on table with subscriber"); StoreCore.setRecord(table, key, data); + endGasReport(); data = abi.encodePacked(bytes16(0x1112131415161718191a1b1c1d1e1f20)); - // !gasreport set static field on table with subscriber + startGasReport("set static field on table with subscriber"); StoreCore.setField(table, key, 0, data); + endGasReport(); - // !gasreport delete record on table with subscriber + startGasReport("delete record on table with subscriber"); StoreCore.deleteRecord(table, key); + endGasReport(); } function testHooksDynamicData() public { @@ -569,8 +609,9 @@ contract StoreCoreGasTest is Test, StoreMock { // Create subscriber MirrorSubscriber subscriber = new MirrorSubscriber(table, schema, defaultKeySchema); - // !gasreport register subscriber + startGasReport("register subscriber"); StoreCore.registerStoreHook(table, subscriber); + endGasReport(); uint32[] memory arrayData = new uint32[](1); arrayData[0] = 0x01020304; @@ -580,8 +621,9 @@ contract StoreCoreGasTest is Test, StoreMock { bytes memory staticData = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); bytes memory data = abi.encodePacked(staticData, dynamicData); - // !gasreport set (dynamic) record on table with subscriber + startGasReport("set (dynamic) record on table with subscriber"); StoreCore.setRecord(table, key, data); + endGasReport(); // Update dynamic data arrayData[0] = 0x11121314; @@ -589,11 +631,13 @@ contract StoreCoreGasTest is Test, StoreMock { dynamicData = abi.encodePacked(encodedArrayDataLength.unwrap(), arrayDataBytes); data = abi.encodePacked(staticData, dynamicData); - // !gasreport set (dynamic) field on table with subscriber + startGasReport("set (dynamic) field on table with subscriber"); StoreCore.setField(table, key, 1, arrayDataBytes); + endGasReport(); - // !gasreport delete (dynamic) record on table with subscriber + startGasReport("delete (dynamic) record on table with subscriber"); StoreCore.deleteRecord(table, key); + endGasReport(); } } diff --git a/packages/store/test/StoreMetadata.t.sol b/packages/store/test/StoreMetadata.t.sol index d3837cb8b0..4d98cc10f1 100644 --- a/packages/store/test/StoreMetadata.t.sol +++ b/packages/store/test/StoreMetadata.t.sol @@ -1,13 +1,14 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { StoreMetadata, StoreMetadataData } from "../src/codegen/Tables.sol"; import { StoreCore } from "../src/StoreCore.sol"; import { StoreReadWithStubs } from "../src/StoreReadWithStubs.sol"; import { Schema } from "../src/Schema.sol"; -contract StoreMetadataTest is Test, StoreReadWithStubs { +contract StoreMetadataTest is Test, GasReporter, StoreReadWithStubs { function testSetAndGet() public { bytes32 tableId = "1"; string memory tableName = "firstTable"; @@ -15,11 +16,13 @@ contract StoreMetadataTest is Test, StoreReadWithStubs { fieldNames[0] = "firstField"; fieldNames[1] = "secondField"; - // !gasreport set record in StoreMetadataTable + startGasReport("set record in StoreMetadataTable"); StoreMetadata.set({ tableId: tableId, tableName: tableName, abiEncodedFieldNames: abi.encode(fieldNames) }); + endGasReport(); - // !gasreport get record from StoreMetadataTable + startGasReport("get record from StoreMetadataTable"); StoreMetadataData memory metadata = StoreMetadata.get(tableId); + endGasReport(); assertEq(metadata.tableName, tableName); assertEq(metadata.abiEncodedFieldNames, abi.encode(fieldNames)); diff --git a/packages/store/test/StoreSwitch.t.sol b/packages/store/test/StoreSwitch.t.sol index f64f299a57..1d186136e7 100644 --- a/packages/store/test/StoreSwitch.t.sol +++ b/packages/store/test/StoreSwitch.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { StoreCore } from "../src/StoreCore.sol"; import { StoreReadWithStubs } from "../src/StoreReadWithStubs.sol"; import { StoreSwitch } from "../src/StoreSwitch.sol"; @@ -24,14 +25,15 @@ contract StoreSwitchTestStore is StoreReadWithStubs { } // Mock system to wrap StoreSwitch.isDelegateCall() -contract MockSystem { - function isDelegateCall() public view returns (bool isDelegate) { - // !gasreport check if delegatecall +contract MockSystem is GasReporter { + function isDelegateCall() public returns (bool isDelegate) { + startGasReport("check if delegatecall"); isDelegate = StoreSwitch.isDelegateCall(); + endGasReport(); } } -contract StoreSwitchTest is Test { +contract StoreSwitchTest is Test, GasReporter { StoreSwitchTestStore store; function setUp() public { diff --git a/packages/store/test/Vector2.t.sol b/packages/store/test/Vector2.t.sol index e21889ee4a..16791ddd8c 100644 --- a/packages/store/test/Vector2.t.sol +++ b/packages/store/test/Vector2.t.sol @@ -1,16 +1,18 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { Vector2, Vector2Data, Vector2TableId } from "../src/codegen/Tables.sol"; import { StoreCore } from "../src/StoreCore.sol"; import { StoreReadWithStubs } from "../src/StoreReadWithStubs.sol"; import { Schema } from "../src/Schema.sol"; -contract Vector2Test is Test, StoreReadWithStubs { +contract Vector2Test is Test, GasReporter, StoreReadWithStubs { function testRegisterAndGetSchema() public { - // !gasreport register Vector2 schema + startGasReport("register Vector2 schema"); Vector2.registerSchema(); + endGasReport(); Schema registeredSchema = StoreCore.getSchema(Vector2TableId); Schema declaredSchema = Vector2.getSchema(); @@ -22,11 +24,13 @@ contract Vector2Test is Test, StoreReadWithStubs { Vector2.registerSchema(); bytes32 key = keccak256("somekey"); - // !gasreport set Vector2 record + startGasReport("set Vector2 record"); Vector2.set({ key: key, x: 1, y: 2 }); + endGasReport(); - // !gasreport get Vector2 record + startGasReport("get Vector2 record"); Vector2Data memory vector = Vector2.get(key); + endGasReport(); assertEq(vector.x, 1); assertEq(vector.y, 2); diff --git a/packages/store/test/tables/Callbacks.t.sol b/packages/store/test/tables/Callbacks.t.sol index a39ab97770..609ee6dedc 100644 --- a/packages/store/test/tables/Callbacks.t.sol +++ b/packages/store/test/tables/Callbacks.t.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { StoreReadWithStubs } from "../../src/StoreReadWithStubs.sol"; import { Callbacks } from "../../src/codegen/Tables.sol"; -contract CallbacksTest is Test, StoreReadWithStubs { +contract CallbacksTest is Test, GasReporter, StoreReadWithStubs { function testSetAndGet() public { Callbacks.registerSchema(); bytes32 key = keccak256("somekey"); @@ -13,17 +14,20 @@ contract CallbacksTest is Test, StoreReadWithStubs { bytes24[] memory callbacks = new bytes24[](1); callbacks[0] = bytes24(abi.encode(this.testSetAndGet)); - // !gasreport set field in Callbacks + startGasReport("set field in Callbacks"); Callbacks.set(key, callbacks); + endGasReport(); - // !gasreport get field from Callbacks (warm) + startGasReport("get field from Callbacks (warm)"); bytes24[] memory returnedCallbacks = Callbacks.get(key); + endGasReport(); assertEq(returnedCallbacks.length, callbacks.length); assertEq(returnedCallbacks[0], callbacks[0]); - // !gasreport push field to Callbacks + startGasReport("push field to Callbacks"); Callbacks.push(key, callbacks[0]); + endGasReport(); returnedCallbacks = Callbacks.get(key); diff --git a/packages/store/test/tables/Hooks.t.sol b/packages/store/test/tables/Hooks.t.sol index 833056b5d5..4f93ced1d0 100644 --- a/packages/store/test/tables/Hooks.t.sol +++ b/packages/store/test/tables/Hooks.t.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { StoreReadWithStubs } from "../../src/StoreReadWithStubs.sol"; import { Hooks } from "../../src/codegen/Tables.sol"; -contract HooksTest is Test, StoreReadWithStubs { +contract HooksTest is Test, GasReporter, StoreReadWithStubs { function testSetAndGet() public { // Hooks schema is already registered by StoreCore bytes32 key = keccak256("somekey"); @@ -13,17 +14,20 @@ contract HooksTest is Test, StoreReadWithStubs { address[] memory addresses = new address[](1); addresses[0] = address(this); - // !gasreport set field in Hooks + startGasReport("set field in Hooks"); Hooks.set(key, addresses); + endGasReport(); - // !gasreport get field from Hooks (warm) + startGasReport("get field from Hooks (warm)"); address[] memory returnedAddresses = Hooks.get(key); + endGasReport(); assertEq(returnedAddresses.length, addresses.length); assertEq(returnedAddresses[0], addresses[0]); - // !gasreport push field to Hooks + startGasReport("push field to Hooks"); Hooks.push(key, addresses[0]); + endGasReport(); returnedAddresses = Hooks.get(key); diff --git a/packages/store/test/tightcoder/DecodeSlice.t.sol b/packages/store/test/tightcoder/DecodeSlice.t.sol index 96e42fb387..7bd2f417b1 100644 --- a/packages/store/test/tightcoder/DecodeSlice.t.sol +++ b/packages/store/test/tightcoder/DecodeSlice.t.sol @@ -1,10 +1,11 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { SliceLib } from "../../src/Slice.sol"; -contract DecodeSliceTest is Test { +contract DecodeSliceTest is Test, GasReporter { function testToBytes32Array() public { bytes memory input = new bytes(64); input[0] = 0x01; @@ -12,8 +13,9 @@ contract DecodeSliceTest is Test { input[32] = 0x03; input[63] = 0x04; - // !gasreport decode packed bytes32[] + startGasReport("decode packed bytes32[]"); bytes32[] memory output = SliceLib.fromBytes(input).decodeArray_bytes32(); + endGasReport(); assertEq(output.length, 2); assertEq(uint256(output[0]), 0x0100000000000000000000000000000000000000000000000000000000000002); @@ -37,8 +39,9 @@ contract DecodeSliceTest is Test { uint32 num2 = 0x05060708; bytes memory input = abi.encodePacked(num1, num2); - // !gasreport decode packed uint32[] + startGasReport("decode packed uint32[]"); uint32[] memory arr = SliceLib.fromBytes(input).decodeArray_uint32(); + endGasReport(); assertEq(arr.length, 2); assertEq(arr[0], num1); diff --git a/packages/store/test/tightcoder/EncodeArray.t.sol b/packages/store/test/tightcoder/EncodeArray.t.sol index 7457a6c9a8..79a1fc4010 100644 --- a/packages/store/test/tightcoder/EncodeArray.t.sol +++ b/packages/store/test/tightcoder/EncodeArray.t.sol @@ -1,11 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { Bytes } from "../../src/Bytes.sol"; import { EncodeArray } from "../../src/tightcoder/EncodeArray.sol"; -contract EncodeArrayTest is Test { +contract EncodeArrayTest is Test, GasReporter { function testEncodeBytesArray() public { bytes[] memory input = new bytes[](2); input[0] = new bytes(32); @@ -15,8 +16,9 @@ contract EncodeArrayTest is Test { input[1][0] = 0x03; input[1][31] = 0x04; - // !gasreport encode packed bytes[] + startGasReport("encode packed bytes[]"); bytes memory output = EncodeArray.encode(input); + endGasReport(); assertEq(output.length, 64); assertEq(uint256(Bytes.toBytes32(output, 0)), 0x0100000000000000000000000000000000000000000000000000000000000002); @@ -30,8 +32,9 @@ contract EncodeArrayTest is Test { input[0] = val0; input[1] = val1; - // !gasreport encode packed uint8[] + startGasReport("encode packed uint8[]"); bytes memory output = EncodeArray.encode(input); + endGasReport(); assertEq(output, abi.encodePacked(val0, val1)); } @@ -45,8 +48,9 @@ contract EncodeArrayTest is Test { input[1] = val1; input[2] = val2; - // !gasreport encode packed uint16[] + startGasReport("encode packed uint16[]"); bytes memory output = EncodeArray.encode(input); + endGasReport(); assertEq(output, abi.encodePacked(val0, val1, val2)); } @@ -58,8 +62,9 @@ contract EncodeArrayTest is Test { input[0] = val0; input[1] = val1; - // !gasreport encode packed uint32[] + startGasReport("encode packed uint32[]"); bytes memory output = EncodeArray.encode(input); + endGasReport(); assertEq(output, abi.encodePacked(val0, val1)); } diff --git a/packages/store/test/tightcoder/TightCoder.t.sol b/packages/store/test/tightcoder/TightCoder.t.sol index fea33f599e..a41dbe48c3 100644 --- a/packages/store/test/tightcoder/TightCoder.t.sol +++ b/packages/store/test/tightcoder/TightCoder.t.sol @@ -1,12 +1,13 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { SliceLib } from "../../src/Slice.sol"; import { EncodeArray } from "../../src/tightcoder/EncodeArray.sol"; -contract TightCoderTest is Test { +contract TightCoderTest is Test, GasReporter { function testFromAndToUint32Array() public { uint32[] memory input = new uint32[](2); input[0] = 0x01020304; @@ -15,8 +16,9 @@ contract TightCoderTest is Test { bytes memory packed = EncodeArray.encode(input); assertEq(packed.length, 8); - // !gasreport decode packed uint32[] + startGasReport("decode packed uint32[]"); uint32[] memory output = SliceLib.fromBytes(packed).decodeArray_uint32(); + endGasReport(); assertEq(output.length, 2); assertEq(output[0], 0x01020304); @@ -28,13 +30,15 @@ contract TightCoderTest is Test { input[0] = bytes24(0x0102030405060708090a0b0c0d0e0f101112131415161718); input[1] = bytes24(0x19202122232425262728292a2b2c2d2e2f30313233343536); - // !gasreport encode packed bytes24[] + startGasReport("encode packed bytes24[]"); bytes memory packed = EncodeArray.encode(input); + endGasReport(); assertEq(packed.length, 48); - // !gasreport decode packed uint32[] + startGasReport("decode packed uint32[]"); bytes24[] memory output = SliceLib.fromBytes(packed).decodeArray_bytes24(); + endGasReport(); assertEq(output.length, 2); assertEq(output[0], input[0]); diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index f40c7f71d5..110a8602f0 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -1,320 +1,320 @@ [ { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testInstallComposite", "name": "install keys in table module", - "functionCall": "world.installRootModule(keysInTableModule, abi.encode(tableId))", - "gasUsed": 1286932 + "gasUsed": 1286949 }, { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testInstallGas", "name": "install keys in table module", - "functionCall": "world.installRootModule(keysInTableModule, abi.encode(tableId))", - "gasUsed": 1286932 + "gasUsed": 1286949 }, { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testInstallGas", "name": "set a record on a table with keysInTableModule installed", - "functionCall": "world.setRecord(namespace, name, keyTuple1, abi.encodePacked(value))", - "gasUsed": 193894 + "gasUsed": 193904 }, { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testInstallSingleton", "name": "install keys in table module", - "functionCall": "world.installRootModule(keysInTableModule, abi.encode(tableId))", - "gasUsed": 1286932 + "gasUsed": 1286949 }, { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testSetAndDeleteRecordHookCompositeGas", "name": "install keys in table module", - "functionCall": "world.installRootModule(keysInTableModule, abi.encode(tableId))", - "gasUsed": 1286932 + "gasUsed": 1286949 }, { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testSetAndDeleteRecordHookCompositeGas", "name": "change a composite record on a table with keysInTableModule installed", - "functionCall": "world.setRecord(namespace, compositeName, keyTupleA, abi.encodePacked(value2))", - "gasUsed": 30066 + "gasUsed": 30071 }, { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testSetAndDeleteRecordHookCompositeGas", "name": "delete a composite record on a table with keysInTableModule installed", - "functionCall": "world.deleteRecord(namespace, compositeName, keyTupleA)", - "gasUsed": 292110 + "gasUsed": 292112 }, { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testSetAndDeleteRecordHookGas", "name": "install keys in table module", - "functionCall": "world.installRootModule(keysInTableModule, abi.encode(tableId))", - "gasUsed": 1286932 + "gasUsed": 1286949 }, { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testSetAndDeleteRecordHookGas", "name": "change a record on a table with keysInTableModule installed", - "functionCall": "world.setRecord(namespace, name, keyTuple1, abi.encodePacked(value2))", - "gasUsed": 28689 + "gasUsed": 28685 }, { - "source": "test/KeysInTableModule.t.sol", + "file": "test/KeysInTableModule.t.sol", + "test": "testSetAndDeleteRecordHookGas", "name": "delete a record on a table with keysInTableModule installed", - "functionCall": "world.deleteRecord(namespace, name, keyTuple1)", - "gasUsed": 153364 + "gasUsed": 153351 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testGetKeysWithValue", "name": "install keys with value module", - "functionCall": "world.installRootModule(keysWithValueModule, abi.encode(sourceTableId))", - "gasUsed": 626500 + "gasUsed": 626517 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testGetKeysWithValue", "name": "Get list of keys with a given value", - "functionCall": "bytes32[] memory keysWithValue = getKeysWithValue(world, sourceTableId, abi.encode(value1))", - "gasUsed": 7654 + "gasUsed": 7715 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testGetTargetTableSelector", "name": "compute the target table selector", - "functionCall": "bytes32 targetTableSelector = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId)", - "gasUsed": 2240 + "gasUsed": 2233 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testInstall", "name": "install keys with value module", - "functionCall": "world.installRootModule(keysWithValueModule, abi.encode(sourceTableId))", - "gasUsed": 626500 + "gasUsed": 626517 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testInstall", "name": "set a record on a table with KeysWithValueModule installed", - "functionCall": "world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value))", - "gasUsed": 165712 + "gasUsed": 165706 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testSetAndDeleteRecordHook", "name": "install keys with value module", - "functionCall": "world.installRootModule(keysWithValueModule, abi.encode(sourceTableId))", - "gasUsed": 626500 + "gasUsed": 626517 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testSetAndDeleteRecordHook", "name": "change a record on a table with KeysWithValueModule installed", - "functionCall": "world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value2))", - "gasUsed": 135364 + "gasUsed": 135358 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testSetAndDeleteRecordHook", "name": "delete a record on a table with KeysWithValueModule installed", - "functionCall": "world.deleteRecord(namespace, sourceName, keyTuple1)", - "gasUsed": 54309 + "gasUsed": 54296 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testSetField", "name": "install keys with value module", - "functionCall": "world.installRootModule(keysWithValueModule, abi.encode(sourceTableId))", - "gasUsed": 626500 + "gasUsed": 626517 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testSetField", "name": "set a field on a table with KeysWithValueModule installed", - "functionCall": "world.setField(namespace, sourceName, keyTuple1, 0, abi.encodePacked(value1))", - "gasUsed": 173726 + "gasUsed": 173711 }, { - "source": "test/KeysWithValueModule.t.sol", + "file": "test/KeysWithValueModule.t.sol", + "test": "testSetField", "name": "change a field on a table with KeysWithValueModule installed", - "functionCall": "world.setField(namespace, sourceName, keyTuple1, 0, abi.encodePacked(value2))", - "gasUsed": 138084 + "gasUsed": 138069 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testCombinedHasHasValueNotQuery", "name": "CombinedHasHasValueNotQuery", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 168826 + "gasUsed": 169287 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testCombinedHasHasValueQuery", "name": "CombinedHasHasValueQuery", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 78844 + "gasUsed": 79069 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testCombinedHasNotQuery", "name": "CombinedHasNotQuery", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 232573 + "gasUsed": 233190 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testCombinedHasQuery", "name": "CombinedHasQuery", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 146143 + "gasUsed": 146483 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testCombinedHasValueNotQuery", "name": "CombinedHasValueNotQuery", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 144801 + "gasUsed": 145185 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testCombinedHasValueQuery", "name": "CombinedHasValueQuery", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 19555 + "gasUsed": 19620 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testHasQuery", "name": "HasQuery", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 33032 + "gasUsed": 33096 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testHasQuery1000Keys", "name": "HasQuery with 1000 keys", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 11272548 + "gasUsed": 11312083 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testHasQuery100Keys", "name": "HasQuery with 100 keys", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 1056092 + "gasUsed": 1060034 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testHasValueQuery", "name": "HasValueQuery", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 9494 + "gasUsed": 9521 }, { - "source": "test/query.t.sol", + "file": "test/query.t.sol", + "test": "testNotValueQuery", "name": "NotValueQuery", - "functionCall": "bytes32[][] memory keyTuples = query(world, fragments)", - "gasUsed": 72026 + "gasUsed": 72250 }, { - "source": "test/SnapSyncModule.t.sol", + "file": "test/SnapSyncModule.t.sol", + "test": "testSnapSyncGas", "name": "Call snap sync on a table with 1 record", - "functionCall": "SyncRecord[] memory records = ISnapSyncSystem(address(world)).snapSync_system_getRecords(tableId, limit, 0)", - "gasUsed": 43813 + "gasUsed": 43864 }, { - "source": "test/SnapSyncModule.t.sol", + "file": "test/SnapSyncModule.t.sol", + "test": "testSnapSyncGas", "name": "Call snap sync on a table with 2 records", - "functionCall": "records = ISnapSyncSystem(address(world)).snapSync_system_getRecords(tableId, limit, 0)", - "gasUsed": 62449 + "gasUsed": 62552 }, { - "source": "test/UniqueEntityModule.t.sol", + "file": "test/UniqueEntityModule.t.sol", + "test": "testInstall", "name": "install unique entity module", - "functionCall": "world.installModule(uniqueEntityModule, new bytes(0))", - "gasUsed": 824012 + "gasUsed": 824002 }, { - "source": "test/UniqueEntityModule.t.sol", + "file": "test/UniqueEntityModule.t.sol", + "test": "testInstall", "name": "get a unique entity nonce (non-root module)", - "functionCall": "uint256 uniqueEntity = uint256(getUniqueEntity(world))", - "gasUsed": 73389 + "gasUsed": 73376 }, { - "source": "test/UniqueEntityModule.t.sol", + "file": "test/UniqueEntityModule.t.sol", + "test": "testInstallRoot", "name": "installRoot unique entity module", - "functionCall": "world.installRootModule(uniqueEntityModule, new bytes(0))", - "gasUsed": 794087 + "gasUsed": 794077 }, { - "source": "test/UniqueEntityModule.t.sol", + "file": "test/UniqueEntityModule.t.sol", + "test": "testInstallRoot", "name": "get a unique entity nonce (root module)", - "functionCall": "uint256 uniqueEntity = uint256(getUniqueEntity(world))", - "gasUsed": 73389 + "gasUsed": 73376 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testDeleteRecord", "name": "Delete record", - "functionCall": "world.deleteRecord(namespace, name, singletonKey)", - "gasUsed": 16152 + "gasUsed": 16148 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testPushToField", "name": "Push data to the table", - "functionCall": "world.pushToField(namespace, name, keyTuple, 0, encodedData)", - "gasUsed": 96514 + "gasUsed": 96510 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testRegisterFallbackSystem", "name": "Register a fallback system", - "functionCall": "bytes4 funcSelector1 = world.registerFunctionSelector(namespace, name, \"\", \"\")", - "gasUsed": 87024 + "gasUsed": 87011 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testRegisterFallbackSystem", "name": "Register a root fallback system", - "functionCall": "bytes4 funcSelector2 = world.registerRootFunctionSelector(namespace, name, worldFunc, 0)", - "gasUsed": 78208 + "gasUsed": 78195 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testRegisterFunctionSelector", "name": "Register a function selector", - "functionCall": "bytes4 functionSelector = world.registerFunctionSelector(namespace, name, \"msgSender\", \"()\")", - "gasUsed": 107622 + "gasUsed": 107606 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testRegisterNamespace", "name": "Register a new namespace", - "functionCall": "world.registerNamespace(\"test\")", - "gasUsed": 161681 + "gasUsed": 161671 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testRegisterRootFunctionSelector", "name": "Register a root function selector", - "functionCall": "bytes4 functionSelector = world.registerRootFunctionSelector(namespace, name, worldFunc, sysFunc)", - "gasUsed": 94114 + "gasUsed": 94098 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testRegisterTable", "name": "Register a new table in the namespace", - "functionCall": "bytes32 tableSelector = world.registerTable(namespace, table, schema, defaultKeySchema)", - "gasUsed": 262408 + "gasUsed": 262386 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testSetField", "name": "Write data to a table field", - "functionCall": "world.setField(namespace, name, singletonKey, 0, abi.encodePacked(true))", - "gasUsed": 44803 + "gasUsed": 44812 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testSetMetadata", "name": "Set metadata", - "functionCall": "world.setMetadata(namespace, name, tableName, fieldNames)", - "gasUsed": 283358 + "gasUsed": 283379 }, { - "source": "test/World.t.sol", + "file": "test/World.t.sol", + "test": "testSetRecord", "name": "Write data to the table", - "functionCall": "Bool.set(world, tableId, true)", "gasUsed": 42692 }, { - "source": "test/WorldDynamicUpdate.t.sol", + "file": "test/WorldDynamicUpdate.t.sol", + "test": "testPopFromField", "name": "pop 1 address (cold)", - "functionCall": "world.popFromField(namespace, name, keyTuple, 0, byteLengthToPop)", - "gasUsed": 38042 + "gasUsed": 38032 }, { - "source": "test/WorldDynamicUpdate.t.sol", + "file": "test/WorldDynamicUpdate.t.sol", + "test": "testPopFromField", "name": "pop 1 address (warm)", - "functionCall": "world.popFromField(namespace, name, keyTuple, 0, byteLengthToPop)", - "gasUsed": 22836 + "gasUsed": 22829 }, { - "source": "test/WorldDynamicUpdate.t.sol", + "file": "test/WorldDynamicUpdate.t.sol", + "test": "testUpdateInField", "name": "updateInField 1 item (cold)", - "functionCall": "world.updateInField(namespace, name, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate))", - "gasUsed": 40376 + "gasUsed": 40361 }, { - "source": "test/WorldDynamicUpdate.t.sol", + "file": "test/WorldDynamicUpdate.t.sol", + "test": "testUpdateInField", "name": "updateInField 1 item (warm)", - "functionCall": "world.updateInField(namespace, name, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate))", - "gasUsed": 25574 + "gasUsed": 25565 } ] diff --git a/packages/world/package.json b/packages/world/package.json index 9a19c9c87c..e53e005648 100644 --- a/packages/world/package.json +++ b/packages/world/package.json @@ -47,7 +47,7 @@ "clean:typechain": "rimraf types", "dev": "tsup --watch", "docs": "rimraf API && hardhat docgen", - "gas-report": "../cli/dist/mud.js gas-report --path test/* --path test/**/* --save gas-report.json", + "gas-report": "../cli/dist/mud.js gas-report --save gas-report.json", "lint": "solhint --config ./.solhint.json 'src/**/*.sol'", "test": "tsc --noEmit && vitest --run && forge test" }, @@ -62,6 +62,7 @@ "zod": "^3.21.4" }, "devDependencies": { + "@latticexyz/std-contracts": "workspace:*", "@typechain/ethers-v5": "^10.2.0", "@types/ejs": "^3.1.1", "@types/glob": "^7.2.0", diff --git a/packages/world/test/KeysInTableModule.t.sol b/packages/world/test/KeysInTableModule.t.sol index 1ff6dada72..51a7ca8b0e 100644 --- a/packages/world/test/KeysInTableModule.t.sol +++ b/packages/world/test/KeysInTableModule.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; @@ -16,7 +17,7 @@ import { KeysInTableModule } from "../src/modules/keysintable/KeysInTableModule. import { getKeysInTable } from "../src/modules/keysintable/getKeysInTable.sol"; import { hasKey } from "../src/modules/keysintable/hasKey.sol"; -contract KeysInTableModuleTest is Test { +contract KeysInTableModuleTest is Test, GasReporter { using ResourceSelector for bytes32; IBaseWorld world; KeysInTableModule keysInTableModule = new KeysInTableModule(); // Modules can be deployed once and installed multiple times @@ -70,8 +71,9 @@ contract KeysInTableModuleTest is Test { // Install the index module // TODO: add support for installing this via installModule // -> requires `callFrom` for the module to be able to register a hook in the name of the original caller - // !gasreport install keys in table module + startGasReport("install keys in table module"); world.installRootModule(keysInTableModule, abi.encode(tableId)); + endGasReport(); world.installRootModule(keysInTableModule, abi.encode(singletonTableId)); world.installRootModule(keysInTableModule, abi.encode(compositeTableId)); } @@ -117,14 +119,16 @@ contract KeysInTableModuleTest is Test { } function testInstallGas() public { + // call fuzzed test manually to get gas report testInstall(val1); } function testInstall(uint256 value) public { _installKeysInTableModule(); // Set a value in the source table - // !gasreport set a record on a table with keysInTableModule installed + startGasReport("set a record on a table with keysInTableModule installed"); world.setRecord(namespace, name, keyTuple1, abi.encodePacked(value)); + endGasReport(); // Get the list of keys in this target table bytes32[][] memory keysInTable = getKeysInTable(world, tableId); @@ -141,8 +145,9 @@ contract KeysInTableModuleTest is Test { keyTuple[0] = keyA; // Set a value in the source table - // !gasreport set a record on a table with keysInTableModule installed + startGasReport("set a record on a table with keysInTableModule installed (first)"); world.setRecord(namespace, name, keyTuple, abi.encodePacked(value1)); + endGasReport(); // Get the list of keys in the first target table bytes32[][] memory keysInTable = getKeysInTable(world, tableId); @@ -160,8 +165,9 @@ contract KeysInTableModuleTest is Test { keyTuple[0] = keyB; // Set a value in the source table - // !gasreport set a record on a table with keysInTableModule installed + startGasReport("set a record on a table with keysInTableModule installed (second)"); world.setRecord(namespace, sourceFile2, keyTuple, abi.encodePacked(value2)); + endGasReport(); // Get the list of keys in the second target table keysInTable = getKeysInTable(world, sourceTableId2); @@ -172,6 +178,7 @@ contract KeysInTableModuleTest is Test { } function testSetAndDeleteRecordHookGas() public { + // call fuzzed test manually to get gas report testSetAndDeleteRecordHook(val1, val2); } @@ -200,8 +207,9 @@ contract KeysInTableModuleTest is Test { assertEq(keysInTable[1][0], key2, "4"); // Change the value of the first key - // !gasreport change a record on a table with keysInTableModule installed + startGasReport("change a record on a table with keysInTableModule installed"); world.setRecord(namespace, name, keyTuple1, abi.encodePacked(value2)); + endGasReport(); // Get the list of keys in the target table keysInTable = getKeysInTable(world, tableId); @@ -212,8 +220,9 @@ contract KeysInTableModuleTest is Test { assertEq(keysInTable[1][0], key2, "7"); // Delete the first key - // !gasreport delete a record on a table with keysInTableModule installed + startGasReport("delete a record on a table with keysInTableModule installed"); world.deleteRecord(namespace, name, keyTuple1); + endGasReport(); // Get the list of keys in the target table keysInTable = getKeysInTable(world, tableId); @@ -224,6 +233,7 @@ contract KeysInTableModuleTest is Test { } function testSetAndDeleteRecordHookCompositeGas() public { + // call fuzzed test manually to get gas report testSetAndDeleteRecordHookComposite(val1, val2); } @@ -268,8 +278,9 @@ contract KeysInTableModuleTest is Test { } // Change the value of the first key - // !gasreport change a composite record on a table with keysInTableModule installed + startGasReport("change a composite record on a table with keysInTableModule installed"); world.setRecord(namespace, compositeName, keyTupleA, abi.encodePacked(value2)); + endGasReport(); // Get the list of keys in the target table keysInTable = getKeysInTable(world, compositeTableId); @@ -284,8 +295,9 @@ contract KeysInTableModuleTest is Test { } // Delete the first key - // !gasreport delete a composite record on a table with keysInTableModule installed + startGasReport("delete a composite record on a table with keysInTableModule installed"); world.deleteRecord(namespace, compositeName, keyTupleA); + endGasReport(); // Get the list of keys in the target table keysInTable = getKeysInTable(world, compositeTableId); @@ -301,8 +313,9 @@ contract KeysInTableModuleTest is Test { _installKeysInTableModule(); // Set a value in the source table - // !gasreport set a field on a table with keysInTableModule installed + startGasReport("set a field on a table with keysInTableModule installed"); world.setField(namespace, name, keyTuple1, 0, abi.encodePacked(value1)); + endGasReport(); // Get the list of keys in the target table bytes32[][] memory keysInTable = getKeysInTable(world, tableId); @@ -312,8 +325,9 @@ contract KeysInTableModuleTest is Test { assertEq(keysInTable[0][0], key1); // Change the value using setField - // !gasreport change a field on a table with keysInTableModule installed + startGasReport("change a field on a table with keysInTableModule installed"); world.setField(namespace, name, keyTuple1, 0, abi.encodePacked(value2)); + endGasReport(); // Get the list of keys in the target table keysInTable = getKeysInTable(world, tableId); @@ -329,8 +343,9 @@ contract KeysInTableModuleTest is Test { // Set a value in the source table world.setRecord(namespace, name, keyTuple1, abi.encodePacked(value1)); - // !gasreport Get list of keys in a given table + startGasReport("Get list of keys in a given table"); bytes32[][] memory keysInTable = getKeysInTable(world, tableId); + endGasReport(); // Assert that the list is correct assertEq(keysInTable.length, 1); diff --git a/packages/world/test/KeysWithValueModule.t.sol b/packages/world/test/KeysWithValueModule.t.sol index 907fba2b76..2a3c0cabf2 100644 --- a/packages/world/test/KeysWithValueModule.t.sol +++ b/packages/world/test/KeysWithValueModule.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; @@ -18,7 +19,7 @@ import { KeysWithValue } from "../src/modules/keyswithvalue/tables/KeysWithValue import { getKeysWithValue } from "../src/modules/keyswithvalue/getKeysWithValue.sol"; import { getTargetTableSelector } from "../src/modules/utils/getTargetTableSelector.sol"; -contract KeysWithValueModuleTest is Test { +contract KeysWithValueModuleTest is Test, GasReporter { using ResourceSelector for bytes32; IBaseWorld world; KeysWithValueModule keysWithValueModule = new KeysWithValueModule(); // Modules can be deployed once and installed multiple times @@ -55,8 +56,9 @@ contract KeysWithValueModuleTest is Test { // Install the index module // TODO: add support for installing this via installModule // -> requires `callFrom` for the module to be able to register a hook in the name of the original caller - // !gasreport install keys with value module + startGasReport("install keys with value module"); world.installRootModule(keysWithValueModule, abi.encode(sourceTableId)); + endGasReport(); } function testInstall() public { @@ -64,8 +66,9 @@ contract KeysWithValueModuleTest is Test { // Set a value in the source table uint256 value = 1; - // !gasreport set a record on a table with KeysWithValueModule installed + startGasReport("set a record on a table with KeysWithValueModule installed"); world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value)); + endGasReport(); // Get the list of entities with this value from the target table bytes32[] memory keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value))); @@ -104,8 +107,9 @@ contract KeysWithValueModuleTest is Test { // Change the value of the first key uint256 value2 = 2; - // !gasreport change a record on a table with KeysWithValueModule installed + startGasReport("change a record on a table with KeysWithValueModule installed"); world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value2)); + endGasReport(); // Get the list of entities with value1 from the target table keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); @@ -122,8 +126,9 @@ contract KeysWithValueModuleTest is Test { assertEq(keysWithValue[0], key1, "8"); // Delete the first key - // !gasreport delete a record on a table with KeysWithValueModule installed + startGasReport("delete a record on a table with KeysWithValueModule installed"); world.deleteRecord(namespace, sourceName, keyTuple1); + endGasReport(); // Get the list of entities with value2 from the target table keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value2))); @@ -138,8 +143,9 @@ contract KeysWithValueModuleTest is Test { // Set a value in the source table uint256 value1 = 1; - // !gasreport set a field on a table with KeysWithValueModule installed + startGasReport("set a field on a table with KeysWithValueModule installed"); world.setField(namespace, sourceName, keyTuple1, 0, abi.encodePacked(value1)); + endGasReport(); // Get the list of entities with value1 from the target table bytes32[] memory keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); @@ -151,8 +157,9 @@ contract KeysWithValueModuleTest is Test { uint256 value2 = 2; // Change the value using setField - // !gasreport change a field on a table with KeysWithValueModule installed + startGasReport("change a field on a table with KeysWithValueModule installed"); world.setField(namespace, sourceName, keyTuple1, 0, abi.encodePacked(value2)); + endGasReport(); // Get the list of entities with value1 from the target table keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); @@ -169,8 +176,9 @@ contract KeysWithValueModuleTest is Test { } function testGetTargetTableSelector() public { - // !gasreport compute the target table selector + startGasReport("compute the target table selector"); bytes32 targetTableSelector = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); + endGasReport(); // The first 8 bytes are the module namespace assertEq(bytes8(targetTableSelector), MODULE_NAMESPACE); @@ -190,8 +198,9 @@ contract KeysWithValueModuleTest is Test { world.setRecord(namespace, sourceName, keyTuple1, abi.encodePacked(value1)); - // !gasreport Get list of keys with a given value + startGasReport("Get list of keys with a given value"); bytes32[] memory keysWithValue = getKeysWithValue(world, sourceTableId, abi.encode(value1)); + endGasReport(); // Assert that the list is correct assertEq(keysWithValue.length, 1); diff --git a/packages/world/test/SnapSyncModule.t.sol b/packages/world/test/SnapSyncModule.t.sol index bfc09a04bd..4209deb0d9 100644 --- a/packages/world/test/SnapSyncModule.t.sol +++ b/packages/world/test/SnapSyncModule.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; @@ -28,7 +29,7 @@ interface ISnapSyncSystem { function snapSync_system_getNumKeysInTable(bytes32 tableId) external view returns (uint256); } -contract SnapSyncModuleTest is Test { +contract SnapSyncModuleTest is Test, GasReporter { using ResourceSelector for bytes32; IBaseWorld world; KeysInTableModule keysInTableModule = new KeysInTableModule(); // Modules can be deployed once and installed multiple times @@ -90,8 +91,9 @@ contract SnapSyncModuleTest is Test { uint256 limit = ISnapSyncSystem(address(world)).snapSync_system_getNumKeysInTable(tableId); - // !gasreport Call snap sync on a table with 1 record + startGasReport("Call snap sync on a table with 1 record"); SyncRecord[] memory records = ISnapSyncSystem(address(world)).snapSync_system_getRecords(tableId, limit, 0); + endGasReport(); // Assert that the list is correct assertEq(records.length, 1); @@ -103,8 +105,9 @@ contract SnapSyncModuleTest is Test { limit = ISnapSyncSystem(address(world)).snapSync_system_getNumKeysInTable(tableId); - // !gasreport Call snap sync on a table with 2 records + startGasReport("Call snap sync on a table with 2 records"); records = ISnapSyncSystem(address(world)).snapSync_system_getRecords(tableId, limit, 0); + endGasReport(); // Assert that the list is correct assertEq(records.length, 2); @@ -137,8 +140,9 @@ contract SnapSyncModuleTest is Test { uint256 limit = syncSystem.snapSync_system_getNumKeysInTable(compositeTableId); - // !gasreport Call snap sync on a table with 1 record + startGasReport("Call snap sync on a table with 1 record"); SyncRecord[] memory records = syncSystem.snapSync_system_getRecords(compositeTableId, limit, 0); + endGasReport(); // Assert that the list is correct assertEq(records.length, 1); @@ -152,8 +156,9 @@ contract SnapSyncModuleTest is Test { limit = syncSystem.snapSync_system_getNumKeysInTable(compositeTableId); - // !gasreport Call snap sync on a table with 2 records + startGasReport("Call snap sync on a table with 2 records"); records = syncSystem.snapSync_system_getRecords(compositeTableId, limit, 0); + endGasReport(); // Assert that the list is correct assertEq(records.length, 2); @@ -184,8 +189,9 @@ contract SnapSyncModuleTest is Test { uint256 limit = syncSystem.snapSync_system_getNumKeysInTable(compositeTableId); - // !gasreport Call snap sync on a table with 1 record + startGasReport("Call snap sync on a table with 1 record"); SyncRecord[] memory records = syncSystem.snapSync_system_getRecords(compositeTableId, limit, 0); + endGasReport(); // Assert that the list is correct assertEq(records.length, 1); @@ -199,8 +205,9 @@ contract SnapSyncModuleTest is Test { limit = syncSystem.snapSync_system_getNumKeysInTable(compositeTableId); - // !gasreport Call snap sync on a table with 2 records + startGasReport("Call snap sync on a table with 2 records"); records = syncSystem.snapSync_system_getRecords(compositeTableId, limit, 0); + endGasReport(); // Assert that the list is correct assertEq(records.length, 2); diff --git a/packages/world/test/UniqueEntityModule.t.sol b/packages/world/test/UniqueEntityModule.t.sol index 031a5af96b..7b8a5dfa73 100644 --- a/packages/world/test/UniqueEntityModule.t.sol +++ b/packages/world/test/UniqueEntityModule.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { World } from "../src/World.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; @@ -15,7 +16,7 @@ import { getUniqueEntity } from "../src/modules/uniqueentity/getUniqueEntity.sol import { NAMESPACE, TABLE_NAME } from "../src/modules/uniqueentity/constants.sol"; import { ResourceSelector } from "../src/ResourceSelector.sol"; -contract UniqueEntityModuleTest is Test { +contract UniqueEntityModuleTest is Test, GasReporter { using ResourceSelector for bytes32; IBaseWorld world; @@ -28,11 +29,13 @@ contract UniqueEntityModuleTest is Test { } function testInstall() public { - // !gasreport install unique entity module + startGasReport("install unique entity module"); world.installModule(uniqueEntityModule, new bytes(0)); + endGasReport(); - // !gasreport get a unique entity nonce (non-root module) + startGasReport("get a unique entity nonce (non-root module)"); uint256 uniqueEntity = uint256(getUniqueEntity(world)); + endGasReport(); // Table must have the same entity set assertEq(UniqueEntity.get(world, tableId), uniqueEntity); @@ -42,11 +45,13 @@ contract UniqueEntityModuleTest is Test { } function testInstallRoot() public { - // !gasreport installRoot unique entity module + startGasReport("installRoot unique entity module"); world.installRootModule(uniqueEntityModule, new bytes(0)); + endGasReport(); - // !gasreport get a unique entity nonce (root module) + startGasReport("get a unique entity nonce (root module)"); uint256 uniqueEntity = uint256(getUniqueEntity(world)); + endGasReport(); // Table must have the same entity set assertEq(UniqueEntity.get(world, tableId), uniqueEntity); diff --git a/packages/world/test/World.t.sol b/packages/world/test/World.t.sol index 69934c922b..be1e3c3349 100644 --- a/packages/world/test/World.t.sol +++ b/packages/world/test/World.t.sol @@ -1,7 +1,9 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; + import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { IStoreHook } from "@latticexyz/store/src/IStore.sol"; @@ -129,7 +131,7 @@ contract WorldTestSystemHook is ISystemHook { } } -contract WorldTest is Test { +contract WorldTest is Test, GasReporter { using ResourceSelector for bytes32; event HelloWorld(); @@ -194,8 +196,9 @@ contract WorldTest is Test { } function testRegisterNamespace() public { - // !gasreport Register a new namespace + startGasReport("Register a new namespace"); world.registerNamespace("test"); + endGasReport(); // Expect the caller to be the namespace owner assertEq(NamespaceOwner.get(world, "test"), address(this), "caller should be namespace owner"); @@ -215,8 +218,9 @@ contract WorldTest is Test { bytes16 namespace = "testNamespace"; bytes16 table = "testTable"; - // !gasreport Register a new table in the namespace + startGasReport("Register a new table in the namespace"); bytes32 tableSelector = world.registerTable(namespace, table, schema, defaultKeySchema); + endGasReport(); // Expect the namespace to be created and owned by the caller assertEq(NamespaceOwner.get(world, namespace), address(this)); @@ -256,8 +260,9 @@ contract WorldTest is Test { // Register a table world.registerTable(namespace, name, schema, defaultKeySchema); - // !gasreport Set metadata + startGasReport("Set metadata"); world.setMetadata(namespace, name, tableName, fieldNames); + endGasReport(); // Expect the metadata to be set StoreMetadataData memory metadata = StoreMetadata.get(world, tableId); @@ -364,8 +369,9 @@ contract WorldTest is Test { // Register a new table bytes32 tableId = world.registerTable("testSetRecord", "testTable", Bool.getSchema(), defaultKeySchema); - // !gasreport Write data to the table + startGasReport("Write data to the table"); Bool.set(world, tableId, true); + endGasReport(); // Expect the data to be written assertTrue(Bool.get(world, tableId)); @@ -386,8 +392,9 @@ contract WorldTest is Test { // Register a new table bytes32 tableId = world.registerTable(namespace, name, Bool.getSchema(), defaultKeySchema); - // !gasreport Write data to a table field + startGasReport("Write data to a table field"); world.setField(namespace, name, singletonKey, 0, abi.encodePacked(true)); + endGasReport(); // Expect the data to be written assertTrue(Bool.get(world, tableId)); @@ -425,8 +432,9 @@ contract WorldTest is Test { dataToPush[2] = address(bytes20(keccak256("another address"))); bytes memory encodedData = EncodeArray.encode(dataToPush); - // !gasreport Push data to the table + startGasReport("Push data to the table"); world.pushToField(namespace, name, keyTuple, 0, encodedData); + endGasReport(); // Expect the data to be written assertEq(AddressArray.get(world, tableId, key), dataToPush); @@ -464,8 +472,9 @@ contract WorldTest is Test { world.setRecord(namespace, name, singletonKey, abi.encodePacked(true)); assertTrue(Bool.get(world, tableId)); - // !gasreport Delete record + startGasReport("Delete record"); world.deleteRecord(namespace, name, singletonKey); + endGasReport(); // expect it to be deleted assertFalse(Bool.get(world, tableId)); @@ -679,8 +688,9 @@ contract WorldTest is Test { WorldTestSystem system = new WorldTestSystem(); world.registerSystem(namespace, name, system, true); - // !gasreport Register a function selector + startGasReport("Register a function selector"); bytes4 functionSelector = world.registerFunctionSelector(namespace, name, "msgSender", "()"); + endGasReport(); string memory expectedWorldFunctionSignature = "testNamespace_testSystem_msgSender()"; bytes4 expectedWorldFunctionSelector = bytes4(keccak256(abi.encodePacked(expectedWorldFunctionSignature))); @@ -719,8 +729,9 @@ contract WorldTest is Test { vm.prank(address(world)); world.registerRootFunctionSelector(namespace, name, "smth", "smth"); - // !gasreport Register a root function selector + startGasReport("Register a root function selector"); bytes4 functionSelector = world.registerRootFunctionSelector(namespace, name, worldFunc, sysFunc); + endGasReport(); assertEq(functionSelector, worldFunc, "wrong function selector returned"); @@ -751,8 +762,9 @@ contract WorldTest is Test { WorldTestSystem system = new WorldTestSystem(); world.registerSystem(namespace, name, system, true); - // !gasreport Register a fallback system + startGasReport("Register a fallback system"); bytes4 funcSelector1 = world.registerFunctionSelector(namespace, name, "", ""); + endGasReport(); // Call the system's fallback function vm.expectEmit(true, true, true, true); @@ -762,8 +774,10 @@ contract WorldTest is Test { bytes4 worldFunc = bytes4(abi.encodeWithSignature("testSelector()")); - // !gasreport Register a root fallback system + startGasReport("Register a root fallback system"); bytes4 funcSelector2 = world.registerRootFunctionSelector(namespace, name, worldFunc, 0); + endGasReport(); + assertEq(funcSelector2, worldFunc, "wrong function selector returned"); // Call the system's fallback function diff --git a/packages/world/test/WorldDynamicUpdate.t.sol b/packages/world/test/WorldDynamicUpdate.t.sol index 49acc675d1..4e8acb9462 100644 --- a/packages/world/test/WorldDynamicUpdate.t.sol +++ b/packages/world/test/WorldDynamicUpdate.t.sol @@ -2,6 +2,8 @@ pragma solidity >=0.8.0; import { Test, console } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; + import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { IStoreHook } from "@latticexyz/store/src/IStore.sol"; @@ -22,7 +24,7 @@ import { CoreModule } from "../src/modules/core/CoreModule.sol"; import { IBaseWorld } from "../src/interfaces/IBaseWorld.sol"; import { IWorldErrors } from "../src/interfaces/IWorldErrors.sol"; -contract UpdateInFieldTest is Test { +contract UpdateInFieldTest is Test, GasReporter { using ResourceSelector for bytes32; event HookCalled(bytes data); @@ -87,8 +89,11 @@ contract UpdateInFieldTest is Test { // Pop 1 item uint256 byteLengthToPop = 20; - // !gasreport pop 1 address (cold) + + startGasReport("pop 1 address (cold)"); world.popFromField(namespace, name, keyTuple, 0, byteLengthToPop); + endGasReport(); + // Expect the data to be updated address[] memory loadedData = AddressArray.get(world, tableId, key); assertEq(loadedData.length, initData.length - 1); @@ -98,8 +103,11 @@ contract UpdateInFieldTest is Test { // Pop 1 more item byteLengthToPop = 20; - // !gasreport pop 1 address (warm) + + startGasReport("pop 1 address (warm)"); world.popFromField(namespace, name, keyTuple, 0, byteLengthToPop); + endGasReport(); + // Expect the data to be updated loadedData = AddressArray.get(world, tableId, key); assertEq(loadedData.length, initData.length - 2); @@ -142,10 +150,14 @@ contract UpdateInFieldTest is Test { // Update index 0 address[] memory dataForUpdate = new address[](1); dataForUpdate[0] = address(bytes20(keccak256("address for update"))); - // !gasreport updateInField 1 item (cold) + + startGasReport("updateInField 1 item (cold)"); world.updateInField(namespace, name, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate)); - // !gasreport updateInField 1 item (warm) + endGasReport(); + + startGasReport("updateInField 1 item (warm)"); world.updateInField(namespace, name, keyTuple, 0, 0, EncodeArray.encode(dataForUpdate)); + endGasReport(); // Expect the data to be updated initData[0] = dataForUpdate[0]; diff --git a/packages/world/test/query.t.sol b/packages/world/test/query.t.sol index 1846228270..45c8e79c1e 100644 --- a/packages/world/test/query.t.sol +++ b/packages/world/test/query.t.sol @@ -1,7 +1,8 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import "forge-std/Test.sol"; +import { Test } from "forge-std/Test.sol"; +import { GasReporter } from "@latticexyz/std-contracts/src/test/GasReporter.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; @@ -16,7 +17,7 @@ import { KeysInTableModule } from "../src/modules/keysintable/KeysInTableModule. import { KeysWithValueModule } from "../src/modules/keyswithvalue/KeysWithValueModule.sol"; import { query, QueryFragment, QueryType } from "../src/modules/keysintable/query.sol"; -contract QueryTest is Test { +contract QueryTest is Test, GasReporter { using ResourceSelector for bytes32; IBaseWorld world; KeysInTableModule keysInTableModule = new KeysInTableModule(); // Modules can be deployed once and installed multiple times @@ -92,8 +93,9 @@ contract QueryTest is Test { QueryFragment[] memory fragments = new QueryFragment[](1); // The value argument is ignored in for Has query fragments fragments[0] = QueryFragment(QueryType.Has, table1, new bytes(0)); - // !gasreport HasQuery + startGasReport("HasQuery"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 2); assertTrue(keyTuples[0][0] == key1[0]); @@ -110,8 +112,9 @@ contract QueryTest is Test { // Query should return all keys in table1 with value 1 QueryFragment[] memory fragments = new QueryFragment[](1); fragments[0] = QueryFragment(QueryType.HasValue, table1, abi.encode(1)); - // !gasreport HasValueQuery + startGasReport("HasValueQuery"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 2); assertTrue(keyTuples[0][0] == key2[0]); @@ -132,8 +135,9 @@ contract QueryTest is Test { QueryFragment[] memory fragments = new QueryFragment[](2); fragments[0] = QueryFragment(QueryType.Has, table1, new bytes(0)); fragments[1] = QueryFragment(QueryType.Has, table2, new bytes(0)); - // !gasreport CombinedHasQuery + startGasReport("CombinedHasQuery"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 2); assertTrue(keyTuples[0][0] == key2[0]); @@ -155,8 +159,9 @@ contract QueryTest is Test { QueryFragment[] memory fragments = new QueryFragment[](2); fragments[0] = QueryFragment(QueryType.HasValue, table1, abi.encode(1)); fragments[1] = QueryFragment(QueryType.HasValue, table2, abi.encode(1)); - // !gasreport CombinedHasValueQuery + startGasReport("CombinedHasValueQuery"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 1); assertTrue(keyTuples[0][0] == key3[0]); @@ -178,8 +183,9 @@ contract QueryTest is Test { QueryFragment[] memory fragments = new QueryFragment[](2); fragments[0] = QueryFragment(QueryType.Has, table1, new bytes(0)); fragments[1] = QueryFragment(QueryType.HasValue, table2, abi.encode(2)); - // !gasreport CombinedHasHasValueQuery + startGasReport("CombinedHasHasValueQuery"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 2); assertTrue(keyTuples[0][0] == key2[0]); @@ -201,8 +207,9 @@ contract QueryTest is Test { QueryFragment[] memory fragments = new QueryFragment[](2); fragments[0] = QueryFragment(QueryType.Has, table2, new bytes(0)); fragments[1] = QueryFragment(QueryType.Not, table1, new bytes(0)); - // !gasreport CombinedHasNotQuery + startGasReport("CombinedHasNotQuery"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 1); assertTrue(keyTuples[0][0] == key4[0]); @@ -224,8 +231,9 @@ contract QueryTest is Test { QueryFragment[] memory fragments = new QueryFragment[](2); fragments[0] = QueryFragment(QueryType.HasValue, table2, abi.encode(1)); fragments[1] = QueryFragment(QueryType.Not, table1, new bytes(0)); - // !gasreport CombinedHasValueNotQuery + startGasReport("CombinedHasValueNotQuery"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 1); assertTrue(keyTuples[0][0] == key4[0]); @@ -251,8 +259,9 @@ contract QueryTest is Test { fragments[0] = QueryFragment(QueryType.Has, table1, new bytes(0)); fragments[1] = QueryFragment(QueryType.HasValue, table2, abi.encode(1)); fragments[2] = QueryFragment(QueryType.Not, table3, new bytes(0)); - // !gasreport CombinedHasHasValueNotQuery + startGasReport("CombinedHasHasValueNotQuery"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 1); assertTrue(keyTuples[0][0] == key1[0]); @@ -270,8 +279,9 @@ contract QueryTest is Test { QueryFragment[] memory fragments = new QueryFragment[](2); fragments[0] = QueryFragment(QueryType.Has, table1, new bytes(0)); fragments[1] = QueryFragment(QueryType.NotValue, table1, abi.encode(6)); - // !gasreport NotValueQuery + startGasReport("NotValueQuery"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 2); assertTrue(keyTuples[0][0] == key1[0]); @@ -292,8 +302,9 @@ contract QueryTest is Test { QueryFragment[] memory fragments = new QueryFragment[](1); // The value argument is ignored in for Has query fragments fragments[0] = QueryFragment(QueryType.Has, table1, new bytes(0)); - // !gasreport HasQuery with 100 keys + startGasReport("HasQuery with 100 keys"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 100); } @@ -312,8 +323,9 @@ contract QueryTest is Test { QueryFragment[] memory fragments = new QueryFragment[](1); // The value argument is ignored in for Has query fragments fragments[0] = QueryFragment(QueryType.Has, table1, new bytes(0)); - // !gasreport HasQuery with 1000 keys + startGasReport("HasQuery with 1000 keys"); bytes32[][] memory keyTuples = query(world, fragments); + endGasReport(); assertTrue(keyTuples.length == 1000); } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c2f4721cd6..15b0a1b6a4 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1085,6 +1085,9 @@ importers: specifier: ^3.21.4 version: 3.21.4 devDependencies: + '@latticexyz/std-contracts': + specifier: workspace:* + version: link:../std-contracts '@typechain/ethers-v5': specifier: ^10.2.0 version: 10.2.0(@ethersproject/abi@5.7.0)(@ethersproject/bytes@5.7.0)(@ethersproject/providers@5.7.2)(ethers@5.7.2)(typechain@8.1.1)(typescript@4.9.5)