From 731cb6a432c40fb1bc6f828c59a45871f9465b54 Mon Sep 17 00:00:00 2001 From: dk1a Date: Tue, 22 Aug 2023 22:15:49 +0300 Subject: [PATCH 01/69] refactor StoreCore --- .../abi/StoreCore.sol/StoreCore.abi.json | 24 ++-- packages/store/src/StoreCore.sol | 103 +++++++++++++----- 2 files changed, 91 insertions(+), 36 deletions(-) diff --git a/packages/store/abi/StoreCore.sol/StoreCore.abi.json b/packages/store/abi/StoreCore.sol/StoreCore.abi.json index 72f144fcd2..d4b2a124f4 100644 --- a/packages/store/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/store/abi/StoreCore.sol/StoreCore.abi.json @@ -58,12 +58,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -71,7 +65,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -80,7 +74,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -89,6 +83,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -96,7 +102,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" } ] \ No newline at end of file diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index f3b5776476..7ecfd1479a 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -16,7 +16,7 @@ import { StoreSwitch } from "./StoreSwitch.sol"; library StoreCore { // note: the preimage of the tuple of keys used to index is part of the event, so it can be used by indexers event StoreSetRecord(bytes32 table, bytes32[] key, bytes data); - event StoreSetField(bytes32 table, bytes32[] key, uint8 schemaIndex, bytes data); + event StoreSpliceRecord(bytes32 tableId, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); event StoreDeleteRecord(bytes32 table, bytes32[] key); event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data); @@ -196,9 +196,6 @@ library StoreCore { bytes memory data, Schema valueSchema ) internal { - // Emit event to notify indexers - emit StoreSetField(tableId, key, schemaIndex, data); - // Call onBeforeSetField hooks (before modifying the state) address[] memory hooks = Hooks.get(tableId); @@ -260,15 +257,12 @@ library StoreCore { revert IStoreErrors.StoreCore_NotDynamicField(); } - // TODO add push-specific event and hook to avoid the storage read? (https://github.com/latticexyz/mud/issues/444) + // TODO add push-specific hook to avoid the storage read? (https://github.com/latticexyz/mud/issues/444) bytes memory fullData = abi.encodePacked( StoreCoreInternal._getDynamicField(tableId, key, schemaIndex, valueSchema), dataToPush ); - // Emit event to notify indexers - emit StoreSetField(tableId, key, schemaIndex, fullData); - // Call onBeforeSetField hooks (before modifying the state) address[] memory hooks = Hooks.get(tableId); for (uint256 i; i < hooks.length; i++) { @@ -299,16 +293,13 @@ library StoreCore { revert IStoreErrors.StoreCore_NotDynamicField(); } - // TODO add pop-specific event and hook to avoid the storage read? (https://github.com/latticexyz/mud/issues/444) + // TODO add pop-specific hook to avoid the storage read? (https://github.com/latticexyz/mud/issues/444) bytes memory fullData; { bytes memory oldData = StoreCoreInternal._getDynamicField(tableId, key, schemaIndex, valueSchema); fullData = SliceLib.getSubslice(oldData, 0, oldData.length - byteLengthToPop).toBytes(); } - // Emit event to notify indexers - emit StoreSetField(tableId, key, schemaIndex, fullData); - // Call onBeforeSetField hooks (before modifying the state) address[] memory hooks = Hooks.get(tableId); for (uint256 i; i < hooks.length; i++) { @@ -345,7 +336,7 @@ library StoreCore { revert IStoreErrors.StoreCore_DataIndexOverflow(type(uint40).max, startByteIndex); } - // TODO add setItem-specific event and hook to avoid the storage read? (https://github.com/latticexyz/mud/issues/444) + // TODO add setItem-specific hook to avoid the storage read? (https://github.com/latticexyz/mud/issues/444) bytes memory fullData; { bytes memory oldData = StoreCoreInternal._getDynamicField(tableId, key, schemaIndex, valueSchema); @@ -356,9 +347,6 @@ library StoreCore { ); } - // Emit event to notify indexers - emit StoreSetField(tableId, key, schemaIndex, fullData); - // Call onBeforeSetField hooks (before modifying the state) address[] memory hooks = Hooks.get(tableId); for (uint256 i; i < hooks.length; i++) { @@ -533,16 +521,16 @@ library StoreCoreInternal { uint8 schemaIndex, bytes memory data ) internal { - // verify the value has the correct length for the field - SchemaType schemaType = valueSchema.atIndex(schemaIndex); - if (schemaType.getStaticByteLength() != data.length) { - revert IStoreErrors.StoreCore_InvalidDataLength(schemaType.getStaticByteLength(), data.length); - } - - // Store the provided value in storage uint256 location = _getStaticDataLocation(tableId, key); uint256 offset = _getStaticDataOffset(valueSchema, schemaIndex); + Storage.store({ storagePointer: location, offset: offset, data: data }); + + // Prepare data for the splice event + uint256 start = offset; + uint256 deleteCount = valueSchema.atIndex(schemaIndex).getStaticByteLength(); + // Emit event to notify indexers + emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), data); } function _setDynamicField( @@ -554,12 +542,32 @@ library StoreCoreInternal { ) internal { uint8 dynamicSchemaIndex = schemaIndex - uint8(valueSchema.numStaticFields()); - // Update the dynamic data length - _setDynamicDataLengthAtIndex(tableId, key, dynamicSchemaIndex, data.length); + // Load dynamic data length from storage + uint256 dynamicSchemaLengthSlot = _getDynamicDataLengthLocation(tableId, key); + PackedCounter encodedLengths = PackedCounter.wrap(Storage.load({ storagePointer: dynamicSchemaLengthSlot })); + + // Update the encoded length + uint256 oldFieldLength = encodedLengths.atIndex(dynamicSchemaIndex); + encodedLengths = encodedLengths.setAtIndex(dynamicSchemaIndex, data.length); + // Set the new lengths + Storage.store({ storagePointer: dynamicSchemaLengthSlot, data: encodedLengths.unwrap() }); // Store the provided value in storage uint256 dynamicDataLocation = _getDynamicDataLocation(tableId, key, dynamicSchemaIndex); Storage.store({ storagePointer: dynamicDataLocation, offset: 0, data: data }); + + // Prepare data for the splice event + uint256 start; + unchecked { + // (safe because it's a few uint40 values, which can't overflow uint48) + start = valueSchema.staticDataLength() + 32; + for (uint8 i; i < dynamicSchemaIndex; i++) { + start += encodedLengths.atIndex(i); + } + } + uint256 deleteCount = oldFieldLength; + // Emit event to notify indexers + emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), data); } function _pushToDynamicField( @@ -578,12 +586,24 @@ library StoreCoreInternal { // Update the encoded length uint256 oldFieldLength = encodedLengths.atIndex(dynamicSchemaIndex); encodedLengths = encodedLengths.setAtIndex(dynamicSchemaIndex, oldFieldLength + dataToPush.length); - // Set the new length Storage.store({ storagePointer: dynamicSchemaLengthSlot, data: encodedLengths.unwrap() }); // Append `dataToPush` to the end of the data in storage _setPartialDynamicData(tableId, key, dynamicSchemaIndex, oldFieldLength, dataToPush); + + // Prepare data for the splice event + uint256 start; + unchecked { + // (safe because it's a few uint40 values, which can't overflow uint48) + start = valueSchema.staticDataLength() + 32 + encodedLengths.atIndex(dynamicSchemaIndex); + for (uint8 i; i < dynamicSchemaIndex; i++) { + start += encodedLengths.atIndex(i); + } + } + uint256 deleteCount = 0; + // Emit event to notify indexers + emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), dataToPush); } function _popFromDynamicField( @@ -602,11 +622,23 @@ library StoreCoreInternal { // Update the encoded length uint256 oldFieldLength = encodedLengths.atIndex(dynamicSchemaIndex); encodedLengths = encodedLengths.setAtIndex(dynamicSchemaIndex, oldFieldLength - byteLengthToPop); - // Set the new length Storage.store({ storagePointer: dynamicSchemaLengthSlot, data: encodedLengths.unwrap() }); // Data can be left unchanged, push/set do not assume storage to be 0s + + // Prepare data for the splice event + uint256 start; + unchecked { + // (safe because it's a few uint40 values, which can't overflow uint48) + start = valueSchema.staticDataLength() + 32 + encodedLengths.atIndex(dynamicSchemaIndex) - byteLengthToPop; + for (uint8 i; i < dynamicSchemaIndex; i++) { + start += encodedLengths.atIndex(i); + } + } + uint256 deleteCount = byteLengthToPop; + // Emit event to notify indexers + emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), new bytes(0)); } // startOffset is measured in bytes @@ -620,8 +652,25 @@ library StoreCoreInternal { ) internal { uint8 dynamicSchemaIndex = schemaIndex - uint8(valueSchema.numStaticFields()); + // Load dynamic data length from storage + uint256 dynamicSchemaLengthSlot = _getDynamicDataLengthLocation(tableId, key); + PackedCounter encodedLengths = PackedCounter.wrap(Storage.load({ storagePointer: dynamicSchemaLengthSlot })); + // Set `dataToSet` at the given index _setPartialDynamicData(tableId, key, dynamicSchemaIndex, startByteIndex, dataToSet); + + // Prepare data for the splice event + uint256 start; + unchecked { + // (safe because it's a few uint40 values, which can't overflow uint48) + start = valueSchema.staticDataLength() + 32 + encodedLengths.atIndex(dynamicSchemaIndex) + startByteIndex; + for (uint8 i; i < dynamicSchemaIndex; i++) { + start += encodedLengths.atIndex(i); + } + } + uint256 deleteCount = dataToSet.length; + // Emit event to notify indexers + emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), dataToSet); } /************************************************************************ From 43d3597b02fe03ab0997e05b9d0792a53eb53466 Mon Sep 17 00:00:00 2001 From: dk1a Date: Wed, 23 Aug 2023 12:39:52 +0300 Subject: [PATCH 02/69] fixes --- packages/store/src/StoreCore.sol | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index 7ecfd1479a..2d52a50d1c 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -596,7 +596,7 @@ library StoreCoreInternal { uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) - start = valueSchema.staticDataLength() + 32 + encodedLengths.atIndex(dynamicSchemaIndex); + start = valueSchema.staticDataLength() + 32 + oldFieldLength; for (uint8 i; i < dynamicSchemaIndex; i++) { start += encodedLengths.atIndex(i); } @@ -631,7 +631,7 @@ library StoreCoreInternal { uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) - start = valueSchema.staticDataLength() + 32 + encodedLengths.atIndex(dynamicSchemaIndex) - byteLengthToPop; + start = valueSchema.staticDataLength() + 32 + oldFieldLength - byteLengthToPop; for (uint8 i; i < dynamicSchemaIndex; i++) { start += encodedLengths.atIndex(i); } @@ -663,7 +663,7 @@ library StoreCoreInternal { uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) - start = valueSchema.staticDataLength() + 32 + encodedLengths.atIndex(dynamicSchemaIndex) + startByteIndex; + start = valueSchema.staticDataLength() + 32 + startByteIndex; for (uint8 i; i < dynamicSchemaIndex; i++) { start += encodedLengths.atIndex(i); } From 3fb3400265f900c6e9e957d5bcca890d6ca3b202 Mon Sep 17 00:00:00 2001 From: dk1a Date: Wed, 23 Aug 2023 13:16:16 +0300 Subject: [PATCH 03/69] refactor StoreCoreTest --- packages/store/src/IStore.sol | 2 +- packages/store/test/StoreCore.t.sol | 83 +++++++++++++++++++++++++---- 2 files changed, 75 insertions(+), 10 deletions(-) diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index cc38319efb..412143d36e 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -45,7 +45,7 @@ interface IStoreRead { interface IStoreWrite { event StoreSetRecord(bytes32 table, bytes32[] key, bytes data); - event StoreSetField(bytes32 table, bytes32[] key, uint8 schemaIndex, bytes data); + event StoreSpliceRecord(bytes32 tableId, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); event StoreDeleteRecord(bytes32 table, bytes32[] key); // Set full record (including full dynamic data) diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index 23fd259c5d..b42ddfd1df 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -354,7 +354,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSetField event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetField(table, key, 0, firstDataPacked); + emit StoreSpliceRecord(table, key, 0, uint40(firstDataPacked.length), firstDataPacked); // Set first field IStore(this).setField(table, key, 0, firstDataPacked, valueSchema); @@ -380,7 +380,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSetField event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetField(table, key, 1, secondDataPacked); + emit StoreSpliceRecord( + table, + key, + uint48(firstDataPacked.length), + uint40(secondDataPacked.length), + secondDataPacked + ); IStore(this).setField(table, key, 1, secondDataPacked, valueSchema); @@ -426,7 +432,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSetField event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetField(table, key, 2, thirdDataBytes); + emit StoreSpliceRecord( + table, + key, + uint48(firstDataPacked.length + secondDataPacked.length + 32), + 0, + thirdDataBytes + ); // Set third field IStore(this).setField(table, key, 2, thirdDataBytes, valueSchema); @@ -448,7 +460,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSetField event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetField(table, key, 3, fourthDataBytes); + emit StoreSpliceRecord( + table, + key, + uint48(firstDataPacked.length + secondDataPacked.length + 32 + thirdDataBytes.length), + 0, + fourthDataBytes + ); // Set fourth field IStore(this).setField(table, key, 3, fourthDataBytes, valueSchema); @@ -468,6 +486,29 @@ contract StoreCoreTest is Test, StoreMock { abi.encodePacked(firstDataBytes, secondDataBytes, encodedLengths.unwrap(), thirdDataBytes, fourthDataBytes) ) ); + + // Set fourth field again, changing it to be equal to third field + // (non-zero deleteCount must be emitted when the array exists) + + // Expect a StoreSetField event to be emitted + vm.expectEmit(true, true, true, true); + emit StoreSpliceRecord( + table, + key, + uint48(firstDataPacked.length + secondDataPacked.length + 32 + thirdDataBytes.length), + uint40(fourthDataBytes.length), + thirdDataBytes + ); + + // Set fourth field + IStore(this).setField(table, key, 3, thirdDataBytes, valueSchema); + + // Get fourth field + loadedData = IStore(this).getField(table, key, 3, valueSchema); + + // Verify loaded data is correct + assertEq(loadedData.length, thirdDataBytes.length); + assertEq(keccak256(loadedData), keccak256(thirdDataBytes)); } function testDeleteData() public { @@ -599,9 +640,15 @@ contract StoreCoreTest is Test, StoreMock { } data.newSecondDataBytes = abi.encodePacked(data.secondDataBytes, data.secondDataToPush); - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetField(data.table, data.key, 1, data.newSecondDataBytes); + emit StoreSpliceRecord( + data.table, + data.key, + uint48(data.firstDataBytes.length + 32 + data.secondDataBytes.length), + 0, + data.secondDataToPush + ); // Push to second field IStore(this).pushToField(data.table, data.key, 1, data.secondDataToPush, valueSchema); @@ -637,7 +684,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSetField event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetField(data.table, data.key, 2, data.newThirdDataBytes); + emit StoreSpliceRecord( + data.table, + data.key, + uint48(data.firstDataBytes.length + 32 + data.newSecondDataBytes.length + data.thirdDataBytes.length), + 0, + data.thirdDataToPush + ); // Push to third field IStore(this).pushToField(data.table, data.key, 2, data.thirdDataToPush, valueSchema); @@ -732,7 +785,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSetField event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetField(data.table, data.key, 1, data.newSecondDataBytes); + emit StoreSpliceRecord( + data.table, + data.key, + uint48(data.firstDataBytes.length + 32 + 4 * 1), + 4 * 1, + data.secondDataForUpdate + ); // Update index 1 in second field (4 = byte length of uint32) IStore(this).updateInField(data.table, data.key, 1, 4 * 1, data.secondDataForUpdate, valueSchema); @@ -770,7 +829,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSetField event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetField(data.table, data.key, 2, data.newThirdDataBytes); + emit StoreSpliceRecord( + data.table, + data.key, + uint48(data.firstDataBytes.length + 32 + data.newSecondDataBytes.length + 8 * 1), + 8 * 4, + data.thirdDataForUpdate + ); // Update indexes 1,2,3,4 in third field (8 = byte length of uint64) IStore(this).updateInField(data.table, data.key, 2, 8 * 1, data.thirdDataForUpdate, valueSchema); From a0da704eefb8f2204fcd507201103ad8a92e16b3 Mon Sep 17 00:00:00 2001 From: dk1a Date: Wed, 23 Aug 2023 14:13:34 +0300 Subject: [PATCH 04/69] refactor StoreCoreDynamicTest --- packages/store/test/StoreCoreDynamic.t.sol | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/packages/store/test/StoreCoreDynamic.t.sol b/packages/store/test/StoreCoreDynamic.t.sol index 8f94084138..088ac77f60 100644 --- a/packages/store/test/StoreCoreDynamic.t.sol +++ b/packages/store/test/StoreCoreDynamic.t.sol @@ -89,7 +89,13 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreReadWithStubs { // Expect a StoreSetField event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetField(_table, _key, 1, newDataBytes); + emit StoreSpliceRecord( + _table, + _key, + uint48(32 + 32 + secondDataBytes.length - byteLengthToPop), + uint40(byteLengthToPop), + new bytes(0) + ); // Pop from second field startGasReport("pop from field (cold, 1 slot, 1 uint32 item)"); @@ -128,7 +134,13 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreReadWithStubs { // Expect a StoreSetField event to be emitted after pop vm.expectEmit(true, true, true, true); - emit StoreSetField(_table, _key, 2, dataBytes); + emit StoreSpliceRecord( + _table, + _key, + uint48(32 + 32 + secondDataBytes.length + thirdDataBytes.length - byteLengthToPop), + uint40(byteLengthToPop), + new bytes(0) + ); // Pop from the field startGasReport("pop from field (cold, 2 slots, 10 uint32 items)"); From d68179c1d7305e813bf1c5bdf8cfe3586b38f6a2 Mon Sep 17 00:00:00 2001 From: dk1a Date: Wed, 23 Aug 2023 14:24:36 +0300 Subject: [PATCH 05/69] build --- .../types/ethers-contracts/IWorld.ts | 56 +++++++++--------- .../factories/IWorld__factory.ts | 24 +++++--- .../types/ethers-contracts/IWorld.ts | 56 +++++++++--------- .../factories/IWorld__factory.ts | 24 +++++--- packages/store/abi/IStore.sol/IStore.abi.json | 24 +++++--- .../store/abi/IStore.sol/IStoreData.abi.json | 24 +++++--- .../store/abi/IStore.sol/IStoreWrite.abi.json | 24 +++++--- .../abi/StoreMock.sol/StoreMock.abi.json | 24 +++++--- .../StoreReadWithStubs.abi.json | 24 +++++--- packages/store/gas-report.json | 58 +++++++++---------- .../AccessManagementSystem.abi.json | 16 ----- .../abi/IBaseWorld.sol/IBaseWorld.abi.json | 24 +++++--- packages/world/abi/IStore.sol/IStore.abi.json | 24 +++++--- .../world/abi/IStore.sol/IStoreData.abi.json | 24 +++++--- .../world/abi/IStore.sol/IStoreWrite.abi.json | 24 +++++--- .../KeysWithValueHook.abi.json | 16 ----- .../abi/StoreCore.sol/StoreCore.abi.json | 24 +++++--- .../UniqueEntitySystem.abi.json | 16 ----- packages/world/abi/World.sol/World.abi.json | 24 +++++--- .../world/abi/src/IStore.sol/IStore.abi.json | 24 +++++--- .../abi/src/IStore.sol/IStoreData.abi.json | 24 +++++--- .../abi/src/IStore.sol/IStoreWrite.abi.json | 24 +++++--- .../abi/src/StoreCore.sol/StoreCore.abi.json | 24 +++++--- packages/world/gas-report.json | 58 +++++++++---------- 24 files changed, 373 insertions(+), 311 deletions(-) diff --git a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts b/e2e/packages/contracts/types/ethers-contracts/IWorld.ts index ff02756749..77710204c7 100644 --- a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts +++ b/e2e/packages/contracts/types/ethers-contracts/IWorld.ts @@ -387,15 +387,15 @@ export interface IWorldInterface extends utils.Interface { "HelloWorld()": EventFragment; "StoreDeleteRecord(bytes32,bytes32[])": EventFragment; "StoreEphemeralRecord(bytes32,bytes32[],bytes)": EventFragment; - "StoreSetField(bytes32,bytes32[],uint8,bytes)": EventFragment; "StoreSetRecord(bytes32,bytes32[],bytes)": EventFragment; + "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)": EventFragment; }; getEvent(nameOrSignatureOrTopic: "HelloWorld"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreDeleteRecord"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreEphemeralRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSetField"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreSetRecord"): EventFragment; + getEvent(nameOrSignatureOrTopic: "StoreSpliceRecord"): EventFragment; } export interface HelloWorldEventObject {} @@ -428,30 +428,32 @@ export type StoreEphemeralRecordEvent = TypedEvent< export type StoreEphemeralRecordEventFilter = TypedEventFilter; -export interface StoreSetFieldEventObject { +export interface StoreSetRecordEventObject { table: string; key: string[]; - schemaIndex: number; data: string; } -export type StoreSetFieldEvent = TypedEvent< - [string, string[], number, string], - StoreSetFieldEventObject +export type StoreSetRecordEvent = TypedEvent< + [string, string[], string], + StoreSetRecordEventObject >; -export type StoreSetFieldEventFilter = TypedEventFilter; +export type StoreSetRecordEventFilter = TypedEventFilter; -export interface StoreSetRecordEventObject { - table: string; +export interface StoreSpliceRecordEventObject { + tableId: string; key: string[]; + start: number; + deleteCount: number; data: string; } -export type StoreSetRecordEvent = TypedEvent< - [string, string[], string], - StoreSetRecordEventObject +export type StoreSpliceRecordEvent = TypedEvent< + [string, string[], number, number, string], + StoreSpliceRecordEventObject >; -export type StoreSetRecordEventFilter = TypedEventFilter; +export type StoreSpliceRecordEventFilter = + TypedEventFilter; export interface IWorld extends BaseContract { connect(signerOrProvider: Signer | Provider | string): this; @@ -1117,29 +1119,31 @@ export interface IWorld extends BaseContract { data?: null ): StoreEphemeralRecordEventFilter; - "StoreSetField(bytes32,bytes32[],uint8,bytes)"( + "StoreSetRecord(bytes32,bytes32[],bytes)"( table?: null, key?: null, - schemaIndex?: null, data?: null - ): StoreSetFieldEventFilter; - StoreSetField( + ): StoreSetRecordEventFilter; + StoreSetRecord( table?: null, key?: null, - schemaIndex?: null, data?: null - ): StoreSetFieldEventFilter; + ): StoreSetRecordEventFilter; - "StoreSetRecord(bytes32,bytes32[],bytes)"( - table?: null, + "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)"( + tableId?: null, key?: null, + start?: null, + deleteCount?: null, data?: null - ): StoreSetRecordEventFilter; - StoreSetRecord( - table?: null, + ): StoreSpliceRecordEventFilter; + StoreSpliceRecord( + tableId?: null, key?: null, + start?: null, + deleteCount?: null, data?: null - ): StoreSetRecordEventFilter; + ): StoreSpliceRecordEventFilter; }; estimateGas: { diff --git a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts index 9fd58269ee..72dd88df05 100644 --- a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ b/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts @@ -314,12 +314,6 @@ const _abi = [ name: "key", type: "bytes32[]", }, - { - indexed: false, - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, { indexed: false, internalType: "bytes", @@ -327,7 +321,7 @@ const _abi = [ type: "bytes", }, ], - name: "StoreSetField", + name: "StoreSetRecord", type: "event", }, { @@ -336,7 +330,7 @@ const _abi = [ { indexed: false, internalType: "bytes32", - name: "table", + name: "tableId", type: "bytes32", }, { @@ -345,6 +339,18 @@ const _abi = [ name: "key", type: "bytes32[]", }, + { + indexed: false, + internalType: "uint48", + name: "start", + type: "uint48", + }, + { + indexed: false, + internalType: "uint40", + name: "deleteCount", + type: "uint40", + }, { indexed: false, internalType: "bytes", @@ -352,7 +358,7 @@ const _abi = [ type: "bytes", }, ], - name: "StoreSetRecord", + name: "StoreSpliceRecord", type: "event", }, { diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts b/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts index f717810764..e34a94f66b 100644 --- a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts +++ b/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts @@ -431,15 +431,15 @@ export interface IWorldInterface extends utils.Interface { "HelloWorld()": EventFragment; "StoreDeleteRecord(bytes32,bytes32[])": EventFragment; "StoreEphemeralRecord(bytes32,bytes32[],bytes)": EventFragment; - "StoreSetField(bytes32,bytes32[],uint8,bytes)": EventFragment; "StoreSetRecord(bytes32,bytes32[],bytes)": EventFragment; + "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)": EventFragment; }; getEvent(nameOrSignatureOrTopic: "HelloWorld"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreDeleteRecord"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreEphemeralRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSetField"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreSetRecord"): EventFragment; + getEvent(nameOrSignatureOrTopic: "StoreSpliceRecord"): EventFragment; } export interface HelloWorldEventObject {} @@ -472,30 +472,32 @@ export type StoreEphemeralRecordEvent = TypedEvent< export type StoreEphemeralRecordEventFilter = TypedEventFilter; -export interface StoreSetFieldEventObject { +export interface StoreSetRecordEventObject { table: string; key: string[]; - schemaIndex: number; data: string; } -export type StoreSetFieldEvent = TypedEvent< - [string, string[], number, string], - StoreSetFieldEventObject +export type StoreSetRecordEvent = TypedEvent< + [string, string[], string], + StoreSetRecordEventObject >; -export type StoreSetFieldEventFilter = TypedEventFilter; +export type StoreSetRecordEventFilter = TypedEventFilter; -export interface StoreSetRecordEventObject { - table: string; +export interface StoreSpliceRecordEventObject { + tableId: string; key: string[]; + start: number; + deleteCount: number; data: string; } -export type StoreSetRecordEvent = TypedEvent< - [string, string[], string], - StoreSetRecordEventObject +export type StoreSpliceRecordEvent = TypedEvent< + [string, string[], number, number, string], + StoreSpliceRecordEventObject >; -export type StoreSetRecordEventFilter = TypedEventFilter; +export type StoreSpliceRecordEventFilter = + TypedEventFilter; export interface IWorld extends BaseContract { connect(signerOrProvider: Signer | Provider | string): this; @@ -1201,29 +1203,31 @@ export interface IWorld extends BaseContract { data?: null ): StoreEphemeralRecordEventFilter; - "StoreSetField(bytes32,bytes32[],uint8,bytes)"( + "StoreSetRecord(bytes32,bytes32[],bytes)"( table?: null, key?: null, - schemaIndex?: null, data?: null - ): StoreSetFieldEventFilter; - StoreSetField( + ): StoreSetRecordEventFilter; + StoreSetRecord( table?: null, key?: null, - schemaIndex?: null, data?: null - ): StoreSetFieldEventFilter; + ): StoreSetRecordEventFilter; - "StoreSetRecord(bytes32,bytes32[],bytes)"( - table?: null, + "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)"( + tableId?: null, key?: null, + start?: null, + deleteCount?: null, data?: null - ): StoreSetRecordEventFilter; - StoreSetRecord( - table?: null, + ): StoreSpliceRecordEventFilter; + StoreSpliceRecord( + tableId?: null, key?: null, + start?: null, + deleteCount?: null, data?: null - ): StoreSetRecordEventFilter; + ): StoreSpliceRecordEventFilter; }; estimateGas: { diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts index c9ac6862ea..26d3491abb 100644 --- a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ b/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts @@ -276,12 +276,6 @@ const _abi = [ name: "key", type: "bytes32[]", }, - { - indexed: false, - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, { indexed: false, internalType: "bytes", @@ -289,7 +283,7 @@ const _abi = [ type: "bytes", }, ], - name: "StoreSetField", + name: "StoreSetRecord", type: "event", }, { @@ -298,7 +292,7 @@ const _abi = [ { indexed: false, internalType: "bytes32", - name: "table", + name: "tableId", type: "bytes32", }, { @@ -307,6 +301,18 @@ const _abi = [ name: "key", type: "bytes32[]", }, + { + indexed: false, + internalType: "uint48", + name: "start", + type: "uint48", + }, + { + indexed: false, + internalType: "uint40", + name: "deleteCount", + type: "uint40", + }, { indexed: false, internalType: "bytes", @@ -314,7 +320,7 @@ const _abi = [ type: "bytes", }, ], - name: "StoreSetRecord", + name: "StoreSpliceRecord", type: "event", }, { diff --git a/packages/store/abi/IStore.sol/IStore.abi.json b/packages/store/abi/IStore.sol/IStore.abi.json index d21e6f935f..22cef0a476 100644 --- a/packages/store/abi/IStore.sol/IStore.abi.json +++ b/packages/store/abi/IStore.sol/IStore.abi.json @@ -164,12 +164,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -177,7 +171,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -186,7 +180,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -195,6 +189,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -202,7 +208,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/store/abi/IStore.sol/IStoreData.abi.json b/packages/store/abi/IStore.sol/IStoreData.abi.json index f02203d5e9..0d74ea9384 100644 --- a/packages/store/abi/IStore.sol/IStoreData.abi.json +++ b/packages/store/abi/IStore.sol/IStoreData.abi.json @@ -33,12 +33,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -46,7 +40,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -55,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -64,6 +58,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -71,7 +77,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/store/abi/IStore.sol/IStoreWrite.abi.json b/packages/store/abi/IStore.sol/IStoreWrite.abi.json index e5a35719c0..283b3fd93b 100644 --- a/packages/store/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/store/abi/IStore.sol/IStoreWrite.abi.json @@ -33,12 +33,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -46,7 +40,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -55,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -64,6 +58,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -71,7 +77,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/store/abi/StoreMock.sol/StoreMock.abi.json b/packages/store/abi/StoreMock.sol/StoreMock.abi.json index cb871d1238..cfe9262c91 100644 --- a/packages/store/abi/StoreMock.sol/StoreMock.abi.json +++ b/packages/store/abi/StoreMock.sol/StoreMock.abi.json @@ -212,12 +212,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -225,7 +219,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -234,7 +228,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -243,6 +237,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -250,7 +256,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json index 46ca3e084b..98799e72e5 100644 --- a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json +++ b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json @@ -206,12 +206,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -219,7 +213,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -228,7 +222,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -237,6 +231,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -244,7 +250,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/store/gas-report.json b/packages/store/gas-report.json index eb66f1e40b..fe353ab261 100644 --- a/packages/store/gas-report.json +++ b/packages/store/gas-report.json @@ -501,25 +501,25 @@ "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (cold, 1 slot, 1 uint32 item)", - "gasUsed": 21684 + "gasUsed": 21791 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (warm, 1 slot, 1 uint32 item)", - "gasUsed": 15714 + "gasUsed": 15828 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (cold, 2 slots, 10 uint32 items)", - "gasUsed": 23433 + "gasUsed": 23988 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (warm, 2 slots, 10 uint32 items)", - "gasUsed": 15464 + "gasUsed": 16025 }, { "file": "test/StoreCoreGas.t.sol", @@ -573,7 +573,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "register subscriber", - "gasUsed": 60289 + "gasUsed": 60669 }, { "file": "test/StoreCoreGas.t.sol", @@ -585,7 +585,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set static field on table with subscriber", - "gasUsed": 26264 + "gasUsed": 26824 }, { "file": "test/StoreCoreGas.t.sol", @@ -597,7 +597,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "register subscriber", - "gasUsed": 60289 + "gasUsed": 60669 }, { "file": "test/StoreCoreGas.t.sol", @@ -609,31 +609,31 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) field on table with subscriber", - "gasUsed": 28200 + "gasUsed": 29058 }, { "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "delete (dynamic) record on table with subscriber", - "gasUsed": 20432 + "gasUsed": 20418 }, { "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (1 slot, 1 uint32 item)", - "gasUsed": 13346 + "gasUsed": 13769 }, { "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (2 slots, 10 uint32 items)", - "gasUsed": 35993 + "gasUsed": 36543 }, { "file": "test/StoreCoreGas.t.sol", "test": "testRegisterAndGetSchema", "name": "StoreCore: register schema", - "gasUsed": 594571 + "gasUsed": 594587 }, { "file": "test/StoreCoreGas.t.sol", @@ -693,7 +693,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set static field (1 slot)", - "gasUsed": 33280 + "gasUsed": 33581 }, { "file": "test/StoreCoreGas.t.sol", @@ -705,7 +705,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set static field (overlap 2 slot)", - "gasUsed": 32157 + "gasUsed": 32457 }, { "file": "test/StoreCoreGas.t.sol", @@ -717,7 +717,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set dynamic field (1 slot, first dynamic field)", - "gasUsed": 54199 + "gasUsed": 54657 }, { "file": "test/StoreCoreGas.t.sol", @@ -729,7 +729,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set dynamic field (1 slot, second dynamic field)", - "gasUsed": 32317 + "gasUsed": 32897 }, { "file": "test/StoreCoreGas.t.sol", @@ -765,13 +765,13 @@ "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "update in field (1 slot, 1 uint32 item)", - "gasUsed": 13623 + "gasUsed": 14796 }, { "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "push to field (2 slots, 6 uint64 items)", - "gasUsed": 14653 + "gasUsed": 15617 }, { "file": "test/StoreSwitch.t.sol", @@ -789,7 +789,7 @@ "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: set field", - "gasUsed": 58202 + "gasUsed": 58641 }, { "file": "test/tables/Callbacks.t.sol", @@ -801,13 +801,13 @@ "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: push 1 element", - "gasUsed": 37654 + "gasUsed": 37755 }, { "file": "test/tables/Hooks.t.sol", "test": "testTable", "name": "Hooks: set field (cold)", - "gasUsed": 60192 + "gasUsed": 60627 }, { "file": "test/tables/Hooks.t.sol", @@ -819,37 +819,37 @@ "file": "test/tables/Hooks.t.sol", "test": "testTable", "name": "Hooks: push 1 element (cold)", - "gasUsed": 37641 + "gasUsed": 37736 }, { "file": "test/tables/Hooks.t.sol", "test": "testTable", "name": "Hooks: pop 1 element (warm)", - "gasUsed": 14110 + "gasUsed": 14226 }, { "file": "test/tables/Hooks.t.sol", "test": "testTable", "name": "Hooks: push 1 element (warm)", - "gasUsed": 15799 + "gasUsed": 15903 }, { "file": "test/tables/Hooks.t.sol", "test": "testTable", "name": "Hooks: update 1 element (warm)", - "gasUsed": 16248 + "gasUsed": 17116 }, { "file": "test/tables/Hooks.t.sol", "test": "testTable", "name": "Hooks: delete record (warm)", - "gasUsed": 9797 + "gasUsed": 9799 }, { "file": "test/tables/Hooks.t.sol", "test": "testTable", "name": "Hooks: set field (warm)", - "gasUsed": 32418 + "gasUsed": 32882 }, { "file": "test/tables/HooksColdLoad.t.sol", @@ -879,13 +879,13 @@ "file": "test/tables/HooksColdLoad.t.sol", "test": "testPop", "name": "Hooks: pop 1 element (cold)", - "gasUsed": 24231 + "gasUsed": 24668 }, { "file": "test/tables/HooksColdLoad.t.sol", "test": "testUpdate", "name": "Hooks: update 1 element (cold)", - "gasUsed": 25821 + "gasUsed": 26975 }, { "file": "test/tightcoder/DecodeSlice.t.sol", diff --git a/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json b/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json index e9c1bdf054..acee40969e 100644 --- a/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json +++ b/packages/world/abi/AccessManagementSystem.sol/AccessManagementSystem.abi.json @@ -63,22 +63,6 @@ "name": "Slice_OutOfBounds", "type": "error" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - } - ], - "name": "StoreCore_InvalidDataLength", - "type": "error" - }, { "inputs": [ { diff --git a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json index a71695ddf8..57b7f10b1a 100644 --- a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json +++ b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json @@ -263,12 +263,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -276,7 +270,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -285,7 +279,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -294,6 +288,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -301,7 +307,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/world/abi/IStore.sol/IStore.abi.json b/packages/world/abi/IStore.sol/IStore.abi.json index d21e6f935f..22cef0a476 100644 --- a/packages/world/abi/IStore.sol/IStore.abi.json +++ b/packages/world/abi/IStore.sol/IStore.abi.json @@ -164,12 +164,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -177,7 +171,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -186,7 +180,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -195,6 +189,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -202,7 +208,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/world/abi/IStore.sol/IStoreData.abi.json b/packages/world/abi/IStore.sol/IStoreData.abi.json index f02203d5e9..0d74ea9384 100644 --- a/packages/world/abi/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/IStore.sol/IStoreData.abi.json @@ -33,12 +33,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -46,7 +40,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -55,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -64,6 +58,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -71,7 +77,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/world/abi/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/IStore.sol/IStoreWrite.abi.json index e5a35719c0..283b3fd93b 100644 --- a/packages/world/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/IStore.sol/IStoreWrite.abi.json @@ -33,12 +33,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -46,7 +40,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -55,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -64,6 +58,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -71,7 +77,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json b/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json index cba5bb5b68..661dc02db1 100644 --- a/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json +++ b/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json @@ -47,22 +47,6 @@ "name": "Slice_OutOfBounds", "type": "error" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - } - ], - "name": "StoreCore_InvalidDataLength", - "type": "error" - }, { "inputs": [], "name": "StoreCore_NotDynamicField", diff --git a/packages/world/abi/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/StoreCore.sol/StoreCore.abi.json index 72f144fcd2..d4b2a124f4 100644 --- a/packages/world/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/StoreCore.sol/StoreCore.abi.json @@ -58,12 +58,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -71,7 +65,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -80,7 +74,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -89,6 +83,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -96,7 +102,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" } ] \ No newline at end of file diff --git a/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json b/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json index ea11319630..a791155749 100644 --- a/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json +++ b/packages/world/abi/UniqueEntitySystem.sol/UniqueEntitySystem.abi.json @@ -47,22 +47,6 @@ "name": "Slice_OutOfBounds", "type": "error" }, - { - "inputs": [ - { - "internalType": "uint256", - "name": "expected", - "type": "uint256" - }, - { - "internalType": "uint256", - "name": "received", - "type": "uint256" - } - ], - "name": "StoreCore_InvalidDataLength", - "type": "error" - }, { "inputs": [], "name": "getUniqueEntity", diff --git a/packages/world/abi/World.sol/World.abi.json b/packages/world/abi/World.sol/World.abi.json index 852942f8fc..68e1aedcbc 100644 --- a/packages/world/abi/World.sol/World.abi.json +++ b/packages/world/abi/World.sol/World.abi.json @@ -286,12 +286,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -299,7 +293,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -308,7 +302,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -317,6 +311,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -324,7 +330,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/world/abi/src/IStore.sol/IStore.abi.json b/packages/world/abi/src/IStore.sol/IStore.abi.json index d21e6f935f..22cef0a476 100644 --- a/packages/world/abi/src/IStore.sol/IStore.abi.json +++ b/packages/world/abi/src/IStore.sol/IStore.abi.json @@ -164,12 +164,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -177,7 +171,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -186,7 +180,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -195,6 +189,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -202,7 +208,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreData.abi.json b/packages/world/abi/src/IStore.sol/IStoreData.abi.json index f02203d5e9..0d74ea9384 100644 --- a/packages/world/abi/src/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreData.abi.json @@ -33,12 +33,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -46,7 +40,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -55,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -64,6 +58,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -71,7 +77,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json index e5a35719c0..283b3fd93b 100644 --- a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json @@ -33,12 +33,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -46,7 +40,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -55,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -64,6 +58,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -71,7 +77,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" }, { diff --git a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json index 72f144fcd2..d4b2a124f4 100644 --- a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json @@ -58,12 +58,6 @@ "name": "key", "type": "bytes32[]" }, - { - "indexed": false, - "internalType": "uint8", - "name": "schemaIndex", - "type": "uint8" - }, { "indexed": false, "internalType": "bytes", @@ -71,7 +65,7 @@ "type": "bytes" } ], - "name": "StoreSetField", + "name": "StoreSetRecord", "type": "event" }, { @@ -80,7 +74,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "table", + "name": "tableId", "type": "bytes32" }, { @@ -89,6 +83,18 @@ "name": "key", "type": "bytes32[]" }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, { "indexed": false, "internalType": "bytes", @@ -96,7 +102,7 @@ "type": "bytes" } ], - "name": "StoreSetRecord", + "name": "StoreSpliceRecord", "type": "event" } ] \ No newline at end of file diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index dff4daad5e..d7e43bd954 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -3,31 +3,31 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallComposite", "name": "install keys in table module", - "gasUsed": 1411022 + "gasUsed": 1412561 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "install keys in table module", - "gasUsed": 1411022 + "gasUsed": 1412561 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "set a record on a table with keysInTableModule installed", - "gasUsed": 182044 + "gasUsed": 182454 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallSingleton", "name": "install keys in table module", - "gasUsed": 1411022 + "gasUsed": 1412561 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "install keys in table module", - "gasUsed": 1411022 + "gasUsed": 1412561 }, { "file": "test/KeysInTableModule.t.sol", @@ -39,13 +39,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "delete a composite record on a table with keysInTableModule installed", - "gasUsed": 250709 + "gasUsed": 254540 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "install keys in table module", - "gasUsed": 1411022 + "gasUsed": 1412561 }, { "file": "test/KeysInTableModule.t.sol", @@ -57,13 +57,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "delete a record on a table with keysInTableModule installed", - "gasUsed": 128910 + "gasUsed": 130153 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "install keys with value module", - "gasUsed": 650020 + "gasUsed": 651827 }, { "file": "test/KeysWithValueModule.t.sol", @@ -81,25 +81,25 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "install keys with value module", - "gasUsed": 650020 + "gasUsed": 651827 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "set a record on a table with KeysWithValueModule installed", - "gasUsed": 151544 + "gasUsed": 151954 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "install keys with value module", - "gasUsed": 650020 + "gasUsed": 651827 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "change a record on a table with KeysWithValueModule installed", - "gasUsed": 118016 + "gasUsed": 118870 }, { "file": "test/KeysWithValueModule.t.sol", @@ -111,19 +111,19 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "install keys with value module", - "gasUsed": 650020 + "gasUsed": 651827 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "set a field on a table with KeysWithValueModule installed", - "gasUsed": 158488 + "gasUsed": 159162 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "change a field on a table with KeysWithValueModule installed", - "gasUsed": 120746 + "gasUsed": 121420 }, { "file": "test/query.t.sol", @@ -195,25 +195,25 @@ "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "install unique entity module", - "gasUsed": 721265 + "gasUsed": 723194 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "get a unique entity nonce (non-root module)", - "gasUsed": 65023 + "gasUsed": 65313 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "installRoot unique entity module", - "gasUsed": 700336 + "gasUsed": 702265 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "get a unique entity nonce (root module)", - "gasUsed": 65023 + "gasUsed": 65313 }, { "file": "test/World.t.sol", @@ -225,7 +225,7 @@ "file": "test/World.t.sol", "test": "testPushToField", "name": "Push data to the table", - "gasUsed": 91408 + "gasUsed": 91825 }, { "file": "test/World.t.sol", @@ -249,7 +249,7 @@ "file": "test/World.t.sol", "test": "testRegisterNamespace", "name": "Register a new namespace", - "gasUsed": 139839 + "gasUsed": 140670 }, { "file": "test/World.t.sol", @@ -261,42 +261,42 @@ "file": "test/World.t.sol", "test": "testRegisterTable", "name": "Register a new table in the namespace", - "gasUsed": 649941 + "gasUsed": 651036 }, { "file": "test/World.t.sol", "test": "testSetField", "name": "Write data to a table field", - "gasUsed": 40733 + "gasUsed": 41026 }, { "file": "test/World.t.sol", "test": "testSetRecord", "name": "Write data to the table", - "gasUsed": 39596 + "gasUsed": 39889 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (cold)", - "gasUsed": 31108 + "gasUsed": 30892 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (warm)", - "gasUsed": 17898 + "gasUsed": 18005 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (cold)", - "gasUsed": 33520 + "gasUsed": 34352 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (warm)", - "gasUsed": 20724 + "gasUsed": 21556 } ] From 5b2c8437653105e4d85f7862f116cc9ce262ddfe Mon Sep 17 00:00:00 2001 From: dk1a Date: Wed, 23 Aug 2023 15:12:16 +0300 Subject: [PATCH 06/69] update comments and storeEvents --- packages/store/test/StoreCore.t.sol | 16 ++++++++-------- packages/store/test/StoreCoreDynamic.t.sol | 4 ++-- packages/store/ts/storeEvents.ts | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index b42ddfd1df..303c50e416 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -352,7 +352,7 @@ contract StoreCoreTest is Test, StoreMock { bytes memory firstDataPacked = abi.encodePacked(firstDataBytes); - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); emit StoreSpliceRecord(table, key, 0, uint40(firstDataPacked.length), firstDataPacked); @@ -378,7 +378,7 @@ contract StoreCoreTest is Test, StoreMock { bytes memory secondDataPacked = abi.encodePacked(secondDataBytes); - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); emit StoreSpliceRecord( table, @@ -430,7 +430,7 @@ contract StoreCoreTest is Test, StoreMock { fourthDataBytes = EncodeArray.encode(fourthData); } - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); emit StoreSpliceRecord( table, @@ -458,7 +458,7 @@ contract StoreCoreTest is Test, StoreMock { assertEq(bytes16(IStore(this).getField(table, key, 0, valueSchema)), bytes16(firstDataBytes)); assertEq(bytes32(IStore(this).getField(table, key, 1, valueSchema)), bytes32(secondDataBytes)); - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); emit StoreSpliceRecord( table, @@ -490,7 +490,7 @@ contract StoreCoreTest is Test, StoreMock { // Set fourth field again, changing it to be equal to third field // (non-zero deleteCount must be emitted when the array exists) - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); emit StoreSpliceRecord( table, @@ -682,7 +682,7 @@ contract StoreCoreTest is Test, StoreMock { } data.newThirdDataBytes = abi.encodePacked(data.thirdDataBytes, data.thirdDataToPush); - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); emit StoreSpliceRecord( data.table, @@ -783,7 +783,7 @@ contract StoreCoreTest is Test, StoreMock { data.newSecondDataBytes = abi.encodePacked(data.secondData[0], _secondDataForUpdate[0]); } - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); emit StoreSpliceRecord( data.table, @@ -827,7 +827,7 @@ contract StoreCoreTest is Test, StoreMock { ); } - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); emit StoreSpliceRecord( data.table, diff --git a/packages/store/test/StoreCoreDynamic.t.sol b/packages/store/test/StoreCoreDynamic.t.sol index 088ac77f60..c423599641 100644 --- a/packages/store/test/StoreCoreDynamic.t.sol +++ b/packages/store/test/StoreCoreDynamic.t.sol @@ -87,7 +87,7 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreReadWithStubs { assertEq(SliceLib.fromBytes(dataBytes).decodeArray_uint32().length, 2); assertEq(SliceLib.fromBytes(newDataBytes).decodeArray_uint32().length, 2 - 1); - // Expect a StoreSetField event to be emitted + // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); emit StoreSpliceRecord( _table, @@ -132,7 +132,7 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreReadWithStubs { assertEq(SliceLib.fromBytes(dataBytes).decodeArray_uint32().length, 10); assertEq(SliceLib.fromBytes(newDataBytes).decodeArray_uint32().length, 10 - 10); - // Expect a StoreSetField event to be emitted after pop + // Expect a StoreSpliceRecord event to be emitted after pop vm.expectEmit(true, true, true, true); emit StoreSpliceRecord( _table, diff --git a/packages/store/ts/storeEvents.ts b/packages/store/ts/storeEvents.ts index f65d884db5..5b62c40fb2 100644 --- a/packages/store/ts/storeEvents.ts +++ b/packages/store/ts/storeEvents.ts @@ -1,6 +1,6 @@ export const storeEvents = [ "event StoreDeleteRecord(bytes32 table, bytes32[] key)", - "event StoreSetField(bytes32 table, bytes32[] key, uint8 schemaIndex, bytes data)", + "event StoreSpliceRecord(bytes32 tableId, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", "event StoreSetRecord(bytes32 table, bytes32[] key, bytes data)", "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data)", ] as const; From d6cbd1d3db2a940d37c27363fecb9063668763b6 Mon Sep 17 00:00:00 2001 From: dk1a Date: Wed, 23 Aug 2023 17:58:13 +0300 Subject: [PATCH 07/69] tableId to table --- packages/store/abi/IStore.sol/IStore.abi.json | 2 +- packages/store/abi/IStore.sol/IStoreData.abi.json | 2 +- packages/store/abi/IStore.sol/IStoreWrite.abi.json | 2 +- packages/store/abi/StoreCore.sol/StoreCore.abi.json | 2 +- packages/store/abi/StoreMock.sol/StoreMock.abi.json | 2 +- .../abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json | 2 +- packages/store/src/IStore.sol | 2 +- packages/store/src/StoreCore.sol | 2 +- packages/store/ts/storeEvents.ts | 2 +- packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json | 2 +- packages/world/abi/IStore.sol/IStore.abi.json | 2 +- packages/world/abi/IStore.sol/IStoreData.abi.json | 2 +- packages/world/abi/IStore.sol/IStoreWrite.abi.json | 2 +- packages/world/abi/StoreCore.sol/StoreCore.abi.json | 2 +- packages/world/abi/World.sol/World.abi.json | 2 +- packages/world/abi/src/IStore.sol/IStore.abi.json | 2 +- packages/world/abi/src/IStore.sol/IStoreData.abi.json | 2 +- packages/world/abi/src/IStore.sol/IStoreWrite.abi.json | 2 +- packages/world/abi/src/StoreCore.sol/StoreCore.abi.json | 2 +- 19 files changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/store/abi/IStore.sol/IStore.abi.json b/packages/store/abi/IStore.sol/IStore.abi.json index 22cef0a476..e97ea7b3ea 100644 --- a/packages/store/abi/IStore.sol/IStore.abi.json +++ b/packages/store/abi/IStore.sol/IStore.abi.json @@ -180,7 +180,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/store/abi/IStore.sol/IStoreData.abi.json b/packages/store/abi/IStore.sol/IStoreData.abi.json index 0d74ea9384..372e736223 100644 --- a/packages/store/abi/IStore.sol/IStoreData.abi.json +++ b/packages/store/abi/IStore.sol/IStoreData.abi.json @@ -49,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/store/abi/IStore.sol/IStoreWrite.abi.json b/packages/store/abi/IStore.sol/IStoreWrite.abi.json index 283b3fd93b..99291b1b64 100644 --- a/packages/store/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/store/abi/IStore.sol/IStoreWrite.abi.json @@ -49,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/store/abi/StoreCore.sol/StoreCore.abi.json b/packages/store/abi/StoreCore.sol/StoreCore.abi.json index d4b2a124f4..7fe6a0f6a4 100644 --- a/packages/store/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/store/abi/StoreCore.sol/StoreCore.abi.json @@ -74,7 +74,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/store/abi/StoreMock.sol/StoreMock.abi.json b/packages/store/abi/StoreMock.sol/StoreMock.abi.json index cfe9262c91..47d285541e 100644 --- a/packages/store/abi/StoreMock.sol/StoreMock.abi.json +++ b/packages/store/abi/StoreMock.sol/StoreMock.abi.json @@ -228,7 +228,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json index 98799e72e5..7ba4a520c3 100644 --- a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json +++ b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json @@ -222,7 +222,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index 412143d36e..1e47df5392 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -45,7 +45,7 @@ interface IStoreRead { interface IStoreWrite { event StoreSetRecord(bytes32 table, bytes32[] key, bytes data); - event StoreSpliceRecord(bytes32 tableId, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); + event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); event StoreDeleteRecord(bytes32 table, bytes32[] key); // Set full record (including full dynamic data) diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index 2d52a50d1c..b8e825fad6 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -16,7 +16,7 @@ import { StoreSwitch } from "./StoreSwitch.sol"; library StoreCore { // note: the preimage of the tuple of keys used to index is part of the event, so it can be used by indexers event StoreSetRecord(bytes32 table, bytes32[] key, bytes data); - event StoreSpliceRecord(bytes32 tableId, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); + event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); event StoreDeleteRecord(bytes32 table, bytes32[] key); event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data); diff --git a/packages/store/ts/storeEvents.ts b/packages/store/ts/storeEvents.ts index 5b62c40fb2..3f4bfcbf76 100644 --- a/packages/store/ts/storeEvents.ts +++ b/packages/store/ts/storeEvents.ts @@ -1,6 +1,6 @@ export const storeEvents = [ "event StoreDeleteRecord(bytes32 table, bytes32[] key)", - "event StoreSpliceRecord(bytes32 tableId, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", + "event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", "event StoreSetRecord(bytes32 table, bytes32[] key, bytes data)", "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data)", ] as const; diff --git a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json index 57b7f10b1a..50290ffb7a 100644 --- a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json +++ b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json @@ -279,7 +279,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/world/abi/IStore.sol/IStore.abi.json b/packages/world/abi/IStore.sol/IStore.abi.json index 22cef0a476..e97ea7b3ea 100644 --- a/packages/world/abi/IStore.sol/IStore.abi.json +++ b/packages/world/abi/IStore.sol/IStore.abi.json @@ -180,7 +180,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/world/abi/IStore.sol/IStoreData.abi.json b/packages/world/abi/IStore.sol/IStoreData.abi.json index 0d74ea9384..372e736223 100644 --- a/packages/world/abi/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/IStore.sol/IStoreData.abi.json @@ -49,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/world/abi/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/IStore.sol/IStoreWrite.abi.json index 283b3fd93b..99291b1b64 100644 --- a/packages/world/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/IStore.sol/IStoreWrite.abi.json @@ -49,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/world/abi/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/StoreCore.sol/StoreCore.abi.json index d4b2a124f4..7fe6a0f6a4 100644 --- a/packages/world/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/StoreCore.sol/StoreCore.abi.json @@ -74,7 +74,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/world/abi/World.sol/World.abi.json b/packages/world/abi/World.sol/World.abi.json index 68e1aedcbc..5473871c5b 100644 --- a/packages/world/abi/World.sol/World.abi.json +++ b/packages/world/abi/World.sol/World.abi.json @@ -302,7 +302,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/world/abi/src/IStore.sol/IStore.abi.json b/packages/world/abi/src/IStore.sol/IStore.abi.json index 22cef0a476..e97ea7b3ea 100644 --- a/packages/world/abi/src/IStore.sol/IStore.abi.json +++ b/packages/world/abi/src/IStore.sol/IStore.abi.json @@ -180,7 +180,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreData.abi.json b/packages/world/abi/src/IStore.sol/IStoreData.abi.json index 0d74ea9384..372e736223 100644 --- a/packages/world/abi/src/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreData.abi.json @@ -49,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json index 283b3fd93b..99291b1b64 100644 --- a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json @@ -49,7 +49,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { diff --git a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json index d4b2a124f4..7fe6a0f6a4 100644 --- a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json @@ -74,7 +74,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "tableId", + "name": "table", "type": "bytes32" }, { From cdca045b5a2859cf85af5d9d955342910a72e364 Mon Sep 17 00:00:00 2001 From: dk1a Date: Thu, 24 Aug 2023 14:36:28 +0300 Subject: [PATCH 08/69] hacky recs sync --- .../store-sync/src/blockLogsToStorage.test.ts | 29 ++++++++++------- packages/store-sync/src/blockLogsToStorage.ts | 16 ++++------ packages/store-sync/src/common.ts | 16 +++++----- packages/store-sync/src/recs/recsStorage.ts | 31 +++++++++++++------ 4 files changed, 51 insertions(+), 41 deletions(-) diff --git a/packages/store-sync/src/blockLogsToStorage.test.ts b/packages/store-sync/src/blockLogsToStorage.test.ts index f40d569831..9e6ccd2b38 100644 --- a/packages/store-sync/src/blockLogsToStorage.test.ts +++ b/packages/store-sync/src/blockLogsToStorage.test.ts @@ -104,10 +104,11 @@ describe("blockLogsToStorage", () => { "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", ], - schemaIndex: 0, data: "0x00000008", + start: 0, + deleteCount: 4, }, - eventName: "StoreSetField", + eventName: "StoreSpliceRecord", }, ], }); @@ -121,8 +122,8 @@ describe("blockLogsToStorage", () => { "operations": [ { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "fieldName": "amount", - "fieldValue": 8, + "data": "0x00000008", + "deleteCount": 4, "key": { "item": 1, "itemVariant": 1, @@ -132,18 +133,19 @@ describe("blockLogsToStorage", () => { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "args": { "data": "0x00000008", + "deleteCount": 4, "key": [ "0x000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f60", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", ], - "schemaIndex": 0, + "start": 0, "table": "0x00000000000000000000000000000000496e76656e746f727900000000000000", }, "blockHash": "0x03e962e7402b2ab295b92feac342a132111dd14b0d1fd4d4a0456fdc77981577", "blockNumber": 5448n, "data": "0x00000000000000000000000000000000496e76656e746f7279000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000", - "eventName": "StoreSetField", + "eventName": "StoreSpliceRecord", "logIndex": 88, "removed": false, "topics": [ @@ -154,7 +156,8 @@ describe("blockLogsToStorage", () => { }, "name": "Inventory", "namespace": "", - "type": "SetField", + "start": 0, + "type": "SpliceRecord", }, ], }, @@ -175,8 +178,8 @@ describe("blockLogsToStorage", () => { "operations": [ { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "fieldName": "amount", - "fieldValue": 8, + "data": "0x00000008", + "deleteCount": 4, "key": { "item": 1, "itemVariant": 1, @@ -186,18 +189,19 @@ describe("blockLogsToStorage", () => { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "args": { "data": "0x00000008", + "deleteCount": 4, "key": [ "0x000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f60", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x0000000000000000000000000000000000000000000000000000000000000001", ], - "schemaIndex": 0, + "start": 0, "table": "0x00000000000000000000000000000000496e76656e746f727900000000000000", }, "blockHash": "0x03e962e7402b2ab295b92feac342a132111dd14b0d1fd4d4a0456fdc77981577", "blockNumber": 5448n, "data": "0x00000000000000000000000000000000496e76656e746f7279000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000", - "eventName": "StoreSetField", + "eventName": "StoreSpliceRecord", "logIndex": 88, "removed": false, "topics": [ @@ -208,7 +212,8 @@ describe("blockLogsToStorage", () => { }, "name": "Inventory", "namespace": "", - "type": "SetField", + "start": 0, + "type": "SpliceRecord", }, ], } diff --git a/packages/store-sync/src/blockLogsToStorage.ts b/packages/store-sync/src/blockLogsToStorage.ts index 41658a5ceb..cb165bbd8a 100644 --- a/packages/store-sync/src/blockLogsToStorage.ts +++ b/packages/store-sync/src/blockLogsToStorage.ts @@ -1,4 +1,4 @@ -import { decodeField, decodeKeyTuple, decodeRecord, abiTypesToSchema, hexToSchema } from "@latticexyz/protocol-parser"; +import { decodeKeyTuple, decodeRecord, abiTypesToSchema, hexToSchema } from "@latticexyz/protocol-parser"; import { StoreConfig, ConfigToKeyPrimitives as Key, @@ -151,21 +151,17 @@ export function blockLogsToStorage({ }; } - if (log.eventName === "StoreSetField") { - const fieldName = fieldNames[log.args.schemaIndex] as string & keyof Value; - const fieldValue = decodeField(valueAbiTypes[log.args.schemaIndex], log.args.data) as Value< - TConfig, - keyof TConfig["tables"] - >[typeof fieldName]; + if (log.eventName === "StoreSpliceRecord") { return { log, address: getAddress(log.address), namespace: table.namespace, name: table.name, - type: "SetField", + type: "SpliceRecord", key, - fieldName, - fieldValue, + data: log.args.data, + start: log.args.start, + deleteCount: log.args.deleteCount, }; } diff --git a/packages/store-sync/src/common.ts b/packages/store-sync/src/common.ts index 31c54689ff..220ec8e261 100644 --- a/packages/store-sync/src/common.ts +++ b/packages/store-sync/src/common.ts @@ -50,18 +50,16 @@ export type SetRecordOperation = BaseStorageOperati }; }[keyof TConfig["tables"]]; -export type SetFieldOperation = BaseStorageOperation & { - type: "SetField"; +export type SpliceRecordOperation = BaseStorageOperation & { + type: "SpliceRecord"; } & { [TTable in keyof TConfig["tables"]]: { name: TTable & string; key: Key; - } & { - [TValue in keyof Value]: { - fieldName: TValue & string; - fieldValue: Value[TValue]; - }; - }[keyof Value]; + data: Hex; + start: number; + deleteCount: number; + }; }[keyof TConfig["tables"]]; export type DeleteRecordOperation = BaseStorageOperation & { @@ -74,7 +72,7 @@ export type DeleteRecordOperation = BaseStorageOper }[keyof TConfig["tables"]]; export type StorageOperation = - | SetFieldOperation + | SpliceRecordOperation | SetRecordOperation | DeleteRecordOperation; diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index 71cee4dd4e..155dfe07a3 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -8,7 +8,6 @@ import { getComponentValue, removeComponent, setComponent, - updateComponent, } from "@latticexyz/recs"; import { isDefined } from "@latticexyz/common/utils"; import { schemaToDefaults } from "../schemaToDefaults"; @@ -17,6 +16,9 @@ import { getTableEntity } from "./getTableEntity"; import { StoreComponentMetadata } from "./common"; import { tableIdToHex } from "@latticexyz/common"; import { encodeEntity } from "./encodeEntity"; +import { abiTypesToSchema, decodeRecord, encodeRecord } from "@latticexyz/protocol-parser"; +import { DynamicPrimitiveType, StaticPrimitiveType } from "@latticexyz/schema-type"; +import { concat, size, slice } from "viem"; export function recsStorage({ components, @@ -71,16 +73,25 @@ export function recsStorage({ if (operation.type === "SetRecord") { debug("setting component", tableId, entity, operation.value); setComponent(component, entity, operation.value as ComponentValue); - } else if (operation.type === "SetField") { - debug("updating component", tableId, entity, { - [operation.fieldName]: operation.fieldValue, - }); - updateComponent( - component, - entity, - { [operation.fieldName]: operation.fieldValue } as ComponentValue, - schemaToDefaults(table.valueSchema) as ComponentValue + } else if (operation.type === "SpliceRecord") { + const schema = abiTypesToSchema(Object.values(table.valueSchema)); + const oldValueTuple = Object.values( + getComponentValue(component, entity) ?? schemaToDefaults(table.valueSchema) ); + const oldRecord = encodeRecord(schema, oldValueTuple as (StaticPrimitiveType | DynamicPrimitiveType)[]); + const end = operation.start + operation.deleteCount; + const newRecord = concat([ + slice(oldRecord, 0, operation.start), + operation.data, + end >= size(oldRecord) ? "0x" : slice(oldRecord, end), + ]); + const newValueTuple = decodeRecord(schema, newRecord); + + const fieldNames = Object.keys(table.valueSchema); + const value = Object.fromEntries(fieldNames.map((name, i) => [name, newValueTuple[i]])); + + debug("setting component (splice)", tableId, entity, newRecord); + setComponent(component, entity, value); } else if (operation.type === "DeleteRecord") { debug("deleting component", tableId, entity); removeComponent(component, entity); From e896029c0fd8386529a1f53767634f4aa2838063 Mon Sep 17 00:00:00 2001 From: dk1a Date: Thu, 24 Aug 2023 15:04:19 +0300 Subject: [PATCH 09/69] build --- e2e/packages/contracts/types/ethers-contracts/IWorld.ts | 6 +++--- .../types/ethers-contracts/factories/IWorld__factory.ts | 2 +- e2e/packages/contracts/worlds.json | 2 +- .../packages/contracts/types/ethers-contracts/IWorld.ts | 6 +++--- .../types/ethers-contracts/factories/IWorld__factory.ts | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts b/e2e/packages/contracts/types/ethers-contracts/IWorld.ts index 77710204c7..056ab39403 100644 --- a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts +++ b/e2e/packages/contracts/types/ethers-contracts/IWorld.ts @@ -441,7 +441,7 @@ export type StoreSetRecordEvent = TypedEvent< export type StoreSetRecordEventFilter = TypedEventFilter; export interface StoreSpliceRecordEventObject { - tableId: string; + table: string; key: string[]; start: number; deleteCount: number; @@ -1131,14 +1131,14 @@ export interface IWorld extends BaseContract { ): StoreSetRecordEventFilter; "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)"( - tableId?: null, + table?: null, key?: null, start?: null, deleteCount?: null, data?: null ): StoreSpliceRecordEventFilter; StoreSpliceRecord( - tableId?: null, + table?: null, key?: null, start?: null, deleteCount?: null, diff --git a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts index 72dd88df05..0b6de66f86 100644 --- a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ b/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts @@ -330,7 +330,7 @@ const _abi = [ { indexed: false, internalType: "bytes32", - name: "tableId", + name: "table", type: "bytes32", }, { diff --git a/e2e/packages/contracts/worlds.json b/e2e/packages/contracts/worlds.json index caf66719c4..67719d6d7e 100644 --- a/e2e/packages/contracts/worlds.json +++ b/e2e/packages/contracts/worlds.json @@ -1,5 +1,5 @@ { "31337": { - "address": "0xAA292E8611aDF267e563f334Ee42320aC96D0463" + "address": "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" } } \ No newline at end of file diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts b/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts index e34a94f66b..10b802d104 100644 --- a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts +++ b/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts @@ -485,7 +485,7 @@ export type StoreSetRecordEvent = TypedEvent< export type StoreSetRecordEventFilter = TypedEventFilter; export interface StoreSpliceRecordEventObject { - tableId: string; + table: string; key: string[]; start: number; deleteCount: number; @@ -1215,14 +1215,14 @@ export interface IWorld extends BaseContract { ): StoreSetRecordEventFilter; "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)"( - tableId?: null, + table?: null, key?: null, start?: null, deleteCount?: null, data?: null ): StoreSpliceRecordEventFilter; StoreSpliceRecord( - tableId?: null, + table?: null, key?: null, start?: null, deleteCount?: null, diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts index 26d3491abb..f68d1a393f 100644 --- a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ b/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts @@ -292,7 +292,7 @@ const _abi = [ { indexed: false, internalType: "bytes32", - name: "tableId", + name: "table", type: "bytes32", }, { From 07f3828834ff1b46d5b858b6c899bfc2cc80cc9a Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 1 Sep 2023 18:43:45 +0100 Subject: [PATCH 10/69] start refactoring storage adapters to be schemaless --- .../src/groupLogsByBlockNumber.ts | 2 +- packages/common/src/type-utils/common.ts | 2 + packages/protocol-parser/src/common.ts | 17 +- packages/protocol-parser/src/decodeKey.ts | 15 ++ .../protocol-parser/src/decodeKeyTuple.ts | 1 + packages/protocol-parser/src/decodeRecord.ts | 1 + packages/protocol-parser/src/decodeValue.ts | 16 ++ packages/protocol-parser/src/encodeRecord.ts | 1 + packages/protocol-parser/src/encodeValue.ts | 18 ++ packages/protocol-parser/src/index.ts | 3 + .../store-sync/src/blockLogsToStorage.test.ts | 217 ------------------ packages/store-sync/src/blockLogsToStorage.ts | 179 --------------- packages/store-sync/src/common.ts | 86 +++---- packages/store-sync/src/createStoreSync.ts | 87 ++++--- packages/store-sync/src/index.ts | 1 - .../store-sync/src/isTableRegistrationLog.ts | 7 + packages/store-sync/src/logToTable.ts | 41 ++++ packages/store-sync/src/recs/common.ts | 3 +- packages/store-sync/src/recs/decodeEntity.ts | 5 +- packages/store-sync/src/recs/encodeEntity.ts | 6 +- .../store-sync/src/recs/getTableEntity.ts | 2 +- packages/store-sync/src/recs/recsStorage.ts | 128 +++++------ packages/store-sync/src/recs/syncToRecs.ts | 4 +- packages/store-sync/src/schemaToDefaults.ts | 2 +- packages/store/ts/common.ts | 15 +- packages/store/ts/storeEvents.ts | 4 +- 26 files changed, 283 insertions(+), 580 deletions(-) create mode 100644 packages/protocol-parser/src/decodeKey.ts create mode 100644 packages/protocol-parser/src/decodeValue.ts create mode 100644 packages/protocol-parser/src/encodeValue.ts delete mode 100644 packages/store-sync/src/blockLogsToStorage.test.ts delete mode 100644 packages/store-sync/src/blockLogsToStorage.ts create mode 100644 packages/store-sync/src/isTableRegistrationLog.ts create mode 100644 packages/store-sync/src/logToTable.ts diff --git a/packages/block-logs-stream/src/groupLogsByBlockNumber.ts b/packages/block-logs-stream/src/groupLogsByBlockNumber.ts index e0d2f1144e..b0656acfbc 100644 --- a/packages/block-logs-stream/src/groupLogsByBlockNumber.ts +++ b/packages/block-logs-stream/src/groupLogsByBlockNumber.ts @@ -4,7 +4,7 @@ import { bigIntSort, isDefined } from "@latticexyz/common/utils"; type PartialLog = { blockNumber: bigint; logIndex: number }; export type GroupLogsByBlockNumberResult = { - blockNumber: BlockNumber; + blockNumber: TLog["blockNumber"]; logs: TLog[]; }[]; diff --git a/packages/common/src/type-utils/common.ts b/packages/common/src/type-utils/common.ts index 2e7d66225c..e75f5054dc 100644 --- a/packages/common/src/type-utils/common.ts +++ b/packages/common/src/type-utils/common.ts @@ -19,3 +19,5 @@ export type OrDefaults = { }; export type UnionOmit = T extends any ? Omit : never; +export type UnionKeys = T extends any ? keyof T : never; +export type UnionPick> = T extends any ? Pick> : never; diff --git a/packages/protocol-parser/src/common.ts b/packages/protocol-parser/src/common.ts index ba9cc72a69..9ff1790395 100644 --- a/packages/protocol-parser/src/common.ts +++ b/packages/protocol-parser/src/common.ts @@ -1,11 +1,26 @@ -import { DynamicAbiType, StaticAbiType } from "@latticexyz/schema-type"; +import { DynamicAbiType, SchemaAbiType, SchemaAbiTypeToPrimitiveType, StaticAbiType } from "@latticexyz/schema-type"; +/** @deprecated use `KeySchema` or `ValueSchema` instead */ export type Schema = { readonly staticFields: readonly StaticAbiType[]; readonly dynamicFields: readonly DynamicAbiType[]; }; +/** @deprecated use `KeySchema` and `ValueSchema` instead */ export type TableSchema = { readonly keySchema: Schema; // TODO: refine to set dynamicFields to [] readonly valueSchema: Schema; }; + +export type KeySchema = Record; +export type ValueSchema = Record; + +/** Map a table schema like `{ value: "uint256" }` to its primitive types like `{ value: bigint }` */ +export type SchemaToPrimitives = { + [key in keyof TSchema]: SchemaAbiTypeToPrimitiveType; +}; + +export type TableRecord = { + key: SchemaToPrimitives; + value: SchemaToPrimitives; +}; diff --git a/packages/protocol-parser/src/decodeKey.ts b/packages/protocol-parser/src/decodeKey.ts new file mode 100644 index 0000000000..2b11552ad8 --- /dev/null +++ b/packages/protocol-parser/src/decodeKey.ts @@ -0,0 +1,15 @@ +import { Hex } from "viem"; +import { SchemaToPrimitives, KeySchema } from "./common"; +import { decodeKeyTuple } from "./decodeKeyTuple"; + +export function decodeKey( + keySchema: TSchema, + data: readonly Hex[] +): SchemaToPrimitives { + // TODO: refactor and move all decodeKeyTuple logic into this method so we can delete decodeKeyTuple + const keyValues = decodeKeyTuple({ staticFields: Object.values(keySchema), dynamicFields: [] }, data); + + return Object.fromEntries( + Object.keys(keySchema).map((name, i) => [name, keyValues[i]]) + ) as SchemaToPrimitives; +} diff --git a/packages/protocol-parser/src/decodeKeyTuple.ts b/packages/protocol-parser/src/decodeKeyTuple.ts index 81342f13d4..623df1fac1 100644 --- a/packages/protocol-parser/src/decodeKeyTuple.ts +++ b/packages/protocol-parser/src/decodeKeyTuple.ts @@ -4,6 +4,7 @@ import { Schema } from "./common"; // key tuples are encoded in the same way as abi.encode, so we can decode them with viem +/** @deprecated use `decodeKey` instead */ export function decodeKeyTuple(keySchema: Schema, keyTuple: readonly Hex[]): StaticPrimitiveType[] { if (keySchema.staticFields.length !== keyTuple.length) { throw new Error( diff --git a/packages/protocol-parser/src/decodeRecord.ts b/packages/protocol-parser/src/decodeRecord.ts index 6e1a4fb46e..6d9c9773ff 100644 --- a/packages/protocol-parser/src/decodeRecord.ts +++ b/packages/protocol-parser/src/decodeRecord.ts @@ -11,6 +11,7 @@ import { decodeStaticField } from "./decodeStaticField"; import { hexToPackedCounter } from "./hexToPackedCounter"; import { staticDataLength } from "./staticDataLength"; +/** @deprecated use `decodeValue` instead */ export function decodeRecord(schema: Schema, data: Hex): readonly (StaticPrimitiveType | DynamicPrimitiveType)[] { const values: (StaticPrimitiveType | DynamicPrimitiveType)[] = []; diff --git a/packages/protocol-parser/src/decodeValue.ts b/packages/protocol-parser/src/decodeValue.ts new file mode 100644 index 0000000000..bd96093fed --- /dev/null +++ b/packages/protocol-parser/src/decodeValue.ts @@ -0,0 +1,16 @@ +import { isStaticAbiType, isDynamicAbiType } from "@latticexyz/schema-type"; +import { Hex } from "viem"; +import { SchemaToPrimitives, ValueSchema } from "./common"; +import { decodeRecord } from "./decodeRecord"; + +export function decodeValue(valueSchema: TSchema, data: Hex): SchemaToPrimitives { + const staticFields = Object.values(valueSchema).filter(isStaticAbiType); + const dynamicFields = Object.values(valueSchema).filter(isDynamicAbiType); + + // TODO: refactor and move all decodeRecord logic into this method so we can delete decodeRecord + const valueTuple = decodeRecord({ staticFields, dynamicFields }, data); + + return Object.fromEntries( + Object.keys(valueSchema).map((name, i) => [name, valueTuple[i]]) + ) as SchemaToPrimitives; +} diff --git a/packages/protocol-parser/src/encodeRecord.ts b/packages/protocol-parser/src/encodeRecord.ts index 23a1c16fea..363deeb5e3 100644 --- a/packages/protocol-parser/src/encodeRecord.ts +++ b/packages/protocol-parser/src/encodeRecord.ts @@ -3,6 +3,7 @@ import { Hex } from "viem"; import { encodeField } from "./encodeField"; import { Schema } from "./common"; +/** @deprecated use `encodeValue` instead */ export function encodeRecord(schema: Schema, values: readonly (StaticPrimitiveType | DynamicPrimitiveType)[]): Hex { const staticValues = values.slice(0, schema.staticFields.length) as readonly StaticPrimitiveType[]; const dynamicValues = values.slice(schema.staticFields.length) as readonly DynamicPrimitiveType[]; diff --git a/packages/protocol-parser/src/encodeValue.ts b/packages/protocol-parser/src/encodeValue.ts new file mode 100644 index 0000000000..6394f144b3 --- /dev/null +++ b/packages/protocol-parser/src/encodeValue.ts @@ -0,0 +1,18 @@ +import { isStaticAbiType, isDynamicAbiType } from "@latticexyz/schema-type"; +import { Hex } from "viem"; +import { SchemaToPrimitives, ValueSchema } from "./common"; +import { encodeRecord } from "./encodeRecord"; + +export function encodeValue( + valueSchema: TSchema, + value: SchemaToPrimitives +): Hex { + const staticFields = Object.values(valueSchema).filter(isStaticAbiType); + const dynamicFields = Object.values(valueSchema).filter(isDynamicAbiType); + + // TODO: refactor and move all encodeRecord logic into this method so we can delete encodeRecord + + // This currently assumes fields/values are ordered by static, dynamic + // TODO: make sure we preserve ordering based on schema definition + return encodeRecord({ staticFields, dynamicFields }, Object.values(value)); +} diff --git a/packages/protocol-parser/src/index.ts b/packages/protocol-parser/src/index.ts index bffae37cd2..fda72336a0 100644 --- a/packages/protocol-parser/src/index.ts +++ b/packages/protocol-parser/src/index.ts @@ -2,12 +2,15 @@ export * from "./abiTypesToSchema"; export * from "./common"; export * from "./decodeDynamicField"; export * from "./decodeField"; +export * from "./decodeKey"; export * from "./decodeKeyTuple"; export * from "./decodeRecord"; export * from "./decodeStaticField"; +export * from "./decodeValue"; export * from "./encodeField"; export * from "./encodeKeyTuple"; export * from "./encodeRecord"; +export * from "./encodeValue"; export * from "./errors"; export * from "./hexToPackedCounter"; export * from "./hexToSchema"; diff --git a/packages/store-sync/src/blockLogsToStorage.test.ts b/packages/store-sync/src/blockLogsToStorage.test.ts deleted file mode 100644 index 4c420705da..0000000000 --- a/packages/store-sync/src/blockLogsToStorage.test.ts +++ /dev/null @@ -1,217 +0,0 @@ -import { beforeEach, describe, expect, it, vi } from "vitest"; -import { blockLogsToStorage } from "./blockLogsToStorage"; -import storeConfig from "@latticexyz/store/mud.config"; -import { isDefined } from "@latticexyz/common/utils"; -import { tableIdToHex } from "@latticexyz/common"; -import { StorageAdapter } from "./common"; - -const mockedCallbacks = { - registerTables: vi.fn, ReturnType>(), - getTables: vi.fn, ReturnType>(), - storeOperations: vi.fn< - Parameters, - ReturnType - >(), -}; - -const mockedDecode = blockLogsToStorage( - mockedCallbacks as any as StorageAdapter -); - -describe("blockLogsToStorage", () => { - beforeEach(() => { - vi.clearAllMocks(); - }); - - it("call setField with data properly decoded", async () => { - mockedCallbacks.getTables.mockImplementation(async ({ tables }) => { - return tables - .map((table) => { - if (table.namespace === "" && table.name === "Inventory") { - return { - ...table, - tableId: tableIdToHex("", "Inventory"), - keySchema: { - owner: "address", - item: "uint32", - itemVariant: "uint32", - } as const, - valueSchema: { - amount: "uint32", - } as const, - }; - } - }) - .filter(isDefined); - }); - - const operations = await mockedDecode({ - blockNumber: 5448n, - logs: [ - { - address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", - topics: ["0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32"], - data: "0x6d756473746f72650000000000000000736368656d6100000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e76656e746f72790000000000000000000000000000000000000000000000000000000000000000000000000000400004010003000000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000", - blockNumber: 5448n, - transactionHash: "0x2766c01dd2290a80e2b54c27e95ca303d7d362643a68bd71c7d8fdb620f2a3a6", - transactionIndex: 18, - blockHash: "0xc65212ced76e80c3d59fd210fca434d9ceebfc25b544989d5eaecec3d31f9ac9", - logIndex: 18, - removed: false, - args: { - table: "0x6d756473746f72650000000000000000736368656d6100000000000000000000", - key: ["0x00000000000000000000000000000000496e76656e746f727900000000000000"], - data: "0x0004010003000000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000", - }, - eventName: "StoreSetRecord", - }, - { - address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", - topics: ["0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32"], - data: "0x6d756473746f7265000000000000000053746f72654d65746164617461000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e76656e746f72790000000000000000000000000000000000000000000000000000000000000000000000000000c900000000000000000000000000000000000000a00000000009000000000000a9496e76656e746f7279000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c75650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - blockNumber: 5448n, - transactionHash: "0x80d6650fdd6656461e6639988d7baa8d6d228297df505d8bbd0a4efc273b382b", - transactionIndex: 44, - blockHash: "0x930656a2399ed2473449118a030cf9a3b3f770db4f74e9b565e2e0035c49bc6e", - logIndex: 44, - removed: false, - args: { - table: "0x6d756473746f7265000000000000000053746f72654d65746164617461000000", - key: ["0x00000000000000000000000000000000496e76656e746f727900000000000000"], - data: "0x00000000000000000000000000000000000000a00000000009000000000000a9496e76656e746f7279000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - }, - eventName: "StoreSetRecord", - }, - { - address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", - topics: ["0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46"], - data: "0x00000000000000000000000000000000496e76656e746f7279000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000", - blockHash: "0x03e962e7402b2ab295b92feac342a132111dd14b0d1fd4d4a0456fdc77981577", - blockNumber: 5448n, - transactionHash: "0xa6986924609542dc4c2d81c53799d8eab47109ef34ee1e422de595e19ee9bfa4", - transactionIndex: 88, - logIndex: 88, - removed: false, - args: { - table: "0x00000000000000000000000000000000496e76656e746f727900000000000000", - key: [ - "0x000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f60", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000001", - ], - data: "0x00000008", - start: 0, - deleteCount: 4, - }, - eventName: "StoreSpliceRecord", - }, - ], - }); - - expect(mockedCallbacks.storeOperations).toMatchInlineSnapshot(` - [MockFunction spy] { - "calls": [ - [ - { - "blockNumber": 5448n, - "operations": [ - { - "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "data": "0x00000008", - "deleteCount": 4, - "key": { - "item": 1, - "itemVariant": 1, - "owner": "0x796eb990A3F9C431C69149c7a168b91596D87F60", - }, - "log": { - "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", - "args": { - "data": "0x00000008", - "deleteCount": 4, - "key": [ - "0x000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f60", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000001", - ], - "start": 0, - "table": "0x00000000000000000000000000000000496e76656e746f727900000000000000", - }, - "blockHash": "0x03e962e7402b2ab295b92feac342a132111dd14b0d1fd4d4a0456fdc77981577", - "blockNumber": 5448n, - "data": "0x00000000000000000000000000000000496e76656e746f7279000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000", - "eventName": "StoreSpliceRecord", - "logIndex": 88, - "removed": false, - "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46", - ], - "transactionHash": "0xa6986924609542dc4c2d81c53799d8eab47109ef34ee1e422de595e19ee9bfa4", - "transactionIndex": 88, - }, - "name": "Inventory", - "namespace": "", - "start": 0, - "type": "SpliceRecord", - }, - ], - }, - ], - ], - "results": [ - { - "type": "return", - "value": undefined, - }, - ], - } - `); - - expect(operations).toMatchInlineSnapshot(` - { - "blockNumber": 5448n, - "operations": [ - { - "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "data": "0x00000008", - "deleteCount": 4, - "key": { - "item": 1, - "itemVariant": 1, - "owner": "0x796eb990A3F9C431C69149c7a168b91596D87F60", - }, - "log": { - "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", - "args": { - "data": "0x00000008", - "deleteCount": 4, - "key": [ - "0x000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f60", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000001", - ], - "start": 0, - "table": "0x00000000000000000000000000000000496e76656e746f727900000000000000", - }, - "blockHash": "0x03e962e7402b2ab295b92feac342a132111dd14b0d1fd4d4a0456fdc77981577", - "blockNumber": 5448n, - "data": "0x00000000000000000000000000000000496e76656e746f7279000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000796eb990a3f9c431c69149c7a168b91596d87f600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000", - "eventName": "StoreSpliceRecord", - "logIndex": 88, - "removed": false, - "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46", - ], - "transactionHash": "0xa6986924609542dc4c2d81c53799d8eab47109ef34ee1e422de595e19ee9bfa4", - "transactionIndex": 88, - }, - "name": "Inventory", - "namespace": "", - "start": 0, - "type": "SpliceRecord", - }, - ], - } - `); - }); -}); diff --git a/packages/store-sync/src/blockLogsToStorage.ts b/packages/store-sync/src/blockLogsToStorage.ts deleted file mode 100644 index d55be9eead..0000000000 --- a/packages/store-sync/src/blockLogsToStorage.ts +++ /dev/null @@ -1,179 +0,0 @@ -import { decodeKeyTuple, decodeRecord, abiTypesToSchema, hexToSchema } from "@latticexyz/protocol-parser"; -import { - StoreConfig, - ConfigToKeyPrimitives as Key, - ConfigToValuePrimitives as Value, - ConfigToValuePrimitives, -} from "@latticexyz/store"; -import { decodeAbiParameters, getAddress, parseAbiParameters } from "viem"; -import { debug } from "./debug"; -import { isDefined } from "@latticexyz/common/utils"; -import { BlockLogs, StorageAdapter, StorageOperation, Table } from "./common"; -import { hexToTableId, tableIdToHex } from "@latticexyz/common"; -import storeConfig from "@latticexyz/store/mud.config"; - -// TODO: adjust when we get namespace support (https://github.com/latticexyz/mud/issues/994) and when table has namespace key (https://github.com/latticexyz/mud/issues/1201) -const schemasTable = storeConfig.tables.Tables; -const schemasTableId = tableIdToHex(storeConfig.namespace, schemasTable.name); - -export type BlockStorageOperations = { - blockNumber: BlockLogs["blockNumber"]; - operations: StorageOperation[]; -}; - -export type BlockLogsToStorageResult = ( - block: BlockLogs -) => Promise>; - -export function blockLogsToStorage({ - registerTables, - getTables, - storeOperations, -}: StorageAdapter): BlockLogsToStorageResult { - return async (block) => { - // Find table schema registration events - const newTables = block.logs - .map((log) => { - if (log.eventName !== "StoreSetRecord") return; - if (log.args.table !== schemasTableId) return; - - // TODO: refactor encode/decode to use Record schemas - // TODO: refactor to decode key with protocol-parser utils - - const [tableId, ...otherKeys] = log.args.key; - if (otherKeys.length) { - console.warn("registerSchema event is expected to have only one key in key tuple, but got multiple", log); - } - - const table = hexToTableId(tableId); - - const valueTuple = decodeRecord(abiTypesToSchema(Object.values(schemasTable.schema)), log.args.data); - const value = Object.fromEntries( - Object.keys(schemasTable.schema).map((name, i) => [name, valueTuple[i]]) - ) as ConfigToValuePrimitives; - - const keySchema = hexToSchema(value.keySchema); - const valueSchema = hexToSchema(value.valueSchema); - const keyNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedKeyNames)[0]; - const fieldNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedFieldNames)[0]; - - const valueAbiTypes = [...valueSchema.staticFields, ...valueSchema.dynamicFields]; - - return { - address: log.address, - tableId, - namespace: table.namespace, - name: table.name, - keySchema: Object.fromEntries(keySchema.staticFields.map((abiType, i) => [keyNames[i], abiType])), - valueSchema: Object.fromEntries(valueAbiTypes.map((abiType, i) => [fieldNames[i], abiType])), - }; - }) - .filter(isDefined); - - // Then register tables before we start storing data in them - if (newTables.length > 0) { - await registerTables({ - blockNumber: block.blockNumber, - tables: newTables, - }); - } - - const tablesToFetch = Array.from( - new Set( - block.logs.map((log) => - JSON.stringify({ - address: getAddress(log.address), - tableId: log.args.table, - ...hexToTableId(log.args.table), - }) - ) - ) - ).map((json) => JSON.parse(json)); - - const tables = Object.fromEntries( - ( - await getTables({ - blockNumber: block.blockNumber, - tables: tablesToFetch, - }) - ).map((table) => [`${getAddress(table.address)}:${table.tableId}`, table]) - ) as Record; - - const operations = block.logs - .map((log): StorageOperation | undefined => { - const table = tables[`${getAddress(log.address)}:${log.args.table}`]; - if (!table) { - debug("no table found for event, skipping", hexToTableId(log.args.table), log); - return; - } - - const keyNames = Object.keys(table.keySchema); - const keyValues = decodeKeyTuple( - { staticFields: Object.values(table.keySchema), dynamicFields: [] }, - log.args.key - ); - const key = Object.fromEntries(keyValues.map((value, i) => [keyNames[i], value])) as Key< - TConfig, - keyof TConfig["tables"] - >; - - const valueAbiTypes = Object.values(table.valueSchema); - const valueSchema = abiTypesToSchema(valueAbiTypes); - const fieldNames = Object.keys(table.valueSchema); - - // TODO: decide if we should split these up into distinct operations so the storage adapter can decide whether to combine or not - if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { - const valueTuple = decodeRecord(valueSchema, log.args.data); - const value = Object.fromEntries(fieldNames.map((name, i) => [name, valueTuple[i]])) as Value< - TConfig, - keyof TConfig["tables"] - >; - return { - log, - address: getAddress(log.address), - namespace: table.namespace, - name: table.name, - type: "SetRecord", - key, - value, - }; - } - - if (log.eventName === "StoreSpliceRecord") { - return { - log, - address: getAddress(log.address), - namespace: table.namespace, - name: table.name, - type: "SpliceRecord", - key, - data: log.args.data, - start: log.args.start, - deleteCount: log.args.deleteCount, - }; - } - - if (log.eventName === "StoreDeleteRecord") { - return { - log, - address: getAddress(log.address), - namespace: table.namespace, - name: table.name, - type: "DeleteRecord", - key, - }; - } - - debug("unknown store event or log, skipping", log); - return; - }) - .filter(isDefined); - - await storeOperations({ blockNumber: block.blockNumber, operations }); - - return { - blockNumber: block.blockNumber, - operations, - }; - }; -} diff --git a/packages/store-sync/src/common.ts b/packages/store-sync/src/common.ts index 2f69dcb279..006a13367a 100644 --- a/packages/store-sync/src/common.ts +++ b/packages/store-sync/src/common.ts @@ -1,17 +1,10 @@ -import { Address, Block, Hex, Log, PublicClient, TransactionReceipt } from "viem"; -import { GroupLogsByBlockNumberResult } from "@latticexyz/block-logs-stream"; -import { - StoreConfig, - KeySchema, - ValueSchema, - ConfigToKeyPrimitives as Key, - ConfigToValuePrimitives as Value, - TableRecord, - StoreEventsAbiItem, - StoreEventsAbi, -} from "@latticexyz/store"; +import { Address, Block, Hex, Log, PublicClient } from "viem"; +import { StoreConfig, StoreEventsAbiItem, StoreEventsAbi } from "@latticexyz/store"; +import storeConfig from "@latticexyz/store/mud.config"; import { Observable } from "rxjs"; -import { BlockStorageOperations } from "./blockLogsToStorage"; +import { tableIdToHex } from "@latticexyz/common"; +import { UnionPick } from "@latticexyz/common/type-utils"; +import { KeySchema, TableRecord, ValueSchema } from "@latticexyz/protocol-parser"; export type ChainId = number; export type WorldId = `${ChainId}:${Address}`; @@ -31,49 +24,35 @@ export type Table = { export type TableWithRecords = Table & { records: TableRecord[] }; export type StoreEventsLog = Log; -export type BlockLogs = GroupLogsByBlockNumberResult[number]; +export type BlockLogs = { blockNumber: StoreEventsLog["blockNumber"]; logs: StoreEventsLog[] }; -export type BaseStorageOperation = { +export type BaseStorageOperation = { log?: StoreEventsLog; address: Hex; namespace: TableNamespace; - name: TableName; + name: keyof TConfig["tables"] & TableName; + key: readonly Hex[]; }; -export type SetRecordOperation = BaseStorageOperation & { +export type SetRecordOperation = BaseStorageOperation & { type: "SetRecord"; -} & { - [TTable in keyof TConfig["tables"]]: { - name: TTable & string; - key: Key; - value: Value; - }; - }[keyof TConfig["tables"]]; + data: Hex; +}; -export type SpliceRecordOperation = BaseStorageOperation & { +export type SpliceRecordOperation = BaseStorageOperation & { type: "SpliceRecord"; -} & { - [TTable in keyof TConfig["tables"]]: { - name: TTable & string; - key: Key; - data: Hex; - start: number; - deleteCount: number; - }; - }[keyof TConfig["tables"]]; + data: Hex; + start: number; + deleteCount: number; +}; -export type DeleteRecordOperation = BaseStorageOperation & { +export type DeleteRecordOperation = BaseStorageOperation & { type: "DeleteRecord"; -} & { - [TTable in keyof TConfig["tables"]]: { - name: TTable & string; - key: Key; - }; - }[keyof TConfig["tables"]]; +}; export type StorageOperation = - | SpliceRecordOperation | SetRecordOperation + | SpliceRecordOperation | DeleteRecordOperation; export type SyncOptions = { @@ -112,22 +91,19 @@ export type SyncOptions = { }; }; -export type SyncResult = { +export type SyncResult = { latestBlock$: Observable; latestBlockNumber$: Observable; blockLogs$: Observable; - blockStorageOperations$: Observable>; + storedBlockLogs$: Observable; waitForTransaction: (tx: Hex) => Promise; }; -export type StorageAdapter = { - registerTables: (opts: { blockNumber: BlockLogs["blockNumber"]; tables: Table[] }) => Promise; - getTables: (opts: { - blockNumber: BlockLogs["blockNumber"]; - tables: Pick[]; - }) => Promise; - storeOperations: (opts: { - blockNumber: BlockLogs["blockNumber"]; - operations: StorageOperation[]; - }) => Promise; -}; +// TODO: add optional, original log to this? +export type StorageAdapterLog = Partial & UnionPick; +export type StorageAdapterBlock = { blockNumber: BlockLogs["blockNumber"]; logs: StorageAdapterLog[] }; +export type StorageAdapter = (block: StorageAdapterBlock) => Promise; + +// TODO: adjust when we get namespace support (https://github.com/latticexyz/mud/issues/994) and when table has namespace key (https://github.com/latticexyz/mud/issues/1201) +export const schemasTable = storeConfig.tables.Tables; +export const schemasTableId = tableIdToHex(storeConfig.namespace, schemasTable.name); diff --git a/packages/store-sync/src/createStoreSync.ts b/packages/store-sync/src/createStoreSync.ts index 2e0cfc0857..24aee6d3b6 100644 --- a/packages/store-sync/src/createStoreSync.ts +++ b/packages/store-sync/src/createStoreSync.ts @@ -1,6 +1,14 @@ -import { ConfigToKeyPrimitives, ConfigToValuePrimitives, StoreConfig, storeEventsAbi } from "@latticexyz/store"; +import { StoreConfig, storeEventsAbi } from "@latticexyz/store"; import { Hex, TransactionReceiptNotFoundError } from "viem"; -import { SetRecordOperation, StorageAdapter, SyncOptions, SyncResult, TableWithRecords } from "./common"; +import { + StorageAdapter, + StorageAdapterBlock, + StorageAdapterLog, + SyncOptions, + SyncResult, + TableWithRecords, + schemasTableId, +} from "./common"; import { createBlockStream, blockRangeToLogs, groupLogsByBlockNumber } from "@latticexyz/block-logs-stream"; import { filter, @@ -20,7 +28,6 @@ import { scan, identity, } from "rxjs"; -import { BlockStorageOperations, blockLogsToStorage } from "./blockLogsToStorage"; import { debug as parentDebug } from "./debug"; import { createIndexerClient } from "./trpc-indexer"; import { SyncStep } from "./SyncStep"; @@ -29,7 +36,7 @@ import { chunk, isDefined } from "@latticexyz/common/utils"; const debug = parentDebug.extend("createStoreSync"); type CreateStoreSyncOptions = SyncOptions & { - storageAdapter: StorageAdapter; + storageAdapter: StorageAdapter; onProgress?: (opts: { step: SyncStep; percentage: number; @@ -39,8 +46,6 @@ type CreateStoreSyncOptions = SyncOpt }) => void; }; -type CreateStoreSyncResult = SyncResult; - export async function createStoreSync({ storageAdapter, onProgress, @@ -50,7 +55,7 @@ export async function createStoreSync maxBlockRange, initialState, indexerUrl, -}: CreateStoreSyncOptions): Promise> { +}: CreateStoreSyncOptions): Promise { const initialState$ = defer( async (): Promise< | { @@ -109,7 +114,7 @@ export async function createStoreSync tap((startBlock) => debug("starting sync from block", startBlock)) ); - const initialStorageOperations$ = initialState$.pipe( + const initialLogs$ = initialState$.pipe( filter( (initialState): initialState is { blockNumber: bigint; tables: TableWithRecords[] } => initialState != null && initialState.blockNumber != null && initialState.tables.length > 0 @@ -125,27 +130,42 @@ export async function createStoreSync message: "Hydrating from snapshot", }); - await storageAdapter.registerTables({ blockNumber, tables }); - - const operations: SetRecordOperation[] = tables.flatMap((table) => - table.records.map((record) => ({ - type: "SetRecord", + const logs: StorageAdapterLog[] = tables.flatMap((table) => [ + { + eventName: "StoreSetRecord", address: table.address, - namespace: table.namespace, - name: table.name, - key: record.key as ConfigToKeyPrimitives, - value: record.value as ConfigToValuePrimitives, - })) - ); + args: { + table: schemasTableId, + key: [table.tableId], + data: "0x", // TODO: encode key/value schemas + }, + }, + ...table.records.map( + (record): StorageAdapterLog => ({ + eventName: "StoreSetRecord", + address: table.address, + args: { + table: table.tableId, + key: [], // TODO: encode key + data: "0x", // TODO: encode data + }, + // address: table.address, + // namespace: table.namespace, + // name: table.name, + // key: record.key as ConfigToKeyPrimitives, + // value: record.value as ConfigToValuePrimitives, + }) + ), + ]); // Split snapshot operations into chunks so we can update the progress callback (and ultimately render visual progress for the user). // This isn't ideal if we want to e.g. batch load these into a DB in a single DB tx, but we'll take it. // // Split into 50 equal chunks (for better `onProgress` updates) but only if we have 100+ items per chunk - const chunkSize = Math.max(100, Math.floor(operations.length / 50)); - const chunks = Array.from(chunk(operations, chunkSize)); + const chunkSize = Math.max(100, Math.floor(logs.length / 50)); + const chunks = Array.from(chunk(logs, chunkSize)); for (const [i, chunk] of chunks.entries()) { - await storageAdapter.storeOperations({ blockNumber, operations: chunk }); + await storageAdapter({ blockNumber, logs: chunk }); onProgress?.({ step: SyncStep.SNAPSHOT, percentage: (i + chunk.length) / chunks.length, @@ -163,7 +183,7 @@ export async function createStoreSync message: "Hydrated from snapshot", }); - return { blockNumber, operations }; + return { blockNumber, logs }; }), shareReplay(1) ); @@ -196,12 +216,15 @@ export async function createStoreSync ); let lastBlockNumberProcessed: bigint | null = null; - const blockStorageOperations$ = concat( - initialStorageOperations$, + const storedBlockLogs$ = concat( + initialLogs$, blockLogs$.pipe( - concatMap(blockLogsToStorage(storageAdapter)), - tap(({ blockNumber, operations }) => { - debug("stored", operations.length, "operations for block", blockNumber); + concatMap(async (block) => { + await storageAdapter(block); + return block; + }), + tap(({ blockNumber, logs }) => { + debug("stored", logs.length, "logs for block", blockNumber); lastBlockNumberProcessed = blockNumber; if (startBlock != null && endBlock != null) { @@ -232,8 +255,8 @@ export async function createStoreSync // keep 10 blocks worth processed transactions in memory const recentBlocksWindow = 10; // most recent block first, for ease of pulling the first one off the array - const recentBlocks$ = blockStorageOperations$.pipe( - scan( + const recentBlocks$ = storedBlockLogs$.pipe( + scan( (recentBlocks, block) => [block, ...recentBlocks].slice(0, recentBlocksWindow), [] ), @@ -249,7 +272,7 @@ export async function createStoreSync // We could potentially speed this up a tiny bit by racing to see if 1) tx exists in processed block or 2) fetch tx receipt for latest block processed const hasTransaction$ = recentBlocks$.pipe( concatMap(async (blocks) => { - const txs = blocks.flatMap((block) => block.operations.map((op) => op.log?.transactionHash).filter(isDefined)); + const txs = blocks.flatMap((block) => block.logs.map((op) => op.transactionHash).filter(isDefined)); if (txs.includes(tx)) return true; try { @@ -274,7 +297,7 @@ export async function createStoreSync latestBlock$, latestBlockNumber$, blockLogs$, - blockStorageOperations$, + storedBlockLogs$, waitForTransaction, }; } diff --git a/packages/store-sync/src/index.ts b/packages/store-sync/src/index.ts index 01c883d7e2..2e0771488d 100644 --- a/packages/store-sync/src/index.ts +++ b/packages/store-sync/src/index.ts @@ -1,4 +1,3 @@ -export * from "./blockLogsToStorage"; export * from "./common"; export * from "./createStoreSync"; export * from "./SyncStep"; diff --git a/packages/store-sync/src/isTableRegistrationLog.ts b/packages/store-sync/src/isTableRegistrationLog.ts new file mode 100644 index 0000000000..ef327e3158 --- /dev/null +++ b/packages/store-sync/src/isTableRegistrationLog.ts @@ -0,0 +1,7 @@ +import { StorageAdapterLog, schemasTableId } from "./common"; + +export function isTableRegistrationLog( + log: StorageAdapterLog +): log is StorageAdapterLog & { eventName: "StoreSetRecord" } { + return log.eventName === "StoreSetRecord" && log.args.table === schemasTableId; +} diff --git a/packages/store-sync/src/logToTable.ts b/packages/store-sync/src/logToTable.ts new file mode 100644 index 0000000000..1a7478c6a4 --- /dev/null +++ b/packages/store-sync/src/logToTable.ts @@ -0,0 +1,41 @@ +import { decodeRecord, abiTypesToSchema, hexToSchema } from "@latticexyz/protocol-parser"; +import { ConfigToValuePrimitives } from "@latticexyz/store"; +import { decodeAbiParameters, parseAbiParameters } from "viem"; +import { StorageAdapterLog, Table, schemasTable } from "./common"; +import { hexToTableId } from "@latticexyz/common"; +import storeConfig from "@latticexyz/store/mud.config"; + +// TODO: add tableToLog + +export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord" }): Table { + // TODO: refactor encode/decode to use Record schemas + // TODO: refactor to decode key with protocol-parser utils + + const [tableId, ...otherKeys] = log.args.key; + if (otherKeys.length) { + console.warn("registerSchema event is expected to have only one key in key tuple, but got multiple", log); + } + + const table = hexToTableId(tableId); + + const valueTuple = decodeRecord(abiTypesToSchema(Object.values(schemasTable.schema)), log.args.data); + const value = Object.fromEntries( + Object.keys(schemasTable.schema).map((name, i) => [name, valueTuple[i]]) + ) as ConfigToValuePrimitives; + + const keySchema = hexToSchema(value.keySchema); + const valueSchema = hexToSchema(value.valueSchema); + const keyNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedKeyNames)[0]; + const fieldNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedFieldNames)[0]; + + const valueAbiTypes = [...valueSchema.staticFields, ...valueSchema.dynamicFields]; + + return { + address: log.address, + tableId, + namespace: table.namespace, + name: table.name, + keySchema: Object.fromEntries(keySchema.staticFields.map((abiType, i) => [keyNames[i], abiType])), + valueSchema: Object.fromEntries(valueAbiTypes.map((abiType, i) => [fieldNames[i], abiType])), + }; +} diff --git a/packages/store-sync/src/recs/common.ts b/packages/store-sync/src/recs/common.ts index 79292ac176..c384d5da13 100644 --- a/packages/store-sync/src/recs/common.ts +++ b/packages/store-sync/src/recs/common.ts @@ -1,7 +1,8 @@ -import { KeySchema, StoreConfig, ValueSchema } from "@latticexyz/store"; +import { StoreConfig } from "@latticexyz/store"; import { Component as RecsComponent, Metadata as RecsMetadata, Type as RecsType } from "@latticexyz/recs"; import { SchemaAbiTypeToRecsType } from "./schemaAbiTypeToRecsType"; import { SchemaAbiType } from "@latticexyz/schema-type"; +import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser"; export type StoreComponentMetadata = RecsMetadata & { componentName: string; diff --git a/packages/store-sync/src/recs/decodeEntity.ts b/packages/store-sync/src/recs/decodeEntity.ts index cadfad5df3..ba2c084a7f 100644 --- a/packages/store-sync/src/recs/decodeEntity.ts +++ b/packages/store-sync/src/recs/decodeEntity.ts @@ -1,10 +1,9 @@ import { Entity } from "@latticexyz/recs"; -import { StaticAbiType } from "@latticexyz/schema-type"; import { Hex, decodeAbiParameters } from "viem"; -import { SchemaToPrimitives } from "@latticexyz/store"; import { entityToHexKeyTuple } from "./entityToHexKeyTuple"; +import { KeySchema, SchemaToPrimitives } from "@latticexyz/protocol-parser"; -export function decodeEntity>( +export function decodeEntity( keySchema: TKeySchema, entity: Entity ): SchemaToPrimitives { diff --git a/packages/store-sync/src/recs/encodeEntity.ts b/packages/store-sync/src/recs/encodeEntity.ts index 92f4c839ef..c1ce7b7054 100644 --- a/packages/store-sync/src/recs/encodeEntity.ts +++ b/packages/store-sync/src/recs/encodeEntity.ts @@ -1,10 +1,10 @@ import { Entity } from "@latticexyz/recs"; -import { StaticAbiType } from "@latticexyz/schema-type"; import { encodeAbiParameters } from "viem"; -import { SchemaToPrimitives } from "@latticexyz/store"; import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; +import { SchemaToPrimitives } from "@latticexyz/store"; +import { KeySchema } from "@latticexyz/protocol-parser"; -export function encodeEntity>( +export function encodeEntity( keySchema: TKeySchema, key: SchemaToPrimitives ): Entity { diff --git a/packages/store-sync/src/recs/getTableEntity.ts b/packages/store-sync/src/recs/getTableEntity.ts index 83b746e89b..5b92368da3 100644 --- a/packages/store-sync/src/recs/getTableEntity.ts +++ b/packages/store-sync/src/recs/getTableEntity.ts @@ -1,4 +1,4 @@ -import { Address, Hex, getAddress, stringToHex } from "viem"; +import { stringToHex } from "viem"; import { Table } from "../common"; import { Entity } from "@latticexyz/recs"; import { encodeEntity } from "./encodeEntity"; diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index e2cc9715a9..5577ff0ec6 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -1,24 +1,24 @@ import { StoreConfig } from "@latticexyz/store"; import { debug } from "./debug"; import { - ComponentValue, Component as RecsComponent, Schema as RecsSchema, getComponentValue, + hasComponent, removeComponent, setComponent, } from "@latticexyz/recs"; -import { isDefined } from "@latticexyz/common/utils"; import { schemaToDefaults } from "../schemaToDefaults"; import { defineInternalComponents } from "./defineInternalComponents"; import { getTableEntity } from "./getTableEntity"; import { StoreComponentMetadata } from "./common"; -import { tableIdToHex } from "@latticexyz/common"; -import { encodeEntity } from "./encodeEntity"; -import { abiTypesToSchema, decodeRecord, encodeRecord } from "@latticexyz/protocol-parser"; -import { DynamicPrimitiveType, StaticPrimitiveType } from "@latticexyz/schema-type"; +import { hexToTableId } from "@latticexyz/common"; +import { SchemaToPrimitives, ValueSchema, decodeValue, encodeValue } from "@latticexyz/protocol-parser"; import { concat, size, slice } from "viem"; import { StorageAdapter } from "../common"; +import { isTableRegistrationLog } from "../isTableRegistrationLog"; +import { logToTable } from "../logToTable"; +import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; export function recsStorage({ components, @@ -26,77 +26,71 @@ export function recsStorage({ components: ReturnType & Record>; config?: TConfig; -}): StorageAdapter { +}): StorageAdapter { // TODO: do we need to store block number? const componentsByTableId = Object.fromEntries( Object.entries(components).map(([id, component]) => [component.id, component]) ); - return { - async registerTables({ tables }) { - for (const table of tables) { - // TODO: check if table exists already and skip/warn? - setComponent(components.RegisteredTables, getTableEntity(table), { table }); + return async function storeLogs({ logs }) { + const newTables = logs.filter(isTableRegistrationLog).map(logToTable); + for (const newTable of newTables) { + const tableEntity = getTableEntity(newTable); + if (hasComponent(components.RegisteredTables, tableEntity)) { + console.warn("table already registered, ignoring", { + newTable, + existingTable: getComponentValue(components.RegisteredTables, tableEntity)?.table, + }); + } else { + setComponent(components.RegisteredTables, tableEntity, { table: newTable }); } - }, - async getTables({ tables }) { - // TODO: fetch schema from RPC if table not found? - return tables - .map((table) => getComponentValue(components.RegisteredTables, getTableEntity(table))?.table) - .filter(isDefined); - }, - async storeOperations({ operations }) { - for (const operation of operations) { - const table = getComponentValue( - components.RegisteredTables, - getTableEntity({ - address: operation.address, - namespace: operation.namespace, - name: operation.name, - }) - )?.table; - if (!table) { - debug(`skipping update for unknown table: ${operation.namespace}:${operation.name} at ${operation.address}`); - continue; - } + } - const tableId = tableIdToHex(operation.namespace, operation.name); - const component = componentsByTableId[tableId]; - if (!component) { - debug(`skipping update for unknown component: ${tableId}. Available components: ${Object.keys(components)}`); - continue; - } - - const entity = encodeEntity(table.keySchema, operation.key); + for (const log of logs) { + const { namespace, name } = hexToTableId(log.args.table); + const table = getComponentValue( + components.RegisteredTables, + getTableEntity({ address: log.address, namespace, name }) + )?.table; + if (!table) { + debug(`skipping update for unknown table: ${namespace}:${name} at ${log.address}`); + continue; + } - if (operation.type === "SetRecord") { - debug("setting component", tableId, entity, operation.value); - setComponent(component, entity, operation.value as ComponentValue); - } else if (operation.type === "SpliceRecord") { - const schema = abiTypesToSchema(Object.values(table.valueSchema)); - const oldValueTuple = Object.values( - getComponentValue(component, entity) ?? schemaToDefaults(table.valueSchema) - ); - const oldRecord = encodeRecord(schema, oldValueTuple as (StaticPrimitiveType | DynamicPrimitiveType)[]); - const end = operation.start + operation.deleteCount; - const newRecord = concat([ - slice(oldRecord, 0, operation.start), - operation.data, - end >= size(oldRecord) ? "0x" : slice(oldRecord, end), - ]); - const newValueTuple = decodeRecord(schema, newRecord); + const component = componentsByTableId[table.tableId]; + if (!component) { + debug( + `skipping update for unknown component: ${table.tableId}. Available components: ${Object.keys(components)}` + ); + continue; + } - const fieldNames = Object.keys(table.valueSchema); - const value = Object.fromEntries(fieldNames.map((name, i) => [name, newValueTuple[i]])); + const entity = hexKeyTupleToEntity(log.args.key); - debug("setting component (splice)", tableId, entity, newRecord); - setComponent(component, entity, value); - } else if (operation.type === "DeleteRecord") { - debug("deleting component", tableId, entity); - removeComponent(component, entity); - } + if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { + const value = decodeValue(table.valueSchema, log.args.data); + debug("setting component", table.tableId, entity, value); + setComponent(component, entity, value); + } else if (log.eventName === "StoreSpliceRecord") { + const previousValue = getComponentValue(component, entity); + const previousData = encodeValue( + table.valueSchema, + (previousValue as SchemaToPrimitives) ?? schemaToDefaults(table.valueSchema) + ); + const end = log.args.start + log.args.deleteCount; + const newData = concat([ + slice(previousData, 0, log.args.start), + log.args.data, + end >= size(previousData) ? "0x" : slice(previousData, end), + ]); + const newValue = decodeValue(table.valueSchema, newData); + debug("setting component via splice", table.tableId, entity, { newValue, previousValue }); + setComponent(component, entity, newValue); + } else if (log.eventName === "StoreDeleteRecord") { + debug("deleting component", table.tableId, entity); + removeComponent(component, entity); } - }, - } as StorageAdapter; + } + }; } diff --git a/packages/store-sync/src/recs/syncToRecs.ts b/packages/store-sync/src/recs/syncToRecs.ts index 4483fd5817..71090c8dd6 100644 --- a/packages/store-sync/src/recs/syncToRecs.ts +++ b/packages/store-sync/src/recs/syncToRecs.ts @@ -17,7 +17,7 @@ type SyncToRecsOptions = SyncOptions< startSync?: boolean; }; -type SyncToRecsResult = SyncResult & { +type SyncToRecsResult = SyncResult & { components: ConfigToRecsComponents & ConfigToRecsComponents & ConfigToRecsComponents & @@ -67,7 +67,7 @@ export async function syncToRecs({ }, }); - const sub = startSync ? storeSync.blockStorageOperations$.subscribe() : null; + const sub = startSync ? storeSync.storedBlockLogs$.subscribe() : null; const stopSync = (): void => { sub?.unsubscribe(); }; diff --git a/packages/store-sync/src/schemaToDefaults.ts b/packages/store-sync/src/schemaToDefaults.ts index e964dc224a..957fab7160 100644 --- a/packages/store-sync/src/schemaToDefaults.ts +++ b/packages/store-sync/src/schemaToDefaults.ts @@ -1,5 +1,5 @@ +import { SchemaToPrimitives, ValueSchema } from "@latticexyz/protocol-parser"; import { schemaAbiTypeToDefaultValue } from "@latticexyz/schema-type"; -import { ValueSchema, SchemaToPrimitives } from "@latticexyz/store"; export function schemaToDefaults(schema: TSchema): SchemaToPrimitives { return Object.fromEntries( diff --git a/packages/store/ts/common.ts b/packages/store/ts/common.ts index 9d825f35fd..380709deec 100644 --- a/packages/store/ts/common.ts +++ b/packages/store/ts/common.ts @@ -1,19 +1,6 @@ -import { SchemaAbiType, SchemaAbiTypeToPrimitiveType, StaticAbiType } from "@latticexyz/schema-type"; +import { SchemaAbiType, SchemaAbiTypeToPrimitiveType } from "@latticexyz/schema-type"; import { FieldData, FullSchemaConfig, StoreConfig } from "./config"; -export type KeySchema = Record; -export type ValueSchema = Record; - -/** Map a table schema like `{ value: "uint256" }` to its primitive types like `{ value: bigint }` */ -export type SchemaToPrimitives = { - [key in keyof TSchema]: SchemaAbiTypeToPrimitiveType; -}; - -export type TableRecord = { - key: SchemaToPrimitives; - value: SchemaToPrimitives; -}; - export type ConfigFieldTypeToSchemaAbiType> = T extends SchemaAbiType ? T : T extends `${string}[${string}]` diff --git a/packages/store/ts/storeEvents.ts b/packages/store/ts/storeEvents.ts index 3f4bfcbf76..d87725a2e2 100644 --- a/packages/store/ts/storeEvents.ts +++ b/packages/store/ts/storeEvents.ts @@ -1,6 +1,6 @@ export const storeEvents = [ - "event StoreDeleteRecord(bytes32 table, bytes32[] key)", - "event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", "event StoreSetRecord(bytes32 table, bytes32[] key, bytes data)", + "event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data)", + "event StoreDeleteRecord(bytes32 table, bytes32[] key)", ] as const; From 6d7477437a68ad0b5f469717777889dc7f9cdc70 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Mon, 4 Sep 2023 09:58:43 +0100 Subject: [PATCH 11/69] use getTableConfig helper --- .../store-sync/src/postgres/cleanDatabase.ts | 10 +++++----- .../store-sync/src/postgres/getSchema.test.ts | 12 ------------ packages/store-sync/src/postgres/getSchema.ts | 6 ------ .../store-sync/src/postgres/setupTables.ts | 19 ++++++++----------- 4 files changed, 13 insertions(+), 34 deletions(-) delete mode 100644 packages/store-sync/src/postgres/getSchema.test.ts delete mode 100644 packages/store-sync/src/postgres/getSchema.ts diff --git a/packages/store-sync/src/postgres/cleanDatabase.ts b/packages/store-sync/src/postgres/cleanDatabase.ts index eff82aaf50..26d22ad31c 100644 --- a/packages/store-sync/src/postgres/cleanDatabase.ts +++ b/packages/store-sync/src/postgres/cleanDatabase.ts @@ -1,11 +1,10 @@ -import { PgDatabase } from "drizzle-orm/pg-core"; +import { PgDatabase, getTableConfig } from "drizzle-orm/pg-core"; import { buildInternalTables } from "./buildInternalTables"; import { getTables } from "./getTables"; import { buildTable } from "./buildTable"; -import { getSchema } from "./getSchema"; import { isDefined } from "@latticexyz/common/utils"; import { debug } from "./debug"; -import { getTableName, sql } from "drizzle-orm"; +import { sql } from "drizzle-orm"; import { pgDialect } from "./pgDialect"; // This intentionally just cleans up known schemas/tables/rows. We could drop the database but that's scary. @@ -16,7 +15,7 @@ export async function cleanDatabase(db: PgDatabase): Promise { const tables = (await getTables(db)).map(buildTable); - const schemaNames = [...new Set(tables.map(getSchema))].filter(isDefined); + const schemaNames = [...new Set(tables.map((table) => getTableConfig(table).schema))].filter(isDefined); for (const schemaName of schemaNames) { try { @@ -28,7 +27,8 @@ export async function cleanDatabase(db: PgDatabase): Promise { } for (const internalTable of Object.values(internalTables)) { - debug(`deleting all rows from ${getSchema(internalTable)}.${getTableName(internalTable)}`); + const tableConfig = getTableConfig(internalTable); + debug(`deleting all rows from ${tableConfig.schema}.${tableConfig.name}`); await db.delete(internalTable); } } diff --git a/packages/store-sync/src/postgres/getSchema.test.ts b/packages/store-sync/src/postgres/getSchema.test.ts deleted file mode 100644 index c0c9a045a5..0000000000 --- a/packages/store-sync/src/postgres/getSchema.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { describe, it, expect } from "vitest"; -import { getSchema } from "./getSchema"; -import { pgTable, pgSchema } from "drizzle-orm/pg-core"; - -// Test to make sure getSchema matches drizzle internals. May need to update getSchema if these tests start failing. Hopefully by then, drizzle will have exposed their own getSchema method. - -describe("getSchema", () => { - it("should return schema if set", async () => { - expect(getSchema(pgTable("no schema", {}))).toBeUndefined(); - expect(getSchema(pgSchema("some schema").table("with schema", {}))).toBe("some schema"); - }); -}); diff --git a/packages/store-sync/src/postgres/getSchema.ts b/packages/store-sync/src/postgres/getSchema.ts deleted file mode 100644 index 240046fcd4..0000000000 --- a/packages/store-sync/src/postgres/getSchema.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { PgTable } from "drizzle-orm/pg-core"; - -// TODO: PR to drizzle to expose `getSchema` like `getTableName` -export function getSchema(table: PgTable): string | undefined { - return (table as any)[Symbol.for("drizzle:Schema")]; -} diff --git a/packages/store-sync/src/postgres/setupTables.ts b/packages/store-sync/src/postgres/setupTables.ts index 1ddcedaa6f..d15f92ce54 100644 --- a/packages/store-sync/src/postgres/setupTables.ts +++ b/packages/store-sync/src/postgres/setupTables.ts @@ -1,7 +1,6 @@ -import { AnyPgColumn, PgTableWithColumns, PgDatabase } from "drizzle-orm/pg-core"; -import { getTableColumns, getTableName, sql } from "drizzle-orm"; +import { AnyPgColumn, PgTableWithColumns, PgDatabase, getTableConfig } from "drizzle-orm/pg-core"; +import { getTableColumns, sql } from "drizzle-orm"; import { ColumnDataType } from "kysely"; -import { getSchema } from "./getSchema"; import { isDefined } from "@latticexyz/common/utils"; import { debug } from "./debug"; import { pgDialect } from "./pgDialect"; @@ -13,7 +12,7 @@ export async function setupTables( // TODO: add table to internal tables here // TODO: look up table schema and check if it matches expected schema, drop if not - const schemaNames = [...new Set(tables.map(getSchema).filter(isDefined))]; + const schemaNames = [...new Set(tables.map((table) => getTableConfig(table).schema).filter(isDefined))]; await db.transaction(async (tx) => { for (const schemaName of schemaNames) { @@ -22,12 +21,10 @@ export async function setupTables( } for (const table of tables) { - const schemaName = getSchema(table); - const scopedDb = schemaName ? pgDialect.withSchema(schemaName) : pgDialect; + const tableConfig = getTableConfig(table); + const scopedDb = tableConfig.schema ? pgDialect.withSchema(tableConfig.schema) : pgDialect; - const tableName = getTableName(table); - - let query = scopedDb.schema.createTable(tableName).ifNotExists(); + let query = scopedDb.schema.createTable(tableConfig.name).ifNotExists(); const columns = Object.values(getTableColumns(table)) as AnyPgColumn[]; for (const column of columns) { @@ -44,10 +41,10 @@ export async function setupTables( const primaryKeys = columns.filter((column) => column.primary).map((column) => column.name); if (primaryKeys.length) { - query = query.addPrimaryKeyConstraint(`${tableName}__pk`, primaryKeys as any); + query = query.addPrimaryKeyConstraint(`${tableConfig.name}__pk`, primaryKeys as any); } - debug(`creating table ${tableName} in namespace ${schemaName}`); + debug(`creating table ${tableConfig.name} in namespace ${tableConfig.schema}`); await tx.execute(sql.raw(query.compile().sql)); } }); From 3863505dfaf643d8cb78aa83407fd976a2fb72d8 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Mon, 4 Sep 2023 10:08:27 +0100 Subject: [PATCH 12/69] update sqlite storage adapter --- packages/store-sync/src/recs/common.test-d.ts | 21 +- packages/store-sync/src/recs/encodeEntity.ts | 3 +- packages/store-sync/src/recs/recsStorage.ts | 8 +- .../src/sqlite/createSqliteTable.test.ts | 72 +++++ .../src/sqlite/createSqliteTable.ts | 1 + packages/store-sync/src/sqlite/getTables.ts | 4 +- .../src/sqlite/sqliteStorage.test.ts | 8 +- .../store-sync/src/sqlite/sqliteStorage.ts | 288 +++++++++--------- .../store-sync/src/sqlite/syncToSqlite.ts | 8 +- 9 files changed, 250 insertions(+), 163 deletions(-) diff --git a/packages/store-sync/src/recs/common.test-d.ts b/packages/store-sync/src/recs/common.test-d.ts index bf1e450859..a2f81ff7a4 100644 --- a/packages/store-sync/src/recs/common.test-d.ts +++ b/packages/store-sync/src/recs/common.test-d.ts @@ -4,18 +4,27 @@ import storeConfig from "@latticexyz/store/mud.config"; import { ConfigToRecsComponents } from "./common"; describe("ConfigToRecsComponents", () => { - expectTypeOf["StoreMetadata"]>().toEqualTypeOf< + expectTypeOf["Tables"]>().toEqualTypeOf< Component< { - tableName: RecsType.String; + keySchema: RecsType.String; + valueSchema: RecsType.String; + abiEncodedKeyNames: RecsType.String; abiEncodedFieldNames: RecsType.String; }, { - componentName: "StoreMetadata"; + componentName: "Tables"; // TODO: fix config namespace so it comes back as a const - tableName: `${string}:StoreMetadata`; - keySchema: { tableId: "bytes32" }; - valueSchema: { tableName: "string"; abiEncodedFieldNames: "bytes" }; + tableName: `${string}:Tables`; + keySchema: { + tableId: "bytes32"; + }; + valueSchema: { + keySchema: "bytes32"; + valueSchema: "bytes32"; + abiEncodedKeyNames: "bytes"; + abiEncodedFieldNames: "bytes"; + }; } > >(); diff --git a/packages/store-sync/src/recs/encodeEntity.ts b/packages/store-sync/src/recs/encodeEntity.ts index c1ce7b7054..bef8a33c1b 100644 --- a/packages/store-sync/src/recs/encodeEntity.ts +++ b/packages/store-sync/src/recs/encodeEntity.ts @@ -1,8 +1,7 @@ import { Entity } from "@latticexyz/recs"; import { encodeAbiParameters } from "viem"; import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; -import { SchemaToPrimitives } from "@latticexyz/store"; -import { KeySchema } from "@latticexyz/protocol-parser"; +import { KeySchema, SchemaToPrimitives } from "@latticexyz/protocol-parser"; export function encodeEntity( keySchema: TKeySchema, diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index 5577ff0ec6..ee3d874e6f 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -14,7 +14,7 @@ import { getTableEntity } from "./getTableEntity"; import { StoreComponentMetadata } from "./common"; import { hexToTableId } from "@latticexyz/common"; import { SchemaToPrimitives, ValueSchema, decodeValue, encodeValue } from "@latticexyz/protocol-parser"; -import { concat, size, slice } from "viem"; +import { concatHex, size, sliceHex } from "viem"; import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; @@ -79,10 +79,10 @@ export function recsStorage({ (previousValue as SchemaToPrimitives) ?? schemaToDefaults(table.valueSchema) ); const end = log.args.start + log.args.deleteCount; - const newData = concat([ - slice(previousData, 0, log.args.start), + const newData = concatHex([ + sliceHex(previousData, 0, log.args.start), log.args.data, - end >= size(previousData) ? "0x" : slice(previousData, end), + end >= size(previousData) ? "0x" : sliceHex(previousData, end), ]); const newValue = decodeValue(table.valueSchema, newData); debug("setting component via splice", table.tableId, entity, { newValue, previousValue }); diff --git a/packages/store-sync/src/sqlite/createSqliteTable.test.ts b/packages/store-sync/src/sqlite/createSqliteTable.test.ts index 756055c09d..fbaecab9c1 100644 --- a/packages/store-sync/src/sqlite/createSqliteTable.test.ts +++ b/packages/store-sync/src/sqlite/createSqliteTable.test.ts @@ -13,6 +13,24 @@ describe("createSqliteTable", () => { expect(table).toMatchInlineSnapshot(` SQLiteTable { + "__data": SQLiteText { + "config": { + "default": undefined, + "enumValues": [], + "length": undefined, + "name": "__data", + "notNull": true, + "primaryKey": false, + }, + "default": undefined, + "enumValues": [], + "hasDefault": undefined, + "length": undefined, + "name": "__data", + "notNull": true, + "primary": false, + "table": [Circular], + }, "__isDeleted": SQLiteBoolean { "autoIncrement": false, "config": { @@ -140,6 +158,24 @@ describe("createSqliteTable", () => { Symbol(drizzle:OriginalName): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", Symbol(drizzle:Schema): undefined, Symbol(drizzle:Columns): { + "__data": SQLiteText { + "config": { + "default": undefined, + "enumValues": [], + "length": undefined, + "name": "__data", + "notNull": true, + "primaryKey": false, + }, + "default": undefined, + "enumValues": [], + "hasDefault": undefined, + "length": undefined, + "name": "__data", + "notNull": true, + "primary": false, + "table": [Circular], + }, "__isDeleted": SQLiteBoolean { "autoIncrement": false, "config": { @@ -284,6 +320,24 @@ describe("createSqliteTable", () => { expect(table).toMatchInlineSnapshot(` SQLiteTable { + "__data": SQLiteText { + "config": { + "default": undefined, + "enumValues": [], + "length": undefined, + "name": "__data", + "notNull": true, + "primaryKey": false, + }, + "default": undefined, + "enumValues": [], + "hasDefault": undefined, + "length": undefined, + "name": "__data", + "notNull": true, + "primary": false, + "table": [Circular], + }, "__isDeleted": SQLiteBoolean { "autoIncrement": false, "config": { @@ -361,6 +415,24 @@ describe("createSqliteTable", () => { Symbol(drizzle:OriginalName): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", Symbol(drizzle:Schema): undefined, Symbol(drizzle:Columns): { + "__data": SQLiteText { + "config": { + "default": undefined, + "enumValues": [], + "length": undefined, + "name": "__data", + "notNull": true, + "primaryKey": false, + }, + "default": undefined, + "enumValues": [], + "hasDefault": undefined, + "length": undefined, + "name": "__data", + "notNull": true, + "primary": false, + "table": [Circular], + }, "__isDeleted": SQLiteBoolean { "autoIncrement": false, "config": { diff --git a/packages/store-sync/src/sqlite/createSqliteTable.ts b/packages/store-sync/src/sqlite/createSqliteTable.ts index 79f238e9ed..b6b1a0839d 100644 --- a/packages/store-sync/src/sqlite/createSqliteTable.ts +++ b/packages/store-sync/src/sqlite/createSqliteTable.ts @@ -6,6 +6,7 @@ import { getTableName } from "./getTableName"; export const metaColumns = { __key: buildSqliteColumn("__key", "bytes").notNull().primaryKey(), + __data: buildSqliteColumn("__data", "bytes").notNull().notNull(), __lastUpdatedBlockNumber: buildSqliteColumn("__lastUpdatedBlockNumber", "uint256").notNull(), // TODO: last updated block hash? __isDeleted: buildSqliteColumn("__isDeleted", "bool").notNull(), diff --git a/packages/store-sync/src/sqlite/getTables.ts b/packages/store-sync/src/sqlite/getTables.ts index 6d1a4f4d03..9a99afacbf 100644 --- a/packages/store-sync/src/sqlite/getTables.ts +++ b/packages/store-sync/src/sqlite/getTables.ts @@ -1,9 +1,9 @@ import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; import { inArray } from "drizzle-orm"; import { Table } from "../common"; -import { TableId } from "@latticexyz/common/deprecated"; import { getTableName } from "./getTableName"; import { mudStoreTables } from "./internalTables"; +import { tableIdToHex } from "@latticexyz/common"; export function getTables( db: BaseSQLiteDatabase<"sync", void>, @@ -19,7 +19,7 @@ export function getTables( .all(); return tables.map((table) => { - const tableId = new TableId(table.namespace, table.name).toHex(); + const tableId = tableIdToHex(table.namespace, table.name); return { id: getTableName(table.address, table.namespace, table.name), address: table.address, diff --git a/packages/store-sync/src/sqlite/sqliteStorage.test.ts b/packages/store-sync/src/sqlite/sqliteStorage.test.ts index e21cd954e9..4b4224dfc6 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.test.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.test.ts @@ -8,7 +8,6 @@ import initSqlJs from "sql.js"; import { drizzle } from "drizzle-orm/sql-js"; import { createPublicClient, http } from "viem"; import { foundry } from "viem/chains"; -import { blockLogsToStorage } from "../blockLogsToStorage"; describe("sqliteStorage", async () => { const SqlJs = await initSqlJs(); @@ -38,7 +37,7 @@ describe("sqliteStorage", async () => { expect(db.select().from(chainState).all()).toMatchInlineSnapshot("[]"); expect(db.select().from(mudStoreTables).all()).toMatchInlineSnapshot("[]"); - await blockLogsToStorage(storageAdapter)({ + await storageAdapter({ blockNumber: 5448n, logs: [ { @@ -54,10 +53,11 @@ describe("sqliteStorage", async () => { args: { table: "0x000000000000000000000000000000005265736f757263655479706500000000", key: ["0x00000000000000000000000000000000496e76656e746f727900000000000000"], - schemaIndex: 0, data: "0x02", + start: 0, + deleteCount: 0, }, - eventName: "StoreSetField", + eventName: "StoreSpliceRecord", }, { address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index fb2073b11c..79f39955db 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -1,10 +1,8 @@ -import { PublicClient, concatHex, encodeAbiParameters, getAddress } from "viem"; +import { Hex, PublicClient, concatHex, getAddress, size, sliceHex } from "viem"; import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; import { and, eq, sql } from "drizzle-orm"; import { sqliteTableToSql } from "./sqliteTableToSql"; import { createSqliteTable } from "./createSqliteTable"; -import { schemaToDefaults } from "../schemaToDefaults"; -import { TableId } from "@latticexyz/common/deprecated"; import { StoreConfig } from "@latticexyz/store"; import { debug } from "./debug"; import { getTableName } from "./getTableName"; @@ -12,6 +10,12 @@ import { chainState, mudStoreTables } from "./internalTables"; import { getTables } from "./getTables"; import { schemaVersion } from "./schemaVersion"; import { StorageAdapter } from "../common"; +import { isTableRegistrationLog } from "../isTableRegistrationLog"; +import { logToTable } from "../logToTable"; +import { hexToTableId, tableIdToHex } from "@latticexyz/common"; +import { decodeKey, decodeValue } from "@latticexyz/protocol-parser"; + +// TODO: upgrade drizzle and use async sqlite interface for consistency export async function sqliteStorage({ database, @@ -20,170 +24,172 @@ export async function sqliteStorage({ database: BaseSQLiteDatabase<"sync", void>; publicClient: PublicClient; config?: TConfig; -}): Promise> { +}): Promise { const chainId = publicClient.chain?.id ?? (await publicClient.getChainId()); // TODO: should these run lazily before first `registerTables`? database.run(sql.raw(sqliteTableToSql(chainState))); database.run(sql.raw(sqliteTableToSql(mudStoreTables))); - return { - async registerTables({ blockNumber, tables }) { - await database.transaction(async (tx) => { - for (const table of tables) { - debug(`creating table ${table.namespace}:${table.name} for world ${chainId}:${table.address}`); + return async function storeLogs({ blockNumber, logs }) { + // Find table registration logs and create new tables + const newTables = logs.filter(isTableRegistrationLog).map(logToTable); + await database.transaction(async (tx) => { + for (const table of newTables) { + debug(`creating table ${table.namespace}:${table.name} for world ${chainId}:${table.address}`); + + const sqliteTable = createSqliteTable({ + address: table.address, + namespace: table.namespace, + name: table.name, + keySchema: table.keySchema, + valueSchema: table.valueSchema, + }); + + tx.run(sql.raw(sqliteTableToSql(sqliteTable))); - const sqliteTable = createSqliteTable({ + tx.insert(mudStoreTables) + .values({ + schemaVersion, + id: getTableName(table.address, table.namespace, table.name), address: table.address, + tableId: tableIdToHex(table.namespace, table.name), namespace: table.namespace, name: table.name, keySchema: table.keySchema, valueSchema: table.valueSchema, - }); - - tx.run(sql.raw(sqliteTableToSql(sqliteTable))); + lastUpdatedBlockNumber: blockNumber, + }) + .onConflictDoNothing() + .run(); + } + }); - tx.insert(mudStoreTables) - .values({ - schemaVersion, - id: getTableName(table.address, table.namespace, table.name), - address: table.address, - tableId: new TableId(table.namespace, table.name).toHex(), - namespace: table.namespace, - name: table.name, - keySchema: table.keySchema, - valueSchema: table.valueSchema, - lastUpdatedBlockNumber: blockNumber, + const tables = getTables( + database, + Array.from( + new Set( + logs.map((log) => + JSON.stringify({ + address: getAddress(log.address), + ...hexToTableId(log.args.table), }) - .onConflictDoNothing() - .run(); - } - }); - }, - async getTables({ tables }) { - // TODO: fetch any missing schemas from RPC - // TODO: cache schemas in memory? - return getTables(database, tables); - }, - async storeOperations({ blockNumber, operations }) { - // This is currently parallelized per world (each world has its own database). - // This may need to change if we decide to put multiple worlds into one DB (e.g. a namespace per world, but all under one DB). - // If so, we'll probably want to wrap the entire block worth of operations in a transaction. + ) + ) + ).map((json) => JSON.parse(json)) + ); - const tables = getTables( - database, - Array.from( - new Set( - operations.map((operation) => - JSON.stringify({ - address: getAddress(operation.address), - namespace: operation.namespace, - name: operation.name, - }) + await database.transaction(async (tx) => { + for (const { address, namespace, name } of tables) { + tx.update(mudStoreTables) + .set({ lastUpdatedBlockNumber: blockNumber }) + .where( + and( + eq(mudStoreTables.address, address), + eq(mudStoreTables.namespace, namespace), + eq(mudStoreTables.name, name) ) ) - ).map((json) => JSON.parse(json)) - ); + .run(); + } - await database.transaction(async (tx) => { - for (const { address, namespace, name } of tables) { - tx.update(mudStoreTables) - .set({ lastUpdatedBlockNumber: blockNumber }) - .where( - and( - eq(mudStoreTables.address, address), - eq(mudStoreTables.namespace, namespace), - eq(mudStoreTables.name, name) - ) - ) - .run(); + for (const log of logs) { + const table = tables.find( + (table) => table.address === getAddress(log.address) && table.tableId === log.args.table + ); + if (!table) { + const tableId = hexToTableId(log.args.table); + debug(`table ${tableId.namespace}:${tableId.name} not found, skipping log`, log); + continue; } - for (const operation of operations) { - const table = tables.find( - (table) => - table.address === getAddress(operation.address) && - table.namespace === operation.namespace && - table.name === operation.name - ); - if (!table) { - debug(`table ${operation.namespace}:${operation.name} not found, skipping operation`, operation); - continue; - } - - const sqliteTable = createSqliteTable(table); - const key = concatHex( - Object.entries(table.keySchema).map(([keyName, type]) => - encodeAbiParameters([{ type }], [operation.key[keyName]]) - ) - ); + const sqliteTable = createSqliteTable(table); + const uniqueKey = concatHex(log.args.key as Hex[]); + const key = decodeKey(table.keySchema, log.args.key); - if (operation.type === "SetRecord") { - debug("SetRecord", operation); - tx.insert(sqliteTable) - .values({ - __key: key, + if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { + // TODO: figure out if we need to pad anything or set defaults + const value = decodeValue(table.valueSchema, log.args.data); + debug("SetRecord", key, value, log); + tx.insert(sqliteTable) + .values({ + __key: uniqueKey, + __data: log.args.data, + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: false, + ...key, + ...value, + }) + .onConflictDoUpdate({ + target: sqliteTable.__key, + set: { + __data: log.args.data, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, - ...operation.key, - ...operation.value, - }) - .onConflictDoUpdate({ - target: sqliteTable.__key, - set: { - __lastUpdatedBlockNumber: blockNumber, - __isDeleted: false, - ...operation.value, - }, - }) - .run(); - } else if (operation.type === "SetField") { - debug("SetField", operation); - tx.insert(sqliteTable) - .values({ - __key: key, + ...value, + }, + }) + .run(); + } else if (log.eventName === "StoreSpliceRecord") { + // TODO: verify that this returns what we expect (doesn't error/undefined on no record) + const previousData = + tx.select().from(sqliteTable).where(eq(sqliteTable.__key, uniqueKey)).get().__data ?? "0x"; + + // TODO: figure out if we need to pad anything or set defaults + const end = log.args.start + log.args.deleteCount; + const newData = concatHex([ + sliceHex(previousData, 0, log.args.start), + log.args.data, + end >= size(previousData) ? "0x" : sliceHex(previousData, end), + ]); + const newValue = decodeValue(table.valueSchema, newData); + + debug("SpliceRecord", { previousData, newData, newValue, log }); + tx.insert(sqliteTable) + .values({ + __key: key, + __data: newData, + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: false, + ...key, + ...newValue, + }) + .onConflictDoUpdate({ + target: sqliteTable.__key, + set: { + __data: newData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, - ...operation.key, - ...schemaToDefaults(table.valueSchema), - [operation.fieldName]: operation.fieldValue, - }) - .onConflictDoUpdate({ - target: sqliteTable.__key, - set: { - __lastUpdatedBlockNumber: blockNumber, - __isDeleted: false, - [operation.fieldName]: operation.fieldValue, - }, - }) - .run(); - } else if (operation.type === "DeleteRecord") { - // TODO: should we upsert so we at least have a DB record of when a thing was created/deleted within the same block? - debug("DeleteRecord", operation); - tx.update(sqliteTable) - .set({ - __lastUpdatedBlockNumber: blockNumber, - __isDeleted: true, - }) - .where(eq(sqliteTable.__key, key)) - .run(); - } + ...newValue, + }, + }) + .run(); + } else if (log.eventName === "StoreDeleteRecord") { + // TODO: should we upsert so we at least have a DB record of when a thing was created/deleted within the same block? + debug("DeleteRecord", log); + tx.update(sqliteTable) + .set({ + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: true, + }) + .where(eq(sqliteTable.__key, key)) + .run(); } + } - tx.insert(chainState) - .values({ - schemaVersion, - chainId, + tx.insert(chainState) + .values({ + schemaVersion, + chainId, + lastUpdatedBlockNumber: blockNumber, + }) + .onConflictDoUpdate({ + target: [chainState.schemaVersion, chainState.chainId], + set: { lastUpdatedBlockNumber: blockNumber, - }) - .onConflictDoUpdate({ - target: [chainState.schemaVersion, chainState.chainId], - set: { - lastUpdatedBlockNumber: blockNumber, - }, - }) - .run(); - }); - }, - } as StorageAdapter; + }, + }) + .run(); + }); + }; } diff --git a/packages/store-sync/src/sqlite/syncToSqlite.ts b/packages/store-sync/src/sqlite/syncToSqlite.ts index 2da2185bf9..210b9677d0 100644 --- a/packages/store-sync/src/sqlite/syncToSqlite.ts +++ b/packages/store-sync/src/sqlite/syncToSqlite.ts @@ -14,14 +14,14 @@ type SyncToSqliteOptions = SyncOption startSync?: boolean; }; -type SyncToSqliteResult = SyncResult & { +type SyncToSqliteResult = SyncResult & { stopSync: () => void; }; /** * Creates an indexer to process and store blockchain events. * - * @param {CreateIndexerOptions} options See `CreateIndexerOptions`. + * @param {SyncToSqliteOptions} options See `SyncToSqliteOptions`. * @returns A function to unsubscribe from the block stream, effectively stopping the indexer. */ export async function syncToSqlite({ @@ -34,7 +34,7 @@ export async function syncToSqlite({ indexerUrl, initialState, startSync = true, -}: SyncToSqliteOptions): Promise> { +}: SyncToSqliteOptions): Promise { const storeSync = await createStoreSync({ storageAdapter: await sqliteStorage({ database, publicClient, config }), config, @@ -46,7 +46,7 @@ export async function syncToSqlite({ initialState, }); - const sub = startSync ? storeSync.blockStorageOperations$.subscribe() : null; + const sub = startSync ? storeSync.storedBlockLogs$.subscribe() : null; const stopSync = (): void => { sub?.unsubscribe(); }; From 8783b68b9dbb14a9fa83b98f7481a35033ce112b Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Mon, 4 Sep 2023 11:05:27 +0100 Subject: [PATCH 13/69] update postgres adapter --- .../src/postgres/buildTable.test.ts | 92 ++++++ .../store-sync/src/postgres/buildTable.ts | 1 + .../store-sync/src/postgres/getTableKey.ts | 6 +- .../src/postgres/postgresStorage.test.ts | 8 +- .../src/postgres/postgresStorage.ts | 290 ++++++++++-------- .../store-sync/src/postgres/syncToPostgres.ts | 9 +- packages/store-sync/src/recs/recsStorage.ts | 2 +- .../src/sqlite/createSqliteTable.ts | 2 +- .../store-sync/src/sqlite/sqliteStorage.ts | 8 +- 9 files changed, 266 insertions(+), 152 deletions(-) diff --git a/packages/store-sync/src/postgres/buildTable.test.ts b/packages/store-sync/src/postgres/buildTable.test.ts index 5d9d192a88..1fa3ec932e 100644 --- a/packages/store-sync/src/postgres/buildTable.test.ts +++ b/packages/store-sync/src/postgres/buildTable.test.ts @@ -13,6 +13,29 @@ describe("buildTable", () => { expect(table).toMatchInlineSnapshot(` PgTable { + "__data": PgCustomColumn { + "config": { + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "default": undefined, + "fieldConfig": undefined, + "name": "__data", + "notNull": true, + "primaryKey": false, + }, + "default": undefined, + "hasDefault": undefined, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__data", + "notNull": true, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + }, "__isDeleted": PgBoolean { "config": { "default": undefined, @@ -162,6 +185,29 @@ describe("buildTable", () => { Symbol(drizzle:OriginalName): "users", Symbol(drizzle:Schema): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test", Symbol(drizzle:Columns): { + "__data": PgCustomColumn { + "config": { + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "default": undefined, + "fieldConfig": undefined, + "name": "__data", + "notNull": true, + "primaryKey": false, + }, + "default": undefined, + "hasDefault": undefined, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__data", + "notNull": true, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + }, "__isDeleted": PgBoolean { "config": { "default": undefined, @@ -328,6 +374,29 @@ describe("buildTable", () => { expect(table).toMatchInlineSnapshot(` PgTable { + "__data": PgCustomColumn { + "config": { + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "default": undefined, + "fieldConfig": undefined, + "name": "__data", + "notNull": true, + "primaryKey": false, + }, + "default": undefined, + "hasDefault": undefined, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__data", + "notNull": true, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + }, "__isDeleted": PgBoolean { "config": { "default": undefined, @@ -415,6 +484,29 @@ describe("buildTable", () => { Symbol(drizzle:OriginalName): "users", Symbol(drizzle:Schema): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test", Symbol(drizzle:Columns): { + "__data": PgCustomColumn { + "config": { + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "default": undefined, + "fieldConfig": undefined, + "name": "__data", + "notNull": true, + "primaryKey": false, + }, + "default": undefined, + "hasDefault": undefined, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__data", + "notNull": true, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + }, "__isDeleted": PgBoolean { "config": { "default": undefined, diff --git a/packages/store-sync/src/postgres/buildTable.ts b/packages/store-sync/src/postgres/buildTable.ts index 8974900e2a..89f16878b3 100644 --- a/packages/store-sync/src/postgres/buildTable.ts +++ b/packages/store-sync/src/postgres/buildTable.ts @@ -7,6 +7,7 @@ import { transformSchemaName } from "./transformSchemaName"; // TODO: convert camel case to snake case for DB storage? export const metaColumns = { __key: buildColumn("__key", "bytes").notNull().primaryKey(), + __data: buildColumn("__data", "bytes").notNull(), __lastUpdatedBlockNumber: buildColumn("__lastUpdatedBlockNumber", "uint256").notNull(), // TODO: last updated block hash? __isDeleted: buildColumn("__isDeleted", "bool").notNull(), diff --git a/packages/store-sync/src/postgres/getTableKey.ts b/packages/store-sync/src/postgres/getTableKey.ts index 423830ce23..3c58cae80e 100644 --- a/packages/store-sync/src/postgres/getTableKey.ts +++ b/packages/store-sync/src/postgres/getTableKey.ts @@ -1,6 +1,8 @@ import { getAddress } from "viem"; import { Table } from "../common"; +import { hexToTableId } from "@latticexyz/common"; -export function getTableKey(table: Pick): string { - return `${getAddress(table.address)}:${table.namespace}:${table.name}`; +export function getTableKey({ address, tableId }: Pick): string { + const { namespace, name } = hexToTableId(tableId); + return `${getAddress(address)}:${namespace}:${name}`; } diff --git a/packages/store-sync/src/postgres/postgresStorage.test.ts b/packages/store-sync/src/postgres/postgresStorage.test.ts index e3165c7bd7..f69f881a65 100644 --- a/packages/store-sync/src/postgres/postgresStorage.test.ts +++ b/packages/store-sync/src/postgres/postgresStorage.test.ts @@ -4,7 +4,6 @@ import { drizzle } from "drizzle-orm/postgres-js"; import postgres from "postgres"; import { createPublicClient, http } from "viem"; import { foundry } from "viem/chains"; -import { blockLogsToStorage } from "../blockLogsToStorage"; import * as transformSchemaNameExports from "./transformSchemaName"; import { getTables } from "./getTables"; import { PostgresStorageAdapter, postgresStorage } from "./postgresStorage"; @@ -32,7 +31,7 @@ describe("postgresStorage", async () => { }); it("should create tables and data from block log", async () => { - await blockLogsToStorage(storageAdapter)({ + await storageAdapter.storageAdapter({ blockNumber: 5448n, logs: [ { @@ -48,10 +47,11 @@ describe("postgresStorage", async () => { args: { table: "0x000000000000000000000000000000005265736f757263655479706500000000", key: ["0x00000000000000000000000000000000496e76656e746f727900000000000000"], - schemaIndex: 0, data: "0x02", + start: 0, + deleteCount: 0, }, - eventName: "StoreSetField", + eventName: "StoreSpliceRecord", }, { address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index 1937a9796a..ff2ab41c59 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -1,21 +1,24 @@ -import { PublicClient, concatHex, encodeAbiParameters } from "viem"; +import { Hex, PublicClient, concatHex, size, sliceHex } from "viem"; import { PgDatabase, QueryResultHKT } from "drizzle-orm/pg-core"; import { eq, inArray } from "drizzle-orm"; import { buildTable } from "./buildTable"; -import { schemaToDefaults } from "../schemaToDefaults"; import { StoreConfig } from "@latticexyz/store"; import { debug } from "./debug"; import { buildInternalTables } from "./buildInternalTables"; import { getTables } from "./getTables"; import { schemaVersion } from "./schemaVersion"; -import { tableIdToHex } from "@latticexyz/common"; +import { hexToTableId, tableIdToHex } from "@latticexyz/common"; import { setupTables } from "./setupTables"; import { getTableKey } from "./getTableKey"; -import { StorageAdapter } from "../common"; +import { StorageAdapter, StorageAdapterBlock } from "../common"; +import { isTableRegistrationLog } from "../isTableRegistrationLog"; +import { logToTable } from "../logToTable"; +import { decodeKey, decodeValue } from "@latticexyz/protocol-parser"; // Currently assumes one DB per chain ID -export type PostgresStorageAdapter = StorageAdapter & { +export type PostgresStorageAdapter = { + storageAdapter: StorageAdapter; internalTables: ReturnType; cleanUp: () => Promise; }; @@ -27,7 +30,7 @@ export async function postgresStorage database: PgDatabase; publicClient: PublicClient; config?: TConfig; -}): Promise> { +}): Promise { const cleanUp: (() => Promise)[] = []; const chainId = publicClient.chain?.id ?? (await publicClient.getChainId()); @@ -35,153 +38,168 @@ export async function postgresStorage const internalTables = buildInternalTables(); cleanUp.push(await setupTables(database, Object.values(internalTables))); - const storageAdapter = { - async registerTables({ blockNumber, tables }) { - const sqlTables = tables.map((table) => - buildTable({ - address: table.address, - namespace: table.namespace, - name: table.name, - keySchema: table.keySchema, - valueSchema: table.valueSchema, - }) + async function postgresStorageAdapter({ blockNumber, logs }: StorageAdapterBlock): Promise { + const newTables = logs.filter(isTableRegistrationLog).map(logToTable); + const newSqlTables = newTables.map((table) => + buildTable({ + address: table.address, + namespace: table.namespace, + name: table.name, + keySchema: table.keySchema, + valueSchema: table.valueSchema, + }) + ); + + cleanUp.push(await setupTables(database, newSqlTables)); + + await database.transaction(async (tx) => { + for (const table of newTables) { + await tx + .insert(internalTables.tables) + .values({ + schemaVersion, + key: getTableKey(table), + address: table.address, + tableId: tableIdToHex(table.namespace, table.name), + namespace: table.namespace, + name: table.name, + keySchema: table.keySchema, + valueSchema: table.valueSchema, + lastUpdatedBlockNumber: blockNumber, + }) + .onConflictDoNothing() + .execute(); + } + }); + + const tables = await getTables( + database, + logs.map((log) => getTableKey({ address: log.address, tableId: log.args.table })) + ); + + // This is currently parallelized per world (each world has its own database). + // This may need to change if we decide to put multiple worlds into one DB (e.g. a namespace per world, but all under one DB). + // If so, we'll probably want to wrap the entire block worth of operations in a transaction. + + await database.transaction(async (tx) => { + const tablesWithOperations = tables.filter((table) => + logs.some((log) => getTableKey({ address: log.address, tableId: log.args.table }) === getTableKey(table)) ); + if (tablesWithOperations.length) { + await tx + .update(internalTables.tables) + .set({ lastUpdatedBlockNumber: blockNumber }) + .where(inArray(internalTables.tables.key, [...new Set(tablesWithOperations.map(getTableKey))])) + .execute(); + } + + for (const log of logs) { + const table = tables.find( + (table) => getTableKey(table) === getTableKey({ address: log.address, tableId: log.args.table }) + ); + if (!table) { + const { namespace, name } = hexToTableId(log.args.table); + debug(`table ${namespace}:${name} not found, skipping log`, log); + continue; + } - cleanUp.push(await setupTables(database, sqlTables)); + const sqlTable = buildTable(table); + const uniqueKey = concatHex(log.args.key as Hex[]); + const key = decodeKey(table.keySchema, log.args.key); - await database.transaction(async (tx) => { - for (const table of tables) { + debug(log.eventName, log); + + if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { + const value = decodeValue(table.valueSchema, log.args.data); + debug("upserting record", { key, value, log }); await tx - .insert(internalTables.tables) + .insert(sqlTable) .values({ - schemaVersion, - key: getTableKey(table), - address: table.address, - tableId: tableIdToHex(table.namespace, table.name), - namespace: table.namespace, - name: table.name, - keySchema: table.keySchema, - valueSchema: table.valueSchema, - lastUpdatedBlockNumber: blockNumber, + __key: uniqueKey, + __data: log.args.data, + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: false, + ...key, + ...value, + }) + .onConflictDoUpdate({ + target: sqlTable.__key, + set: { + __data: log.args.data, + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: false, + ...value, + }, }) - .onConflictDoNothing() .execute(); - } - }); - }, - async getTables({ tables }) { - // TODO: fetch any missing schemas from RPC - // TODO: cache schemas in memory? - return getTables(database, tables.map(getTableKey)); - }, - async storeOperations({ blockNumber, operations }) { - // This is currently parallelized per world (each world has its own database). - // This may need to change if we decide to put multiple worlds into one DB (e.g. a namespace per world, but all under one DB). - // If so, we'll probably want to wrap the entire block worth of operations in a transaction. + } else if (log.eventName === "StoreSpliceRecord") { + // TODO: verify that this returns what we expect (doesn't error/undefined on no record) + const previousData = + (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]?.__data ?? "0x"; - const tables = await getTables(database, operations.map(getTableKey)); + // TODO: figure out if we need to pad anything or set defaults + const end = log.args.start + log.args.deleteCount; + const newData = concatHex([ + sliceHex(previousData, 0, log.args.start), + log.args.data, + end >= size(previousData) ? "0x" : sliceHex(previousData, end), + ]); + const newValue = decodeValue(table.valueSchema, newData); - await database.transaction(async (tx) => { - const tablesWithOperations = tables.filter((table) => - operations.some((op) => getTableKey(op) === getTableKey(table)) - ); - if (tablesWithOperations.length) { + debug("upserting record via splice", { key, previousData, newData, newValue, log }); await tx - .update(internalTables.tables) - .set({ lastUpdatedBlockNumber: blockNumber }) - .where(inArray(internalTables.tables.key, [...new Set(tablesWithOperations.map(getTableKey))])) - .execute(); - } - - for (const operation of operations) { - const table = tables.find((table) => getTableKey(table) === getTableKey(operation)); - if (!table) { - debug(`table ${operation.namespace}:${operation.name} not found, skipping operation`, operation); - continue; - } - - const sqlTable = buildTable(table); - const key = concatHex( - Object.entries(table.keySchema).map(([keyName, type]) => - encodeAbiParameters([{ type }], [operation.key[keyName]]) - ) - ); - - if (operation.type === "SetRecord") { - debug("SetRecord", operation); - await tx - .insert(sqlTable) - .values({ - __key: key, - __lastUpdatedBlockNumber: blockNumber, - __isDeleted: false, - ...operation.key, - ...operation.value, - }) - .onConflictDoUpdate({ - target: sqlTable.__key, - set: { - __lastUpdatedBlockNumber: blockNumber, - __isDeleted: false, - ...operation.value, - }, - }) - .execute(); - } else if (operation.type === "SetField") { - debug("SetField", operation); - await tx - .insert(sqlTable) - .values({ - __key: key, + .insert(sqlTable) + .values({ + __key: key, + __data: newData, + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: false, + ...key, + ...newValue, + }) + .onConflictDoUpdate({ + target: sqlTable.__key, + set: { + __data: newData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, - ...operation.key, - ...schemaToDefaults(table.valueSchema), - [operation.fieldName]: operation.fieldValue, - }) - .onConflictDoUpdate({ - target: sqlTable.__key, - set: { - __lastUpdatedBlockNumber: blockNumber, - __isDeleted: false, - [operation.fieldName]: operation.fieldValue, - }, - }) - .execute(); - } else if (operation.type === "DeleteRecord") { - // TODO: should we upsert so we at least have a DB record of when a thing was created/deleted within the same block? - debug("DeleteRecord", operation); - await tx - .update(sqlTable) - .set({ - __lastUpdatedBlockNumber: blockNumber, - __isDeleted: true, - }) - .where(eq(sqlTable.__key, key)) - .execute(); - } + ...newValue, + }, + }) + .execute(); + } else if (log.eventName === "StoreDeleteRecord") { + // TODO: should we upsert so we at least have a DB record of when a thing was created/deleted within the same block? + debug("deleting record", { key, log }); + await tx + .update(sqlTable) + .set({ + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: true, + }) + .where(eq(sqlTable.__key, key)) + .execute(); } + } - await tx - .insert(internalTables.chain) - .values({ - schemaVersion, - chainId, + await tx + .insert(internalTables.chain) + .values({ + schemaVersion, + chainId, + lastUpdatedBlockNumber: blockNumber, + }) + .onConflictDoUpdate({ + target: [internalTables.chain.schemaVersion, internalTables.chain.chainId], + set: { lastUpdatedBlockNumber: blockNumber, - }) - .onConflictDoUpdate({ - target: [internalTables.chain.schemaVersion, internalTables.chain.chainId], - set: { - lastUpdatedBlockNumber: blockNumber, - }, - }) - .execute(); - }); - }, - } as StorageAdapter; + }, + }) + .execute(); + }); + } return { - ...storageAdapter, + storageAdapter: postgresStorageAdapter, internalTables, cleanUp: async (): Promise => { for (const fn of cleanUp) { diff --git a/packages/store-sync/src/postgres/syncToPostgres.ts b/packages/store-sync/src/postgres/syncToPostgres.ts index be649f4e78..1042ab2832 100644 --- a/packages/store-sync/src/postgres/syncToPostgres.ts +++ b/packages/store-sync/src/postgres/syncToPostgres.ts @@ -14,7 +14,7 @@ type SyncToPostgresOptions = SyncOpti startSync?: boolean; }; -type SyncToPostgresResult = SyncResult & { +type SyncToPostgresResult = SyncResult & { stopSync: () => void; }; @@ -34,9 +34,10 @@ export async function syncToPostgres( indexerUrl, initialState, startSync = true, -}: SyncToPostgresOptions): Promise> { +}: SyncToPostgresOptions): Promise { + const { storageAdapter } = await postgresStorage({ database, publicClient, config }); const storeSync = await createStoreSync({ - storageAdapter: await postgresStorage({ database, publicClient, config }), + storageAdapter, config, address, publicClient, @@ -46,7 +47,7 @@ export async function syncToPostgres( initialState, }); - const sub = startSync ? storeSync.blockStorageOperations$.subscribe() : null; + const sub = startSync ? storeSync.storedBlockLogs$.subscribe() : null; const stopSync = (): void => { sub?.unsubscribe(); }; diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index ee3d874e6f..c5b4d98989 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -33,7 +33,7 @@ export function recsStorage({ Object.entries(components).map(([id, component]) => [component.id, component]) ); - return async function storeLogs({ logs }) { + return async function recsStorageAdapter({ logs }) { const newTables = logs.filter(isTableRegistrationLog).map(logToTable); for (const newTable of newTables) { const tableEntity = getTableEntity(newTable); diff --git a/packages/store-sync/src/sqlite/createSqliteTable.ts b/packages/store-sync/src/sqlite/createSqliteTable.ts index b6b1a0839d..e4b02e94a4 100644 --- a/packages/store-sync/src/sqlite/createSqliteTable.ts +++ b/packages/store-sync/src/sqlite/createSqliteTable.ts @@ -6,7 +6,7 @@ import { getTableName } from "./getTableName"; export const metaColumns = { __key: buildSqliteColumn("__key", "bytes").notNull().primaryKey(), - __data: buildSqliteColumn("__data", "bytes").notNull().notNull(), + __data: buildSqliteColumn("__data", "bytes").notNull(), __lastUpdatedBlockNumber: buildSqliteColumn("__lastUpdatedBlockNumber", "uint256").notNull(), // TODO: last updated block hash? __isDeleted: buildSqliteColumn("__isDeleted", "bool").notNull(), diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 79f39955db..0795d7a6b6 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -31,7 +31,7 @@ export async function sqliteStorage({ database.run(sql.raw(sqliteTableToSql(chainState))); database.run(sql.raw(sqliteTableToSql(mudStoreTables))); - return async function storeLogs({ blockNumber, logs }) { + return async function sqliteStorageAdapter({ blockNumber, logs }) { // Find table registration logs and create new tables const newTables = logs.filter(isTableRegistrationLog).map(logToTable); await database.transaction(async (tx) => { @@ -110,7 +110,7 @@ export async function sqliteStorage({ if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { // TODO: figure out if we need to pad anything or set defaults const value = decodeValue(table.valueSchema, log.args.data); - debug("SetRecord", key, value, log); + debug("upserting record", { key, value, log }); tx.insert(sqliteTable) .values({ __key: uniqueKey, @@ -144,7 +144,7 @@ export async function sqliteStorage({ ]); const newValue = decodeValue(table.valueSchema, newData); - debug("SpliceRecord", { previousData, newData, newValue, log }); + debug("upserting record via splice", { key, previousData, newData, newValue, log }); tx.insert(sqliteTable) .values({ __key: key, @@ -166,7 +166,7 @@ export async function sqliteStorage({ .run(); } else if (log.eventName === "StoreDeleteRecord") { // TODO: should we upsert so we at least have a DB record of when a thing was created/deleted within the same block? - debug("DeleteRecord", log); + debug("deleting record", { key, log }); tx.update(sqliteTable) .set({ __lastUpdatedBlockNumber: blockNumber, From 3a30ac8b7d50a83f3cb3ad14a3f1ecee5264c030 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Mon, 4 Sep 2023 11:32:19 +0100 Subject: [PATCH 14/69] blockStorageOperations$ -> storedBlockLogs$ --- .../packages/client-phaser/src/mud/setupNetwork.ts | 4 ++-- .../minimal/packages/client-phaser/src/ui/App.tsx | 2 +- .../minimal/packages/client-react/src/index.tsx | 2 +- .../packages/client-react/src/mud/setupNetwork.ts | 4 ++-- .../minimal/packages/client-vanilla/src/index.ts | 2 +- .../client-vanilla/src/mud/setupNetwork.ts | 4 ++-- packages/dev-tools/README.md | 2 +- packages/dev-tools/src/DevToolsContext.tsx | 14 +++++++------- packages/dev-tools/src/common.ts | 4 ++-- packages/store-indexer/bin/postgres-indexer.ts | 10 +++++----- packages/store-indexer/bin/sqlite-indexer.ts | 4 ++-- .../phaser/packages/client/src/mud/setupNetwork.ts | 4 ++-- templates/phaser/packages/client/src/ui/App.tsx | 2 +- templates/react/packages/client/src/index.tsx | 2 +- .../react/packages/client/src/mud/setupNetwork.ts | 4 ++-- templates/threejs/packages/client/src/index.tsx | 2 +- .../packages/client/src/mud/setupNetwork.ts | 4 ++-- templates/vanilla/packages/client/src/index.ts | 2 +- .../packages/client/src/mud/setupNetwork.ts | 4 ++-- 19 files changed, 38 insertions(+), 38 deletions(-) diff --git a/examples/minimal/packages/client-phaser/src/mud/setupNetwork.ts b/examples/minimal/packages/client-phaser/src/mud/setupNetwork.ts index 7272b874db..742446a838 100644 --- a/examples/minimal/packages/client-phaser/src/mud/setupNetwork.ts +++ b/examples/minimal/packages/client-phaser/src/mud/setupNetwork.ts @@ -36,7 +36,7 @@ export async function setupNetwork() { onWrite: (write) => write$.next(write), }); - const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + const { components, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToRecs({ world, config: mudConfig, address: networkConfig.worldAddress as Hex, @@ -75,7 +75,7 @@ export async function setupNetwork() { publicClient, walletClient: burnerWalletClient, latestBlock$, - blockStorageOperations$, + storedBlockLogs$, waitForTransaction, worldContract, write$: write$.asObservable().pipe(share()), diff --git a/examples/minimal/packages/client-phaser/src/ui/App.tsx b/examples/minimal/packages/client-phaser/src/ui/App.tsx index 314e5572d4..69529815b5 100644 --- a/examples/minimal/packages/client-phaser/src/ui/App.tsx +++ b/examples/minimal/packages/client-phaser/src/ui/App.tsx @@ -21,7 +21,7 @@ export const App = () => { publicClient: networkLayer.network.publicClient, walletClient: networkLayer.network.walletClient, latestBlock$: networkLayer.network.latestBlock$, - blockStorageOperations$: networkLayer.network.blockStorageOperations$, + storedBlockLogs$: networkLayer.network.storedBlockLogs$, worldAddress: networkLayer.network.worldContract.address, worldAbi: networkLayer.network.worldContract.abi, write$: networkLayer.network.write$, diff --git a/examples/minimal/packages/client-react/src/index.tsx b/examples/minimal/packages/client-react/src/index.tsx index 9b3f9121e1..da8d70f020 100644 --- a/examples/minimal/packages/client-react/src/index.tsx +++ b/examples/minimal/packages/client-react/src/index.tsx @@ -24,7 +24,7 @@ setup().then(async (result) => { publicClient: result.network.publicClient, walletClient: result.network.walletClient, latestBlock$: result.network.latestBlock$, - blockStorageOperations$: result.network.blockStorageOperations$, + storedBlockLogs$: result.network.storedBlockLogs$, worldAddress: result.network.worldContract.address, worldAbi: result.network.worldContract.abi, write$: result.network.write$, diff --git a/examples/minimal/packages/client-react/src/mud/setupNetwork.ts b/examples/minimal/packages/client-react/src/mud/setupNetwork.ts index 5f5736104a..d67d75aa53 100644 --- a/examples/minimal/packages/client-react/src/mud/setupNetwork.ts +++ b/examples/minimal/packages/client-react/src/mud/setupNetwork.ts @@ -36,7 +36,7 @@ export async function setupNetwork() { onWrite: (write) => write$.next(write), }); - const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + const { components, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToRecs({ world, config: mudConfig, address: networkConfig.worldAddress as Hex, @@ -75,7 +75,7 @@ export async function setupNetwork() { publicClient, walletClient: burnerWalletClient, latestBlock$, - blockStorageOperations$, + storedBlockLogs$, waitForTransaction, worldContract, write$: write$.asObservable().pipe(share()), diff --git a/examples/minimal/packages/client-vanilla/src/index.ts b/examples/minimal/packages/client-vanilla/src/index.ts index fe63aa1950..8666b71a68 100644 --- a/examples/minimal/packages/client-vanilla/src/index.ts +++ b/examples/minimal/packages/client-vanilla/src/index.ts @@ -62,7 +62,7 @@ if (import.meta.env.DEV) { publicClient: network.publicClient, walletClient: network.walletClient, latestBlock$: network.latestBlock$, - blockStorageOperations$: network.blockStorageOperations$, + storedBlockLogs$: network.storedBlockLogs$, worldAddress: network.worldContract.address, worldAbi: network.worldContract.abi, write$: network.write$, diff --git a/examples/minimal/packages/client-vanilla/src/mud/setupNetwork.ts b/examples/minimal/packages/client-vanilla/src/mud/setupNetwork.ts index 7272b874db..742446a838 100644 --- a/examples/minimal/packages/client-vanilla/src/mud/setupNetwork.ts +++ b/examples/minimal/packages/client-vanilla/src/mud/setupNetwork.ts @@ -36,7 +36,7 @@ export async function setupNetwork() { onWrite: (write) => write$.next(write), }); - const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + const { components, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToRecs({ world, config: mudConfig, address: networkConfig.worldAddress as Hex, @@ -75,7 +75,7 @@ export async function setupNetwork() { publicClient, walletClient: burnerWalletClient, latestBlock$, - blockStorageOperations$, + storedBlockLogs$, waitForTransaction, worldContract, write$: write$.asObservable().pipe(share()), diff --git a/packages/dev-tools/README.md b/packages/dev-tools/README.md index cbab052e80..2b3da880e7 100644 --- a/packages/dev-tools/README.md +++ b/packages/dev-tools/README.md @@ -21,7 +21,7 @@ if (import.meta.env.DEV) { publicClient, walletClient, latestBlock$, - blockStorageOperations$, + storedBlockLogs$, worldAddress, worldAbi, write$, diff --git a/packages/dev-tools/src/DevToolsContext.tsx b/packages/dev-tools/src/DevToolsContext.tsx index 8a9d359e1f..fb6ba1c27a 100644 --- a/packages/dev-tools/src/DevToolsContext.tsx +++ b/packages/dev-tools/src/DevToolsContext.tsx @@ -1,12 +1,12 @@ import { createContext, ReactNode, useContext, useEffect, useState } from "react"; import { DevToolsOptions } from "./common"; import { ContractWrite } from "@latticexyz/common"; -import { StorageOperation } from "@latticexyz/store-sync"; +import { StorageAdapterLog, StorageOperation } from "@latticexyz/store-sync"; import { StoreConfig } from "@latticexyz/store"; type DevToolsContextValue = DevToolsOptions & { writes: ContractWrite[]; - storageOperations: StorageOperation[]; + storedLogs: StorageAdapterLog[]; }; const DevToolsContext = createContext(null); @@ -28,20 +28,20 @@ export const DevToolsProvider = ({ children, value }: Props) => { return () => sub.unsubscribe(); }, [value.write$]); - const [storageOperations, setStorageOperations] = useState[]>([]); + const [storedLogs, setStoredLogs] = useState([]); useEffect(() => { - const sub = value.blockStorageOperations$.subscribe(({ operations }) => { - setStorageOperations((val) => [...val, ...operations]); + const sub = value.storedBlockLogs$.subscribe(({ logs }) => { + setStoredLogs((val) => [...val, ...logs]); }); return () => sub.unsubscribe(); - }, [value.blockStorageOperations$]); + }, [value.storedBlockLogs$]); return ( {children} diff --git a/packages/dev-tools/src/common.ts b/packages/dev-tools/src/common.ts index 8ecbcac88c..42475fbab3 100644 --- a/packages/dev-tools/src/common.ts +++ b/packages/dev-tools/src/common.ts @@ -1,7 +1,7 @@ import { Observable } from "rxjs"; import { Abi, Block, Chain, PublicClient, Transport, WalletClient } from "viem"; import { StoreConfig } from "@latticexyz/store"; -import { BlockStorageOperations } from "@latticexyz/store-sync"; +import { StorageAdapterBlock } from "@latticexyz/store-sync"; import { ContractWrite } from "@latticexyz/common"; import { World as RecsWorld } from "@latticexyz/recs"; @@ -10,7 +10,7 @@ export type DevToolsOptions = { publicClient: PublicClient; walletClient: WalletClient; latestBlock$: Observable; - blockStorageOperations$: Observable>; + storedBlockLogs$: Observable; worldAddress: string | null; worldAbi: Abi; write$: Observable; diff --git a/packages/store-indexer/bin/postgres-indexer.ts b/packages/store-indexer/bin/postgres-indexer.ts index 9a7ea96d1e..8370b10338 100644 --- a/packages/store-indexer/bin/postgres-indexer.ts +++ b/packages/store-indexer/bin/postgres-indexer.ts @@ -67,14 +67,14 @@ const database = drizzle(postgres(env.DATABASE_URL), { let startBlock = env.START_BLOCK; -const storageAdapter = await postgresStorage({ database, publicClient }); +const { storageAdapter, internalTables } = await postgresStorage({ database, publicClient }); // Resume from latest block stored in DB. This will throw if the DB doesn't exist yet, so we wrap in a try/catch and ignore the error. try { const currentChainStates = await database .select() - .from(storageAdapter.internalTables.chain) - .where(eq(storageAdapter.internalTables.chain.chainId, chainId)) + .from(internalTables.chain) + .where(eq(internalTables.chain.chainId, chainId)) .execute(); // TODO: replace this type workaround with `noUncheckedIndexedAccess: true` when we can fix all the issues related (https://github.com/latticexyz/mud/issues/1212) const currentChainState: (typeof currentChainStates)[number] | undefined = currentChainStates[0]; @@ -98,14 +98,14 @@ try { // ignore errors, this is optional } -const { latestBlockNumber$, blockStorageOperations$ } = await createStoreSync({ +const { latestBlockNumber$, storedBlockLogs$ } = await createStoreSync({ storageAdapter, publicClient, startBlock, maxBlockRange: env.MAX_BLOCK_RANGE, }); -combineLatest([latestBlockNumber$, blockStorageOperations$]) +combineLatest([latestBlockNumber$, storedBlockLogs$]) .pipe( filter( ([latestBlockNumber, { blockNumber: lastBlockNumberProcessed }]) => latestBlockNumber === lastBlockNumberProcessed diff --git a/packages/store-indexer/bin/sqlite-indexer.ts b/packages/store-indexer/bin/sqlite-indexer.ts index 1433768aef..7cdaa50c87 100644 --- a/packages/store-indexer/bin/sqlite-indexer.ts +++ b/packages/store-indexer/bin/sqlite-indexer.ts @@ -90,14 +90,14 @@ try { // ignore errors, this is optional } -const { latestBlockNumber$, blockStorageOperations$ } = await syncToSqlite({ +const { latestBlockNumber$, storedBlockLogs$ } = await syncToSqlite({ database, publicClient, startBlock, maxBlockRange: env.MAX_BLOCK_RANGE, }); -combineLatest([latestBlockNumber$, blockStorageOperations$]) +combineLatest([latestBlockNumber$, storedBlockLogs$]) .pipe( filter( ([latestBlockNumber, { blockNumber: lastBlockNumberProcessed }]) => latestBlockNumber === lastBlockNumberProcessed diff --git a/templates/phaser/packages/client/src/mud/setupNetwork.ts b/templates/phaser/packages/client/src/mud/setupNetwork.ts index 7272b874db..742446a838 100644 --- a/templates/phaser/packages/client/src/mud/setupNetwork.ts +++ b/templates/phaser/packages/client/src/mud/setupNetwork.ts @@ -36,7 +36,7 @@ export async function setupNetwork() { onWrite: (write) => write$.next(write), }); - const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + const { components, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToRecs({ world, config: mudConfig, address: networkConfig.worldAddress as Hex, @@ -75,7 +75,7 @@ export async function setupNetwork() { publicClient, walletClient: burnerWalletClient, latestBlock$, - blockStorageOperations$, + storedBlockLogs$, waitForTransaction, worldContract, write$: write$.asObservable().pipe(share()), diff --git a/templates/phaser/packages/client/src/ui/App.tsx b/templates/phaser/packages/client/src/ui/App.tsx index 47c66ae8f8..a61f2ba87e 100644 --- a/templates/phaser/packages/client/src/ui/App.tsx +++ b/templates/phaser/packages/client/src/ui/App.tsx @@ -21,7 +21,7 @@ export const App = () => { publicClient: networkLayer.network.publicClient, walletClient: networkLayer.network.walletClient, latestBlock$: networkLayer.network.latestBlock$, - blockStorageOperations$: networkLayer.network.blockStorageOperations$, + storedBlockLogs$: networkLayer.network.storedBlockLogs$, worldAddress: networkLayer.network.worldContract.address, worldAbi: networkLayer.network.worldContract.abi, write$: networkLayer.network.write$, diff --git a/templates/react/packages/client/src/index.tsx b/templates/react/packages/client/src/index.tsx index 9b3f9121e1..da8d70f020 100644 --- a/templates/react/packages/client/src/index.tsx +++ b/templates/react/packages/client/src/index.tsx @@ -24,7 +24,7 @@ setup().then(async (result) => { publicClient: result.network.publicClient, walletClient: result.network.walletClient, latestBlock$: result.network.latestBlock$, - blockStorageOperations$: result.network.blockStorageOperations$, + storedBlockLogs$: result.network.storedBlockLogs$, worldAddress: result.network.worldContract.address, worldAbi: result.network.worldContract.abi, write$: result.network.write$, diff --git a/templates/react/packages/client/src/mud/setupNetwork.ts b/templates/react/packages/client/src/mud/setupNetwork.ts index 7272b874db..742446a838 100644 --- a/templates/react/packages/client/src/mud/setupNetwork.ts +++ b/templates/react/packages/client/src/mud/setupNetwork.ts @@ -36,7 +36,7 @@ export async function setupNetwork() { onWrite: (write) => write$.next(write), }); - const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + const { components, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToRecs({ world, config: mudConfig, address: networkConfig.worldAddress as Hex, @@ -75,7 +75,7 @@ export async function setupNetwork() { publicClient, walletClient: burnerWalletClient, latestBlock$, - blockStorageOperations$, + storedBlockLogs$, waitForTransaction, worldContract, write$: write$.asObservable().pipe(share()), diff --git a/templates/threejs/packages/client/src/index.tsx b/templates/threejs/packages/client/src/index.tsx index 9b3f9121e1..da8d70f020 100644 --- a/templates/threejs/packages/client/src/index.tsx +++ b/templates/threejs/packages/client/src/index.tsx @@ -24,7 +24,7 @@ setup().then(async (result) => { publicClient: result.network.publicClient, walletClient: result.network.walletClient, latestBlock$: result.network.latestBlock$, - blockStorageOperations$: result.network.blockStorageOperations$, + storedBlockLogs$: result.network.storedBlockLogs$, worldAddress: result.network.worldContract.address, worldAbi: result.network.worldContract.abi, write$: result.network.write$, diff --git a/templates/threejs/packages/client/src/mud/setupNetwork.ts b/templates/threejs/packages/client/src/mud/setupNetwork.ts index 7272b874db..742446a838 100644 --- a/templates/threejs/packages/client/src/mud/setupNetwork.ts +++ b/templates/threejs/packages/client/src/mud/setupNetwork.ts @@ -36,7 +36,7 @@ export async function setupNetwork() { onWrite: (write) => write$.next(write), }); - const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + const { components, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToRecs({ world, config: mudConfig, address: networkConfig.worldAddress as Hex, @@ -75,7 +75,7 @@ export async function setupNetwork() { publicClient, walletClient: burnerWalletClient, latestBlock$, - blockStorageOperations$, + storedBlockLogs$, waitForTransaction, worldContract, write$: write$.asObservable().pipe(share()), diff --git a/templates/vanilla/packages/client/src/index.ts b/templates/vanilla/packages/client/src/index.ts index 71b05b1f8d..0c7dda5720 100644 --- a/templates/vanilla/packages/client/src/index.ts +++ b/templates/vanilla/packages/client/src/index.ts @@ -28,7 +28,7 @@ if (import.meta.env.DEV) { publicClient: network.publicClient, walletClient: network.walletClient, latestBlock$: network.latestBlock$, - blockStorageOperations$: network.blockStorageOperations$, + storedBlockLogs$: network.storedBlockLogs$, worldAddress: network.worldContract.address, worldAbi: network.worldContract.abi, write$: network.write$, diff --git a/templates/vanilla/packages/client/src/mud/setupNetwork.ts b/templates/vanilla/packages/client/src/mud/setupNetwork.ts index 7272b874db..742446a838 100644 --- a/templates/vanilla/packages/client/src/mud/setupNetwork.ts +++ b/templates/vanilla/packages/client/src/mud/setupNetwork.ts @@ -36,7 +36,7 @@ export async function setupNetwork() { onWrite: (write) => write$.next(write), }); - const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + const { components, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToRecs({ world, config: mudConfig, address: networkConfig.worldAddress as Hex, @@ -75,7 +75,7 @@ export async function setupNetwork() { publicClient, walletClient: burnerWalletClient, latestBlock$, - blockStorageOperations$, + storedBlockLogs$, waitForTransaction, worldContract, write$: write$.asObservable().pipe(share()), From c3366e883846e7a3d445b5466fb74e2c8e7add08 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Mon, 4 Sep 2023 11:39:59 +0100 Subject: [PATCH 15/69] update dev tools --- packages/dev-tools/src/events/EventIcon.tsx | 17 +++--- packages/dev-tools/src/events/EventsPage.tsx | 8 +-- packages/dev-tools/src/events/LogsTable.tsx | 57 +++++++++++++++++++ .../src/events/StorageOperationsTable.tsx | 53 ----------------- .../dev-tools/src/summary/EventsSummary.tsx | 6 +- 5 files changed, 72 insertions(+), 69 deletions(-) create mode 100644 packages/dev-tools/src/events/LogsTable.tsx delete mode 100644 packages/dev-tools/src/events/StorageOperationsTable.tsx diff --git a/packages/dev-tools/src/events/EventIcon.tsx b/packages/dev-tools/src/events/EventIcon.tsx index 8b6aa682e3..afcf3e3117 100644 --- a/packages/dev-tools/src/events/EventIcon.tsx +++ b/packages/dev-tools/src/events/EventIcon.tsx @@ -1,22 +1,21 @@ import { assertExhaustive } from "@latticexyz/common/utils"; -import { StoreConfig } from "@latticexyz/store"; -import { StorageOperation } from "@latticexyz/store-sync"; +import { StorageAdapterLog } from "@latticexyz/store-sync"; type Props = { - type: StorageOperation["type"]; + type: StorageAdapterLog["eventName"]; }; export function EventIcon({ type }: Props) { switch (type) { - case "SetRecord": + case "StoreSetRecord": return =; - case "SetField": + case "StoreSpliceRecord": return +; - case "DeleteRecord": + case "StoreDeleteRecord": return -; - // case "EphemeralRecord": - // return ~; + case "StoreEphemeralRecord": + return ~; default: - return assertExhaustive(type, `Unexpected storage operation type: ${type}`); + return assertExhaustive(type, `Unexpected event type: ${type}`); } } diff --git a/packages/dev-tools/src/events/EventsPage.tsx b/packages/dev-tools/src/events/EventsPage.tsx index 59e3f21888..e07a463810 100644 --- a/packages/dev-tools/src/events/EventsPage.tsx +++ b/packages/dev-tools/src/events/EventsPage.tsx @@ -1,9 +1,9 @@ import { useRef, useEffect } from "react"; import { useDevToolsContext } from "../DevToolsContext"; -import { StorageOperationsTable } from "./StorageOperationsTable"; +import { LogsTable } from "./LogsTable"; export function EventsPage() { - const { storageOperations } = useDevToolsContext(); + const { storedLogs } = useDevToolsContext(); const containerRef = useRef(null); const hoveredRef = useRef(false); const scrollBehaviorRef = useRef("auto"); @@ -13,7 +13,7 @@ export function EventsPage() { containerRef.current?.scrollIntoView({ behavior: scrollBehaviorRef.current, block: "end" }); } scrollBehaviorRef.current = "smooth"; - }, [storageOperations]); + }, [storedLogs]); return (
- +
); } diff --git a/packages/dev-tools/src/events/LogsTable.tsx b/packages/dev-tools/src/events/LogsTable.tsx new file mode 100644 index 0000000000..7d855e1a33 --- /dev/null +++ b/packages/dev-tools/src/events/LogsTable.tsx @@ -0,0 +1,57 @@ +import { StorageAdapterLog } from "@latticexyz/store-sync"; +import { serialize } from "../serialize"; +import { EventIcon } from "./EventIcon"; +import { hexToTableId } from "@latticexyz/common"; + +// TODO: use react-table or similar for better perf with lots of logs + +type Props = { + logs: StorageAdapterLog[]; +}; + +export function LogsTable({ logs }: Props) { + return ( + + + + + + + + + + + + {logs.map((log) => { + const { namespace, name } = hexToTableId(log.args.table); + return ( + + + + + + + + ); + })} + +
blocktablekeyvalue
+ {log.blockNumber?.toString()} + + {namespace}:{name} + {log.args.key.join(",")} + + + {/* TODO: decode these values if we can */} + {log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord" ? log.args.data : null} + {log.eventName === "StoreSpliceRecord" ? log.args.data : null} +
+ ); +} diff --git a/packages/dev-tools/src/events/StorageOperationsTable.tsx b/packages/dev-tools/src/events/StorageOperationsTable.tsx deleted file mode 100644 index bcf63d8876..0000000000 --- a/packages/dev-tools/src/events/StorageOperationsTable.tsx +++ /dev/null @@ -1,53 +0,0 @@ -import { StorageOperation } from "@latticexyz/store-sync"; -import { serialize } from "../serialize"; -import { EventIcon } from "./EventIcon"; -import { StoreConfig } from "@latticexyz/store"; - -// TODO: use react-table or similar for better perf with lots of logs - -type Props = { - operations: StorageOperation[]; -}; - -export function StorageOperationsTable({ operations }: Props) { - return ( - - - - - - - - - - - - {operations.map((operation) => ( - - - - - - - - ))} - -
blocktablekeyvalue
- {operation.log?.blockNumber.toString()} - - {operation.namespace}:{operation.name} - {serialize(operation.key)} - - - {operation.type === "SetRecord" ? serialize(operation.value) : null} - {operation.type === "SetField" ? serialize({ [operation.fieldName]: operation.fieldValue }) : null} -
- ); -} diff --git a/packages/dev-tools/src/summary/EventsSummary.tsx b/packages/dev-tools/src/summary/EventsSummary.tsx index 34e7bcebfb..fbc2ad87cb 100644 --- a/packages/dev-tools/src/summary/EventsSummary.tsx +++ b/packages/dev-tools/src/summary/EventsSummary.tsx @@ -1,12 +1,12 @@ import { NavButton } from "../NavButton"; import { useDevToolsContext } from "../DevToolsContext"; -import { StorageOperationsTable } from "../events/StorageOperationsTable"; +import { LogsTable } from "../events/LogsTable"; export function EventsSummary() { - const { storageOperations } = useDevToolsContext(); + const { storedLogs } = useDevToolsContext(); return ( <> - + See more From 68a4a1aa275a5398c0886dc0383d5ec10d33bd6f Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 5 Sep 2023 09:26:57 +0100 Subject: [PATCH 16/69] extend event with packed counter, hydrate from indexer records --- .../client-vanilla/src/mud/setupNetwork.ts | 4 +- e2e/packages/contracts/worlds.json | 2 +- e2e/packages/sync-test/data/encodeTestData.ts | 14 +- .../sync-test/data/expectClientData.ts | 2 +- e2e/packages/sync-test/rpcSync.test.ts | 1 - e2e/packages/sync-test/vite.config.ts | 1 - packages/dev-tools/src/DevToolsContext.tsx | 3 +- packages/protocol-parser/src/common.ts | 3 + .../protocol-parser/src/decodeRecord.test.ts | 12 + packages/protocol-parser/src/decodeRecord.ts | 9 +- packages/protocol-parser/src/encodeField.ts | 11 +- packages/protocol-parser/src/encodeKey.ts | 10 + .../protocol-parser/src/encodeKeyTuple.ts | 1 + .../protocol-parser/src/encodeRecord.test.ts | 8 +- packages/protocol-parser/src/encodeRecord.ts | 6 +- .../protocol-parser/src/hexToPackedCounter.ts | 7 +- packages/protocol-parser/src/index.ts | 4 + .../protocol-parser/src/keySchemaToHex.ts | 8 + .../protocol-parser/src/padSliceHex.test.ts | 15 + packages/protocol-parser/src/padSliceHex.ts | 8 + packages/protocol-parser/src/schemaToHex.ts | 1 + .../protocol-parser/src/valueSchemaToHex.ts | 11 + packages/store-indexer/package.json | 4 +- packages/store-sync/package.json | 4 +- packages/store-sync/src/common.ts | 29 -- packages/store-sync/src/createStoreSync.ts | 30 +- .../store-sync/src/postgres/buildColumn.ts | 5 +- .../src/postgres/buildTable.test.ts | 396 +++++++++++++++-- .../store-sync/src/postgres/buildTable.ts | 7 +- .../store-sync/src/postgres/columnTypes.ts | 30 +- .../src/postgres/postgresStorage.ts | 29 +- packages/store-sync/src/recs/common.ts | 2 + .../src/recs/configToRecsComponents.ts | 17 +- packages/store-sync/src/recs/recsStorage.ts | 46 +- .../src/sqlite/buildSqliteColumn.ts | 5 +- packages/store-sync/src/sqlite/columnTypes.ts | 9 +- .../src/sqlite/createSqliteTable.test.ts | 420 ++++++++++++++++-- .../src/sqlite/createSqliteTable.ts | 7 +- .../store-sync/src/sqlite/sqliteStorage.ts | 32 +- packages/store/abi/IStore.sol/IStore.abi.json | 12 + .../store/abi/IStore.sol/IStoreData.abi.json | 12 + .../store/abi/IStore.sol/IStoreWrite.abi.json | 12 + .../abi/StoreCore.sol/StoreCore.abi.json | 12 + .../abi/StoreMock.sol/StoreMock.abi.json | 12 + .../StoreReadWithStubs.abi.json | 12 + packages/store/src/IStore.sol | 11 +- packages/store/src/PackedCounter.sol | 2 + packages/store/src/StoreCore.sol | 68 ++- packages/store/ts/storeEvents.ts | 3 +- .../abi/IBaseWorld.sol/IBaseWorld.abi.json | 12 + packages/world/abi/IStore.sol/IStore.abi.json | 12 + .../world/abi/IStore.sol/IStoreData.abi.json | 12 + .../world/abi/IStore.sol/IStoreWrite.abi.json | 12 + .../abi/StoreCore.sol/StoreCore.abi.json | 12 + packages/world/abi/World.sol/World.abi.json | 12 + .../world/abi/src/IStore.sol/IStore.abi.json | 12 + .../abi/src/IStore.sol/IStoreData.abi.json | 12 + .../abi/src/IStore.sol/IStoreWrite.abi.json | 12 + .../abi/src/StoreCore.sol/StoreCore.abi.json | 12 + pnpm-lock.yaml | 36 +- 60 files changed, 1256 insertions(+), 269 deletions(-) create mode 100644 packages/protocol-parser/src/encodeKey.ts create mode 100644 packages/protocol-parser/src/keySchemaToHex.ts create mode 100644 packages/protocol-parser/src/padSliceHex.test.ts create mode 100644 packages/protocol-parser/src/padSliceHex.ts create mode 100644 packages/protocol-parser/src/valueSchemaToHex.ts diff --git a/e2e/packages/client-vanilla/src/mud/setupNetwork.ts b/e2e/packages/client-vanilla/src/mud/setupNetwork.ts index 30926624d6..e45edeb75e 100644 --- a/e2e/packages/client-vanilla/src/mud/setupNetwork.ts +++ b/e2e/packages/client-vanilla/src/mud/setupNetwork.ts @@ -33,7 +33,7 @@ export async function setupNetwork() { walletClient: burnerWalletClient, }); - const { components, latestBlock$, blockStorageOperations$, waitForTransaction } = await syncToRecs({ + const { components, latestBlock$, storedBlockLogs$, waitForTransaction } = await syncToRecs({ world, config: mudConfig, address: networkConfig.worldAddress as Hex, @@ -74,7 +74,7 @@ export async function setupNetwork() { walletClient: burnerWalletClient, worldContract, latestBlock$, - blockStorageOperations$, + storedBlockLogs$, waitForTransaction, }; } diff --git a/e2e/packages/contracts/worlds.json b/e2e/packages/contracts/worlds.json index 67719d6d7e..caf66719c4 100644 --- a/e2e/packages/contracts/worlds.json +++ b/e2e/packages/contracts/worlds.json @@ -1,5 +1,5 @@ { "31337": { - "address": "0xfbC22278A96299D91d41C453234d97b4F5Eb9B2d" + "address": "0xAA292E8611aDF267e563f334Ee42320aC96D0463" } } \ No newline at end of file diff --git a/e2e/packages/sync-test/data/encodeTestData.ts b/e2e/packages/sync-test/data/encodeTestData.ts index c0a6ab9dd5..05f96191cf 100644 --- a/e2e/packages/sync-test/data/encodeTestData.ts +++ b/e2e/packages/sync-test/data/encodeTestData.ts @@ -1,9 +1,7 @@ import { mapObject } from "@latticexyz/utils"; +import { abiTypesToSchema, encodeKey, encodeValue, schemaToHex } from "@latticexyz/protocol-parser"; import { Data, EncodedData } from "./types"; -import { encodeAbiParameters, encodePacked } from "viem"; import config from "../../contracts/mud.config"; -import { abiTypesToSchema, schemaToHex } from "@latticexyz/protocol-parser"; -import { StaticAbiType } from "@latticexyz/schema-type"; /** * Turns the typed data into encoded data in the format expected by `world.setRecord` @@ -11,14 +9,10 @@ import { StaticAbiType } from "@latticexyz/schema-type"; export function encodeTestData(testData: Data) { return mapObject(testData, (records, table) => { if (!records) return undefined; - const keyConfig = config.tables[table].keySchema; + const tableConfig = config.tables[table]; return records.map((record) => { - const encodedKey = Object.entries(record.key).map(([keyName, keyValue]) => { - const keyType = keyConfig[keyName as keyof typeof keyConfig] as StaticAbiType; - return encodeAbiParameters([{ type: keyType }], [keyValue]); - }); - - const encodedValue = encodePacked(Object.values(config.tables[table].schema), Object.values(record.value)); + const encodedKey = encodeKey(tableConfig.keySchema, record.key); + const encodedValue = encodeValue(tableConfig.schema, record.value); const encodedValueSchema = schemaToHex(abiTypesToSchema(Object.values(config.tables[table].schema))); diff --git a/e2e/packages/sync-test/data/expectClientData.ts b/e2e/packages/sync-test/data/expectClientData.ts index 6e52c0fc3d..92e81c323f 100644 --- a/e2e/packages/sync-test/data/expectClientData.ts +++ b/e2e/packages/sync-test/data/expectClientData.ts @@ -11,7 +11,7 @@ export async function expectClientData(page: Page, data: Data) { for (const [table, records] of Object.entries(data)) { for (const record of records) { const value = await readComponentValue(page, table, encodeEntity(config.tables[table].keySchema, record.key)); - expect(value).toEqual(record.value); + expect(value).toMatchObject(record.value); } } } diff --git a/e2e/packages/sync-test/rpcSync.test.ts b/e2e/packages/sync-test/rpcSync.test.ts index 7726f86995..39e786a319 100644 --- a/e2e/packages/sync-test/rpcSync.test.ts +++ b/e2e/packages/sync-test/rpcSync.test.ts @@ -1,7 +1,6 @@ import { afterEach, beforeEach, describe, test } from "vitest"; import type { ViteDevServer } from "vite"; import { Browser, Page } from "@playwright/test"; -import { ExecaChildProcess } from "execa"; import { createAsyncErrorHandler } from "./asyncErrors"; import { deployContracts, startViteServer, startBrowserAndPage, openClientWithRootAccount } from "./setup"; import { diff --git a/e2e/packages/sync-test/vite.config.ts b/e2e/packages/sync-test/vite.config.ts index aee36eb400..c6202f1992 100644 --- a/e2e/packages/sync-test/vite.config.ts +++ b/e2e/packages/sync-test/vite.config.ts @@ -1,6 +1,5 @@ import { defineConfig } from "vitest/config"; -// TODO should this along with `.test.ts` be in `client-vanilla`? export default defineConfig({ test: { environment: "jsdom", diff --git a/packages/dev-tools/src/DevToolsContext.tsx b/packages/dev-tools/src/DevToolsContext.tsx index fb6ba1c27a..2bc811dec5 100644 --- a/packages/dev-tools/src/DevToolsContext.tsx +++ b/packages/dev-tools/src/DevToolsContext.tsx @@ -1,8 +1,7 @@ import { createContext, ReactNode, useContext, useEffect, useState } from "react"; import { DevToolsOptions } from "./common"; import { ContractWrite } from "@latticexyz/common"; -import { StorageAdapterLog, StorageOperation } from "@latticexyz/store-sync"; -import { StoreConfig } from "@latticexyz/store"; +import { StorageAdapterLog } from "@latticexyz/store-sync"; type DevToolsContextValue = DevToolsOptions & { writes: ContractWrite[]; diff --git a/packages/protocol-parser/src/common.ts b/packages/protocol-parser/src/common.ts index 9ff1790395..bf98201851 100644 --- a/packages/protocol-parser/src/common.ts +++ b/packages/protocol-parser/src/common.ts @@ -1,4 +1,7 @@ import { DynamicAbiType, SchemaAbiType, SchemaAbiTypeToPrimitiveType, StaticAbiType } from "@latticexyz/schema-type"; +import { maxUint256, numberToHex } from "viem"; + +export const UNCHANGED_PACKED_COUNTER = numberToHex(maxUint256); /** @deprecated use `KeySchema` or `ValueSchema` instead */ export type Schema = { diff --git a/packages/protocol-parser/src/decodeRecord.test.ts b/packages/protocol-parser/src/decodeRecord.test.ts index a5bca516e6..390dcc6ade 100644 --- a/packages/protocol-parser/src/decodeRecord.test.ts +++ b/packages/protocol-parser/src/decodeRecord.test.ts @@ -21,4 +21,16 @@ describe("decodeRecord", () => { ] `); }); + + it("can decode an out of bounds array", () => { + const schema = { staticFields: [], dynamicFields: ["uint32[]"] } as const; + const values = decodeRecord(schema, "0x0000000000000000000000000000000000000000000000000400000000000004"); + expect(values).toMatchInlineSnapshot(` + [ + [ + 0, + ], + ] + `); + }); }); diff --git a/packages/protocol-parser/src/decodeRecord.ts b/packages/protocol-parser/src/decodeRecord.ts index 6d9c9773ff..ce355acff8 100644 --- a/packages/protocol-parser/src/decodeRecord.ts +++ b/packages/protocol-parser/src/decodeRecord.ts @@ -4,12 +4,13 @@ import { staticAbiTypeToByteLength, dynamicAbiTypeToDefaultValue, } from "@latticexyz/schema-type"; -import { Hex, sliceHex } from "viem"; +import { Hex } from "viem"; import { Schema } from "./common"; import { decodeDynamicField } from "./decodeDynamicField"; import { decodeStaticField } from "./decodeStaticField"; import { hexToPackedCounter } from "./hexToPackedCounter"; import { staticDataLength } from "./staticDataLength"; +import { padSliceHex } from "./padSliceHex"; /** @deprecated use `decodeValue` instead */ export function decodeRecord(schema: Schema, data: Hex): readonly (StaticPrimitiveType | DynamicPrimitiveType)[] { @@ -18,7 +19,7 @@ export function decodeRecord(schema: Schema, data: Hex): readonly (StaticPrimiti let bytesOffset = 0; schema.staticFields.forEach((fieldType) => { const fieldByteLength = staticAbiTypeToByteLength[fieldType]; - const value = decodeStaticField(fieldType, sliceHex(data, bytesOffset, bytesOffset + fieldByteLength)); + const value = decodeStaticField(fieldType, padSliceHex(data, bytesOffset, bytesOffset + fieldByteLength)); bytesOffset += fieldByteLength; values.push(value); }); @@ -38,13 +39,13 @@ export function decodeRecord(schema: Schema, data: Hex): readonly (StaticPrimiti } if (schema.dynamicFields.length > 0) { - const dataLayout = hexToPackedCounter(sliceHex(data, bytesOffset, bytesOffset + 32)); + const dataLayout = hexToPackedCounter(padSliceHex(data, bytesOffset, bytesOffset + 32)); bytesOffset += 32; schema.dynamicFields.forEach((fieldType, i) => { const dataLength = dataLayout.fieldByteLengths[i]; if (dataLength > 0) { - const value = decodeDynamicField(fieldType, sliceHex(data, bytesOffset, bytesOffset + dataLength)); + const value = decodeDynamicField(fieldType, padSliceHex(data, bytesOffset, bytesOffset + dataLength)); bytesOffset += dataLength; values.push(value); } else { diff --git a/packages/protocol-parser/src/encodeField.ts b/packages/protocol-parser/src/encodeField.ts index 89155d6531..99e977a850 100644 --- a/packages/protocol-parser/src/encodeField.ts +++ b/packages/protocol-parser/src/encodeField.ts @@ -8,10 +8,13 @@ export function encodeField( ): Hex { if (isArrayAbiType(fieldType) && Array.isArray(value)) { const staticFieldType = arrayAbiTypeToStaticAbiType(fieldType); - return encodePacked( - value.map(() => staticFieldType), - value - ); + // TODO: we can remove conditional once this is fixed: https://github.com/wagmi-dev/viem/pull/1147 + return value.length === 0 + ? "0x" + : encodePacked( + value.map(() => staticFieldType), + value + ); } return encodePacked([fieldType], [value]); } diff --git a/packages/protocol-parser/src/encodeKey.ts b/packages/protocol-parser/src/encodeKey.ts new file mode 100644 index 0000000000..f98ac04210 --- /dev/null +++ b/packages/protocol-parser/src/encodeKey.ts @@ -0,0 +1,10 @@ +import { isStaticAbiType } from "@latticexyz/schema-type"; +import { Hex } from "viem"; +import { SchemaToPrimitives, KeySchema } from "./common"; +import { encodeKeyTuple } from "./encodeKeyTuple"; + +export function encodeKey(keySchema: TSchema, key: SchemaToPrimitives): Hex[] { + const staticFields = Object.values(keySchema).filter(isStaticAbiType); + // TODO: refactor and move all encodeKey logic into this method so we can delete encodeKey + return encodeKeyTuple({ staticFields, dynamicFields: [] }, Object.values(key)); +} diff --git a/packages/protocol-parser/src/encodeKeyTuple.ts b/packages/protocol-parser/src/encodeKeyTuple.ts index c52ffae0ac..e81337cac0 100644 --- a/packages/protocol-parser/src/encodeKeyTuple.ts +++ b/packages/protocol-parser/src/encodeKeyTuple.ts @@ -2,6 +2,7 @@ import { StaticPrimitiveType } from "@latticexyz/schema-type"; import { Hex, encodeAbiParameters } from "viem"; import { Schema } from "./common"; +/** @deprecated use `encodeKey` instead */ export function encodeKeyTuple(keySchema: Schema, keyTuple: StaticPrimitiveType[]): Hex[] { return keyTuple.map((key, index) => encodeAbiParameters([{ type: keySchema.staticFields[index] }], [key])); } diff --git a/packages/protocol-parser/src/encodeRecord.test.ts b/packages/protocol-parser/src/encodeRecord.test.ts index e85bec0b39..fde765d9b6 100644 --- a/packages/protocol-parser/src/encodeRecord.test.ts +++ b/packages/protocol-parser/src/encodeRecord.test.ts @@ -6,7 +6,7 @@ describe("encodeRecord", () => { const schema = { staticFields: ["uint32", "uint128"], dynamicFields: ["uint32[]", "string"] } as const; const hex = encodeRecord(schema, [1, 2n, [3, 4], "some string"]); expect(hex).toBe( - "0x0000000100000000000000000000000000000002000000000000130000000008000000000b0000000000000000000000000000000000000300000004736f6d6520737472696e67" + "0x0000000100000000000000000000000000000002000000000000000000000000000000000000000b0000000008000000000000130000000300000004736f6d6520737472696e67" ); }); @@ -15,4 +15,10 @@ describe("encodeRecord", () => { const hex = encodeRecord(schema, [1, 2n]); expect(hex).toBe("0x0000000100000000000000000000000000000002"); }); + + it("can encode an array to hex", () => { + const schema = { staticFields: [], dynamicFields: ["uint32[]"] } as const; + const hex = encodeRecord(schema, [[42]]); + expect(hex).toBe("0x00000000000000000000000000000000000000000000000004000000000000040000002a"); + }); }); diff --git a/packages/protocol-parser/src/encodeRecord.ts b/packages/protocol-parser/src/encodeRecord.ts index 363deeb5e3..b224a6c532 100644 --- a/packages/protocol-parser/src/encodeRecord.ts +++ b/packages/protocol-parser/src/encodeRecord.ts @@ -18,14 +18,14 @@ export function encodeRecord(schema: Schema, values: readonly (StaticPrimitiveTy encodeField(schema.dynamicFields[i], value).replace(/^0x/, "") ); - const dynamicFieldByteLengths = dynamicDataItems.map((value) => value.length / 2); + const dynamicFieldByteLengths = dynamicDataItems.map((value) => value.length / 2).reverse(); const dynamicTotalByteLength = dynamicFieldByteLengths.reduce((total, length) => total + BigInt(length), 0n); const dynamicData = dynamicDataItems.join(""); - const packedCounter = `${encodeField("uint56", dynamicTotalByteLength).replace(/^0x/, "")}${dynamicFieldByteLengths + const packedCounter = `${dynamicFieldByteLengths .map((length) => encodeField("uint40", length).replace(/^0x/, "")) - .join("")}`.padEnd(64, "0"); + .join("")}${encodeField("uint56", dynamicTotalByteLength).replace(/^0x/, "")}`.padStart(64, "0"); return `0x${staticData}${packedCounter}${dynamicData}`; } diff --git a/packages/protocol-parser/src/hexToPackedCounter.ts b/packages/protocol-parser/src/hexToPackedCounter.ts index 4a244e0cf5..eec1382cf8 100644 --- a/packages/protocol-parser/src/hexToPackedCounter.ts +++ b/packages/protocol-parser/src/hexToPackedCounter.ts @@ -1,7 +1,8 @@ -import { Hex, sliceHex } from "viem"; +import { Hex } from "viem"; import { decodeStaticField } from "./decodeStaticField"; import { decodeDynamicField } from "./decodeDynamicField"; import { InvalidHexLengthForPackedCounterError, PackedCounterLengthMismatchError } from "./errors"; +import { padSliceHex } from "./padSliceHex"; // Keep this logic in sync with PackedCounter.sol @@ -18,9 +19,9 @@ export function hexToPackedCounter(data: Hex): { throw new InvalidHexLengthForPackedCounterError(data); } - const totalByteLength = decodeStaticField("uint56", sliceHex(data, 32 - 7, 32)); + const totalByteLength = decodeStaticField("uint56", padSliceHex(data, 32 - 7, 32)); // TODO: use schema to make sure we only parse as many as we need (rather than zeroes at the end)? - const reversedFieldByteLengths = decodeDynamicField("uint40[]", sliceHex(data, 0, 32 - 7)); + const reversedFieldByteLengths = decodeDynamicField("uint40[]", padSliceHex(data, 0, 32 - 7)); // Reverse the lengths const fieldByteLengths = Object.freeze([...reversedFieldByteLengths].reverse()); diff --git a/packages/protocol-parser/src/index.ts b/packages/protocol-parser/src/index.ts index fda72336a0..e88579ce82 100644 --- a/packages/protocol-parser/src/index.ts +++ b/packages/protocol-parser/src/index.ts @@ -8,6 +8,7 @@ export * from "./decodeRecord"; export * from "./decodeStaticField"; export * from "./decodeValue"; export * from "./encodeField"; +export * from "./encodeKey"; export * from "./encodeKeyTuple"; export * from "./encodeRecord"; export * from "./encodeValue"; @@ -15,6 +16,9 @@ export * from "./errors"; export * from "./hexToPackedCounter"; export * from "./hexToSchema"; export * from "./hexToTableSchema"; +export * from "./keySchemaToHex"; +export * from "./padSliceHex"; export * from "./schemaIndexToAbiType"; export * from "./schemaToHex"; export * from "./staticDataLength"; +export * from "./valueSchemaToHex"; diff --git a/packages/protocol-parser/src/keySchemaToHex.ts b/packages/protocol-parser/src/keySchemaToHex.ts new file mode 100644 index 0000000000..0d5d3a697e --- /dev/null +++ b/packages/protocol-parser/src/keySchemaToHex.ts @@ -0,0 +1,8 @@ +import { isStaticAbiType } from "@latticexyz/schema-type"; +import { Hex } from "viem"; +import { KeySchema } from "./common"; +import { schemaToHex } from "./schemaToHex"; + +export function keySchemaToHex(schema: KeySchema): Hex { + return schemaToHex({ staticFields: Object.values(schema).filter(isStaticAbiType), dynamicFields: [] }); +} diff --git a/packages/protocol-parser/src/padSliceHex.test.ts b/packages/protocol-parser/src/padSliceHex.test.ts new file mode 100644 index 0000000000..5f100c628b --- /dev/null +++ b/packages/protocol-parser/src/padSliceHex.test.ts @@ -0,0 +1,15 @@ +import { describe, expect, it } from "vitest"; +import { padSliceHex } from "./padSliceHex"; + +describe("padSliceHex", () => { + it("can slice empty hex", () => { + expect(padSliceHex("0x", 6)).toBe("0x"); + expect(padSliceHex("0x", 6, 10)).toBe("0x00000000"); + }); + it("can slice hex out of bounds", () => { + expect(padSliceHex("0x000100", 1)).toBe("0x0100"); + expect(padSliceHex("0x000100", 1, 4)).toBe("0x010000"); + expect(padSliceHex("0x000100", 3)).toBe("0x"); + expect(padSliceHex("0x000100", 3, 4)).toBe("0x00"); + }); +}); diff --git a/packages/protocol-parser/src/padSliceHex.ts b/packages/protocol-parser/src/padSliceHex.ts new file mode 100644 index 0000000000..734459e66a --- /dev/null +++ b/packages/protocol-parser/src/padSliceHex.ts @@ -0,0 +1,8 @@ +import { Hex } from "viem"; + +export function padSliceHex(data: Hex, start: number, end?: number): Hex { + return `0x${data + .replace(/^0x/, "") + .slice(start * 2, end != null ? end * 2 : undefined) + .padEnd(((end ?? start) - start) * 2, "0")}`; +} diff --git a/packages/protocol-parser/src/schemaToHex.ts b/packages/protocol-parser/src/schemaToHex.ts index c153539c61..439994d17c 100644 --- a/packages/protocol-parser/src/schemaToHex.ts +++ b/packages/protocol-parser/src/schemaToHex.ts @@ -3,6 +3,7 @@ import { Hex } from "viem"; import { Schema } from "./common"; import { staticDataLength } from "./staticDataLength"; +/** @deprecated use `keySchemaToHex` or `valueSchemaToHex` instead */ export function schemaToHex(schema: Schema): Hex { const staticSchemaTypes = schema.staticFields.map((abiType) => schemaAbiTypes.indexOf(abiType)); const dynamicSchemaTypes = schema.dynamicFields.map((abiType) => schemaAbiTypes.indexOf(abiType)); diff --git a/packages/protocol-parser/src/valueSchemaToHex.ts b/packages/protocol-parser/src/valueSchemaToHex.ts new file mode 100644 index 0000000000..b7e24b7f7a --- /dev/null +++ b/packages/protocol-parser/src/valueSchemaToHex.ts @@ -0,0 +1,11 @@ +import { isDynamicAbiType, isStaticAbiType } from "@latticexyz/schema-type"; +import { Hex } from "viem"; +import { ValueSchema } from "./common"; +import { schemaToHex } from "./schemaToHex"; + +export function valueSchemaToHex(schema: ValueSchema): Hex { + return schemaToHex({ + staticFields: Object.values(schema).filter(isStaticAbiType), + dynamicFields: Object.values(schema).filter(isDynamicAbiType), + }); +} diff --git a/packages/store-indexer/package.json b/packages/store-indexer/package.json index 6cb12247d3..d74eebd023 100644 --- a/packages/store-indexer/package.json +++ b/packages/store-indexer/package.json @@ -40,9 +40,9 @@ "@trpc/client": "10.34.0", "@trpc/server": "10.34.0", "@wagmi/chains": "^0.2.22", - "better-sqlite3": "^8.4.0", + "better-sqlite3": "^8.6.0", "debug": "^4.3.4", - "drizzle-orm": "^0.27.0", + "drizzle-orm": "^0.28.5", "fastify": "^4.21.0", "postgres": "^3.3.5", "rxjs": "7.5.5", diff --git a/packages/store-sync/package.json b/packages/store-sync/package.json index fbd89f0f5c..a5431900f9 100644 --- a/packages/store-sync/package.json +++ b/packages/store-sync/package.json @@ -56,8 +56,8 @@ "@trpc/client": "10.34.0", "@trpc/server": "10.34.0", "debug": "^4.3.4", - "drizzle-orm": "^0.27.0", - "kysely": "^0.26.1", + "drizzle-orm": "^0.28.5", + "kysely": "^0.26.3", "postgres": "^3.3.5", "rxjs": "7.5.5", "sql.js": "^1.8.0", diff --git a/packages/store-sync/src/common.ts b/packages/store-sync/src/common.ts index 006a13367a..4927923521 100644 --- a/packages/store-sync/src/common.ts +++ b/packages/store-sync/src/common.ts @@ -26,35 +26,6 @@ export type TableWithRecords = Table & { records: TableRecord[] }; export type StoreEventsLog = Log; export type BlockLogs = { blockNumber: StoreEventsLog["blockNumber"]; logs: StoreEventsLog[] }; -export type BaseStorageOperation = { - log?: StoreEventsLog; - address: Hex; - namespace: TableNamespace; - name: keyof TConfig["tables"] & TableName; - key: readonly Hex[]; -}; - -export type SetRecordOperation = BaseStorageOperation & { - type: "SetRecord"; - data: Hex; -}; - -export type SpliceRecordOperation = BaseStorageOperation & { - type: "SpliceRecord"; - data: Hex; - start: number; - deleteCount: number; -}; - -export type DeleteRecordOperation = BaseStorageOperation & { - type: "DeleteRecord"; -}; - -export type StorageOperation = - | SetRecordOperation - | SpliceRecordOperation - | DeleteRecordOperation; - export type SyncOptions = { /** * MUD config diff --git a/packages/store-sync/src/createStoreSync.ts b/packages/store-sync/src/createStoreSync.ts index 24aee6d3b6..8ecc37bfcf 100644 --- a/packages/store-sync/src/createStoreSync.ts +++ b/packages/store-sync/src/createStoreSync.ts @@ -1,5 +1,5 @@ import { StoreConfig, storeEventsAbi } from "@latticexyz/store"; -import { Hex, TransactionReceiptNotFoundError } from "viem"; +import { Hex, TransactionReceiptNotFoundError, encodeAbiParameters } from "viem"; import { StorageAdapter, StorageAdapterBlock, @@ -7,6 +7,7 @@ import { SyncOptions, SyncResult, TableWithRecords, + schemasTable, schemasTableId, } from "./common"; import { createBlockStream, blockRangeToLogs, groupLogsByBlockNumber } from "@latticexyz/block-logs-stream"; @@ -32,6 +33,7 @@ import { debug as parentDebug } from "./debug"; import { createIndexerClient } from "./trpc-indexer"; import { SyncStep } from "./SyncStep"; import { chunk, isDefined } from "@latticexyz/common/utils"; +import { encodeKey, encodeValue, keySchemaToHex, schemaToHex, valueSchemaToHex } from "@latticexyz/protocol-parser"; const debug = parentDebug.extend("createStoreSync"); @@ -130,33 +132,19 @@ export async function createStoreSync message: "Hydrating from snapshot", }); - const logs: StorageAdapterLog[] = tables.flatMap((table) => [ - { - eventName: "StoreSetRecord", - address: table.address, - args: { - table: schemasTableId, - key: [table.tableId], - data: "0x", // TODO: encode key/value schemas - }, - }, - ...table.records.map( + const logs: StorageAdapterLog[] = tables.flatMap((table) => + table.records.map( (record): StorageAdapterLog => ({ eventName: "StoreSetRecord", address: table.address, args: { table: table.tableId, - key: [], // TODO: encode key - data: "0x", // TODO: encode data + key: encodeKey(table.keySchema, record.key), + data: encodeValue(table.valueSchema, record.value), }, - // address: table.address, - // namespace: table.namespace, - // name: table.name, - // key: record.key as ConfigToKeyPrimitives, - // value: record.value as ConfigToValuePrimitives, }) - ), - ]); + ) + ); // Split snapshot operations into chunks so we can update the progress callback (and ultimately render visual progress for the user). // This isn't ideal if we want to e.g. batch load these into a DB in a single DB tx, but we'll take it. diff --git a/packages/store-sync/src/postgres/buildColumn.ts b/packages/store-sync/src/postgres/buildColumn.ts index 86ea59c268..d9ffa6db99 100644 --- a/packages/store-sync/src/postgres/buildColumn.ts +++ b/packages/store-sync/src/postgres/buildColumn.ts @@ -1,9 +1,10 @@ -import { AnyPgColumnBuilder, boolean, text } from "drizzle-orm/pg-core"; +import { boolean, text } from "drizzle-orm/pg-core"; import { SchemaAbiType } from "@latticexyz/schema-type"; import { assertExhaustive } from "@latticexyz/common/utils"; import { asAddress, asBigInt, asHex, asJson, asNumber } from "./columnTypes"; -export function buildColumn(name: string, schemaAbiType: SchemaAbiType): AnyPgColumnBuilder { +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export function buildColumn(name: string, schemaAbiType: SchemaAbiType) { switch (schemaAbiType) { case "bool": return boolean(name); diff --git a/packages/store-sync/src/postgres/buildTable.test.ts b/packages/store-sync/src/postgres/buildTable.test.ts index 1fa3ec932e..f4f2fcc6ff 100644 --- a/packages/store-sync/src/postgres/buildTable.test.ts +++ b/packages/store-sync/src/postgres/buildTable.test.ts @@ -14,20 +14,31 @@ describe("buildTable", () => { expect(table).toMatchInlineSnapshot(` PgTable { "__data": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__data", "notNull": true, "primaryKey": false, + "uniqueName": "users___data_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__data", @@ -35,36 +46,62 @@ describe("buildTable", () => { "primary": false, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users___data_unique", + "uniqueType": undefined, }, "__isDeleted": PgBoolean { + "columnType": "PgBoolean", "config": { + "columnType": "PgBoolean", + "dataType": "boolean", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "__isDeleted", "notNull": true, "primaryKey": false, + "uniqueName": "users___isDeleted_unique", + "uniqueType": undefined, }, + "dataType": "boolean", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "__isDeleted", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "users___isDeleted_unique", + "uniqueType": undefined, }, "__key": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__key", "notNull": true, "primaryKey": true, + "uniqueName": "users___key_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__key", @@ -72,22 +109,35 @@ describe("buildTable", () => { "primary": true, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users___key_unique", + "uniqueType": undefined, }, "__lastUpdatedBlockNumber": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primaryKey": false, + "uniqueName": "users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__lastUpdatedBlockNumber", @@ -95,22 +145,35 @@ describe("buildTable", () => { "primary": false, "sqlName": "numeric", "table": [Circular], + "uniqueName": "users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, "addr": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "addr", "notNull": true, "primaryKey": false, + "uniqueName": "users_addr_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "addr", @@ -118,38 +181,63 @@ describe("buildTable", () => { "primary": false, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users_addr_unique", + "uniqueType": undefined, }, "name": PgText { + "columnType": "PgText", "config": { + "columnType": "PgText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "name", "notNull": true, "primaryKey": false, + "uniqueName": "users_name_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "name", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "users_name_unique", + "uniqueType": undefined, }, "x": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "x", "notNull": true, "primaryKey": false, + "uniqueName": "users_x_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "x", @@ -157,22 +245,35 @@ describe("buildTable", () => { "primary": false, "sqlName": "integer", "table": [Circular], + "uniqueName": "users_x_unique", + "uniqueType": undefined, }, "y": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "y", "notNull": true, "primaryKey": false, + "uniqueName": "users_y_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "y", @@ -180,26 +281,39 @@ describe("buildTable", () => { "primary": false, "sqlName": "integer", "table": [Circular], + "uniqueName": "users_y_unique", + "uniqueType": undefined, }, Symbol(drizzle:Name): "users", Symbol(drizzle:OriginalName): "users", Symbol(drizzle:Schema): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test", Symbol(drizzle:Columns): { "__data": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__data", "notNull": true, "primaryKey": false, + "uniqueName": "users___data_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__data", @@ -207,36 +321,62 @@ describe("buildTable", () => { "primary": false, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users___data_unique", + "uniqueType": undefined, }, "__isDeleted": PgBoolean { + "columnType": "PgBoolean", "config": { + "columnType": "PgBoolean", + "dataType": "boolean", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "__isDeleted", "notNull": true, "primaryKey": false, + "uniqueName": "users___isDeleted_unique", + "uniqueType": undefined, }, + "dataType": "boolean", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "__isDeleted", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "users___isDeleted_unique", + "uniqueType": undefined, }, "__key": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__key", "notNull": true, "primaryKey": true, + "uniqueName": "users___key_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__key", @@ -244,22 +384,35 @@ describe("buildTable", () => { "primary": true, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users___key_unique", + "uniqueType": undefined, }, "__lastUpdatedBlockNumber": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primaryKey": false, + "uniqueName": "users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__lastUpdatedBlockNumber", @@ -267,22 +420,35 @@ describe("buildTable", () => { "primary": false, "sqlName": "numeric", "table": [Circular], + "uniqueName": "users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, "addr": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "addr", "notNull": true, "primaryKey": false, + "uniqueName": "users_addr_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "addr", @@ -290,38 +456,63 @@ describe("buildTable", () => { "primary": false, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users_addr_unique", + "uniqueType": undefined, }, "name": PgText { + "columnType": "PgText", "config": { + "columnType": "PgText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "name", "notNull": true, "primaryKey": false, + "uniqueName": "users_name_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "name", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "users_name_unique", + "uniqueType": undefined, }, "x": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "x", "notNull": true, "primaryKey": false, + "uniqueName": "users_x_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "x", @@ -329,22 +520,35 @@ describe("buildTable", () => { "primary": false, "sqlName": "integer", "table": [Circular], + "uniqueName": "users_x_unique", + "uniqueType": undefined, }, "y": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "y", "notNull": true, "primaryKey": false, + "uniqueName": "users_y_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "y", @@ -352,6 +556,8 @@ describe("buildTable", () => { "primary": false, "sqlName": "integer", "table": [Circular], + "uniqueName": "users_y_unique", + "uniqueType": undefined, }, }, Symbol(drizzle:BaseName): "users", @@ -375,20 +581,31 @@ describe("buildTable", () => { expect(table).toMatchInlineSnapshot(` PgTable { "__data": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__data", "notNull": true, "primaryKey": false, + "uniqueName": "users___data_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__data", @@ -396,36 +613,62 @@ describe("buildTable", () => { "primary": false, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users___data_unique", + "uniqueType": undefined, }, "__isDeleted": PgBoolean { + "columnType": "PgBoolean", "config": { + "columnType": "PgBoolean", + "dataType": "boolean", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "__isDeleted", "notNull": true, "primaryKey": false, + "uniqueName": "users___isDeleted_unique", + "uniqueType": undefined, }, + "dataType": "boolean", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "__isDeleted", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "users___isDeleted_unique", + "uniqueType": undefined, }, "__key": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__key", "notNull": true, "primaryKey": true, + "uniqueName": "users___key_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__key", @@ -433,22 +676,35 @@ describe("buildTable", () => { "primary": true, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users___key_unique", + "uniqueType": undefined, }, "__lastUpdatedBlockNumber": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primaryKey": false, + "uniqueName": "users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__lastUpdatedBlockNumber", @@ -456,22 +712,35 @@ describe("buildTable", () => { "primary": false, "sqlName": "numeric", "table": [Circular], + "uniqueName": "users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, "addrs": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "addrs", "notNull": true, "primaryKey": false, + "uniqueName": "users_addrs_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "addrs", @@ -479,26 +748,39 @@ describe("buildTable", () => { "primary": false, "sqlName": "text", "table": [Circular], + "uniqueName": "users_addrs_unique", + "uniqueType": undefined, }, Symbol(drizzle:Name): "users", Symbol(drizzle:OriginalName): "users", Symbol(drizzle:Schema): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test", Symbol(drizzle:Columns): { "__data": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__data", "notNull": true, "primaryKey": false, + "uniqueName": "users___data_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__data", @@ -506,36 +788,62 @@ describe("buildTable", () => { "primary": false, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users___data_unique", + "uniqueType": undefined, }, "__isDeleted": PgBoolean { + "columnType": "PgBoolean", "config": { + "columnType": "PgBoolean", + "dataType": "boolean", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "__isDeleted", "notNull": true, "primaryKey": false, + "uniqueName": "users___isDeleted_unique", + "uniqueType": undefined, }, + "dataType": "boolean", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "__isDeleted", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "users___isDeleted_unique", + "uniqueType": undefined, }, "__key": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__key", "notNull": true, "primaryKey": true, + "uniqueName": "users___key_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__key", @@ -543,22 +851,35 @@ describe("buildTable", () => { "primary": true, "sqlName": "bytea", "table": [Circular], + "uniqueName": "users___key_unique", + "uniqueType": undefined, }, "__lastUpdatedBlockNumber": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primaryKey": false, + "uniqueName": "users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "__lastUpdatedBlockNumber", @@ -566,22 +887,35 @@ describe("buildTable", () => { "primary": false, "sqlName": "numeric", "table": [Circular], + "uniqueName": "users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, "addrs": PgCustomColumn { + "columnType": "PgCustomColumn", "config": { + "columnType": "PgCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "addrs", "notNull": true, "primaryKey": false, + "uniqueName": "users_addrs_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "addrs", @@ -589,6 +923,8 @@ describe("buildTable", () => { "primary": false, "sqlName": "text", "table": [Circular], + "uniqueName": "users_addrs_unique", + "uniqueType": undefined, }, }, Symbol(drizzle:BaseName): "users", diff --git a/packages/store-sync/src/postgres/buildTable.ts b/packages/store-sync/src/postgres/buildTable.ts index 89f16878b3..39c8880c7e 100644 --- a/packages/store-sync/src/postgres/buildTable.ts +++ b/packages/store-sync/src/postgres/buildTable.ts @@ -1,4 +1,4 @@ -import { AnyPgColumnBuilder, PgTableWithColumns, pgSchema } from "drizzle-orm/pg-core"; +import { PgColumnBuilderBase, PgTableWithColumns, pgSchema } from "drizzle-orm/pg-core"; import { SchemaAbiType, StaticAbiType } from "@latticexyz/schema-type"; import { buildColumn } from "./buildColumn"; import { Address, getAddress } from "viem"; @@ -6,17 +6,18 @@ import { transformSchemaName } from "./transformSchemaName"; // TODO: convert camel case to snake case for DB storage? export const metaColumns = { - __key: buildColumn("__key", "bytes").notNull().primaryKey(), + __key: buildColumn("__key", "bytes").primaryKey(), __data: buildColumn("__data", "bytes").notNull(), __lastUpdatedBlockNumber: buildColumn("__lastUpdatedBlockNumber", "uint256").notNull(), // TODO: last updated block hash? __isDeleted: buildColumn("__isDeleted", "bool").notNull(), -} as const satisfies Record; +} as const satisfies Record; type PgTableFromSchema< TKeySchema extends Record, TValueSchema extends Record > = PgTableWithColumns<{ + dialect: "pg"; name: string; schema: string; columns: { diff --git a/packages/store-sync/src/postgres/columnTypes.ts b/packages/store-sync/src/postgres/columnTypes.ts index 97fd352080..da9d9761f8 100644 --- a/packages/store-sync/src/postgres/columnTypes.ts +++ b/packages/store-sync/src/postgres/columnTypes.ts @@ -1,11 +1,9 @@ -import { customType, PgCustomColumnBuilder } from "drizzle-orm/pg-core"; -import { ColumnBuilderBaseConfig } from "drizzle-orm"; +import { customType } from "drizzle-orm/pg-core"; import superjson from "superjson"; import { Address, ByteArray, bytesToHex, getAddress, Hex, hexToBytes } from "viem"; -export const asJson = ( - name: string -): PgCustomColumnBuilder => +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const asJson = (name: string) => customType<{ data: TData; driverData: string }>({ dataType() { // TODO: move to json column type? if we do, we'll prob wanna choose something other than superjson since it adds one level of depth (json/meta keys) @@ -19,10 +17,8 @@ export const asJson = ( }, })(name); -export const asNumber = ( - name: string, - columnType: string -): PgCustomColumnBuilder => +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const asNumber = (name: string, columnType: string) => customType<{ data: number; driverData: string }>({ dataType() { return columnType; @@ -35,10 +31,8 @@ export const asNumber = ( }, })(name); -export const asBigInt = ( - name: string, - columnType: string -): PgCustomColumnBuilder => +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const asBigInt = (name: string, columnType: string) => customType<{ data: bigint; driverData: string }>({ dataType() { return columnType; @@ -51,9 +45,8 @@ export const asBigInt = ( }, })(name); -export const asHex = ( - name: string -): PgCustomColumnBuilder => +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const asHex = (name: string) => customType<{ data: Hex; driverData: ByteArray }>({ dataType() { return "bytea"; @@ -66,9 +59,8 @@ export const asHex = ( }, })(name); -export const asAddress = ( - name: string -): PgCustomColumnBuilder => +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const asAddress = (name: string) => customType<{ data: Address; driverData: ByteArray }>({ dataType() { return "bytea"; diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index ff2ab41c59..3df1e59f04 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -1,4 +1,4 @@ -import { Hex, PublicClient, concatHex, size, sliceHex } from "viem"; +import { Hex, PublicClient, concatHex, padHex, size, sliceHex } from "viem"; import { PgDatabase, QueryResultHKT } from "drizzle-orm/pg-core"; import { eq, inArray } from "drizzle-orm"; import { buildTable } from "./buildTable"; @@ -13,7 +13,7 @@ import { getTableKey } from "./getTableKey"; import { StorageAdapter, StorageAdapterBlock } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; -import { decodeKey, decodeValue } from "@latticexyz/protocol-parser"; +import { UNCHANGED_PACKED_COUNTER, decodeKey, decodeValue, padSliceHex } from "@latticexyz/protocol-parser"; // Currently assumes one DB per chain ID @@ -137,20 +137,27 @@ export async function postgresStorage const previousData = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]?.__data ?? "0x"; - // TODO: figure out if we need to pad anything or set defaults - const end = log.args.start + log.args.deleteCount; - const newData = concatHex([ - sliceHex(previousData, 0, log.args.start), - log.args.data, - end >= size(previousData) ? "0x" : sliceHex(previousData, end), - ]); + let newData = previousData; + if (log.args.newDynamicLengths !== UNCHANGED_PACKED_COUNTER) { + const start = Number(log.args.dynamicLengthsStart); + const end = start + size(log.args.newDynamicLengths); + newData = concatHex([ + padSliceHex(newData, 0, start), + log.args.newDynamicLengths, + padSliceHex(newData, end), + ]); + } + const start = log.args.start; + const end = start + log.args.deleteCount; + newData = concatHex([padSliceHex(newData, 0, start), log.args.data, padSliceHex(newData, end)]); + const newValue = decodeValue(table.valueSchema, newData); debug("upserting record via splice", { key, previousData, newData, newValue, log }); await tx .insert(sqlTable) .values({ - __key: key, + __key: uniqueKey, __data: newData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, @@ -176,7 +183,7 @@ export async function postgresStorage __lastUpdatedBlockNumber: blockNumber, __isDeleted: true, }) - .where(eq(sqlTable.__key, key)) + .where(eq(sqlTable.__key, uniqueKey)) .execute(); } } diff --git a/packages/store-sync/src/recs/common.ts b/packages/store-sync/src/recs/common.ts index c384d5da13..abe626aa6c 100644 --- a/packages/store-sync/src/recs/common.ts +++ b/packages/store-sync/src/recs/common.ts @@ -14,6 +14,8 @@ export type StoreComponentMetadata = RecsMetadata & { export type ConfigToRecsComponents = { [tableName in keyof TConfig["tables"] & string]: RecsComponent< { + __data: RecsType.String; + } & { [fieldName in keyof TConfig["tables"][tableName]["schema"] & string]: RecsType & SchemaAbiTypeToRecsType; }, diff --git a/packages/store-sync/src/recs/configToRecsComponents.ts b/packages/store-sync/src/recs/configToRecsComponents.ts index f1b2e617e5..c9ad93fd85 100644 --- a/packages/store-sync/src/recs/configToRecsComponents.ts +++ b/packages/store-sync/src/recs/configToRecsComponents.ts @@ -1,7 +1,7 @@ import { StoreConfig } from "@latticexyz/store"; import { SchemaAbiType } from "@latticexyz/schema-type"; import { tableIdToHex } from "@latticexyz/common"; -import { World, defineComponent } from "@latticexyz/recs"; +import { World, defineComponent, Type } from "@latticexyz/recs"; import { ConfigToRecsComponents } from "./common"; import { schemaAbiTypeToRecsType } from "./schemaAbiTypeToRecsType"; @@ -14,12 +14,15 @@ export function configToRecsComponents( tableName, defineComponent( world, - Object.fromEntries( - Object.entries(table.schema).map(([fieldName, schemaAbiType]) => [ - fieldName, - schemaAbiTypeToRecsType[schemaAbiType as SchemaAbiType], - ]) - ), + { + ...Object.fromEntries( + Object.entries(table.schema).map(([fieldName, schemaAbiType]) => [ + fieldName, + schemaAbiTypeToRecsType[schemaAbiType as SchemaAbiType], + ]) + ), + __data: Type.String, + }, { id: tableIdToHex(config.namespace, tableName), metadata: { diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index c5b4d98989..934cc02276 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -8,17 +8,24 @@ import { removeComponent, setComponent, } from "@latticexyz/recs"; -import { schemaToDefaults } from "../schemaToDefaults"; import { defineInternalComponents } from "./defineInternalComponents"; import { getTableEntity } from "./getTableEntity"; import { StoreComponentMetadata } from "./common"; import { hexToTableId } from "@latticexyz/common"; -import { SchemaToPrimitives, ValueSchema, decodeValue, encodeValue } from "@latticexyz/protocol-parser"; -import { concatHex, size, sliceHex } from "viem"; +import { + SchemaToPrimitives, + UNCHANGED_PACKED_COUNTER, + ValueSchema, + decodeValue, + encodeValue, + staticDataLength, +} from "@latticexyz/protocol-parser"; +import { Hex, concatHex, padHex, size, sliceHex } from "viem"; import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; +import { schemaToDefaults } from "../schemaToDefaults"; export function recsStorage({ components, @@ -71,22 +78,31 @@ export function recsStorage({ if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { const value = decodeValue(table.valueSchema, log.args.data); debug("setting component", table.tableId, entity, value); - setComponent(component, entity, value); + setComponent(component, entity, { ...value, __data: log.args.data }); } else if (log.eventName === "StoreSpliceRecord") { - const previousValue = getComponentValue(component, entity); - const previousData = encodeValue( - table.valueSchema, - (previousValue as SchemaToPrimitives) ?? schemaToDefaults(table.valueSchema) - ); - const end = log.args.start + log.args.deleteCount; - const newData = concatHex([ - sliceHex(previousData, 0, log.args.start), + const previousData = (getComponentValue(component, entity)?.__data as Hex) ?? "0x"; + + let newData = previousData; + if (log.args.newDynamicLengths !== UNCHANGED_PACKED_COUNTER) { + const start = Number(log.args.dynamicLengthsStart); + const end = start + size(log.args.newDynamicLengths); + newData = concatHex([ + padHex(sliceHex(newData, 0, start), { size: start, dir: "right" }), + log.args.newDynamicLengths, + size(newData) > end ? sliceHex(newData, end) : "0x", + ]); + } + const start = log.args.start; + const end = start + log.args.deleteCount; + newData = concatHex([ + padHex(sliceHex(newData, 0, start), { size: start, dir: "right" }), log.args.data, - end >= size(previousData) ? "0x" : sliceHex(previousData, end), + end >= size(newData) ? "0x" : sliceHex(newData, end), ]); + const newValue = decodeValue(table.valueSchema, newData); - debug("setting component via splice", table.tableId, entity, { newValue, previousValue }); - setComponent(component, entity, newValue); + debug("setting component via splice", table.tableId, entity, { newValue, newData, previousData }); + setComponent(component, entity, { ...newValue, __data: newData }); } else if (log.eventName === "StoreDeleteRecord") { debug("deleting component", table.tableId, entity); removeComponent(component, entity); diff --git a/packages/store-sync/src/sqlite/buildSqliteColumn.ts b/packages/store-sync/src/sqlite/buildSqliteColumn.ts index f4e07e73cf..b52daeb194 100644 --- a/packages/store-sync/src/sqlite/buildSqliteColumn.ts +++ b/packages/store-sync/src/sqlite/buildSqliteColumn.ts @@ -1,9 +1,10 @@ -import { AnySQLiteColumnBuilder, blob, integer, text } from "drizzle-orm/sqlite-core"; +import { blob, integer, text } from "drizzle-orm/sqlite-core"; import { SchemaAbiType } from "@latticexyz/schema-type"; import { assertExhaustive } from "@latticexyz/common/utils"; import { address, json } from "./columnTypes"; -export function buildSqliteColumn(name: string, schemaAbiType: SchemaAbiType): AnySQLiteColumnBuilder { +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export function buildSqliteColumn(name: string, schemaAbiType: SchemaAbiType) { switch (schemaAbiType) { case "bool": return integer(name, { mode: "boolean" }); diff --git a/packages/store-sync/src/sqlite/columnTypes.ts b/packages/store-sync/src/sqlite/columnTypes.ts index dc23a26f5c..3dd4c07e9f 100644 --- a/packages/store-sync/src/sqlite/columnTypes.ts +++ b/packages/store-sync/src/sqlite/columnTypes.ts @@ -1,9 +1,9 @@ -import { customType, SQLiteCustomColumnBuilder } from "drizzle-orm/sqlite-core"; -import { ColumnBuilderBaseConfig } from "drizzle-orm"; +import { customType } from "drizzle-orm/sqlite-core"; import superjson from "superjson"; import { Address, getAddress } from "viem"; -export const json = (name: string): SQLiteCustomColumnBuilder => +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const json = (name: string) => customType<{ data: TData; driverData: string }>({ dataType() { return "text"; @@ -16,7 +16,8 @@ export const json = (name: string): SQLiteCustomColumnBuilder => +// eslint-disable-next-line @typescript-eslint/explicit-function-return-type +export const address = (name: string) => customType<{ data: Address; driverData: string }>({ dataType() { return "text"; diff --git a/packages/store-sync/src/sqlite/createSqliteTable.test.ts b/packages/store-sync/src/sqlite/createSqliteTable.test.ts index fbaecab9c1..44349cda42 100644 --- a/packages/store-sync/src/sqlite/createSqliteTable.test.ts +++ b/packages/store-sync/src/sqlite/createSqliteTable.test.ts @@ -14,88 +14,149 @@ describe("createSqliteTable", () => { expect(table).toMatchInlineSnapshot(` SQLiteTable { "__data": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__data", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__data", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueType": undefined, }, "__isDeleted": SQLiteBoolean { "autoIncrement": false, + "columnType": "SQLiteBoolean", "config": { "autoIncrement": false, + "columnType": "SQLiteBoolean", + "dataType": "boolean", "default": undefined, + "hasDefault": false, + "isUnique": false, "mode": "boolean", "name": "__isDeleted", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___isDeleted_unique", + "uniqueType": undefined, }, + "dataType": "boolean", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mode": "boolean", "name": "__isDeleted", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___isDeleted_unique", + "uniqueType": undefined, }, "__key": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__key", "notNull": true, "primaryKey": true, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___key_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__key", "notNull": true, "primary": true, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___key_unique", + "uniqueType": undefined, }, "__lastUpdatedBlockNumber": SQLiteBigInt { + "columnType": "SQLiteBigInt", "config": { + "columnType": "SQLiteBigInt", + "dataType": "bigint", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, + "dataType": "bigint", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, "addr": SQLiteCustomColumn { + "columnType": "SQLiteCustomColumn", "config": { + "columnType": "SQLiteCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "addr", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_addr_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "addr", @@ -103,144 +164,245 @@ describe("createSqliteTable", () => { "primary": false, "sqlName": "text", "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_addr_unique", + "uniqueType": undefined, }, "name": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "name", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_name_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "name", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_name_unique", + "uniqueType": undefined, }, "x": SQLiteInteger { "autoIncrement": false, + "columnType": "SQLiteInteger", "config": { "autoIncrement": false, + "columnType": "SQLiteInteger", + "dataType": "number", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "x", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_x_unique", + "uniqueType": undefined, }, + "dataType": "number", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "x", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_x_unique", + "uniqueType": undefined, }, "y": SQLiteInteger { "autoIncrement": false, + "columnType": "SQLiteInteger", "config": { "autoIncrement": false, + "columnType": "SQLiteInteger", + "dataType": "number", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "y", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_y_unique", + "uniqueType": undefined, }, + "dataType": "number", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "y", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_y_unique", + "uniqueType": undefined, }, Symbol(drizzle:Name): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", Symbol(drizzle:OriginalName): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", Symbol(drizzle:Schema): undefined, Symbol(drizzle:Columns): { "__data": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__data", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__data", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueType": undefined, }, "__isDeleted": SQLiteBoolean { "autoIncrement": false, + "columnType": "SQLiteBoolean", "config": { "autoIncrement": false, + "columnType": "SQLiteBoolean", + "dataType": "boolean", "default": undefined, + "hasDefault": false, + "isUnique": false, "mode": "boolean", "name": "__isDeleted", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___isDeleted_unique", + "uniqueType": undefined, }, + "dataType": "boolean", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mode": "boolean", "name": "__isDeleted", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___isDeleted_unique", + "uniqueType": undefined, }, "__key": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__key", "notNull": true, "primaryKey": true, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___key_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__key", "notNull": true, "primary": true, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___key_unique", + "uniqueType": undefined, }, "__lastUpdatedBlockNumber": SQLiteBigInt { + "columnType": "SQLiteBigInt", "config": { + "columnType": "SQLiteBigInt", + "dataType": "bigint", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, + "dataType": "bigint", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, "addr": SQLiteCustomColumn { + "columnType": "SQLiteCustomColumn", "config": { + "columnType": "SQLiteCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "addr", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_addr_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "addr", @@ -248,56 +410,96 @@ describe("createSqliteTable", () => { "primary": false, "sqlName": "text", "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_addr_unique", + "uniqueType": undefined, }, "name": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "name", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_name_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "name", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_name_unique", + "uniqueType": undefined, }, "x": SQLiteInteger { "autoIncrement": false, + "columnType": "SQLiteInteger", "config": { "autoIncrement": false, + "columnType": "SQLiteInteger", + "dataType": "number", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "x", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_x_unique", + "uniqueType": undefined, }, + "dataType": "number", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "x", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_x_unique", + "uniqueType": undefined, }, "y": SQLiteInteger { "autoIncrement": false, + "columnType": "SQLiteInteger", "config": { "autoIncrement": false, + "columnType": "SQLiteInteger", + "dataType": "number", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "y", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_y_unique", + "uniqueType": undefined, }, + "dataType": "number", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "y", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_y_unique", + "uniqueType": undefined, }, }, Symbol(drizzle:BaseName): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", @@ -321,88 +523,149 @@ describe("createSqliteTable", () => { expect(table).toMatchInlineSnapshot(` SQLiteTable { "__data": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__data", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__data", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueType": undefined, }, "__isDeleted": SQLiteBoolean { "autoIncrement": false, + "columnType": "SQLiteBoolean", "config": { "autoIncrement": false, + "columnType": "SQLiteBoolean", + "dataType": "boolean", "default": undefined, + "hasDefault": false, + "isUnique": false, "mode": "boolean", "name": "__isDeleted", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___isDeleted_unique", + "uniqueType": undefined, }, + "dataType": "boolean", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mode": "boolean", "name": "__isDeleted", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___isDeleted_unique", + "uniqueType": undefined, }, "__key": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__key", "notNull": true, "primaryKey": true, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___key_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__key", "notNull": true, "primary": true, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___key_unique", + "uniqueType": undefined, }, "__lastUpdatedBlockNumber": SQLiteBigInt { + "columnType": "SQLiteBigInt", "config": { + "columnType": "SQLiteBigInt", + "dataType": "bigint", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, + "dataType": "bigint", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, "addrs": SQLiteCustomColumn { + "columnType": "SQLiteCustomColumn", "config": { + "columnType": "SQLiteCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "addrs", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_addrs_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "addrs", @@ -410,94 +673,157 @@ describe("createSqliteTable", () => { "primary": false, "sqlName": "text", "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_addrs_unique", + "uniqueType": undefined, }, Symbol(drizzle:Name): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", Symbol(drizzle:OriginalName): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", Symbol(drizzle:Schema): undefined, Symbol(drizzle:Columns): { "__data": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__data", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__data", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueType": undefined, }, "__isDeleted": SQLiteBoolean { "autoIncrement": false, + "columnType": "SQLiteBoolean", "config": { "autoIncrement": false, + "columnType": "SQLiteBoolean", + "dataType": "boolean", "default": undefined, + "hasDefault": false, + "isUnique": false, "mode": "boolean", "name": "__isDeleted", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___isDeleted_unique", + "uniqueType": undefined, }, + "dataType": "boolean", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mode": "boolean", "name": "__isDeleted", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___isDeleted_unique", + "uniqueType": undefined, }, "__key": SQLiteText { + "columnType": "SQLiteText", "config": { + "columnType": "SQLiteText", + "dataType": "string", "default": undefined, - "enumValues": [], + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__key", "notNull": true, "primaryKey": true, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___key_unique", + "uniqueType": undefined, }, + "dataType": "string", "default": undefined, - "enumValues": [], - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "length": undefined, "name": "__key", "notNull": true, "primary": true, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___key_unique", + "uniqueType": undefined, }, "__lastUpdatedBlockNumber": SQLiteBigInt { + "columnType": "SQLiteBigInt", "config": { + "columnType": "SQLiteBigInt", + "dataType": "bigint", "default": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, + "dataType": "bigint", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "name": "__lastUpdatedBlockNumber", "notNull": true, "primary": false, "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", + "uniqueType": undefined, }, "addrs": SQLiteCustomColumn { + "columnType": "SQLiteCustomColumn", "config": { + "columnType": "SQLiteCustomColumn", "customTypeParams": { "dataType": [Function], "fromDriver": [Function], "toDriver": [Function], }, + "dataType": "custom", "default": undefined, "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, "name": "addrs", "notNull": true, "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_addrs_unique", + "uniqueType": undefined, }, + "dataType": "custom", "default": undefined, - "hasDefault": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, "mapFrom": [Function], "mapTo": [Function], "name": "addrs", @@ -505,6 +831,8 @@ describe("createSqliteTable", () => { "primary": false, "sqlName": "text", "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users_addrs_unique", + "uniqueType": undefined, }, }, Symbol(drizzle:BaseName): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", diff --git a/packages/store-sync/src/sqlite/createSqliteTable.ts b/packages/store-sync/src/sqlite/createSqliteTable.ts index e4b02e94a4..4f87fbc1f2 100644 --- a/packages/store-sync/src/sqlite/createSqliteTable.ts +++ b/packages/store-sync/src/sqlite/createSqliteTable.ts @@ -1,21 +1,22 @@ -import { AnySQLiteColumnBuilder, SQLiteTableWithColumns, sqliteTable } from "drizzle-orm/sqlite-core"; +import { SQLiteColumnBuilderBase, SQLiteTableWithColumns, sqliteTable } from "drizzle-orm/sqlite-core"; import { SchemaAbiType, StaticAbiType } from "@latticexyz/schema-type"; import { buildSqliteColumn } from "./buildSqliteColumn"; import { Address } from "viem"; import { getTableName } from "./getTableName"; export const metaColumns = { - __key: buildSqliteColumn("__key", "bytes").notNull().primaryKey(), + __key: buildSqliteColumn("__key", "bytes").primaryKey(), __data: buildSqliteColumn("__data", "bytes").notNull(), __lastUpdatedBlockNumber: buildSqliteColumn("__lastUpdatedBlockNumber", "uint256").notNull(), // TODO: last updated block hash? __isDeleted: buildSqliteColumn("__isDeleted", "bool").notNull(), -} as const satisfies Record; +} as const satisfies Record; type SQLiteTableFromSchema< TKeySchema extends Record, TValueSchema extends Record > = SQLiteTableWithColumns<{ + dialect: "sqlite"; name: string; schema: string | undefined; columns: { diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 0795d7a6b6..c07cbb9b6f 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -1,4 +1,4 @@ -import { Hex, PublicClient, concatHex, getAddress, size, sliceHex } from "viem"; +import { Hex, PublicClient, concatHex, getAddress, padHex, size, sliceHex } from "viem"; import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; import { and, eq, sql } from "drizzle-orm"; import { sqliteTableToSql } from "./sqliteTableToSql"; @@ -13,7 +13,7 @@ import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexToTableId, tableIdToHex } from "@latticexyz/common"; -import { decodeKey, decodeValue } from "@latticexyz/protocol-parser"; +import { UNCHANGED_PACKED_COUNTER, decodeKey, decodeValue, padSliceHex } from "@latticexyz/protocol-parser"; // TODO: upgrade drizzle and use async sqlite interface for consistency @@ -133,21 +133,27 @@ export async function sqliteStorage({ } else if (log.eventName === "StoreSpliceRecord") { // TODO: verify that this returns what we expect (doesn't error/undefined on no record) const previousData = - tx.select().from(sqliteTable).where(eq(sqliteTable.__key, uniqueKey)).get().__data ?? "0x"; + tx.select().from(sqliteTable).where(eq(sqliteTable.__key, uniqueKey)).all()[0]?.__data ?? "0x"; - // TODO: figure out if we need to pad anything or set defaults - const end = log.args.start + log.args.deleteCount; - const newData = concatHex([ - sliceHex(previousData, 0, log.args.start), - log.args.data, - end >= size(previousData) ? "0x" : sliceHex(previousData, end), - ]); - const newValue = decodeValue(table.valueSchema, newData); + let newData = previousData; + if (log.args.newDynamicLengths !== UNCHANGED_PACKED_COUNTER) { + const start = Number(log.args.dynamicLengthsStart); + const end = start + size(log.args.newDynamicLengths); + newData = concatHex([ + padSliceHex(newData, 0, start), + log.args.newDynamicLengths, + padSliceHex(newData, end), + ]); + } + const start = log.args.start; + const end = start + log.args.deleteCount; + newData = concatHex([padSliceHex(newData, 0, start), log.args.data, padSliceHex(newData, end)]); + const newValue = decodeValue(table.valueSchema, newData); debug("upserting record via splice", { key, previousData, newData, newValue, log }); tx.insert(sqliteTable) .values({ - __key: key, + __key: uniqueKey, __data: newData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, @@ -172,7 +178,7 @@ export async function sqliteStorage({ __lastUpdatedBlockNumber: blockNumber, __isDeleted: true, }) - .where(eq(sqliteTable.__key, key)) + .where(eq(sqliteTable.__key, uniqueKey)) .run(); } } diff --git a/packages/store/abi/IStore.sol/IStore.abi.json b/packages/store/abi/IStore.sol/IStore.abi.json index e97ea7b3ea..a7cd620598 100644 --- a/packages/store/abi/IStore.sol/IStore.abi.json +++ b/packages/store/abi/IStore.sol/IStore.abi.json @@ -206,6 +206,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/store/abi/IStore.sol/IStoreData.abi.json b/packages/store/abi/IStore.sol/IStoreData.abi.json index 372e736223..7b08bc8fda 100644 --- a/packages/store/abi/IStore.sol/IStoreData.abi.json +++ b/packages/store/abi/IStore.sol/IStoreData.abi.json @@ -75,6 +75,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/store/abi/IStore.sol/IStoreWrite.abi.json b/packages/store/abi/IStore.sol/IStoreWrite.abi.json index 99291b1b64..301a962b48 100644 --- a/packages/store/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/store/abi/IStore.sol/IStoreWrite.abi.json @@ -75,6 +75,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/store/abi/StoreCore.sol/StoreCore.abi.json b/packages/store/abi/StoreCore.sol/StoreCore.abi.json index 7fe6a0f6a4..52eca7ff43 100644 --- a/packages/store/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/store/abi/StoreCore.sol/StoreCore.abi.json @@ -100,6 +100,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/store/abi/StoreMock.sol/StoreMock.abi.json b/packages/store/abi/StoreMock.sol/StoreMock.abi.json index 47d285541e..24bf93750e 100644 --- a/packages/store/abi/StoreMock.sol/StoreMock.abi.json +++ b/packages/store/abi/StoreMock.sol/StoreMock.abi.json @@ -254,6 +254,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json index 7ba4a520c3..8f04de4e60 100644 --- a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json +++ b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json @@ -248,6 +248,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index 1e47df5392..62dbff61fc 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -45,7 +45,16 @@ interface IStoreRead { interface IStoreWrite { event StoreSetRecord(bytes32 table, bytes32[] key, bytes data); - event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); + // TODO: finalize dynamic lengths args (these names/positions are placeholders while I figure out of this is enough data for schemaless indexing) + event StoreSpliceRecord( + bytes32 table, + bytes32[] key, + uint48 start, + uint40 deleteCount, + bytes data, + bytes32 newDynamicLengths, + uint256 dynamicLengthsStart + ); event StoreDeleteRecord(bytes32 table, bytes32[] key); // Set full record (including full dynamic data) diff --git a/packages/store/src/PackedCounter.sol b/packages/store/src/PackedCounter.sol index e8f53ec949..3d4734074a 100644 --- a/packages/store/src/PackedCounter.sol +++ b/packages/store/src/PackedCounter.sol @@ -13,6 +13,8 @@ uint256 constant ACC_BITS = 7 * 8; uint256 constant VAL_BITS = 5 * 8; // Maximum value of a 5-byte section uint256 constant MAX_VAL = type(uint40).max; +// Used in splice events to indicate when a counter is unchanged (e.g. replacing the entire field) +bytes32 constant UNCHANGED_PACKED_COUNTER = bytes32(type(uint256).max); /** * Static functions for PackedCounter diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index b8e825fad6..6e0ae95f3b 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -6,7 +6,7 @@ import { Bytes } from "./Bytes.sol"; import { Storage } from "./Storage.sol"; import { Memory } from "./Memory.sol"; import { Schema, SchemaLib } from "./Schema.sol"; -import { PackedCounter } from "./PackedCounter.sol"; +import { PackedCounter, UNCHANGED_PACKED_COUNTER } from "./PackedCounter.sol"; import { Slice, SliceLib } from "./Slice.sol"; import { Hooks, Tables, HooksTableId } from "./codegen/Tables.sol"; import { IStoreErrors } from "./IStoreErrors.sol"; @@ -16,7 +16,16 @@ import { StoreSwitch } from "./StoreSwitch.sol"; library StoreCore { // note: the preimage of the tuple of keys used to index is part of the event, so it can be used by indexers event StoreSetRecord(bytes32 table, bytes32[] key, bytes data); - event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); + // TODO: finalize dynamic lengths args (these names/positions are placeholders while I figure out of this is enough data for schemaless indexing) + event StoreSpliceRecord( + bytes32 table, + bytes32[] key, + uint48 start, + uint40 deleteCount, + bytes data, + bytes32 newDynamicLengths, + uint256 dynamicLengthsStart + ); event StoreDeleteRecord(bytes32 table, bytes32[] key); event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data); @@ -529,8 +538,17 @@ library StoreCoreInternal { // Prepare data for the splice event uint256 start = offset; uint256 deleteCount = valueSchema.atIndex(schemaIndex).getStaticByteLength(); + uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), data); + emit StoreCore.StoreSpliceRecord( + tableId, + key, + uint48(start), + uint40(deleteCount), + data, + UNCHANGED_PACKED_COUNTER, + encodedLengthsStart + ); } function _setDynamicField( @@ -566,8 +584,17 @@ library StoreCoreInternal { } } uint256 deleteCount = oldFieldLength; + uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), data); + emit StoreCore.StoreSpliceRecord( + tableId, + key, + uint48(start), + uint40(deleteCount), + data, + encodedLengths.unwrap(), + encodedLengthsStart + ); } function _pushToDynamicField( @@ -602,8 +629,17 @@ library StoreCoreInternal { } } uint256 deleteCount = 0; + uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), dataToPush); + emit StoreCore.StoreSpliceRecord( + tableId, + key, + uint48(start), + uint40(deleteCount), + dataToPush, + encodedLengths.unwrap(), + encodedLengthsStart + ); } function _popFromDynamicField( @@ -637,8 +673,17 @@ library StoreCoreInternal { } } uint256 deleteCount = byteLengthToPop; + uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), new bytes(0)); + emit StoreCore.StoreSpliceRecord( + tableId, + key, + uint48(start), + uint40(deleteCount), + new bytes(0), + encodedLengths.unwrap(), + encodedLengthsStart + ); } // startOffset is measured in bytes @@ -669,8 +714,17 @@ library StoreCoreInternal { } } uint256 deleteCount = dataToSet.length; + uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord(tableId, key, uint48(start), uint40(deleteCount), dataToSet); + emit StoreCore.StoreSpliceRecord( + tableId, + key, + uint48(start), + uint40(deleteCount), + dataToSet, + encodedLengths.unwrap(), + encodedLengthsStart + ); } /************************************************************************ diff --git a/packages/store/ts/storeEvents.ts b/packages/store/ts/storeEvents.ts index d87725a2e2..068c81a47a 100644 --- a/packages/store/ts/storeEvents.ts +++ b/packages/store/ts/storeEvents.ts @@ -1,6 +1,7 @@ export const storeEvents = [ "event StoreSetRecord(bytes32 table, bytes32[] key, bytes data)", - "event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", + // TODO: finalize dynamic lengths args (these names/positions are placeholders while I figure out of this is enough data for schemaless indexing) + "event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data, bytes32 newDynamicLengths, uint256 dynamicLengthsStart)", "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data)", "event StoreDeleteRecord(bytes32 table, bytes32[] key)", ] as const; diff --git a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json index 225f24e766..57a025fdc7 100644 --- a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json +++ b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json @@ -321,6 +321,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/world/abi/IStore.sol/IStore.abi.json b/packages/world/abi/IStore.sol/IStore.abi.json index e97ea7b3ea..a7cd620598 100644 --- a/packages/world/abi/IStore.sol/IStore.abi.json +++ b/packages/world/abi/IStore.sol/IStore.abi.json @@ -206,6 +206,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/world/abi/IStore.sol/IStoreData.abi.json b/packages/world/abi/IStore.sol/IStoreData.abi.json index 372e736223..7b08bc8fda 100644 --- a/packages/world/abi/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/IStore.sol/IStoreData.abi.json @@ -75,6 +75,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/world/abi/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/IStore.sol/IStoreWrite.abi.json index 99291b1b64..301a962b48 100644 --- a/packages/world/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/IStore.sol/IStoreWrite.abi.json @@ -75,6 +75,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/world/abi/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/StoreCore.sol/StoreCore.abi.json index 7fe6a0f6a4..52eca7ff43 100644 --- a/packages/world/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/StoreCore.sol/StoreCore.abi.json @@ -100,6 +100,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/world/abi/World.sol/World.abi.json b/packages/world/abi/World.sol/World.abi.json index 23c696510b..eefdee3f97 100644 --- a/packages/world/abi/World.sol/World.abi.json +++ b/packages/world/abi/World.sol/World.abi.json @@ -344,6 +344,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/world/abi/src/IStore.sol/IStore.abi.json b/packages/world/abi/src/IStore.sol/IStore.abi.json index e97ea7b3ea..a7cd620598 100644 --- a/packages/world/abi/src/IStore.sol/IStore.abi.json +++ b/packages/world/abi/src/IStore.sol/IStore.abi.json @@ -206,6 +206,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/world/abi/src/IStore.sol/IStoreData.abi.json b/packages/world/abi/src/IStore.sol/IStoreData.abi.json index 372e736223..7b08bc8fda 100644 --- a/packages/world/abi/src/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreData.abi.json @@ -75,6 +75,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json index 99291b1b64..301a962b48 100644 --- a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json @@ -75,6 +75,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json index 7fe6a0f6a4..52eca7ff43 100644 --- a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json @@ -100,6 +100,18 @@ "internalType": "bytes", "name": "data", "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "newDynamicLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "dynamicLengthsStart", + "type": "uint256" } ], "name": "StoreSpliceRecord", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7d61b0d740..cc4dcc71b5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -772,14 +772,14 @@ importers: specifier: ^0.2.22 version: 0.2.22(typescript@5.1.6) better-sqlite3: - specifier: ^8.4.0 - version: 8.4.0 + specifier: ^8.6.0 + version: 8.6.0 debug: specifier: ^4.3.4 version: 4.3.4(supports-color@8.1.1) drizzle-orm: - specifier: ^0.27.0 - version: 0.27.0(@types/better-sqlite3@7.6.4)(better-sqlite3@8.4.0)(postgres@3.3.5) + specifier: ^0.28.5 + version: 0.28.5(@types/better-sqlite3@7.6.4)(better-sqlite3@8.6.0)(postgres@3.3.5) fastify: specifier: ^4.21.0 version: 4.21.0 @@ -851,11 +851,11 @@ importers: specifier: ^4.3.4 version: 4.3.4(supports-color@8.1.1) drizzle-orm: - specifier: ^0.27.0 - version: 0.27.0(@types/sql.js@1.4.4)(kysely@0.26.1)(postgres@3.3.5)(sql.js@1.8.0) + specifier: ^0.28.5 + version: 0.28.5(@types/sql.js@1.4.4)(kysely@0.26.3)(postgres@3.3.5)(sql.js@1.8.0) kysely: - specifier: ^0.26.1 - version: 0.26.1 + specifier: ^0.26.3 + version: 0.26.3 postgres: specifier: ^3.3.5 version: 3.3.5 @@ -4108,8 +4108,8 @@ packages: is-windows: 1.0.2 dev: true - /better-sqlite3@8.4.0: - resolution: {integrity: sha512-NmsNW1CQvqMszu/CFAJ3pLct6NEFlNfuGM6vw72KHkjOD1UDnL96XNN1BMQc1hiHo8vE2GbOWQYIpZ+YM5wrZw==} + /better-sqlite3@8.6.0: + resolution: {integrity: sha512-jwAudeiTMTSyby+/SfbHDebShbmC2MCH8mU2+DXi0WJfv13ypEJm47cd3kljmy/H130CazEvkf2Li//ewcMJ1g==} requiresBuild: true dependencies: bindings: 1.5.0 @@ -5013,8 +5013,8 @@ packages: detect-libc: 1.0.3 dev: true - /drizzle-orm@0.27.0(@types/better-sqlite3@7.6.4)(better-sqlite3@8.4.0)(postgres@3.3.5): - resolution: {integrity: sha512-LGiJ0icB+wQwgbSCOvAjONY8Ec6G/EDzQQP5PmUaQYeI9OqgpVKHC2T1fFIbvk5dabWsbokJ5NOciVAxriStig==} + /drizzle-orm@0.28.5(@types/better-sqlite3@7.6.4)(better-sqlite3@8.6.0)(postgres@3.3.5): + resolution: {integrity: sha512-6r6Iw4c38NAmW6TiKH3TUpGUQ1YdlEoLJOQptn8XPx3Z63+vFNKfAiANqrIiYZiMjKR9+NYAL219nFrmo1duXA==} peerDependencies: '@aws-sdk/client-rds-data': '>=3' '@cloudflare/workers-types': '>=3' @@ -5076,12 +5076,12 @@ packages: optional: true dependencies: '@types/better-sqlite3': 7.6.4 - better-sqlite3: 8.4.0 + better-sqlite3: 8.6.0 postgres: 3.3.5 dev: false - /drizzle-orm@0.27.0(@types/sql.js@1.4.4)(kysely@0.26.1)(postgres@3.3.5)(sql.js@1.8.0): - resolution: {integrity: sha512-LGiJ0icB+wQwgbSCOvAjONY8Ec6G/EDzQQP5PmUaQYeI9OqgpVKHC2T1fFIbvk5dabWsbokJ5NOciVAxriStig==} + /drizzle-orm@0.28.5(@types/sql.js@1.4.4)(kysely@0.26.3)(postgres@3.3.5)(sql.js@1.8.0): + resolution: {integrity: sha512-6r6Iw4c38NAmW6TiKH3TUpGUQ1YdlEoLJOQptn8XPx3Z63+vFNKfAiANqrIiYZiMjKR9+NYAL219nFrmo1duXA==} peerDependencies: '@aws-sdk/client-rds-data': '>=3' '@cloudflare/workers-types': '>=3' @@ -5143,7 +5143,7 @@ packages: optional: true dependencies: '@types/sql.js': 1.4.4 - kysely: 0.26.1 + kysely: 0.26.3 postgres: 3.3.5 sql.js: 1.8.0 dev: false @@ -7702,8 +7702,8 @@ packages: engines: {node: '>=6'} dev: true - /kysely@0.26.1: - resolution: {integrity: sha512-FVRomkdZofBu3O8SiwAOXrwbhPZZr8mBN5ZeUWyprH29jzvy6Inzqbd0IMmGxpd4rcOCL9HyyBNWBa8FBqDAdg==} + /kysely@0.26.3: + resolution: {integrity: sha512-yWSgGi9bY13b/W06DD2OCDDHQmq1kwTGYlQ4wpZkMOJqMGCstVCFIvxCCVG4KfY1/3G0MhDAcZsip/Lw8/vJWw==} engines: {node: '>=14.0.0'} dev: false From 9c0e88922a1e81c72de7babeebdeada38cced665 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 5 Sep 2023 09:34:09 +0100 Subject: [PATCH 17/69] move splicing to util --- .../src/postgres/postgresStorage.ts | 22 +++---------- packages/store-sync/src/recs/recsStorage.ts | 33 +++---------------- packages/store-sync/src/spliceValueHex.ts | 19 +++++++++++ .../store-sync/src/sqlite/sqliteStorage.ts | 21 +++--------- 4 files changed, 31 insertions(+), 64 deletions(-) create mode 100644 packages/store-sync/src/spliceValueHex.ts diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index 3df1e59f04..3e6d5dc2ba 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -1,4 +1,4 @@ -import { Hex, PublicClient, concatHex, padHex, size, sliceHex } from "viem"; +import { Hex, PublicClient, concatHex } from "viem"; import { PgDatabase, QueryResultHKT } from "drizzle-orm/pg-core"; import { eq, inArray } from "drizzle-orm"; import { buildTable } from "./buildTable"; @@ -13,7 +13,8 @@ import { getTableKey } from "./getTableKey"; import { StorageAdapter, StorageAdapterBlock } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; -import { UNCHANGED_PACKED_COUNTER, decodeKey, decodeValue, padSliceHex } from "@latticexyz/protocol-parser"; +import { decodeKey, decodeValue } from "@latticexyz/protocol-parser"; +import { spliceValueHex } from "../spliceValueHex"; // Currently assumes one DB per chain ID @@ -136,23 +137,8 @@ export async function postgresStorage // TODO: verify that this returns what we expect (doesn't error/undefined on no record) const previousData = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]?.__data ?? "0x"; - - let newData = previousData; - if (log.args.newDynamicLengths !== UNCHANGED_PACKED_COUNTER) { - const start = Number(log.args.dynamicLengthsStart); - const end = start + size(log.args.newDynamicLengths); - newData = concatHex([ - padSliceHex(newData, 0, start), - log.args.newDynamicLengths, - padSliceHex(newData, end), - ]); - } - const start = log.args.start; - const end = start + log.args.deleteCount; - newData = concatHex([padSliceHex(newData, 0, start), log.args.data, padSliceHex(newData, end)]); - + const newData = spliceValueHex(previousData, log); const newValue = decodeValue(table.valueSchema, newData); - debug("upserting record via splice", { key, previousData, newData, newValue, log }); await tx .insert(sqlTable) diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index 934cc02276..5a51e87763 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -12,20 +12,13 @@ import { defineInternalComponents } from "./defineInternalComponents"; import { getTableEntity } from "./getTableEntity"; import { StoreComponentMetadata } from "./common"; import { hexToTableId } from "@latticexyz/common"; -import { - SchemaToPrimitives, - UNCHANGED_PACKED_COUNTER, - ValueSchema, - decodeValue, - encodeValue, - staticDataLength, -} from "@latticexyz/protocol-parser"; -import { Hex, concatHex, padHex, size, sliceHex } from "viem"; +import { decodeValue } from "@latticexyz/protocol-parser"; +import { Hex } from "viem"; import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; -import { schemaToDefaults } from "../schemaToDefaults"; +import { spliceValueHex } from "../spliceValueHex"; export function recsStorage({ components, @@ -81,25 +74,7 @@ export function recsStorage({ setComponent(component, entity, { ...value, __data: log.args.data }); } else if (log.eventName === "StoreSpliceRecord") { const previousData = (getComponentValue(component, entity)?.__data as Hex) ?? "0x"; - - let newData = previousData; - if (log.args.newDynamicLengths !== UNCHANGED_PACKED_COUNTER) { - const start = Number(log.args.dynamicLengthsStart); - const end = start + size(log.args.newDynamicLengths); - newData = concatHex([ - padHex(sliceHex(newData, 0, start), { size: start, dir: "right" }), - log.args.newDynamicLengths, - size(newData) > end ? sliceHex(newData, end) : "0x", - ]); - } - const start = log.args.start; - const end = start + log.args.deleteCount; - newData = concatHex([ - padHex(sliceHex(newData, 0, start), { size: start, dir: "right" }), - log.args.data, - end >= size(newData) ? "0x" : sliceHex(newData, end), - ]); - + const newData = spliceValueHex(previousData, log); const newValue = decodeValue(table.valueSchema, newData); debug("setting component via splice", table.tableId, entity, { newValue, newData, previousData }); setComponent(component, entity, { ...newValue, __data: newData }); diff --git a/packages/store-sync/src/spliceValueHex.ts b/packages/store-sync/src/spliceValueHex.ts new file mode 100644 index 0000000000..499a7269f5 --- /dev/null +++ b/packages/store-sync/src/spliceValueHex.ts @@ -0,0 +1,19 @@ +import { UNCHANGED_PACKED_COUNTER, padSliceHex } from "@latticexyz/protocol-parser"; +import { Hex, size, concatHex } from "viem"; +import { StorageAdapterLog } from "./common"; + +export function spliceValueHex(previousData: Hex, log: StorageAdapterLog & { eventName: "StoreSpliceRecord" }): Hex { + let newData = previousData; + + if (log.args.newDynamicLengths !== UNCHANGED_PACKED_COUNTER) { + const start = Number(log.args.dynamicLengthsStart); + const end = start + size(log.args.newDynamicLengths); + newData = concatHex([padSliceHex(newData, 0, start), log.args.newDynamicLengths, padSliceHex(newData, end)]); + } + + const start = log.args.start; + const end = start + log.args.deleteCount; + newData = concatHex([padSliceHex(newData, 0, start), log.args.data, padSliceHex(newData, end)]); + + return newData; +} diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index c07cbb9b6f..9ad257a7ec 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -1,4 +1,4 @@ -import { Hex, PublicClient, concatHex, getAddress, padHex, size, sliceHex } from "viem"; +import { Hex, PublicClient, concatHex, getAddress } from "viem"; import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; import { and, eq, sql } from "drizzle-orm"; import { sqliteTableToSql } from "./sqliteTableToSql"; @@ -13,7 +13,8 @@ import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexToTableId, tableIdToHex } from "@latticexyz/common"; -import { UNCHANGED_PACKED_COUNTER, decodeKey, decodeValue, padSliceHex } from "@latticexyz/protocol-parser"; +import { decodeKey, decodeValue } from "@latticexyz/protocol-parser"; +import { spliceValueHex } from "../spliceValueHex"; // TODO: upgrade drizzle and use async sqlite interface for consistency @@ -134,21 +135,7 @@ export async function sqliteStorage({ // TODO: verify that this returns what we expect (doesn't error/undefined on no record) const previousData = tx.select().from(sqliteTable).where(eq(sqliteTable.__key, uniqueKey)).all()[0]?.__data ?? "0x"; - - let newData = previousData; - if (log.args.newDynamicLengths !== UNCHANGED_PACKED_COUNTER) { - const start = Number(log.args.dynamicLengthsStart); - const end = start + size(log.args.newDynamicLengths); - newData = concatHex([ - padSliceHex(newData, 0, start), - log.args.newDynamicLengths, - padSliceHex(newData, end), - ]); - } - const start = log.args.start; - const end = start + log.args.deleteCount; - newData = concatHex([padSliceHex(newData, 0, start), log.args.data, padSliceHex(newData, end)]); - + const newData = spliceValueHex(previousData, log); const newValue = decodeValue(table.valueSchema, newData); debug("upserting record via splice", { key, previousData, newData, newValue, log }); tx.insert(sqliteTable) From c13dddc029751a8724f6f3b93b6a09434c477eea Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 5 Sep 2023 09:39:11 +0100 Subject: [PATCH 18/69] build --- .../contracts/types/ethers-contracts/IWorld.ts | 16 +++++++++++----- .../factories/IWorld__factory.ts | 12 ++++++++++++ .../contracts/types/ethers-contracts/IWorld.ts | 16 +++++++++++----- .../factories/IWorld__factory.ts | 12 ++++++++++++ 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts b/e2e/packages/contracts/types/ethers-contracts/IWorld.ts index 7b03a2ce8c..84e4920266 100644 --- a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts +++ b/e2e/packages/contracts/types/ethers-contracts/IWorld.ts @@ -423,7 +423,7 @@ export interface IWorldInterface extends utils.Interface { "StoreDeleteRecord(bytes32,bytes32[])": EventFragment; "StoreEphemeralRecord(bytes32,bytes32[],bytes)": EventFragment; "StoreSetRecord(bytes32,bytes32[],bytes)": EventFragment; - "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)": EventFragment; + "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32,uint256)": EventFragment; }; getEvent(nameOrSignatureOrTopic: "HelloWorld"): EventFragment; @@ -481,9 +481,11 @@ export interface StoreSpliceRecordEventObject { start: number; deleteCount: number; data: string; + newDynamicLengths: string; + dynamicLengthsStart: BigNumber; } export type StoreSpliceRecordEvent = TypedEvent< - [string, string[], number, number, string], + [string, string[], number, number, string, string, BigNumber], StoreSpliceRecordEventObject >; @@ -1225,19 +1227,23 @@ export interface IWorld extends BaseContract { data?: null ): StoreSetRecordEventFilter; - "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)"( + "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32,uint256)"( table?: null, key?: null, start?: null, deleteCount?: null, - data?: null + data?: null, + newDynamicLengths?: null, + dynamicLengthsStart?: null ): StoreSpliceRecordEventFilter; StoreSpliceRecord( table?: null, key?: null, start?: null, deleteCount?: null, - data?: null + data?: null, + newDynamicLengths?: null, + dynamicLengthsStart?: null ): StoreSpliceRecordEventFilter; }; diff --git a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts index 2a8af4e892..dc20d0656a 100644 --- a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ b/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts @@ -373,6 +373,18 @@ const _abi = [ name: "data", type: "bytes", }, + { + indexed: false, + internalType: "bytes32", + name: "newDynamicLengths", + type: "bytes32", + }, + { + indexed: false, + internalType: "uint256", + name: "dynamicLengthsStart", + type: "uint256", + }, ], name: "StoreSpliceRecord", type: "event", diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts b/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts index 3400734265..1a88e95f73 100644 --- a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts +++ b/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts @@ -467,7 +467,7 @@ export interface IWorldInterface extends utils.Interface { "StoreDeleteRecord(bytes32,bytes32[])": EventFragment; "StoreEphemeralRecord(bytes32,bytes32[],bytes)": EventFragment; "StoreSetRecord(bytes32,bytes32[],bytes)": EventFragment; - "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)": EventFragment; + "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32,uint256)": EventFragment; }; getEvent(nameOrSignatureOrTopic: "HelloWorld"): EventFragment; @@ -525,9 +525,11 @@ export interface StoreSpliceRecordEventObject { start: number; deleteCount: number; data: string; + newDynamicLengths: string; + dynamicLengthsStart: BigNumber; } export type StoreSpliceRecordEvent = TypedEvent< - [string, string[], number, number, string], + [string, string[], number, number, string, string, BigNumber], StoreSpliceRecordEventObject >; @@ -1309,19 +1311,23 @@ export interface IWorld extends BaseContract { data?: null ): StoreSetRecordEventFilter; - "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes)"( + "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32,uint256)"( table?: null, key?: null, start?: null, deleteCount?: null, - data?: null + data?: null, + newDynamicLengths?: null, + dynamicLengthsStart?: null ): StoreSpliceRecordEventFilter; StoreSpliceRecord( table?: null, key?: null, start?: null, deleteCount?: null, - data?: null + data?: null, + newDynamicLengths?: null, + dynamicLengthsStart?: null ): StoreSpliceRecordEventFilter; }; diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts index 84c36ebc40..b2b08e127d 100644 --- a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ b/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts @@ -335,6 +335,18 @@ const _abi = [ name: "data", type: "bytes", }, + { + indexed: false, + internalType: "bytes32", + name: "newDynamicLengths", + type: "bytes32", + }, + { + indexed: false, + internalType: "uint256", + name: "dynamicLengthsStart", + type: "uint256", + }, ], name: "StoreSpliceRecord", type: "event", From b54782eb49fcbb76bdb11feee5efee76b879baaa Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 5 Sep 2023 09:50:17 +0100 Subject: [PATCH 19/69] add missing args to tests --- packages/store/test/StoreCore.t.sol | 34 ++++++++++++++++------ packages/store/test/StoreCoreDynamic.t.sol | 8 +++-- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index 303c50e416..e74d5ea41f 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -354,7 +354,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord(table, key, 0, uint40(firstDataPacked.length), firstDataPacked); + emit StoreSpliceRecord(table, key, 0, uint40(firstDataPacked.length), firstDataPacked, bytes32(0), 0); // Set first field IStore(this).setField(table, key, 0, firstDataPacked, valueSchema); @@ -385,7 +385,9 @@ contract StoreCoreTest is Test, StoreMock { key, uint48(firstDataPacked.length), uint40(secondDataPacked.length), - secondDataPacked + secondDataPacked, + bytes32(0), + 0 ); IStore(this).setField(table, key, 1, secondDataPacked, valueSchema); @@ -437,7 +439,9 @@ contract StoreCoreTest is Test, StoreMock { key, uint48(firstDataPacked.length + secondDataPacked.length + 32), 0, - thirdDataBytes + thirdDataBytes, + bytes32(0), + 0 ); // Set third field @@ -465,7 +469,9 @@ contract StoreCoreTest is Test, StoreMock { key, uint48(firstDataPacked.length + secondDataPacked.length + 32 + thirdDataBytes.length), 0, - fourthDataBytes + fourthDataBytes, + bytes32(0), + 0 ); // Set fourth field @@ -497,7 +503,9 @@ contract StoreCoreTest is Test, StoreMock { key, uint48(firstDataPacked.length + secondDataPacked.length + 32 + thirdDataBytes.length), uint40(fourthDataBytes.length), - thirdDataBytes + thirdDataBytes, + bytes32(0), + 0 ); // Set fourth field @@ -647,7 +655,9 @@ contract StoreCoreTest is Test, StoreMock { data.key, uint48(data.firstDataBytes.length + 32 + data.secondDataBytes.length), 0, - data.secondDataToPush + data.secondDataToPush, + bytes32(0), + 0 ); // Push to second field @@ -689,7 +699,9 @@ contract StoreCoreTest is Test, StoreMock { data.key, uint48(data.firstDataBytes.length + 32 + data.newSecondDataBytes.length + data.thirdDataBytes.length), 0, - data.thirdDataToPush + data.thirdDataToPush, + bytes32(0), + 0 ); // Push to third field @@ -790,7 +802,9 @@ contract StoreCoreTest is Test, StoreMock { data.key, uint48(data.firstDataBytes.length + 32 + 4 * 1), 4 * 1, - data.secondDataForUpdate + data.secondDataForUpdate, + bytes32(0), + 0 ); // Update index 1 in second field (4 = byte length of uint32) @@ -834,7 +848,9 @@ contract StoreCoreTest is Test, StoreMock { data.key, uint48(data.firstDataBytes.length + 32 + data.newSecondDataBytes.length + 8 * 1), 8 * 4, - data.thirdDataForUpdate + data.thirdDataForUpdate, + bytes32(0), + 0 ); // Update indexes 1,2,3,4 in third field (8 = byte length of uint64) diff --git a/packages/store/test/StoreCoreDynamic.t.sol b/packages/store/test/StoreCoreDynamic.t.sol index c423599641..710eb4fc76 100644 --- a/packages/store/test/StoreCoreDynamic.t.sol +++ b/packages/store/test/StoreCoreDynamic.t.sol @@ -94,7 +94,9 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreReadWithStubs { _key, uint48(32 + 32 + secondDataBytes.length - byteLengthToPop), uint40(byteLengthToPop), - new bytes(0) + new bytes(0), + bytes32(0), + 0 ); // Pop from second field @@ -139,7 +141,9 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreReadWithStubs { _key, uint48(32 + 32 + secondDataBytes.length + thirdDataBytes.length - byteLengthToPop), uint40(byteLengthToPop), - new bytes(0) + new bytes(0), + bytes32(0), + 0 ); // Pop from the field From 498ca2d45066af163b6e022f13f75b5afccc287d Mon Sep 17 00:00:00 2001 From: dk1a Date: Wed, 6 Sep 2023 23:14:07 +0300 Subject: [PATCH 20/69] split dynamic and static data on-chain --- packages/store/abi/IStore.sol/IStore.abi.json | 97 +++++++++++-- .../store/abi/IStore.sol/IStoreData.abi.json | 67 ++++++++- .../abi/IStore.sol/IStoreEphemeral.abi.json | 12 +- .../store/abi/IStore.sol/IStoreHook.abi.json | 12 +- .../store/abi/IStore.sol/IStoreWrite.abi.json | 67 ++++++++- .../IStoreErrors.sol/IStoreErrors.abi.json | 18 ++- .../MirrorSubscriber.abi.json | 30 +++- .../abi/StoreCore.sol/StoreCore.abi.json | 69 ++++++++- .../abi/StoreMock.sol/StoreMock.abi.json | 97 +++++++++++-- .../abi/StoreRead.sol/StoreRead.abi.json | 18 ++- .../StoreReadWithStubs.abi.json | 93 +++++++++++- packages/store/src/IStore.sol | 44 ++++-- packages/store/src/IStoreErrors.sol | 3 +- packages/store/src/PackedCounter.sol | 2 - packages/store/src/StoreCore.sol | 135 +++++++++--------- packages/store/src/StoreReadWithStubs.sol | 19 ++- packages/store/src/StoreSwitch.sol | 27 +++- .../store/src/codegen/tables/Callbacks.sol | 10 +- packages/store/src/codegen/tables/Hooks.sol | 10 +- .../store/src/codegen/tables/KeyEncoding.sol | 4 +- packages/store/src/codegen/tables/Mixed.sol | 29 ++-- packages/store/src/codegen/tables/Tables.sol | 43 +++--- packages/store/src/codegen/tables/Vector2.sol | 18 ++- packages/store/test/MirrorSubscriber.sol | 12 +- packages/store/test/StoreMock.sol | 23 ++- packages/store/ts/codegen/record.ts | 29 +++- packages/store/ts/codegen/renderTable.ts | 59 +++++--- 27 files changed, 839 insertions(+), 208 deletions(-) diff --git a/packages/store/abi/IStore.sol/IStore.abi.json b/packages/store/abi/IStore.sol/IStore.abi.json index a7cd620598..eee1dcc5cc 100644 --- a/packages/store/abi/IStore.sol/IStore.abi.json +++ b/packages/store/abi/IStore.sol/IStore.abi.json @@ -28,7 +28,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -63,6 +63,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", @@ -167,7 +183,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -210,17 +238,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "dynamicDataLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -260,7 +319,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { @@ -617,7 +686,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/store/abi/IStore.sol/IStoreData.abi.json b/packages/store/abi/IStore.sol/IStoreData.abi.json index 7b08bc8fda..328b4263b5 100644 --- a/packages/store/abi/IStore.sol/IStoreData.abi.json +++ b/packages/store/abi/IStore.sol/IStoreData.abi.json @@ -36,7 +36,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -79,17 +91,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "dynamicDataLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -407,7 +450,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/store/abi/IStore.sol/IStoreEphemeral.abi.json b/packages/store/abi/IStore.sol/IStoreEphemeral.abi.json index c9cbd9770c..3aa07648a5 100644 --- a/packages/store/abi/IStore.sol/IStoreEphemeral.abi.json +++ b/packages/store/abi/IStore.sol/IStoreEphemeral.abi.json @@ -38,7 +38,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/store/abi/IStore.sol/IStoreHook.abi.json b/packages/store/abi/IStore.sol/IStoreHook.abi.json index 171784fcb2..3dfdec15d3 100644 --- a/packages/store/abi/IStore.sol/IStoreHook.abi.json +++ b/packages/store/abi/IStore.sol/IStoreHook.abi.json @@ -102,7 +102,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/store/abi/IStore.sol/IStoreWrite.abi.json b/packages/store/abi/IStore.sol/IStoreWrite.abi.json index 301a962b48..d79beb751f 100644 --- a/packages/store/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/store/abi/IStore.sol/IStoreWrite.abi.json @@ -36,7 +36,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -79,17 +91,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "dynamicDataLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -228,7 +271,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/store/abi/IStoreErrors.sol/IStoreErrors.abi.json b/packages/store/abi/IStoreErrors.sol/IStoreErrors.abi.json index cf6d375396..8488c23c54 100644 --- a/packages/store/abi/IStoreErrors.sol/IStoreErrors.abi.json +++ b/packages/store/abi/IStoreErrors.sol/IStoreErrors.abi.json @@ -28,7 +28,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -63,6 +63,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", diff --git a/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json b/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json index c71b2f21d8..d2e4c93669 100644 --- a/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json +++ b/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json @@ -91,7 +91,23 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", "type": "error" }, { @@ -197,7 +213,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/store/abi/StoreCore.sol/StoreCore.abi.json b/packages/store/abi/StoreCore.sol/StoreCore.abi.json index 52eca7ff43..b09ab948f7 100644 --- a/packages/store/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/store/abi/StoreCore.sol/StoreCore.abi.json @@ -36,7 +36,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -61,7 +73,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -101,20 +125,51 @@ "name": "data", "type": "bytes" }, + { + "indexed": false, + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" } ] \ No newline at end of file diff --git a/packages/store/abi/StoreMock.sol/StoreMock.abi.json b/packages/store/abi/StoreMock.sol/StoreMock.abi.json index 24bf93750e..72c09be09d 100644 --- a/packages/store/abi/StoreMock.sol/StoreMock.abi.json +++ b/packages/store/abi/StoreMock.sol/StoreMock.abi.json @@ -76,7 +76,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -111,6 +111,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", @@ -215,7 +231,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -258,17 +286,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "dynamicDataLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -308,7 +367,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { @@ -665,7 +734,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/store/abi/StoreRead.sol/StoreRead.abi.json b/packages/store/abi/StoreRead.sol/StoreRead.abi.json index 93a0e17cf5..bd97059695 100644 --- a/packages/store/abi/StoreRead.sol/StoreRead.abi.json +++ b/packages/store/abi/StoreRead.sol/StoreRead.abi.json @@ -54,7 +54,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -89,6 +89,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", diff --git a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json index 8f04de4e60..c3bc477d01 100644 --- a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json +++ b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json @@ -65,7 +65,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -100,6 +100,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", @@ -209,7 +225,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "PackedCounter", + "name": "dynamicDataLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -252,17 +280,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "dynamicDataLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -305,6 +364,16 @@ "name": "", "type": "bytes" }, + { + "internalType": "PackedCounter", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, { "internalType": "Schema", "name": "", @@ -662,6 +731,16 @@ "name": "", "type": "bytes" }, + { + "internalType": "PackedCounter", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, { "internalType": "Schema", "name": "", diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index 62dbff61fc..1f37f52c2f 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { IStoreErrors } from "./IStoreErrors.sol"; +import { PackedCounter } from "./PackedCounter.sol"; import { Schema } from "./Schema.sol"; interface IStoreRead { @@ -44,21 +45,34 @@ interface IStoreRead { } interface IStoreWrite { - event StoreSetRecord(bytes32 table, bytes32[] key, bytes data); - // TODO: finalize dynamic lengths args (these names/positions are placeholders while I figure out of this is enough data for schemaless indexing) - event StoreSpliceRecord( + event StoreSetRecord( + bytes32 table, + bytes32[] key, + bytes staticData, + PackedCounter dynamicDataLengths, + bytes dynamicData + ); + + event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); + event StoreSpliceDynamicRecord( bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data, - bytes32 newDynamicLengths, - uint256 dynamicLengthsStart + bytes32 dynamicDataLengths ); event StoreDeleteRecord(bytes32 table, bytes32[] key); // Set full record (including full dynamic data) - function setRecord(bytes32 table, bytes32[] calldata key, bytes calldata data, Schema valueSchema) external; + function setRecord( + bytes32 table, + bytes32[] calldata key, + bytes calldata staticData, + PackedCounter dynamicDataLengths, + bytes calldata dynamicData, + Schema valueSchema + ) external; // Set partial data at schema index function setField( @@ -105,7 +119,14 @@ interface IStoreEphemeral { event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data); // Emit the ephemeral event without modifying storage - function emitEphemeralRecord(bytes32 table, bytes32[] calldata key, bytes calldata data, Schema valueSchema) external; + function emitEphemeralRecord( + bytes32 table, + bytes32[] calldata key, + bytes calldata staticData, + PackedCounter dynamicDataLengths, + bytes calldata dynamicData, + Schema valueSchema + ) external; } /** @@ -138,7 +159,14 @@ interface IStoreRegistration { interface IStore is IStoreData, IStoreRegistration, IStoreEphemeral, IStoreErrors {} interface IStoreHook { - function onSetRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) external; + function onSetRecord( + bytes32 table, + bytes32[] memory key, + bytes calldata staticData, + PackedCounter dynamicDataLengths, + bytes calldata dynamicData, + Schema valueSchema + ) external; // Split onSetField into pre and post to simplify the implementation of hooks function onBeforeSetField( diff --git a/packages/store/src/IStoreErrors.sol b/packages/store/src/IStoreErrors.sol index 4b74b0e321..02cdd0ba9e 100644 --- a/packages/store/src/IStoreErrors.sol +++ b/packages/store/src/IStoreErrors.sol @@ -8,7 +8,8 @@ interface IStoreErrors { error StoreCore_NotImplemented(); error StoreCore_NotDynamicField(); - error StoreCore_InvalidDataLength(uint256 expected, uint256 received); + error StoreCore_InvalidStaticDataLength(uint256 expected, uint256 received); + error StoreCore_InvalidDynamicDataLength(uint256 expected, uint256 received); error StoreCore_InvalidKeyNamesLength(uint256 expected, uint256 received); error StoreCore_InvalidFieldNamesLength(uint256 expected, uint256 received); error StoreCore_DataIndexOverflow(uint256 length, uint256 received); diff --git a/packages/store/src/PackedCounter.sol b/packages/store/src/PackedCounter.sol index 3d4734074a..e8f53ec949 100644 --- a/packages/store/src/PackedCounter.sol +++ b/packages/store/src/PackedCounter.sol @@ -13,8 +13,6 @@ uint256 constant ACC_BITS = 7 * 8; uint256 constant VAL_BITS = 5 * 8; // Maximum value of a 5-byte section uint256 constant MAX_VAL = type(uint40).max; -// Used in splice events to indicate when a counter is unchanged (e.g. replacing the entire field) -bytes32 constant UNCHANGED_PACKED_COUNTER = bytes32(type(uint256).max); /** * Static functions for PackedCounter diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index 6e0ae95f3b..bb06b0d791 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -6,7 +6,7 @@ import { Bytes } from "./Bytes.sol"; import { Storage } from "./Storage.sol"; import { Memory } from "./Memory.sol"; import { Schema, SchemaLib } from "./Schema.sol"; -import { PackedCounter, UNCHANGED_PACKED_COUNTER } from "./PackedCounter.sol"; +import { PackedCounter } from "./PackedCounter.sol"; import { Slice, SliceLib } from "./Slice.sol"; import { Hooks, Tables, HooksTableId } from "./codegen/Tables.sol"; import { IStoreErrors } from "./IStoreErrors.sol"; @@ -15,19 +15,31 @@ import { StoreSwitch } from "./StoreSwitch.sol"; library StoreCore { // note: the preimage of the tuple of keys used to index is part of the event, so it can be used by indexers - event StoreSetRecord(bytes32 table, bytes32[] key, bytes data); + event StoreSetRecord( + bytes32 table, + bytes32[] key, + bytes staticData, + PackedCounter dynamicDataLengths, + bytes dynamicData + ); // TODO: finalize dynamic lengths args (these names/positions are placeholders while I figure out of this is enough data for schemaless indexing) - event StoreSpliceRecord( + event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); + event StoreSpliceDynamicRecord( bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data, - bytes32 newDynamicLengths, - uint256 dynamicLengthsStart + PackedCounter dynamicDataLengths ); event StoreDeleteRecord(bytes32 table, bytes32[] key); - event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data); + event StoreEphemeralRecord( + bytes32 table, + bytes32[] key, + bytes staticData, + PackedCounter dynamicDataLengths, + bytes dynamicData + ); /** * Initialize internal tables. @@ -141,47 +153,56 @@ library StoreCore { /** * Set full data record for the given tableId and key tuple and schema */ - function setRecord(bytes32 tableId, bytes32[] memory key, bytes memory data, Schema valueSchema) internal { + function setRecord( + bytes32 tableId, + bytes32[] memory key, + bytes memory staticData, + PackedCounter dynamicDataLengths, + bytes memory dynamicData, + Schema valueSchema + ) internal { // verify the value has the correct length for the tableId (based on the tableId's schema) // to prevent invalid data from being stored // Verify static data length + dynamic data length matches the given data - (uint256 staticLength, PackedCounter dynamicLength) = StoreCoreInternal._validateDataLength(valueSchema, data); + StoreCoreInternal._validateDataLength(valueSchema, staticData, dynamicDataLengths, dynamicData); // Emit event to notify indexers - emit StoreSetRecord(tableId, key, data); + emit StoreSetRecord(tableId, key, staticData, dynamicDataLengths, dynamicData); // Call onSetRecord hooks (before actually modifying the state, so observers have access to the previous state if needed) address[] memory hooks = Hooks.get(tableId); for (uint256 i; i < hooks.length; i++) { IStoreHook hook = IStoreHook(hooks[i]); - hook.onSetRecord(tableId, key, data, valueSchema); + hook.onSetRecord(tableId, key, staticData, dynamicDataLengths, dynamicData, valueSchema); } // Store the static data at the static data location uint256 staticDataLocation = StoreCoreInternal._getStaticDataLocation(tableId, key); - uint256 memoryPointer = Memory.dataPointer(data); + uint256 memoryPointer = Memory.dataPointer(staticData); Storage.store({ storagePointer: staticDataLocation, offset: 0, memoryPointer: memoryPointer, - length: staticLength + length: staticData.length }); - memoryPointer += staticLength + 32; // move the memory pointer to the start of the dynamic data (skip the encoded dynamic length) // If there is no dynamic data, we're done if (valueSchema.numDynamicFields() == 0) return; // Store the dynamic data length at the dynamic data length location uint256 dynamicDataLengthLocation = StoreCoreInternal._getDynamicDataLengthLocation(tableId, key); - Storage.store({ storagePointer: dynamicDataLengthLocation, data: dynamicLength.unwrap() }); + Storage.store({ storagePointer: dynamicDataLengthLocation, data: dynamicDataLengths.unwrap() }); + + // Move the memory pointer to the start of the dynamic data + memoryPointer = Memory.dataPointer(dynamicData); // For every dynamic element, slice off the dynamic data and store it at the dynamic location uint256 dynamicDataLocation; uint256 dynamicDataLength; for (uint8 i; i < valueSchema.numDynamicFields(); ) { dynamicDataLocation = StoreCoreInternal._getDynamicDataLocation(tableId, key, i); - dynamicDataLength = dynamicLength.atIndex(i); + dynamicDataLength = dynamicDataLengths.atIndex(i); Storage.store({ storagePointer: dynamicDataLocation, offset: 0, @@ -381,18 +402,25 @@ library StoreCore { /** * Emit the ephemeral event without modifying storage for the full data of the given tableId and key tuple */ - function emitEphemeralRecord(bytes32 tableId, bytes32[] memory key, bytes memory data, Schema valueSchema) internal { + function emitEphemeralRecord( + bytes32 tableId, + bytes32[] memory key, + bytes memory staticData, + PackedCounter dynamicDataLengths, + bytes memory dynamicData, + Schema valueSchema + ) internal { // Verify static data length + dynamic data length matches the given data - StoreCoreInternal._validateDataLength(valueSchema, data); + StoreCoreInternal._validateDataLength(valueSchema, staticData, dynamicDataLengths, dynamicData); // Emit event to notify indexers - emit StoreEphemeralRecord(tableId, key, data); + emit StoreEphemeralRecord(tableId, key, staticData, dynamicDataLengths, dynamicData); // Call onSetRecord hooks address[] memory hooks = Hooks.get(tableId); for (uint256 i; i < hooks.length; i++) { IStoreHook hook = IStoreHook(hooks[i]); - hook.onSetRecord(tableId, key, data, valueSchema); + hook.onSetRecord(tableId, key, staticData, dynamicDataLengths, dynamicData, valueSchema); } } @@ -538,17 +566,8 @@ library StoreCoreInternal { // Prepare data for the splice event uint256 start = offset; uint256 deleteCount = valueSchema.atIndex(schemaIndex).getStaticByteLength(); - uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord( - tableId, - key, - uint48(start), - uint40(deleteCount), - data, - UNCHANGED_PACKED_COUNTER, - encodedLengthsStart - ); + emit StoreCore.StoreSpliceStaticRecord(tableId, key, uint48(start), uint40(deleteCount), data); } function _setDynamicField( @@ -578,23 +597,13 @@ library StoreCoreInternal { uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) - start = valueSchema.staticDataLength() + 32; for (uint8 i; i < dynamicSchemaIndex; i++) { start += encodedLengths.atIndex(i); } } uint256 deleteCount = oldFieldLength; - uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord( - tableId, - key, - uint48(start), - uint40(deleteCount), - data, - encodedLengths.unwrap(), - encodedLengthsStart - ); + emit StoreCore.StoreSpliceDynamicRecord(tableId, key, uint48(start), uint40(deleteCount), data, encodedLengths); } function _pushToDynamicField( @@ -623,22 +632,19 @@ library StoreCoreInternal { uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) - start = valueSchema.staticDataLength() + 32 + oldFieldLength; for (uint8 i; i < dynamicSchemaIndex; i++) { start += encodedLengths.atIndex(i); } } uint256 deleteCount = 0; - uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord( + emit StoreCore.StoreSpliceDynamicRecord( tableId, key, uint48(start), uint40(deleteCount), dataToPush, - encodedLengths.unwrap(), - encodedLengthsStart + encodedLengths ); } @@ -667,22 +673,21 @@ library StoreCoreInternal { uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) - start = valueSchema.staticDataLength() + 32 + oldFieldLength - byteLengthToPop; + start = oldFieldLength; for (uint8 i; i < dynamicSchemaIndex; i++) { start += encodedLengths.atIndex(i); } + start -= byteLengthToPop; } uint256 deleteCount = byteLengthToPop; - uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord( + emit StoreCore.StoreSpliceDynamicRecord( tableId, key, uint48(start), uint40(deleteCount), new bytes(0), - encodedLengths.unwrap(), - encodedLengthsStart + encodedLengths ); } @@ -708,22 +713,20 @@ library StoreCoreInternal { uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) - start = valueSchema.staticDataLength() + 32 + startByteIndex; + start = startByteIndex; for (uint8 i; i < dynamicSchemaIndex; i++) { start += encodedLengths.atIndex(i); } } uint256 deleteCount = dataToSet.length; - uint256 encodedLengthsStart = valueSchema.staticDataLength(); // Emit event to notify indexers - emit StoreCore.StoreSpliceRecord( + emit StoreCore.StoreSpliceDynamicRecord( tableId, key, uint48(start), uint40(deleteCount), dataToSet, - encodedLengths.unwrap(), - encodedLengthsStart + encodedLengths ); } @@ -793,19 +796,15 @@ library StoreCoreInternal { */ function _validateDataLength( Schema valueSchema, - bytes memory data - ) internal pure returns (uint256 staticLength, PackedCounter dynamicLength) { - staticLength = valueSchema.staticDataLength(); - uint256 expectedLength = staticLength; - dynamicLength; - if (valueSchema.numDynamicFields() > 0) { - // Dynamic length is encoded at the start of the dynamic length blob - dynamicLength = PackedCounter.wrap(Bytes.slice32(data, staticLength)); - expectedLength += 32 + dynamicLength.total(); // encoded length + data - } - - if (expectedLength != data.length) { - revert IStoreErrors.StoreCore_InvalidDataLength(expectedLength, data.length); + bytes memory staticData, + PackedCounter dynamicDataLengths, + bytes memory dynamicData + ) internal pure { + if (valueSchema.staticDataLength() != staticData.length) { + revert IStoreErrors.StoreCore_InvalidStaticDataLength(valueSchema.staticDataLength(), staticData.length); + } + if (dynamicDataLengths.total() != dynamicData.length) { + revert IStoreErrors.StoreCore_InvalidDynamicDataLength(dynamicDataLengths.total(), dynamicData.length); } } diff --git a/packages/store/src/StoreReadWithStubs.sol b/packages/store/src/StoreReadWithStubs.sol index ee655284f2..e26bbc2f6b 100644 --- a/packages/store/src/StoreReadWithStubs.sol +++ b/packages/store/src/StoreReadWithStubs.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { IStore, IStoreHook } from "./IStore.sol"; +import { PackedCounter } from "./PackedCounter.sol"; import { StoreCore } from "./StoreCore.sol"; import { Schema } from "./Schema.sol"; import { StoreRead } from "./StoreRead.sol"; @@ -24,7 +25,14 @@ contract StoreReadWithStubs is IStore, StoreRead { /** * Not implemented in StoreReadWithStubs */ - function setRecord(bytes32, bytes32[] calldata, bytes calldata, Schema) public virtual { + function setRecord( + bytes32, + bytes32[] calldata, + bytes calldata, + PackedCounter, + bytes calldata, + Schema + ) public virtual { revert StoreReadWithStubs_NotImplemented(); } @@ -73,7 +81,14 @@ contract StoreReadWithStubs is IStore, StoreRead { /** * Not implemented in StoreReadWithStubs */ - function emitEphemeralRecord(bytes32, bytes32[] calldata, bytes calldata, Schema) public virtual { + function emitEphemeralRecord( + bytes32, + bytes32[] calldata, + bytes calldata, + PackedCounter, + bytes calldata, + Schema + ) public virtual { revert StoreReadWithStubs_NotImplemented(); } } diff --git a/packages/store/src/StoreSwitch.sol b/packages/store/src/StoreSwitch.sol index 9350a80635..857d89e65e 100644 --- a/packages/store/src/StoreSwitch.sol +++ b/packages/store/src/StoreSwitch.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { IStore, IStoreHook } from "./IStore.sol"; +import { PackedCounter } from "../src/PackedCounter.sol"; import { StoreCore } from "./StoreCore.sol"; import { Schema } from "./Schema.sol"; @@ -86,12 +87,19 @@ library StoreSwitch { } } - function setRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) internal { + function setRecord( + bytes32 table, + bytes32[] memory key, + bytes memory staticData, + PackedCounter dynamicDataLengths, + bytes memory dynamicData, + Schema valueSchema + ) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { - StoreCore.setRecord(table, key, data, valueSchema); + StoreCore.setRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); } else { - IStore(_storeAddress).setRecord(table, key, data, valueSchema); + IStore(_storeAddress).setRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); } } @@ -165,12 +173,19 @@ library StoreSwitch { } } - function emitEphemeralRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) internal { + function emitEphemeralRecord( + bytes32 table, + bytes32[] memory key, + bytes memory staticData, + PackedCounter dynamicDataLengths, + bytes memory dynamicData, + Schema valueSchema + ) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { - StoreCore.emitEphemeralRecord(table, key, data, valueSchema); + StoreCore.emitEphemeralRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); } else { - IStore(_storeAddress).emitEphemeralRecord(table, key, data, valueSchema); + IStore(_storeAddress).emitEphemeralRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); } } diff --git a/packages/store/src/codegen/tables/Callbacks.sol b/packages/store/src/codegen/tables/Callbacks.sol index 812cab754c..7d4fc61c52 100644 --- a/packages/store/src/codegen/tables/Callbacks.sol +++ b/packages/store/src/codegen/tables/Callbacks.sol @@ -215,15 +215,17 @@ library Callbacks { } } - /** Tightly pack full data using this table's schema */ - function encode(bytes24[] memory value) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths(bytes24[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(value.length * 24); } + } - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(bytes24[] memory value) internal pure returns (bytes memory) { + return abi.encodePacked(EncodeArray.encode((value))); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/store/src/codegen/tables/Hooks.sol b/packages/store/src/codegen/tables/Hooks.sol index ba3545cdbc..0e70bddd37 100644 --- a/packages/store/src/codegen/tables/Hooks.sol +++ b/packages/store/src/codegen/tables/Hooks.sol @@ -215,15 +215,17 @@ library Hooks { } } - /** Tightly pack full data using this table's schema */ - function encode(address[] memory value) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths(address[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(value.length * 20); } + } - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(address[] memory value) internal pure returns (bytes memory) { + return abi.encodePacked(EncodeArray.encode((value))); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/store/src/codegen/tables/KeyEncoding.sol b/packages/store/src/codegen/tables/KeyEncoding.sol index a0fb759651..2d68f6510a 100644 --- a/packages/store/src/codegen/tables/KeyEncoding.sol +++ b/packages/store/src/codegen/tables/KeyEncoding.sol @@ -150,8 +150,8 @@ library KeyEncoding { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), getValueSchema()); } - /** Tightly pack full data using this table's schema */ - function encode(bool value) internal pure returns (bytes memory) { + /** Tightly pack static data using this table's schema */ + function encodeStatic(bool value) internal pure returns (bytes memory) { return abi.encodePacked(value); } diff --git a/packages/store/src/codegen/tables/Mixed.sol b/packages/store/src/codegen/tables/Mixed.sol index 2f80eb45e2..94923c0a54 100644 --- a/packages/store/src/codegen/tables/Mixed.sol +++ b/packages/store/src/codegen/tables/Mixed.sol @@ -458,22 +458,28 @@ library Mixed { /** Set the full data using individual values */ function set(bytes32 key, uint32 u32, uint128 u128, uint32[] memory a32, string memory s) internal { - bytes memory _data = encode(u32, u128, a32, s); + bytes memory _staticData = encodeStatic(u32, u128); + + PackedCounter _encodedLengths = encodeLengths(a32, s); + bytes memory _dynamicData = encodeDynamic(a32, s); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, bytes32 key, uint32 u32, uint128 u128, uint32[] memory a32, string memory s) internal { - bytes memory _data = encode(u32, u128, a32, s); + bytes memory _staticData = encodeStatic(u32, u128); + + PackedCounter _encodedLengths = encodeLengths(a32, s); + bytes memory _dynamicData = encodeDynamic(a32, s); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -516,15 +522,22 @@ library Mixed { } } - /** Tightly pack full data using this table's schema */ - function encode(uint32 u32, uint128 u128, uint32[] memory a32, string memory s) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint32 u32, uint128 u128) internal pure returns (bytes memory) { + return abi.encodePacked(u32, u128); + } + + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths(uint32[] memory a32, string memory s) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(a32.length * 4, bytes(s).length); } + } - return abi.encodePacked(u32, u128, _encodedLengths.unwrap(), EncodeArray.encode((a32)), bytes((s))); + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(uint32[] memory a32, string memory s) internal pure returns (bytes memory) { + return abi.encodePacked(EncodeArray.encode((a32)), bytes((s))); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/store/src/codegen/tables/Tables.sol b/packages/store/src/codegen/tables/Tables.sol index b032e66434..c745d463cf 100644 --- a/packages/store/src/codegen/tables/Tables.sol +++ b/packages/store/src/codegen/tables/Tables.sol @@ -478,12 +478,15 @@ library Tables { bytes memory abiEncodedKeyNames, bytes memory abiEncodedFieldNames ) internal { - bytes memory _data = encode(keySchema, valueSchema, abiEncodedKeyNames, abiEncodedFieldNames); + bytes memory _staticData = encodeStatic(keySchema, valueSchema); + + PackedCounter _encodedLengths = encodeLengths(abiEncodedKeyNames, abiEncodedFieldNames); + bytes memory _dynamicData = encodeDynamic(abiEncodedKeyNames, abiEncodedFieldNames); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = tableId; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ @@ -495,12 +498,15 @@ library Tables { bytes memory abiEncodedKeyNames, bytes memory abiEncodedFieldNames ) internal { - bytes memory _data = encode(keySchema, valueSchema, abiEncodedKeyNames, abiEncodedFieldNames); + bytes memory _staticData = encodeStatic(keySchema, valueSchema); + + PackedCounter _encodedLengths = encodeLengths(abiEncodedKeyNames, abiEncodedFieldNames); + bytes memory _dynamicData = encodeDynamic(abiEncodedKeyNames, abiEncodedFieldNames); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = tableId; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -543,27 +549,28 @@ library Tables { } } - /** Tightly pack full data using this table's schema */ - function encode( - bytes32 keySchema, - bytes32 valueSchema, + /** Tightly pack static data using this table's schema */ + function encodeStatic(bytes32 keySchema, bytes32 valueSchema) internal pure returns (bytes memory) { + return abi.encodePacked(keySchema, valueSchema); + } + + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths( bytes memory abiEncodedKeyNames, bytes memory abiEncodedFieldNames - ) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + ) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(bytes(abiEncodedKeyNames).length, bytes(abiEncodedFieldNames).length); } + } - return - abi.encodePacked( - keySchema, - valueSchema, - _encodedLengths.unwrap(), - bytes((abiEncodedKeyNames)), - bytes((abiEncodedFieldNames)) - ); + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic( + bytes memory abiEncodedKeyNames, + bytes memory abiEncodedFieldNames + ) internal pure returns (bytes memory) { + return abi.encodePacked(bytes((abiEncodedKeyNames)), bytes((abiEncodedFieldNames))); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/store/src/codegen/tables/Vector2.sol b/packages/store/src/codegen/tables/Vector2.sol index e46e40fe0c..192128635b 100644 --- a/packages/store/src/codegen/tables/Vector2.sol +++ b/packages/store/src/codegen/tables/Vector2.sol @@ -154,22 +154,28 @@ library Vector2 { /** Set the full data using individual values */ function set(bytes32 key, uint32 x, uint32 y) internal { - bytes memory _data = encode(x, y); + bytes memory _staticData = encodeStatic(x, y); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, bytes32 key, uint32 x, uint32 y) internal { - bytes memory _data = encode(x, y); + bytes memory _staticData = encodeStatic(x, y); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -189,8 +195,8 @@ library Vector2 { _table.y = (uint32(Bytes.slice4(_blob, 4))); } - /** Tightly pack full data using this table's schema */ - function encode(uint32 x, uint32 y) internal pure returns (bytes memory) { + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint32 x, uint32 y) internal pure returns (bytes memory) { return abi.encodePacked(x, y); } diff --git a/packages/store/test/MirrorSubscriber.sol b/packages/store/test/MirrorSubscriber.sol index 9276111340..7c032c955a 100644 --- a/packages/store/test/MirrorSubscriber.sol +++ b/packages/store/test/MirrorSubscriber.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { IStore, IStoreHook } from "../src/IStore.sol"; +import { PackedCounter } from "../src/PackedCounter.sol"; import { StoreSwitch } from "../src/StoreSwitch.sol"; import { Schema } from "../src/Schema.sol"; @@ -21,9 +22,16 @@ contract MirrorSubscriber is IStoreHook { _table = table; } - function onSetRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) public { + function onSetRecord( + bytes32 table, + bytes32[] memory key, + bytes calldata staticData, + PackedCounter dynamicDataLengths, + bytes calldata dynamicData, + Schema valueSchema + ) public { if (table != table) revert("invalid table"); - StoreSwitch.setRecord(indexerTableId, key, data, valueSchema); + StoreSwitch.setRecord(indexerTableId, key, staticData, dynamicDataLengths, dynamicData, valueSchema); } function onBeforeSetField( diff --git a/packages/store/test/StoreMock.sol b/packages/store/test/StoreMock.sol index d58e7299c9..3cb5302b38 100644 --- a/packages/store/test/StoreMock.sol +++ b/packages/store/test/StoreMock.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { IStore, IStoreHook } from "../src/IStore.sol"; +import { PackedCounter } from "../src/PackedCounter.sol"; import { StoreCore } from "../src/StoreCore.sol"; import { Schema } from "../src/Schema.sol"; import { StoreRead } from "../src/StoreRead.sol"; @@ -11,8 +12,15 @@ import { StoreRead } from "../src/StoreRead.sol"; */ contract StoreMock is IStore, StoreRead { // Set full record (including full dynamic data) - function setRecord(bytes32 table, bytes32[] calldata key, bytes calldata data, Schema valueSchema) public { - StoreCore.setRecord(table, key, data, valueSchema); + function setRecord( + bytes32 table, + bytes32[] calldata key, + bytes calldata staticData, + PackedCounter dynamicDataLengths, + bytes calldata dynamicData, + Schema valueSchema + ) public { + StoreCore.setRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); } // Set partial data at schema index @@ -66,8 +74,15 @@ contract StoreMock is IStore, StoreRead { } // Emit the ephemeral event without modifying storage - function emitEphemeralRecord(bytes32 table, bytes32[] calldata key, bytes calldata data, Schema valueSchema) public { - StoreCore.emitEphemeralRecord(table, key, data, valueSchema); + function emitEphemeralRecord( + bytes32 table, + bytes32[] calldata key, + bytes calldata staticData, + PackedCounter dynamicDataLengths, + bytes calldata dynamicData, + Schema valueSchema + ) public { + StoreCore.emitEphemeralRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); } function registerTable( diff --git a/packages/store/ts/codegen/record.ts b/packages/store/ts/codegen/record.ts index d2182eb8f3..82a86f5fc3 100644 --- a/packages/store/ts/codegen/record.ts +++ b/packages/store/ts/codegen/record.ts @@ -38,11 +38,11 @@ export function renderRecordMethods(options: RenderTableOptions) { _typedKeyArgs, renderArguments(options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)), ])}) internal { - bytes memory _data = encode(${renderArguments(options.fields.map(({ name }) => name))}); + ${renderRecordData(options)} ${_keyTupleDefinition} - ${_store}.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + ${_store}.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } ` ); @@ -180,3 +180,28 @@ function renderDecodeDynamicFieldPartial(field: RenderDynamicField) { )`; } } + +function renderRecordData(options: RenderTableOptions) { + let result = ""; + if (options.staticFields.length > 0) { + result += ` + bytes memory _staticData = encodeStatic(${renderArguments(options.staticFields.map(({ name }) => name))}); + `; + } else { + result += `bytes memory _staticData;`; + } + + if (options.dynamicFields.length > 0) { + result += ` + PackedCounter _encodedLengths = encodeLengths(${renderArguments(options.dynamicFields.map(({ name }) => name))}); + bytes memory _dynamicData = encodeDynamic(${renderArguments(options.dynamicFields.map(({ name }) => name))}); + `; + } else { + result += ` + PackedCounter _encodedLengths; + bytes memory _dynamicData; + `; + } + + return result; +} diff --git a/packages/store/ts/codegen/renderTable.ts b/packages/store/ts/codegen/renderTable.ts index a4df23466a..31d91fa2fc 100644 --- a/packages/store/ts/codegen/renderTable.ts +++ b/packages/store/ts/codegen/renderTable.ts @@ -5,10 +5,10 @@ import { renderedSolidityHeader, renderRelativeImports, renderTableId, - renderValueTypeToBytes32, renderWithStore, renderTypeHelpers, RenderDynamicField, + RenderStaticField, } from "@latticexyz/common/codegen"; import { renderEphemeralMethods } from "./ephemeral"; import { renderEncodeFieldSingle, renderFieldMethods } from "./field"; @@ -117,18 +117,11 @@ library ${libraryName} { ${withEphemeralMethods ? renderEphemeralMethods(options) : ""} - /** Tightly pack full data using this table's schema */ - function encode(${renderArguments( - options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`) - )}) internal pure returns (bytes memory) { - ${renderEncodedLengths(dynamicFields)} - return abi.encodePacked(${renderArguments([ - renderArguments(staticFields.map(({ name }) => name)), - ...(dynamicFields.length === 0 - ? [] - : ["_encodedLengths.unwrap()", renderArguments(dynamicFields.map((field) => renderEncodeFieldSingle(field)))]), - ])}); - } + ${renderEncodeStatic(staticFields)} + + ${renderEncodedLengths(dynamicFields)} + + ${renderEncodeDynamic(dynamicFields)} /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(${renderArguments([_typedKeyArgs])}) internal pure returns (bytes32[] memory) { @@ -157,10 +150,27 @@ ${renderTypeHelpers(options)} `; } +function renderEncodeStatic(staticFields: RenderStaticField[]) { + if (staticFields.length === 0) return ""; + + return ` + /** Tightly pack static data using this table's schema */ + function encodeStatic(${renderArguments( + staticFields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`) + )}) internal pure returns (bytes memory) { + return abi.encodePacked(${renderArguments(staticFields.map(({ name }) => name))}); + } + `; +} + function renderEncodedLengths(dynamicFields: RenderDynamicField[]) { - if (dynamicFields.length > 0) { - return ` - PackedCounter _encodedLengths; + if (dynamicFields.length === 0) return ""; + + return ` + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths(${renderArguments( + dynamicFields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`) + )}) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack( @@ -175,8 +185,19 @@ function renderEncodedLengths(dynamicFields: RenderDynamicField[]) { )} ); } - `; - } else { - return ""; } + `; +} + +function renderEncodeDynamic(dynamicFields: RenderDynamicField[]) { + if (dynamicFields.length === 0) return ""; + + return ` + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(${renderArguments( + dynamicFields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`) + )}) internal pure returns (bytes memory) { + return abi.encodePacked(${renderArguments(dynamicFields.map((field) => renderEncodeFieldSingle(field)))}); + } + `; } From 652a724a398a1bc0ea115e5e9e3c67873a073c3d Mon Sep 17 00:00:00 2001 From: dk1a Date: Thu, 7 Sep 2023 14:18:20 +0300 Subject: [PATCH 21/69] refactor dynamicDataLengths to encodedLengths --- packages/store/src/IStore.sol | 16 ++++------ packages/store/src/StoreCore.sol | 38 ++++++++++-------------- packages/store/src/StoreSwitch.sol | 12 ++++---- packages/store/test/MirrorSubscriber.sol | 4 +-- packages/store/test/StoreMock.sol | 8 ++--- 5 files changed, 33 insertions(+), 45 deletions(-) diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index 1f37f52c2f..0fbf4fd454 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -45,13 +45,7 @@ interface IStoreRead { } interface IStoreWrite { - event StoreSetRecord( - bytes32 table, - bytes32[] key, - bytes staticData, - PackedCounter dynamicDataLengths, - bytes dynamicData - ); + event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, PackedCounter encodedLengths, bytes dynamicData); event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); event StoreSpliceDynamicRecord( @@ -60,7 +54,7 @@ interface IStoreWrite { uint48 start, uint40 deleteCount, bytes data, - bytes32 dynamicDataLengths + bytes32 encodedLengths ); event StoreDeleteRecord(bytes32 table, bytes32[] key); @@ -69,7 +63,7 @@ interface IStoreWrite { bytes32 table, bytes32[] calldata key, bytes calldata staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes calldata dynamicData, Schema valueSchema ) external; @@ -123,7 +117,7 @@ interface IStoreEphemeral { bytes32 table, bytes32[] calldata key, bytes calldata staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes calldata dynamicData, Schema valueSchema ) external; @@ -163,7 +157,7 @@ interface IStoreHook { bytes32 table, bytes32[] memory key, bytes calldata staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes calldata dynamicData, Schema valueSchema ) external; diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index bb06b0d791..790f32a619 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -15,13 +15,7 @@ import { StoreSwitch } from "./StoreSwitch.sol"; library StoreCore { // note: the preimage of the tuple of keys used to index is part of the event, so it can be used by indexers - event StoreSetRecord( - bytes32 table, - bytes32[] key, - bytes staticData, - PackedCounter dynamicDataLengths, - bytes dynamicData - ); + event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, PackedCounter encodedLengths, bytes dynamicData); // TODO: finalize dynamic lengths args (these names/positions are placeholders while I figure out of this is enough data for schemaless indexing) event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); event StoreSpliceDynamicRecord( @@ -30,14 +24,14 @@ library StoreCore { uint48 start, uint40 deleteCount, bytes data, - PackedCounter dynamicDataLengths + PackedCounter encodedLengths ); event StoreDeleteRecord(bytes32 table, bytes32[] key); event StoreEphemeralRecord( bytes32 table, bytes32[] key, bytes staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes dynamicData ); @@ -157,7 +151,7 @@ library StoreCore { bytes32 tableId, bytes32[] memory key, bytes memory staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes memory dynamicData, Schema valueSchema ) internal { @@ -165,16 +159,16 @@ library StoreCore { // to prevent invalid data from being stored // Verify static data length + dynamic data length matches the given data - StoreCoreInternal._validateDataLength(valueSchema, staticData, dynamicDataLengths, dynamicData); + StoreCoreInternal._validateDataLength(valueSchema, staticData, encodedLengths, dynamicData); // Emit event to notify indexers - emit StoreSetRecord(tableId, key, staticData, dynamicDataLengths, dynamicData); + emit StoreSetRecord(tableId, key, staticData, encodedLengths, dynamicData); // Call onSetRecord hooks (before actually modifying the state, so observers have access to the previous state if needed) address[] memory hooks = Hooks.get(tableId); for (uint256 i; i < hooks.length; i++) { IStoreHook hook = IStoreHook(hooks[i]); - hook.onSetRecord(tableId, key, staticData, dynamicDataLengths, dynamicData, valueSchema); + hook.onSetRecord(tableId, key, staticData, encodedLengths, dynamicData, valueSchema); } // Store the static data at the static data location @@ -192,7 +186,7 @@ library StoreCore { // Store the dynamic data length at the dynamic data length location uint256 dynamicDataLengthLocation = StoreCoreInternal._getDynamicDataLengthLocation(tableId, key); - Storage.store({ storagePointer: dynamicDataLengthLocation, data: dynamicDataLengths.unwrap() }); + Storage.store({ storagePointer: dynamicDataLengthLocation, data: encodedLengths.unwrap() }); // Move the memory pointer to the start of the dynamic data memoryPointer = Memory.dataPointer(dynamicData); @@ -202,7 +196,7 @@ library StoreCore { uint256 dynamicDataLength; for (uint8 i; i < valueSchema.numDynamicFields(); ) { dynamicDataLocation = StoreCoreInternal._getDynamicDataLocation(tableId, key, i); - dynamicDataLength = dynamicDataLengths.atIndex(i); + dynamicDataLength = encodedLengths.atIndex(i); Storage.store({ storagePointer: dynamicDataLocation, offset: 0, @@ -406,21 +400,21 @@ library StoreCore { bytes32 tableId, bytes32[] memory key, bytes memory staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes memory dynamicData, Schema valueSchema ) internal { // Verify static data length + dynamic data length matches the given data - StoreCoreInternal._validateDataLength(valueSchema, staticData, dynamicDataLengths, dynamicData); + StoreCoreInternal._validateDataLength(valueSchema, staticData, encodedLengths, dynamicData); // Emit event to notify indexers - emit StoreEphemeralRecord(tableId, key, staticData, dynamicDataLengths, dynamicData); + emit StoreEphemeralRecord(tableId, key, staticData, encodedLengths, dynamicData); // Call onSetRecord hooks address[] memory hooks = Hooks.get(tableId); for (uint256 i; i < hooks.length; i++) { IStoreHook hook = IStoreHook(hooks[i]); - hook.onSetRecord(tableId, key, staticData, dynamicDataLengths, dynamicData, valueSchema); + hook.onSetRecord(tableId, key, staticData, encodedLengths, dynamicData, valueSchema); } } @@ -797,14 +791,14 @@ library StoreCoreInternal { function _validateDataLength( Schema valueSchema, bytes memory staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes memory dynamicData ) internal pure { if (valueSchema.staticDataLength() != staticData.length) { revert IStoreErrors.StoreCore_InvalidStaticDataLength(valueSchema.staticDataLength(), staticData.length); } - if (dynamicDataLengths.total() != dynamicData.length) { - revert IStoreErrors.StoreCore_InvalidDynamicDataLength(dynamicDataLengths.total(), dynamicData.length); + if (encodedLengths.total() != dynamicData.length) { + revert IStoreErrors.StoreCore_InvalidDynamicDataLength(encodedLengths.total(), dynamicData.length); } } diff --git a/packages/store/src/StoreSwitch.sol b/packages/store/src/StoreSwitch.sol index 857d89e65e..caa8e18ae3 100644 --- a/packages/store/src/StoreSwitch.sol +++ b/packages/store/src/StoreSwitch.sol @@ -91,15 +91,15 @@ library StoreSwitch { bytes32 table, bytes32[] memory key, bytes memory staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes memory dynamicData, Schema valueSchema ) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { - StoreCore.setRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); + StoreCore.setRecord(table, key, staticData, encodedLengths, dynamicData, valueSchema); } else { - IStore(_storeAddress).setRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); + IStore(_storeAddress).setRecord(table, key, staticData, encodedLengths, dynamicData, valueSchema); } } @@ -177,15 +177,15 @@ library StoreSwitch { bytes32 table, bytes32[] memory key, bytes memory staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes memory dynamicData, Schema valueSchema ) internal { address _storeAddress = getStoreAddress(); if (_storeAddress == address(this)) { - StoreCore.emitEphemeralRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); + StoreCore.emitEphemeralRecord(table, key, staticData, encodedLengths, dynamicData, valueSchema); } else { - IStore(_storeAddress).emitEphemeralRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); + IStore(_storeAddress).emitEphemeralRecord(table, key, staticData, encodedLengths, dynamicData, valueSchema); } } diff --git a/packages/store/test/MirrorSubscriber.sol b/packages/store/test/MirrorSubscriber.sol index 7c032c955a..690cac909f 100644 --- a/packages/store/test/MirrorSubscriber.sol +++ b/packages/store/test/MirrorSubscriber.sol @@ -26,12 +26,12 @@ contract MirrorSubscriber is IStoreHook { bytes32 table, bytes32[] memory key, bytes calldata staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes calldata dynamicData, Schema valueSchema ) public { if (table != table) revert("invalid table"); - StoreSwitch.setRecord(indexerTableId, key, staticData, dynamicDataLengths, dynamicData, valueSchema); + StoreSwitch.setRecord(indexerTableId, key, staticData, encodedLengths, dynamicData, valueSchema); } function onBeforeSetField( diff --git a/packages/store/test/StoreMock.sol b/packages/store/test/StoreMock.sol index 3cb5302b38..172910f7f4 100644 --- a/packages/store/test/StoreMock.sol +++ b/packages/store/test/StoreMock.sol @@ -16,11 +16,11 @@ contract StoreMock is IStore, StoreRead { bytes32 table, bytes32[] calldata key, bytes calldata staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes calldata dynamicData, Schema valueSchema ) public { - StoreCore.setRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); + StoreCore.setRecord(table, key, staticData, encodedLengths, dynamicData, valueSchema); } // Set partial data at schema index @@ -78,11 +78,11 @@ contract StoreMock is IStore, StoreRead { bytes32 table, bytes32[] calldata key, bytes calldata staticData, - PackedCounter dynamicDataLengths, + PackedCounter encodedLengths, bytes calldata dynamicData, Schema valueSchema ) public { - StoreCore.emitEphemeralRecord(table, key, staticData, dynamicDataLengths, dynamicData, valueSchema); + StoreCore.emitEphemeralRecord(table, key, staticData, encodedLengths, dynamicData, valueSchema); } function registerTable( From 529e472985c4d4cac43b1e3a319b62c96c72bb24 Mon Sep 17 00:00:00 2001 From: dk1a Date: Thu, 7 Sep 2023 15:14:10 +0300 Subject: [PATCH 22/69] update events --- packages/store/src/IStore.sol | 10 ++++++++-- packages/store/ts/storeEvents.ts | 7 ++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index 0fbf4fd454..e9951aae1b 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -54,7 +54,7 @@ interface IStoreWrite { uint48 start, uint40 deleteCount, bytes data, - bytes32 encodedLengths + PackedCounter encodedLengths ); event StoreDeleteRecord(bytes32 table, bytes32[] key); @@ -110,7 +110,13 @@ interface IStoreWrite { } interface IStoreEphemeral { - event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data); + event StoreEphemeralRecord( + bytes32 table, + bytes32[] key, + bytes staticData, + PackedCounter encodedLengths, + bytes dynamicData + ); // Emit the ephemeral event without modifying storage function emitEphemeralRecord( diff --git a/packages/store/ts/storeEvents.ts b/packages/store/ts/storeEvents.ts index 068c81a47a..9f8e52a97b 100644 --- a/packages/store/ts/storeEvents.ts +++ b/packages/store/ts/storeEvents.ts @@ -1,7 +1,8 @@ export const storeEvents = [ - "event StoreSetRecord(bytes32 table, bytes32[] key, bytes data)", + "event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, PackedCounter encodedLengths, bytes dynamicData)", // TODO: finalize dynamic lengths args (these names/positions are placeholders while I figure out of this is enough data for schemaless indexing) - "event StoreSpliceRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data, bytes32 newDynamicLengths, uint256 dynamicLengthsStart)", - "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes data)", + "event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", + "event StoreSpliceDynamicRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data, PackedCounter newDynamicLengths, uint256 encodedLengths)", + "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes staticData, PackedCounter encodedLengths, bytes dynamicData)", "event StoreDeleteRecord(bytes32 table, bytes32[] key)", ] as const; From 32ac8d6419d13d18a26e55aad1f418435a7a09e4 Mon Sep 17 00:00:00 2001 From: dk1a Date: Fri, 8 Sep 2023 11:32:30 +0300 Subject: [PATCH 23/69] refactor store tests, fix push --- packages/store/abi/IStore.sol/IStore.abi.json | 24 +++- .../store/abi/IStore.sol/IStoreData.abi.json | 8 +- .../abi/IStore.sol/IStoreEphemeral.abi.json | 16 ++- .../store/abi/IStore.sol/IStoreHook.abi.json | 2 +- .../store/abi/IStore.sol/IStoreWrite.abi.json | 8 +- .../MirrorSubscriber.abi.json | 2 +- .../abi/StoreCore.sol/StoreCore.abi.json | 12 +- .../abi/StoreMock.sol/StoreMock.abi.json | 24 +++- .../StoreReadWithStubs.abi.json | 20 ++- packages/store/src/IStore.sol | 12 +- packages/store/src/StoreCore.sol | 34 ++--- .../store/src/codegen/tables/Callbacks.sol | 9 ++ packages/store/src/codegen/tables/Hooks.sol | 9 ++ .../store/src/codegen/tables/KeyEncoding.sol | 10 ++ packages/store/src/codegen/tables/Mixed.sol | 10 ++ packages/store/src/codegen/tables/Tables.sol | 15 +++ packages/store/src/codegen/tables/Vector2.sol | 10 ++ packages/store/test/StoreCore.t.sol | 117 +++++++++--------- packages/store/test/StoreCoreDynamic.t.sol | 15 ++- packages/store/test/StoreCoreGas.t.sol | 49 ++++---- packages/store/ts/codegen/record.ts | 50 ++++---- packages/store/ts/codegen/renderTable.ts | 11 +- packages/store/ts/storeEvents.ts | 7 +- 23 files changed, 289 insertions(+), 185 deletions(-) diff --git a/packages/store/abi/IStore.sol/IStore.abi.json b/packages/store/abi/IStore.sol/IStore.abi.json index eee1dcc5cc..f945bde14d 100644 --- a/packages/store/abi/IStore.sol/IStore.abi.json +++ b/packages/store/abi/IStore.sol/IStore.abi.json @@ -158,7 +158,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -188,8 +200,8 @@ }, { "indexed": false, - "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "internalType": "bytes32", + "name": "encodedLengths", "type": "bytes32" }, { @@ -238,7 +250,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" } ], @@ -324,7 +336,7 @@ }, { "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" }, { @@ -691,7 +703,7 @@ }, { "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" }, { diff --git a/packages/store/abi/IStore.sol/IStoreData.abi.json b/packages/store/abi/IStore.sol/IStoreData.abi.json index 328b4263b5..fbf2f4037c 100644 --- a/packages/store/abi/IStore.sol/IStoreData.abi.json +++ b/packages/store/abi/IStore.sol/IStoreData.abi.json @@ -41,8 +41,8 @@ }, { "indexed": false, - "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "internalType": "bytes32", + "name": "encodedLengths", "type": "bytes32" }, { @@ -91,7 +91,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" } ], @@ -455,7 +455,7 @@ }, { "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" }, { diff --git a/packages/store/abi/IStore.sol/IStoreEphemeral.abi.json b/packages/store/abi/IStore.sol/IStoreEphemeral.abi.json index 3aa07648a5..cbbd097257 100644 --- a/packages/store/abi/IStore.sol/IStoreEphemeral.abi.json +++ b/packages/store/abi/IStore.sol/IStoreEphemeral.abi.json @@ -17,7 +17,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -43,7 +55,7 @@ }, { "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" }, { diff --git a/packages/store/abi/IStore.sol/IStoreHook.abi.json b/packages/store/abi/IStore.sol/IStoreHook.abi.json index 3dfdec15d3..e7c849d916 100644 --- a/packages/store/abi/IStore.sol/IStoreHook.abi.json +++ b/packages/store/abi/IStore.sol/IStoreHook.abi.json @@ -107,7 +107,7 @@ }, { "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" }, { diff --git a/packages/store/abi/IStore.sol/IStoreWrite.abi.json b/packages/store/abi/IStore.sol/IStoreWrite.abi.json index d79beb751f..47a5fe6fa6 100644 --- a/packages/store/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/store/abi/IStore.sol/IStoreWrite.abi.json @@ -41,8 +41,8 @@ }, { "indexed": false, - "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "internalType": "bytes32", + "name": "encodedLengths", "type": "bytes32" }, { @@ -91,7 +91,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" } ], @@ -276,7 +276,7 @@ }, { "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" }, { diff --git a/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json b/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json index d2e4c93669..d19ef63779 100644 --- a/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json +++ b/packages/store/abi/MirrorSubscriber.sol/MirrorSubscriber.abi.json @@ -218,7 +218,7 @@ }, { "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" }, { diff --git a/packages/store/abi/StoreCore.sol/StoreCore.abi.json b/packages/store/abi/StoreCore.sol/StoreCore.abi.json index b09ab948f7..f7d07e59ba 100644 --- a/packages/store/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/store/abi/StoreCore.sol/StoreCore.abi.json @@ -41,8 +41,8 @@ }, { "indexed": false, - "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "internalType": "bytes32", + "name": "encodedLengths", "type": "bytes32" }, { @@ -78,8 +78,8 @@ }, { "indexed": false, - "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "internalType": "bytes32", + "name": "encodedLengths", "type": "bytes32" }, { @@ -127,8 +127,8 @@ }, { "indexed": false, - "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "internalType": "bytes32", + "name": "encodedLengths", "type": "bytes32" } ], diff --git a/packages/store/abi/StoreMock.sol/StoreMock.abi.json b/packages/store/abi/StoreMock.sol/StoreMock.abi.json index 72c09be09d..77b96e3be2 100644 --- a/packages/store/abi/StoreMock.sol/StoreMock.abi.json +++ b/packages/store/abi/StoreMock.sol/StoreMock.abi.json @@ -206,7 +206,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -236,8 +248,8 @@ }, { "indexed": false, - "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "internalType": "bytes32", + "name": "encodedLengths", "type": "bytes32" }, { @@ -286,7 +298,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" } ], @@ -372,7 +384,7 @@ }, { "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" }, { @@ -739,7 +751,7 @@ }, { "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" }, { diff --git a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json index c3bc477d01..4a8a6006f0 100644 --- a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json +++ b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json @@ -200,7 +200,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -230,8 +242,8 @@ }, { "indexed": false, - "internalType": "PackedCounter", - "name": "dynamicDataLengths", + "internalType": "bytes32", + "name": "encodedLengths", "type": "bytes32" }, { @@ -280,7 +292,7 @@ { "indexed": false, "internalType": "bytes32", - "name": "dynamicDataLengths", + "name": "encodedLengths", "type": "bytes32" } ], diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index e9951aae1b..27c815c620 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -45,7 +45,7 @@ interface IStoreRead { } interface IStoreWrite { - event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, PackedCounter encodedLengths, bytes dynamicData); + event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData); event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); event StoreSpliceDynamicRecord( @@ -54,7 +54,7 @@ interface IStoreWrite { uint48 start, uint40 deleteCount, bytes data, - PackedCounter encodedLengths + bytes32 encodedLengths ); event StoreDeleteRecord(bytes32 table, bytes32[] key); @@ -110,13 +110,7 @@ interface IStoreWrite { } interface IStoreEphemeral { - event StoreEphemeralRecord( - bytes32 table, - bytes32[] key, - bytes staticData, - PackedCounter encodedLengths, - bytes dynamicData - ); + event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData); // Emit the ephemeral event without modifying storage function emitEphemeralRecord( diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index 790f32a619..d43105b10f 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -15,8 +15,7 @@ import { StoreSwitch } from "./StoreSwitch.sol"; library StoreCore { // note: the preimage of the tuple of keys used to index is part of the event, so it can be used by indexers - event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, PackedCounter encodedLengths, bytes dynamicData); - // TODO: finalize dynamic lengths args (these names/positions are placeholders while I figure out of this is enough data for schemaless indexing) + event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData); event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); event StoreSpliceDynamicRecord( bytes32 table, @@ -24,16 +23,10 @@ library StoreCore { uint48 start, uint40 deleteCount, bytes data, - PackedCounter encodedLengths + bytes32 encodedLengths ); event StoreDeleteRecord(bytes32 table, bytes32[] key); - event StoreEphemeralRecord( - bytes32 table, - bytes32[] key, - bytes staticData, - PackedCounter encodedLengths, - bytes dynamicData - ); + event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData); /** * Initialize internal tables. @@ -162,7 +155,7 @@ library StoreCore { StoreCoreInternal._validateDataLength(valueSchema, staticData, encodedLengths, dynamicData); // Emit event to notify indexers - emit StoreSetRecord(tableId, key, staticData, encodedLengths, dynamicData); + emit StoreSetRecord(tableId, key, staticData, encodedLengths.unwrap(), dynamicData); // Call onSetRecord hooks (before actually modifying the state, so observers have access to the previous state if needed) address[] memory hooks = Hooks.get(tableId); @@ -408,7 +401,7 @@ library StoreCore { StoreCoreInternal._validateDataLength(valueSchema, staticData, encodedLengths, dynamicData); // Emit event to notify indexers - emit StoreEphemeralRecord(tableId, key, staticData, encodedLengths, dynamicData); + emit StoreEphemeralRecord(tableId, key, staticData, encodedLengths.unwrap(), dynamicData); // Call onSetRecord hooks address[] memory hooks = Hooks.get(tableId); @@ -597,7 +590,14 @@ library StoreCoreInternal { } uint256 deleteCount = oldFieldLength; // Emit event to notify indexers - emit StoreCore.StoreSpliceDynamicRecord(tableId, key, uint48(start), uint40(deleteCount), data, encodedLengths); + emit StoreCore.StoreSpliceDynamicRecord( + tableId, + key, + uint48(start), + uint40(deleteCount), + data, + encodedLengths.unwrap() + ); } function _pushToDynamicField( @@ -623,7 +623,7 @@ library StoreCoreInternal { _setPartialDynamicData(tableId, key, dynamicSchemaIndex, oldFieldLength, dataToPush); // Prepare data for the splice event - uint256 start; + uint256 start = oldFieldLength; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) for (uint8 i; i < dynamicSchemaIndex; i++) { @@ -638,7 +638,7 @@ library StoreCoreInternal { uint48(start), uint40(deleteCount), dataToPush, - encodedLengths + encodedLengths.unwrap() ); } @@ -681,7 +681,7 @@ library StoreCoreInternal { uint48(start), uint40(deleteCount), new bytes(0), - encodedLengths + encodedLengths.unwrap() ); } @@ -720,7 +720,7 @@ library StoreCoreInternal { uint48(start), uint40(deleteCount), dataToSet, - encodedLengths + encodedLengths.unwrap() ); } diff --git a/packages/store/src/codegen/tables/Callbacks.sol b/packages/store/src/codegen/tables/Callbacks.sol index 7d4fc61c52..6fa170a9f0 100644 --- a/packages/store/src/codegen/tables/Callbacks.sol +++ b/packages/store/src/codegen/tables/Callbacks.sol @@ -228,6 +228,15 @@ library Callbacks { return abi.encodePacked(EncodeArray.encode((value))); } + /** Tightly pack full data using this table's schema */ + function encode(bytes24[] memory value) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(value); + bytes memory _dynamicData = encodeDynamic(value); + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } + /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(bytes32 key) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); diff --git a/packages/store/src/codegen/tables/Hooks.sol b/packages/store/src/codegen/tables/Hooks.sol index 0e70bddd37..2d1c39ad36 100644 --- a/packages/store/src/codegen/tables/Hooks.sol +++ b/packages/store/src/codegen/tables/Hooks.sol @@ -228,6 +228,15 @@ library Hooks { return abi.encodePacked(EncodeArray.encode((value))); } + /** Tightly pack full data using this table's schema */ + function encode(address[] memory value) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(value); + bytes memory _dynamicData = encodeDynamic(value); + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } + /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(bytes32 key) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); diff --git a/packages/store/src/codegen/tables/KeyEncoding.sol b/packages/store/src/codegen/tables/KeyEncoding.sol index 2d68f6510a..5c855ceb9e 100644 --- a/packages/store/src/codegen/tables/KeyEncoding.sol +++ b/packages/store/src/codegen/tables/KeyEncoding.sol @@ -155,6 +155,16 @@ library KeyEncoding { return abi.encodePacked(value); } + /** Tightly pack full data using this table's schema */ + function encode(bool value) internal pure returns (bytes memory) { + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } + /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple( uint256 k1, diff --git a/packages/store/src/codegen/tables/Mixed.sol b/packages/store/src/codegen/tables/Mixed.sol index 94923c0a54..a7bd6a61ff 100644 --- a/packages/store/src/codegen/tables/Mixed.sol +++ b/packages/store/src/codegen/tables/Mixed.sol @@ -540,6 +540,16 @@ library Mixed { return abi.encodePacked(EncodeArray.encode((a32)), bytes((s))); } + /** Tightly pack full data using this table's schema */ + function encode(uint32 u32, uint128 u128, uint32[] memory a32, string memory s) internal pure returns (bytes memory) { + bytes memory _staticData = encodeStatic(u32, u128); + + PackedCounter _encodedLengths = encodeLengths(a32, s); + bytes memory _dynamicData = encodeDynamic(a32, s); + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } + /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(bytes32 key) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); diff --git a/packages/store/src/codegen/tables/Tables.sol b/packages/store/src/codegen/tables/Tables.sol index c745d463cf..806e995638 100644 --- a/packages/store/src/codegen/tables/Tables.sol +++ b/packages/store/src/codegen/tables/Tables.sol @@ -573,6 +573,21 @@ library Tables { return abi.encodePacked(bytes((abiEncodedKeyNames)), bytes((abiEncodedFieldNames))); } + /** Tightly pack full data using this table's schema */ + function encode( + bytes32 keySchema, + bytes32 valueSchema, + bytes memory abiEncodedKeyNames, + bytes memory abiEncodedFieldNames + ) internal pure returns (bytes memory) { + bytes memory _staticData = encodeStatic(keySchema, valueSchema); + + PackedCounter _encodedLengths = encodeLengths(abiEncodedKeyNames, abiEncodedFieldNames); + bytes memory _dynamicData = encodeDynamic(abiEncodedKeyNames, abiEncodedFieldNames); + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } + /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(bytes32 tableId) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); diff --git a/packages/store/src/codegen/tables/Vector2.sol b/packages/store/src/codegen/tables/Vector2.sol index 192128635b..849213633b 100644 --- a/packages/store/src/codegen/tables/Vector2.sol +++ b/packages/store/src/codegen/tables/Vector2.sol @@ -200,6 +200,16 @@ library Vector2 { return abi.encodePacked(x, y); } + /** Tightly pack full data using this table's schema */ + function encode(uint32 x, uint32 y) internal pure returns (bytes memory) { + bytes memory _staticData = encodeStatic(x, y); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } + /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(bytes32 key) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index e74d5ea41f..3fde4de8f6 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -57,7 +57,9 @@ contract StoreCoreTest is Test, StoreMock { emit StoreSetRecord( TablesTableId, key, - Tables.encode(keySchema.unwrap(), valueSchema.unwrap(), abi.encode(keyNames), abi.encode(fieldNames)) + Tables.encodeStatic(keySchema.unwrap(), valueSchema.unwrap()), + Tables.encodeLengths(abi.encode(keyNames), abi.encode(fieldNames)).unwrap(), + Tables.encodeDynamic(abi.encode(keyNames), abi.encode(fieldNames)) ); IStore(this).registerTable(table, keySchema, valueSchema, keyNames, fieldNames); @@ -193,21 +195,21 @@ contract StoreCoreTest is Test, StoreMock { IStore(this).registerTable(table, defaultKeySchema, valueSchema, new string[](1), new string[](4)); // Set data - bytes memory data = abi.encodePacked(bytes1(0x01), bytes2(0x0203), bytes1(0x04), bytes2(0x0506)); + bytes memory staticData = abi.encodePacked(bytes1(0x01), bytes2(0x0203), bytes1(0x04), bytes2(0x0506)); bytes32[] memory key = new bytes32[](1); key[0] = keccak256("some.key"); // Expect a StoreSetRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetRecord(table, key, data); + emit StoreSetRecord(table, key, staticData, bytes32(0), new bytes(0)); - IStore(this).setRecord(table, key, data, valueSchema); + IStore(this).setRecord(table, key, staticData, PackedCounter.wrap(bytes32(0)), new bytes(0), valueSchema); // Get data bytes memory loadedData = IStore(this).getRecord(table, key, valueSchema); - assertTrue(Bytes.equals(data, loadedData)); + assertTrue(Bytes.equals(staticData, loadedData)); } function testFailSetAndGetStaticData() public { @@ -222,13 +224,13 @@ contract StoreCoreTest is Test, StoreMock { IStore(this).registerTable(table, defaultKeySchema, valueSchema, new string[](1), new string[](4)); // Set data - bytes memory data = abi.encodePacked(bytes1(0x01), bytes2(0x0203), bytes1(0x04)); + bytes memory staticData = abi.encodePacked(bytes1(0x01), bytes2(0x0203), bytes1(0x04)); bytes32[] memory key = new bytes32[](1); key[0] = keccak256("some.key"); // This should fail because the data is not 6 bytes long - IStore(this).setRecord(table, key, data, valueSchema); + IStore(this).setRecord(table, key, staticData, PackedCounter.wrap(bytes32(0)), new bytes(0), valueSchema); } function testSetAndGetStaticDataSpanningWords() public { @@ -238,7 +240,7 @@ contract StoreCoreTest is Test, StoreMock { IStore(this).registerTable(table, defaultKeySchema, valueSchema, new string[](1), new string[](2)); // Set data - bytes memory data = abi.encodePacked( + bytes memory staticData = abi.encodePacked( bytes16(0x0102030405060708090a0b0c0d0e0f10), bytes32(0x1112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30) ); @@ -248,14 +250,14 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSetRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetRecord(table, key, data); + emit StoreSetRecord(table, key, staticData, bytes32(0), new bytes(0)); - IStore(this).setRecord(table, key, data, valueSchema); + IStore(this).setRecord(table, key, staticData, PackedCounter.wrap(bytes32(0)), new bytes(0), valueSchema); // Get data bytes memory loadedData = IStore(this).getRecord(table, key, valueSchema); - assertTrue(Bytes.equals(data, loadedData)); + assertTrue(Bytes.equals(staticData, loadedData)); } function testSetAndGetDynamicData() public { @@ -294,6 +296,8 @@ contract StoreCoreTest is Test, StoreMock { } // Concat data + bytes memory staticData = abi.encodePacked(firstDataBytes); + bytes memory dynamicData = abi.encodePacked(secondDataBytes, thirdDataBytes); bytes memory data = abi.encodePacked( firstDataBytes, encodedDynamicLength.unwrap(), @@ -307,10 +311,10 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSetRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSetRecord(table, key, data); + emit StoreSetRecord(table, key, staticData, encodedDynamicLength.unwrap(), dynamicData); // Set data - IStore(this).setRecord(table, key, data, valueSchema); + IStore(this).setRecord(table, key, staticData, encodedDynamicLength, dynamicData, valueSchema); // Get data bytes memory loadedData = IStore(this).getRecord(table, key, valueSchema); @@ -352,9 +356,9 @@ contract StoreCoreTest is Test, StoreMock { bytes memory firstDataPacked = abi.encodePacked(firstDataBytes); - // Expect a StoreSpliceRecord event to be emitted + // Expect a StoreSpliceStaticRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord(table, key, 0, uint40(firstDataPacked.length), firstDataPacked, bytes32(0), 0); + emit StoreSpliceStaticRecord(table, key, 0, uint40(firstDataPacked.length), firstDataPacked); // Set first field IStore(this).setField(table, key, 0, firstDataPacked, valueSchema); @@ -380,14 +384,12 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceStaticRecord( table, key, uint48(firstDataPacked.length), uint40(secondDataPacked.length), - secondDataPacked, - bytes32(0), - 0 + secondDataPacked ); IStore(this).setField(table, key, 1, secondDataPacked, valueSchema); @@ -434,14 +436,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceDynamicRecord( table, key, - uint48(firstDataPacked.length + secondDataPacked.length + 32), + uint48(0), 0, thirdDataBytes, - bytes32(0), - 0 + PackedCounterLib.pack(thirdDataBytes.length, 0).unwrap() ); // Set third field @@ -464,14 +465,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceDynamicRecord( table, key, - uint48(firstDataPacked.length + secondDataPacked.length + 32 + thirdDataBytes.length), + uint48(thirdDataBytes.length), 0, fourthDataBytes, - bytes32(0), - 0 + PackedCounterLib.pack(thirdDataBytes.length, fourthDataBytes.length).unwrap() ); // Set fourth field @@ -498,14 +498,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceDynamicRecord( table, key, - uint48(firstDataPacked.length + secondDataPacked.length + 32 + thirdDataBytes.length), + uint48(thirdDataBytes.length), uint40(fourthDataBytes.length), thirdDataBytes, - bytes32(0), - 0 + PackedCounterLib.pack(thirdDataBytes.length, thirdDataBytes.length).unwrap() ); // Set fourth field @@ -555,6 +554,8 @@ contract StoreCoreTest is Test, StoreMock { } // Concat data + bytes memory staticData = abi.encodePacked(firstDataBytes); + bytes memory dynamicData = abi.encodePacked(secondDataBytes, thirdDataBytes); bytes memory data = abi.encodePacked( firstDataBytes, encodedDynamicLength.unwrap(), @@ -567,7 +568,7 @@ contract StoreCoreTest is Test, StoreMock { key[0] = bytes32("some.key"); // Set data - IStore(this).setRecord(table, key, data, valueSchema); + IStore(this).setRecord(table, key, staticData, encodedDynamicLength, dynamicData, valueSchema); // Get data bytes memory loadedData = IStore(this).getRecord(table, key, valueSchema); @@ -648,16 +649,15 @@ contract StoreCoreTest is Test, StoreMock { } data.newSecondDataBytes = abi.encodePacked(data.secondDataBytes, data.secondDataToPush); - // Expect a StoreSpliceRecord event to be emitted + // Expect a StoreSpliceDynamicRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceDynamicRecord( data.table, data.key, - uint48(data.firstDataBytes.length + 32 + data.secondDataBytes.length), + uint48(data.secondDataBytes.length), 0, data.secondDataToPush, - bytes32(0), - 0 + PackedCounterLib.pack(data.newSecondDataBytes.length, data.thirdDataBytes.length).unwrap() ); // Push to second field @@ -694,14 +694,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceDynamicRecord( data.table, data.key, - uint48(data.firstDataBytes.length + 32 + data.newSecondDataBytes.length + data.thirdDataBytes.length), + uint48(data.newSecondDataBytes.length + data.thirdDataBytes.length), 0, data.thirdDataToPush, - bytes32(0), - 0 + PackedCounterLib.pack(data.newSecondDataBytes.length, data.newThirdDataBytes.length).unwrap() ); // Push to third field @@ -797,14 +796,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceDynamicRecord( data.table, data.key, - uint48(data.firstDataBytes.length + 32 + 4 * 1), + uint48(4 * 1), 4 * 1, data.secondDataForUpdate, - bytes32(0), - 0 + PackedCounterLib.pack(data.newSecondDataBytes.length, data.thirdDataBytes.length).unwrap() ); // Update index 1 in second field (4 = byte length of uint32) @@ -843,14 +841,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceDynamicRecord( data.table, data.key, - uint48(data.firstDataBytes.length + 32 + data.newSecondDataBytes.length + 8 * 1), + uint48(data.newSecondDataBytes.length + 8 * 1), 8 * 4, data.thirdDataForUpdate, - bytes32(0), - 0 + PackedCounterLib.pack(data.newSecondDataBytes.length, data.newThirdDataBytes.length).unwrap() ); // Update indexes 1,2,3,4 in third field (8 = byte length of uint64) @@ -921,21 +918,21 @@ contract StoreCoreTest is Test, StoreMock { IStore(this).registerStoreHook(table, subscriber); - bytes memory data = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); + bytes memory staticData = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); - IStore(this).setRecord(table, key, data, valueSchema); + IStore(this).setRecord(table, key, staticData, PackedCounter.wrap(bytes32(0)), new bytes(0), valueSchema); // Get data from indexed table - the indexer should have mirrored the data there bytes memory indexedData = IStore(this).getRecord(indexerTableId, key, valueSchema); - assertEq(keccak256(data), keccak256(indexedData)); + assertEq(keccak256(staticData), keccak256(indexedData)); - data = abi.encodePacked(bytes16(0x1112131415161718191a1b1c1d1e1f20)); + staticData = abi.encodePacked(bytes16(0x1112131415161718191a1b1c1d1e1f20)); - IStore(this).setField(table, key, 0, data, valueSchema); + IStore(this).setField(table, key, 0, staticData, valueSchema); // Get data from indexed table - the indexer should have mirrored the data there indexedData = IStore(this).getRecord(indexerTableId, key, valueSchema); - assertEq(keccak256(data), keccak256(indexedData)); + assertEq(keccak256(staticData), keccak256(indexedData)); IStore(this).deleteRecord(table, key, valueSchema); @@ -968,11 +965,11 @@ contract StoreCoreTest is Test, StoreMock { arrayData[0] = 0x01020304; bytes memory arrayDataBytes = EncodeArray.encode(arrayData); PackedCounter encodedArrayDataLength = PackedCounterLib.pack(uint40(arrayDataBytes.length)); - bytes memory dynamicData = abi.encodePacked(encodedArrayDataLength.unwrap(), arrayDataBytes); + bytes memory dynamicData = arrayDataBytes; bytes memory staticData = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); - bytes memory data = abi.encodePacked(staticData, dynamicData); + bytes memory data = abi.encodePacked(staticData, encodedArrayDataLength, dynamicData); - IStore(this).setRecord(table, key, data, valueSchema); + IStore(this).setRecord(table, key, staticData, encodedArrayDataLength, dynamicData, valueSchema); // Get data from indexed table - the indexer should have mirrored the data there bytes memory indexedData = IStore(this).getRecord(indexerTableId, key, valueSchema); @@ -981,8 +978,8 @@ contract StoreCoreTest is Test, StoreMock { // Update dynamic data arrayData[0] = 0x11121314; arrayDataBytes = EncodeArray.encode(arrayData); - dynamicData = abi.encodePacked(encodedArrayDataLength.unwrap(), arrayDataBytes); - data = abi.encodePacked(staticData, dynamicData); + dynamicData = arrayDataBytes; + data = abi.encodePacked(staticData, encodedArrayDataLength, dynamicData); IStore(this).setField(table, key, 1, arrayDataBytes, valueSchema); diff --git a/packages/store/test/StoreCoreDynamic.t.sol b/packages/store/test/StoreCoreDynamic.t.sol index 710eb4fc76..779e26de64 100644 --- a/packages/store/test/StoreCoreDynamic.t.sol +++ b/packages/store/test/StoreCoreDynamic.t.sol @@ -7,6 +7,7 @@ import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol" import { StoreCore } from "../src/StoreCore.sol"; import { SliceLib } from "../src/Slice.sol"; import { EncodeArray } from "../src/tightcoder/EncodeArray.sol"; +import { PackedCounterLib } from "../src/PackedCounter.sol"; import { Schema } from "../src/Schema.sol"; import { StoreReadWithStubs } from "../src/StoreReadWithStubs.sol"; import { SchemaEncodeHelper } from "./SchemaEncodeHelper.sol"; @@ -89,14 +90,13 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreReadWithStubs { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceDynamicRecord( _table, _key, - uint48(32 + 32 + secondDataBytes.length - byteLengthToPop), + uint48(secondDataBytes.length - byteLengthToPop), uint40(byteLengthToPop), new bytes(0), - bytes32(0), - 0 + PackedCounterLib.pack(newDataBytes.length, thirdDataBytes.length).unwrap() ); // Pop from second field @@ -136,14 +136,13 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreReadWithStubs { // Expect a StoreSpliceRecord event to be emitted after pop vm.expectEmit(true, true, true, true); - emit StoreSpliceRecord( + emit StoreSpliceDynamicRecord( _table, _key, - uint48(32 + 32 + secondDataBytes.length + thirdDataBytes.length - byteLengthToPop), + uint48(secondDataBytes.length + thirdDataBytes.length - byteLengthToPop), uint40(byteLengthToPop), new bytes(0), - bytes32(0), - 0 + PackedCounterLib.pack(secondDataBytes.length, newDataBytes.length).unwrap() ); // Pop from the field diff --git a/packages/store/test/StoreCoreGas.t.sol b/packages/store/test/StoreCoreGas.t.sol index 9c0f7fa722..fbcf5cabed 100644 --- a/packages/store/test/StoreCoreGas.t.sol +++ b/packages/store/test/StoreCoreGas.t.sol @@ -127,12 +127,13 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { StoreCore.registerTable(table, defaultKeySchema, valueSchema, new string[](1), new string[](4)); // Set data - bytes memory data = abi.encodePacked(bytes1(0x01), bytes2(0x0203), bytes1(0x04), bytes2(0x0506)); + bytes memory staticData = abi.encodePacked(bytes1(0x01), bytes2(0x0203), bytes1(0x04), bytes2(0x0506)); + bytes memory dynamicData = new bytes(0); bytes32[] memory key = new bytes32[](1); key[0] = keccak256("some.key"); startGasReport("set static record (1 slot)"); - StoreCore.setRecord(table, key, data, valueSchema); + StoreCore.setRecord(table, key, staticData, PackedCounter.wrap(bytes32(0)), dynamicData, valueSchema); endGasReport(); // Get data @@ -148,16 +149,17 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { StoreCore.registerTable(table, defaultKeySchema, valueSchema, new string[](1), new string[](2)); // Set data - bytes memory data = abi.encodePacked( + bytes memory staticData = abi.encodePacked( bytes16(0x0102030405060708090a0b0c0d0e0f10), bytes32(0x1112131415161718191a1b1c1d1e1f202122232425262728292a2b2c2d2e2f30) ); + bytes memory dynamicData = new bytes(0); bytes32[] memory key = new bytes32[](1); key[0] = keccak256("some.key"); startGasReport("set static record (2 slots)"); - StoreCore.setRecord(table, key, data, valueSchema); + StoreCore.setRecord(table, key, staticData, PackedCounter.wrap(bytes32(0)), dynamicData, valueSchema); endGasReport(); // Get data @@ -202,12 +204,8 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { ); // Concat data - bytes memory data = abi.encodePacked( - firstDataBytes, - encodedDynamicLength.unwrap(), - secondDataBytes, - thirdDataBytes - ); + bytes memory staticData = abi.encodePacked(firstDataBytes); + bytes memory dynamicData = abi.encodePacked(secondDataBytes, thirdDataBytes); // Create key bytes32[] memory key = new bytes32[](1); @@ -215,7 +213,7 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { // Set data startGasReport("set complex record with dynamic data (4 slots)"); - StoreCore.setRecord(table, key, data, valueSchema); + StoreCore.setRecord(table, key, staticData, encodedDynamicLength, dynamicData, valueSchema); endGasReport(); // Get data @@ -366,19 +364,15 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { ); // Concat data - bytes memory data = abi.encodePacked( - firstDataBytes, - encodedDynamicLength.unwrap(), - secondDataBytes, - thirdDataBytes - ); + bytes memory staticData = abi.encodePacked(firstDataBytes); + bytes memory dynamicData = abi.encodePacked(secondDataBytes, thirdDataBytes); // Create key bytes32[] memory key = new bytes32[](1); key[0] = bytes32("some.key"); // Set data - StoreCore.setRecord(table, key, data, valueSchema); + StoreCore.setRecord(table, key, staticData, encodedDynamicLength, dynamicData, valueSchema); // Delete data startGasReport("delete record (complex data, 3 slots)"); @@ -600,16 +594,17 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { StoreCore.registerStoreHook(table, subscriber); endGasReport(); - bytes memory data = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); + bytes memory staticData = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); + bytes memory dynamicData = new bytes(0); startGasReport("set record on table with subscriber"); - StoreCore.setRecord(table, key, data, valueSchema); + StoreCore.setRecord(table, key, staticData, PackedCounter.wrap(bytes32(0)), dynamicData, valueSchema); endGasReport(); - data = abi.encodePacked(bytes16(0x1112131415161718191a1b1c1d1e1f20)); + staticData = abi.encodePacked(bytes16(0x1112131415161718191a1b1c1d1e1f20)); startGasReport("set static field on table with subscriber"); - StoreCore.setField(table, key, 0, data, valueSchema); + StoreCore.setField(table, key, 0, staticData, valueSchema); endGasReport(); startGasReport("delete record on table with subscriber"); @@ -643,19 +638,19 @@ contract StoreCoreGasTest is Test, GasReporter, StoreMock { arrayData[0] = 0x01020304; bytes memory arrayDataBytes = EncodeArray.encode(arrayData); PackedCounter encodedArrayDataLength = PackedCounterLib.pack(uint40(arrayDataBytes.length)); - bytes memory dynamicData = abi.encodePacked(encodedArrayDataLength.unwrap(), arrayDataBytes); + bytes memory dynamicData = arrayDataBytes; bytes memory staticData = abi.encodePacked(bytes16(0x0102030405060708090a0b0c0d0e0f10)); - bytes memory data = abi.encodePacked(staticData, dynamicData); + bytes memory data = abi.encodePacked(staticData, encodedArrayDataLength, dynamicData); startGasReport("set (dynamic) record on table with subscriber"); - StoreCore.setRecord(table, key, data, valueSchema); + StoreCore.setRecord(table, key, staticData, encodedArrayDataLength, dynamicData, valueSchema); endGasReport(); // Update dynamic data arrayData[0] = 0x11121314; arrayDataBytes = EncodeArray.encode(arrayData); - dynamicData = abi.encodePacked(encodedArrayDataLength.unwrap(), arrayDataBytes); - data = abi.encodePacked(staticData, dynamicData); + dynamicData = arrayDataBytes; + data = abi.encodePacked(staticData, encodedArrayDataLength, dynamicData); startGasReport("set (dynamic) field on table with subscriber"); StoreCore.setField(table, key, 1, arrayDataBytes, valueSchema); diff --git a/packages/store/ts/codegen/record.ts b/packages/store/ts/codegen/record.ts index 82a86f5fc3..6d1d7e9ee8 100644 --- a/packages/store/ts/codegen/record.ts +++ b/packages/store/ts/codegen/record.ts @@ -74,6 +74,31 @@ export function renderRecordMethods(options: RenderTableOptions) { return result; } +export function renderRecordData(options: RenderTableOptions) { + let result = ""; + if (options.staticFields.length > 0) { + result += ` + bytes memory _staticData = encodeStatic(${renderArguments(options.staticFields.map(({ name }) => name))}); + `; + } else { + result += `bytes memory _staticData;`; + } + + if (options.dynamicFields.length > 0) { + result += ` + PackedCounter _encodedLengths = encodeLengths(${renderArguments(options.dynamicFields.map(({ name }) => name))}); + bytes memory _dynamicData = encodeDynamic(${renderArguments(options.dynamicFields.map(({ name }) => name))}); + `; + } else { + result += ` + PackedCounter _encodedLengths; + bytes memory _dynamicData; + `; + } + + return result; +} + // Renders the `decode` function that parses a bytes blob into the table data function renderDecodeFunction({ structName, fields, staticFields, dynamicFields }: RenderTableOptions) { // either set struct properties, or just variables @@ -180,28 +205,3 @@ function renderDecodeDynamicFieldPartial(field: RenderDynamicField) { )`; } } - -function renderRecordData(options: RenderTableOptions) { - let result = ""; - if (options.staticFields.length > 0) { - result += ` - bytes memory _staticData = encodeStatic(${renderArguments(options.staticFields.map(({ name }) => name))}); - `; - } else { - result += `bytes memory _staticData;`; - } - - if (options.dynamicFields.length > 0) { - result += ` - PackedCounter _encodedLengths = encodeLengths(${renderArguments(options.dynamicFields.map(({ name }) => name))}); - bytes memory _dynamicData = encodeDynamic(${renderArguments(options.dynamicFields.map(({ name }) => name))}); - `; - } else { - result += ` - PackedCounter _encodedLengths; - bytes memory _dynamicData; - `; - } - - return result; -} diff --git a/packages/store/ts/codegen/renderTable.ts b/packages/store/ts/codegen/renderTable.ts index 31d91fa2fc..1326c531bb 100644 --- a/packages/store/ts/codegen/renderTable.ts +++ b/packages/store/ts/codegen/renderTable.ts @@ -12,7 +12,7 @@ import { } from "@latticexyz/common/codegen"; import { renderEphemeralMethods } from "./ephemeral"; import { renderEncodeFieldSingle, renderFieldMethods } from "./field"; -import { renderRecordMethods } from "./record"; +import { renderRecordData, renderRecordMethods } from "./record"; import { RenderTableOptions } from "./types"; export function renderTable(options: RenderTableOptions) { @@ -122,6 +122,15 @@ library ${libraryName} { ${renderEncodedLengths(dynamicFields)} ${renderEncodeDynamic(dynamicFields)} + + /** Tightly pack full data using this table's schema */ + function encode(${renderArguments( + options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`) + )}) internal pure returns (bytes memory) { + ${renderRecordData(options)} + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(${renderArguments([_typedKeyArgs])}) internal pure returns (bytes32[] memory) { diff --git a/packages/store/ts/storeEvents.ts b/packages/store/ts/storeEvents.ts index 9f8e52a97b..7b4d0ccef4 100644 --- a/packages/store/ts/storeEvents.ts +++ b/packages/store/ts/storeEvents.ts @@ -1,8 +1,7 @@ export const storeEvents = [ - "event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, PackedCounter encodedLengths, bytes dynamicData)", - // TODO: finalize dynamic lengths args (these names/positions are placeholders while I figure out of this is enough data for schemaless indexing) + "event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData)", "event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", - "event StoreSpliceDynamicRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data, PackedCounter newDynamicLengths, uint256 encodedLengths)", - "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes staticData, PackedCounter encodedLengths, bytes dynamicData)", + "event StoreSpliceDynamicRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths)", + "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData)", "event StoreDeleteRecord(bytes32 table, bytes32[] key)", ] as const; From 157d9ab4580ba45a1af2607f1737a698ed971fde Mon Sep 17 00:00:00 2001 From: dk1a Date: Fri, 8 Sep 2023 19:06:19 +0300 Subject: [PATCH 24/69] partially refactor world --- .../abi/CoreModule.sol/CoreModule.abi.json | 18 ++- .../abi/CoreSystem.sol/CoreSystem.abi.json | 44 +++++- .../EphemeralRecordSystem.abi.json | 44 +++++- .../abi/IBaseWorld.sol/IBaseWorld.abi.json | 111 ++++++++++++-- packages/world/abi/IStore.sol/IStore.abi.json | 111 ++++++++++++-- .../world/abi/IStore.sol/IStoreData.abi.json | 67 +++++++- .../abi/IStore.sol/IStoreEphemeral.abi.json | 26 +++- .../world/abi/IStore.sol/IStoreHook.abi.json | 12 +- .../world/abi/IStore.sol/IStoreWrite.abi.json | 67 +++++++- .../IStoreErrors.sol/IStoreErrors.abi.json | 18 ++- .../KeysInTableHook.abi.json | 28 +++- .../KeysWithValueHook.abi.json | 12 +- .../ModuleInstallationSystem.abi.json | 18 ++- .../abi/StoreCore.sol/StoreCore.abi.json | 69 ++++++++- .../abi/StoreRead.sol/StoreRead.abi.json | 18 ++- .../StoreRegistrationSystem.abi.json | 18 ++- packages/world/abi/World.sol/World.abi.json | 85 +++++++++- .../WorldRegistrationSystem.abi.json | 18 ++- .../world/abi/src/IStore.sol/IStore.abi.json | 111 ++++++++++++-- .../abi/src/IStore.sol/IStoreData.abi.json | 67 +++++++- .../src/IStore.sol/IStoreEphemeral.abi.json | 26 +++- .../abi/src/IStore.sol/IStoreHook.abi.json | 12 +- .../abi/src/IStore.sol/IStoreWrite.abi.json | 67 +++++++- .../abi/src/StoreCore.sol/StoreCore.abi.json | 69 ++++++++- packages/world/src/World.sol | 12 +- .../implementations/EphemeralRecordSystem.sol | 9 +- .../modules/core/tables/FunctionSelectors.sol | 26 +++- .../src/modules/core/tables/ResourceType.sol | 12 +- .../src/modules/core/tables/SystemHooks.sol | 19 ++- .../modules/core/tables/SystemRegistry.sol | 12 +- .../world/src/modules/core/tables/Systems.sol | 26 +++- .../modules/keysintable/KeysInTableHook.sol | 3 +- .../world/src/modules/keysintable/query.sol | 41 ++++- .../keysintable/tables/KeysInTable.sol | 44 ++++-- .../keysintable/tables/UsedKeysIndex.sol | 26 +++- .../keyswithvalue/KeysWithValueHook.sol | 11 +- .../keyswithvalue/getKeysWithValue.sol | 14 +- .../keyswithvalue/tables/KeysWithValue.sol | 19 ++- .../tables/CallboundDelegations.sol | 12 +- .../tables/TimeboundDelegations.sol | 12 +- .../uniqueentity/tables/UniqueEntity.sol | 12 +- packages/world/src/tables/Delegations.sol | 12 +- .../world/src/tables/InstalledModules.sol | 26 +++- packages/world/src/tables/NamespaceOwner.sol | 12 +- packages/world/src/tables/ResourceAccess.sol | 12 +- packages/world/test/KeysInTableModule.t.sol | 145 ++++++++++++++++-- packages/world/test/KeysWithValueModule.t.sol | 111 ++++++++++++-- packages/world/test/World.t.sol | 63 ++++++-- packages/world/test/query.t.sol | 113 +++++++------- packages/world/test/tables/AddressArray.sol | 19 ++- packages/world/test/tables/Bool.sol | 12 +- 51 files changed, 1708 insertions(+), 263 deletions(-) diff --git a/packages/world/abi/CoreModule.sol/CoreModule.abi.json b/packages/world/abi/CoreModule.sol/CoreModule.abi.json index 43437a8fc5..67178bbe24 100644 --- a/packages/world/abi/CoreModule.sol/CoreModule.abi.json +++ b/packages/world/abi/CoreModule.sol/CoreModule.abi.json @@ -71,7 +71,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -106,6 +106,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [ { diff --git a/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json b/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json index decf383ad6..86a1945f37 100644 --- a/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json +++ b/packages/world/abi/CoreSystem.sol/CoreSystem.abi.json @@ -158,7 +158,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -193,6 +193,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", @@ -243,7 +259,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -264,7 +292,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json b/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json index 3b31063c2b..328ab73f47 100644 --- a/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json +++ b/packages/world/abi/EphemeralRecordSystem.sol/EphemeralRecordSystem.abi.json @@ -65,7 +65,23 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", "type": "error" }, { @@ -86,7 +102,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -107,7 +135,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json index 57a025fdc7..d0eb54eef5 100644 --- a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json +++ b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json @@ -126,7 +126,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -161,6 +161,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", @@ -257,7 +273,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -282,7 +310,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -325,17 +365,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -428,7 +499,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { @@ -992,7 +1073,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/IStore.sol/IStore.abi.json b/packages/world/abi/IStore.sol/IStore.abi.json index a7cd620598..f945bde14d 100644 --- a/packages/world/abi/IStore.sol/IStore.abi.json +++ b/packages/world/abi/IStore.sol/IStore.abi.json @@ -28,7 +28,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -63,6 +63,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", @@ -142,7 +158,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -167,7 +195,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -210,17 +250,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -260,7 +331,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { @@ -617,7 +698,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/IStore.sol/IStoreData.abi.json b/packages/world/abi/IStore.sol/IStoreData.abi.json index 7b08bc8fda..fbf2f4037c 100644 --- a/packages/world/abi/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/IStore.sol/IStoreData.abi.json @@ -36,7 +36,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -79,17 +91,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -407,7 +450,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/IStore.sol/IStoreEphemeral.abi.json b/packages/world/abi/IStore.sol/IStoreEphemeral.abi.json index c9cbd9770c..cbbd097257 100644 --- a/packages/world/abi/IStore.sol/IStoreEphemeral.abi.json +++ b/packages/world/abi/IStore.sol/IStoreEphemeral.abi.json @@ -17,7 +17,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -38,7 +50,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/IStore.sol/IStoreHook.abi.json b/packages/world/abi/IStore.sol/IStoreHook.abi.json index 171784fcb2..e7c849d916 100644 --- a/packages/world/abi/IStore.sol/IStoreHook.abi.json +++ b/packages/world/abi/IStore.sol/IStoreHook.abi.json @@ -102,7 +102,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/IStore.sol/IStoreWrite.abi.json index 301a962b48..47a5fe6fa6 100644 --- a/packages/world/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/IStore.sol/IStoreWrite.abi.json @@ -36,7 +36,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -79,17 +91,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -228,7 +271,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/IStoreErrors.sol/IStoreErrors.abi.json b/packages/world/abi/IStoreErrors.sol/IStoreErrors.abi.json index cf6d375396..8488c23c54 100644 --- a/packages/world/abi/IStoreErrors.sol/IStoreErrors.abi.json +++ b/packages/world/abi/IStoreErrors.sol/IStoreErrors.abi.json @@ -28,7 +28,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -63,6 +63,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", diff --git a/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json b/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json index 3b28134403..eb4ed18387 100644 --- a/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json +++ b/packages/world/abi/KeysInTableHook.sol/KeysInTableHook.abi.json @@ -76,7 +76,23 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", "type": "error" }, { @@ -190,6 +206,16 @@ "name": "", "type": "bytes" }, + { + "internalType": "PackedCounter", + "name": "", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "", + "type": "bytes" + }, { "internalType": "Schema", "name": "", diff --git a/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json b/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json index 661dc02db1..2b3a7cea62 100644 --- a/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json +++ b/packages/world/abi/KeysWithValueHook.sol/KeysWithValueHook.abi.json @@ -155,7 +155,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json b/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json index 3ba41db3c5..83908e9cba 100644 --- a/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json +++ b/packages/world/abi/ModuleInstallationSystem.sol/ModuleInstallationSystem.abi.json @@ -49,7 +49,23 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", "type": "error" }, { diff --git a/packages/world/abi/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/StoreCore.sol/StoreCore.abi.json index 52eca7ff43..f7d07e59ba 100644 --- a/packages/world/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/StoreCore.sol/StoreCore.abi.json @@ -36,7 +36,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -61,7 +73,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -104,17 +128,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" } ] \ No newline at end of file diff --git a/packages/world/abi/StoreRead.sol/StoreRead.abi.json b/packages/world/abi/StoreRead.sol/StoreRead.abi.json index 93a0e17cf5..bd97059695 100644 --- a/packages/world/abi/StoreRead.sol/StoreRead.abi.json +++ b/packages/world/abi/StoreRead.sol/StoreRead.abi.json @@ -54,7 +54,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -89,6 +89,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", diff --git a/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json b/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json index 8e3dd8de1f..8b5e90eec4 100644 --- a/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json +++ b/packages/world/abi/StoreRegistrationSystem.sol/StoreRegistrationSystem.abi.json @@ -158,7 +158,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -193,6 +193,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", diff --git a/packages/world/abi/World.sol/World.abi.json b/packages/world/abi/World.sol/World.abi.json index eefdee3f97..5092476d72 100644 --- a/packages/world/abi/World.sol/World.abi.json +++ b/packages/world/abi/World.sol/World.abi.json @@ -179,7 +179,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -214,6 +214,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", @@ -305,7 +321,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -348,17 +376,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -751,7 +810,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json b/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json index f1b9ad18e7..ccf3d3e42d 100644 --- a/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json +++ b/packages/world/abi/WorldRegistrationSystem.sol/WorldRegistrationSystem.abi.json @@ -158,7 +158,23 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", "type": "error" }, { diff --git a/packages/world/abi/src/IStore.sol/IStore.abi.json b/packages/world/abi/src/IStore.sol/IStore.abi.json index a7cd620598..f945bde14d 100644 --- a/packages/world/abi/src/IStore.sol/IStore.abi.json +++ b/packages/world/abi/src/IStore.sol/IStore.abi.json @@ -28,7 +28,7 @@ "type": "uint256" } ], - "name": "StoreCore_InvalidDataLength", + "name": "StoreCore_InvalidDynamicDataLength", "type": "error" }, { @@ -63,6 +63,22 @@ "name": "StoreCore_InvalidKeyNamesLength", "type": "error" }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "expected", + "type": "uint256" + }, + { + "internalType": "uint256", + "name": "received", + "type": "uint256" + } + ], + "name": "StoreCore_InvalidStaticDataLength", + "type": "error" + }, { "inputs": [], "name": "StoreCore_NotDynamicField", @@ -142,7 +158,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -167,7 +195,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -210,17 +250,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -260,7 +331,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { @@ -617,7 +698,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreData.abi.json b/packages/world/abi/src/IStore.sol/IStoreData.abi.json index 7b08bc8fda..fbf2f4037c 100644 --- a/packages/world/abi/src/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreData.abi.json @@ -36,7 +36,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -79,17 +91,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -407,7 +450,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreEphemeral.abi.json b/packages/world/abi/src/IStore.sol/IStoreEphemeral.abi.json index c9cbd9770c..cbbd097257 100644 --- a/packages/world/abi/src/IStore.sol/IStoreEphemeral.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreEphemeral.abi.json @@ -17,7 +17,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -38,7 +50,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreHook.abi.json b/packages/world/abi/src/IStore.sol/IStoreHook.abi.json index 171784fcb2..e7c849d916 100644 --- a/packages/world/abi/src/IStore.sol/IStoreHook.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreHook.abi.json @@ -102,7 +102,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json index 301a962b48..47a5fe6fa6 100644 --- a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json @@ -36,7 +36,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -79,17 +91,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", + "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", "type": "bytes32" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" + }, + { + "indexed": false, + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" }, { @@ -228,7 +271,17 @@ }, { "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "internalType": "PackedCounter", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" }, { diff --git a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json index 52eca7ff43..f7d07e59ba 100644 --- a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json @@ -36,7 +36,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -61,7 +73,19 @@ { "indexed": false, "internalType": "bytes", - "name": "data", + "name": "staticData", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "encodedLengths", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "dynamicData", "type": "bytes" } ], @@ -104,17 +128,48 @@ { "indexed": false, "internalType": "bytes32", - "name": "newDynamicLengths", + "name": "encodedLengths", "type": "bytes32" + } + ], + "name": "StoreSpliceDynamicRecord", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes32", + "name": "table", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "bytes32[]", + "name": "key", + "type": "bytes32[]" }, { "indexed": false, - "internalType": "uint256", - "name": "dynamicLengthsStart", - "type": "uint256" + "internalType": "uint48", + "name": "start", + "type": "uint48" + }, + { + "indexed": false, + "internalType": "uint40", + "name": "deleteCount", + "type": "uint40" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "data", + "type": "bytes" } ], - "name": "StoreSpliceRecord", + "name": "StoreSpliceStaticRecord", "type": "event" } ] \ No newline at end of file diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index fce2f6ad72..f46dedfcb3 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -6,6 +6,7 @@ import { IStoreData } from "@latticexyz/store/src/IStore.sol"; import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; import { Bytes } from "@latticexyz/store/src/Bytes.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { System } from "./System.sol"; import { ResourceSelector } from "./ResourceSelector.sol"; @@ -72,12 +73,19 @@ contract World is StoreRead, IStoreData, IWorldKernel { * Write a record in the table at the given tableId. * Requires the caller to have access to the table's namespace or name (encoded in the tableId). */ - function setRecord(bytes32 tableId, bytes32[] calldata key, bytes calldata data, Schema valueSchema) public virtual { + function setRecord( + bytes32 tableId, + bytes32[] calldata key, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, + Schema valueSchema + ) public virtual { // Require access to the namespace or name AccessControl.requireAccess(tableId, msg.sender); // Set the record - StoreCore.setRecord(tableId, key, data, valueSchema); + StoreCore.setRecord(tableId, key, staticData, encodedLengths, dynamicData, valueSchema); } /** diff --git a/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol b/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol index d52278520c..20aacdedf8 100644 --- a/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol +++ b/packages/world/src/modules/core/implementations/EphemeralRecordSystem.sol @@ -3,10 +3,11 @@ pragma solidity >=0.8.0; import { IStoreEphemeral } from "@latticexyz/store/src/IStore.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; +import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { System } from "../../../System.sol"; import { ResourceSelector } from "../../../ResourceSelector.sol"; import { AccessControl } from "../../../AccessControl.sol"; -import { StoreCore } from "@latticexyz/store/src/StoreCore.sol"; contract EphemeralRecordSystem is IStoreEphemeral, System { using ResourceSelector for bytes32; @@ -18,13 +19,15 @@ contract EphemeralRecordSystem is IStoreEphemeral, System { function emitEphemeralRecord( bytes32 resourceSelector, bytes32[] calldata key, - bytes calldata data, + bytes calldata staticData, + PackedCounter encodedLengths, + bytes calldata dynamicData, Schema valueSchema ) public virtual { // Require access to the namespace or name AccessControl.requireAccess(resourceSelector, msg.sender); // Set the record - StoreCore.emitEphemeralRecord(resourceSelector, key, data, valueSchema); + StoreCore.emitEphemeralRecord(resourceSelector, key, staticData, encodedLengths, dynamicData, valueSchema); } } diff --git a/packages/world/src/modules/core/tables/FunctionSelectors.sol b/packages/world/src/modules/core/tables/FunctionSelectors.sol index 7e87cd6ad0..f1c5505d60 100644 --- a/packages/world/src/modules/core/tables/FunctionSelectors.sol +++ b/packages/world/src/modules/core/tables/FunctionSelectors.sol @@ -160,12 +160,15 @@ library FunctionSelectors { /** Set the full data using individual values */ function set(bytes4 functionSelector, bytes32 resourceSelector, bytes4 systemFunctionSelector) internal { - bytes memory _data = encode(resourceSelector, systemFunctionSelector); + bytes memory _staticData = encodeStatic(resourceSelector, systemFunctionSelector); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ @@ -175,12 +178,15 @@ library FunctionSelectors { bytes32 resourceSelector, bytes4 systemFunctionSelector ) internal { - bytes memory _data = encode(resourceSelector, systemFunctionSelector); + bytes memory _staticData = encodeStatic(resourceSelector, systemFunctionSelector); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(functionSelector); - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Decode the tightly packed blob using this table's schema */ @@ -190,9 +196,19 @@ library FunctionSelectors { systemFunctionSelector = (Bytes.slice4(_blob, 32)); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(bytes32 resourceSelector, bytes4 systemFunctionSelector) internal pure returns (bytes memory) { + return abi.encodePacked(resourceSelector, systemFunctionSelector); + } + /** Tightly pack full data using this table's schema */ function encode(bytes32 resourceSelector, bytes4 systemFunctionSelector) internal pure returns (bytes memory) { - return abi.encodePacked(resourceSelector, systemFunctionSelector); + bytes memory _staticData = encodeStatic(resourceSelector, systemFunctionSelector); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/core/tables/ResourceType.sol b/packages/world/src/modules/core/tables/ResourceType.sol index 74bd1179fd..0952807d69 100644 --- a/packages/world/src/modules/core/tables/ResourceType.sol +++ b/packages/world/src/modules/core/tables/ResourceType.sol @@ -96,9 +96,19 @@ library ResourceType { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked(uint8(resourceType)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(Resource resourceType) internal pure returns (bytes memory) { + return abi.encodePacked(resourceType); + } + /** Tightly pack full data using this table's schema */ function encode(Resource resourceType) internal pure returns (bytes memory) { - return abi.encodePacked(resourceType); + bytes memory _staticData = encodeStatic(resourceType); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/core/tables/SystemHooks.sol b/packages/world/src/modules/core/tables/SystemHooks.sol index 0489ccbb7a..91538ed07e 100644 --- a/packages/world/src/modules/core/tables/SystemHooks.sol +++ b/packages/world/src/modules/core/tables/SystemHooks.sol @@ -215,15 +215,26 @@ library SystemHooks { } } - /** Tightly pack full data using this table's schema */ - function encode(address[] memory value) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths(address[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(value.length * 20); } + } + + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(address[] memory value) internal pure returns (bytes memory) { + return abi.encodePacked(EncodeArray.encode((value))); + } + + /** Tightly pack full data using this table's schema */ + function encode(address[] memory value) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(value); + bytes memory _dynamicData = encodeDynamic(value); - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/core/tables/SystemRegistry.sol b/packages/world/src/modules/core/tables/SystemRegistry.sol index f1923a50af..64377edc6f 100644 --- a/packages/world/src/modules/core/tables/SystemRegistry.sol +++ b/packages/world/src/modules/core/tables/SystemRegistry.sol @@ -93,9 +93,19 @@ library SystemRegistry { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((resourceSelector)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(bytes32 resourceSelector) internal pure returns (bytes memory) { + return abi.encodePacked(resourceSelector); + } + /** Tightly pack full data using this table's schema */ function encode(bytes32 resourceSelector) internal pure returns (bytes memory) { - return abi.encodePacked(resourceSelector); + bytes memory _staticData = encodeStatic(resourceSelector); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/core/tables/Systems.sol b/packages/world/src/modules/core/tables/Systems.sol index 9b0c9568e3..05aa000b2c 100644 --- a/packages/world/src/modules/core/tables/Systems.sol +++ b/packages/world/src/modules/core/tables/Systems.sol @@ -149,22 +149,28 @@ library Systems { /** Set the full data using individual values */ function set(bytes32 resourceSelector, address system, bool publicAccess) internal { - bytes memory _data = encode(system, publicAccess); + bytes memory _staticData = encodeStatic(system, publicAccess); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = resourceSelector; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, bytes32 resourceSelector, address system, bool publicAccess) internal { - bytes memory _data = encode(system, publicAccess); + bytes memory _staticData = encodeStatic(system, publicAccess); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = resourceSelector; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Decode the tightly packed blob using this table's schema */ @@ -174,9 +180,19 @@ library Systems { publicAccess = (_toBool(uint8(Bytes.slice1(_blob, 20)))); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(address system, bool publicAccess) internal pure returns (bytes memory) { + return abi.encodePacked(system, publicAccess); + } + /** Tightly pack full data using this table's schema */ function encode(address system, bool publicAccess) internal pure returns (bytes memory) { - return abi.encodePacked(system, publicAccess); + bytes memory _staticData = encodeStatic(system, publicAccess); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/keysintable/KeysInTableHook.sol b/packages/world/src/modules/keysintable/KeysInTableHook.sol index f2c4522de5..80e5ecfed5 100644 --- a/packages/world/src/modules/keysintable/KeysInTableHook.sol +++ b/packages/world/src/modules/keysintable/KeysInTableHook.sol @@ -3,6 +3,7 @@ pragma solidity >=0.8.0; import { IStoreHook } from "@latticexyz/store/src/IStore.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { KeysInTable } from "./tables/KeysInTable.sol"; import { UsedKeysIndex } from "./tables/UsedKeysIndex.sol"; @@ -40,7 +41,7 @@ contract KeysInTableHook is IStoreHook { } } - function onSetRecord(bytes32 table, bytes32[] memory key, bytes memory, Schema) public { + function onSetRecord(bytes32 table, bytes32[] memory key, bytes memory, PackedCounter, bytes memory, Schema) public { handleSet(table, key); } diff --git a/packages/world/src/modules/keysintable/query.sol b/packages/world/src/modules/keysintable/query.sol index 90946bc2c0..53769a113e 100644 --- a/packages/world/src/modules/keysintable/query.sol +++ b/packages/world/src/modules/keysintable/query.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { getKeysInTable } from "./getKeysInTable.sol"; import { getKeysWithValue } from "../keyswithvalue/getKeysWithValue.sol"; @@ -45,7 +46,13 @@ function passesQueryFragment(bytes32[] memory keyTuple, QueryFragment memory fra if (fragment.queryType == QueryType.HasValue) { // Key must have the given value - return ArrayLib.includes(valuesToTuples(getKeysWithValue(fragment.tableId, fragment.value)), keyTuple); + return + ArrayLib.includes( + valuesToTuples( + getKeysWithValue(fragment.tableId, fragment.value, PackedCounter.wrap(bytes32(0)), new bytes(0)) + ), + keyTuple + ); } if (fragment.queryType == QueryType.Not) { @@ -55,7 +62,13 @@ function passesQueryFragment(bytes32[] memory keyTuple, QueryFragment memory fra if (fragment.queryType == QueryType.NotValue) { // Key must not have the given value - return !ArrayLib.includes(valuesToTuples(getKeysWithValue(fragment.tableId, fragment.value)), keyTuple); + return + !ArrayLib.includes( + valuesToTuples( + getKeysWithValue(fragment.tableId, fragment.value, PackedCounter.wrap(bytes32(0)), new bytes(0)) + ), + keyTuple + ); } return false; @@ -78,7 +91,13 @@ function passesQueryFragment( if (fragment.queryType == QueryType.HasValue) { // Key must be have the given value - return ArrayLib.includes(valuesToTuples(getKeysWithValue(store, fragment.tableId, fragment.value)), keyTuple); + return + ArrayLib.includes( + valuesToTuples( + getKeysWithValue(store, fragment.tableId, fragment.value, PackedCounter.wrap(bytes32(0)), new bytes(0)) + ), + keyTuple + ); } if (fragment.queryType == QueryType.Not) { @@ -88,7 +107,13 @@ function passesQueryFragment( if (fragment.queryType == QueryType.NotValue) { // Key must not have the given value - return !ArrayLib.includes(valuesToTuples(getKeysWithValue(store, fragment.tableId, fragment.value)), keyTuple); + return + !ArrayLib.includes( + valuesToTuples( + getKeysWithValue(store, fragment.tableId, fragment.value, PackedCounter.wrap(bytes32(0)), new bytes(0)) + ), + keyTuple + ); } return false; @@ -108,7 +133,9 @@ function query(QueryFragment[] memory fragments) view returns (bytes32[][] memor // Create the first interim result keyTuples = fragments[0].queryType == QueryType.Has ? getKeysInTable(fragments[0].tableId) - : valuesToTuples(getKeysWithValue(fragments[0].tableId, fragments[0].value)); + : valuesToTuples( + getKeysWithValue(fragments[0].tableId, fragments[0].value, PackedCounter.wrap(bytes32(0)), new bytes(0)) + ); for (uint256 i = 1; i < fragments.length; i++) { bytes32[][] memory result = new bytes32[][](0); @@ -143,7 +170,9 @@ function query(IStore store, QueryFragment[] memory fragments) view returns (byt // Create the first interim result keyTuples = fragments[0].queryType == QueryType.Has ? getKeysInTable(store, fragments[0].tableId) - : valuesToTuples(getKeysWithValue(store, fragments[0].tableId, fragments[0].value)); + : valuesToTuples( + getKeysWithValue(store, fragments[0].tableId, fragments[0].value, PackedCounter.wrap(bytes32(0)), new bytes(0)) + ); for (uint256 i = 1; i < fragments.length; i++) { bytes32[][] memory result = new bytes32[][](0); diff --git a/packages/world/src/modules/keysintable/tables/KeysInTable.sol b/packages/world/src/modules/keysintable/tables/KeysInTable.sol index c0a6832e7e..883a913b5d 100644 --- a/packages/world/src/modules/keysintable/tables/KeysInTable.sol +++ b/packages/world/src/modules/keysintable/tables/KeysInTable.sol @@ -882,12 +882,14 @@ library KeysInTable { bytes32[] memory keys3, bytes32[] memory keys4 ) internal { - bytes memory _data = encode(keys0, keys1, keys2, keys3, keys4); + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(keys0, keys1, keys2, keys3, keys4); + bytes memory _dynamicData = encodeDynamic(keys0, keys1, keys2, keys3, keys4); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = sourceTable; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ @@ -900,12 +902,14 @@ library KeysInTable { bytes32[] memory keys3, bytes32[] memory keys4 ) internal { - bytes memory _data = encode(keys0, keys1, keys2, keys3, keys4); + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(keys0, keys1, keys2, keys3, keys4); + bytes memory _dynamicData = encodeDynamic(keys0, keys1, keys2, keys3, keys4); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = sourceTable; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -962,15 +966,14 @@ library KeysInTable { } } - /** Tightly pack full data using this table's schema */ - function encode( + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths( bytes32[] memory keys0, bytes32[] memory keys1, bytes32[] memory keys2, bytes32[] memory keys3, bytes32[] memory keys4 - ) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + ) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack( @@ -981,10 +984,18 @@ library KeysInTable { keys4.length * 32 ); } + } + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic( + bytes32[] memory keys0, + bytes32[] memory keys1, + bytes32[] memory keys2, + bytes32[] memory keys3, + bytes32[] memory keys4 + ) internal pure returns (bytes memory) { return abi.encodePacked( - _encodedLengths.unwrap(), EncodeArray.encode((keys0)), EncodeArray.encode((keys1)), EncodeArray.encode((keys2)), @@ -993,6 +1004,21 @@ library KeysInTable { ); } + /** Tightly pack full data using this table's schema */ + function encode( + bytes32[] memory keys0, + bytes32[] memory keys1, + bytes32[] memory keys2, + bytes32[] memory keys3, + bytes32[] memory keys4 + ) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(keys0, keys1, keys2, keys3, keys4); + bytes memory _dynamicData = encodeDynamic(keys0, keys1, keys2, keys3, keys4); + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } + /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(bytes32 sourceTable) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); diff --git a/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol b/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol index c83423843e..cade80424e 100644 --- a/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol +++ b/packages/world/src/modules/keysintable/tables/UsedKeysIndex.sol @@ -161,24 +161,30 @@ library UsedKeysIndex { /** Set the full data using individual values */ function set(bytes32 sourceTable, bytes32 keysHash, bool has, uint40 index) internal { - bytes memory _data = encode(has, index); + bytes memory _staticData = encodeStatic(has, index); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = sourceTable; _keyTuple[1] = keysHash; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, bytes32 sourceTable, bytes32 keysHash, bool has, uint40 index) internal { - bytes memory _data = encode(has, index); + bytes memory _staticData = encodeStatic(has, index); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = sourceTable; _keyTuple[1] = keysHash; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Decode the tightly packed blob using this table's schema */ @@ -188,9 +194,19 @@ library UsedKeysIndex { index = (uint40(Bytes.slice5(_blob, 1))); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(bool has, uint40 index) internal pure returns (bytes memory) { + return abi.encodePacked(has, index); + } + /** Tightly pack full data using this table's schema */ function encode(bool has, uint40 index) internal pure returns (bytes memory) { - return abi.encodePacked(has, index); + bytes memory _staticData = encodeStatic(has, index); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol index d16f90b2a2..e398519665 100644 --- a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol +++ b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol @@ -5,6 +5,7 @@ import { IStoreHook } from "@latticexyz/store/src/IStore.sol"; import { Bytes } from "@latticexyz/store/src/Bytes.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { IBaseWorld } from "../../interfaces/IBaseWorld.sol"; import { ResourceSelector } from "../../ResourceSelector.sol"; @@ -29,7 +30,14 @@ contract KeysWithValueHook is IStoreHook { return IBaseWorld(StoreSwitch.getStoreAddress()); } - function onSetRecord(bytes32 sourceTableId, bytes32[] memory key, bytes memory data, Schema valueSchema) public { + function onSetRecord( + bytes32 sourceTableId, + bytes32[] memory key, + bytes memory staticData, + PackedCounter encodedLengths, + bytes memory dynamicData, + Schema valueSchema + ) public { bytes32 targetTableId = getTargetTableSelector(MODULE_NAMESPACE, sourceTableId); // Get the previous value @@ -39,6 +47,7 @@ contract KeysWithValueHook is IStoreHook { _removeKeyFromList(targetTableId, key[0], previousValue); // Push the key to the list of keys with the new value + bytes memory data = abi.encodePacked(staticData, encodedLengths, dynamicData); KeysWithValue.push(targetTableId, keccak256(data), key[0]); } diff --git a/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol b/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol index f5e8605c63..945adc2986 100644 --- a/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol +++ b/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol @@ -2,6 +2,7 @@ pragma solidity >=0.8.0; import { IStore } from "@latticexyz/store/src/IStore.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { MODULE_NAMESPACE } from "./constants.sol"; import { KeysWithValue } from "./tables/KeysWithValue.sol"; @@ -13,11 +14,17 @@ import { getTargetTableSelector } from "../utils/getTargetTableSelector.sol"; * Note: this util can only be called within the context of a Store (e.g. from a System or Module). * For usage outside of a Store, use the overload that takes an explicit store argument. */ -function getKeysWithValue(bytes32 tableId, bytes memory value) view returns (bytes32[] memory keysWithValue) { +function getKeysWithValue( + bytes32 tableId, + bytes memory staticData, + PackedCounter encodedLengths, + bytes memory dynamicData +) view returns (bytes32[] memory keysWithValue) { // Get the corresponding reverse mapping table bytes32 keysWithValueTableId = getTargetTableSelector(MODULE_NAMESPACE, tableId); // Get the keys with the given value + bytes memory value = abi.encodePacked(staticData, encodedLengths, dynamicData); keysWithValue = KeysWithValue.get(keysWithValueTableId, keccak256(value)); } @@ -27,11 +34,14 @@ function getKeysWithValue(bytes32 tableId, bytes memory value) view returns (byt function getKeysWithValue( IStore store, bytes32 tableId, - bytes memory value + bytes memory staticData, + PackedCounter encodedLengths, + bytes memory dynamicData ) view returns (bytes32[] memory keysWithValue) { // Get the corresponding reverse mapping table bytes32 keysWithValueTableId = getTargetTableSelector(MODULE_NAMESPACE, tableId); // Get the keys with the given value + bytes memory value = abi.encodePacked(staticData, encodedLengths, dynamicData); keysWithValue = KeysWithValue.get(store, keysWithValueTableId, keccak256(value)); } diff --git a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol index 1f85d91d59..febe34a3c0 100644 --- a/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol +++ b/packages/world/src/modules/keyswithvalue/tables/KeysWithValue.sol @@ -216,15 +216,26 @@ library KeysWithValue { } } - /** Tightly pack full data using this table's schema */ - function encode(bytes32[] memory keysWithValue) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths(bytes32[] memory keysWithValue) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(keysWithValue.length * 32); } + } + + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(bytes32[] memory keysWithValue) internal pure returns (bytes memory) { + return abi.encodePacked(EncodeArray.encode((keysWithValue))); + } + + /** Tightly pack full data using this table's schema */ + function encode(bytes32[] memory keysWithValue) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(keysWithValue); + bytes memory _dynamicData = encodeDynamic(keysWithValue); - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((keysWithValue))); + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol b/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol index 2a0282f97d..fd70697fac 100644 --- a/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol +++ b/packages/world/src/modules/std-delegations/tables/CallboundDelegations.sol @@ -135,9 +135,19 @@ library CallboundDelegations { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((availableCalls)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint256 availableCalls) internal pure returns (bytes memory) { + return abi.encodePacked(availableCalls); + } + /** Tightly pack full data using this table's schema */ function encode(uint256 availableCalls) internal pure returns (bytes memory) { - return abi.encodePacked(availableCalls); + bytes memory _staticData = encodeStatic(availableCalls); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol b/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol index 57df78c17a..4a61b90c2a 100644 --- a/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol +++ b/packages/world/src/modules/std-delegations/tables/TimeboundDelegations.sol @@ -99,9 +99,19 @@ library TimeboundDelegations { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((maxTimestamp)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint256 maxTimestamp) internal pure returns (bytes memory) { + return abi.encodePacked(maxTimestamp); + } + /** Tightly pack full data using this table's schema */ function encode(uint256 maxTimestamp) internal pure returns (bytes memory) { - return abi.encodePacked(maxTimestamp); + bytes memory _staticData = encodeStatic(maxTimestamp); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol b/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol index f7c9cc8fae..8531788fef 100644 --- a/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol +++ b/packages/world/src/modules/uniqueentity/tables/UniqueEntity.sol @@ -84,9 +84,19 @@ library UniqueEntity { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint256 value) internal pure returns (bytes memory) { + return abi.encodePacked(value); + } + /** Tightly pack full data using this table's schema */ function encode(uint256 value) internal pure returns (bytes memory) { - return abi.encodePacked(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/tables/Delegations.sol b/packages/world/src/tables/Delegations.sol index 85c695f526..dccf69adbb 100644 --- a/packages/world/src/tables/Delegations.sol +++ b/packages/world/src/tables/Delegations.sol @@ -103,9 +103,19 @@ library Delegations { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((delegationControlId)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(bytes32 delegationControlId) internal pure returns (bytes memory) { + return abi.encodePacked(delegationControlId); + } + /** Tightly pack full data using this table's schema */ function encode(bytes32 delegationControlId) internal pure returns (bytes memory) { - return abi.encodePacked(delegationControlId); + bytes memory _staticData = encodeStatic(delegationControlId); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/tables/InstalledModules.sol b/packages/world/src/tables/InstalledModules.sol index 6add672ab5..4b6cc32d83 100644 --- a/packages/world/src/tables/InstalledModules.sol +++ b/packages/world/src/tables/InstalledModules.sol @@ -133,24 +133,30 @@ library InstalledModules { /** Set the full data using individual values */ function set(bytes16 moduleName, bytes32 argumentsHash, address moduleAddress) internal { - bytes memory _data = encode(moduleAddress); + bytes memory _staticData = encodeStatic(moduleAddress); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(moduleName); _keyTuple[1] = argumentsHash; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, bytes16 moduleName, bytes32 argumentsHash, address moduleAddress) internal { - bytes memory _data = encode(moduleAddress); + bytes memory _staticData = encodeStatic(moduleAddress); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](2); _keyTuple[0] = bytes32(moduleName); _keyTuple[1] = argumentsHash; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -168,9 +174,19 @@ library InstalledModules { _table.moduleAddress = (address(Bytes.slice20(_blob, 0))); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(address moduleAddress) internal pure returns (bytes memory) { + return abi.encodePacked(moduleAddress); + } + /** Tightly pack full data using this table's schema */ function encode(address moduleAddress) internal pure returns (bytes memory) { - return abi.encodePacked(moduleAddress); + bytes memory _staticData = encodeStatic(moduleAddress); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/tables/NamespaceOwner.sol b/packages/world/src/tables/NamespaceOwner.sol index 4685b734fc..ef81aca803 100644 --- a/packages/world/src/tables/NamespaceOwner.sol +++ b/packages/world/src/tables/NamespaceOwner.sol @@ -93,9 +93,19 @@ library NamespaceOwner { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((owner)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(address owner) internal pure returns (bytes memory) { + return abi.encodePacked(owner); + } + /** Tightly pack full data using this table's schema */ function encode(address owner) internal pure returns (bytes memory) { - return abi.encodePacked(owner); + bytes memory _staticData = encodeStatic(owner); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/tables/ResourceAccess.sol b/packages/world/src/tables/ResourceAccess.sol index 1d2e090231..ac66f0eb4a 100644 --- a/packages/world/src/tables/ResourceAccess.sol +++ b/packages/world/src/tables/ResourceAccess.sol @@ -99,9 +99,19 @@ library ResourceAccess { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((access)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(bool access) internal pure returns (bytes memory) { + return abi.encodePacked(access); + } + /** Tightly pack full data using this table's schema */ function encode(bool access) internal pure returns (bytes memory) { - return abi.encodePacked(access); + bytes memory _staticData = encodeStatic(access); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/test/KeysInTableModule.t.sol b/packages/world/test/KeysInTableModule.t.sol index 1968d14a00..0acd24e286 100644 --- a/packages/world/test/KeysInTableModule.t.sol +++ b/packages/world/test/KeysInTableModule.t.sol @@ -5,6 +5,7 @@ import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { SchemaEncodeHelper } from "@latticexyz/store/test/SchemaEncodeHelper.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; @@ -86,7 +87,14 @@ contract KeysInTableModuleTest is Test, GasReporter { bytes32[] memory keyTuple = new bytes32[](0); - world.setRecord(singletonTableId, keyTuple, abi.encodePacked(val1), tableValueSchema); + world.setRecord( + singletonTableId, + keyTuple, + abi.encodePacked(val1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); // Get the list of keys in this target table bytes32[][] memory keysInTable = getKeysInTable(world, singletonTableId); @@ -103,7 +111,14 @@ contract KeysInTableModuleTest is Test, GasReporter { keyTuple[1] = "two"; keyTuple[2] = "three"; - world.setRecord(compositeTableId, keyTuple, abi.encodePacked(val1), tableValueSchema); + world.setRecord( + compositeTableId, + keyTuple, + abi.encodePacked(val1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); // Get the list of keys in this target table bytes32[][] memory keysInTable = getKeysInTable(world, compositeTableId); @@ -128,7 +143,14 @@ contract KeysInTableModuleTest is Test, GasReporter { _installKeysInTableModule(); // Set a value in the source table startGasReport("set a record on a table with keysInTableModule installed"); - world.setRecord(tableId, keyTuple1, abi.encodePacked(value), tableValueSchema); + world.setRecord( + tableId, + keyTuple1, + abi.encodePacked(value), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); endGasReport(); // Get the list of keys in this target table @@ -147,7 +169,14 @@ contract KeysInTableModuleTest is Test, GasReporter { // Set a value in the source table startGasReport("set a record on a table with keysInTableModule installed (first)"); - world.setRecord(tableId, keyTuple, abi.encodePacked(value1), tableValueSchema); + world.setRecord( + tableId, + keyTuple, + abi.encodePacked(value1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); endGasReport(); // Get the list of keys in the first target table @@ -168,7 +197,14 @@ contract KeysInTableModuleTest is Test, GasReporter { // Set a value in the source table startGasReport("set a record on a table with keysInTableModule installed (second)"); - world.setRecord(sourceTableId2, keyTuple, abi.encodePacked(value2), tableValueSchema); + world.setRecord( + sourceTableId2, + keyTuple, + abi.encodePacked(value2), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); endGasReport(); // Get the list of keys in the second target table @@ -188,7 +224,14 @@ contract KeysInTableModuleTest is Test, GasReporter { _installKeysInTableModule(); // Set a value in the source table - world.setRecord(tableId, keyTuple1, abi.encodePacked(value1), tableValueSchema); + world.setRecord( + tableId, + keyTuple1, + abi.encodePacked(value1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); // Get the list of keys in the target table bytes32[][] memory keysInTable = getKeysInTable(world, tableId); @@ -198,7 +241,14 @@ contract KeysInTableModuleTest is Test, GasReporter { assertEq(keysInTable[0][0], key1, "2"); // Set another key with the same value - world.setRecord(tableId, keyTuple2, abi.encodePacked(value1), tableValueSchema); + world.setRecord( + tableId, + keyTuple2, + abi.encodePacked(value1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); // Get the list of keys in the target table keysInTable = getKeysInTable(world, tableId); @@ -210,7 +260,14 @@ contract KeysInTableModuleTest is Test, GasReporter { // Change the value of the first key startGasReport("change a record on a table with keysInTableModule installed"); - world.setRecord(tableId, keyTuple1, abi.encodePacked(value2), tableValueSchema); + world.setRecord( + tableId, + keyTuple1, + abi.encodePacked(value2), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); endGasReport(); // Get the list of keys in the target table @@ -253,7 +310,14 @@ contract KeysInTableModuleTest is Test, GasReporter { keyTupleB[2] = "charlie"; // Set a value in the source table - world.setRecord(compositeTableId, keyTupleA, abi.encodePacked(value1), tableValueSchema); + world.setRecord( + compositeTableId, + keyTupleA, + abi.encodePacked(value1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); // Get the list of keys in the target table bytes32[][] memory keysInTable = getKeysInTable(world, compositeTableId); @@ -265,7 +329,14 @@ contract KeysInTableModuleTest is Test, GasReporter { } // Set another key with the same value - world.setRecord(compositeTableId, keyTupleB, abi.encodePacked(value1), tableValueSchema); + world.setRecord( + compositeTableId, + keyTupleB, + abi.encodePacked(value1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); // Get the list of keys in the target table keysInTable = getKeysInTable(world, compositeTableId); @@ -281,7 +352,14 @@ contract KeysInTableModuleTest is Test, GasReporter { // Change the value of the first key startGasReport("change a composite record on a table with keysInTableModule installed"); - world.setRecord(compositeTableId, keyTupleA, abi.encodePacked(value2), tableValueSchema); + world.setRecord( + compositeTableId, + keyTupleA, + abi.encodePacked(value2), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); endGasReport(); // Get the list of keys in the target table @@ -343,7 +421,14 @@ contract KeysInTableModuleTest is Test, GasReporter { _installKeysInTableModule(); // Set a value in the source table - world.setRecord(tableId, keyTuple1, abi.encodePacked(value1), tableValueSchema); + world.setRecord( + tableId, + keyTuple1, + abi.encodePacked(value1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); startGasReport("Get list of keys in a given table"); bytes32[][] memory keysInTable = getKeysInTable(world, tableId); @@ -354,7 +439,14 @@ contract KeysInTableModuleTest is Test, GasReporter { assertEq(keysInTable[0][0], key1); // Set another key with a different value - world.setRecord(tableId, keyTuple2, abi.encodePacked(value2), tableValueSchema); + world.setRecord( + tableId, + keyTuple2, + abi.encodePacked(value2), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); // Get the list of keys in the target table keysInTable = getKeysInTable(world, tableId); @@ -369,9 +461,30 @@ contract KeysInTableModuleTest is Test, GasReporter { _installKeysInTableModule(); // Add 3 values - world.setRecord(tableId, keyTuple1, abi.encodePacked(value), tableValueSchema); - world.setRecord(tableId, keyTuple2, abi.encodePacked(value), tableValueSchema); - world.setRecord(tableId, keyTuple3, abi.encodePacked(value), tableValueSchema); + world.setRecord( + tableId, + keyTuple1, + abi.encodePacked(value), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); + world.setRecord( + tableId, + keyTuple2, + abi.encodePacked(value), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); + world.setRecord( + tableId, + keyTuple3, + abi.encodePacked(value), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + tableValueSchema + ); // Remove 2, starting from the middle // This tests that KeysInTable correctly tracks swaps indexes diff --git a/packages/world/test/KeysWithValueModule.t.sol b/packages/world/test/KeysWithValueModule.t.sol index 4e27ae8cc7..9e3879b2fc 100644 --- a/packages/world/test/KeysWithValueModule.t.sol +++ b/packages/world/test/KeysWithValueModule.t.sol @@ -5,6 +5,7 @@ import { Test } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { SchemaEncodeHelper } from "@latticexyz/store/test/SchemaEncodeHelper.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; @@ -68,11 +69,22 @@ contract KeysWithValueModuleTest is Test, GasReporter { uint256 value = 1; startGasReport("set a record on a table with KeysWithValueModule installed"); - world.setRecord(sourceTableId, keyTuple1, abi.encodePacked(value), sourceTableSchema); + world.setRecord( + sourceTableId, + keyTuple1, + abi.encodePacked(value), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + sourceTableSchema + ); endGasReport(); // Get the list of entities with this value from the target table - bytes32[] memory keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value))); + bytes32[] memory keysWithValue = KeysWithValue.get( + world, + targetTableId, + keccak256(abi.encodePacked(value, PackedCounter.wrap(bytes32(0)), new bytes(0))) + ); // Assert that the list is correct assertEq(keysWithValue.length, 1); @@ -85,20 +97,42 @@ contract KeysWithValueModuleTest is Test, GasReporter { // Set a value in the source table uint256 value1 = 1; - world.setRecord(sourceTableId, keyTuple1, abi.encodePacked(value1), sourceTableSchema); + world.setRecord( + sourceTableId, + keyTuple1, + abi.encodePacked(value1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + sourceTableSchema + ); // Get the list of entities with value1 from the target table - bytes32[] memory keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); + bytes32[] memory keysWithValue = KeysWithValue.get( + world, + targetTableId, + keccak256(abi.encodePacked(value1, PackedCounter.wrap(bytes32(0)), new bytes(0))) + ); // Assert that the list is correct assertEq(keysWithValue.length, 1, "1"); assertEq(keysWithValue[0], key1, "2"); // Set a another key with the same value - world.setRecord(sourceTableId, keyTuple2, abi.encodePacked(value1), sourceTableSchema); + world.setRecord( + sourceTableId, + keyTuple2, + abi.encodePacked(value1), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + sourceTableSchema + ); // Get the list of entities with value2 from the target table - keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); + keysWithValue = KeysWithValue.get( + world, + targetTableId, + keccak256(abi.encodePacked(value1, PackedCounter.wrap(bytes32(0)), new bytes(0))) + ); // Assert that the list is correct assertEq(keysWithValue.length, 2); @@ -109,18 +143,33 @@ contract KeysWithValueModuleTest is Test, GasReporter { uint256 value2 = 2; startGasReport("change a record on a table with KeysWithValueModule installed"); - world.setRecord(sourceTableId, keyTuple1, abi.encodePacked(value2), sourceTableSchema); + world.setRecord( + sourceTableId, + keyTuple1, + abi.encodePacked(value2), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + sourceTableSchema + ); endGasReport(); // Get the list of entities with value1 from the target table - keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value1))); + keysWithValue = KeysWithValue.get( + world, + targetTableId, + keccak256(abi.encodePacked(value1, PackedCounter.wrap(bytes32(0)), new bytes(0))) + ); // Assert that the list is correct - assertEq(keysWithValue.length, 1, "5"); + assertEq(keysWithValue.length, 2, "5"); assertEq(keysWithValue[0], key2, "6"); // Get the list of entities with value2 from the target table - keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value2))); + keysWithValue = KeysWithValue.get( + world, + targetTableId, + keccak256(abi.encodePacked(value2, PackedCounter.wrap(bytes32(0)), new bytes(0))) + ); // Assert that the list is correct assertEq(keysWithValue.length, 1, "7"); @@ -132,10 +181,14 @@ contract KeysWithValueModuleTest is Test, GasReporter { endGasReport(); // Get the list of entities with value2 from the target table - keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encode(value2))); + keysWithValue = KeysWithValue.get( + world, + targetTableId, + keccak256(abi.encodePacked(value2, PackedCounter.wrap(bytes32(0)), new bytes(0))) + ); // Assert that the list is correct - assertEq(keysWithValue.length, 0, "9"); + assertEq(keysWithValue.length, 1, "9"); } function testSetField() public { @@ -200,10 +253,23 @@ contract KeysWithValueModuleTest is Test, GasReporter { _installKeysWithValueModule(); // Set a value in the source table - world.setRecord(sourceTableId, keyTuple1, abi.encodePacked(value), sourceTableSchema); + world.setRecord( + sourceTableId, + keyTuple1, + abi.encodePacked(value), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + sourceTableSchema + ); startGasReport("Get list of keys with a given value"); - bytes32[] memory keysWithValue = getKeysWithValue(world, sourceTableId, abi.encode(value)); + bytes32[] memory keysWithValue = getKeysWithValue( + world, + sourceTableId, + abi.encodePacked(value), + PackedCounter.wrap(bytes32(0)), + new bytes(0) + ); endGasReport(); // Assert that the list is correct @@ -211,10 +277,23 @@ contract KeysWithValueModuleTest is Test, GasReporter { assertEq(keysWithValue[0], key1); // Set a another key with the same value - world.setRecord(sourceTableId, keyTuple2, abi.encodePacked(value), sourceTableSchema); + world.setRecord( + sourceTableId, + keyTuple2, + abi.encodePacked(value), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + sourceTableSchema + ); // Get the list of keys with value from the target table - keysWithValue = getKeysWithValue(world, sourceTableId, abi.encode(value)); + keysWithValue = getKeysWithValue( + world, + sourceTableId, + abi.encodePacked(value), + PackedCounter.wrap(bytes32(0)), + new bytes(0) + ); // Assert that the list is correct assertEq(keysWithValue.length, 2); diff --git a/packages/world/test/World.t.sol b/packages/world/test/World.t.sol index 5044a3f4d5..4379388c75 100644 --- a/packages/world/test/World.t.sol +++ b/packages/world/test/World.t.sol @@ -12,6 +12,7 @@ import { StoreSwitch } from "@latticexyz/store/src/StoreSwitch.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; import { SchemaEncodeHelper } from "@latticexyz/store/test/SchemaEncodeHelper.sol"; import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { Tables, TablesTableId } from "@latticexyz/store/src/codegen/Tables.sol"; import { EncodeArray } from "@latticexyz/store/src/tightcoder/EncodeArray.sol"; @@ -81,9 +82,23 @@ contract WorldTestSystem is System { Schema valueSchema = StoreSwitch.getValueSchema(tableId); if (StoreSwitch.getStoreAddress() == address(this)) { - StoreCore.setRecord(tableId, key, abi.encodePacked(data), valueSchema); + StoreCore.setRecord( + tableId, + key, + abi.encodePacked(data), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + valueSchema + ); } else { - IBaseWorld(msg.sender).setRecord(tableId, key, abi.encodePacked(data), valueSchema); + IBaseWorld(msg.sender).setRecord( + tableId, + key, + abi.encodePacked(data), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + valueSchema + ); } } @@ -109,8 +124,15 @@ contract PayableFallbackSystem is System { contract WorldTestTableHook is IStoreHook { event HookCalled(bytes data); - function onSetRecord(bytes32 table, bytes32[] memory key, bytes memory data, Schema valueSchema) public { - emit HookCalled(abi.encode(table, key, data, valueSchema)); + function onSetRecord( + bytes32 table, + bytes32[] memory key, + bytes memory staticData, + PackedCounter encodedLengths, + bytes memory dynamicData, + Schema valueSchema + ) public { + emit HookCalled(abi.encode(table, key, staticData, encodedLengths, dynamicData, valueSchema)); } function onBeforeSetField( @@ -512,7 +534,14 @@ contract WorldTest is Test, GasReporter { world.registerTable(tableId, defaultKeySchema, valueSchema, new string[](1), new string[](1)); // Write data to the table via the namespace and expect it to be written - world.setRecord(tableId, singletonKey, abi.encodePacked(true), valueSchema); + world.setRecord( + tableId, + singletonKey, + abi.encodePacked(true), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + valueSchema + ); assertTrue(Bool.get(world, tableId)); startGasReport("Delete record"); @@ -523,7 +552,14 @@ contract WorldTest is Test, GasReporter { assertFalse(Bool.get(world, tableId)); // Write data to the table via the namespace and expect it to be written - world.setRecord(tableId, singletonKey, abi.encodePacked(true), valueSchema); + world.setRecord( + tableId, + singletonKey, + abi.encodePacked(true), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + valueSchema + ); assertTrue(Bool.get(world, tableId)); // Delete the record via the tableId and expect it to be deleted @@ -531,7 +567,14 @@ contract WorldTest is Test, GasReporter { assertFalse(Bool.get(world, tableId)); // Write data to the table via the namespace and expect it to be written - world.setRecord(tableId, singletonKey, abi.encodePacked(true), valueSchema); + world.setRecord( + tableId, + singletonKey, + abi.encodePacked(true), + PackedCounter.wrap(bytes32(0)), + new bytes(0), + valueSchema + ); assertTrue(Bool.get(world, tableId)); // Expect an error when trying to delete from an address that doesn't have access @@ -684,12 +727,12 @@ contract WorldTest is Test, GasReporter { world.registerStoreHook(tableId, tableHook); // Prepare data to write to the table - bytes memory value = abi.encodePacked(true); + bytes memory staticData = abi.encodePacked(true); // Expect the hook to be notified when a record is written vm.expectEmit(true, true, true, true); - emit HookCalled(abi.encode(tableId, singletonKey, value, valueSchema)); - world.setRecord(tableId, singletonKey, value, valueSchema); + emit HookCalled(abi.encode(tableId, singletonKey, staticData, bytes32(0), new bytes(0), valueSchema)); + world.setRecord(tableId, singletonKey, staticData, PackedCounter.wrap(bytes32(0)), new bytes(0), valueSchema); // TODO: add tests for other hook methods (onBeforeSetField, onAfterSetField, onDeleteRecord) // (See https://github.com/latticexyz/mud/issues/444) diff --git a/packages/world/test/query.t.sol b/packages/world/test/query.t.sol index 7f061dcd1f..e16f28039d 100644 --- a/packages/world/test/query.t.sol +++ b/packages/world/test/query.t.sol @@ -6,6 +6,7 @@ import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; import { SchemaEncodeHelper } from "@latticexyz/store/test/SchemaEncodeHelper.sol"; +import { PackedCounter } from "@latticexyz/store/src/PackedCounter.sol"; import { SchemaType } from "@latticexyz/schema-type/src/solidity/SchemaType.sol"; import { World } from "../src/World.sol"; @@ -86,9 +87,9 @@ contract QueryTest is Test, GasReporter { function testHasQuery() public { _installKeysInTableModule(); - world.setRecord(table1, key1, abi.encode(1), tableValueSchema); - world.setRecord(table1, key2, abi.encode(1), tableValueSchema); - world.setRecord(table2, key1, abi.encode(0), tableValueSchema); + world.setRecord(table1, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key1, abi.encode(0), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all keys in table1 QueryFragment[] memory fragments = new QueryFragment[](1); @@ -107,9 +108,9 @@ contract QueryTest is Test, GasReporter { _installKeysInTableModule(); _installKeysWithValueModule(); - world.setRecord(table1, key1, abi.encode(2), tableValueSchema); - world.setRecord(table1, key2, abi.encode(1), tableValueSchema); - world.setRecord(table1, key3, abi.encode(1), tableValueSchema); + world.setRecord(table1, key1, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // 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)); @@ -125,12 +126,12 @@ contract QueryTest is Test, GasReporter { function testCombinedHasQuery() public { _installKeysInTableModule(); - world.setRecord(table1, key1, abi.encode(2), tableValueSchema); - world.setRecord(table1, key2, abi.encode(1), tableValueSchema); - world.setRecord(table1, key3, abi.encode(1), tableValueSchema); - world.setRecord(table2, key2, abi.encode(1), tableValueSchema); - world.setRecord(table2, key3, abi.encode(1), tableValueSchema); - world.setRecord(table3, key1, abi.encode(1), tableValueSchema); + world.setRecord(table1, key1, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table3, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all entities that have table1 and table2 QueryFragment[] memory fragments = new QueryFragment[](2); @@ -149,12 +150,12 @@ contract QueryTest is Test, GasReporter { _installKeysInTableModule(); _installKeysWithValueModule(); - world.setRecord(table1, key1, abi.encode(2), tableValueSchema); - world.setRecord(table1, key2, abi.encode(2), tableValueSchema); - world.setRecord(table1, key3, abi.encode(1), tableValueSchema); - world.setRecord(table2, key2, abi.encode(1), tableValueSchema); - world.setRecord(table2, key3, abi.encode(1), tableValueSchema); - world.setRecord(table3, key1, abi.encode(1), tableValueSchema); + world.setRecord(table1, key1, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key2, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table3, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all entities that have table1 and table2 QueryFragment[] memory fragments = new QueryFragment[](2); @@ -172,13 +173,13 @@ contract QueryTest is Test, GasReporter { _installKeysInTableModule(); _installKeysWithValueModule(); - world.setRecord(table1, key1, abi.encode(1), tableValueSchema); - world.setRecord(table1, key2, abi.encode(1), tableValueSchema); - world.setRecord(table1, key3, abi.encode(1), tableValueSchema); - world.setRecord(table2, key1, abi.encode(1), tableValueSchema); - world.setRecord(table2, key2, abi.encode(2), tableValueSchema); - world.setRecord(table2, key3, abi.encode(2), tableValueSchema); - world.setRecord(table2, key4, abi.encode(2), tableValueSchema); + world.setRecord(table1, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key2, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key3, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key4, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all entities that have table1 and table2 QueryFragment[] memory fragments = new QueryFragment[](2); @@ -196,13 +197,13 @@ contract QueryTest is Test, GasReporter { function testCombinedHasNotQuery() public { _installKeysInTableModule(); - world.setRecord(table1, key1, abi.encode(1), tableValueSchema); - world.setRecord(table1, key2, abi.encode(1), tableValueSchema); - world.setRecord(table1, key3, abi.encode(1), tableValueSchema); - world.setRecord(table2, key1, abi.encode(1), tableValueSchema); - world.setRecord(table2, key2, abi.encode(2), tableValueSchema); - world.setRecord(table2, key3, abi.encode(2), tableValueSchema); - world.setRecord(table2, key4, abi.encode(2), tableValueSchema); + world.setRecord(table1, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key2, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key3, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key4, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all entities that have table1 and table2 QueryFragment[] memory fragments = new QueryFragment[](2); @@ -220,13 +221,13 @@ contract QueryTest is Test, GasReporter { _installKeysInTableModule(); _installKeysWithValueModule(); - world.setRecord(table1, key1, abi.encode(1), tableValueSchema); - world.setRecord(table1, key2, abi.encode(1), tableValueSchema); - world.setRecord(table1, key3, abi.encode(1), tableValueSchema); - world.setRecord(table2, key1, abi.encode(1), tableValueSchema); - world.setRecord(table2, key2, abi.encode(2), tableValueSchema); - world.setRecord(table2, key3, abi.encode(1), tableValueSchema); - world.setRecord(table2, key4, abi.encode(1), tableValueSchema); + world.setRecord(table1, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key2, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key4, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all entities that have table1 and table2 QueryFragment[] memory fragments = new QueryFragment[](2); @@ -244,16 +245,16 @@ contract QueryTest is Test, GasReporter { _installKeysInTableModule(); _installKeysWithValueModule(); - world.setRecord(table1, key1, abi.encode(1), tableValueSchema); - world.setRecord(table1, key2, abi.encode(1), tableValueSchema); - world.setRecord(table1, key3, abi.encode(1), tableValueSchema); - world.setRecord(table2, key1, abi.encode(1), tableValueSchema); - world.setRecord(table2, key2, abi.encode(2), tableValueSchema); - world.setRecord(table2, key3, abi.encode(1), tableValueSchema); - world.setRecord(table2, key4, abi.encode(1), tableValueSchema); - world.setRecord(table3, key2, abi.encode(1), tableValueSchema); - world.setRecord(table3, key3, abi.encode(1), tableValueSchema); - world.setRecord(table3, key4, abi.encode(1), tableValueSchema); + world.setRecord(table1, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key1, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key2, abi.encode(2), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table2, key4, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table3, key2, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table3, key3, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table3, key4, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all entities that have table2 and not table1 QueryFragment[] memory fragments = new QueryFragment[](3); @@ -272,9 +273,9 @@ contract QueryTest is Test, GasReporter { _installKeysInTableModule(); _installKeysWithValueModule(); - world.setRecord(table1, key1, abi.encode(4), tableValueSchema); - world.setRecord(table1, key2, abi.encode(5), tableValueSchema); - world.setRecord(table1, key3, abi.encode(6), tableValueSchema); + world.setRecord(table1, key1, abi.encode(4), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key2, abi.encode(5), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); + world.setRecord(table1, key3, abi.encode(6), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all entities with table1 except value 6 QueryFragment[] memory fragments = new QueryFragment[](2); @@ -295,9 +296,9 @@ contract QueryTest is Test, GasReporter { for (uint256 i; i < 100; i++) { bytes32[] memory key = new bytes32[](1); key[0] = bytes32(i); - world.setRecord(table1, key, abi.encode(1), tableValueSchema); + world.setRecord(table1, key, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); } - world.setRecord(table2, key1, abi.encode(0), tableValueSchema); + world.setRecord(table2, key1, abi.encode(0), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all keys in table1 QueryFragment[] memory fragments = new QueryFragment[](1); @@ -316,9 +317,9 @@ contract QueryTest is Test, GasReporter { for (uint256 i; i < 1000; i++) { bytes32[] memory key = new bytes32[](1); key[0] = bytes32(i); - world.setRecord(table1, key, abi.encode(1), tableValueSchema); + world.setRecord(table1, key, abi.encode(1), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); } - world.setRecord(table2, key1, abi.encode(0), tableValueSchema); + world.setRecord(table2, key1, abi.encode(0), PackedCounter.wrap(bytes32(0)), new bytes(0), tableValueSchema); // Query should return all keys in table1 QueryFragment[] memory fragments = new QueryFragment[](1); diff --git a/packages/world/test/tables/AddressArray.sol b/packages/world/test/tables/AddressArray.sol index e17350eaac..ef3c83b4ff 100644 --- a/packages/world/test/tables/AddressArray.sol +++ b/packages/world/test/tables/AddressArray.sol @@ -212,15 +212,26 @@ library AddressArray { } } - /** Tightly pack full data using this table's schema */ - function encode(address[] memory value) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths(address[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(value.length * 20); } + } + + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(address[] memory value) internal pure returns (bytes memory) { + return abi.encodePacked(EncodeArray.encode((value))); + } + + /** Tightly pack full data using this table's schema */ + function encode(address[] memory value) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(value); + bytes memory _dynamicData = encodeDynamic(value); - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/test/tables/Bool.sol b/packages/world/test/tables/Bool.sol index 828eb8bb45..76e3703f40 100644 --- a/packages/world/test/tables/Bool.sol +++ b/packages/world/test/tables/Bool.sol @@ -84,9 +84,19 @@ library Bool { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(bool value) internal pure returns (bytes memory) { + return abi.encodePacked(value); + } + /** Tightly pack full data using this table's schema */ function encode(bool value) internal pure returns (bytes memory) { - return abi.encodePacked(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ From e7db2a11809abe9e9b110c9dbaa16902a67ec2f0 Mon Sep 17 00:00:00 2001 From: dk1a Date: Sun, 10 Sep 2023 17:56:36 +0300 Subject: [PATCH 25/69] fix keyswithvalue --- .../src/codegen/tables/Dynamics1.sol | 44 ++++++++++++---- .../src/codegen/tables/Dynamics2.sol | 35 ++++++++++--- .../src/codegen/tables/Ephemeral.sol | 12 ++++- .../src/codegen/tables/Singleton.sol | 51 +++++++++++++++---- .../contracts/src/codegen/tables/Statics.sol | 34 +++++++++++-- .../keyswithvalue/KeysWithValueHook.sol | 7 ++- .../keyswithvalue/getKeysWithValue.sol | 14 ++++- packages/world/test/KeysWithValueModule.t.sol | 42 ++++----------- 8 files changed, 169 insertions(+), 70 deletions(-) diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol index 49b381771c..ee21f1e3c3 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics1.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics1.sol @@ -910,12 +910,14 @@ library Dynamics1 { address[4] memory staticAddrs, bool[5] memory staticBools ) internal { - bytes memory _data = encode(staticB32, staticI32, staticU128, staticAddrs, staticBools); + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(staticB32, staticI32, staticU128, staticAddrs, staticBools); + bytes memory _dynamicData = encodeDynamic(staticB32, staticI32, staticU128, staticAddrs, staticBools); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ @@ -928,12 +930,14 @@ library Dynamics1 { address[4] memory staticAddrs, bool[5] memory staticBools ) internal { - bytes memory _data = encode(staticB32, staticI32, staticU128, staticAddrs, staticBools); + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(staticB32, staticI32, staticU128, staticAddrs, staticBools); + bytes memory _dynamicData = encodeDynamic(staticB32, staticI32, staticU128, staticAddrs, staticBools); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -990,15 +994,14 @@ library Dynamics1 { } } - /** Tightly pack full data using this table's schema */ - function encode( + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths( bytes32[1] memory staticB32, int32[2] memory staticI32, uint128[3] memory staticU128, address[4] memory staticAddrs, bool[5] memory staticBools - ) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + ) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack( @@ -1009,10 +1012,18 @@ library Dynamics1 { staticBools.length * 1 ); } + } + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic( + bytes32[1] memory staticB32, + int32[2] memory staticI32, + uint128[3] memory staticU128, + address[4] memory staticAddrs, + bool[5] memory staticBools + ) internal pure returns (bytes memory) { return abi.encodePacked( - _encodedLengths.unwrap(), EncodeArray.encode(fromStaticArray_bytes32_1(staticB32)), EncodeArray.encode(fromStaticArray_int32_2(staticI32)), EncodeArray.encode(fromStaticArray_uint128_3(staticU128)), @@ -1021,6 +1032,21 @@ library Dynamics1 { ); } + /** Tightly pack full data using this table's schema */ + function encode( + bytes32[1] memory staticB32, + int32[2] memory staticI32, + uint128[3] memory staticU128, + address[4] memory staticAddrs, + bool[5] memory staticBools + ) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(staticB32, staticI32, staticU128, staticAddrs, staticBools); + bytes memory _dynamicData = encodeDynamic(staticB32, staticI32, staticU128, staticAddrs, staticBools); + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } + /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple(bytes32 key) internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](1); diff --git a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol index 79272c9e40..f38b655add 100644 --- a/packages/cli/contracts/src/codegen/tables/Dynamics2.sol +++ b/packages/cli/contracts/src/codegen/tables/Dynamics2.sol @@ -536,22 +536,26 @@ library Dynamics2 { /** Set the full data using individual values */ function set(bytes32 key, uint64[] memory u64, string memory str, bytes memory b) internal { - bytes memory _data = encode(u64, str, b); + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(u64, str, b); + bytes memory _dynamicData = encodeDynamic(u64, str, b); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, bytes32 key, uint64[] memory u64, string memory str, bytes memory b) internal { - bytes memory _data = encode(u64, str, b); + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(u64, str, b); + bytes memory _dynamicData = encodeDynamic(u64, str, b); bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -596,15 +600,30 @@ library Dynamics2 { } } - /** Tightly pack full data using this table's schema */ - function encode(uint64[] memory u64, string memory str, bytes memory b) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths( + uint64[] memory u64, + string memory str, + bytes memory b + ) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(u64.length * 8, bytes(str).length, bytes(b).length); } + } + + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(uint64[] memory u64, string memory str, bytes memory b) internal pure returns (bytes memory) { + return abi.encodePacked(EncodeArray.encode((u64)), bytes((str)), bytes((b))); + } + + /** Tightly pack full data using this table's schema */ + function encode(uint64[] memory u64, string memory str, bytes memory b) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(u64, str, b); + bytes memory _dynamicData = encodeDynamic(u64, str, b); - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((u64)), bytes((str)), bytes((b))); + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/cli/contracts/src/codegen/tables/Ephemeral.sol b/packages/cli/contracts/src/codegen/tables/Ephemeral.sol index 16f69fc94b..294bd45999 100644 --- a/packages/cli/contracts/src/codegen/tables/Ephemeral.sol +++ b/packages/cli/contracts/src/codegen/tables/Ephemeral.sol @@ -79,9 +79,19 @@ library Ephemeral { _store.emitEphemeralRecord(_tableId, _keyTuple, _data, getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint256 value) internal pure returns (bytes memory) { + return abi.encodePacked(value); + } + /** Tightly pack full data using this table's schema */ function encode(uint256 value) internal pure returns (bytes memory) { - return abi.encodePacked(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/cli/contracts/src/codegen/tables/Singleton.sol b/packages/cli/contracts/src/codegen/tables/Singleton.sol index f3632fbf3d..6a1322833f 100644 --- a/packages/cli/contracts/src/codegen/tables/Singleton.sol +++ b/packages/cli/contracts/src/codegen/tables/Singleton.sol @@ -518,20 +518,26 @@ library Singleton { /** Set the full data using individual values */ function set(int256 v1, uint32[2] memory v2, uint32[2] memory v3, uint32[1] memory v4) internal { - bytes memory _data = encode(v1, v2, v3, v4); + bytes memory _staticData = encodeStatic(v1); + + PackedCounter _encodedLengths = encodeLengths(v2, v3, v4); + bytes memory _dynamicData = encodeDynamic(v2, v3, v4); bytes32[] memory _keyTuple = new bytes32[](0); - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, int256 v1, uint32[2] memory v2, uint32[2] memory v3, uint32[1] memory v4) internal { - bytes memory _data = encode(v1, v2, v3, v4); + bytes memory _staticData = encodeStatic(v1); + + PackedCounter _encodedLengths = encodeLengths(v2, v3, v4); + bytes memory _dynamicData = encodeDynamic(v2, v3, v4); bytes32[] memory _keyTuple = new bytes32[](0); - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** @@ -570,29 +576,52 @@ library Singleton { } } - /** Tightly pack full data using this table's schema */ - function encode( - int256 v1, + /** Tightly pack static data using this table's schema */ + function encodeStatic(int256 v1) internal pure returns (bytes memory) { + return abi.encodePacked(v1); + } + + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths( uint32[2] memory v2, uint32[2] memory v3, uint32[1] memory v4 - ) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + ) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(v2.length * 4, v3.length * 4, v4.length * 4); } + } + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic( + uint32[2] memory v2, + uint32[2] memory v3, + uint32[1] memory v4 + ) internal pure returns (bytes memory) { return abi.encodePacked( - v1, - _encodedLengths.unwrap(), EncodeArray.encode(fromStaticArray_uint32_2(v2)), EncodeArray.encode(fromStaticArray_uint32_2(v3)), EncodeArray.encode(fromStaticArray_uint32_1(v4)) ); } + /** Tightly pack full data using this table's schema */ + function encode( + int256 v1, + uint32[2] memory v2, + uint32[2] memory v3, + uint32[1] memory v4 + ) internal pure returns (bytes memory) { + bytes memory _staticData = encodeStatic(v1); + + PackedCounter _encodedLengths = encodeLengths(v2, v3, v4); + bytes memory _dynamicData = encodeDynamic(v2, v3, v4); + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); + } + /** Encode keys as a bytes32 array using this table's schema */ function encodeKeyTuple() internal pure returns (bytes32[] memory) { bytes32[] memory _keyTuple = new bytes32[](0); diff --git a/packages/cli/contracts/src/codegen/tables/Statics.sol b/packages/cli/contracts/src/codegen/tables/Statics.sol index c4356780c3..203644f1d1 100644 --- a/packages/cli/contracts/src/codegen/tables/Statics.sol +++ b/packages/cli/contracts/src/codegen/tables/Statics.sol @@ -755,7 +755,10 @@ library Statics { Enum1 v6, Enum2 v7 ) internal { - bytes memory _data = encode(v1, v2, v3, v4, v5, v6, v7); + bytes memory _staticData = encodeStatic(v1, v2, v3, v4, v5, v6, v7); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](7); _keyTuple[0] = bytes32(uint256(k1)); @@ -766,7 +769,7 @@ library Statics { _keyTuple[5] = bytes32(uint256(uint8(k6))); _keyTuple[6] = bytes32(uint256(uint8(k7))); - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ @@ -787,7 +790,10 @@ library Statics { Enum1 v6, Enum2 v7 ) internal { - bytes memory _data = encode(v1, v2, v3, v4, v5, v6, v7); + bytes memory _staticData = encodeStatic(v1, v2, v3, v4, v5, v6, v7); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](7); _keyTuple[0] = bytes32(uint256(k1)); @@ -798,7 +804,7 @@ library Statics { _keyTuple[5] = bytes32(uint256(uint8(k6))); _keyTuple[6] = bytes32(uint256(uint8(k7))); - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -863,6 +869,19 @@ library Statics { _table.v7 = Enum2(uint8(Bytes.slice1(_blob, 74))); } + /** Tightly pack static data using this table's schema */ + function encodeStatic( + uint256 v1, + int32 v2, + bytes16 v3, + address v4, + bool v5, + Enum1 v6, + Enum2 v7 + ) internal pure returns (bytes memory) { + return abi.encodePacked(v1, v2, v3, v4, v5, v6, v7); + } + /** Tightly pack full data using this table's schema */ function encode( uint256 v1, @@ -873,7 +892,12 @@ library Statics { Enum1 v6, Enum2 v7 ) internal pure returns (bytes memory) { - return abi.encodePacked(v1, v2, v3, v4, v5, v6, v7); + bytes memory _staticData = encodeStatic(v1, v2, v3, v4, v5, v6, v7); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol index e398519665..271414feea 100644 --- a/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol +++ b/packages/world/src/modules/keyswithvalue/KeysWithValueHook.sol @@ -47,7 +47,12 @@ contract KeysWithValueHook is IStoreHook { _removeKeyFromList(targetTableId, key[0], previousValue); // Push the key to the list of keys with the new value - bytes memory data = abi.encodePacked(staticData, encodedLengths, dynamicData); + bytes memory data; + if (dynamicData.length > 0) { + data = abi.encodePacked(staticData, encodedLengths, dynamicData); + } else { + data = staticData; + } KeysWithValue.push(targetTableId, keccak256(data), key[0]); } diff --git a/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol b/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol index 945adc2986..e47fba0d10 100644 --- a/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol +++ b/packages/world/src/modules/keyswithvalue/getKeysWithValue.sol @@ -24,7 +24,12 @@ function getKeysWithValue( bytes32 keysWithValueTableId = getTargetTableSelector(MODULE_NAMESPACE, tableId); // Get the keys with the given value - bytes memory value = abi.encodePacked(staticData, encodedLengths, dynamicData); + bytes memory value; + if (dynamicData.length > 0) { + value = abi.encodePacked(staticData, encodedLengths, dynamicData); + } else { + value = staticData; + } keysWithValue = KeysWithValue.get(keysWithValueTableId, keccak256(value)); } @@ -42,6 +47,11 @@ function getKeysWithValue( bytes32 keysWithValueTableId = getTargetTableSelector(MODULE_NAMESPACE, tableId); // Get the keys with the given value - bytes memory value = abi.encodePacked(staticData, encodedLengths, dynamicData); + bytes memory value; + if (dynamicData.length > 0) { + value = abi.encodePacked(staticData, encodedLengths, dynamicData); + } else { + value = staticData; + } keysWithValue = KeysWithValue.get(store, keysWithValueTableId, keccak256(value)); } diff --git a/packages/world/test/KeysWithValueModule.t.sol b/packages/world/test/KeysWithValueModule.t.sol index 9e3879b2fc..7bda9fd688 100644 --- a/packages/world/test/KeysWithValueModule.t.sol +++ b/packages/world/test/KeysWithValueModule.t.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT pragma solidity >=0.8.0; -import { Test } from "forge-std/Test.sol"; +import { Test, console } from "forge-std/Test.sol"; import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { Schema } from "@latticexyz/store/src/Schema.sol"; @@ -80,11 +80,7 @@ contract KeysWithValueModuleTest is Test, GasReporter { endGasReport(); // Get the list of entities with this value from the target table - bytes32[] memory keysWithValue = KeysWithValue.get( - world, - targetTableId, - keccak256(abi.encodePacked(value, PackedCounter.wrap(bytes32(0)), new bytes(0))) - ); + bytes32[] memory keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encodePacked(value))); // Assert that the list is correct assertEq(keysWithValue.length, 1); @@ -107,11 +103,7 @@ contract KeysWithValueModuleTest is Test, GasReporter { ); // Get the list of entities with value1 from the target table - bytes32[] memory keysWithValue = KeysWithValue.get( - world, - targetTableId, - keccak256(abi.encodePacked(value1, PackedCounter.wrap(bytes32(0)), new bytes(0))) - ); + bytes32[] memory keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encodePacked(value1))); // Assert that the list is correct assertEq(keysWithValue.length, 1, "1"); @@ -128,11 +120,7 @@ contract KeysWithValueModuleTest is Test, GasReporter { ); // Get the list of entities with value2 from the target table - keysWithValue = KeysWithValue.get( - world, - targetTableId, - keccak256(abi.encodePacked(value1, PackedCounter.wrap(bytes32(0)), new bytes(0))) - ); + keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encodePacked(value1))); // Assert that the list is correct assertEq(keysWithValue.length, 2); @@ -154,22 +142,14 @@ contract KeysWithValueModuleTest is Test, GasReporter { endGasReport(); // Get the list of entities with value1 from the target table - keysWithValue = KeysWithValue.get( - world, - targetTableId, - keccak256(abi.encodePacked(value1, PackedCounter.wrap(bytes32(0)), new bytes(0))) - ); + keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encodePacked(value1))); // Assert that the list is correct - assertEq(keysWithValue.length, 2, "5"); + assertEq(keysWithValue.length, 1, "5"); assertEq(keysWithValue[0], key2, "6"); // Get the list of entities with value2 from the target table - keysWithValue = KeysWithValue.get( - world, - targetTableId, - keccak256(abi.encodePacked(value2, PackedCounter.wrap(bytes32(0)), new bytes(0))) - ); + keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encodePacked(value2))); // Assert that the list is correct assertEq(keysWithValue.length, 1, "7"); @@ -181,14 +161,10 @@ contract KeysWithValueModuleTest is Test, GasReporter { endGasReport(); // Get the list of entities with value2 from the target table - keysWithValue = KeysWithValue.get( - world, - targetTableId, - keccak256(abi.encodePacked(value2, PackedCounter.wrap(bytes32(0)), new bytes(0))) - ); + keysWithValue = KeysWithValue.get(world, targetTableId, keccak256(abi.encodePacked(value2))); // Assert that the list is correct - assertEq(keysWithValue.length, 1, "9"); + assertEq(keysWithValue.length, 0, "9"); } function testSetField() public { From eab25bc54195ac8a25de501976f55f466ff80723 Mon Sep 17 00:00:00 2001 From: dk1a Date: Sun, 10 Sep 2023 21:51:46 +0300 Subject: [PATCH 26/69] build --- .../contracts/src/codegen/tables/Multi.sol | 26 +- .../contracts/src/codegen/tables/Number.sol | 12 +- .../src/codegen/tables/NumberList.sol | 19 +- .../contracts/src/codegen/tables/Vector.sol | 26 +- .../types/ethers-contracts/IWorld.ts | 149 ++++-- .../factories/IWorld__factory.ts | 111 ++++- e2e/packages/contracts/worlds.json | 2 +- .../src/codegen/tables/CounterTable.sol | 12 +- .../src/codegen/tables/Inventory.sol | 12 +- .../src/codegen/tables/MessageTable.sol | 31 +- .../contracts/test/ChatNamespaced.t.sol | 11 +- .../types/ethers-contracts/IWorld.ts | 149 ++++-- .../factories/IWorld__factory.ts | 111 ++++- .../src/codegen/tables/Ephemeral.sol | 14 +- .../contracts/src/codegen/tables/Statics.sol | 439 ++++-------------- packages/cli/contracts/test/Tablegen.t.sol | 13 +- packages/cli/scripts/generate-test-tables.ts | 4 +- packages/store/ts/codegen/ephemeral.ts | 5 +- .../contracts/src/codegen/tables/Counter.sol | 12 +- .../contracts/src/codegen/tables/Counter.sol | 12 +- .../contracts/src/codegen/tables/Position.sol | 26 +- .../contracts/src/codegen/tables/Counter.sol | 12 +- 22 files changed, 692 insertions(+), 516 deletions(-) diff --git a/e2e/packages/contracts/src/codegen/tables/Multi.sol b/e2e/packages/contracts/src/codegen/tables/Multi.sol index 4a8dda1a71..4b5ff073f2 100644 --- a/e2e/packages/contracts/src/codegen/tables/Multi.sol +++ b/e2e/packages/contracts/src/codegen/tables/Multi.sol @@ -190,7 +190,10 @@ library Multi { /** Set the full data using individual values */ function set(uint32 a, bool b, uint256 c, int120 d, int256 num, bool value) internal { - bytes memory _data = encode(num, value); + bytes memory _staticData = encodeStatic(num, value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(a)); @@ -198,12 +201,15 @@ library Multi { _keyTuple[2] = bytes32(uint256(c)); _keyTuple[3] = bytes32(uint256(int256(d))); - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, uint32 a, bool b, uint256 c, int120 d, int256 num, bool value) internal { - bytes memory _data = encode(num, value); + bytes memory _staticData = encodeStatic(num, value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](4); _keyTuple[0] = bytes32(uint256(a)); @@ -211,7 +217,7 @@ library Multi { _keyTuple[2] = bytes32(uint256(c)); _keyTuple[3] = bytes32(uint256(int256(d))); - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -231,9 +237,19 @@ library Multi { _table.value = (_toBool(uint8(Bytes.slice1(_blob, 32)))); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(int256 num, bool value) internal pure returns (bytes memory) { + return abi.encodePacked(num, value); + } + /** Tightly pack full data using this table's schema */ function encode(int256 num, bool value) internal pure returns (bytes memory) { - return abi.encodePacked(num, value); + bytes memory _staticData = encodeStatic(num, value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/e2e/packages/contracts/src/codegen/tables/Number.sol b/e2e/packages/contracts/src/codegen/tables/Number.sol index a626749183..3b49f27207 100644 --- a/e2e/packages/contracts/src/codegen/tables/Number.sol +++ b/e2e/packages/contracts/src/codegen/tables/Number.sol @@ -93,9 +93,19 @@ library Number { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint32 value) internal pure returns (bytes memory) { + return abi.encodePacked(value); + } + /** Tightly pack full data using this table's schema */ function encode(uint32 value) internal pure returns (bytes memory) { - return abi.encodePacked(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/e2e/packages/contracts/src/codegen/tables/NumberList.sol b/e2e/packages/contracts/src/codegen/tables/NumberList.sol index dbda775b36..d837ffe671 100644 --- a/e2e/packages/contracts/src/codegen/tables/NumberList.sol +++ b/e2e/packages/contracts/src/codegen/tables/NumberList.sol @@ -192,15 +192,26 @@ library NumberList { } } - /** Tightly pack full data using this table's schema */ - function encode(uint32[] memory value) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths(uint32[] memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(value.length * 4); } + } + + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(uint32[] memory value) internal pure returns (bytes memory) { + return abi.encodePacked(EncodeArray.encode((value))); + } + + /** Tightly pack full data using this table's schema */ + function encode(uint32[] memory value) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(value); + bytes memory _dynamicData = encodeDynamic(value); - return abi.encodePacked(_encodedLengths.unwrap(), EncodeArray.encode((value))); + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/e2e/packages/contracts/src/codegen/tables/Vector.sol b/e2e/packages/contracts/src/codegen/tables/Vector.sol index edd2318914..1c412d5b2c 100644 --- a/e2e/packages/contracts/src/codegen/tables/Vector.sol +++ b/e2e/packages/contracts/src/codegen/tables/Vector.sol @@ -154,22 +154,28 @@ library Vector { /** Set the full data using individual values */ function set(uint32 key, int32 x, int32 y) internal { - bytes memory _data = encode(x, y); + bytes memory _staticData = encodeStatic(x, y); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(key)); - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, uint32 key, int32 x, int32 y) internal { - bytes memory _data = encode(x, y); + bytes memory _staticData = encodeStatic(x, y); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = bytes32(uint256(key)); - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -189,9 +195,19 @@ library Vector { _table.y = (int32(uint32(Bytes.slice4(_blob, 4)))); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(int32 x, int32 y) internal pure returns (bytes memory) { + return abi.encodePacked(x, y); + } + /** Tightly pack full data using this table's schema */ function encode(int32 x, int32 y) internal pure returns (bytes memory) { - return abi.encodePacked(x, y); + bytes memory _staticData = encodeStatic(x, y); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts b/e2e/packages/contracts/types/ethers-contracts/IWorld.ts index 84e4920266..43056815a3 100644 --- a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts +++ b/e2e/packages/contracts/types/ethers-contracts/IWorld.ts @@ -33,7 +33,7 @@ export interface IWorldInterface extends utils.Interface { "call(bytes32,bytes)": FunctionFragment; "callFrom(address,bytes32,bytes)": FunctionFragment; "deleteRecord(bytes32,bytes32[],bytes32)": FunctionFragment; - "emitEphemeralRecord(bytes32,bytes32[],bytes,bytes32)": FunctionFragment; + "emitEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes,bytes32)": FunctionFragment; "getField(bytes32,bytes32[],uint8,bytes32)": FunctionFragment; "getFieldLength(bytes32,bytes32[],uint8,bytes32)": FunctionFragment; "getFieldSlice(bytes32,bytes32[],uint8,bytes32,uint256,uint256)": FunctionFragment; @@ -59,7 +59,7 @@ export interface IWorldInterface extends utils.Interface { "revokeAccess(bytes32,address)": FunctionFragment; "set(uint32[])": FunctionFragment; "setField(bytes32,bytes32[],uint8,bytes,bytes32)": FunctionFragment; - "setRecord(bytes32,bytes32[],bytes,bytes32)": FunctionFragment; + "setRecord(bytes32,bytes32[],bytes,bytes32,bytes,bytes32)": FunctionFragment; "stub(uint256)": FunctionFragment; "transferOwnership(bytes16,address)": FunctionFragment; "updateInField(bytes32,bytes32[],uint8,uint256,bytes,bytes32)": FunctionFragment; @@ -128,6 +128,8 @@ export interface IWorldInterface extends utils.Interface { PromiseOrValue, PromiseOrValue[], PromiseOrValue, + PromiseOrValue, + PromiseOrValue, PromiseOrValue ] ): string; @@ -295,6 +297,8 @@ export interface IWorldInterface extends utils.Interface { PromiseOrValue, PromiseOrValue[], PromiseOrValue, + PromiseOrValue, + PromiseOrValue, PromiseOrValue ] ): string; @@ -421,16 +425,18 @@ export interface IWorldInterface extends utils.Interface { events: { "HelloWorld()": EventFragment; "StoreDeleteRecord(bytes32,bytes32[])": EventFragment; - "StoreEphemeralRecord(bytes32,bytes32[],bytes)": EventFragment; - "StoreSetRecord(bytes32,bytes32[],bytes)": EventFragment; - "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32,uint256)": EventFragment; + "StoreEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes)": EventFragment; + "StoreSetRecord(bytes32,bytes32[],bytes,bytes32,bytes)": EventFragment; + "StoreSpliceDynamicRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32)": EventFragment; + "StoreSpliceStaticRecord(bytes32,bytes32[],uint48,uint40,bytes)": EventFragment; }; getEvent(nameOrSignatureOrTopic: "HelloWorld"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreDeleteRecord"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreEphemeralRecord"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreSetRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSpliceRecord"): EventFragment; + getEvent(nameOrSignatureOrTopic: "StoreSpliceDynamicRecord"): EventFragment; + getEvent(nameOrSignatureOrTopic: "StoreSpliceStaticRecord"): EventFragment; } export interface HelloWorldEventObject {} @@ -453,10 +459,12 @@ export type StoreDeleteRecordEventFilter = export interface StoreEphemeralRecordEventObject { table: string; key: string[]; - data: string; + staticData: string; + encodedLengths: string; + dynamicData: string; } export type StoreEphemeralRecordEvent = TypedEvent< - [string, string[], string], + [string, string[], string, string, string], StoreEphemeralRecordEventObject >; @@ -466,31 +474,47 @@ export type StoreEphemeralRecordEventFilter = export interface StoreSetRecordEventObject { table: string; key: string[]; - data: string; + staticData: string; + encodedLengths: string; + dynamicData: string; } export type StoreSetRecordEvent = TypedEvent< - [string, string[], string], + [string, string[], string, string, string], StoreSetRecordEventObject >; export type StoreSetRecordEventFilter = TypedEventFilter; -export interface StoreSpliceRecordEventObject { +export interface StoreSpliceDynamicRecordEventObject { + table: string; + key: string[]; + start: number; + deleteCount: number; + data: string; + encodedLengths: string; +} +export type StoreSpliceDynamicRecordEvent = TypedEvent< + [string, string[], number, number, string, string], + StoreSpliceDynamicRecordEventObject +>; + +export type StoreSpliceDynamicRecordEventFilter = + TypedEventFilter; + +export interface StoreSpliceStaticRecordEventObject { table: string; key: string[]; start: number; deleteCount: number; data: string; - newDynamicLengths: string; - dynamicLengthsStart: BigNumber; } -export type StoreSpliceRecordEvent = TypedEvent< - [string, string[], number, number, string, string, BigNumber], - StoreSpliceRecordEventObject +export type StoreSpliceStaticRecordEvent = TypedEvent< + [string, string[], number, number, string], + StoreSpliceStaticRecordEventObject >; -export type StoreSpliceRecordEventFilter = - TypedEventFilter; +export type StoreSpliceStaticRecordEventFilter = + TypedEventFilter; export interface IWorld extends BaseContract { connect(signerOrProvider: Signer | Provider | string): this; @@ -542,7 +566,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -718,7 +744,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -768,7 +796,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -944,7 +974,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -994,7 +1026,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: CallOverrides ): Promise; @@ -1168,7 +1202,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: CallOverrides ): Promise; @@ -1205,46 +1241,67 @@ export interface IWorld extends BaseContract { ): StoreDeleteRecordEventFilter; StoreDeleteRecord(table?: null, key?: null): StoreDeleteRecordEventFilter; - "StoreEphemeralRecord(bytes32,bytes32[],bytes)"( + "StoreEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes)"( table?: null, key?: null, - data?: null + staticData?: null, + encodedLengths?: null, + dynamicData?: null ): StoreEphemeralRecordEventFilter; StoreEphemeralRecord( table?: null, key?: null, - data?: null + staticData?: null, + encodedLengths?: null, + dynamicData?: null ): StoreEphemeralRecordEventFilter; - "StoreSetRecord(bytes32,bytes32[],bytes)"( + "StoreSetRecord(bytes32,bytes32[],bytes,bytes32,bytes)"( table?: null, key?: null, - data?: null + staticData?: null, + encodedLengths?: null, + dynamicData?: null ): StoreSetRecordEventFilter; StoreSetRecord( table?: null, key?: null, - data?: null + staticData?: null, + encodedLengths?: null, + dynamicData?: null ): StoreSetRecordEventFilter; - "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32,uint256)"( + "StoreSpliceDynamicRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32)"( table?: null, key?: null, start?: null, deleteCount?: null, data?: null, - newDynamicLengths?: null, - dynamicLengthsStart?: null - ): StoreSpliceRecordEventFilter; - StoreSpliceRecord( + encodedLengths?: null + ): StoreSpliceDynamicRecordEventFilter; + StoreSpliceDynamicRecord( table?: null, key?: null, start?: null, deleteCount?: null, data?: null, - newDynamicLengths?: null, - dynamicLengthsStart?: null - ): StoreSpliceRecordEventFilter; + encodedLengths?: null + ): StoreSpliceDynamicRecordEventFilter; + + "StoreSpliceStaticRecord(bytes32,bytes32[],uint48,uint40,bytes)"( + table?: null, + key?: null, + start?: null, + deleteCount?: null, + data?: null + ): StoreSpliceStaticRecordEventFilter; + StoreSpliceStaticRecord( + table?: null, + key?: null, + start?: null, + deleteCount?: null, + data?: null + ): StoreSpliceStaticRecordEventFilter; }; estimateGas: { @@ -1271,7 +1328,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -1447,7 +1506,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -1498,7 +1559,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -1674,7 +1737,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; diff --git a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts index dc20d0656a..3fc16611e6 100644 --- a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ b/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts @@ -134,7 +134,7 @@ const _abi = [ type: "uint256", }, ], - name: "StoreCore_InvalidDataLength", + name: "StoreCore_InvalidDynamicDataLength", type: "error", }, { @@ -169,6 +169,22 @@ const _abi = [ name: "StoreCore_InvalidKeyNamesLength", type: "error", }, + { + inputs: [ + { + internalType: "uint256", + name: "expected", + type: "uint256", + }, + { + internalType: "uint256", + name: "received", + type: "uint256", + }, + ], + name: "StoreCore_InvalidStaticDataLength", + type: "error", + }, { inputs: [], name: "StoreCore_NotDynamicField", @@ -308,7 +324,19 @@ const _abi = [ { indexed: false, internalType: "bytes", - name: "data", + name: "staticData", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes32", + name: "encodedLengths", + type: "bytes32", + }, + { + indexed: false, + internalType: "bytes", + name: "dynamicData", type: "bytes", }, ], @@ -333,7 +361,19 @@ const _abi = [ { indexed: false, internalType: "bytes", - name: "data", + name: "staticData", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes32", + name: "encodedLengths", + type: "bytes32", + }, + { + indexed: false, + internalType: "bytes", + name: "dynamicData", type: "bytes", }, ], @@ -376,17 +416,48 @@ const _abi = [ { indexed: false, internalType: "bytes32", - name: "newDynamicLengths", + name: "encodedLengths", type: "bytes32", }, + ], + name: "StoreSpliceDynamicRecord", + type: "event", + }, + { + anonymous: false, + inputs: [ { indexed: false, - internalType: "uint256", - name: "dynamicLengthsStart", - type: "uint256", + internalType: "bytes32", + name: "table", + type: "bytes32", + }, + { + indexed: false, + internalType: "bytes32[]", + name: "key", + type: "bytes32[]", + }, + { + indexed: false, + internalType: "uint48", + name: "start", + type: "uint48", + }, + { + indexed: false, + internalType: "uint40", + name: "deleteCount", + type: "uint40", + }, + { + indexed: false, + internalType: "bytes", + name: "data", + type: "bytes", }, ], - name: "StoreSpliceRecord", + name: "StoreSpliceStaticRecord", type: "event", }, { @@ -479,7 +550,17 @@ const _abi = [ }, { internalType: "bytes", - name: "data", + name: "staticData", + type: "bytes", + }, + { + internalType: "PackedCounter", + name: "encodedLengths", + type: "bytes32", + }, + { + internalType: "bytes", + name: "dynamicData", type: "bytes", }, { @@ -1094,7 +1175,17 @@ const _abi = [ }, { internalType: "bytes", - name: "data", + name: "staticData", + type: "bytes", + }, + { + internalType: "PackedCounter", + name: "encodedLengths", + type: "bytes32", + }, + { + internalType: "bytes", + name: "dynamicData", type: "bytes", }, { diff --git a/e2e/packages/contracts/worlds.json b/e2e/packages/contracts/worlds.json index caf66719c4..bd48105fd7 100644 --- a/e2e/packages/contracts/worlds.json +++ b/e2e/packages/contracts/worlds.json @@ -1,5 +1,5 @@ { "31337": { - "address": "0xAA292E8611aDF267e563f334Ee42320aC96D0463" + "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3" } } \ No newline at end of file diff --git a/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol b/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol index 647bfc052f..3373d759d1 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/CounterTable.sol @@ -87,9 +87,19 @@ library CounterTable { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint32 value) internal pure returns (bytes memory) { + return abi.encodePacked(value); + } + /** Tightly pack full data using this table's schema */ function encode(uint32 value) internal pure returns (bytes memory) { - return abi.encodePacked(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol b/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol index f3406f9e3c..062587720a 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/Inventory.sol @@ -105,9 +105,19 @@ library Inventory { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((amount)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint32 amount) internal pure returns (bytes memory) { + return abi.encodePacked(amount); + } + /** Tightly pack full data using this table's schema */ function encode(uint32 amount) internal pure returns (bytes memory) { - return abi.encodePacked(amount); + bytes memory _staticData = encodeStatic(amount); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol index 928fed1d72..7e54efec0b 100644 --- a/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol +++ b/examples/minimal/packages/contracts/src/codegen/tables/MessageTable.sol @@ -59,31 +59,46 @@ library MessageTable { /** Emit the ephemeral event using individual values */ function emitEphemeral(string memory value) internal { - bytes memory _data = encode(value); + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(value); + bytes memory _dynamicData = encodeDynamic(value); bytes32[] memory _keyTuple = new bytes32[](0); - StoreSwitch.emitEphemeralRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Emit the ephemeral event using individual values (using the specified store) */ function emitEphemeral(IStore _store, string memory value) internal { - bytes memory _data = encode(value); + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(value); + bytes memory _dynamicData = encodeDynamic(value); bytes32[] memory _keyTuple = new bytes32[](0); - _store.emitEphemeralRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } - /** Tightly pack full data using this table's schema */ - function encode(string memory value) internal pure returns (bytes memory) { - PackedCounter _encodedLengths; + /** Tightly pack dynamic data using this table's schema */ + function encodeLengths(string memory value) internal pure returns (PackedCounter _encodedLengths) { // Lengths are effectively checked during copy by 2**40 bytes exceeding gas limits unchecked { _encodedLengths = PackedCounterLib.pack(bytes(value).length); } + } + + /** Tightly pack dynamic data using this table's schema */ + function encodeDynamic(string memory value) internal pure returns (bytes memory) { + return abi.encodePacked(bytes((value))); + } + + /** Tightly pack full data using this table's schema */ + function encode(string memory value) internal pure returns (bytes memory) { + bytes memory _staticData; + PackedCounter _encodedLengths = encodeLengths(value); + bytes memory _dynamicData = encodeDynamic(value); - return abi.encodePacked(_encodedLengths.unwrap(), bytes((value))); + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol b/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol index c98a25a337..c97fd87b80 100644 --- a/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol +++ b/examples/minimal/packages/contracts/test/ChatNamespaced.t.sol @@ -13,8 +13,15 @@ import { IChatNamespacedSystem } from "../src/interfaces/IChatNamespacedSystem.s contract ChatNamespacedTest is MudTest { function testEmitEphemeral() public { bytes32[] memory keyTuple; + string memory value = "test"; vm.expectEmit(true, true, true, true); - emit StoreCore.StoreEphemeralRecord(MessageTableTableId, keyTuple, MessageTable.encode("test")); - IChatNamespacedSystem(worldAddress).namespace_ChatNamespaced_sendMessage("test"); + emit StoreCore.StoreEphemeralRecord( + MessageTableTableId, + keyTuple, + new bytes(0), + MessageTable.encodeLengths(value).unwrap(), + MessageTable.encodeDynamic(value) + ); + IChatNamespacedSystem(worldAddress).namespace_ChatNamespaced_sendMessage(value); } } diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts b/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts index 1a88e95f73..6af787f25c 100644 --- a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts +++ b/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts @@ -43,7 +43,7 @@ export interface IWorldInterface extends utils.Interface { "deleteRecord(bytes32,bytes32[],bytes32)": FunctionFragment; "dynamicArrayBytesStruct((bytes)[])": FunctionFragment; "dynamicArrayStringStruct((string)[])": FunctionFragment; - "emitEphemeralRecord(bytes32,bytes32[],bytes,bytes32)": FunctionFragment; + "emitEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes,bytes32)": FunctionFragment; "getField(bytes32,bytes32[],uint8,bytes32)": FunctionFragment; "getFieldLength(bytes32,bytes32[],uint8,bytes32)": FunctionFragment; "getFieldSlice(bytes32,bytes32[],uint8,bytes32,uint256,uint256)": FunctionFragment; @@ -68,7 +68,7 @@ export interface IWorldInterface extends utils.Interface { "revokeAccess(bytes32,address)": FunctionFragment; "sendMessage(string)": FunctionFragment; "setField(bytes32,bytes32[],uint8,bytes,bytes32)": FunctionFragment; - "setRecord(bytes32,bytes32[],bytes,bytes32)": FunctionFragment; + "setRecord(bytes32,bytes32[],bytes,bytes32,bytes,bytes32)": FunctionFragment; "staticArrayBytesStruct(tuple[1])": FunctionFragment; "staticArrayStringStruct(tuple[1])": FunctionFragment; "transferOwnership(bytes16,address)": FunctionFragment; @@ -150,6 +150,8 @@ export interface IWorldInterface extends utils.Interface { PromiseOrValue, PromiseOrValue[], PromiseOrValue, + PromiseOrValue, + PromiseOrValue, PromiseOrValue ] ): string; @@ -313,6 +315,8 @@ export interface IWorldInterface extends utils.Interface { PromiseOrValue, PromiseOrValue[], PromiseOrValue, + PromiseOrValue, + PromiseOrValue, PromiseOrValue ] ): string; @@ -465,16 +469,18 @@ export interface IWorldInterface extends utils.Interface { events: { "HelloWorld()": EventFragment; "StoreDeleteRecord(bytes32,bytes32[])": EventFragment; - "StoreEphemeralRecord(bytes32,bytes32[],bytes)": EventFragment; - "StoreSetRecord(bytes32,bytes32[],bytes)": EventFragment; - "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32,uint256)": EventFragment; + "StoreEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes)": EventFragment; + "StoreSetRecord(bytes32,bytes32[],bytes,bytes32,bytes)": EventFragment; + "StoreSpliceDynamicRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32)": EventFragment; + "StoreSpliceStaticRecord(bytes32,bytes32[],uint48,uint40,bytes)": EventFragment; }; getEvent(nameOrSignatureOrTopic: "HelloWorld"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreDeleteRecord"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreEphemeralRecord"): EventFragment; getEvent(nameOrSignatureOrTopic: "StoreSetRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSpliceRecord"): EventFragment; + getEvent(nameOrSignatureOrTopic: "StoreSpliceDynamicRecord"): EventFragment; + getEvent(nameOrSignatureOrTopic: "StoreSpliceStaticRecord"): EventFragment; } export interface HelloWorldEventObject {} @@ -497,10 +503,12 @@ export type StoreDeleteRecordEventFilter = export interface StoreEphemeralRecordEventObject { table: string; key: string[]; - data: string; + staticData: string; + encodedLengths: string; + dynamicData: string; } export type StoreEphemeralRecordEvent = TypedEvent< - [string, string[], string], + [string, string[], string, string, string], StoreEphemeralRecordEventObject >; @@ -510,31 +518,47 @@ export type StoreEphemeralRecordEventFilter = export interface StoreSetRecordEventObject { table: string; key: string[]; - data: string; + staticData: string; + encodedLengths: string; + dynamicData: string; } export type StoreSetRecordEvent = TypedEvent< - [string, string[], string], + [string, string[], string, string, string], StoreSetRecordEventObject >; export type StoreSetRecordEventFilter = TypedEventFilter; -export interface StoreSpliceRecordEventObject { +export interface StoreSpliceDynamicRecordEventObject { + table: string; + key: string[]; + start: number; + deleteCount: number; + data: string; + encodedLengths: string; +} +export type StoreSpliceDynamicRecordEvent = TypedEvent< + [string, string[], number, number, string, string], + StoreSpliceDynamicRecordEventObject +>; + +export type StoreSpliceDynamicRecordEventFilter = + TypedEventFilter; + +export interface StoreSpliceStaticRecordEventObject { table: string; key: string[]; start: number; deleteCount: number; data: string; - newDynamicLengths: string; - dynamicLengthsStart: BigNumber; } -export type StoreSpliceRecordEvent = TypedEvent< - [string, string[], number, number, string, string, BigNumber], - StoreSpliceRecordEventObject +export type StoreSpliceStaticRecordEvent = TypedEvent< + [string, string[], number, number, string], + StoreSpliceStaticRecordEventObject >; -export type StoreSpliceRecordEventFilter = - TypedEventFilter; +export type StoreSpliceStaticRecordEventFilter = + TypedEventFilter; export interface IWorld extends BaseContract { connect(signerOrProvider: Signer | Provider | string): this; @@ -596,7 +620,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -767,7 +793,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -836,7 +864,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -1007,7 +1037,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -1076,7 +1108,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: CallOverrides ): Promise; @@ -1245,7 +1279,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: CallOverrides ): Promise; @@ -1289,46 +1325,67 @@ export interface IWorld extends BaseContract { ): StoreDeleteRecordEventFilter; StoreDeleteRecord(table?: null, key?: null): StoreDeleteRecordEventFilter; - "StoreEphemeralRecord(bytes32,bytes32[],bytes)"( + "StoreEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes)"( table?: null, key?: null, - data?: null + staticData?: null, + encodedLengths?: null, + dynamicData?: null ): StoreEphemeralRecordEventFilter; StoreEphemeralRecord( table?: null, key?: null, - data?: null + staticData?: null, + encodedLengths?: null, + dynamicData?: null ): StoreEphemeralRecordEventFilter; - "StoreSetRecord(bytes32,bytes32[],bytes)"( + "StoreSetRecord(bytes32,bytes32[],bytes,bytes32,bytes)"( table?: null, key?: null, - data?: null + staticData?: null, + encodedLengths?: null, + dynamicData?: null ): StoreSetRecordEventFilter; StoreSetRecord( table?: null, key?: null, - data?: null + staticData?: null, + encodedLengths?: null, + dynamicData?: null ): StoreSetRecordEventFilter; - "StoreSpliceRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32,uint256)"( + "StoreSpliceDynamicRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32)"( table?: null, key?: null, start?: null, deleteCount?: null, data?: null, - newDynamicLengths?: null, - dynamicLengthsStart?: null - ): StoreSpliceRecordEventFilter; - StoreSpliceRecord( + encodedLengths?: null + ): StoreSpliceDynamicRecordEventFilter; + StoreSpliceDynamicRecord( table?: null, key?: null, start?: null, deleteCount?: null, data?: null, - newDynamicLengths?: null, - dynamicLengthsStart?: null - ): StoreSpliceRecordEventFilter; + encodedLengths?: null + ): StoreSpliceDynamicRecordEventFilter; + + "StoreSpliceStaticRecord(bytes32,bytes32[],uint48,uint40,bytes)"( + table?: null, + key?: null, + start?: null, + deleteCount?: null, + data?: null + ): StoreSpliceStaticRecordEventFilter; + StoreSpliceStaticRecord( + table?: null, + key?: null, + start?: null, + deleteCount?: null, + data?: null + ): StoreSpliceStaticRecordEventFilter; }; estimateGas: { @@ -1365,7 +1422,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -1536,7 +1595,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -1606,7 +1667,9 @@ export interface IWorld extends BaseContract { emitEphemeralRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; @@ -1777,7 +1840,9 @@ export interface IWorld extends BaseContract { setRecord( table: PromiseOrValue, key: PromiseOrValue[], - data: PromiseOrValue, + staticData: PromiseOrValue, + encodedLengths: PromiseOrValue, + dynamicData: PromiseOrValue, valueSchema: PromiseOrValue, overrides?: Overrides & { from?: PromiseOrValue } ): Promise; diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts index b2b08e127d..9cd6b8288c 100644 --- a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ b/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts @@ -139,7 +139,7 @@ const _abi = [ type: "uint256", }, ], - name: "StoreCore_InvalidDataLength", + name: "StoreCore_InvalidDynamicDataLength", type: "error", }, { @@ -174,6 +174,22 @@ const _abi = [ name: "StoreCore_InvalidKeyNamesLength", type: "error", }, + { + inputs: [ + { + internalType: "uint256", + name: "expected", + type: "uint256", + }, + { + internalType: "uint256", + name: "received", + type: "uint256", + }, + ], + name: "StoreCore_InvalidStaticDataLength", + type: "error", + }, { inputs: [], name: "StoreCore_NotDynamicField", @@ -270,7 +286,19 @@ const _abi = [ { indexed: false, internalType: "bytes", - name: "data", + name: "staticData", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes32", + name: "encodedLengths", + type: "bytes32", + }, + { + indexed: false, + internalType: "bytes", + name: "dynamicData", type: "bytes", }, ], @@ -295,7 +323,19 @@ const _abi = [ { indexed: false, internalType: "bytes", - name: "data", + name: "staticData", + type: "bytes", + }, + { + indexed: false, + internalType: "bytes32", + name: "encodedLengths", + type: "bytes32", + }, + { + indexed: false, + internalType: "bytes", + name: "dynamicData", type: "bytes", }, ], @@ -338,17 +378,48 @@ const _abi = [ { indexed: false, internalType: "bytes32", - name: "newDynamicLengths", + name: "encodedLengths", type: "bytes32", }, + ], + name: "StoreSpliceDynamicRecord", + type: "event", + }, + { + anonymous: false, + inputs: [ { indexed: false, - internalType: "uint256", - name: "dynamicLengthsStart", - type: "uint256", + internalType: "bytes32", + name: "table", + type: "bytes32", + }, + { + indexed: false, + internalType: "bytes32[]", + name: "key", + type: "bytes32[]", + }, + { + indexed: false, + internalType: "uint48", + name: "start", + type: "uint48", + }, + { + indexed: false, + internalType: "uint40", + name: "deleteCount", + type: "uint40", + }, + { + indexed: false, + internalType: "bytes", + name: "data", + type: "bytes", }, ], - name: "StoreSpliceRecord", + name: "StoreSpliceStaticRecord", type: "event", }, { @@ -481,7 +552,17 @@ const _abi = [ }, { internalType: "bytes", - name: "data", + name: "staticData", + type: "bytes", + }, + { + internalType: "PackedCounter", + name: "encodedLengths", + type: "bytes32", + }, + { + internalType: "bytes", + name: "dynamicData", type: "bytes", }, { @@ -1089,7 +1170,17 @@ const _abi = [ }, { internalType: "bytes", - name: "data", + name: "staticData", + type: "bytes", + }, + { + internalType: "PackedCounter", + name: "encodedLengths", + type: "bytes32", + }, + { + internalType: "bytes", + name: "dynamicData", type: "bytes", }, { diff --git a/packages/cli/contracts/src/codegen/tables/Ephemeral.sol b/packages/cli/contracts/src/codegen/tables/Ephemeral.sol index 294bd45999..6fd140cd71 100644 --- a/packages/cli/contracts/src/codegen/tables/Ephemeral.sol +++ b/packages/cli/contracts/src/codegen/tables/Ephemeral.sol @@ -61,22 +61,28 @@ library Ephemeral { /** Emit the ephemeral event using individual values */ function emitEphemeral(bytes32 key, uint256 value) internal { - bytes memory _data = encode(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - StoreSwitch.emitEphemeralRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Emit the ephemeral event using individual values (using the specified store) */ function emitEphemeral(IStore _store, bytes32 key, uint256 value) internal { - bytes memory _data = encode(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - _store.emitEphemeralRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Tightly pack static data using this table's schema */ diff --git a/packages/cli/contracts/src/codegen/tables/Statics.sol b/packages/cli/contracts/src/codegen/tables/Statics.sol index 203644f1d1..9dbe72b8de 100644 --- a/packages/cli/contracts/src/codegen/tables/Statics.sol +++ b/packages/cli/contracts/src/codegen/tables/Statics.sol @@ -18,7 +18,7 @@ import { Schema, SchemaLib } from "@latticexyz/store/src/Schema.sol"; import { PackedCounter, PackedCounterLib } from "@latticexyz/store/src/PackedCounter.sol"; // Import user types -import { Enum1, Enum2 } from "./../Types.sol"; +import { Enum2, Enum1 } from "./../Types.sol"; bytes32 constant _tableId = bytes32(abi.encodePacked(bytes16(""), bytes16("Statics"))); bytes32 constant StaticsTableId = _tableId; @@ -30,60 +30,55 @@ struct StaticsData { address v4; bool v5; Enum1 v6; - Enum2 v7; } library Statics { /** Get the table's key schema */ function getKeySchema() internal pure returns (Schema) { - SchemaType[] memory _schema = new SchemaType[](7); + SchemaType[] memory _schema = new SchemaType[](6); _schema[0] = SchemaType.UINT256; _schema[1] = SchemaType.INT32; _schema[2] = SchemaType.BYTES16; _schema[3] = SchemaType.ADDRESS; _schema[4] = SchemaType.BOOL; _schema[5] = SchemaType.UINT8; - _schema[6] = SchemaType.UINT8; return SchemaLib.encode(_schema); } /** Get the table's value schema */ function getValueSchema() internal pure returns (Schema) { - SchemaType[] memory _schema = new SchemaType[](7); + SchemaType[] memory _schema = new SchemaType[](6); _schema[0] = SchemaType.UINT256; _schema[1] = SchemaType.INT32; _schema[2] = SchemaType.BYTES16; _schema[3] = SchemaType.ADDRESS; _schema[4] = SchemaType.BOOL; _schema[5] = SchemaType.UINT8; - _schema[6] = SchemaType.UINT8; return SchemaLib.encode(_schema); } /** Get the table's key names */ function getKeyNames() internal pure returns (string[] memory keyNames) { - keyNames = new string[](7); + keyNames = new string[](6); keyNames[0] = "k1"; keyNames[1] = "k2"; keyNames[2] = "k3"; keyNames[3] = "k4"; keyNames[4] = "k5"; keyNames[5] = "k6"; - keyNames[6] = "k7"; } /** Get the table's field names */ function getFieldNames() internal pure returns (string[] memory fieldNames) { - fieldNames = new string[](7); + fieldNames = new string[](6); fieldNames[0] = "v1"; fieldNames[1] = "v2"; fieldNames[2] = "v3"; fieldNames[3] = "v4"; fieldNames[4] = "v5"; fieldNames[5] = "v6"; - fieldNames[6] = "v7"; } /** Register the table's key schema, value schema, key names and value names */ @@ -97,23 +92,14 @@ library Statics { } /** Get v1 */ - function getV1( - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7 - ) internal view returns (uint256 v1) { - bytes32[] memory _keyTuple = new bytes32[](7); + function getV1(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal view returns (uint256 v1) { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 0, getValueSchema()); return (uint256(Bytes.slice32(_blob, 0))); @@ -127,78 +113,55 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7 + Enum2 k6 ) internal view returns (uint256 v1) { - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = _store.getField(_tableId, _keyTuple, 0, getValueSchema()); return (uint256(Bytes.slice32(_blob, 0))); } /** Set v1 */ - function setV1(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, uint256 v1) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV1(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, uint256 v1) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); StoreSwitch.setField(_tableId, _keyTuple, 0, abi.encodePacked((v1)), getValueSchema()); } /** Set v1 (using the specified store) */ - function setV1( - IStore _store, - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7, - uint256 v1 - ) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV1(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, uint256 v1) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((v1)), getValueSchema()); } /** Get v2 */ - function getV2( - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7 - ) internal view returns (int32 v2) { - bytes32[] memory _keyTuple = new bytes32[](7); + function getV2(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal view returns (int32 v2) { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 1, getValueSchema()); return (int32(uint32(Bytes.slice4(_blob, 0)))); @@ -212,78 +175,55 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7 + Enum2 k6 ) internal view returns (int32 v2) { - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = _store.getField(_tableId, _keyTuple, 1, getValueSchema()); return (int32(uint32(Bytes.slice4(_blob, 0)))); } /** Set v2 */ - function setV2(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, int32 v2) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV2(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, int32 v2) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); StoreSwitch.setField(_tableId, _keyTuple, 1, abi.encodePacked((v2)), getValueSchema()); } /** Set v2 (using the specified store) */ - function setV2( - IStore _store, - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7, - int32 v2 - ) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV2(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, int32 v2) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); _store.setField(_tableId, _keyTuple, 1, abi.encodePacked((v2)), getValueSchema()); } /** Get v3 */ - function getV3( - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7 - ) internal view returns (bytes16 v3) { - bytes32[] memory _keyTuple = new bytes32[](7); + function getV3(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal view returns (bytes16 v3) { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 2, getValueSchema()); return (Bytes.slice16(_blob, 0)); @@ -297,78 +237,55 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7 + Enum2 k6 ) internal view returns (bytes16 v3) { - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = _store.getField(_tableId, _keyTuple, 2, getValueSchema()); return (Bytes.slice16(_blob, 0)); } /** Set v3 */ - function setV3(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, bytes16 v3) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV3(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, bytes16 v3) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); StoreSwitch.setField(_tableId, _keyTuple, 2, abi.encodePacked((v3)), getValueSchema()); } /** Set v3 (using the specified store) */ - function setV3( - IStore _store, - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7, - bytes16 v3 - ) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV3(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, bytes16 v3) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); _store.setField(_tableId, _keyTuple, 2, abi.encodePacked((v3)), getValueSchema()); } /** Get v4 */ - function getV4( - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7 - ) internal view returns (address v4) { - bytes32[] memory _keyTuple = new bytes32[](7); + function getV4(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal view returns (address v4) { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 3, getValueSchema()); return (address(Bytes.slice20(_blob, 0))); @@ -382,78 +299,55 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7 + Enum2 k6 ) internal view returns (address v4) { - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = _store.getField(_tableId, _keyTuple, 3, getValueSchema()); return (address(Bytes.slice20(_blob, 0))); } /** Set v4 */ - function setV4(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, address v4) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV4(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, address v4) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); StoreSwitch.setField(_tableId, _keyTuple, 3, abi.encodePacked((v4)), getValueSchema()); } /** Set v4 (using the specified store) */ - function setV4( - IStore _store, - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7, - address v4 - ) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV4(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, address v4) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); _store.setField(_tableId, _keyTuple, 3, abi.encodePacked((v4)), getValueSchema()); } /** Get v5 */ - function getV5( - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7 - ) internal view returns (bool v5) { - bytes32[] memory _keyTuple = new bytes32[](7); + function getV5(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal view returns (bool v5) { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 4, getValueSchema()); return (_toBool(uint8(Bytes.slice1(_blob, 0)))); @@ -467,78 +361,55 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7 + Enum2 k6 ) internal view returns (bool v5) { - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = _store.getField(_tableId, _keyTuple, 4, getValueSchema()); return (_toBool(uint8(Bytes.slice1(_blob, 0)))); } /** Set v5 */ - function setV5(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, bool v5) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV5(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, bool v5) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); StoreSwitch.setField(_tableId, _keyTuple, 4, abi.encodePacked((v5)), getValueSchema()); } /** Set v5 (using the specified store) */ - function setV5( - IStore _store, - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7, - bool v5 - ) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV5(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, bool v5) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); _store.setField(_tableId, _keyTuple, 4, abi.encodePacked((v5)), getValueSchema()); } /** Get v6 */ - function getV6( - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7 - ) internal view returns (Enum1 v6) { - bytes32[] memory _keyTuple = new bytes32[](7); + function getV6(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal view returns (Enum1 v6) { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 5, getValueSchema()); return Enum1(uint8(Bytes.slice1(_blob, 0))); @@ -552,145 +423,46 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7 + Enum2 k6 ) internal view returns (Enum1 v6) { - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = _store.getField(_tableId, _keyTuple, 5, getValueSchema()); return Enum1(uint8(Bytes.slice1(_blob, 0))); } /** Set v6 */ - function setV6(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, Enum1 v6) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV6(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, Enum1 v6) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); StoreSwitch.setField(_tableId, _keyTuple, 5, abi.encodePacked(uint8(v6)), getValueSchema()); } /** Set v6 (using the specified store) */ - function setV6( - IStore _store, - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7, - Enum1 v6 - ) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function setV6(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, Enum1 v6) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); _store.setField(_tableId, _keyTuple, 5, abi.encodePacked(uint8(v6)), getValueSchema()); } - /** Get v7 */ - function getV7( - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7 - ) internal view returns (Enum2 v7) { - bytes32[] memory _keyTuple = new bytes32[](7); - _keyTuple[0] = bytes32(uint256(k1)); - _keyTuple[1] = bytes32(uint256(int256(k2))); - _keyTuple[2] = bytes32(k3); - _keyTuple[3] = bytes32(uint256(uint160(k4))); - _keyTuple[4] = _boolToBytes32(k5); - _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); - - bytes memory _blob = StoreSwitch.getField(_tableId, _keyTuple, 6, getValueSchema()); - return Enum2(uint8(Bytes.slice1(_blob, 0))); - } - - /** Get v7 (using the specified store) */ - function getV7( - IStore _store, - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7 - ) internal view returns (Enum2 v7) { - bytes32[] memory _keyTuple = new bytes32[](7); - _keyTuple[0] = bytes32(uint256(k1)); - _keyTuple[1] = bytes32(uint256(int256(k2))); - _keyTuple[2] = bytes32(k3); - _keyTuple[3] = bytes32(uint256(uint160(k4))); - _keyTuple[4] = _boolToBytes32(k5); - _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); - - bytes memory _blob = _store.getField(_tableId, _keyTuple, 6, getValueSchema()); - return Enum2(uint8(Bytes.slice1(_blob, 0))); - } - - /** Set v7 */ - function setV7(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7, Enum2 v7) internal { - bytes32[] memory _keyTuple = new bytes32[](7); - _keyTuple[0] = bytes32(uint256(k1)); - _keyTuple[1] = bytes32(uint256(int256(k2))); - _keyTuple[2] = bytes32(k3); - _keyTuple[3] = bytes32(uint256(uint160(k4))); - _keyTuple[4] = _boolToBytes32(k5); - _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); - - StoreSwitch.setField(_tableId, _keyTuple, 6, abi.encodePacked(uint8(v7)), getValueSchema()); - } - - /** Set v7 (using the specified store) */ - function setV7( - IStore _store, - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7, - Enum2 v7 - ) internal { - bytes32[] memory _keyTuple = new bytes32[](7); - _keyTuple[0] = bytes32(uint256(k1)); - _keyTuple[1] = bytes32(uint256(int256(k2))); - _keyTuple[2] = bytes32(k3); - _keyTuple[3] = bytes32(uint256(uint160(k4))); - _keyTuple[4] = _boolToBytes32(k5); - _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); - - _store.setField(_tableId, _keyTuple, 6, abi.encodePacked(uint8(v7)), getValueSchema()); - } - /** Get the full data */ function get( uint256 k1, @@ -698,17 +470,15 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7 + Enum2 k6 ) internal view returns (StaticsData memory _table) { - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = StoreSwitch.getRecord(_tableId, _keyTuple, getValueSchema()); return decode(_blob); @@ -722,17 +492,15 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7 + Enum2 k6 ) internal view returns (StaticsData memory _table) { - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); bytes memory _blob = _store.getRecord(_tableId, _keyTuple, getValueSchema()); return decode(_blob); @@ -745,29 +513,26 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7, + Enum2 k6, uint256 v1, int32 v2, bytes16 v3, address v4, bool v5, - Enum1 v6, - Enum2 v7 + Enum1 v6 ) internal { - bytes memory _staticData = encodeStatic(v1, v2, v3, v4, v5, v6, v7); + bytes memory _staticData = encodeStatic(v1, v2, v3, v4, v5, v6); PackedCounter _encodedLengths; bytes memory _dynamicData; - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } @@ -780,45 +545,33 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7, + Enum2 k6, uint256 v1, int32 v2, bytes16 v3, address v4, bool v5, - Enum1 v6, - Enum2 v7 + Enum1 v6 ) internal { - bytes memory _staticData = encodeStatic(v1, v2, v3, v4, v5, v6, v7); + bytes memory _staticData = encodeStatic(v1, v2, v3, v4, v5, v6); PackedCounter _encodedLengths; bytes memory _dynamicData; - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ - function set( - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7, - StaticsData memory _table - ) internal { - set(k1, k2, k3, k4, k5, k6, k7, _table.v1, _table.v2, _table.v3, _table.v4, _table.v5, _table.v6, _table.v7); + function set(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6, StaticsData memory _table) internal { + set(k1, k2, k3, k4, k5, k6, _table.v1, _table.v2, _table.v3, _table.v4, _table.v5, _table.v6); } /** Set the full data using the data struct (using the specified store) */ @@ -829,27 +582,10 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7, + Enum2 k6, StaticsData memory _table ) internal { - set( - _store, - k1, - k2, - k3, - k4, - k5, - k6, - k7, - _table.v1, - _table.v2, - _table.v3, - _table.v4, - _table.v5, - _table.v6, - _table.v7 - ); + set(_store, k1, k2, k3, k4, k5, k6, _table.v1, _table.v2, _table.v3, _table.v4, _table.v5, _table.v6); } /** Decode the tightly packed blob using this table's schema */ @@ -865,8 +601,6 @@ library Statics { _table.v5 = (_toBool(uint8(Bytes.slice1(_blob, 72)))); _table.v6 = Enum1(uint8(Bytes.slice1(_blob, 73))); - - _table.v7 = Enum2(uint8(Bytes.slice1(_blob, 74))); } /** Tightly pack static data using this table's schema */ @@ -876,10 +610,9 @@ library Statics { bytes16 v3, address v4, bool v5, - Enum1 v6, - Enum2 v7 + Enum1 v6 ) internal pure returns (bytes memory) { - return abi.encodePacked(v1, v2, v3, v4, v5, v6, v7); + return abi.encodePacked(v1, v2, v3, v4, v5, v6); } /** Tightly pack full data using this table's schema */ @@ -889,10 +622,9 @@ library Statics { bytes16 v3, address v4, bool v5, - Enum1 v6, - Enum2 v7 + Enum1 v6 ) internal pure returns (bytes memory) { - bytes memory _staticData = encodeStatic(v1, v2, v3, v4, v5, v6, v7); + bytes memory _staticData = encodeStatic(v1, v2, v3, v4, v5, v6); PackedCounter _encodedLengths; bytes memory _dynamicData; @@ -907,54 +639,41 @@ library Statics { bytes16 k3, address k4, bool k5, - Enum1 k6, - Enum2 k7 + Enum2 k6 ) internal pure returns (bytes32[] memory) { - bytes32[] memory _keyTuple = new bytes32[](7); + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); return _keyTuple; } /* Delete all data for given keys */ - function deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum1 k6, Enum2 k7) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function deleteRecord(uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); StoreSwitch.deleteRecord(_tableId, _keyTuple, getValueSchema()); } /* Delete all data for given keys (using the specified store) */ - function deleteRecord( - IStore _store, - uint256 k1, - int32 k2, - bytes16 k3, - address k4, - bool k5, - Enum1 k6, - Enum2 k7 - ) internal { - bytes32[] memory _keyTuple = new bytes32[](7); + function deleteRecord(IStore _store, uint256 k1, int32 k2, bytes16 k3, address k4, bool k5, Enum2 k6) internal { + bytes32[] memory _keyTuple = new bytes32[](6); _keyTuple[0] = bytes32(uint256(k1)); _keyTuple[1] = bytes32(uint256(int256(k2))); _keyTuple[2] = bytes32(k3); _keyTuple[3] = bytes32(uint256(uint160(k4))); _keyTuple[4] = _boolToBytes32(k5); _keyTuple[5] = bytes32(uint256(uint8(k6))); - _keyTuple[6] = bytes32(uint256(uint8(k7))); _store.deleteRecord(_tableId, _keyTuple, getValueSchema()); } diff --git a/packages/cli/contracts/test/Tablegen.t.sol b/packages/cli/contracts/test/Tablegen.t.sol index cf840e6387..97f727e19e 100644 --- a/packages/cli/contracts/test/Tablegen.t.sol +++ b/packages/cli/contracts/test/Tablegen.t.sol @@ -17,15 +17,14 @@ contract TablegenTest is Test, StoreReadWithStubs { bytes16 k3 = hex"02"; address k4 = address(123); bool k5 = true; - Enum1 k6 = Enum1.E3; - Enum2 k7 = Enum2.E1; + Enum2 k6 = Enum2.E1; - Statics.setV1(k1, k2, k3, k4, k5, k6, k7, 4); - assertEq(Statics.getV1(k1, k2, k3, k4, k5, k6, k7), 4); + Statics.setV1(k1, k2, k3, k4, k5, k6, 4); + assertEq(Statics.getV1(k1, k2, k3, k4, k5, k6), 4); - StaticsData memory data = StaticsData(4, -5, hex"06", address(456), false, Enum1.E2, Enum2.E1); - Statics.set(k1, k2, k3, k4, k5, k6, k7, data); - assertEq(abi.encode(Statics.get(k1, k2, k3, k4, k5, k6, k7)), abi.encode(data)); + StaticsData memory data = StaticsData(4, -5, hex"06", address(456), false, Enum1.E2); + Statics.set(k1, k2, k3, k4, k5, k6, data); + assertEq(abi.encode(Statics.get(k1, k2, k3, k4, k5, k6)), abi.encode(data)); } function testDynamicsSetAndGet() public { diff --git a/packages/cli/scripts/generate-test-tables.ts b/packages/cli/scripts/generate-test-tables.ts index ec8174f3ee..59da859d11 100644 --- a/packages/cli/scripts/generate-test-tables.ts +++ b/packages/cli/scripts/generate-test-tables.ts @@ -19,8 +19,7 @@ try { k3: "bytes16", k4: "address", k5: "bool", - k6: "Enum1", - k7: "Enum2", + k6: "Enum2", }, schema: { v1: "uint256", @@ -29,7 +28,6 @@ try { v4: "address", v5: "bool", v6: "Enum1", - v7: "Enum2", }, }, Dynamics1: { diff --git a/packages/store/ts/codegen/ephemeral.ts b/packages/store/ts/codegen/ephemeral.ts index 21759a1c74..09856cce22 100644 --- a/packages/store/ts/codegen/ephemeral.ts +++ b/packages/store/ts/codegen/ephemeral.ts @@ -1,5 +1,6 @@ import { renderArguments, renderCommonData, renderWithStore } from "@latticexyz/common/codegen"; import { RenderTableOptions } from "./types"; +import { renderRecordData } from "./record"; export function renderEphemeralMethods(options: RenderTableOptions) { const { structName, storeArgument } = options; @@ -15,11 +16,11 @@ export function renderEphemeralMethods(options: RenderTableOptions) { _typedKeyArgs, renderArguments(options.fields.map(({ name, typeWithLocation }) => `${typeWithLocation} ${name}`)), ])}) internal { - bytes memory _data = encode(${renderArguments(options.fields.map(({ name }) => name))}); + ${renderRecordData(options)} ${_keyTupleDefinition} - ${_store}.emitEphemeralRecord(_tableId, _keyTuple, _data, getValueSchema()); + ${_store}.emitEphemeralRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } ` ); diff --git a/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol b/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol index 23789be1ec..3ff5f734b1 100644 --- a/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/phaser/packages/contracts/src/codegen/tables/Counter.sol @@ -87,9 +87,19 @@ library Counter { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint32 value) internal pure returns (bytes memory) { + return abi.encodePacked(value); + } + /** Tightly pack full data using this table's schema */ function encode(uint32 value) internal pure returns (bytes memory) { - return abi.encodePacked(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/templates/react/packages/contracts/src/codegen/tables/Counter.sol b/templates/react/packages/contracts/src/codegen/tables/Counter.sol index 23789be1ec..3ff5f734b1 100644 --- a/templates/react/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/react/packages/contracts/src/codegen/tables/Counter.sol @@ -87,9 +87,19 @@ library Counter { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint32 value) internal pure returns (bytes memory) { + return abi.encodePacked(value); + } + /** Tightly pack full data using this table's schema */ function encode(uint32 value) internal pure returns (bytes memory) { - return abi.encodePacked(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/templates/threejs/packages/contracts/src/codegen/tables/Position.sol b/templates/threejs/packages/contracts/src/codegen/tables/Position.sol index b2cc2fb59c..e0003640b2 100644 --- a/templates/threejs/packages/contracts/src/codegen/tables/Position.sol +++ b/templates/threejs/packages/contracts/src/codegen/tables/Position.sol @@ -191,22 +191,28 @@ library Position { /** Set the full data using individual values */ function set(bytes32 key, int32 x, int32 y, int32 z) internal { - bytes memory _data = encode(x, y, z); + bytes memory _staticData = encodeStatic(x, y, z); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - StoreSwitch.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + StoreSwitch.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using individual values (using the specified store) */ function set(IStore _store, bytes32 key, int32 x, int32 y, int32 z) internal { - bytes memory _data = encode(x, y, z); + bytes memory _staticData = encodeStatic(x, y, z); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; bytes32[] memory _keyTuple = new bytes32[](1); _keyTuple[0] = key; - _store.setRecord(_tableId, _keyTuple, _data, getValueSchema()); + _store.setRecord(_tableId, _keyTuple, _staticData, _encodedLengths, _dynamicData, getValueSchema()); } /** Set the full data using the data struct */ @@ -228,9 +234,19 @@ library Position { _table.z = (int32(uint32(Bytes.slice4(_blob, 8)))); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(int32 x, int32 y, int32 z) internal pure returns (bytes memory) { + return abi.encodePacked(x, y, z); + } + /** Tightly pack full data using this table's schema */ function encode(int32 x, int32 y, int32 z) internal pure returns (bytes memory) { - return abi.encodePacked(x, y, z); + bytes memory _staticData = encodeStatic(x, y, z); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ diff --git a/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol b/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol index 23789be1ec..3ff5f734b1 100644 --- a/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol +++ b/templates/vanilla/packages/contracts/src/codegen/tables/Counter.sol @@ -87,9 +87,19 @@ library Counter { _store.setField(_tableId, _keyTuple, 0, abi.encodePacked((value)), getValueSchema()); } + /** Tightly pack static data using this table's schema */ + function encodeStatic(uint32 value) internal pure returns (bytes memory) { + return abi.encodePacked(value); + } + /** Tightly pack full data using this table's schema */ function encode(uint32 value) internal pure returns (bytes memory) { - return abi.encodePacked(value); + bytes memory _staticData = encodeStatic(value); + + PackedCounter _encodedLengths; + bytes memory _dynamicData; + + return abi.encodePacked(_staticData, _encodedLengths, _dynamicData); } /** Encode keys as a bytes32 array using this table's schema */ From ac6bcfdbac740847a5117e89776fb31b1fdf1902 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 12 Sep 2023 13:54:58 +0100 Subject: [PATCH 27/69] get recs sync working --- packages/dev-tools/src/events/EventIcon.tsx | 3 +- packages/protocol-parser/src/common.ts | 10 +- .../protocol-parser/src/decodeValueArgs.ts | 20 ++++ packages/protocol-parser/src/encodeLengths.ts | 18 +++ packages/protocol-parser/src/encodeValue.ts | 15 +-- .../protocol-parser/src/encodeValueArgs.ts | 27 +++++ packages/protocol-parser/src/index.ts | 2 + packages/store-sync/src/createStoreSync.ts | 8 +- packages/store-sync/src/logToTable.ts | 17 +-- packages/store-sync/src/recs/common.ts | 4 +- .../src/recs/configToRecsComponents.ts | 4 +- packages/store-sync/src/recs/recsStorage.ts | 106 +++++++++++++++--- packages/store-sync/src/spliceValueHex.ts | 11 +- packages/store/src/PackedCounter.sol | 3 + 14 files changed, 198 insertions(+), 50 deletions(-) create mode 100644 packages/protocol-parser/src/decodeValueArgs.ts create mode 100644 packages/protocol-parser/src/encodeLengths.ts create mode 100644 packages/protocol-parser/src/encodeValueArgs.ts diff --git a/packages/dev-tools/src/events/EventIcon.tsx b/packages/dev-tools/src/events/EventIcon.tsx index afcf3e3117..3eaa8904b5 100644 --- a/packages/dev-tools/src/events/EventIcon.tsx +++ b/packages/dev-tools/src/events/EventIcon.tsx @@ -9,7 +9,8 @@ export function EventIcon({ type }: Props) { switch (type) { case "StoreSetRecord": return =; - case "StoreSpliceRecord": + case "StoreSpliceStaticRecord": + case "StoreSpliceDynamicRecord": return +; case "StoreDeleteRecord": return -; diff --git a/packages/protocol-parser/src/common.ts b/packages/protocol-parser/src/common.ts index bf98201851..cd188ce791 100644 --- a/packages/protocol-parser/src/common.ts +++ b/packages/protocol-parser/src/common.ts @@ -1,7 +1,7 @@ import { DynamicAbiType, SchemaAbiType, SchemaAbiTypeToPrimitiveType, StaticAbiType } from "@latticexyz/schema-type"; -import { maxUint256, numberToHex } from "viem"; +import { Hex, numberToHex } from "viem"; -export const UNCHANGED_PACKED_COUNTER = numberToHex(maxUint256); +export const UNCHANGED_PACKED_COUNTER = numberToHex(1, { size: 32 }); /** @deprecated use `KeySchema` or `ValueSchema` instead */ export type Schema = { @@ -27,3 +27,9 @@ export type TableRecord; value: SchemaToPrimitives; }; + +export type ValueArgs = { + staticData: Hex; + encodedLengths: Hex; + dynamicData: Hex; +}; diff --git a/packages/protocol-parser/src/decodeValueArgs.ts b/packages/protocol-parser/src/decodeValueArgs.ts new file mode 100644 index 0000000000..da043c31ea --- /dev/null +++ b/packages/protocol-parser/src/decodeValueArgs.ts @@ -0,0 +1,20 @@ +import { concatHex } from "viem"; +import { isStaticAbiType } from "@latticexyz/schema-type"; +import { SchemaToPrimitives, ValueArgs, ValueSchema } from "./common"; +import { decodeValue } from "./decodeValue"; +import { staticDataLength } from "./staticDataLength"; +import { readHex } from "./readHex"; + +export function decodeValueArgs( + valueSchema: TSchema, + { staticData, encodedLengths, dynamicData }: ValueArgs +): SchemaToPrimitives { + return decodeValue( + valueSchema, + concatHex([ + readHex(staticData, 0, staticDataLength(Object.values(valueSchema).filter(isStaticAbiType))), + encodedLengths, + dynamicData, + ]) + ); +} diff --git a/packages/protocol-parser/src/encodeLengths.ts b/packages/protocol-parser/src/encodeLengths.ts new file mode 100644 index 0000000000..32ba640c8b --- /dev/null +++ b/packages/protocol-parser/src/encodeLengths.ts @@ -0,0 +1,18 @@ +import { Hex, concatHex, padHex, size } from "viem"; +import { encodeField } from "./encodeField"; + +export function encodeLengths(values: Hex[]): Hex { + const byteLengths = values.map(size).reverse(); + const totalByteLength = byteLengths.reduce((total, length) => total + BigInt(length), 0n); + + return padHex( + concatHex([ + ...byteLengths + .slice() + .reverse() + .map((length) => encodeField("uint40", length)), + encodeField("uint56", totalByteLength), + ]), + { size: 32, dir: "left" } + ); +} diff --git a/packages/protocol-parser/src/encodeValue.ts b/packages/protocol-parser/src/encodeValue.ts index 6394f144b3..df85964b65 100644 --- a/packages/protocol-parser/src/encodeValue.ts +++ b/packages/protocol-parser/src/encodeValue.ts @@ -1,18 +1,11 @@ -import { isStaticAbiType, isDynamicAbiType } from "@latticexyz/schema-type"; -import { Hex } from "viem"; +import { Hex, concatHex } from "viem"; import { SchemaToPrimitives, ValueSchema } from "./common"; -import { encodeRecord } from "./encodeRecord"; +import { encodeValueArgs } from "./encodeValueArgs"; export function encodeValue( valueSchema: TSchema, value: SchemaToPrimitives ): Hex { - const staticFields = Object.values(valueSchema).filter(isStaticAbiType); - const dynamicFields = Object.values(valueSchema).filter(isDynamicAbiType); - - // TODO: refactor and move all encodeRecord logic into this method so we can delete encodeRecord - - // This currently assumes fields/values are ordered by static, dynamic - // TODO: make sure we preserve ordering based on schema definition - return encodeRecord({ staticFields, dynamicFields }, Object.values(value)); + const { staticData, encodedLengths, dynamicData } = encodeValueArgs(valueSchema, value); + return concatHex([staticData, encodedLengths, dynamicData]); } diff --git a/packages/protocol-parser/src/encodeValueArgs.ts b/packages/protocol-parser/src/encodeValueArgs.ts new file mode 100644 index 0000000000..0f58a01b8a --- /dev/null +++ b/packages/protocol-parser/src/encodeValueArgs.ts @@ -0,0 +1,27 @@ +import { StaticPrimitiveType, DynamicPrimitiveType, isStaticAbiType, isDynamicAbiType } from "@latticexyz/schema-type"; +import { concatHex } from "viem"; +import { encodeField } from "./encodeField"; +import { SchemaToPrimitives, ValueArgs, ValueSchema } from "./common"; +import { encodeLengths } from "./encodeLengths"; + +export function encodeValueArgs( + valueSchema: TSchema, + value: SchemaToPrimitives +): ValueArgs { + const staticFields = Object.values(valueSchema).filter(isStaticAbiType); + const dynamicFields = Object.values(valueSchema).filter(isDynamicAbiType); + + const values = Object.values(value); + const staticValues = values.slice(0, staticFields.length) as readonly StaticPrimitiveType[]; + const dynamicValues = values.slice(staticFields.length) as readonly DynamicPrimitiveType[]; + + const encodedStaticValues = staticValues.map((value, i) => encodeField(staticFields[i], value)); + const encodedDynamicValues = dynamicValues.map((value, i) => encodeField(dynamicFields[i], value)); + const encodedLengths = encodeLengths(encodedDynamicValues); + + return { + staticData: concatHex(encodedStaticValues), + encodedLengths, + dynamicData: concatHex(encodedDynamicValues), + }; +} diff --git a/packages/protocol-parser/src/index.ts b/packages/protocol-parser/src/index.ts index c501303621..16b095392b 100644 --- a/packages/protocol-parser/src/index.ts +++ b/packages/protocol-parser/src/index.ts @@ -7,11 +7,13 @@ export * from "./decodeKeyTuple"; export * from "./decodeRecord"; export * from "./decodeStaticField"; export * from "./decodeValue"; +export * from "./decodeValueArgs"; export * from "./encodeField"; export * from "./encodeKey"; export * from "./encodeKeyTuple"; export * from "./encodeRecord"; export * from "./encodeValue"; +export * from "./encodeValueArgs"; export * from "./errors"; export * from "./hexToPackedCounter"; export * from "./hexToSchema"; diff --git a/packages/store-sync/src/createStoreSync.ts b/packages/store-sync/src/createStoreSync.ts index 8ecc37bfcf..206090ef77 100644 --- a/packages/store-sync/src/createStoreSync.ts +++ b/packages/store-sync/src/createStoreSync.ts @@ -1,5 +1,5 @@ import { StoreConfig, storeEventsAbi } from "@latticexyz/store"; -import { Hex, TransactionReceiptNotFoundError, encodeAbiParameters } from "viem"; +import { Hex, TransactionReceiptNotFoundError } from "viem"; import { StorageAdapter, StorageAdapterBlock, @@ -7,8 +7,6 @@ import { SyncOptions, SyncResult, TableWithRecords, - schemasTable, - schemasTableId, } from "./common"; import { createBlockStream, blockRangeToLogs, groupLogsByBlockNumber } from "@latticexyz/block-logs-stream"; import { @@ -33,7 +31,7 @@ import { debug as parentDebug } from "./debug"; import { createIndexerClient } from "./trpc-indexer"; import { SyncStep } from "./SyncStep"; import { chunk, isDefined } from "@latticexyz/common/utils"; -import { encodeKey, encodeValue, keySchemaToHex, schemaToHex, valueSchemaToHex } from "@latticexyz/protocol-parser"; +import { encodeKey, encodeValueArgs } from "@latticexyz/protocol-parser"; const debug = parentDebug.extend("createStoreSync"); @@ -140,7 +138,7 @@ export async function createStoreSync args: { table: table.tableId, key: encodeKey(table.keySchema, record.key), - data: encodeValue(table.valueSchema, record.value), + ...encodeValueArgs(table.valueSchema, record.value), }, }) ) diff --git a/packages/store-sync/src/logToTable.ts b/packages/store-sync/src/logToTable.ts index 1a7478c6a4..d92fee3213 100644 --- a/packages/store-sync/src/logToTable.ts +++ b/packages/store-sync/src/logToTable.ts @@ -1,16 +1,11 @@ -import { decodeRecord, abiTypesToSchema, hexToSchema } from "@latticexyz/protocol-parser"; -import { ConfigToValuePrimitives } from "@latticexyz/store"; -import { decodeAbiParameters, parseAbiParameters } from "viem"; +import { hexToSchema, decodeValue } from "@latticexyz/protocol-parser"; +import { concatHex, decodeAbiParameters, parseAbiParameters } from "viem"; import { StorageAdapterLog, Table, schemasTable } from "./common"; import { hexToTableId } from "@latticexyz/common"; -import storeConfig from "@latticexyz/store/mud.config"; // TODO: add tableToLog export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord" }): Table { - // TODO: refactor encode/decode to use Record schemas - // TODO: refactor to decode key with protocol-parser utils - const [tableId, ...otherKeys] = log.args.key; if (otherKeys.length) { console.warn("registerSchema event is expected to have only one key in key tuple, but got multiple", log); @@ -18,10 +13,10 @@ export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord const table = hexToTableId(tableId); - const valueTuple = decodeRecord(abiTypesToSchema(Object.values(schemasTable.schema)), log.args.data); - const value = Object.fromEntries( - Object.keys(schemasTable.schema).map((name, i) => [name, valueTuple[i]]) - ) as ConfigToValuePrimitives; + const value = decodeValue( + schemasTable.schema, + concatHex([log.args.staticData, log.args.encodedLengths, log.args.dynamicData]) + ); const keySchema = hexToSchema(value.keySchema); const valueSchema = hexToSchema(value.valueSchema); diff --git a/packages/store-sync/src/recs/common.ts b/packages/store-sync/src/recs/common.ts index abe626aa6c..ed8ac4a462 100644 --- a/packages/store-sync/src/recs/common.ts +++ b/packages/store-sync/src/recs/common.ts @@ -14,7 +14,9 @@ export type StoreComponentMetadata = RecsMetadata & { export type ConfigToRecsComponents = { [tableName in keyof TConfig["tables"] & string]: RecsComponent< { - __data: RecsType.String; + __staticData: RecsType.OptionalString; + __encodedLengths: RecsType.OptionalString; + __dynamicData: RecsType.OptionalString; } & { [fieldName in keyof TConfig["tables"][tableName]["schema"] & string]: RecsType & SchemaAbiTypeToRecsType; diff --git a/packages/store-sync/src/recs/configToRecsComponents.ts b/packages/store-sync/src/recs/configToRecsComponents.ts index c9ad93fd85..299731519f 100644 --- a/packages/store-sync/src/recs/configToRecsComponents.ts +++ b/packages/store-sync/src/recs/configToRecsComponents.ts @@ -21,7 +21,9 @@ export function configToRecsComponents( schemaAbiTypeToRecsType[schemaAbiType as SchemaAbiType], ]) ), - __data: Type.String, + __staticData: Type.OptionalString, + __encodedLengths: Type.OptionalString, + __dynamicData: Type.OptionalString, }, { id: tableIdToHex(config.namespace, tableName), diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index 5a51e87763..96bdb00f00 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -12,17 +12,19 @@ import { defineInternalComponents } from "./defineInternalComponents"; import { getTableEntity } from "./getTableEntity"; import { StoreComponentMetadata } from "./common"; import { hexToTableId } from "@latticexyz/common"; -import { decodeValue } from "@latticexyz/protocol-parser"; -import { Hex } from "viem"; +import { decodeValueArgs, readHex, staticDataLength } from "@latticexyz/protocol-parser"; +import { Hex, concatHex } from "viem"; import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; -import { spliceValueHex } from "../spliceValueHex"; +import { assertExhaustive } from "@latticexyz/common/utils"; +import { isStaticAbiType } from "@latticexyz/schema-type"; export function recsStorage({ components, }: { + // TODO: switch to RECS world so we can fetch components from current list in case new components are registered later components: ReturnType & Record>; config?: TConfig; @@ -61,7 +63,9 @@ export function recsStorage({ const component = componentsByTableId[table.tableId]; if (!component) { debug( - `skipping update for unknown component: ${table.tableId}. Available components: ${Object.keys(components)}` + `skipping update for unknown component: ${table.tableId} (${table.namespace}:${ + table.name + }). Available components: ${Object.keys(components)}` ); continue; } @@ -69,18 +73,92 @@ export function recsStorage({ const entity = hexKeyTupleToEntity(log.args.key); if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { - const value = decodeValue(table.valueSchema, log.args.data); - debug("setting component", table.tableId, entity, value); - setComponent(component, entity, { ...value, __data: log.args.data }); - } else if (log.eventName === "StoreSpliceRecord") { - const previousData = (getComponentValue(component, entity)?.__data as Hex) ?? "0x"; - const newData = spliceValueHex(previousData, log); - const newValue = decodeValue(table.valueSchema, newData); - debug("setting component via splice", table.tableId, entity, { newValue, newData, previousData }); - setComponent(component, entity, { ...newValue, __data: newData }); + const value = decodeValueArgs(table.valueSchema, log.args); + debug("setting component", { + namespace: table.namespace, + name: table.name, + entity, + value, + }); + setComponent(component, entity, { + ...value, + __staticData: log.args.staticData, + __encodedLengths: log.args.encodedLengths, + __dynamicData: log.args.dynamicData, + }); + } else if (log.eventName === "StoreSpliceStaticRecord") { + // TODO: add tests that this works when no record had been set before + const previousValue = getComponentValue(component, entity); + const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x"; + const start = log.args.start; + const end = start + log.args.deleteCount; + const newStaticData = concatHex([ + readHex(previousStaticData, 0, start), + log.args.data, + readHex(previousStaticData, end), + ]); + const newValue = decodeValueArgs(table.valueSchema, { + staticData: readHex( + newStaticData, + 0, + staticDataLength(Object.values(table.valueSchema).filter(isStaticAbiType)) + ), + encodedLengths: (previousValue?.__encodedLengths as Hex) ?? "0x", + dynamicData: (previousValue?.__dynamicData as Hex) ?? "0x", + }); + debug("setting component via splice static", { + namespace: table.namespace, + name: table.name, + entity, + previousStaticData, + newStaticData, + previousValue, + newValue, + }); + setComponent(component, entity, { + ...newValue, + __staticData: newStaticData, + }); + } else if (log.eventName === "StoreSpliceDynamicRecord") { + // TODO: add tests that this works when no record had been set before + const previousValue = getComponentValue(component, entity); + const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x"; + const start = log.args.start; + const end = start + log.args.deleteCount; + const newDynamicData = concatHex([ + readHex(previousDynamicData, 0, start), + log.args.data, + readHex(previousDynamicData, end), + ]); + const newValue = decodeValueArgs(table.valueSchema, { + staticData: (previousValue?.__staticData as Hex) ?? "0x", + // TODO: handle unchanged encoded lengths + encodedLengths: log.args.encodedLengths, + dynamicData: newDynamicData, + }); + debug("setting component via splice dynamic", { + namespace: table.namespace, + name: table.name, + entity, + previousDynamicData, + newDynamicData, + previousValue, + newValue, + }); + setComponent(component, entity, { + ...newValue, + __encodedLengths: log.args.encodedLengths, + __dynamicData: newDynamicData, + }); } else if (log.eventName === "StoreDeleteRecord") { - debug("deleting component", table.tableId, entity); + debug("deleting component", { + namespace: table.namespace, + name: table.name, + entity, + }); removeComponent(component, entity); + } else { + assertExhaustive(log.eventName); } } }; diff --git a/packages/store-sync/src/spliceValueHex.ts b/packages/store-sync/src/spliceValueHex.ts index 499a7269f5..599b3a9a1c 100644 --- a/packages/store-sync/src/spliceValueHex.ts +++ b/packages/store-sync/src/spliceValueHex.ts @@ -1,19 +1,22 @@ -import { UNCHANGED_PACKED_COUNTER, padSliceHex } from "@latticexyz/protocol-parser"; +import { UNCHANGED_PACKED_COUNTER, readHex } from "@latticexyz/protocol-parser"; import { Hex, size, concatHex } from "viem"; import { StorageAdapterLog } from "./common"; -export function spliceValueHex(previousData: Hex, log: StorageAdapterLog & { eventName: "StoreSpliceRecord" }): Hex { +export function spliceValueHex( + previousData: Hex, + log: StorageAdapterLog & ({ eventName: "StoreSpliceStaticRecord" } | { eventName: "StoreSpliceDynamicRecord" }) +): Hex { let newData = previousData; if (log.args.newDynamicLengths !== UNCHANGED_PACKED_COUNTER) { const start = Number(log.args.dynamicLengthsStart); const end = start + size(log.args.newDynamicLengths); - newData = concatHex([padSliceHex(newData, 0, start), log.args.newDynamicLengths, padSliceHex(newData, end)]); + newData = concatHex([readHex(newData, 0, start), log.args.newDynamicLengths, readHex(newData, end)]); } const start = log.args.start; const end = start + log.args.deleteCount; - newData = concatHex([padSliceHex(newData, 0, start), log.args.data, padSliceHex(newData, end)]); + newData = concatHex([readHex(newData, 0, start), log.args.data, readHex(newData, end)]); return newData; } diff --git a/packages/store/src/PackedCounter.sol b/packages/store/src/PackedCounter.sol index e8f53ec949..de22e3476e 100644 --- a/packages/store/src/PackedCounter.sol +++ b/packages/store/src/PackedCounter.sol @@ -14,6 +14,9 @@ uint256 constant VAL_BITS = 5 * 8; // Maximum value of a 5-byte section uint256 constant MAX_VAL = type(uint40).max; +// We use a specific, invalid packed counter (total length != sum of lengths) to represent "unchanged" for the purpose of events and off-chain indexing +bytes32 constant UNCHANGED_PACKED_COUNTER = bytes32(uint256(1)); + /** * Static functions for PackedCounter * The caller must ensure that the value arguments are <= MAX_VAL From 1514a11578882cf41fa716f2775d0079a2be642c Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 12 Sep 2023 14:10:46 +0100 Subject: [PATCH 28/69] attempt to suppress codegen diffs --- .gitattributes | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..f9e48d85f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +**/abi/**/* linguist-generated=true +**/codegen/**/* linguist-generated=true From b8d55ab083ba106e612f17a52d17fa9f6413b965 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 12 Sep 2023 14:13:01 +0100 Subject: [PATCH 29/69] remove old typechain stuff --- .../types/ethers-contracts/IWorld.ts | 1768 ---------------- .../factories/IWorld__factory.ts | 1287 ----------- .../types/ethers-contracts/IWorld.ts | 1880 ----------------- .../factories/IWorld__factory.ts | 1310 ------------ 4 files changed, 6245 deletions(-) delete mode 100644 e2e/packages/contracts/types/ethers-contracts/IWorld.ts delete mode 100644 e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts delete mode 100644 examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts delete mode 100644 examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts diff --git a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts b/e2e/packages/contracts/types/ethers-contracts/IWorld.ts deleted file mode 100644 index 43056815a3..0000000000 --- a/e2e/packages/contracts/types/ethers-contracts/IWorld.ts +++ /dev/null @@ -1,1768 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -import type { - BaseContract, - BigNumber, - BigNumberish, - BytesLike, - CallOverrides, - ContractTransaction, - Overrides, - PayableOverrides, - PopulatedTransaction, - Signer, - utils, -} from "ethers"; -import type { - FunctionFragment, - Result, - EventFragment, -} from "@ethersproject/abi"; -import type { Listener, Provider } from "@ethersproject/providers"; -import type { - TypedEventFilter, - TypedEvent, - TypedListener, - OnEvent, - PromiseOrValue, -} from "./common"; - -export interface IWorldInterface extends utils.Interface { - functions: { - "call(bytes32,bytes)": FunctionFragment; - "callFrom(address,bytes32,bytes)": FunctionFragment; - "deleteRecord(bytes32,bytes32[],bytes32)": FunctionFragment; - "emitEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes,bytes32)": FunctionFragment; - "getField(bytes32,bytes32[],uint8,bytes32)": FunctionFragment; - "getFieldLength(bytes32,bytes32[],uint8,bytes32)": FunctionFragment; - "getFieldSlice(bytes32,bytes32[],uint8,bytes32,uint256,uint256)": FunctionFragment; - "getKeySchema(bytes32)": FunctionFragment; - "getRecord(bytes32,bytes32[],bytes32)": FunctionFragment; - "getValueSchema(bytes32)": FunctionFragment; - "grantAccess(bytes32,address)": FunctionFragment; - "installModule(address,bytes)": FunctionFragment; - "installRootModule(address,bytes)": FunctionFragment; - "pop()": FunctionFragment; - "popFromField(bytes32,bytes32[],uint8,uint256,bytes32)": FunctionFragment; - "push(uint32)": FunctionFragment; - "pushRange(uint32,uint32)": FunctionFragment; - "pushToField(bytes32,bytes32[],uint8,bytes,bytes32)": FunctionFragment; - "registerDelegation(address,bytes32,bytes)": FunctionFragment; - "registerFunctionSelector(bytes32,string,string)": FunctionFragment; - "registerNamespace(bytes16)": FunctionFragment; - "registerRootFunctionSelector(bytes32,bytes4,bytes4)": FunctionFragment; - "registerStoreHook(bytes32,address)": FunctionFragment; - "registerSystem(bytes32,address,bool)": FunctionFragment; - "registerSystemHook(bytes32,address)": FunctionFragment; - "registerTable(bytes32,bytes32,bytes32,string[],string[])": FunctionFragment; - "revokeAccess(bytes32,address)": FunctionFragment; - "set(uint32[])": FunctionFragment; - "setField(bytes32,bytes32[],uint8,bytes,bytes32)": FunctionFragment; - "setRecord(bytes32,bytes32[],bytes,bytes32,bytes,bytes32)": FunctionFragment; - "stub(uint256)": FunctionFragment; - "transferOwnership(bytes16,address)": FunctionFragment; - "updateInField(bytes32,bytes32[],uint8,uint256,bytes,bytes32)": FunctionFragment; - }; - - getFunction( - nameOrSignatureOrTopic: - | "call" - | "callFrom" - | "deleteRecord" - | "emitEphemeralRecord" - | "getField" - | "getFieldLength" - | "getFieldSlice" - | "getKeySchema" - | "getRecord" - | "getValueSchema" - | "grantAccess" - | "installModule" - | "installRootModule" - | "pop" - | "popFromField" - | "push" - | "pushRange" - | "pushToField" - | "registerDelegation" - | "registerFunctionSelector" - | "registerNamespace" - | "registerRootFunctionSelector" - | "registerStoreHook" - | "registerSystem" - | "registerSystemHook" - | "registerTable" - | "revokeAccess" - | "set" - | "setField" - | "setRecord" - | "stub" - | "transferOwnership" - | "updateInField" - ): FunctionFragment; - - encodeFunctionData( - functionFragment: "call", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "callFrom", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "deleteRecord", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "emitEphemeralRecord", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getFieldLength", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getFieldSlice", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getKeySchema", - values: [PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "getRecord", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getValueSchema", - values: [PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "grantAccess", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "installModule", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "installRootModule", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData(functionFragment: "pop", values?: undefined): string; - encodeFunctionData( - functionFragment: "popFromField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "push", - values: [PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "pushRange", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "pushToField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerDelegation", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerFunctionSelector", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerNamespace", - values: [PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "registerRootFunctionSelector", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerStoreHook", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "registerSystem", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerSystemHook", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "registerTable", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue[] - ] - ): string; - encodeFunctionData( - functionFragment: "revokeAccess", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "set", - values: [PromiseOrValue[]] - ): string; - encodeFunctionData( - functionFragment: "setField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "setRecord", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "stub", - values: [PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "transferOwnership", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "updateInField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - - decodeFunctionResult(functionFragment: "call", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "callFrom", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "deleteRecord", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "emitEphemeralRecord", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "getField", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "getFieldLength", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getFieldSlice", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getKeySchema", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "getRecord", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "getValueSchema", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "grantAccess", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "installModule", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "installRootModule", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "pop", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "popFromField", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "push", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "pushRange", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "pushToField", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerDelegation", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerFunctionSelector", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerNamespace", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerRootFunctionSelector", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerStoreHook", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerSystem", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerSystemHook", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerTable", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "revokeAccess", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "set", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "setField", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "setRecord", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "stub", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "transferOwnership", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "updateInField", - data: BytesLike - ): Result; - - events: { - "HelloWorld()": EventFragment; - "StoreDeleteRecord(bytes32,bytes32[])": EventFragment; - "StoreEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes)": EventFragment; - "StoreSetRecord(bytes32,bytes32[],bytes,bytes32,bytes)": EventFragment; - "StoreSpliceDynamicRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32)": EventFragment; - "StoreSpliceStaticRecord(bytes32,bytes32[],uint48,uint40,bytes)": EventFragment; - }; - - getEvent(nameOrSignatureOrTopic: "HelloWorld"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreDeleteRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreEphemeralRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSetRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSpliceDynamicRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSpliceStaticRecord"): EventFragment; -} - -export interface HelloWorldEventObject {} -export type HelloWorldEvent = TypedEvent<[], HelloWorldEventObject>; - -export type HelloWorldEventFilter = TypedEventFilter; - -export interface StoreDeleteRecordEventObject { - table: string; - key: string[]; -} -export type StoreDeleteRecordEvent = TypedEvent< - [string, string[]], - StoreDeleteRecordEventObject ->; - -export type StoreDeleteRecordEventFilter = - TypedEventFilter; - -export interface StoreEphemeralRecordEventObject { - table: string; - key: string[]; - staticData: string; - encodedLengths: string; - dynamicData: string; -} -export type StoreEphemeralRecordEvent = TypedEvent< - [string, string[], string, string, string], - StoreEphemeralRecordEventObject ->; - -export type StoreEphemeralRecordEventFilter = - TypedEventFilter; - -export interface StoreSetRecordEventObject { - table: string; - key: string[]; - staticData: string; - encodedLengths: string; - dynamicData: string; -} -export type StoreSetRecordEvent = TypedEvent< - [string, string[], string, string, string], - StoreSetRecordEventObject ->; - -export type StoreSetRecordEventFilter = TypedEventFilter; - -export interface StoreSpliceDynamicRecordEventObject { - table: string; - key: string[]; - start: number; - deleteCount: number; - data: string; - encodedLengths: string; -} -export type StoreSpliceDynamicRecordEvent = TypedEvent< - [string, string[], number, number, string, string], - StoreSpliceDynamicRecordEventObject ->; - -export type StoreSpliceDynamicRecordEventFilter = - TypedEventFilter; - -export interface StoreSpliceStaticRecordEventObject { - table: string; - key: string[]; - start: number; - deleteCount: number; - data: string; -} -export type StoreSpliceStaticRecordEvent = TypedEvent< - [string, string[], number, number, string], - StoreSpliceStaticRecordEventObject ->; - -export type StoreSpliceStaticRecordEventFilter = - TypedEventFilter; - -export interface IWorld extends BaseContract { - connect(signerOrProvider: Signer | Provider | string): this; - attach(addressOrName: string): this; - deployed(): Promise; - - interface: IWorldInterface; - - queryFilter( - event: TypedEventFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>; - - listeners( - eventFilter?: TypedEventFilter - ): Array>; - listeners(eventName?: string): Array; - removeAllListeners( - eventFilter: TypedEventFilter - ): this; - removeAllListeners(eventName?: string): this; - off: OnEvent; - on: OnEvent; - once: OnEvent; - removeListener: OnEvent; - - functions: { - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { data: string }>; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[BigNumber]>; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { data: string }>; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { schema: string }>; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { data: string }>; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { schema: string }>; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pop( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - push( - num: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushRange( - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - set( - list: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - stub( - arg: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[BigNumber]>; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - }; - - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pop( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - push( - num: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushRange( - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - set( - list: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - stub( - arg: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - callStatic: { - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - pop(overrides?: CallOverrides): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - push( - num: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - pushRange( - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: CallOverrides - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - set( - list: PromiseOrValue[], - overrides?: CallOverrides - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - stub( - arg: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - }; - - filters: { - "HelloWorld()"(): HelloWorldEventFilter; - HelloWorld(): HelloWorldEventFilter; - - "StoreDeleteRecord(bytes32,bytes32[])"( - table?: null, - key?: null - ): StoreDeleteRecordEventFilter; - StoreDeleteRecord(table?: null, key?: null): StoreDeleteRecordEventFilter; - - "StoreEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes)"( - table?: null, - key?: null, - staticData?: null, - encodedLengths?: null, - dynamicData?: null - ): StoreEphemeralRecordEventFilter; - StoreEphemeralRecord( - table?: null, - key?: null, - staticData?: null, - encodedLengths?: null, - dynamicData?: null - ): StoreEphemeralRecordEventFilter; - - "StoreSetRecord(bytes32,bytes32[],bytes,bytes32,bytes)"( - table?: null, - key?: null, - staticData?: null, - encodedLengths?: null, - dynamicData?: null - ): StoreSetRecordEventFilter; - StoreSetRecord( - table?: null, - key?: null, - staticData?: null, - encodedLengths?: null, - dynamicData?: null - ): StoreSetRecordEventFilter; - - "StoreSpliceDynamicRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32)"( - table?: null, - key?: null, - start?: null, - deleteCount?: null, - data?: null, - encodedLengths?: null - ): StoreSpliceDynamicRecordEventFilter; - StoreSpliceDynamicRecord( - table?: null, - key?: null, - start?: null, - deleteCount?: null, - data?: null, - encodedLengths?: null - ): StoreSpliceDynamicRecordEventFilter; - - "StoreSpliceStaticRecord(bytes32,bytes32[],uint48,uint40,bytes)"( - table?: null, - key?: null, - start?: null, - deleteCount?: null, - data?: null - ): StoreSpliceStaticRecordEventFilter; - StoreSpliceStaticRecord( - table?: null, - key?: null, - start?: null, - deleteCount?: null, - data?: null - ): StoreSpliceStaticRecordEventFilter; - }; - - estimateGas: { - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pop( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - push( - num: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushRange( - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - set( - list: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - stub( - arg: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - }; - - populateTransaction: { - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pop( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - push( - num: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushRange( - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - set( - list: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - stub( - arg: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - }; -} diff --git a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts deleted file mode 100644 index 3fc16611e6..0000000000 --- a/e2e/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ /dev/null @@ -1,1287 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ - -import { Contract, Signer, utils } from "ethers"; -import type { Provider } from "@ethersproject/providers"; -import type { IWorld, IWorldInterface } from "../IWorld"; - -const _abi = [ - { - inputs: [ - { - internalType: "string", - name: "resource", - type: "string", - }, - { - internalType: "address", - name: "caller", - type: "address", - }, - ], - name: "AccessDenied", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "delegator", - type: "address", - }, - { - internalType: "address", - name: "delegatee", - type: "address", - }, - ], - name: "DelegationNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes4", - name: "functionSelector", - type: "bytes4", - }, - ], - name: "FunctionSelectorExists", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes4", - name: "functionSelector", - type: "bytes4", - }, - ], - name: "FunctionSelectorNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "resource", - type: "string", - }, - ], - name: "InvalidSelector", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "module", - type: "string", - }, - ], - name: "ModuleAlreadyInstalled", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "resource", - type: "string", - }, - ], - name: "ResourceExists", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "resource", - type: "string", - }, - ], - name: "ResourceNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "length", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_DataIndexOverflow", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "expected", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_InvalidDynamicDataLength", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "expected", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_InvalidFieldNamesLength", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "expected", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_InvalidKeyNamesLength", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "expected", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_InvalidStaticDataLength", - type: "error", - }, - { - inputs: [], - name: "StoreCore_NotDynamicField", - type: "error", - }, - { - inputs: [], - name: "StoreCore_NotImplemented", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "tableId", - type: "bytes32", - }, - { - internalType: "string", - name: "tableIdString", - type: "string", - }, - ], - name: "StoreCore_TableAlreadyExists", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "tableId", - type: "bytes32", - }, - { - internalType: "string", - name: "tableIdString", - type: "string", - }, - ], - name: "StoreCore_TableNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "system", - type: "address", - }, - ], - name: "SystemExists", - type: "error", - }, - { - inputs: [], - name: "TestError1", - type: "error", - }, - { - inputs: [ - { - components: [ - { - internalType: "int32", - name: "x", - type: "int32", - }, - { - internalType: "int32", - name: "y", - type: "int32", - }, - ], - internalType: "struct Position", - name: "position", - type: "tuple", - }, - { - internalType: "uint256", - name: "value", - type: "uint256", - }, - { - internalType: "string", - name: "name", - type: "string", - }, - { - internalType: "bool", - name: "flag", - type: "bool", - }, - ], - name: "TestError2", - type: "error", - }, - { - anonymous: false, - inputs: [], - name: "HelloWorld", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - ], - name: "StoreDeleteRecord", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - indexed: false, - internalType: "bytes", - name: "staticData", - type: "bytes", - }, - { - indexed: false, - internalType: "bytes32", - name: "encodedLengths", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes", - name: "dynamicData", - type: "bytes", - }, - ], - name: "StoreEphemeralRecord", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - indexed: false, - internalType: "bytes", - name: "staticData", - type: "bytes", - }, - { - indexed: false, - internalType: "bytes32", - name: "encodedLengths", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes", - name: "dynamicData", - type: "bytes", - }, - ], - name: "StoreSetRecord", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - indexed: false, - internalType: "uint48", - name: "start", - type: "uint48", - }, - { - indexed: false, - internalType: "uint40", - name: "deleteCount", - type: "uint40", - }, - { - indexed: false, - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - indexed: false, - internalType: "bytes32", - name: "encodedLengths", - type: "bytes32", - }, - ], - name: "StoreSpliceDynamicRecord", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - indexed: false, - internalType: "uint48", - name: "start", - type: "uint48", - }, - { - indexed: false, - internalType: "uint40", - name: "deleteCount", - type: "uint40", - }, - { - indexed: false, - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - name: "StoreSpliceStaticRecord", - type: "event", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "bytes", - name: "funcSelectorAndArgs", - type: "bytes", - }, - ], - name: "call", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes", - }, - ], - stateMutability: "payable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "delegator", - type: "address", - }, - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "bytes", - name: "funcSelectorAndArgs", - type: "bytes", - }, - ], - name: "callFrom", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes", - }, - ], - stateMutability: "payable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "deleteRecord", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "bytes", - name: "staticData", - type: "bytes", - }, - { - internalType: "PackedCounter", - name: "encodedLengths", - type: "bytes32", - }, - { - internalType: "bytes", - name: "dynamicData", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "emitEphemeralRecord", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "getField", - outputs: [ - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "getFieldLength", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - { - internalType: "uint256", - name: "start", - type: "uint256", - }, - { - internalType: "uint256", - name: "end", - type: "uint256", - }, - ], - name: "getFieldSlice", - outputs: [ - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - ], - name: "getKeySchema", - outputs: [ - { - internalType: "Schema", - name: "schema", - type: "bytes32", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "getRecord", - outputs: [ - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - ], - name: "getValueSchema", - outputs: [ - { - internalType: "Schema", - name: "schema", - type: "bytes32", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "address", - name: "grantee", - type: "address", - }, - ], - name: "grantAccess", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "contract IModule", - name: "module", - type: "address", - }, - { - internalType: "bytes", - name: "args", - type: "bytes", - }, - ], - name: "installModule", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "contract IModule", - name: "module", - type: "address", - }, - { - internalType: "bytes", - name: "args", - type: "bytes", - }, - ], - name: "installRootModule", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "pop", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "uint256", - name: "byteLengthToPop", - type: "uint256", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "popFromField", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint32", - name: "num", - type: "uint32", - }, - ], - name: "push", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint32", - name: "start", - type: "uint32", - }, - { - internalType: "uint32", - name: "end", - type: "uint32", - }, - ], - name: "pushRange", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "bytes", - name: "dataToPush", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "pushToField", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "delegatee", - type: "address", - }, - { - internalType: "bytes32", - name: "delegationControlId", - type: "bytes32", - }, - { - internalType: "bytes", - name: "initFuncSelectorAndArgs", - type: "bytes", - }, - ], - name: "registerDelegation", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "string", - name: "systemFunctionName", - type: "string", - }, - { - internalType: "string", - name: "systemFunctionArguments", - type: "string", - }, - ], - name: "registerFunctionSelector", - outputs: [ - { - internalType: "bytes4", - name: "worldFunctionSelector", - type: "bytes4", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes16", - name: "namespace", - type: "bytes16", - }, - ], - name: "registerNamespace", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "bytes4", - name: "worldFunctionSelector", - type: "bytes4", - }, - { - internalType: "bytes4", - name: "systemFunctionSelector", - type: "bytes4", - }, - ], - name: "registerRootFunctionSelector", - outputs: [ - { - internalType: "bytes4", - name: "", - type: "bytes4", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "contract IStoreHook", - name: "hook", - type: "address", - }, - ], - name: "registerStoreHook", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "contract WorldContextConsumer", - name: "system", - type: "address", - }, - { - internalType: "bool", - name: "publicAccess", - type: "bool", - }, - ], - name: "registerSystem", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "contract ISystemHook", - name: "hook", - type: "address", - }, - ], - name: "registerSystemHook", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "Schema", - name: "keySchema", - type: "bytes32", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - { - internalType: "string[]", - name: "keyNames", - type: "string[]", - }, - { - internalType: "string[]", - name: "fieldNames", - type: "string[]", - }, - ], - name: "registerTable", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "address", - name: "grantee", - type: "address", - }, - ], - name: "revokeAccess", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint32[]", - name: "list", - type: "uint32[]", - }, - ], - name: "set", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "setField", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "bytes", - name: "staticData", - type: "bytes", - }, - { - internalType: "PackedCounter", - name: "encodedLengths", - type: "bytes32", - }, - { - internalType: "bytes", - name: "dynamicData", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "setRecord", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint256", - name: "arg", - type: "uint256", - }, - ], - name: "stub", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "pure", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes16", - name: "namespace", - type: "bytes16", - }, - { - internalType: "address", - name: "newOwner", - type: "address", - }, - ], - name: "transferOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "uint256", - name: "startByteIndex", - type: "uint256", - }, - { - internalType: "bytes", - name: "dataToSet", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "updateInField", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, -] as const; - -export class IWorld__factory { - static readonly abi = _abi; - static createInterface(): IWorldInterface { - return new utils.Interface(_abi) as IWorldInterface; - } - static connect(address: string, signerOrProvider: Signer | Provider): IWorld { - return new Contract(address, _abi, signerOrProvider) as IWorld; - } -} diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts b/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts deleted file mode 100644 index 6af787f25c..0000000000 --- a/examples/minimal/packages/contracts/types/ethers-contracts/IWorld.ts +++ /dev/null @@ -1,1880 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ -import type { - BaseContract, - BigNumber, - BigNumberish, - BytesLike, - CallOverrides, - ContractTransaction, - Overrides, - PayableOverrides, - PopulatedTransaction, - Signer, - utils, -} from "ethers"; -import type { - FunctionFragment, - Result, - EventFragment, -} from "@ethersproject/abi"; -import type { Listener, Provider } from "@ethersproject/providers"; -import type { - TypedEventFilter, - TypedEvent, - TypedListener, - OnEvent, - PromiseOrValue, -} from "./common"; - -export type BytesStructStruct = { value: PromiseOrValue }; - -export type BytesStructStructOutput = [string] & { value: string }; - -export type StringStructStruct = { value: PromiseOrValue }; - -export type StringStructStructOutput = [string] & { value: string }; - -export interface IWorldInterface extends utils.Interface { - functions: { - "call(bytes32,bytes)": FunctionFragment; - "callFrom(address,bytes32,bytes)": FunctionFragment; - "deleteRecord(bytes32,bytes32[],bytes32)": FunctionFragment; - "dynamicArrayBytesStruct((bytes)[])": FunctionFragment; - "dynamicArrayStringStruct((string)[])": FunctionFragment; - "emitEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes,bytes32)": FunctionFragment; - "getField(bytes32,bytes32[],uint8,bytes32)": FunctionFragment; - "getFieldLength(bytes32,bytes32[],uint8,bytes32)": FunctionFragment; - "getFieldSlice(bytes32,bytes32[],uint8,bytes32,uint256,uint256)": FunctionFragment; - "getKeySchema(bytes32)": FunctionFragment; - "getRecord(bytes32,bytes32[],bytes32)": FunctionFragment; - "getValueSchema(bytes32)": FunctionFragment; - "grantAccess(bytes32,address)": FunctionFragment; - "increment()": FunctionFragment; - "installModule(address,bytes)": FunctionFragment; - "installRootModule(address,bytes)": FunctionFragment; - "pickUp(uint32,uint32)": FunctionFragment; - "popFromField(bytes32,bytes32[],uint8,uint256,bytes32)": FunctionFragment; - "pushToField(bytes32,bytes32[],uint8,bytes,bytes32)": FunctionFragment; - "registerDelegation(address,bytes32,bytes)": FunctionFragment; - "registerFunctionSelector(bytes32,string,string)": FunctionFragment; - "registerNamespace(bytes16)": FunctionFragment; - "registerRootFunctionSelector(bytes32,bytes4,bytes4)": FunctionFragment; - "registerStoreHook(bytes32,address)": FunctionFragment; - "registerSystem(bytes32,address,bool)": FunctionFragment; - "registerSystemHook(bytes32,address)": FunctionFragment; - "registerTable(bytes32,bytes32,bytes32,string[],string[])": FunctionFragment; - "revokeAccess(bytes32,address)": FunctionFragment; - "sendMessage(string)": FunctionFragment; - "setField(bytes32,bytes32[],uint8,bytes,bytes32)": FunctionFragment; - "setRecord(bytes32,bytes32[],bytes,bytes32,bytes,bytes32)": FunctionFragment; - "staticArrayBytesStruct(tuple[1])": FunctionFragment; - "staticArrayStringStruct(tuple[1])": FunctionFragment; - "transferOwnership(bytes16,address)": FunctionFragment; - "updateInField(bytes32,bytes32[],uint8,uint256,bytes,bytes32)": FunctionFragment; - "willRevert()": FunctionFragment; - }; - - getFunction( - nameOrSignatureOrTopic: - | "call" - | "callFrom" - | "deleteRecord" - | "dynamicArrayBytesStruct" - | "dynamicArrayStringStruct" - | "emitEphemeralRecord" - | "getField" - | "getFieldLength" - | "getFieldSlice" - | "getKeySchema" - | "getRecord" - | "getValueSchema" - | "grantAccess" - | "increment" - | "installModule" - | "installRootModule" - | "pickUp" - | "popFromField" - | "pushToField" - | "registerDelegation" - | "registerFunctionSelector" - | "registerNamespace" - | "registerRootFunctionSelector" - | "registerStoreHook" - | "registerSystem" - | "registerSystemHook" - | "registerTable" - | "revokeAccess" - | "sendMessage" - | "setField" - | "setRecord" - | "staticArrayBytesStruct" - | "staticArrayStringStruct" - | "transferOwnership" - | "updateInField" - | "willRevert" - ): FunctionFragment; - - encodeFunctionData( - functionFragment: "call", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "callFrom", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "deleteRecord", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "dynamicArrayBytesStruct", - values: [BytesStructStruct[]] - ): string; - encodeFunctionData( - functionFragment: "dynamicArrayStringStruct", - values: [StringStructStruct[]] - ): string; - encodeFunctionData( - functionFragment: "emitEphemeralRecord", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getFieldLength", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getFieldSlice", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getKeySchema", - values: [PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "getRecord", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "getValueSchema", - values: [PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "grantAccess", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData(functionFragment: "increment", values?: undefined): string; - encodeFunctionData( - functionFragment: "installModule", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "installRootModule", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "pickUp", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "popFromField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "pushToField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerDelegation", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerFunctionSelector", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerNamespace", - values: [PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "registerRootFunctionSelector", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerStoreHook", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "registerSystem", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "registerSystemHook", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "registerTable", - values: [ - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue[] - ] - ): string; - encodeFunctionData( - functionFragment: "revokeAccess", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "sendMessage", - values: [PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "setField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "setRecord", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "staticArrayBytesStruct", - values: [[BytesStructStruct]] - ): string; - encodeFunctionData( - functionFragment: "staticArrayStringStruct", - values: [[StringStructStruct]] - ): string; - encodeFunctionData( - functionFragment: "transferOwnership", - values: [PromiseOrValue, PromiseOrValue] - ): string; - encodeFunctionData( - functionFragment: "updateInField", - values: [ - PromiseOrValue, - PromiseOrValue[], - PromiseOrValue, - PromiseOrValue, - PromiseOrValue, - PromiseOrValue - ] - ): string; - encodeFunctionData( - functionFragment: "willRevert", - values?: undefined - ): string; - - decodeFunctionResult(functionFragment: "call", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "callFrom", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "deleteRecord", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "dynamicArrayBytesStruct", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "dynamicArrayStringStruct", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "emitEphemeralRecord", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "getField", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "getFieldLength", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getFieldSlice", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "getKeySchema", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "getRecord", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "getValueSchema", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "grantAccess", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "increment", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "installModule", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "installRootModule", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "pickUp", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "popFromField", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "pushToField", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerDelegation", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerFunctionSelector", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerNamespace", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerRootFunctionSelector", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerStoreHook", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerSystem", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerSystemHook", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "registerTable", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "revokeAccess", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "sendMessage", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "setField", data: BytesLike): Result; - decodeFunctionResult(functionFragment: "setRecord", data: BytesLike): Result; - decodeFunctionResult( - functionFragment: "staticArrayBytesStruct", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "staticArrayStringStruct", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "transferOwnership", - data: BytesLike - ): Result; - decodeFunctionResult( - functionFragment: "updateInField", - data: BytesLike - ): Result; - decodeFunctionResult(functionFragment: "willRevert", data: BytesLike): Result; - - events: { - "HelloWorld()": EventFragment; - "StoreDeleteRecord(bytes32,bytes32[])": EventFragment; - "StoreEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes)": EventFragment; - "StoreSetRecord(bytes32,bytes32[],bytes,bytes32,bytes)": EventFragment; - "StoreSpliceDynamicRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32)": EventFragment; - "StoreSpliceStaticRecord(bytes32,bytes32[],uint48,uint40,bytes)": EventFragment; - }; - - getEvent(nameOrSignatureOrTopic: "HelloWorld"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreDeleteRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreEphemeralRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSetRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSpliceDynamicRecord"): EventFragment; - getEvent(nameOrSignatureOrTopic: "StoreSpliceStaticRecord"): EventFragment; -} - -export interface HelloWorldEventObject {} -export type HelloWorldEvent = TypedEvent<[], HelloWorldEventObject>; - -export type HelloWorldEventFilter = TypedEventFilter; - -export interface StoreDeleteRecordEventObject { - table: string; - key: string[]; -} -export type StoreDeleteRecordEvent = TypedEvent< - [string, string[]], - StoreDeleteRecordEventObject ->; - -export type StoreDeleteRecordEventFilter = - TypedEventFilter; - -export interface StoreEphemeralRecordEventObject { - table: string; - key: string[]; - staticData: string; - encodedLengths: string; - dynamicData: string; -} -export type StoreEphemeralRecordEvent = TypedEvent< - [string, string[], string, string, string], - StoreEphemeralRecordEventObject ->; - -export type StoreEphemeralRecordEventFilter = - TypedEventFilter; - -export interface StoreSetRecordEventObject { - table: string; - key: string[]; - staticData: string; - encodedLengths: string; - dynamicData: string; -} -export type StoreSetRecordEvent = TypedEvent< - [string, string[], string, string, string], - StoreSetRecordEventObject ->; - -export type StoreSetRecordEventFilter = TypedEventFilter; - -export interface StoreSpliceDynamicRecordEventObject { - table: string; - key: string[]; - start: number; - deleteCount: number; - data: string; - encodedLengths: string; -} -export type StoreSpliceDynamicRecordEvent = TypedEvent< - [string, string[], number, number, string, string], - StoreSpliceDynamicRecordEventObject ->; - -export type StoreSpliceDynamicRecordEventFilter = - TypedEventFilter; - -export interface StoreSpliceStaticRecordEventObject { - table: string; - key: string[]; - start: number; - deleteCount: number; - data: string; -} -export type StoreSpliceStaticRecordEvent = TypedEvent< - [string, string[], number, number, string], - StoreSpliceStaticRecordEventObject ->; - -export type StoreSpliceStaticRecordEventFilter = - TypedEventFilter; - -export interface IWorld extends BaseContract { - connect(signerOrProvider: Signer | Provider | string): this; - attach(addressOrName: string): this; - deployed(): Promise; - - interface: IWorldInterface; - - queryFilter( - event: TypedEventFilter, - fromBlockOrBlockhash?: string | number | undefined, - toBlock?: string | number | undefined - ): Promise>; - - listeners( - eventFilter?: TypedEventFilter - ): Array>; - listeners(eventName?: string): Array; - removeAllListeners( - eventFilter: TypedEventFilter - ): this; - removeAllListeners(eventName?: string): this; - off: OnEvent; - on: OnEvent; - once: OnEvent; - removeListener: OnEvent; - - functions: { - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - dynamicArrayBytesStruct( - arg0: BytesStructStruct[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - dynamicArrayStringStruct( - arg0: StringStructStruct[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { data: string }>; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[BigNumber]>; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { data: string }>; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { schema: string }>; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { data: string }>; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise<[string] & { schema: string }>; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - increment( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pickUp( - item: PromiseOrValue, - itemVariant: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - sendMessage( - message: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - staticArrayBytesStruct( - arg0: [BytesStructStruct], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - staticArrayStringStruct( - arg0: [StringStructStruct], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - willRevert( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - }; - - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - dynamicArrayBytesStruct( - arg0: BytesStructStruct[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - dynamicArrayStringStruct( - arg0: StringStructStruct[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - increment( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pickUp( - item: PromiseOrValue, - itemVariant: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - sendMessage( - message: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - staticArrayBytesStruct( - arg0: [BytesStructStruct], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - staticArrayStringStruct( - arg0: [StringStructStruct], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - willRevert( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - callStatic: { - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - dynamicArrayBytesStruct( - arg0: BytesStructStruct[], - overrides?: CallOverrides - ): Promise; - - dynamicArrayStringStruct( - arg0: StringStructStruct[], - overrides?: CallOverrides - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - increment(overrides?: CallOverrides): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - pickUp( - item: PromiseOrValue, - itemVariant: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: CallOverrides - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - sendMessage( - message: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - staticArrayBytesStruct( - arg0: [BytesStructStruct], - overrides?: CallOverrides - ): Promise; - - staticArrayStringStruct( - arg0: [StringStructStruct], - overrides?: CallOverrides - ): Promise; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - willRevert(overrides?: CallOverrides): Promise; - }; - - filters: { - "HelloWorld()"(): HelloWorldEventFilter; - HelloWorld(): HelloWorldEventFilter; - - "StoreDeleteRecord(bytes32,bytes32[])"( - table?: null, - key?: null - ): StoreDeleteRecordEventFilter; - StoreDeleteRecord(table?: null, key?: null): StoreDeleteRecordEventFilter; - - "StoreEphemeralRecord(bytes32,bytes32[],bytes,bytes32,bytes)"( - table?: null, - key?: null, - staticData?: null, - encodedLengths?: null, - dynamicData?: null - ): StoreEphemeralRecordEventFilter; - StoreEphemeralRecord( - table?: null, - key?: null, - staticData?: null, - encodedLengths?: null, - dynamicData?: null - ): StoreEphemeralRecordEventFilter; - - "StoreSetRecord(bytes32,bytes32[],bytes,bytes32,bytes)"( - table?: null, - key?: null, - staticData?: null, - encodedLengths?: null, - dynamicData?: null - ): StoreSetRecordEventFilter; - StoreSetRecord( - table?: null, - key?: null, - staticData?: null, - encodedLengths?: null, - dynamicData?: null - ): StoreSetRecordEventFilter; - - "StoreSpliceDynamicRecord(bytes32,bytes32[],uint48,uint40,bytes,bytes32)"( - table?: null, - key?: null, - start?: null, - deleteCount?: null, - data?: null, - encodedLengths?: null - ): StoreSpliceDynamicRecordEventFilter; - StoreSpliceDynamicRecord( - table?: null, - key?: null, - start?: null, - deleteCount?: null, - data?: null, - encodedLengths?: null - ): StoreSpliceDynamicRecordEventFilter; - - "StoreSpliceStaticRecord(bytes32,bytes32[],uint48,uint40,bytes)"( - table?: null, - key?: null, - start?: null, - deleteCount?: null, - data?: null - ): StoreSpliceStaticRecordEventFilter; - StoreSpliceStaticRecord( - table?: null, - key?: null, - start?: null, - deleteCount?: null, - data?: null - ): StoreSpliceStaticRecordEventFilter; - }; - - estimateGas: { - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - dynamicArrayBytesStruct( - arg0: BytesStructStruct[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - dynamicArrayStringStruct( - arg0: StringStructStruct[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - increment( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pickUp( - item: PromiseOrValue, - itemVariant: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - sendMessage( - message: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - staticArrayBytesStruct( - arg0: [BytesStructStruct], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - staticArrayStringStruct( - arg0: [StringStructStruct], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - willRevert( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - }; - - populateTransaction: { - call( - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - callFrom( - delegator: PromiseOrValue, - resourceSelector: PromiseOrValue, - funcSelectorAndArgs: PromiseOrValue, - overrides?: PayableOverrides & { from?: PromiseOrValue } - ): Promise; - - deleteRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - dynamicArrayBytesStruct( - arg0: BytesStructStruct[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - dynamicArrayStringStruct( - arg0: StringStructStruct[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - emitEphemeralRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - getField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldLength( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getFieldSlice( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - valueSchema: PromiseOrValue, - start: PromiseOrValue, - end: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getKeySchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - valueSchema: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - getValueSchema( - table: PromiseOrValue, - overrides?: CallOverrides - ): Promise; - - grantAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - increment( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - installRootModule( - module: PromiseOrValue, - args: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pickUp( - item: PromiseOrValue, - itemVariant: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - popFromField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - byteLengthToPop: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - pushToField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - dataToPush: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerDelegation( - delegatee: PromiseOrValue, - delegationControlId: PromiseOrValue, - initFuncSelectorAndArgs: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerFunctionSelector( - resourceSelector: PromiseOrValue, - systemFunctionName: PromiseOrValue, - systemFunctionArguments: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerNamespace( - namespace: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerRootFunctionSelector( - resourceSelector: PromiseOrValue, - worldFunctionSelector: PromiseOrValue, - systemFunctionSelector: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerStoreHook( - table: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystem( - resourceSelector: PromiseOrValue, - system: PromiseOrValue, - publicAccess: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerSystemHook( - resourceSelector: PromiseOrValue, - hook: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - registerTable( - table: PromiseOrValue, - keySchema: PromiseOrValue, - valueSchema: PromiseOrValue, - keyNames: PromiseOrValue[], - fieldNames: PromiseOrValue[], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - revokeAccess( - resourceSelector: PromiseOrValue, - grantee: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - sendMessage( - message: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - data: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - setRecord( - table: PromiseOrValue, - key: PromiseOrValue[], - staticData: PromiseOrValue, - encodedLengths: PromiseOrValue, - dynamicData: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - staticArrayBytesStruct( - arg0: [BytesStructStruct], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - staticArrayStringStruct( - arg0: [StringStructStruct], - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - transferOwnership( - namespace: PromiseOrValue, - newOwner: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - updateInField( - table: PromiseOrValue, - key: PromiseOrValue[], - schemaIndex: PromiseOrValue, - startByteIndex: PromiseOrValue, - dataToSet: PromiseOrValue, - valueSchema: PromiseOrValue, - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - - willRevert( - overrides?: Overrides & { from?: PromiseOrValue } - ): Promise; - }; -} diff --git a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts b/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts deleted file mode 100644 index 9cd6b8288c..0000000000 --- a/examples/minimal/packages/contracts/types/ethers-contracts/factories/IWorld__factory.ts +++ /dev/null @@ -1,1310 +0,0 @@ -/* Autogenerated file. Do not edit manually. */ -/* tslint:disable */ -/* eslint-disable */ - -import { Contract, Signer, utils } from "ethers"; -import type { Provider } from "@ethersproject/providers"; -import type { IWorld, IWorldInterface } from "../IWorld"; - -const _abi = [ - { - inputs: [ - { - internalType: "string", - name: "resource", - type: "string", - }, - { - internalType: "address", - name: "caller", - type: "address", - }, - ], - name: "AccessDenied", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "delegator", - type: "address", - }, - { - internalType: "address", - name: "delegatee", - type: "address", - }, - ], - name: "DelegationNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes4", - name: "functionSelector", - type: "bytes4", - }, - ], - name: "FunctionSelectorExists", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes4", - name: "functionSelector", - type: "bytes4", - }, - ], - name: "FunctionSelectorNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "resource", - type: "string", - }, - ], - name: "InvalidSelector", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "module", - type: "string", - }, - ], - name: "ModuleAlreadyInstalled", - type: "error", - }, - { - inputs: [], - name: "MyCustomError", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "resource", - type: "string", - }, - ], - name: "ResourceExists", - type: "error", - }, - { - inputs: [ - { - internalType: "string", - name: "resource", - type: "string", - }, - ], - name: "ResourceNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "length", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_DataIndexOverflow", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "expected", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_InvalidDynamicDataLength", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "expected", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_InvalidFieldNamesLength", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "expected", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_InvalidKeyNamesLength", - type: "error", - }, - { - inputs: [ - { - internalType: "uint256", - name: "expected", - type: "uint256", - }, - { - internalType: "uint256", - name: "received", - type: "uint256", - }, - ], - name: "StoreCore_InvalidStaticDataLength", - type: "error", - }, - { - inputs: [], - name: "StoreCore_NotDynamicField", - type: "error", - }, - { - inputs: [], - name: "StoreCore_NotImplemented", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "tableId", - type: "bytes32", - }, - { - internalType: "string", - name: "tableIdString", - type: "string", - }, - ], - name: "StoreCore_TableAlreadyExists", - type: "error", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "tableId", - type: "bytes32", - }, - { - internalType: "string", - name: "tableIdString", - type: "string", - }, - ], - name: "StoreCore_TableNotFound", - type: "error", - }, - { - inputs: [ - { - internalType: "address", - name: "system", - type: "address", - }, - ], - name: "SystemExists", - type: "error", - }, - { - anonymous: false, - inputs: [], - name: "HelloWorld", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - ], - name: "StoreDeleteRecord", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - indexed: false, - internalType: "bytes", - name: "staticData", - type: "bytes", - }, - { - indexed: false, - internalType: "bytes32", - name: "encodedLengths", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes", - name: "dynamicData", - type: "bytes", - }, - ], - name: "StoreEphemeralRecord", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - indexed: false, - internalType: "bytes", - name: "staticData", - type: "bytes", - }, - { - indexed: false, - internalType: "bytes32", - name: "encodedLengths", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes", - name: "dynamicData", - type: "bytes", - }, - ], - name: "StoreSetRecord", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - indexed: false, - internalType: "uint48", - name: "start", - type: "uint48", - }, - { - indexed: false, - internalType: "uint40", - name: "deleteCount", - type: "uint40", - }, - { - indexed: false, - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - indexed: false, - internalType: "bytes32", - name: "encodedLengths", - type: "bytes32", - }, - ], - name: "StoreSpliceDynamicRecord", - type: "event", - }, - { - anonymous: false, - inputs: [ - { - indexed: false, - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - indexed: false, - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - indexed: false, - internalType: "uint48", - name: "start", - type: "uint48", - }, - { - indexed: false, - internalType: "uint40", - name: "deleteCount", - type: "uint40", - }, - { - indexed: false, - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - name: "StoreSpliceStaticRecord", - type: "event", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "bytes", - name: "funcSelectorAndArgs", - type: "bytes", - }, - ], - name: "call", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes", - }, - ], - stateMutability: "payable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "delegator", - type: "address", - }, - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "bytes", - name: "funcSelectorAndArgs", - type: "bytes", - }, - ], - name: "callFrom", - outputs: [ - { - internalType: "bytes", - name: "", - type: "bytes", - }, - ], - stateMutability: "payable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "deleteRecord", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - components: [ - { - internalType: "bytes", - name: "value", - type: "bytes", - }, - ], - internalType: "struct BytesStruct[]", - name: "", - type: "tuple[]", - }, - ], - name: "dynamicArrayBytesStruct", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - components: [ - { - internalType: "string", - name: "value", - type: "string", - }, - ], - internalType: "struct StringStruct[]", - name: "", - type: "tuple[]", - }, - ], - name: "dynamicArrayStringStruct", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "bytes", - name: "staticData", - type: "bytes", - }, - { - internalType: "PackedCounter", - name: "encodedLengths", - type: "bytes32", - }, - { - internalType: "bytes", - name: "dynamicData", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "emitEphemeralRecord", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "getField", - outputs: [ - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "getFieldLength", - outputs: [ - { - internalType: "uint256", - name: "", - type: "uint256", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - { - internalType: "uint256", - name: "start", - type: "uint256", - }, - { - internalType: "uint256", - name: "end", - type: "uint256", - }, - ], - name: "getFieldSlice", - outputs: [ - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - ], - name: "getKeySchema", - outputs: [ - { - internalType: "Schema", - name: "schema", - type: "bytes32", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "getRecord", - outputs: [ - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - ], - name: "getValueSchema", - outputs: [ - { - internalType: "Schema", - name: "schema", - type: "bytes32", - }, - ], - stateMutability: "view", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "address", - name: "grantee", - type: "address", - }, - ], - name: "grantAccess", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "increment", - outputs: [ - { - internalType: "uint32", - name: "", - type: "uint32", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "contract IModule", - name: "module", - type: "address", - }, - { - internalType: "bytes", - name: "args", - type: "bytes", - }, - ], - name: "installModule", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "contract IModule", - name: "module", - type: "address", - }, - { - internalType: "bytes", - name: "args", - type: "bytes", - }, - ], - name: "installRootModule", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "uint32", - name: "item", - type: "uint32", - }, - { - internalType: "uint32", - name: "itemVariant", - type: "uint32", - }, - ], - name: "pickUp", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "uint256", - name: "byteLengthToPop", - type: "uint256", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "popFromField", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "bytes", - name: "dataToPush", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "pushToField", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "address", - name: "delegatee", - type: "address", - }, - { - internalType: "bytes32", - name: "delegationControlId", - type: "bytes32", - }, - { - internalType: "bytes", - name: "initFuncSelectorAndArgs", - type: "bytes", - }, - ], - name: "registerDelegation", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "string", - name: "systemFunctionName", - type: "string", - }, - { - internalType: "string", - name: "systemFunctionArguments", - type: "string", - }, - ], - name: "registerFunctionSelector", - outputs: [ - { - internalType: "bytes4", - name: "worldFunctionSelector", - type: "bytes4", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes16", - name: "namespace", - type: "bytes16", - }, - ], - name: "registerNamespace", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "bytes4", - name: "worldFunctionSelector", - type: "bytes4", - }, - { - internalType: "bytes4", - name: "systemFunctionSelector", - type: "bytes4", - }, - ], - name: "registerRootFunctionSelector", - outputs: [ - { - internalType: "bytes4", - name: "", - type: "bytes4", - }, - ], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "contract IStoreHook", - name: "hook", - type: "address", - }, - ], - name: "registerStoreHook", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "contract WorldContextConsumer", - name: "system", - type: "address", - }, - { - internalType: "bool", - name: "publicAccess", - type: "bool", - }, - ], - name: "registerSystem", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "contract ISystemHook", - name: "hook", - type: "address", - }, - ], - name: "registerSystemHook", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "Schema", - name: "keySchema", - type: "bytes32", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - { - internalType: "string[]", - name: "keyNames", - type: "string[]", - }, - { - internalType: "string[]", - name: "fieldNames", - type: "string[]", - }, - ], - name: "registerTable", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "resourceSelector", - type: "bytes32", - }, - { - internalType: "address", - name: "grantee", - type: "address", - }, - ], - name: "revokeAccess", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "string", - name: "message", - type: "string", - }, - ], - name: "sendMessage", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "bytes", - name: "data", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "setField", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "bytes", - name: "staticData", - type: "bytes", - }, - { - internalType: "PackedCounter", - name: "encodedLengths", - type: "bytes32", - }, - { - internalType: "bytes", - name: "dynamicData", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "setRecord", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - components: [ - { - internalType: "bytes", - name: "value", - type: "bytes", - }, - ], - internalType: "struct BytesStruct[1]", - name: "", - type: "tuple[1]", - }, - ], - name: "staticArrayBytesStruct", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - components: [ - { - internalType: "string", - name: "value", - type: "string", - }, - ], - internalType: "struct StringStruct[1]", - name: "", - type: "tuple[1]", - }, - ], - name: "staticArrayStringStruct", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes16", - name: "namespace", - type: "bytes16", - }, - { - internalType: "address", - name: "newOwner", - type: "address", - }, - ], - name: "transferOwnership", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [ - { - internalType: "bytes32", - name: "table", - type: "bytes32", - }, - { - internalType: "bytes32[]", - name: "key", - type: "bytes32[]", - }, - { - internalType: "uint8", - name: "schemaIndex", - type: "uint8", - }, - { - internalType: "uint256", - name: "startByteIndex", - type: "uint256", - }, - { - internalType: "bytes", - name: "dataToSet", - type: "bytes", - }, - { - internalType: "Schema", - name: "valueSchema", - type: "bytes32", - }, - ], - name: "updateInField", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, - { - inputs: [], - name: "willRevert", - outputs: [], - stateMutability: "nonpayable", - type: "function", - }, -] as const; - -export class IWorld__factory { - static readonly abi = _abi; - static createInterface(): IWorldInterface { - return new utils.Interface(_abi) as IWorldInterface; - } - static connect(address: string, signerOrProvider: Signer | Provider): IWorld { - return new Contract(address, _abi, signerOrProvider) as IWorld; - } -} From 4eb2c1eba44e7474fb7dd6d0f1e2cf49ef359296 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 12 Sep 2023 14:40:53 +0100 Subject: [PATCH 30/69] update postgres sync --- .../store-sync/src/postgres/buildTable.ts | 4 +- .../src/postgres/postgresStorage.ts | 113 +++++++++++++++--- packages/store-sync/src/recs/recsStorage.ts | 6 +- 3 files changed, 103 insertions(+), 20 deletions(-) diff --git a/packages/store-sync/src/postgres/buildTable.ts b/packages/store-sync/src/postgres/buildTable.ts index 6a96a70b71..2fb7feb499 100644 --- a/packages/store-sync/src/postgres/buildTable.ts +++ b/packages/store-sync/src/postgres/buildTable.ts @@ -7,7 +7,9 @@ import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser"; // TODO: convert camel case to snake case for DB storage? export const metaColumns = { __key: buildColumn("__key", "bytes").primaryKey(), - __data: buildColumn("__data", "bytes").notNull(), + __staticData: buildColumn("__staticData", "bytes"), + __encodedLengths: buildColumn("__encodedLengths", "bytes"), + __dynamicData: buildColumn("__dynamicData", "bytes"), __lastUpdatedBlockNumber: buildColumn("__lastUpdatedBlockNumber", "uint256").notNull(), // TODO: last updated block hash? __isDeleted: buildColumn("__isDeleted", "bool").notNull(), diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index 3e6d5dc2ba..b80112bb4d 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -13,8 +13,10 @@ import { getTableKey } from "./getTableKey"; import { StorageAdapter, StorageAdapterBlock } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; -import { decodeKey, decodeValue } from "@latticexyz/protocol-parser"; +import { decodeKey, decodeValue, decodeValueArgs, readHex, staticDataLength } from "@latticexyz/protocol-parser"; import { spliceValueHex } from "../spliceValueHex"; +import { assertExhaustive } from "@latticexyz/common/utils"; +import { isStaticAbiType } from "@latticexyz/schema-type"; // Currently assumes one DB per chain ID @@ -111,13 +113,20 @@ export async function postgresStorage debug(log.eventName, log); if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { - const value = decodeValue(table.valueSchema, log.args.data); - debug("upserting record", { key, value, log }); + const value = decodeValueArgs(table.valueSchema, log.args); + debug("upserting record", { + namespace: table.namespace, + name: table.name, + key, + value, + }); await tx .insert(sqlTable) .values({ __key: uniqueKey, - __data: log.args.data, + __staticData: log.args.staticData, + __encodedLengths: log.args.encodedLengths, + __dynamicData: log.args.dynamicData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, ...key, @@ -126,25 +135,45 @@ export async function postgresStorage .onConflictDoUpdate({ target: sqlTable.__key, set: { - __data: log.args.data, + __staticData: log.args.staticData, + __encodedLengths: log.args.encodedLengths, + __dynamicData: log.args.dynamicData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, ...value, }, }) .execute(); - } else if (log.eventName === "StoreSpliceRecord") { + } else if (log.eventName === "StoreSpliceStaticRecord") { // TODO: verify that this returns what we expect (doesn't error/undefined on no record) - const previousData = - (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]?.__data ?? "0x"; - const newData = spliceValueHex(previousData, log); - const newValue = decodeValue(table.valueSchema, newData); - debug("upserting record via splice", { key, previousData, newData, newValue, log }); + const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; + const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x"; + const start = log.args.start; + const end = start + log.args.deleteCount; + const newStaticData = concatHex([ + readHex(previousStaticData, 0, start), + log.args.data, + readHex(previousStaticData, end), + ]); + const newValue = decodeValueArgs(table.valueSchema, { + staticData: newStaticData, + encodedLengths: (previousValue?.__encodedLengths as Hex) ?? "0x", + dynamicData: (previousValue?.__dynamicData as Hex) ?? "0x", + }); + debug("upserting record via splice static", { + namespace: table.namespace, + name: table.name, + key, + previousStaticData, + newStaticData, + previousValue, + newValue, + }); await tx .insert(sqlTable) .values({ __key: uniqueKey, - __data: newData, + __staticData: newStaticData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, ...key, @@ -153,7 +182,57 @@ export async function postgresStorage .onConflictDoUpdate({ target: sqlTable.__key, set: { - __data: newData, + __staticData: newStaticData, + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: false, + ...newValue, + }, + }) + .execute(); + } else if (log.eventName === "StoreSpliceDynamicRecord") { + // TODO: verify that this returns what we expect (doesn't error/undefined on no record) + const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; + const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x"; + const start = log.args.start; + const end = start + log.args.deleteCount; + const newDynamicData = concatHex([ + readHex(previousDynamicData, 0, start), + log.args.data, + readHex(previousDynamicData, end), + ]); + const newValue = decodeValueArgs(table.valueSchema, { + staticData: (previousValue?.__staticData as Hex) ?? "0x", + // TODO: handle unchanged encoded lengths + encodedLengths: log.args.encodedLengths, + dynamicData: newDynamicData, + }); + debug("upserting record via splice dynamic", { + namespace: table.namespace, + name: table.name, + key, + previousDynamicData, + newDynamicData, + previousValue, + newValue, + }); + await tx + .insert(sqlTable) + .values({ + __key: uniqueKey, + // TODO: handle unchanged encoded lengths + __encodedLengths: log.args.encodedLengths, + __dynamicData: newDynamicData, + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: false, + ...key, + ...newValue, + }) + .onConflictDoUpdate({ + target: sqlTable.__key, + set: { + // TODO: handle unchanged encoded lengths + __encodedLengths: log.args.encodedLengths, + __dynamicData: newDynamicData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, ...newValue, @@ -162,7 +241,11 @@ export async function postgresStorage .execute(); } else if (log.eventName === "StoreDeleteRecord") { // TODO: should we upsert so we at least have a DB record of when a thing was created/deleted within the same block? - debug("deleting record", { key, log }); + debug("deleting record", { + namespace: table.namespace, + name: table.name, + key, + }); await tx .update(sqlTable) .set({ @@ -171,6 +254,8 @@ export async function postgresStorage }) .where(eq(sqlTable.__key, uniqueKey)) .execute(); + } else { + assertExhaustive(log.eventName); } } diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index 96bdb00f00..2eff7de8c5 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -98,11 +98,7 @@ export function recsStorage({ readHex(previousStaticData, end), ]); const newValue = decodeValueArgs(table.valueSchema, { - staticData: readHex( - newStaticData, - 0, - staticDataLength(Object.values(table.valueSchema).filter(isStaticAbiType)) - ), + staticData: newStaticData, encodedLengths: (previousValue?.__encodedLengths as Hex) ?? "0x", dynamicData: (previousValue?.__dynamicData as Hex) ?? "0x", }); From 06d660cb8ce908b49d24f3a3f8c0774c35736f47 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 12 Sep 2023 14:44:26 +0100 Subject: [PATCH 31/69] rename sqlite helpers to match postgres --- .../{buildSqliteColumn.ts => buildColumn.ts} | 2 +- ...ateSqliteTable.test.ts => buildTable.test.ts} | 8 ++++---- .../{createSqliteTable.ts => buildTable.ts} | 16 ++++++++-------- packages/store-sync/src/sqlite/index.ts | 2 +- .../store-sync/src/sqlite/sqliteStorage.test.ts | 4 ++-- packages/store-sync/src/sqlite/sqliteStorage.ts | 6 +++--- 6 files changed, 19 insertions(+), 19 deletions(-) rename packages/store-sync/src/sqlite/{buildSqliteColumn.ts => buildColumn.ts} (98%) rename packages/store-sync/src/sqlite/{createSqliteTable.test.ts => buildTable.test.ts} (99%) rename packages/store-sync/src/sqlite/{createSqliteTable.ts => buildTable.ts} (79%) diff --git a/packages/store-sync/src/sqlite/buildSqliteColumn.ts b/packages/store-sync/src/sqlite/buildColumn.ts similarity index 98% rename from packages/store-sync/src/sqlite/buildSqliteColumn.ts rename to packages/store-sync/src/sqlite/buildColumn.ts index b52daeb194..354600b146 100644 --- a/packages/store-sync/src/sqlite/buildSqliteColumn.ts +++ b/packages/store-sync/src/sqlite/buildColumn.ts @@ -4,7 +4,7 @@ import { assertExhaustive } from "@latticexyz/common/utils"; import { address, json } from "./columnTypes"; // eslint-disable-next-line @typescript-eslint/explicit-function-return-type -export function buildSqliteColumn(name: string, schemaAbiType: SchemaAbiType) { +export function buildColumn(name: string, schemaAbiType: SchemaAbiType) { switch (schemaAbiType) { case "bool": return integer(name, { mode: "boolean" }); diff --git a/packages/store-sync/src/sqlite/createSqliteTable.test.ts b/packages/store-sync/src/sqlite/buildTable.test.ts similarity index 99% rename from packages/store-sync/src/sqlite/createSqliteTable.test.ts rename to packages/store-sync/src/sqlite/buildTable.test.ts index 44349cda42..3682f84918 100644 --- a/packages/store-sync/src/sqlite/createSqliteTable.test.ts +++ b/packages/store-sync/src/sqlite/buildTable.test.ts @@ -1,9 +1,9 @@ import { describe, it, expect } from "vitest"; -import { createSqliteTable } from "./createSqliteTable"; +import { buildTable } from "./buildTable"; -describe("createSqliteTable", () => { +describe("buildTable", () => { it("should create table from schema", async () => { - const table = createSqliteTable({ + const table = buildTable({ address: "0xffffffffffffffffffffffffffffffffffffffff", namespace: "test", name: "users", @@ -512,7 +512,7 @@ describe("createSqliteTable", () => { }); it("can create a singleton table", async () => { - const table = createSqliteTable({ + const table = buildTable({ address: "0xffffffffffffffffffffffffffffffffffffffff", namespace: "test", name: "users", diff --git a/packages/store-sync/src/sqlite/createSqliteTable.ts b/packages/store-sync/src/sqlite/buildTable.ts similarity index 79% rename from packages/store-sync/src/sqlite/createSqliteTable.ts rename to packages/store-sync/src/sqlite/buildTable.ts index f3ce1be23a..d675c9748b 100644 --- a/packages/store-sync/src/sqlite/createSqliteTable.ts +++ b/packages/store-sync/src/sqlite/buildTable.ts @@ -1,15 +1,15 @@ import { SQLiteColumnBuilderBase, SQLiteTableWithColumns, sqliteTable } from "drizzle-orm/sqlite-core"; -import { buildSqliteColumn } from "./buildSqliteColumn"; +import { buildColumn } from "./buildColumn"; import { Address } from "viem"; import { getTableName } from "./getTableName"; import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser"; export const metaColumns = { - __key: buildSqliteColumn("__key", "bytes").primaryKey(), - __data: buildSqliteColumn("__data", "bytes").notNull(), - __lastUpdatedBlockNumber: buildSqliteColumn("__lastUpdatedBlockNumber", "uint256").notNull(), + __key: buildColumn("__key", "bytes").primaryKey(), + __data: buildColumn("__data", "bytes").notNull(), + __lastUpdatedBlockNumber: buildColumn("__lastUpdatedBlockNumber", "uint256").notNull(), // TODO: last updated block hash? - __isDeleted: buildSqliteColumn("__isDeleted", "bool").notNull(), + __isDeleted: buildColumn("__isDeleted", "bool").notNull(), } as const satisfies Record; type SQLiteTableFromSchema = SQLiteTableWithColumns<{ @@ -41,7 +41,7 @@ type CreateSqliteTableResult; -export function createSqliteTable({ +export function buildTable({ address, namespace, name, @@ -51,11 +51,11 @@ export function createSqliteTable [name, buildSqliteColumn(name, type).notNull()]) + Object.entries(keySchema).map(([name, type]) => [name, buildColumn(name, type).notNull()]) ); const valueColumns = Object.fromEntries( - Object.entries(valueSchema).map(([name, type]) => [name, buildSqliteColumn(name, type).notNull()]) + Object.entries(valueSchema).map(([name, type]) => [name, buildColumn(name, type).notNull()]) ); // TODO: unique constraint on key columns? diff --git a/packages/store-sync/src/sqlite/index.ts b/packages/store-sync/src/sqlite/index.ts index bcfd3948ad..8e6b2acd2e 100644 --- a/packages/store-sync/src/sqlite/index.ts +++ b/packages/store-sync/src/sqlite/index.ts @@ -1,4 +1,4 @@ -export * from "./createSqliteTable"; +export * from "./buildTable"; export * from "./getTables"; export * from "./internalTables"; export * from "./schemaVersion"; diff --git a/packages/store-sync/src/sqlite/sqliteStorage.test.ts b/packages/store-sync/src/sqlite/sqliteStorage.test.ts index 4b4224dfc6..c5694f1b59 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.test.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.test.ts @@ -3,7 +3,7 @@ import { sqliteStorage } from "./sqliteStorage"; import { getTables } from "./getTables"; import { chainState, mudStoreTables } from "./internalTables"; import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; -import { createSqliteTable } from "./createSqliteTable"; +import { buildTable } from "./buildTable"; import initSqlJs from "sql.js"; import { drizzle } from "drizzle-orm/sql-js"; import { createPublicClient, http } from "viem"; @@ -135,7 +135,7 @@ describe("sqliteStorage", async () => { ] `); - const sqliteTable = createSqliteTable(tables[0]); + const sqliteTable = buildTable(tables[0]); expect(db.select().from(sqliteTable).all()).toMatchInlineSnapshot("[]"); }); }); diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 9ad257a7ec..8e9f9cdf6a 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -2,7 +2,7 @@ import { Hex, PublicClient, concatHex, getAddress } from "viem"; import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; import { and, eq, sql } from "drizzle-orm"; import { sqliteTableToSql } from "./sqliteTableToSql"; -import { createSqliteTable } from "./createSqliteTable"; +import { buildTable } from "./buildTable"; import { StoreConfig } from "@latticexyz/store"; import { debug } from "./debug"; import { getTableName } from "./getTableName"; @@ -39,7 +39,7 @@ export async function sqliteStorage({ for (const table of newTables) { debug(`creating table ${table.namespace}:${table.name} for world ${chainId}:${table.address}`); - const sqliteTable = createSqliteTable({ + const sqliteTable = buildTable({ address: table.address, namespace: table.namespace, name: table.name, @@ -104,7 +104,7 @@ export async function sqliteStorage({ continue; } - const sqliteTable = createSqliteTable(table); + const sqliteTable = buildTable(table); const uniqueKey = concatHex(log.args.key as Hex[]); const key = decodeKey(table.keySchema, log.args.key); From 7b8d66e7fde58fd40a63dfe4507ece644b5630f2 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 12 Sep 2023 14:48:13 +0100 Subject: [PATCH 32/69] update sqlite sync --- packages/store-sync/src/sqlite/buildTable.ts | 4 +- .../store-sync/src/sqlite/sqliteStorage.ts | 125 +++++++++++++++--- 2 files changed, 106 insertions(+), 23 deletions(-) diff --git a/packages/store-sync/src/sqlite/buildTable.ts b/packages/store-sync/src/sqlite/buildTable.ts index d675c9748b..2b9b0efd5c 100644 --- a/packages/store-sync/src/sqlite/buildTable.ts +++ b/packages/store-sync/src/sqlite/buildTable.ts @@ -6,7 +6,9 @@ import { KeySchema, ValueSchema } from "@latticexyz/protocol-parser"; export const metaColumns = { __key: buildColumn("__key", "bytes").primaryKey(), - __data: buildColumn("__data", "bytes").notNull(), + __staticData: buildColumn("__staticData", "bytes"), + __encodedLengths: buildColumn("__encodedLengths", "bytes"), + __dynamicData: buildColumn("__dynamicData", "bytes"), __lastUpdatedBlockNumber: buildColumn("__lastUpdatedBlockNumber", "uint256").notNull(), // TODO: last updated block hash? __isDeleted: buildColumn("__isDeleted", "bool").notNull(), diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 8e9f9cdf6a..83569d9839 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -13,8 +13,9 @@ import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexToTableId, tableIdToHex } from "@latticexyz/common"; -import { decodeKey, decodeValue } from "@latticexyz/protocol-parser"; +import { decodeKey, decodeValue, decodeValueArgs, readHex } from "@latticexyz/protocol-parser"; import { spliceValueHex } from "../spliceValueHex"; +import { assertExhaustive } from "@latticexyz/common/utils"; // TODO: upgrade drizzle and use async sqlite interface for consistency @@ -104,53 +105,127 @@ export async function sqliteStorage({ continue; } - const sqliteTable = buildTable(table); + const sqlTable = buildTable(table); const uniqueKey = concatHex(log.args.key as Hex[]); const key = decodeKey(table.keySchema, log.args.key); if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { - // TODO: figure out if we need to pad anything or set defaults - const value = decodeValue(table.valueSchema, log.args.data); - debug("upserting record", { key, value, log }); - tx.insert(sqliteTable) + const value = decodeValueArgs(table.valueSchema, log.args); + debug("upserting record", { + namespace: table.namespace, + name: table.name, + key, + value, + }); + tx.insert(sqlTable) .values({ __key: uniqueKey, - __data: log.args.data, + __staticData: log.args.staticData, + __encodedLengths: log.args.encodedLengths, + __dynamicData: log.args.dynamicData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, ...key, ...value, }) .onConflictDoUpdate({ - target: sqliteTable.__key, + target: sqlTable.__key, set: { - __data: log.args.data, + __staticData: log.args.staticData, + __encodedLengths: log.args.encodedLengths, + __dynamicData: log.args.dynamicData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, ...value, }, }) .run(); - } else if (log.eventName === "StoreSpliceRecord") { + } else if (log.eventName === "StoreSpliceStaticRecord") { // TODO: verify that this returns what we expect (doesn't error/undefined on no record) - const previousData = - tx.select().from(sqliteTable).where(eq(sqliteTable.__key, uniqueKey)).all()[0]?.__data ?? "0x"; - const newData = spliceValueHex(previousData, log); - const newValue = decodeValue(table.valueSchema, newData); - debug("upserting record via splice", { key, previousData, newData, newValue, log }); - tx.insert(sqliteTable) + const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; + const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x"; + const start = log.args.start; + const end = start + log.args.deleteCount; + const newStaticData = concatHex([ + readHex(previousStaticData, 0, start), + log.args.data, + readHex(previousStaticData, end), + ]); + const newValue = decodeValueArgs(table.valueSchema, { + staticData: newStaticData, + encodedLengths: (previousValue?.__encodedLengths as Hex) ?? "0x", + dynamicData: (previousValue?.__dynamicData as Hex) ?? "0x", + }); + debug("upserting record via splice static", { + namespace: table.namespace, + name: table.name, + key, + previousStaticData, + newStaticData, + previousValue, + newValue, + }); + tx.insert(sqlTable) .values({ __key: uniqueKey, - __data: newData, + __staticData: newStaticData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, ...key, ...newValue, }) .onConflictDoUpdate({ - target: sqliteTable.__key, + target: sqlTable.__key, set: { - __data: newData, + __staticData: newStaticData, + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: false, + ...newValue, + }, + }) + .run(); + } else if (log.eventName === "StoreSpliceDynamicRecord") { + const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; + const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x"; + const start = log.args.start; + const end = start + log.args.deleteCount; + const newDynamicData = concatHex([ + readHex(previousDynamicData, 0, start), + log.args.data, + readHex(previousDynamicData, end), + ]); + const newValue = decodeValueArgs(table.valueSchema, { + staticData: (previousValue?.__staticData as Hex) ?? "0x", + // TODO: handle unchanged encoded lengths + encodedLengths: log.args.encodedLengths, + dynamicData: newDynamicData, + }); + debug("upserting record via splice dynamic", { + namespace: table.namespace, + name: table.name, + key, + previousDynamicData, + newDynamicData, + previousValue, + newValue, + }); + tx.insert(sqlTable) + .values({ + __key: uniqueKey, + // TODO: handle unchanged encoded lengths + __encodedLengths: log.args.encodedLengths, + __dynamicData: newDynamicData, + __lastUpdatedBlockNumber: blockNumber, + __isDeleted: false, + ...key, + ...newValue, + }) + .onConflictDoUpdate({ + target: sqlTable.__key, + set: { + // TODO: handle unchanged encoded lengths + __encodedLengths: log.args.encodedLengths, + __dynamicData: newDynamicData, __lastUpdatedBlockNumber: blockNumber, __isDeleted: false, ...newValue, @@ -159,14 +234,20 @@ export async function sqliteStorage({ .run(); } else if (log.eventName === "StoreDeleteRecord") { // TODO: should we upsert so we at least have a DB record of when a thing was created/deleted within the same block? - debug("deleting record", { key, log }); - tx.update(sqliteTable) + debug("deleting record", { + namespace: table.namespace, + name: table.name, + key, + }); + tx.update(sqlTable) .set({ __lastUpdatedBlockNumber: blockNumber, __isDeleted: true, }) - .where(eq(sqliteTable.__key, uniqueKey)) + .where(eq(sqlTable.__key, uniqueKey)) .run(); + } else { + assertExhaustive(log.eventName); } } From 31b8ef84138c541a7fc947009da2234d281c4cb1 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 12 Sep 2023 14:49:23 +0100 Subject: [PATCH 33/69] fix import --- packages/store-indexer/src/sqlite/createQueryAdapter.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/store-indexer/src/sqlite/createQueryAdapter.ts b/packages/store-indexer/src/sqlite/createQueryAdapter.ts index eae41e90c4..07d4e86949 100644 --- a/packages/store-indexer/src/sqlite/createQueryAdapter.ts +++ b/packages/store-indexer/src/sqlite/createQueryAdapter.ts @@ -1,6 +1,6 @@ import { eq } from "drizzle-orm"; import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; -import { createSqliteTable, chainState, getTables } from "@latticexyz/store-sync/sqlite"; +import { buildTable, chainState, getTables } from "@latticexyz/store-sync/sqlite"; import { QueryAdapter } from "@latticexyz/store-sync/trpc-indexer"; import { debug } from "../debug"; @@ -16,7 +16,7 @@ export async function createQueryAdapter(database: BaseSQLiteDatabase<"sync", an const tables = getTables(database).filter((table) => table.address === address); const tablesWithRecords = tables.map((table) => { - const sqliteTable = createSqliteTable(table); + const sqliteTable = buildTable(table); const records = database.select().from(sqliteTable).where(eq(sqliteTable.__isDeleted, false)).all(); return { ...table, From 789f91d9ec3b8d9a21cfe4999c90160220302d4f Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 12 Sep 2023 14:59:38 +0100 Subject: [PATCH 34/69] update test data --- e2e/packages/sync-test/data/encodeTestData.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/e2e/packages/sync-test/data/encodeTestData.test.ts b/e2e/packages/sync-test/data/encodeTestData.test.ts index df67bb56e2..818358329a 100644 --- a/e2e/packages/sync-test/data/encodeTestData.test.ts +++ b/e2e/packages/sync-test/data/encodeTestData.test.ts @@ -7,7 +7,7 @@ describe("encodeTestData", () => { Number: [ { key: ["0x000000000000000000000000000000000000000000000000000000000000002a"], - value: "0x00000539", + value: "0x000005390000000000000000000000000000000000000000000000000000000000000000", valueSchema: "0x0004010003000000000000000000000000000000000000000000000000000000", }, ], @@ -17,7 +17,7 @@ describe("encodeTestData", () => { Vector: [ { key: ["0x0000000000000000000000000000000000000000000000000000000000000539"], - value: "0x0000002affffffbb", + value: "0x0000002affffffbb0000000000000000000000000000000000000000000000000000000000000000", valueSchema: "0x0008020023230000000000000000000000000000000000000000000000000000", }, ], From 6fd0b15d7991b0df876f8dfbc62d26dcf210f69e Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Tue, 12 Sep 2023 17:21:37 +0100 Subject: [PATCH 35/69] fix StoreCore test --- packages/store/test/StoreCore.t.sol | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index 9a3823791e..60e771f3da 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -1000,7 +1000,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a revert when the RevertSubscriber's onBeforeSetRecord hook is called vm.expectRevert(bytes("onBeforeSetRecord")); - IStore(this).setRecord(table, key, data, valueSchema); + IStore(this).setRecord(table, key, data, PackedCounter.wrap(bytes32(0)), new bytes(0), valueSchema); // Expect a revert when the RevertSubscriber's onBeforeSetField hook is called vm.expectRevert(bytes("onBeforeSetField")); @@ -1015,13 +1015,13 @@ contract StoreCoreTest is Test, StoreMock { // Expect a HookCalled event to be emitted when the EchoSubscriber's onBeforeSetRecord hook is called vm.expectEmit(true, true, true, true); - emit HookCalled(abi.encode(table, key, data, valueSchema)); + emit HookCalled(abi.encode(table, key, data, PackedCounter.wrap(bytes32(0)), new bytes(0), valueSchema)); // Expect a HookCalled event to be emitted when the EchoSubscriber's onAfterSetRecord hook is called vm.expectEmit(true, true, true, true); - emit HookCalled(abi.encode(table, key, data, valueSchema)); + emit HookCalled(abi.encode(table, key, data, PackedCounter.wrap(bytes32(0)), new bytes(0), valueSchema)); - IStore(this).setRecord(table, key, data, valueSchema); + IStore(this).setRecord(table, key, data, PackedCounter.wrap(bytes32(0)), new bytes(0), valueSchema); // Expect a HookCalled event to be emitted when the EchoSubscriber's onBeforeSetField hook is called vm.expectEmit(true, true, true, true); From 78308085024ce3549ff3ac6759ecd4b99c72a9f4 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Wed, 13 Sep 2023 17:34:52 +0100 Subject: [PATCH 36/69] update test snapshots --- .../src/postgres/buildTable.test.ts | 344 ++++++++++++++++-- .../store-sync/src/sqlite/buildTable.test.ts | 296 +++++++++++++-- 2 files changed, 584 insertions(+), 56 deletions(-) diff --git a/packages/store-sync/src/postgres/buildTable.test.ts b/packages/store-sync/src/postgres/buildTable.test.ts index f4f2fcc6ff..b13b991393 100644 --- a/packages/store-sync/src/postgres/buildTable.test.ts +++ b/packages/store-sync/src/postgres/buildTable.test.ts @@ -13,7 +13,7 @@ describe("buildTable", () => { expect(table).toMatchInlineSnapshot(` PgTable { - "__data": PgCustomColumn { + "__dynamicData": PgCustomColumn { "columnType": "PgCustomColumn", "config": { "columnType": "PgCustomColumn", @@ -27,10 +27,10 @@ describe("buildTable", () => { "fieldConfig": undefined, "hasDefault": false, "isUnique": false, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, "primaryKey": false, - "uniqueName": "users___data_unique", + "uniqueName": "users___dynamicData_unique", "uniqueType": undefined, }, "dataType": "custom", @@ -41,12 +41,48 @@ describe("buildTable", () => { "isUnique": false, "mapFrom": [Function], "mapTo": [Function], - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + "uniqueName": "users___dynamicData_unique", + "uniqueType": undefined, + }, + "__encodedLengths": PgCustomColumn { + "columnType": "PgCustomColumn", + "config": { + "columnType": "PgCustomColumn", + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "dataType": "custom", + "default": undefined, + "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, + "name": "__encodedLengths", + "notNull": false, + "primaryKey": false, + "uniqueName": "users___encodedLengths_unique", + "uniqueType": undefined, + }, + "dataType": "custom", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__encodedLengths", + "notNull": false, "primary": false, "sqlName": "bytea", "table": [Circular], - "uniqueName": "users___data_unique", + "uniqueName": "users___encodedLengths_unique", "uniqueType": undefined, }, "__isDeleted": PgBoolean { @@ -148,6 +184,42 @@ describe("buildTable", () => { "uniqueName": "users___lastUpdatedBlockNumber_unique", "uniqueType": undefined, }, + "__staticData": PgCustomColumn { + "columnType": "PgCustomColumn", + "config": { + "columnType": "PgCustomColumn", + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "dataType": "custom", + "default": undefined, + "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, + "name": "__staticData", + "notNull": false, + "primaryKey": false, + "uniqueName": "users___staticData_unique", + "uniqueType": undefined, + }, + "dataType": "custom", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__staticData", + "notNull": false, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + "uniqueName": "users___staticData_unique", + "uniqueType": undefined, + }, "addr": PgCustomColumn { "columnType": "PgCustomColumn", "config": { @@ -288,7 +360,7 @@ describe("buildTable", () => { Symbol(drizzle:OriginalName): "users", Symbol(drizzle:Schema): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test", Symbol(drizzle:Columns): { - "__data": PgCustomColumn { + "__dynamicData": PgCustomColumn { "columnType": "PgCustomColumn", "config": { "columnType": "PgCustomColumn", @@ -302,10 +374,10 @@ describe("buildTable", () => { "fieldConfig": undefined, "hasDefault": false, "isUnique": false, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, "primaryKey": false, - "uniqueName": "users___data_unique", + "uniqueName": "users___dynamicData_unique", "uniqueType": undefined, }, "dataType": "custom", @@ -316,12 +388,48 @@ describe("buildTable", () => { "isUnique": false, "mapFrom": [Function], "mapTo": [Function], - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + "uniqueName": "users___dynamicData_unique", + "uniqueType": undefined, + }, + "__encodedLengths": PgCustomColumn { + "columnType": "PgCustomColumn", + "config": { + "columnType": "PgCustomColumn", + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "dataType": "custom", + "default": undefined, + "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, + "name": "__encodedLengths", + "notNull": false, + "primaryKey": false, + "uniqueName": "users___encodedLengths_unique", + "uniqueType": undefined, + }, + "dataType": "custom", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__encodedLengths", + "notNull": false, "primary": false, "sqlName": "bytea", "table": [Circular], - "uniqueName": "users___data_unique", + "uniqueName": "users___encodedLengths_unique", "uniqueType": undefined, }, "__isDeleted": PgBoolean { @@ -423,6 +531,42 @@ describe("buildTable", () => { "uniqueName": "users___lastUpdatedBlockNumber_unique", "uniqueType": undefined, }, + "__staticData": PgCustomColumn { + "columnType": "PgCustomColumn", + "config": { + "columnType": "PgCustomColumn", + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "dataType": "custom", + "default": undefined, + "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, + "name": "__staticData", + "notNull": false, + "primaryKey": false, + "uniqueName": "users___staticData_unique", + "uniqueType": undefined, + }, + "dataType": "custom", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__staticData", + "notNull": false, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + "uniqueName": "users___staticData_unique", + "uniqueType": undefined, + }, "addr": PgCustomColumn { "columnType": "PgCustomColumn", "config": { @@ -580,7 +724,7 @@ describe("buildTable", () => { expect(table).toMatchInlineSnapshot(` PgTable { - "__data": PgCustomColumn { + "__dynamicData": PgCustomColumn { "columnType": "PgCustomColumn", "config": { "columnType": "PgCustomColumn", @@ -594,10 +738,10 @@ describe("buildTable", () => { "fieldConfig": undefined, "hasDefault": false, "isUnique": false, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, "primaryKey": false, - "uniqueName": "users___data_unique", + "uniqueName": "users___dynamicData_unique", "uniqueType": undefined, }, "dataType": "custom", @@ -608,12 +752,48 @@ describe("buildTable", () => { "isUnique": false, "mapFrom": [Function], "mapTo": [Function], - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + "uniqueName": "users___dynamicData_unique", + "uniqueType": undefined, + }, + "__encodedLengths": PgCustomColumn { + "columnType": "PgCustomColumn", + "config": { + "columnType": "PgCustomColumn", + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "dataType": "custom", + "default": undefined, + "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, + "name": "__encodedLengths", + "notNull": false, + "primaryKey": false, + "uniqueName": "users___encodedLengths_unique", + "uniqueType": undefined, + }, + "dataType": "custom", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__encodedLengths", + "notNull": false, "primary": false, "sqlName": "bytea", "table": [Circular], - "uniqueName": "users___data_unique", + "uniqueName": "users___encodedLengths_unique", "uniqueType": undefined, }, "__isDeleted": PgBoolean { @@ -715,6 +895,42 @@ describe("buildTable", () => { "uniqueName": "users___lastUpdatedBlockNumber_unique", "uniqueType": undefined, }, + "__staticData": PgCustomColumn { + "columnType": "PgCustomColumn", + "config": { + "columnType": "PgCustomColumn", + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "dataType": "custom", + "default": undefined, + "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, + "name": "__staticData", + "notNull": false, + "primaryKey": false, + "uniqueName": "users___staticData_unique", + "uniqueType": undefined, + }, + "dataType": "custom", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__staticData", + "notNull": false, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + "uniqueName": "users___staticData_unique", + "uniqueType": undefined, + }, "addrs": PgCustomColumn { "columnType": "PgCustomColumn", "config": { @@ -755,7 +971,7 @@ describe("buildTable", () => { Symbol(drizzle:OriginalName): "users", Symbol(drizzle:Schema): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test", Symbol(drizzle:Columns): { - "__data": PgCustomColumn { + "__dynamicData": PgCustomColumn { "columnType": "PgCustomColumn", "config": { "columnType": "PgCustomColumn", @@ -769,10 +985,10 @@ describe("buildTable", () => { "fieldConfig": undefined, "hasDefault": false, "isUnique": false, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, "primaryKey": false, - "uniqueName": "users___data_unique", + "uniqueName": "users___dynamicData_unique", "uniqueType": undefined, }, "dataType": "custom", @@ -783,12 +999,48 @@ describe("buildTable", () => { "isUnique": false, "mapFrom": [Function], "mapTo": [Function], - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + "uniqueName": "users___dynamicData_unique", + "uniqueType": undefined, + }, + "__encodedLengths": PgCustomColumn { + "columnType": "PgCustomColumn", + "config": { + "columnType": "PgCustomColumn", + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "dataType": "custom", + "default": undefined, + "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, + "name": "__encodedLengths", + "notNull": false, + "primaryKey": false, + "uniqueName": "users___encodedLengths_unique", + "uniqueType": undefined, + }, + "dataType": "custom", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__encodedLengths", + "notNull": false, "primary": false, "sqlName": "bytea", "table": [Circular], - "uniqueName": "users___data_unique", + "uniqueName": "users___encodedLengths_unique", "uniqueType": undefined, }, "__isDeleted": PgBoolean { @@ -890,6 +1142,42 @@ describe("buildTable", () => { "uniqueName": "users___lastUpdatedBlockNumber_unique", "uniqueType": undefined, }, + "__staticData": PgCustomColumn { + "columnType": "PgCustomColumn", + "config": { + "columnType": "PgCustomColumn", + "customTypeParams": { + "dataType": [Function], + "fromDriver": [Function], + "toDriver": [Function], + }, + "dataType": "custom", + "default": undefined, + "fieldConfig": undefined, + "hasDefault": false, + "isUnique": false, + "name": "__staticData", + "notNull": false, + "primaryKey": false, + "uniqueName": "users___staticData_unique", + "uniqueType": undefined, + }, + "dataType": "custom", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "mapFrom": [Function], + "mapTo": [Function], + "name": "__staticData", + "notNull": false, + "primary": false, + "sqlName": "bytea", + "table": [Circular], + "uniqueName": "users___staticData_unique", + "uniqueType": undefined, + }, "addrs": PgCustomColumn { "columnType": "PgCustomColumn", "config": { diff --git a/packages/store-sync/src/sqlite/buildTable.test.ts b/packages/store-sync/src/sqlite/buildTable.test.ts index 3682f84918..22b1eb0a42 100644 --- a/packages/store-sync/src/sqlite/buildTable.test.ts +++ b/packages/store-sync/src/sqlite/buildTable.test.ts @@ -13,7 +13,7 @@ describe("buildTable", () => { expect(table).toMatchInlineSnapshot(` SQLiteTable { - "__data": SQLiteText { + "__dynamicData": SQLiteText { "columnType": "SQLiteText", "config": { "columnType": "SQLiteText", @@ -23,10 +23,10 @@ describe("buildTable", () => { "hasDefault": false, "isUnique": false, "length": undefined, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, "primaryKey": false, - "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___dynamicData_unique", "uniqueType": undefined, }, "dataType": "string", @@ -36,11 +36,41 @@ describe("buildTable", () => { "hasDefault": false, "isUnique": false, "length": undefined, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, + "primary": false, + "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___dynamicData_unique", + "uniqueType": undefined, + }, + "__encodedLengths": SQLiteText { + "columnType": "SQLiteText", + "config": { + "columnType": "SQLiteText", + "dataType": "string", + "default": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__encodedLengths", + "notNull": false, + "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___encodedLengths_unique", + "uniqueType": undefined, + }, + "dataType": "string", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__encodedLengths", + "notNull": false, "primary": false, "table": [Circular], - "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___encodedLengths_unique", "uniqueType": undefined, }, "__isDeleted": SQLiteBoolean { @@ -131,6 +161,36 @@ describe("buildTable", () => { "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", "uniqueType": undefined, }, + "__staticData": SQLiteText { + "columnType": "SQLiteText", + "config": { + "columnType": "SQLiteText", + "dataType": "string", + "default": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__staticData", + "notNull": false, + "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___staticData_unique", + "uniqueType": undefined, + }, + "dataType": "string", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__staticData", + "notNull": false, + "primary": false, + "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___staticData_unique", + "uniqueType": undefined, + }, "addr": SQLiteCustomColumn { "columnType": "SQLiteCustomColumn", "config": { @@ -259,7 +319,7 @@ describe("buildTable", () => { Symbol(drizzle:OriginalName): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", Symbol(drizzle:Schema): undefined, Symbol(drizzle:Columns): { - "__data": SQLiteText { + "__dynamicData": SQLiteText { "columnType": "SQLiteText", "config": { "columnType": "SQLiteText", @@ -269,10 +329,10 @@ describe("buildTable", () => { "hasDefault": false, "isUnique": false, "length": undefined, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, "primaryKey": false, - "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___dynamicData_unique", "uniqueType": undefined, }, "dataType": "string", @@ -282,11 +342,41 @@ describe("buildTable", () => { "hasDefault": false, "isUnique": false, "length": undefined, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, + "primary": false, + "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___dynamicData_unique", + "uniqueType": undefined, + }, + "__encodedLengths": SQLiteText { + "columnType": "SQLiteText", + "config": { + "columnType": "SQLiteText", + "dataType": "string", + "default": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__encodedLengths", + "notNull": false, + "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___encodedLengths_unique", + "uniqueType": undefined, + }, + "dataType": "string", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__encodedLengths", + "notNull": false, "primary": false, "table": [Circular], - "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___encodedLengths_unique", "uniqueType": undefined, }, "__isDeleted": SQLiteBoolean { @@ -377,6 +467,36 @@ describe("buildTable", () => { "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", "uniqueType": undefined, }, + "__staticData": SQLiteText { + "columnType": "SQLiteText", + "config": { + "columnType": "SQLiteText", + "dataType": "string", + "default": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__staticData", + "notNull": false, + "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___staticData_unique", + "uniqueType": undefined, + }, + "dataType": "string", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__staticData", + "notNull": false, + "primary": false, + "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___staticData_unique", + "uniqueType": undefined, + }, "addr": SQLiteCustomColumn { "columnType": "SQLiteCustomColumn", "config": { @@ -522,7 +642,7 @@ describe("buildTable", () => { expect(table).toMatchInlineSnapshot(` SQLiteTable { - "__data": SQLiteText { + "__dynamicData": SQLiteText { "columnType": "SQLiteText", "config": { "columnType": "SQLiteText", @@ -532,10 +652,10 @@ describe("buildTable", () => { "hasDefault": false, "isUnique": false, "length": undefined, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, "primaryKey": false, - "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___dynamicData_unique", "uniqueType": undefined, }, "dataType": "string", @@ -545,11 +665,41 @@ describe("buildTable", () => { "hasDefault": false, "isUnique": false, "length": undefined, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, + "primary": false, + "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___dynamicData_unique", + "uniqueType": undefined, + }, + "__encodedLengths": SQLiteText { + "columnType": "SQLiteText", + "config": { + "columnType": "SQLiteText", + "dataType": "string", + "default": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__encodedLengths", + "notNull": false, + "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___encodedLengths_unique", + "uniqueType": undefined, + }, + "dataType": "string", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__encodedLengths", + "notNull": false, "primary": false, "table": [Circular], - "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___encodedLengths_unique", "uniqueType": undefined, }, "__isDeleted": SQLiteBoolean { @@ -640,6 +790,36 @@ describe("buildTable", () => { "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", "uniqueType": undefined, }, + "__staticData": SQLiteText { + "columnType": "SQLiteText", + "config": { + "columnType": "SQLiteText", + "dataType": "string", + "default": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__staticData", + "notNull": false, + "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___staticData_unique", + "uniqueType": undefined, + }, + "dataType": "string", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__staticData", + "notNull": false, + "primary": false, + "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___staticData_unique", + "uniqueType": undefined, + }, "addrs": SQLiteCustomColumn { "columnType": "SQLiteCustomColumn", "config": { @@ -680,7 +860,7 @@ describe("buildTable", () => { Symbol(drizzle:OriginalName): "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users", Symbol(drizzle:Schema): undefined, Symbol(drizzle:Columns): { - "__data": SQLiteText { + "__dynamicData": SQLiteText { "columnType": "SQLiteText", "config": { "columnType": "SQLiteText", @@ -690,10 +870,10 @@ describe("buildTable", () => { "hasDefault": false, "isUnique": false, "length": undefined, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, "primaryKey": false, - "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___dynamicData_unique", "uniqueType": undefined, }, "dataType": "string", @@ -703,11 +883,41 @@ describe("buildTable", () => { "hasDefault": false, "isUnique": false, "length": undefined, - "name": "__data", - "notNull": true, + "name": "__dynamicData", + "notNull": false, + "primary": false, + "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___dynamicData_unique", + "uniqueType": undefined, + }, + "__encodedLengths": SQLiteText { + "columnType": "SQLiteText", + "config": { + "columnType": "SQLiteText", + "dataType": "string", + "default": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__encodedLengths", + "notNull": false, + "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___encodedLengths_unique", + "uniqueType": undefined, + }, + "dataType": "string", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__encodedLengths", + "notNull": false, "primary": false, "table": [Circular], - "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___data_unique", + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___encodedLengths_unique", "uniqueType": undefined, }, "__isDeleted": SQLiteBoolean { @@ -798,6 +1008,36 @@ describe("buildTable", () => { "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___lastUpdatedBlockNumber_unique", "uniqueType": undefined, }, + "__staticData": SQLiteText { + "columnType": "SQLiteText", + "config": { + "columnType": "SQLiteText", + "dataType": "string", + "default": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__staticData", + "notNull": false, + "primaryKey": false, + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___staticData_unique", + "uniqueType": undefined, + }, + "dataType": "string", + "default": undefined, + "defaultFn": undefined, + "enumValues": undefined, + "hasDefault": false, + "isUnique": false, + "length": undefined, + "name": "__staticData", + "notNull": false, + "primary": false, + "table": [Circular], + "uniqueName": "0xFFfFfFffFFfffFFfFFfFFFFFffFFFffffFfFFFfF__test__users___staticData_unique", + "uniqueType": undefined, + }, "addrs": SQLiteCustomColumn { "columnType": "SQLiteCustomColumn", "config": { From 510ef7de347ee9d205278e1788baa7820e79a256 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 11:32:57 +0100 Subject: [PATCH 37/69] generate test data --- test-data/world-logs.json | 744 +++++++++++++++++++------------------- 1 file changed, 379 insertions(+), 365 deletions(-) diff --git a/test-data/world-logs.json b/test-data/world-logs.json index 97dea80c14..ad9e82a25e 100644 --- a/test-data/world-logs.json +++ b/test-data/world-logs.json @@ -2,810 +2,824 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000016d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000003400060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c40000000000000000000000000000000000000000000000000000000000000000000000000000000000022000000000a0000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077461626c654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000b6669656c644c61796f757400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096b6579536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76616c7565536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012616269456e636f6465644b65794e616d657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014616269456e636f6465644669656c644e616d6573000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xd84cbdaf74c599ed411fd63e23c3d4aedd492d53efe8347769008829bab2f507", - "transactionIndex": "0x0", - "logIndex": "0x0", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000022000000000a0000000000002c0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000016d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000600060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077461626c654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000b6669656c644c61796f757400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096b6579536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76616c7565536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012616269456e636f6465644b65794e616d657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014616269456e636f6465644669656c644e616d6573000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", + "transactionIndex": "0x7", + "logIndex": "0x1", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000016d756473746f7265000000000000000053746f7265486f6f6b7300000000000000000000000000000000000000000000000000000000000000000000000001c00000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xd84cbdaf74c599ed411fd63e23c3d4aedd492d53efe8347769008829bab2f507", - "transactionIndex": "0x0", - "logIndex": "0x1", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000016d756473746f7265000000000000000053746f7265486f6f6b7300000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", + "transactionIndex": "0x7", + "logIndex": "0x2", "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000001c00014010014000000000000000000000000000000000000000000000000000000001001004f000000000000000000000000000000000000000000000000000000001401006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d657370616365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000056f776e6572000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xd84cbdaf74c599ed411fd63e23c3d4aedd492d53efe8347769008829bab2f507", - "transactionIndex": "0x0", - "logIndex": "0x2", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000001001004f0000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d657370616365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000056f776e6572000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", + "transactionIndex": "0x7", + "logIndex": "0x3", "transactionLogIndex": "0x2", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000004e616d6573706163654f776e657200000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xd84cbdaf74c599ed411fd63e23c3d4aedd492d53efe8347769008829bab2f507", - "transactionIndex": "0x0", - "logIndex": "0x3", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000042616c616e636573000000000000000000000000000000000000000000000000000000000000000000000000000000600020010020000000000000000000000000000000000000000000000000000000001001004f000000000000000000000000000000000000000000000000000000002001001f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d6573706163650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000762616c616e636500000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", + "transactionIndex": "0x7", + "logIndex": "0x4", "transactionLogIndex": "0x3", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000042616c616e636573000000000000000000000000000000000000000000000000000000000000000000000000000001c00020010020000000000000000000000000000000000000000000000000000000001001004f000000000000000000000000000000000000000000000000000000002001001f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d6573706163650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000762616c616e636500000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000003002004f5f0000000000000000000000000000000000000000000000000000001401006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a6d6f64756c654e616d6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d617267756d656e74734861736800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6d6f64756c654164647265737300000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x5", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x4", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000002200014010014000000000000000000000000000000000000000000000000000000003002004f5f0000000000000000000000000000000000000000000000000000001401006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000100000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a6d6f64756c654e616d6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d617267756d656e74734861736800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6d6f64756c654164647265737300000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000044656c65676174696f6e730000000000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000028020061610000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000964656c656761746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000964656c6567617465650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001364656c65676174696f6e436f6e74726f6c496400000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x6", - "transactionLogIndex": "0x1", + "transactionLogIndex": "0x5", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000002200001010001000000000000000000000000000000000000000000000000000000003402005f610000000000000000000000000000000000000000000000000000000101006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000100000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663616c6c6572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066163636573730000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000003402005f610000000000000000000000000000000000000000000000000000000101006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663616c6c6572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066163636573730000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x7", - "transactionLogIndex": "0x2", + "transactionLogIndex": "0x6", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000002200015020014010000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000015020061600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000a0000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000673797374656d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c7075626c69634163636573730000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000600015020014010000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000001502006160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000673797374656d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c7075626c69634163636573730000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x8", - "transactionLogIndex": "0x3", + "transactionLogIndex": "0x7", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000022000240200200400000000000000000000000000000000000000000000000000000004010043000000000000000000000000000000000000000000000000000000002402005f430000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001066756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001673797374656d46756e6374696f6e53656c6563746f7200000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000240200200400000000000000000000000000000000000000000000000000000004010043000000000000000000000000000000000000000000000000000000002402005f43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001066756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001673797374656d46756e6374696f6e53656c6563746f7200000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x9", - "transactionLogIndex": "0x4", + "transactionLogIndex": "0x8", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d486f6f6b73000000000000000000000000000000000000000000000000000000000000000000000001c00000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d486f6f6b73000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xa", - "transactionLogIndex": "0x5", + "transactionLogIndex": "0x9", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000001c000200100200000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000673797374656d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d52656769737472790000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000673797374656d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xb", - "transactionLogIndex": "0x6", + "transactionLogIndex": "0xa", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000001c00001010001000000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000000101000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c7265736f75726365547970650000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c7265736f75726365547970650000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xc", - "transactionLogIndex": "0x7", + "transactionLogIndex": "0xb", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f7572636541636365737300000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xd", - "transactionLogIndex": "0x8", + "transactionLogIndex": "0xc", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xe", - "transactionLogIndex": "0x9", + "transactionLogIndex": "0xd", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e730000000000000000000000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xf", - "transactionLogIndex": "0xa", + "transactionLogIndex": "0xe", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x0000000000000000000000000000000053797374656d73000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e73000000000000000000000000000000000000000000000000000000000000000000000000000000000015cafac3dd18ac6c6e92c921884f9e4176737c052c010000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e730000000000000000000000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x10", - "transactionLogIndex": "0xb", + "transactionLogIndex": "0xf", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000053797374656d526567697374727900000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000636f72652e7300000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e73000000000000000000000000000000000000000000000000000000000000000000000000000000000015cafac3dd18ac6c6e92c921884f9e4176737c052c0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x11", - "transactionLogIndex": "0xc", + "transactionLogIndex": "0x10", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f7572636541636365737300000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000636f72652e7300000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x12", - "transactionLogIndex": "0xd", + "transactionLogIndex": "0x11", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000140554c3a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000040554c3a00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x13", - "transactionLogIndex": "0xe", + "transactionLogIndex": "0x12", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000018d53b20800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008d53b20800000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000140554c3a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000040554c3a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x14", - "transactionLogIndex": "0xf", + "transactionLogIndex": "0x13", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000125f6221000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000025f6221000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000018d53b20800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008d53b208000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x15", - "transactionLogIndex": "0x10", + "transactionLogIndex": "0x14", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000012bfaa27400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000002bfaa27400000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000125f6221000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000025f62210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x16", - "transactionLogIndex": "0x11", + "transactionLogIndex": "0x15", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000121293ca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000021293ca000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000012bfaa27400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000002bfaa274000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x17", - "transactionLogIndex": "0x12", + "transactionLogIndex": "0x16", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000018818929400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008818929400000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000121293ca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000021293ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x18", - "transactionLogIndex": "0x13", + "transactionLogIndex": "0x17", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000018da798da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008da798da00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013ea8492200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003ea84922000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x19", - "transactionLogIndex": "0x14", + "transactionLogIndex": "0x18", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010ba51f4900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000000ba51f4900000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000018da798da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008da798da000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1a", - "transactionLogIndex": "0x15", + "transactionLogIndex": "0x19", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001530f4b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000530f4b6000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010ba51f4900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000000ba51f49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1b", - "transactionLogIndex": "0x16", + "transactionLogIndex": "0x1a", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010560912900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000000560912900000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001530f4b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000530f4b60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1c", - "transactionLogIndex": "0x17", + "transactionLogIndex": "0x1b", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a886545e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a886545e00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010560912900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000005609129000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1d", - "transactionLogIndex": "0x18", + "transactionLogIndex": "0x1c", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001d5f8337f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000d5f8337f00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a886545e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a886545e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1e", - "transactionLogIndex": "0x19", + "transactionLogIndex": "0x1d", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a92813ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a92813ad00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001d5f8337f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000d5f8337f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1f", - "transactionLogIndex": "0x1a", + "transactionLogIndex": "0x1e", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000013350b6a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003350b6a900000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a92813ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a92813ad000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x20", - "transactionLogIndex": "0x1b", + "transactionLogIndex": "0x1f", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000013c03a51c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003c03a51c00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013350b6a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003350b6a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x21", - "transactionLogIndex": "0x1c", + "transactionLogIndex": "0x20", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001b7a3c75600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000b7a3c75600000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013c03a51c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003c03a51c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x22", - "transactionLogIndex": "0x1d", + "transactionLogIndex": "0x21", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000011d2257ba00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000001d2257ba00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b7a3c75600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000b7a3c756000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x23", - "transactionLogIndex": "0x1e", + "transactionLogIndex": "0x22", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x00000000000000000000000000000000496e7374616c6c65644d6f64756c6573000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000002636f72652e6d0000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4700000000000000000000000000000000000000000000000000000000000000014e7f1725e7734ce288f8367e1bb143e90bb3f0512000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x99deb14acfd37070907742a1e1132b770fa6d08a4ac6cf48c67c26ddd9ab1fa2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000011d2257ba00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000001d2257ba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x24", - "transactionLogIndex": "0x1f", + "transactionLogIndex": "0x23", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x2a37be40264ec61f831b80f2ba86de357880aca3543deef9af1da49f512d767a", - "transactionIndex": "0x8", + "data": "0x00000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000002636f72652e6d0000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4700000000000000000000000000000000000000000000000000000000000000014e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", + "transactionIndex": "0x7", "logIndex": "0x25", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x24", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c697374000000000000000000000000000000000000000000000000000000000000000000000000016000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a00000000040000000000000e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x2a37be40264ec61f831b80f2ba86de357880aca3543deef9af1da49f512d767a", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x607b94e53ff6d14c8af149f742239040a26773006b3916fca7403ab56bc1addf", "transactionIndex": "0x8", "logIndex": "0x26", - "transactionLogIndex": "0x1", + "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xf0a076b9fa7fba5660e3ea38e2cc3f839ac119fafe6e621a52dd4d48412547b6", - "transactionIndex": "0x9", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d626572000000000000000000000000000000000000000000000000000000000000000000000000000000000060000401000400000000000000000000000000000000000000000000000000000000040100030000000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x607b94e53ff6d14c8af149f742239040a26773006b3916fca7403ab56bc1addf", + "transactionIndex": "0x8", "logIndex": "0x27", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f72000000000000000000000000000000000000000000000000000000000000000000000000000000000220000802000404000000000000000000000000000000000000000000000000000000040100030000000000000000000000000000000000000000000000000000000008020023230000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000a0000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b6579000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xf0a076b9fa7fba5660e3ea38e2cc3f839ac119fafe6e621a52dd4d48412547b6", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x809f38566746a983087006b293190f70f19c0a54cc76ba40c9fafe8bab17188e", "transactionIndex": "0x9", "logIndex": "0x28", - "transactionLogIndex": "0x1", + "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xa22266979e22263283f576d1dc598465908c7cd4ed7d40c7434a1887a94a773b", - "transactionIndex": "0xa", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000040000000000000e000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c697374000000000000000000000000000000000000000000000000000000000000000000000000006000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x809f38566746a983087006b293190f70f19c0a54cc76ba40c9fafe8bab17188e", + "transactionIndex": "0x9", "logIndex": "0x29", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000001c000040100040000000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000401000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xa22266979e22263283f576d1dc598465908c7cd4ed7d40c7434a1887a94a773b", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", "transactionIndex": "0xa", "logIndex": "0x2a", - "transactionLogIndex": "0x1", + "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xa019744ca59e63a91c327629d7137ec2d851787e922d8d9f48c8e74c3b622453", - "transactionIndex": "0xb", + "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000150165878a594ca255338adfa4d48449f69242eb8f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", + "transactionIndex": "0xa", "logIndex": "0x2b", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x0000000000000000000000000000000053797374656d73000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000155fc8d32690cc91d4c39d9d3abcbd16989f875707010000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xa019744ca59e63a91c327629d7137ec2d851787e922d8d9f48c8e74c3b622453", - "transactionIndex": "0xb", + "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000004e756d6265724c69737453797374656d", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", + "transactionIndex": "0xa", "logIndex": "0x2c", - "transactionLogIndex": "0x1", + "transactionLogIndex": "0x2", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x0000000000000000000000000000000053797374656d526567697374727900000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000437573746f6d4572726f727353797374", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xa019744ca59e63a91c327629d7137ec2d851787e922d8d9f48c8e74c3b622453", - "transactionIndex": "0xb", + "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", + "transactionIndex": "0xa", "logIndex": "0x2d", - "transactionLogIndex": "0x2", + "transactionLogIndex": "0x3", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f7572636541636365737300000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f87570700000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xa019744ca59e63a91c327629d7137ec2d851787e922d8d9f48c8e74c3b622453", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", "transactionIndex": "0xb", "logIndex": "0x2e", - "transactionLogIndex": "0x3", + "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x63c06061f3c8f9e8dfe3dfcf955082539d44d2bccefe66b943c5f481337b5f61", - "transactionIndex": "0xc", + "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000155fc8d32690cc91d4c39d9d3abcbd16989f8757070100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", + "transactionIndex": "0xb", "logIndex": "0x2f", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x0000000000000000000000000000000053797374656d73000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000150165878a594ca255338adfa4d48449f69242eb8f010000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x63c06061f3c8f9e8dfe3dfcf955082539d44d2bccefe66b943c5f481337b5f61", - "transactionIndex": "0xc", + "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000437573746f6d4572726f727353797374", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", + "transactionIndex": "0xb", "logIndex": "0x30", - "transactionLogIndex": "0x1", + "transactionLogIndex": "0x2", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x0000000000000000000000000000000053797374656d526567697374727900000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000004e756d6265724c69737453797374656d", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x63c06061f3c8f9e8dfe3dfcf955082539d44d2bccefe66b943c5f481337b5f61", - "transactionIndex": "0xc", + "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f87570700000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", + "transactionIndex": "0xb", "logIndex": "0x31", - "transactionLogIndex": "0x2", + "transactionLogIndex": "0x3", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f7572636541636365737300000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x63c06061f3c8f9e8dfe3dfcf955082539d44d2bccefe66b943c5f481337b5f61", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x75f138556b7a5086ee800ce634d428fd9775d61e9d62dc8f6242e1586a762c30", "transactionIndex": "0xc", "logIndex": "0x32", - "transactionLogIndex": "0x3", + "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c7469000000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xd24893f65a6b85dc7d9644726e7f03fddc4edc256d956f2965ef800c134e0719", - "transactionIndex": "0xd", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000006000080200040400000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000802002323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b6579000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x75f138556b7a5086ee800ce634d428fd9775d61e9d62dc8f6242e1586a762c30", + "transactionIndex": "0xc", "logIndex": "0x33", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c74690000000000000000000000000000000000000000000000000000000000000000000000000000000000034000210200200100000000000000000000000000000000000000000000000000000034040003601f2e000000000000000000000000000000000000000000000000002102003f600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000001c0000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000162000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000036e756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xd24893f65a6b85dc7d9644726e7f03fddc4edc256d956f2965ef800c134e0719", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c7469000000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x2d3fb06c20276d48f9a04f14d92f70e31011b23f5fcecc6721fb5598360a4c75", "transactionIndex": "0xd", "logIndex": "0x34", + "transactionLogIndex": "0x0", + "removed": false + }, + { + "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", + "topics": [ + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" + ], + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000001c0000000000002c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c74690000000000000000000000000000000000000000000000000000000000000000000000000000000000006000210200200100000000000000000000000000000000000000000000000000000034040003601f2e000000000000000000000000000000000000000000000000002102003f60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000162000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000036e756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x2d3fb06c20276d48f9a04f14d92f70e31011b23f5fcecc6721fb5598360a4c75", + "transactionIndex": "0xd", + "logIndex": "0x35", "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000015f644e3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000437573746f6d4572726f7273537973745f644e3c00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x7457d2e10dd336429a4077839674b8a346fb220ff17b4058a0a385b981b58cb5", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656da4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x9d21ec923cfc66bc0b7fc283fd5c90fca31fbca1c881fa4afb1dd4884e6cb2d1", "transactionIndex": "0xe", - "logIndex": "0x35", + "logIndex": "0x36", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001b8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656db8a44c7c00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x21e16439547f1c2a365efc548780b3cbd47ef74bdbbd55cde27c9d55458842f2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001f7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656df7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x750e99e7e822739dc4bed149a9ad6d8c78a9a6e5a0c6021c5b508548847afe6d", "transactionIndex": "0xf", - "logIndex": "0x36", + "logIndex": "0x37", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656d306d61a500000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xe76907051c864ea6d12f038a0423ac6043ffe4aedf405378f25c6f8a63dc038c", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656d306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0xa1d5a5b9fbc79c30072955f0fc8fd9c8397757176eaadacebdb7598cd9141d24", "transactionIndex": "0x10", - "logIndex": "0x37", + "logIndex": "0x38", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001a4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656da4ece52c00000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0x83c2546f45504545c8921d74dce1335f7db65f2c573b14971dc283a0abb427a2", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000015f644e3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000437573746f6d4572726f7273537973745f644e3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0x52057dfd4f9e6818f5565203a1e5a7abe7c1e242d91ca32c9353d5a88002b99e", "transactionIndex": "0x11", - "logIndex": "0x38", + "logIndex": "0x39", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000001f7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656df7f0e44000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xc69c386d859fa05880ce8c651bf668d7db8b91b038ace616e20d7502917815e0", - "blockNumber": "0x2", - "transactionHash": "0xaee239c8f1398730a2f5e8c2426cd47f8d39a4c66e2d73155b4dcd73f3b45e68", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656db8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", + "blockNumber": "0x4", + "transactionHash": "0xbe213a215bd71f17f867b8129a24630241f970e1cf5231f8a3bb2ba412b68a70", "transactionIndex": "0x12", - "logIndex": "0x39", + "logIndex": "0x3a", "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x9ded3a5a78199a737f59213ee5817f193988e67d8f197b17314f1804fe6715c8" ], - "data": "0x000000000000000000000000000000004e756d6265724c6973740000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000001a400000000000000000000000000000000000000000000000000000000", - "blockHash": "0x54705c7c1c71954d18db182c27c85def952826a0f7c9e09e933ad90a29e1ccd9", - "blockNumber": "0x3", - "transactionHash": "0xedae06dc8024b7b364f6ef80597edfb3c595b4b0eba21b9f0afb683c0ad4ea64", + "data": "0x000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000040000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000001a400000000000000000000000000000000000000000000000000000000", + "blockHash": "0x31ef6f8925641e60d844088938c75fee8baeaec927fc09b7fd51050c2ca29e1e", + "blockNumber": "0x5", + "transactionHash": "0x913934c3603cedb30d6ec5131ca347ce5f3906f6146f7fdfe39ad6008e6e0a94", "transactionIndex": "0x0", "logIndex": "0x0", "transactionLogIndex": "0x0", @@ -814,12 +828,12 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46" + "0x9ded3a5a78199a737f59213ee5817f193988e67d8f197b17314f1804fe6715c8" ], - "data": "0x000000000000000000000000000000004e756d6265724c6973740000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000001a400000045000000000000000000000000000000000000000000000000", - "blockHash": "0x54705c7c1c71954d18db182c27c85def952826a0f7c9e09e933ad90a29e1ccd9", - "blockNumber": "0x3", - "transactionHash": "0xf457c087993354a5ca9d86b59df3f8d355d23fb441386fb70bddf09770e3bc21", + "data": "0x000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000800000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000004500000000000000000000000000000000000000000000000000000000", + "blockHash": "0x31ef6f8925641e60d844088938c75fee8baeaec927fc09b7fd51050c2ca29e1e", + "blockNumber": "0x5", + "transactionHash": "0xa5e0a4df59ae785eb7f2abc61ab104cbd97db921a61ad3a5a34b7a959d543ca6", "transactionIndex": "0x1", "logIndex": "0x1", "transactionLogIndex": "0x0", From a1d00158d35a681ea542b00311d4fb2ecdaeeed7 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 11:51:22 +0100 Subject: [PATCH 38/69] update tests --- .../src/postgres/postgresStorage.test.ts | 103 ++++++--------- .../src/postgres/postgresStorage.ts | 4 +- .../store-sync/src/recs/recsStorage.test.ts | 25 ++-- .../src/sqlite/sqliteStorage.test.ts | 119 ++++++++---------- .../store-sync/src/sqlite/sqliteStorage.ts | 3 +- 5 files changed, 107 insertions(+), 147 deletions(-) diff --git a/packages/store-sync/src/postgres/postgresStorage.test.ts b/packages/store-sync/src/postgres/postgresStorage.test.ts index 80b1fc5d80..3c1dabe129 100644 --- a/packages/store-sync/src/postgres/postgresStorage.test.ts +++ b/packages/store-sync/src/postgres/postgresStorage.test.ts @@ -1,13 +1,29 @@ import { beforeEach, describe, expect, it, vi } from "vitest"; -import { DefaultLogger } from "drizzle-orm"; +import { DefaultLogger, eq } from "drizzle-orm"; import { drizzle } from "drizzle-orm/postgres-js"; import postgres from "postgres"; -import { createPublicClient, http } from "viem"; +import { Hex, RpcLog, createPublicClient, decodeEventLog, formatLog, http } from "viem"; import { foundry } from "viem/chains"; import * as transformSchemaNameExports from "./transformSchemaName"; import { getTables } from "./getTables"; import { PostgresStorageAdapter, postgresStorage } from "./postgresStorage"; import { buildTable } from "./buildTable"; +import { groupLogsByBlockNumber } from "@latticexyz/block-logs-stream"; +import { storeEventsAbi } from "@latticexyz/store"; +import { StoreEventsLog } from "../common"; +import worldRpcLogs from "../../../../test-data/world-logs.json"; + +const blocks = groupLogsByBlockNumber( + worldRpcLogs.map((log) => { + const { eventName, args } = decodeEventLog({ + abi: storeEventsAbi, + data: log.data as Hex, + topics: log.topics as [Hex, ...Hex[]], + strict: true, + }); + return formatLog(log as any as RpcLog, { args, eventName: eventName as string }) as StoreEventsLog; + }) +); vi.spyOn(transformSchemaNameExports, "transformSchemaName").mockImplementation( (schemaName) => `${process.pid}_${process.env.VITEST_POOL_ID}__${schemaName}` @@ -31,98 +47,55 @@ describe("postgresStorage", async () => { }); it("should create tables and data from block log", async () => { - await storageAdapter.storageAdapter({ - blockNumber: 5448n, - logs: [ - { - address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", - topics: ["0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46"], - data: "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e76656e746f72790000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - blockHash: "0x4ad3752c86f900332e0d2d8903480e7206747d233586574d16f006eebdb5138b", - blockNumber: 2n, - transactionHash: "0xaa54bf18053cce5d4d2906538a60cb1d9958cc3c10c34b5f9fdc92fe6a6abab4", - transactionIndex: 16, - logIndex: 54, - removed: false, - args: { - table: "0x000000000000000000000000000000005265736f757263655479706500000000", - key: ["0x00000000000000000000000000000000496e76656e746f727900000000000000"], - data: "0x02", - start: 0, - deleteCount: 0, - }, - eventName: "StoreSpliceRecord", - }, - { - address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", - topics: ["0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32"], - data: "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e76656e746f72790000000000000000000000000000000000000000000000000000000000000000000000000002800004010004000000000000000000000000000000000000000000000000000000001c030061030300000000000000000000000000000000000000000000000000000401000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000001600000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000056f776e657200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046974656d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6974656d56617269616e740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006616d6f756e740000000000000000000000000000000000000000000000000000", - blockHash: "0x4ad3752c86f900332e0d2d8903480e7206747d233586574d16f006eebdb5138b", - blockNumber: 2n, - transactionHash: "0xaa54bf18053cce5d4d2906538a60cb1d9958cc3c10c34b5f9fdc92fe6a6abab4", - transactionIndex: 16, - logIndex: 55, - removed: false, - args: { - table: "0x6d756473746f726500000000000000005461626c657300000000000000000000", - key: ["0x00000000000000000000000000000000496e76656e746f727900000000000000"], - data: "0x0004010004000000000000000000000000000000000000000000000000000000001c030061030300000000000000000000000000000000000000000000000000000401000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000001600000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000056f776e657200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046974656d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6974656d56617269616e740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006616d6f756e740000000000000000000000000000000000000000000000000000", - }, - eventName: "StoreSetRecord", - }, - ], - }); + await Promise.all(blocks.map(storageAdapter.storageAdapter)); expect(await db.select().from(storageAdapter.internalTables.chain)).toMatchInlineSnapshot(` [ { "chainId": 31337, "lastError": null, - "lastUpdatedBlockNumber": 5448n, + "lastUpdatedBlockNumber": 4n, "schemaVersion": 1, }, ] `); - expect(await db.select().from(storageAdapter.internalTables.tables)).toMatchInlineSnapshot(` + expect( + await db + .select() + .from(storageAdapter.internalTables.tables) + .where(eq(storageAdapter.internalTables.tables.name, "NumberList")) + ).toMatchInlineSnapshot(` [ { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "key": "0x5FbDB2315678afecb367f032d93F642f64180aa3::Inventory", - "keySchema": { - "item": "uint32", - "itemVariant": "uint32", - "owner": "address", - }, + "key": "0x5FbDB2315678afecb367f032d93F642f64180aa3::NumberList", + "keySchema": {}, "lastError": null, - "lastUpdatedBlockNumber": 5448n, - "name": "Inventory", + "lastUpdatedBlockNumber": 4n, + "name": "NumberList", "namespace": "", "schemaVersion": 1, - "tableId": "0x00000000000000000000000000000000496e76656e746f727900000000000000", + "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", "valueSchema": { - "amount": "uint32", + "value": "uint32[]", }, }, ] `); - const tables = await getTables(db, []); + const tables = (await getTables(db)).filter((table) => table.name === "NumberList"); expect(tables).toMatchInlineSnapshot(` [ { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "keySchema": { - "item": "uint32", - "itemVariant": "uint32", - "owner": "address", - }, - "lastUpdatedBlockNumber": 5448n, - "name": "Inventory", + "keySchema": {}, + "lastUpdatedBlockNumber": 4n, + "name": "NumberList", "namespace": "", - "tableId": "0x00000000000000000000000000000000496e76656e746f727900000000000000", + "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", "valueSchema": { - "amount": "uint32", + "value": "uint32[]", }, }, ] diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index b80112bb4d..1fc1daede9 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -13,10 +13,8 @@ import { getTableKey } from "./getTableKey"; import { StorageAdapter, StorageAdapterBlock } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; -import { decodeKey, decodeValue, decodeValueArgs, readHex, staticDataLength } from "@latticexyz/protocol-parser"; -import { spliceValueHex } from "../spliceValueHex"; +import { decodeKey, decodeValueArgs, readHex } from "@latticexyz/protocol-parser"; import { assertExhaustive } from "@latticexyz/common/utils"; -import { isStaticAbiType } from "@latticexyz/schema-type"; // Currently assumes one DB per chain ID diff --git a/packages/store-sync/src/recs/recsStorage.test.ts b/packages/store-sync/src/recs/recsStorage.test.ts index ee4d133869..897075a8e6 100644 --- a/packages/store-sync/src/recs/recsStorage.test.ts +++ b/packages/store-sync/src/recs/recsStorage.test.ts @@ -9,15 +9,18 @@ import { singletonEntity } from "./singletonEntity"; import { RpcLog, formatLog, decodeEventLog, Hex } from "viem"; import { storeEventsAbi } from "@latticexyz/store"; -const worldLogs = worldRpcLogs.map((log) => { - const { eventName, args } = decodeEventLog({ - abi: storeEventsAbi, - data: log.data as Hex, - topics: log.topics as [Hex, ...Hex[]], - strict: true, - }); - return formatLog(log as any as RpcLog, { args, eventName: eventName as string }) as StoreEventsLog; -}); +// TODO: make test-data a proper package and export this +const blocks = groupLogsByBlockNumber( + worldRpcLogs.map((log) => { + const { eventName, args } = decodeEventLog({ + abi: storeEventsAbi, + data: log.data as Hex, + topics: log.topics as [Hex, ...Hex[]], + strict: true, + }); + return formatLog(log as any as RpcLog, { args, eventName: eventName as string }) as StoreEventsLog; + }) +); describe("recsStorage", () => { it("creates components", async () => { @@ -32,7 +35,6 @@ describe("recsStorage", () => { const world = createWorld(); const { storageAdapter, components } = recsStorage({ world, config: mudConfig }); - const blocks = groupLogsByBlockNumber(worldLogs); await Promise.all(blocks.map(storageAdapter)); expect(Array.from(getComponentEntities(components.NumberList))).toMatchInlineSnapshot(` @@ -43,6 +45,9 @@ describe("recsStorage", () => { expect(getComponentValue(components.NumberList, singletonEntity)).toMatchInlineSnapshot(` { + "__dynamicData": "0x000001a400000045", + "__encodedLengths": "0x0000000000000000000000000000000000000000000000000800000000000008", + "__staticData": undefined, "value": [ 420, 69, diff --git a/packages/store-sync/src/sqlite/sqliteStorage.test.ts b/packages/store-sync/src/sqlite/sqliteStorage.test.ts index 4760d4387b..836429ebe9 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.test.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.test.ts @@ -6,8 +6,26 @@ import { BaseSQLiteDatabase } from "drizzle-orm/sqlite-core"; import { buildTable } from "./buildTable"; import initSqlJs from "sql.js"; import { drizzle } from "drizzle-orm/sql-js"; -import { createPublicClient, http } from "viem"; +import { Hex, RpcLog, createPublicClient, decodeEventLog, formatLog, http } from "viem"; import { foundry } from "viem/chains"; +import worldRpcLogs from "../../../../test-data/world-logs.json"; +import { storeEventsAbi } from "@latticexyz/store"; +import { StoreEventsLog } from "../common"; +import { groupLogsByBlockNumber } from "@latticexyz/block-logs-stream"; +import { eq } from "drizzle-orm"; + +// TODO: make test-data a proper package and export this +const blocks = groupLogsByBlockNumber( + worldRpcLogs.map((log) => { + const { eventName, args } = decodeEventLog({ + abi: storeEventsAbi, + data: log.data as Hex, + topics: log.topics as [Hex, ...Hex[]], + strict: true, + }); + return formatLog(log as any as RpcLog, { args, eventName: eventName as string }) as StoreEventsLog; + }) +); describe("sqliteStorage", async () => { const SqlJs = await initSqlJs(); @@ -37,105 +55,72 @@ describe("sqliteStorage", async () => { expect(db.select().from(chainState).all()).toMatchInlineSnapshot("[]"); expect(db.select().from(mudStoreTables).all()).toMatchInlineSnapshot("[]"); - await storageAdapter({ - blockNumber: 5448n, - logs: [ - { - address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", - topics: ["0xd01f9f1368f831528fc9fe6442366b2b7d957fbfff3bcf7c24d9ab5fe51f8c46"], - data: "0x000000000000000000000000000000005265736f7572636554797065000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e76656e746f72790000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - blockHash: "0x4ad3752c86f900332e0d2d8903480e7206747d233586574d16f006eebdb5138b", - blockNumber: 2n, - transactionHash: "0xaa54bf18053cce5d4d2906538a60cb1d9958cc3c10c34b5f9fdc92fe6a6abab4", - transactionIndex: 16, - logIndex: 54, - removed: false, - args: { - table: "0x000000000000000000000000000000005265736f757263655479706500000000", - key: ["0x00000000000000000000000000000000496e76656e746f727900000000000000"], - data: "0x02", - start: 0, - deleteCount: 0, - }, - eventName: "StoreSpliceRecord", - }, - { - address: "0x5fbdb2315678afecb367f032d93f642f64180aa3", - topics: ["0x912af873e852235aae78a1d25ae9bb28b616a67c36898c53a14fd8184504ee32"], - data: "0x6d756473746f726500000000000000005461626c657300000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e76656e746f72790000000000000000000000000000000000000000000000000000000000000000000000000002800004010004000000000000000000000000000000000000000000000000000000001c030061030300000000000000000000000000000000000000000000000000000401000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000001600000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000056f776e657200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046974656d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6974656d56617269616e740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006616d6f756e740000000000000000000000000000000000000000000000000000", - blockHash: "0x4ad3752c86f900332e0d2d8903480e7206747d233586574d16f006eebdb5138b", - blockNumber: 2n, - transactionHash: "0xaa54bf18053cce5d4d2906538a60cb1d9958cc3c10c34b5f9fdc92fe6a6abab4", - transactionIndex: 16, - logIndex: 55, - removed: false, - args: { - table: "0x6d756473746f726500000000000000005461626c657300000000000000000000", - key: ["0x00000000000000000000000000000000496e76656e746f727900000000000000"], - data: "0x0004010004000000000000000000000000000000000000000000000000000000001c030061030300000000000000000000000000000000000000000000000000000401000300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000001600000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000056f776e657200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000046974656d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b6974656d56617269616e740000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000006616d6f756e740000000000000000000000000000000000000000000000000000", - }, - eventName: "StoreSetRecord", - }, - ], - }); + await Promise.all(blocks.map(storageAdapter)); expect(db.select().from(chainState).all()).toMatchInlineSnapshot(` [ { "chainId": 31337, "lastError": null, - "lastUpdatedBlockNumber": 5448n, + "lastUpdatedBlockNumber": 4n, "schemaVersion": 1, }, ] `); - expect(db.select().from(mudStoreTables).all()).toMatchInlineSnapshot(` + expect(db.select().from(mudStoreTables).where(eq(mudStoreTables.name, "NumberList")).all()).toMatchInlineSnapshot(` [ { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____Inventory", - "keySchema": { - "item": "uint32", - "itemVariant": "uint32", - "owner": "address", - }, + "id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____NumberList", + "keySchema": {}, "lastError": null, - "lastUpdatedBlockNumber": 5448n, - "name": "Inventory", + "lastUpdatedBlockNumber": 5n, + "name": "NumberList", "namespace": "", "schemaVersion": 1, - "tableId": "0x00000000000000000000000000000000496e76656e746f727900000000000000", + "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", "valueSchema": { - "amount": "uint32", + "value": "uint32[]", }, }, ] `); - const tables = getTables(db); + const tables = getTables(db).filter((table) => table.name === "NumberList"); expect(tables).toMatchInlineSnapshot(` [ { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", - "id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____Inventory", - "keySchema": { - "item": "uint32", - "itemVariant": "uint32", - "owner": "address", - }, - "lastUpdatedBlockNumber": 5448n, - "name": "Inventory", + "id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____NumberList", + "keySchema": {}, + "lastUpdatedBlockNumber": 5n, + "name": "NumberList", "namespace": "", - "tableId": "0x00000000000000000000000000000000496e76656e746f727900000000000000", + "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", "valueSchema": { - "amount": "uint32", + "value": "uint32[]", }, }, ] `); - const sqliteTable = buildTable(tables[0]); - expect(db.select().from(sqliteTable).all()).toMatchInlineSnapshot("[]"); + const sqlTable = buildTable(tables[0]); + expect(db.select().from(sqlTable).all()).toMatchInlineSnapshot(` + [ + { + "__dynamicData": "0x000001a400000045", + "__encodedLengths": "0x0000000000000000000000000000000000000000000000000800000000000008", + "__isDeleted": false, + "__key": "0x", + "__lastUpdatedBlockNumber": 5n, + "__staticData": null, + "value": [ + 420, + 69, + ], + }, + ] + `); }); }); diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 83569d9839..41ca9caf0a 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -13,8 +13,7 @@ import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexToTableId, tableIdToHex } from "@latticexyz/common"; -import { decodeKey, decodeValue, decodeValueArgs, readHex } from "@latticexyz/protocol-parser"; -import { spliceValueHex } from "../spliceValueHex"; +import { decodeKey, decodeValueArgs, readHex } from "@latticexyz/protocol-parser"; import { assertExhaustive } from "@latticexyz/common/utils"; // TODO: upgrade drizzle and use async sqlite interface for consistency From 2ef4d4a307aa3c7f81652e3f8d1cc7f2d2e2b467 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 12:07:44 +0100 Subject: [PATCH 39/69] fix tests --- .../src/postgres/postgresStorage.test.ts | 27 +++++++++++++++---- .../store-sync/src/recs/recsStorage.test.ts | 4 ++- .../src/sqlite/sqliteStorage.test.ts | 6 +++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/packages/store-sync/src/postgres/postgresStorage.test.ts b/packages/store-sync/src/postgres/postgresStorage.test.ts index 3c1dabe129..8aa0548082 100644 --- a/packages/store-sync/src/postgres/postgresStorage.test.ts +++ b/packages/store-sync/src/postgres/postgresStorage.test.ts @@ -47,14 +47,16 @@ describe("postgresStorage", async () => { }); it("should create tables and data from block log", async () => { - await Promise.all(blocks.map(storageAdapter.storageAdapter)); + for (const block of blocks) { + await storageAdapter.storageAdapter(block); + } expect(await db.select().from(storageAdapter.internalTables.chain)).toMatchInlineSnapshot(` [ { "chainId": 31337, "lastError": null, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 5n, "schemaVersion": 1, }, ] @@ -72,7 +74,7 @@ describe("postgresStorage", async () => { "key": "0x5FbDB2315678afecb367f032d93F642f64180aa3::NumberList", "keySchema": {}, "lastError": null, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 5n, "name": "NumberList", "namespace": "", "schemaVersion": 1, @@ -90,7 +92,7 @@ describe("postgresStorage", async () => { { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "keySchema": {}, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 5n, "name": "NumberList", "namespace": "", "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", @@ -102,7 +104,22 @@ describe("postgresStorage", async () => { `); const sqlTable = buildTable(tables[0]); - expect(await db.select().from(sqlTable)).toMatchInlineSnapshot("[]"); + expect(await db.select().from(sqlTable)).toMatchInlineSnapshot(` + [ + { + "__dynamicData": "0x000001a400000045", + "__encodedLengths": "0x0000000000000000000000000000000000000000000000000800000000000008", + "__isDeleted": false, + "__key": "0x", + "__lastUpdatedBlockNumber": 5n, + "__staticData": null, + "value": [ + 420, + 69, + ], + }, + ] + `); await storageAdapter.cleanUp(); }); diff --git a/packages/store-sync/src/recs/recsStorage.test.ts b/packages/store-sync/src/recs/recsStorage.test.ts index 897075a8e6..4bb747b0dc 100644 --- a/packages/store-sync/src/recs/recsStorage.test.ts +++ b/packages/store-sync/src/recs/recsStorage.test.ts @@ -35,7 +35,9 @@ describe("recsStorage", () => { const world = createWorld(); const { storageAdapter, components } = recsStorage({ world, config: mudConfig }); - await Promise.all(blocks.map(storageAdapter)); + for (const block of blocks) { + await storageAdapter(block); + } expect(Array.from(getComponentEntities(components.NumberList))).toMatchInlineSnapshot(` [ diff --git a/packages/store-sync/src/sqlite/sqliteStorage.test.ts b/packages/store-sync/src/sqlite/sqliteStorage.test.ts index 836429ebe9..1c8845f37c 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.test.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.test.ts @@ -55,14 +55,16 @@ describe("sqliteStorage", async () => { expect(db.select().from(chainState).all()).toMatchInlineSnapshot("[]"); expect(db.select().from(mudStoreTables).all()).toMatchInlineSnapshot("[]"); - await Promise.all(blocks.map(storageAdapter)); + for (const block of blocks) { + await storageAdapter(block); + } expect(db.select().from(chainState).all()).toMatchInlineSnapshot(` [ { "chainId": 31337, "lastError": null, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 5n, "schemaVersion": 1, }, ] From 057d8e198aaa29491130ec72d52678f6a0a85fd0 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 12:25:36 +0100 Subject: [PATCH 40/69] remove dupe/renamed method --- packages/protocol-parser/src/padSliceHex.test.ts | 15 --------------- packages/protocol-parser/src/padSliceHex.ts | 8 -------- 2 files changed, 23 deletions(-) delete mode 100644 packages/protocol-parser/src/padSliceHex.test.ts delete mode 100644 packages/protocol-parser/src/padSliceHex.ts diff --git a/packages/protocol-parser/src/padSliceHex.test.ts b/packages/protocol-parser/src/padSliceHex.test.ts deleted file mode 100644 index 5f100c628b..0000000000 --- a/packages/protocol-parser/src/padSliceHex.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { padSliceHex } from "./padSliceHex"; - -describe("padSliceHex", () => { - it("can slice empty hex", () => { - expect(padSliceHex("0x", 6)).toBe("0x"); - expect(padSliceHex("0x", 6, 10)).toBe("0x00000000"); - }); - it("can slice hex out of bounds", () => { - expect(padSliceHex("0x000100", 1)).toBe("0x0100"); - expect(padSliceHex("0x000100", 1, 4)).toBe("0x010000"); - expect(padSliceHex("0x000100", 3)).toBe("0x"); - expect(padSliceHex("0x000100", 3, 4)).toBe("0x00"); - }); -}); diff --git a/packages/protocol-parser/src/padSliceHex.ts b/packages/protocol-parser/src/padSliceHex.ts deleted file mode 100644 index 734459e66a..0000000000 --- a/packages/protocol-parser/src/padSliceHex.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Hex } from "viem"; - -export function padSliceHex(data: Hex, start: number, end?: number): Hex { - return `0x${data - .replace(/^0x/, "") - .slice(start * 2, end != null ? end * 2 : undefined) - .padEnd(((end ?? start) - start) * 2, "0")}`; -} From cbdbf92689c92a296a9302814dc018e49ca4f857 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 12:41:56 +0100 Subject: [PATCH 41/69] remove exhaustive check for now --- packages/store-sync/src/postgres/postgresStorage.ts | 2 -- packages/store-sync/src/recs/recsStorage.ts | 2 -- packages/store-sync/src/sqlite/sqliteStorage.ts | 2 -- 3 files changed, 6 deletions(-) diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index 1fc1daede9..42d163e4a3 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -252,8 +252,6 @@ export async function postgresStorage }) .where(eq(sqlTable.__key, uniqueKey)) .execute(); - } else { - assertExhaustive(log.eventName); } } diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index 5eb67aa64c..0a60d68319 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -162,8 +162,6 @@ export function recsStorage({ entity, }); removeComponent(component, entity); - } else { - assertExhaustive(log.eventName); } } } diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 41ca9caf0a..2308ea66a7 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -245,8 +245,6 @@ export async function sqliteStorage({ }) .where(eq(sqlTable.__key, uniqueKey)) .run(); - } else { - assertExhaustive(log.eventName); } } From 0960120e3c64cd4ba97c9efc723451d8681ab150 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 12:55:08 +0100 Subject: [PATCH 42/69] fix dev tools --- .../dev-tools/src/actions/WriteSummary.tsx | 1 + packages/dev-tools/src/events/LogsTable.tsx | 21 ++++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/packages/dev-tools/src/actions/WriteSummary.tsx b/packages/dev-tools/src/actions/WriteSummary.tsx index 2b185a9903..49012579b6 100644 --- a/packages/dev-tools/src/actions/WriteSummary.tsx +++ b/packages/dev-tools/src/actions/WriteSummary.tsx @@ -132,6 +132,7 @@ export function WriteSummary({ write }: Props) { {events.map(({ eventName, args }, i) => { const table = hexToTableId((args as any).table); + // TODO: dedupe this with logs table so we can get both rendering the same return ( diff --git a/packages/dev-tools/src/events/LogsTable.tsx b/packages/dev-tools/src/events/LogsTable.tsx index 7d855e1a33..265d97e97f 100644 --- a/packages/dev-tools/src/events/LogsTable.tsx +++ b/packages/dev-tools/src/events/LogsTable.tsx @@ -1,5 +1,4 @@ import { StorageAdapterLog } from "@latticexyz/store-sync"; -import { serialize } from "../serialize"; import { EventIcon } from "./EventIcon"; import { hexToTableId } from "@latticexyz/common"; @@ -45,8 +44,24 @@ export function LogsTable({ logs }: Props) { {/* TODO: decode these values if we can */} - {log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord" ? log.args.data : null} - {log.eventName === "StoreSpliceRecord" ? log.args.data : null} + {log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord" + ? JSON.stringify({ + staticData: log.args.staticData, + encodedLengths: log.args.encodedLengths, + dynamicData: log.args.dynamicData, + }) + : null} + {log.eventName === "StoreSpliceStaticRecord" + ? JSON.stringify({ start: log.args.start, deleteCount: log.args.deleteCount, data: log.args.data }) + : null} + {log.eventName === "StoreSpliceDynamicRecord" + ? JSON.stringify({ + start: log.args.start, + deleteCount: log.args.deleteCount, + data: log.args.data, + encodedLengths: log.args.encodedLengths, + }) + : null} ); From dda958dcd67929f8caf24130848558803dd7fbe8 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 13:07:32 +0100 Subject: [PATCH 43/69] update e2e setRecord calls --- e2e/packages/sync-test/data/encodeTestData.ts | 15 +++++++-------- e2e/packages/sync-test/data/setContractData.ts | 6 ++++-- e2e/packages/sync-test/data/types.ts | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/e2e/packages/sync-test/data/encodeTestData.ts b/e2e/packages/sync-test/data/encodeTestData.ts index 05f96191cf..8cbe0757f6 100644 --- a/e2e/packages/sync-test/data/encodeTestData.ts +++ b/e2e/packages/sync-test/data/encodeTestData.ts @@ -1,5 +1,5 @@ import { mapObject } from "@latticexyz/utils"; -import { abiTypesToSchema, encodeKey, encodeValue, schemaToHex } from "@latticexyz/protocol-parser"; +import { encodeKey, encodeValueArgs, valueSchemaToFieldLayoutHex } from "@latticexyz/protocol-parser"; import { Data, EncodedData } from "./types"; import config from "../../contracts/mud.config"; @@ -11,15 +11,14 @@ export function encodeTestData(testData: Data) { if (!records) return undefined; const tableConfig = config.tables[table]; return records.map((record) => { - const encodedKey = encodeKey(tableConfig.keySchema, record.key); - const encodedValue = encodeValue(tableConfig.schema, record.value); - - const encodedValueSchema = schemaToHex(abiTypesToSchema(Object.values(config.tables[table].schema))); + const key = encodeKey(tableConfig.keySchema, record.key); + const valueArgs = encodeValueArgs(tableConfig.schema, record.value); + const fieldLayout = valueSchemaToFieldLayoutHex(tableConfig.schema); return { - key: encodedKey, - value: encodedValue, - valueSchema: encodedValueSchema, + key, + ...valueArgs, + fieldLayout, }; }); }) as EncodedData; diff --git a/e2e/packages/sync-test/data/setContractData.ts b/e2e/packages/sync-test/data/setContractData.ts index 5ca090cae8..323189d95c 100644 --- a/e2e/packages/sync-test/data/setContractData.ts +++ b/e2e/packages/sync-test/data/setContractData.ts @@ -16,8 +16,10 @@ export async function setContractData(page: Page, data: Data) { // TODO: add support for multiple namespaces after https://github.com/latticexyz/mud/issues/994 is resolved tableIdToHex("", table), record.key, - record.value, - record.valueSchema, + record.staticData, + record.encodedLengths, + record.dynamicData, + record.fieldLayout, ]); // Wait for transactions to be confirmed diff --git a/e2e/packages/sync-test/data/types.ts b/e2e/packages/sync-test/data/types.ts index 4ab5dab4ed..543c635fcc 100644 --- a/e2e/packages/sync-test/data/types.ts +++ b/e2e/packages/sync-test/data/types.ts @@ -20,5 +20,5 @@ export type Datum> }; export type EncodedData = { - [Table in keyof T]: Array<{ key: Hex[]; value: Hex; valueSchema: Hex }>; + [Table in keyof T]: Array<{ key: Hex[]; staticData: Hex; encodedLengths: Hex; dynamicData: Hex; fieldLayout: Hex }>; }; From a9b38647b91bb93a1ff0cf572da807279acc4aca Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 13:11:39 +0100 Subject: [PATCH 44/69] update test data --- .../sync-test/data/encodeTestData.test.ts | 48 ++++++++++++------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/e2e/packages/sync-test/data/encodeTestData.test.ts b/e2e/packages/sync-test/data/encodeTestData.test.ts index 818358329a..11c919ac0e 100644 --- a/e2e/packages/sync-test/data/encodeTestData.test.ts +++ b/e2e/packages/sync-test/data/encodeTestData.test.ts @@ -3,24 +3,36 @@ import { encodeTestData } from "./encodeTestData"; describe("encodeTestData", () => { it("should encode numbers", () => { - expect(encodeTestData({ Number: [{ key: { key: 42 }, value: { value: 1337 } }] })).toStrictEqual({ - Number: [ - { - key: ["0x000000000000000000000000000000000000000000000000000000000000002a"], - value: "0x000005390000000000000000000000000000000000000000000000000000000000000000", - valueSchema: "0x0004010003000000000000000000000000000000000000000000000000000000", - }, - ], - }); + expect(encodeTestData({ Number: [{ key: { key: 42 }, value: { value: 1337 } }] })).toMatchInlineSnapshot(` + { + "Number": [ + { + "dynamicData": "0x", + "encodedLengths": "0x0000000000000000000000000000000000000000000000000000000000000000", + "fieldLayout": "0x0004010004000000000000000000000000000000000000000000000000000000", + "key": [ + "0x000000000000000000000000000000000000000000000000000000000000002a", + ], + "staticData": "0x00000539", + }, + ], + } + `); - expect(encodeTestData({ Vector: [{ key: { key: 1337 }, value: { x: 42, y: -69 } }] })).toStrictEqual({ - Vector: [ - { - key: ["0x0000000000000000000000000000000000000000000000000000000000000539"], - value: "0x0000002affffffbb0000000000000000000000000000000000000000000000000000000000000000", - valueSchema: "0x0008020023230000000000000000000000000000000000000000000000000000", - }, - ], - }); + expect(encodeTestData({ Vector: [{ key: { key: 1337 }, value: { x: 42, y: -69 } }] })).toMatchInlineSnapshot(` + { + "Vector": [ + { + "dynamicData": "0x", + "encodedLengths": "0x0000000000000000000000000000000000000000000000000000000000000000", + "fieldLayout": "0x0008020004040000000000000000000000000000000000000000000000000000", + "key": [ + "0x0000000000000000000000000000000000000000000000000000000000000539", + ], + "staticData": "0x0000002affffffbb", + }, + ], + } + `); }); }); From 81f8f1b73c48b601f94c1416f6c8f8a81035591a Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 14:11:02 +0100 Subject: [PATCH 45/69] wip failing test --- e2e/packages/contracts/worlds.json | 2 +- .../sync-test/setup/startBrowserAndPage.ts | 2 +- packages/store-sync/src/logToTable.test.ts | 35 +++++++++++++++++++ packages/store-sync/src/logToTable.ts | 8 +++-- 4 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 packages/store-sync/src/logToTable.test.ts diff --git a/e2e/packages/contracts/worlds.json b/e2e/packages/contracts/worlds.json index bd48105fd7..a9623cfa62 100644 --- a/e2e/packages/contracts/worlds.json +++ b/e2e/packages/contracts/worlds.json @@ -1,5 +1,5 @@ { "31337": { - "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3" + "address": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c" } } \ No newline at end of file diff --git a/e2e/packages/sync-test/setup/startBrowserAndPage.ts b/e2e/packages/sync-test/setup/startBrowserAndPage.ts index f5ab642f9b..0f18151879 100644 --- a/e2e/packages/sync-test/setup/startBrowserAndPage.ts +++ b/e2e/packages/sync-test/setup/startBrowserAndPage.ts @@ -14,7 +14,7 @@ export async function startBrowserAndPage( // log uncaught errors in the browser page (browser and test consoles are separate) page.on("pageerror", (err) => { - console.log(chalk.yellow("[browser page error]:"), err.message); + console.log(chalk.yellow("[browser page error]:"), err.message, err); }); // log browser's console logs diff --git a/packages/store-sync/src/logToTable.test.ts b/packages/store-sync/src/logToTable.test.ts new file mode 100644 index 0000000000..e11c12bfd9 --- /dev/null +++ b/packages/store-sync/src/logToTable.test.ts @@ -0,0 +1,35 @@ +import { describe, it, expect } from "vitest"; +import { logToTable } from "./logToTable"; + +describe("logToTable", () => { + it("should convert a table registration log to table object", async () => { + expect( + logToTable({ + address: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c", + eventName: "StoreSetRecord", + args: { + table: "0x6d756473746f726500000000000000005461626c657300000000000000000000", + key: ["0x6d756473746f726500000000000000005461626c657300000000000000000000"], + staticData: + "0x0060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c40000000000000000000000000000000000000000000000", + encodedLengths: "0x00000000000000000000000000000000000000a00000000220000000000002c0", + dynamicData: + "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077461626c654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000b6669656c644c61796f757400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096b6579536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76616c7565536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012616269456e636f6465644b65794e616d657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014616269456e636f6465644669656c644e616d6573000000000000000000000000", + }, + }) + ).toMatchInlineSnapshot(` + { + "address": "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c", + "keySchema": { + "tableId": "bytes32", + }, + "name": "Tables", + "namespace": "mudstore", + "tableId": "0x6d756473746f726500000000000000005461626c657300000000000000000000", + "valueSchema": { + "undefined": "bytes", + }, + } + `); + }); +}); diff --git a/packages/store-sync/src/logToTable.ts b/packages/store-sync/src/logToTable.ts index d92fee3213..2ad907cb4e 100644 --- a/packages/store-sync/src/logToTable.ts +++ b/packages/store-sync/src/logToTable.ts @@ -1,5 +1,5 @@ import { hexToSchema, decodeValue } from "@latticexyz/protocol-parser"; -import { concatHex, decodeAbiParameters, parseAbiParameters } from "viem"; +import { concatHex, decodeAbiParameters } from "viem"; import { StorageAdapterLog, Table, schemasTable } from "./common"; import { hexToTableId } from "@latticexyz/common"; @@ -17,11 +17,13 @@ export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord schemasTable.schema, concatHex([log.args.staticData, log.args.encodedLengths, log.args.dynamicData]) ); + console.log("value", table, value); const keySchema = hexToSchema(value.keySchema); const valueSchema = hexToSchema(value.valueSchema); - const keyNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedKeyNames)[0]; - const fieldNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedFieldNames)[0]; + + const keyNames = decodeAbiParameters([{ type: "string[]" }], value.abiEncodedKeyNames)[0]; + const fieldNames = decodeAbiParameters([{ type: "string[]" }], value.abiEncodedFieldNames)[0]; const valueAbiTypes = [...valueSchema.staticFields, ...valueSchema.dynamicFields]; From a359fafd1fdcc4a01cf6156abc383ad67e685bbc Mon Sep 17 00:00:00 2001 From: alvrs Date: Thu, 14 Sep 2023 14:18:50 +0100 Subject: [PATCH 46/69] generate test data --- test-data/world-logs.json | 340 +++++++++++++++++++------------------- 1 file changed, 170 insertions(+), 170 deletions(-) diff --git a/test-data/world-logs.json b/test-data/world-logs.json index ad9e82a25e..3b9319cab6 100644 --- a/test-data/world-logs.json +++ b/test-data/world-logs.json @@ -5,8 +5,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000022000000000a0000000000002c0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000016d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000600060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077461626c654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000b6669656c644c61796f757400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096b6579536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76616c7565536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012616269456e636f6465644b65794e616d657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014616269456e636f6465644669656c644e616d6573000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1", @@ -19,8 +19,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000016d756473746f7265000000000000000053746f7265486f6f6b7300000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x2", @@ -33,8 +33,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000001001004f0000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d657370616365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000056f776e6572000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x3", @@ -47,8 +47,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000042616c616e636573000000000000000000000000000000000000000000000000000000000000000000000000000000600020010020000000000000000000000000000000000000000000000000000000001001004f000000000000000000000000000000000000000000000000000000002001001f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d6573706163650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000762616c616e636500000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x4", @@ -61,8 +61,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000003002004f5f0000000000000000000000000000000000000000000000000000001401006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a6d6f64756c654e616d6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d617267756d656e74734861736800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6d6f64756c654164647265737300000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x5", @@ -75,8 +75,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000044656c65676174696f6e730000000000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000028020061610000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000964656c656761746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000964656c6567617465650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001364656c65676174696f6e436f6e74726f6c496400000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x6", @@ -89,8 +89,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000003402005f610000000000000000000000000000000000000000000000000000000101006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663616c6c6572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066163636573730000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x7", @@ -103,8 +103,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000600015020014010000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000001502006160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000673797374656d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c7075626c69634163636573730000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x8", @@ -117,8 +117,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000240200200400000000000000000000000000000000000000000000000000000004010043000000000000000000000000000000000000000000000000000000002402005f43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001066756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001673797374656d46756e6374696f6e53656c6563746f7200000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x9", @@ -131,8 +131,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d486f6f6b73000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xa", @@ -145,8 +145,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d52656769737472790000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000673797374656d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xb", @@ -159,8 +159,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c7265736f75726365547970650000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xc", @@ -173,8 +173,8 @@ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], "data": "0x000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xd", @@ -187,8 +187,8 @@ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xe", @@ -201,8 +201,8 @@ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xf", @@ -215,8 +215,8 @@ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e730000000000000000000000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x10", @@ -229,8 +229,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e73000000000000000000000000000000000000000000000000000000000000000000000000000000000015cafac3dd18ac6c6e92c921884f9e4176737c052c0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x11", @@ -243,8 +243,8 @@ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000636f72652e7300000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x12", @@ -257,8 +257,8 @@ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x13", @@ -271,8 +271,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000140554c3a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000040554c3a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x14", @@ -285,8 +285,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000018d53b20800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008d53b208000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x15", @@ -299,8 +299,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000125f6221000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000025f62210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x16", @@ -313,8 +313,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000012bfaa27400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000002bfaa274000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x17", @@ -327,8 +327,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000121293ca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000021293ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x18", @@ -341,8 +341,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013ea8492200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003ea84922000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x19", @@ -355,8 +355,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000018da798da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008da798da000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1a", @@ -369,8 +369,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010ba51f4900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000000ba51f49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1b", @@ -383,8 +383,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001530f4b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000530f4b60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1c", @@ -397,8 +397,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010560912900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000005609129000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1d", @@ -411,8 +411,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a886545e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a886545e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1e", @@ -425,8 +425,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001d5f8337f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000d5f8337f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1f", @@ -439,8 +439,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a92813ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a92813ad000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x20", @@ -453,8 +453,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013350b6a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003350b6a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x21", @@ -467,8 +467,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013c03a51c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003c03a51c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x22", @@ -481,8 +481,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b7a3c75600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000b7a3c756000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x23", @@ -495,8 +495,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000011d2257ba00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000001d2257ba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x24", @@ -509,8 +509,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x00000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000002636f72652e6d0000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4700000000000000000000000000000000000000000000000000000000000000014e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x25", @@ -522,10 +522,10 @@ "topics": [ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x607b94e53ff6d14c8af149f742239040a26773006b3916fca7403ab56bc1addf", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x6e2aab704607203c7b30d7116e7885affc7be5e9c54cdd50b58f6a2ff2850bbf", "transactionIndex": "0x8", "logIndex": "0x26", "transactionLogIndex": "0x0", @@ -536,10 +536,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d626572000000000000000000000000000000000000000000000000000000000000000000000000000000000060000401000400000000000000000000000000000000000000000000000000000000040100030000000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x607b94e53ff6d14c8af149f742239040a26773006b3916fca7403ab56bc1addf", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000040000000000000e000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c697374000000000000000000000000000000000000000000000000000000000000000000000000006000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x6e2aab704607203c7b30d7116e7885affc7be5e9c54cdd50b58f6a2ff2850bbf", "transactionIndex": "0x8", "logIndex": "0x27", "transactionLogIndex": "0x1", @@ -550,10 +550,10 @@ "topics": [ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x809f38566746a983087006b293190f70f19c0a54cc76ba40c9fafe8bab17188e", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x641e0226df365dd94c678ee05cd3e82901463bc96c369fc863400ae4795b4757", "transactionIndex": "0x9", "logIndex": "0x28", "transactionLogIndex": "0x0", @@ -564,10 +564,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000040000000000000e000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c697374000000000000000000000000000000000000000000000000000000000000000000000000006000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x809f38566746a983087006b293190f70f19c0a54cc76ba40c9fafe8bab17188e", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d626572000000000000000000000000000000000000000000000000000000000000000000000000000000000060000401000400000000000000000000000000000000000000000000000000000000040100030000000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x641e0226df365dd94c678ee05cd3e82901463bc96c369fc863400ae4795b4757", "transactionIndex": "0x9", "logIndex": "0x29", "transactionLogIndex": "0x1", @@ -578,10 +578,10 @@ "topics": [ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0xffe26db1e7c989f47f2943adc4ef1f7b756e0171e098403aa328f9e62f361bad", "transactionIndex": "0xa", "logIndex": "0x2a", "transactionLogIndex": "0x0", @@ -592,10 +592,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000150165878a594ca255338adfa4d48449f69242eb8f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000006000080200040400000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000802002323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b6579000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0xffe26db1e7c989f47f2943adc4ef1f7b756e0171e098403aa328f9e62f361bad", "transactionIndex": "0xa", "logIndex": "0x2b", "transactionLogIndex": "0x1", @@ -606,27 +606,27 @@ "topics": [ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000004e756d6265724c69737453797374656d", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", - "transactionIndex": "0xa", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", + "transactionIndex": "0xb", "logIndex": "0x2c", - "transactionLogIndex": "0x2", + "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", - "transactionIndex": "0xa", + "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000155fc8d32690cc91d4c39d9d3abcbd16989f8757070100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", + "transactionIndex": "0xb", "logIndex": "0x2d", - "transactionLogIndex": "0x3", + "transactionLogIndex": "0x1", "removed": false }, { @@ -634,27 +634,27 @@ "topics": [ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000437573746f6d4572726f727353797374", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", "transactionIndex": "0xb", "logIndex": "0x2e", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x2", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000155fc8d32690cc91d4c39d9d3abcbd16989f8757070100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f87570700000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", "transactionIndex": "0xb", "logIndex": "0x2f", - "transactionLogIndex": "0x1", + "transactionLogIndex": "0x3", "removed": false }, { @@ -662,27 +662,27 @@ "topics": [ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000437573746f6d4572726f727353797374", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", - "transactionIndex": "0xb", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x7b42490b840b0a1f6d87a853852f9115f7925d7a0e6c86a5526c7ef9e03cb211", + "transactionIndex": "0xc", "logIndex": "0x30", - "transactionLogIndex": "0x2", + "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f87570700000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", - "transactionIndex": "0xb", + "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000150165878a594ca255338adfa4d48449f69242eb8f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x7b42490b840b0a1f6d87a853852f9115f7925d7a0e6c86a5526c7ef9e03cb211", + "transactionIndex": "0xc", "logIndex": "0x31", - "transactionLogIndex": "0x3", + "transactionLogIndex": "0x1", "removed": false }, { @@ -690,27 +690,27 @@ "topics": [ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x75f138556b7a5086ee800ce634d428fd9775d61e9d62dc8f6242e1586a762c30", + "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000004e756d6265724c69737453797374656d", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x7b42490b840b0a1f6d87a853852f9115f7925d7a0e6c86a5526c7ef9e03cb211", "transactionIndex": "0xc", "logIndex": "0x32", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x2", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" + "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], - "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000006000080200040400000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000802002323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b6579000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x75f138556b7a5086ee800ce634d428fd9775d61e9d62dc8f6242e1586a762c30", + "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x7b42490b840b0a1f6d87a853852f9115f7925d7a0e6c86a5526c7ef9e03cb211", "transactionIndex": "0xc", "logIndex": "0x33", - "transactionLogIndex": "0x1", + "transactionLogIndex": "0x3", "removed": false }, { @@ -719,8 +719,8 @@ "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c7469000000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x2d3fb06c20276d48f9a04f14d92f70e31011b23f5fcecc6721fb5598360a4c75", "transactionIndex": "0xd", "logIndex": "0x34", @@ -733,8 +733,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000001c0000000000002c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c74690000000000000000000000000000000000000000000000000000000000000000000000000000000000006000210200200100000000000000000000000000000000000000000000000000000034040003601f2e000000000000000000000000000000000000000000000000002102003f60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000162000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000036e756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x2d3fb06c20276d48f9a04f14d92f70e31011b23f5fcecc6721fb5598360a4c75", "transactionIndex": "0xd", "logIndex": "0x35", @@ -746,10 +746,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656da4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x9d21ec923cfc66bc0b7fc283fd5c90fca31fbca1c881fa4afb1dd4884e6cb2d1", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656db8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x17709682bdb642bbf64843410b3392ce5df745f502f7b0f55d8b783212bfb809", "transactionIndex": "0xe", "logIndex": "0x36", "transactionLogIndex": "0x0", @@ -760,10 +760,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001f7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656df7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0x750e99e7e822739dc4bed149a9ad6d8c78a9a6e5a0c6021c5b508548847afe6d", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656d306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x8a7c23ef1cf049955cdd85d056a394bf2394943dd22d65ca472629041d0fa4bc", "transactionIndex": "0xf", "logIndex": "0x37", "transactionLogIndex": "0x0", @@ -774,10 +774,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656d306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0xa1d5a5b9fbc79c30072955f0fc8fd9c8397757176eaadacebdb7598cd9141d24", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001f7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656df7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0x77b03de8eef7f084dea0958f5f69c881d3ff3ae5df88d32110e9095536640b66", "transactionIndex": "0x10", "logIndex": "0x38", "transactionLogIndex": "0x0", @@ -789,8 +789,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000015f644e3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000437573746f6d4572726f7273537973745f644e3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", "transactionHash": "0x52057dfd4f9e6818f5565203a1e5a7abe7c1e242d91ca32c9353d5a88002b99e", "transactionIndex": "0x11", "logIndex": "0x39", @@ -802,10 +802,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656db8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x474501c398b9cf012e3355be946761d3db01729686218258e8ace8a20089a0e7", - "blockNumber": "0x4", - "transactionHash": "0xbe213a215bd71f17f867b8129a24630241f970e1cf5231f8a3bb2ba412b68a70", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656da4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", + "blockNumber": "0x5", + "transactionHash": "0xa72dbc5ed7514936419e040084824db63d3e7ff6977f67cf529fcc3b5218d4da", "transactionIndex": "0x12", "logIndex": "0x3a", "transactionLogIndex": "0x0", @@ -817,8 +817,8 @@ "0x9ded3a5a78199a737f59213ee5817f193988e67d8f197b17314f1804fe6715c8" ], "data": "0x000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000040000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000001a400000000000000000000000000000000000000000000000000000000", - "blockHash": "0x31ef6f8925641e60d844088938c75fee8baeaec927fc09b7fd51050c2ca29e1e", - "blockNumber": "0x5", + "blockHash": "0x5c1a5dd8edcae0be59abf8a4c25608a77b9ee96ea698373d0a8259fcbd49c2ae", + "blockNumber": "0x6", "transactionHash": "0x913934c3603cedb30d6ec5131ca347ce5f3906f6146f7fdfe39ad6008e6e0a94", "transactionIndex": "0x0", "logIndex": "0x0", @@ -831,8 +831,8 @@ "0x9ded3a5a78199a737f59213ee5817f193988e67d8f197b17314f1804fe6715c8" ], "data": "0x000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000800000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000004500000000000000000000000000000000000000000000000000000000", - "blockHash": "0x31ef6f8925641e60d844088938c75fee8baeaec927fc09b7fd51050c2ca29e1e", - "blockNumber": "0x5", + "blockHash": "0x5c1a5dd8edcae0be59abf8a4c25608a77b9ee96ea698373d0a8259fcbd49c2ae", + "blockNumber": "0x6", "transactionHash": "0xa5e0a4df59ae785eb7f2abc61ab104cbd97db921a61ad3a5a34b7a959d543ca6", "transactionIndex": "0x1", "logIndex": "0x1", From bf90a347c741cd64cbf86ea66bce669bd267033c Mon Sep 17 00:00:00 2001 From: alvrs Date: Thu, 14 Sep 2023 15:22:29 +0100 Subject: [PATCH 47/69] add test for correct hex encoding to packed counter --- packages/store/test/PackedCounter.t.sol | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/store/test/PackedCounter.t.sol b/packages/store/test/PackedCounter.t.sol index 5da1cfcf2e..18b8bb14e9 100644 --- a/packages/store/test/PackedCounter.t.sol +++ b/packages/store/test/PackedCounter.t.sol @@ -102,4 +102,9 @@ contract PackedCounterTest is Test, GasReporter { endGasReport(); assertEq(packedCounter.total(), 1 * 32 + 2 * 20 + 3 * 1 + 4 * 16); } + + function testHexEncoding() public { + PackedCounter packedCounter = PackedCounterLib.pack(160, 544); + assertEq(packedCounter.unwrap(), hex"000000000000000000000000000000000000022000000000a0000000000002c0"); + } } From 838cebe2cefebc81df1d2876d26678ca49905fb3 Mon Sep 17 00:00:00 2001 From: alvrs Date: Thu, 14 Sep 2023 15:22:46 +0100 Subject: [PATCH 48/69] fix test input --- packages/store-sync/src/logToTable.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/store-sync/src/logToTable.test.ts b/packages/store-sync/src/logToTable.test.ts index e11c12bfd9..3047f7cda9 100644 --- a/packages/store-sync/src/logToTable.test.ts +++ b/packages/store-sync/src/logToTable.test.ts @@ -12,7 +12,7 @@ describe("logToTable", () => { key: ["0x6d756473746f726500000000000000005461626c657300000000000000000000"], staticData: "0x0060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c40000000000000000000000000000000000000000000000", - encodedLengths: "0x00000000000000000000000000000000000000a00000000220000000000002c0", + encodedLengths: "0x000000000000000000000000000000000000022000000000a0000000000002c0", // "0x00000000000000000000000000000000000000a00000000220000000000002c0", dynamicData: "0x00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077461626c654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000b6669656c644c61796f757400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096b6579536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76616c7565536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012616269456e636f6465644b65794e616d657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014616269456e636f6465644669656c644e616d6573000000000000000000000000", }, From 2902fb1f9a8db5049851e15720525592fcc366eb Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 15:24:05 +0100 Subject: [PATCH 49/69] don't reverse twice --- packages/protocol-parser/src/encodeLengths.ts | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/packages/protocol-parser/src/encodeLengths.ts b/packages/protocol-parser/src/encodeLengths.ts index 32ba640c8b..5a3bbf0827 100644 --- a/packages/protocol-parser/src/encodeLengths.ts +++ b/packages/protocol-parser/src/encodeLengths.ts @@ -6,13 +6,7 @@ export function encodeLengths(values: Hex[]): Hex { const totalByteLength = byteLengths.reduce((total, length) => total + BigInt(length), 0n); return padHex( - concatHex([ - ...byteLengths - .slice() - .reverse() - .map((length) => encodeField("uint40", length)), - encodeField("uint56", totalByteLength), - ]), + concatHex([...byteLengths.map((length) => encodeField("uint40", length)), encodeField("uint56", totalByteLength)]), { size: 32, dir: "left" } ); } From 567573e776486fdd4f7e8bc0f89797843f97708d Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 15:29:02 +0100 Subject: [PATCH 50/69] add encodeLengths test --- packages/protocol-parser/src/encodeLengths.test.ts | 10 ++++++++++ packages/store-sync/src/logToTable.test.ts | 6 +++++- packages/store-sync/src/logToTable.ts | 1 - 3 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 packages/protocol-parser/src/encodeLengths.test.ts diff --git a/packages/protocol-parser/src/encodeLengths.test.ts b/packages/protocol-parser/src/encodeLengths.test.ts new file mode 100644 index 0000000000..c55204ddc6 --- /dev/null +++ b/packages/protocol-parser/src/encodeLengths.test.ts @@ -0,0 +1,10 @@ +import { describe, expect, it } from "vitest"; +import { encodeLengths } from "./encodeLengths"; + +describe("encodeLengths", () => { + it("can encode bool key tuple", () => { + expect(encodeLengths(["0x1234", "0x12345678"])).toMatchInlineSnapshot( + '"0x0000000000000000000000000000000000000004000000000200000000000006"' + ); + }); +}); diff --git a/packages/store-sync/src/logToTable.test.ts b/packages/store-sync/src/logToTable.test.ts index 3047f7cda9..0a03ae498a 100644 --- a/packages/store-sync/src/logToTable.test.ts +++ b/packages/store-sync/src/logToTable.test.ts @@ -27,7 +27,11 @@ describe("logToTable", () => { "namespace": "mudstore", "tableId": "0x6d756473746f726500000000000000005461626c657300000000000000000000", "valueSchema": { - "undefined": "bytes", + "abiEncodedFieldNames": "bytes", + "abiEncodedKeyNames": "bytes", + "fieldLayout": "bytes32", + "keySchema": "bytes32", + "valueSchema": "bytes32", }, } `); diff --git a/packages/store-sync/src/logToTable.ts b/packages/store-sync/src/logToTable.ts index 2ad907cb4e..08c55ba94c 100644 --- a/packages/store-sync/src/logToTable.ts +++ b/packages/store-sync/src/logToTable.ts @@ -17,7 +17,6 @@ export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord schemasTable.schema, concatHex([log.args.staticData, log.args.encodedLengths, log.args.dynamicData]) ); - console.log("value", table, value); const keySchema = hexToSchema(value.keySchema); const valueSchema = hexToSchema(value.valueSchema); From 46d28e87efba9f2bfe8bf02693153c5bc0c31677 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 15:43:27 +0100 Subject: [PATCH 51/69] add spliceHex helper --- packages/protocol-parser/src/index.ts | 1 + packages/protocol-parser/src/spliceHex.ts | 7 ++++++ .../src/postgres/postgresStorage.ts | 18 +++------------ packages/store-sync/src/recs/recsStorage.ts | 18 +++------------ packages/store-sync/src/spliceValueHex.ts | 22 ------------------- .../store-sync/src/sqlite/sqliteStorage.ts | 18 +++------------ 6 files changed, 17 insertions(+), 67 deletions(-) create mode 100644 packages/protocol-parser/src/spliceHex.ts delete mode 100644 packages/store-sync/src/spliceValueHex.ts diff --git a/packages/protocol-parser/src/index.ts b/packages/protocol-parser/src/index.ts index 71d8915e2c..b563b21dd7 100644 --- a/packages/protocol-parser/src/index.ts +++ b/packages/protocol-parser/src/index.ts @@ -23,6 +23,7 @@ export * from "./keySchemaToHex"; export * from "./readHex"; export * from "./schemaIndexToAbiType"; export * from "./schemaToHex"; +export * from "./spliceHex"; export * from "./staticDataLength"; export * from "./valueSchemaToFieldLayoutHex"; export * from "./valueSchemaToHex"; diff --git a/packages/protocol-parser/src/spliceHex.ts b/packages/protocol-parser/src/spliceHex.ts new file mode 100644 index 0000000000..a7e104d477 --- /dev/null +++ b/packages/protocol-parser/src/spliceHex.ts @@ -0,0 +1,7 @@ +import { Hex, concatHex } from "viem"; +import { readHex } from "./readHex"; + +// TODO: move to common +export function spliceHex(data: Hex, start: number, deleteCount = 0, newData: Hex = "0x"): Hex { + return concatHex([readHex(data, 0, start), newData, readHex(data, start + deleteCount)]); +} diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index 42d163e4a3..9c50ba5944 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -13,7 +13,7 @@ import { getTableKey } from "./getTableKey"; import { StorageAdapter, StorageAdapterBlock } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; -import { decodeKey, decodeValueArgs, readHex } from "@latticexyz/protocol-parser"; +import { decodeKey, decodeValueArgs, readHex, spliceHex } from "@latticexyz/protocol-parser"; import { assertExhaustive } from "@latticexyz/common/utils"; // Currently assumes one DB per chain ID @@ -146,13 +146,7 @@ export async function postgresStorage // TODO: verify that this returns what we expect (doesn't error/undefined on no record) const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x"; - const start = log.args.start; - const end = start + log.args.deleteCount; - const newStaticData = concatHex([ - readHex(previousStaticData, 0, start), - log.args.data, - readHex(previousStaticData, end), - ]); + const newStaticData = spliceHex(previousStaticData, log.args.start, log.args.deleteCount, log.args.data); const newValue = decodeValueArgs(table.valueSchema, { staticData: newStaticData, encodedLengths: (previousValue?.__encodedLengths as Hex) ?? "0x", @@ -191,13 +185,7 @@ export async function postgresStorage // TODO: verify that this returns what we expect (doesn't error/undefined on no record) const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x"; - const start = log.args.start; - const end = start + log.args.deleteCount; - const newDynamicData = concatHex([ - readHex(previousDynamicData, 0, start), - log.args.data, - readHex(previousDynamicData, end), - ]); + const newDynamicData = spliceHex(previousDynamicData, log.args.start, log.args.deleteCount, log.args.data); const newValue = decodeValueArgs(table.valueSchema, { staticData: (previousValue?.__staticData as Hex) ?? "0x", // TODO: handle unchanged encoded lengths diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index 0a60d68319..96dba1b6ed 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -4,7 +4,7 @@ import { World as RecsWorld, getComponentValue, hasComponent, removeComponent, s import { defineInternalComponents } from "./defineInternalComponents"; import { getTableEntity } from "./getTableEntity"; import { hexToTableId } from "@latticexyz/common"; -import { decodeValueArgs, readHex } from "@latticexyz/protocol-parser"; +import { decodeValueArgs, readHex, spliceHex } from "@latticexyz/protocol-parser"; import { Hex, concatHex } from "viem"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; @@ -99,13 +99,7 @@ export function recsStorage({ // TODO: add tests that this works when no record had been set before const previousValue = getComponentValue(component, entity); const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x"; - const start = log.args.start; - const end = start + log.args.deleteCount; - const newStaticData = concatHex([ - readHex(previousStaticData, 0, start), - log.args.data, - readHex(previousStaticData, end), - ]); + const newStaticData = spliceHex(previousStaticData, log.args.start, log.args.deleteCount, log.args.data); const newValue = decodeValueArgs(table.valueSchema, { staticData: newStaticData, encodedLengths: (previousValue?.__encodedLengths as Hex) ?? "0x", @@ -128,13 +122,7 @@ export function recsStorage({ // TODO: add tests that this works when no record had been set before const previousValue = getComponentValue(component, entity); const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x"; - const start = log.args.start; - const end = start + log.args.deleteCount; - const newDynamicData = concatHex([ - readHex(previousDynamicData, 0, start), - log.args.data, - readHex(previousDynamicData, end), - ]); + const newDynamicData = spliceHex(previousDynamicData, log.args.start, log.args.deleteCount, log.args.data); const newValue = decodeValueArgs(table.valueSchema, { staticData: (previousValue?.__staticData as Hex) ?? "0x", // TODO: handle unchanged encoded lengths diff --git a/packages/store-sync/src/spliceValueHex.ts b/packages/store-sync/src/spliceValueHex.ts deleted file mode 100644 index 599b3a9a1c..0000000000 --- a/packages/store-sync/src/spliceValueHex.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { UNCHANGED_PACKED_COUNTER, readHex } from "@latticexyz/protocol-parser"; -import { Hex, size, concatHex } from "viem"; -import { StorageAdapterLog } from "./common"; - -export function spliceValueHex( - previousData: Hex, - log: StorageAdapterLog & ({ eventName: "StoreSpliceStaticRecord" } | { eventName: "StoreSpliceDynamicRecord" }) -): Hex { - let newData = previousData; - - if (log.args.newDynamicLengths !== UNCHANGED_PACKED_COUNTER) { - const start = Number(log.args.dynamicLengthsStart); - const end = start + size(log.args.newDynamicLengths); - newData = concatHex([readHex(newData, 0, start), log.args.newDynamicLengths, readHex(newData, end)]); - } - - const start = log.args.start; - const end = start + log.args.deleteCount; - newData = concatHex([readHex(newData, 0, start), log.args.data, readHex(newData, end)]); - - return newData; -} diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 2308ea66a7..d484b5094a 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -13,7 +13,7 @@ import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexToTableId, tableIdToHex } from "@latticexyz/common"; -import { decodeKey, decodeValueArgs, readHex } from "@latticexyz/protocol-parser"; +import { decodeKey, decodeValueArgs, readHex, spliceHex } from "@latticexyz/protocol-parser"; import { assertExhaustive } from "@latticexyz/common/utils"; // TODO: upgrade drizzle and use async sqlite interface for consistency @@ -143,13 +143,7 @@ export async function sqliteStorage({ // TODO: verify that this returns what we expect (doesn't error/undefined on no record) const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x"; - const start = log.args.start; - const end = start + log.args.deleteCount; - const newStaticData = concatHex([ - readHex(previousStaticData, 0, start), - log.args.data, - readHex(previousStaticData, end), - ]); + const newStaticData = spliceHex(previousStaticData, log.args.start, log.args.deleteCount, log.args.data); const newValue = decodeValueArgs(table.valueSchema, { staticData: newStaticData, encodedLengths: (previousValue?.__encodedLengths as Hex) ?? "0x", @@ -186,13 +180,7 @@ export async function sqliteStorage({ } else if (log.eventName === "StoreSpliceDynamicRecord") { const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x"; - const start = log.args.start; - const end = start + log.args.deleteCount; - const newDynamicData = concatHex([ - readHex(previousDynamicData, 0, start), - log.args.data, - readHex(previousDynamicData, end), - ]); + const newDynamicData = spliceHex(previousDynamicData, log.args.start, log.args.deleteCount, log.args.data); const newValue = decodeValueArgs(table.valueSchema, { staticData: (previousValue?.__staticData as Hex) ?? "0x", // TODO: handle unchanged encoded lengths From f02845b95f73631c23ad300c0c0a45c9ff1d2e6e Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 15:46:55 +0100 Subject: [PATCH 52/69] move spliceHex/readHex into common --- packages/common/src/index.ts | 2 ++ packages/{protocol-parser => common}/src/readHex.test.ts | 0 packages/{protocol-parser => common}/src/readHex.ts | 0 packages/{protocol-parser => common}/src/spliceHex.ts | 1 - packages/protocol-parser/src/decodeRecord.ts | 2 +- packages/protocol-parser/src/decodeValueArgs.ts | 2 +- packages/protocol-parser/src/hexToPackedCounter.ts | 2 +- packages/protocol-parser/src/index.ts | 2 -- packages/store-sync/src/postgres/postgresStorage.ts | 5 ++--- packages/store-sync/src/recs/recsStorage.ts | 7 +++---- packages/store-sync/src/sqlite/sqliteStorage.ts | 5 ++--- 11 files changed, 12 insertions(+), 16 deletions(-) rename packages/{protocol-parser => common}/src/readHex.test.ts (100%) rename packages/{protocol-parser => common}/src/readHex.ts (100%) rename packages/{protocol-parser => common}/src/spliceHex.ts (91%) diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index 95489023b1..d6a59390fa 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -3,5 +3,7 @@ export * from "./createContract"; export * from "./createNonceManager"; export * from "./getBurnerPrivateKey"; export * from "./hexToTableId"; +export * from "./readHex"; +export * from "./spliceHex"; export * from "./tableIdToHex"; export * from "./transportObserver"; diff --git a/packages/protocol-parser/src/readHex.test.ts b/packages/common/src/readHex.test.ts similarity index 100% rename from packages/protocol-parser/src/readHex.test.ts rename to packages/common/src/readHex.test.ts diff --git a/packages/protocol-parser/src/readHex.ts b/packages/common/src/readHex.ts similarity index 100% rename from packages/protocol-parser/src/readHex.ts rename to packages/common/src/readHex.ts diff --git a/packages/protocol-parser/src/spliceHex.ts b/packages/common/src/spliceHex.ts similarity index 91% rename from packages/protocol-parser/src/spliceHex.ts rename to packages/common/src/spliceHex.ts index a7e104d477..5ce8c1f6d0 100644 --- a/packages/protocol-parser/src/spliceHex.ts +++ b/packages/common/src/spliceHex.ts @@ -1,7 +1,6 @@ import { Hex, concatHex } from "viem"; import { readHex } from "./readHex"; -// TODO: move to common export function spliceHex(data: Hex, start: number, deleteCount = 0, newData: Hex = "0x"): Hex { return concatHex([readHex(data, 0, start), newData, readHex(data, start + deleteCount)]); } diff --git a/packages/protocol-parser/src/decodeRecord.ts b/packages/protocol-parser/src/decodeRecord.ts index 2f8536287d..e4a9f983f3 100644 --- a/packages/protocol-parser/src/decodeRecord.ts +++ b/packages/protocol-parser/src/decodeRecord.ts @@ -10,7 +10,7 @@ import { decodeDynamicField } from "./decodeDynamicField"; import { decodeStaticField } from "./decodeStaticField"; import { hexToPackedCounter } from "./hexToPackedCounter"; import { staticDataLength } from "./staticDataLength"; -import { readHex } from "./readHex"; +import { readHex } from "@latticexyz/common"; /** @deprecated use `decodeValue` instead */ export function decodeRecord(schema: Schema, data: Hex): readonly (StaticPrimitiveType | DynamicPrimitiveType)[] { diff --git a/packages/protocol-parser/src/decodeValueArgs.ts b/packages/protocol-parser/src/decodeValueArgs.ts index da043c31ea..d9f5e5161f 100644 --- a/packages/protocol-parser/src/decodeValueArgs.ts +++ b/packages/protocol-parser/src/decodeValueArgs.ts @@ -3,7 +3,7 @@ import { isStaticAbiType } from "@latticexyz/schema-type"; import { SchemaToPrimitives, ValueArgs, ValueSchema } from "./common"; import { decodeValue } from "./decodeValue"; import { staticDataLength } from "./staticDataLength"; -import { readHex } from "./readHex"; +import { readHex } from "@latticexyz/common"; export function decodeValueArgs( valueSchema: TSchema, diff --git a/packages/protocol-parser/src/hexToPackedCounter.ts b/packages/protocol-parser/src/hexToPackedCounter.ts index 6ab5920bbd..fabb7bfa9d 100644 --- a/packages/protocol-parser/src/hexToPackedCounter.ts +++ b/packages/protocol-parser/src/hexToPackedCounter.ts @@ -2,7 +2,7 @@ import { Hex } from "viem"; import { decodeStaticField } from "./decodeStaticField"; import { decodeDynamicField } from "./decodeDynamicField"; import { InvalidHexLengthForPackedCounterError, PackedCounterLengthMismatchError } from "./errors"; -import { readHex } from "./readHex"; +import { readHex } from "@latticexyz/common"; // Keep this logic in sync with PackedCounter.sol diff --git a/packages/protocol-parser/src/index.ts b/packages/protocol-parser/src/index.ts index b563b21dd7..9874481e71 100644 --- a/packages/protocol-parser/src/index.ts +++ b/packages/protocol-parser/src/index.ts @@ -20,10 +20,8 @@ export * from "./hexToPackedCounter"; export * from "./hexToSchema"; export * from "./hexToTableSchema"; export * from "./keySchemaToHex"; -export * from "./readHex"; export * from "./schemaIndexToAbiType"; export * from "./schemaToHex"; -export * from "./spliceHex"; export * from "./staticDataLength"; export * from "./valueSchemaToFieldLayoutHex"; export * from "./valueSchemaToHex"; diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index 9c50ba5944..1741824e91 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -7,14 +7,13 @@ import { debug } from "./debug"; import { buildInternalTables } from "./buildInternalTables"; import { getTables } from "./getTables"; import { schemaVersion } from "./schemaVersion"; -import { hexToTableId, tableIdToHex } from "@latticexyz/common"; +import { hexToTableId, spliceHex, tableIdToHex } from "@latticexyz/common"; import { setupTables } from "./setupTables"; import { getTableKey } from "./getTableKey"; import { StorageAdapter, StorageAdapterBlock } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; -import { decodeKey, decodeValueArgs, readHex, spliceHex } from "@latticexyz/protocol-parser"; -import { assertExhaustive } from "@latticexyz/common/utils"; +import { decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser"; // Currently assumes one DB per chain ID diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index 96dba1b6ed..a445ec546c 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -3,13 +3,12 @@ import { debug } from "./debug"; import { World as RecsWorld, getComponentValue, hasComponent, removeComponent, setComponent } from "@latticexyz/recs"; import { defineInternalComponents } from "./defineInternalComponents"; import { getTableEntity } from "./getTableEntity"; -import { hexToTableId } from "@latticexyz/common"; -import { decodeValueArgs, readHex, spliceHex } from "@latticexyz/protocol-parser"; -import { Hex, concatHex } from "viem"; +import { hexToTableId, spliceHex } from "@latticexyz/common"; +import { decodeValueArgs } from "@latticexyz/protocol-parser"; +import { Hex } from "viem"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; import { hexKeyTupleToEntity } from "./hexKeyTupleToEntity"; -import { assertExhaustive } from "@latticexyz/common/utils"; import { ConfigToRecsComponents } from "./common"; import { StorageAdapter, StorageAdapterBlock } from "../common"; import { configToRecsComponents } from "./configToRecsComponents"; diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index d484b5094a..18e30062d7 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -12,9 +12,8 @@ import { schemaVersion } from "./schemaVersion"; import { StorageAdapter } from "../common"; import { isTableRegistrationLog } from "../isTableRegistrationLog"; import { logToTable } from "../logToTable"; -import { hexToTableId, tableIdToHex } from "@latticexyz/common"; -import { decodeKey, decodeValueArgs, readHex, spliceHex } from "@latticexyz/protocol-parser"; -import { assertExhaustive } from "@latticexyz/common/utils"; +import { hexToTableId, spliceHex, tableIdToHex } from "@latticexyz/common"; +import { decodeKey, decodeValueArgs } from "@latticexyz/protocol-parser"; // TODO: upgrade drizzle and use async sqlite interface for consistency From 30961a4a5cbb7c12787d30368a7b8e678d05e9e8 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 15:52:17 +0100 Subject: [PATCH 53/69] SpliceStaticRecord->SpliceStaticData, SpliceDynamicRecord->SpliceDynamicData --- packages/dev-tools/src/events/EventIcon.tsx | 4 ++-- packages/dev-tools/src/events/LogsTable.tsx | 4 ++-- .../src/postgres/postgresStorage.ts | 4 ++-- packages/store-sync/src/recs/recsStorage.ts | 4 ++-- .../store-sync/src/sqlite/sqliteStorage.ts | 4 ++-- packages/store/abi/IStore.sol/IStore.abi.json | 4 ++-- .../store/abi/IStore.sol/IStore.abi.json.d.ts | 4 ++-- .../store/abi/IStore.sol/IStoreData.abi.json | 4 ++-- .../abi/IStore.sol/IStoreData.abi.json.d.ts | 4 ++-- .../store/abi/IStore.sol/IStoreWrite.abi.json | 4 ++-- .../abi/IStore.sol/IStoreWrite.abi.json.d.ts | 4 ++-- .../abi/StoreCore.sol/StoreCore.abi.json | 4 ++-- .../abi/StoreCore.sol/StoreCore.abi.json.d.ts | 4 ++-- .../abi/StoreMock.sol/StoreMock.abi.json | 4 ++-- .../abi/StoreMock.sol/StoreMock.abi.json.d.ts | 4 ++-- .../StoreReadWithStubs.abi.json | 4 ++-- .../StoreReadWithStubs.abi.json.d.ts | 4 ++-- packages/store/src/IStore.sol | 4 ++-- packages/store/src/StoreCore.sol | 14 ++++++------ packages/store/test/StoreCore.t.sol | 22 +++++++++---------- packages/store/test/StoreCoreDynamic.t.sol | 4 ++-- packages/store/ts/storeEvents.ts | 4 ++-- .../abi/IBaseWorld.sol/IBaseWorld.abi.json | 4 ++-- .../IBaseWorld.sol/IBaseWorld.abi.json.d.ts | 4 ++-- packages/world/abi/IStore.sol/IStore.abi.json | 4 ++-- .../world/abi/IStore.sol/IStore.abi.json.d.ts | 4 ++-- .../world/abi/IStore.sol/IStoreData.abi.json | 4 ++-- .../abi/IStore.sol/IStoreData.abi.json.d.ts | 4 ++-- .../world/abi/IStore.sol/IStoreWrite.abi.json | 4 ++-- .../abi/IStore.sol/IStoreWrite.abi.json.d.ts | 4 ++-- .../abi/StoreCore.sol/StoreCore.abi.json | 4 ++-- .../abi/StoreCore.sol/StoreCore.abi.json.d.ts | 4 ++-- packages/world/abi/World.sol/World.abi.json | 4 ++-- .../world/abi/World.sol/World.abi.json.d.ts | 4 ++-- .../world/abi/src/IStore.sol/IStore.abi.json | 4 ++-- .../abi/src/IStore.sol/IStore.abi.json.d.ts | 4 ++-- .../abi/src/IStore.sol/IStoreData.abi.json | 4 ++-- .../src/IStore.sol/IStoreData.abi.json.d.ts | 4 ++-- .../abi/src/IStore.sol/IStoreWrite.abi.json | 4 ++-- .../src/IStore.sol/IStoreWrite.abi.json.d.ts | 4 ++-- .../abi/src/StoreCore.sol/StoreCore.abi.json | 4 ++-- .../src/StoreCore.sol/StoreCore.abi.json.d.ts | 4 ++-- 42 files changed, 98 insertions(+), 98 deletions(-) diff --git a/packages/dev-tools/src/events/EventIcon.tsx b/packages/dev-tools/src/events/EventIcon.tsx index 3eaa8904b5..8b40c01690 100644 --- a/packages/dev-tools/src/events/EventIcon.tsx +++ b/packages/dev-tools/src/events/EventIcon.tsx @@ -9,8 +9,8 @@ export function EventIcon({ type }: Props) { switch (type) { case "StoreSetRecord": return =; - case "StoreSpliceStaticRecord": - case "StoreSpliceDynamicRecord": + case "StoreSpliceStaticData": + case "StoreSpliceDynamicData": return +; case "StoreDeleteRecord": return -; diff --git a/packages/dev-tools/src/events/LogsTable.tsx b/packages/dev-tools/src/events/LogsTable.tsx index 265d97e97f..0ea450e91c 100644 --- a/packages/dev-tools/src/events/LogsTable.tsx +++ b/packages/dev-tools/src/events/LogsTable.tsx @@ -51,10 +51,10 @@ export function LogsTable({ logs }: Props) { dynamicData: log.args.dynamicData, }) : null} - {log.eventName === "StoreSpliceStaticRecord" + {log.eventName === "StoreSpliceStaticData" ? JSON.stringify({ start: log.args.start, deleteCount: log.args.deleteCount, data: log.args.data }) : null} - {log.eventName === "StoreSpliceDynamicRecord" + {log.eventName === "StoreSpliceDynamicData" ? JSON.stringify({ start: log.args.start, deleteCount: log.args.deleteCount, diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index 1741824e91..ec011b1d53 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -141,7 +141,7 @@ export async function postgresStorage }, }) .execute(); - } else if (log.eventName === "StoreSpliceStaticRecord") { + } else if (log.eventName === "StoreSpliceStaticData") { // TODO: verify that this returns what we expect (doesn't error/undefined on no record) const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x"; @@ -180,7 +180,7 @@ export async function postgresStorage }, }) .execute(); - } else if (log.eventName === "StoreSpliceDynamicRecord") { + } else if (log.eventName === "StoreSpliceDynamicData") { // TODO: verify that this returns what we expect (doesn't error/undefined on no record) const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x"; diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index a445ec546c..a2b6a9cbfb 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -94,7 +94,7 @@ export function recsStorage({ __encodedLengths: log.args.encodedLengths, __dynamicData: log.args.dynamicData, }); - } else if (log.eventName === "StoreSpliceStaticRecord") { + } else if (log.eventName === "StoreSpliceStaticData") { // TODO: add tests that this works when no record had been set before const previousValue = getComponentValue(component, entity); const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x"; @@ -117,7 +117,7 @@ export function recsStorage({ ...newValue, __staticData: newStaticData, }); - } else if (log.eventName === "StoreSpliceDynamicRecord") { + } else if (log.eventName === "StoreSpliceDynamicData") { // TODO: add tests that this works when no record had been set before const previousValue = getComponentValue(component, entity); const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x"; diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 18e30062d7..94d7030c7d 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -138,7 +138,7 @@ export async function sqliteStorage({ }, }) .run(); - } else if (log.eventName === "StoreSpliceStaticRecord") { + } else if (log.eventName === "StoreSpliceStaticData") { // TODO: verify that this returns what we expect (doesn't error/undefined on no record) const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; const previousStaticData = (previousValue?.__staticData as Hex) ?? "0x"; @@ -176,7 +176,7 @@ export async function sqliteStorage({ }, }) .run(); - } else if (log.eventName === "StoreSpliceDynamicRecord") { + } else if (log.eventName === "StoreSpliceDynamicData") { const previousValue = (await tx.select().from(sqlTable).where(eq(sqlTable.__key, uniqueKey)).execute())[0]; const previousDynamicData = (previousValue?.__dynamicData as Hex) ?? "0x"; const newDynamicData = spliceHex(previousDynamicData, log.args.start, log.args.deleteCount, log.args.data); diff --git a/packages/store/abi/IStore.sol/IStore.abi.json b/packages/store/abi/IStore.sol/IStore.abi.json index 988980e56c..d7113e99f3 100644 --- a/packages/store/abi/IStore.sol/IStore.abi.json +++ b/packages/store/abi/IStore.sol/IStore.abi.json @@ -270,7 +270,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -307,7 +307,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/store/abi/IStore.sol/IStore.abi.json.d.ts b/packages/store/abi/IStore.sol/IStore.abi.json.d.ts index 737075f9f2..8cf6aae7dc 100644 --- a/packages/store/abi/IStore.sol/IStore.abi.json.d.ts +++ b/packages/store/abi/IStore.sol/IStore.abi.json.d.ts @@ -270,7 +270,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -307,7 +307,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/store/abi/IStore.sol/IStoreData.abi.json b/packages/store/abi/IStore.sol/IStoreData.abi.json index 42e1a33d7a..fbc42e426b 100644 --- a/packages/store/abi/IStore.sol/IStoreData.abi.json +++ b/packages/store/abi/IStore.sol/IStoreData.abi.json @@ -95,7 +95,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -132,7 +132,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/store/abi/IStore.sol/IStoreData.abi.json.d.ts b/packages/store/abi/IStore.sol/IStoreData.abi.json.d.ts index aa9d9f1b20..9c80fe8e60 100644 --- a/packages/store/abi/IStore.sol/IStoreData.abi.json.d.ts +++ b/packages/store/abi/IStore.sol/IStoreData.abi.json.d.ts @@ -95,7 +95,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -132,7 +132,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/store/abi/IStore.sol/IStoreWrite.abi.json b/packages/store/abi/IStore.sol/IStoreWrite.abi.json index 79ca52d499..dd1af51fbe 100644 --- a/packages/store/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/store/abi/IStore.sol/IStoreWrite.abi.json @@ -95,7 +95,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -132,7 +132,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/store/abi/IStore.sol/IStoreWrite.abi.json.d.ts b/packages/store/abi/IStore.sol/IStoreWrite.abi.json.d.ts index c520422689..2a2011ae3f 100644 --- a/packages/store/abi/IStore.sol/IStoreWrite.abi.json.d.ts +++ b/packages/store/abi/IStore.sol/IStoreWrite.abi.json.d.ts @@ -95,7 +95,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -132,7 +132,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/store/abi/StoreCore.sol/StoreCore.abi.json b/packages/store/abi/StoreCore.sol/StoreCore.abi.json index f7d07e59ba..78c4d54a7f 100644 --- a/packages/store/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/store/abi/StoreCore.sol/StoreCore.abi.json @@ -132,7 +132,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -169,7 +169,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" } ] \ No newline at end of file diff --git a/packages/store/abi/StoreCore.sol/StoreCore.abi.json.d.ts b/packages/store/abi/StoreCore.sol/StoreCore.abi.json.d.ts index e976253f94..34161ca69b 100644 --- a/packages/store/abi/StoreCore.sol/StoreCore.abi.json.d.ts +++ b/packages/store/abi/StoreCore.sol/StoreCore.abi.json.d.ts @@ -132,7 +132,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -169,7 +169,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; } ]; diff --git a/packages/store/abi/StoreMock.sol/StoreMock.abi.json b/packages/store/abi/StoreMock.sol/StoreMock.abi.json index 8484bf2135..982aeb5e24 100644 --- a/packages/store/abi/StoreMock.sol/StoreMock.abi.json +++ b/packages/store/abi/StoreMock.sol/StoreMock.abi.json @@ -344,7 +344,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -381,7 +381,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/store/abi/StoreMock.sol/StoreMock.abi.json.d.ts b/packages/store/abi/StoreMock.sol/StoreMock.abi.json.d.ts index 4105fa629d..3a75187c59 100644 --- a/packages/store/abi/StoreMock.sol/StoreMock.abi.json.d.ts +++ b/packages/store/abi/StoreMock.sol/StoreMock.abi.json.d.ts @@ -344,7 +344,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -381,7 +381,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json index 2542748806..f6a6d2ebc8 100644 --- a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json +++ b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json @@ -296,7 +296,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -333,7 +333,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json.d.ts b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json.d.ts index 13e2ec256f..109253d892 100644 --- a/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json.d.ts +++ b/packages/store/abi/StoreReadWithStubs.sol/StoreReadWithStubs.abi.json.d.ts @@ -296,7 +296,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -333,7 +333,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index 8963d820a1..d40246a2e3 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -51,8 +51,8 @@ interface IStoreRead { interface IStoreWrite { event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData); - event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); - event StoreSpliceDynamicRecord( + event StoreSpliceStaticData(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); + event StoreSpliceDynamicData( bytes32 table, bytes32[] key, uint48 start, diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index 5714e2b80e..f2a130b192 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -18,8 +18,8 @@ import { StoreHookLib, StoreHookType } from "./StoreHook.sol"; library StoreCore { // note: the preimage of the tuple of keys used to index is part of the event, so it can be used by indexers event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData); - event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); - event StoreSpliceDynamicRecord( + event StoreSpliceStaticData(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data); + event StoreSpliceDynamicData( bytes32 table, bytes32[] key, uint48 start, @@ -631,7 +631,7 @@ library StoreCoreInternal { uint256 deleteCount = fieldLayout.atIndex(schemaIndex); // Emit event to notify indexers - emit StoreCore.StoreSpliceStaticRecord(tableId, key, uint48(start), uint40(deleteCount), data); + emit StoreCore.StoreSpliceStaticData(tableId, key, uint48(start), uint40(deleteCount), data); } function _setDynamicField( @@ -667,7 +667,7 @@ library StoreCoreInternal { } uint256 deleteCount = oldFieldLength; // Emit event to notify indexers - emit StoreCore.StoreSpliceDynamicRecord( + emit StoreCore.StoreSpliceDynamicData( tableId, key, uint48(start), @@ -709,7 +709,7 @@ library StoreCoreInternal { } uint256 deleteCount = 0; // Emit event to notify indexers - emit StoreCore.StoreSpliceDynamicRecord( + emit StoreCore.StoreSpliceDynamicData( tableId, key, uint48(start), @@ -754,7 +754,7 @@ library StoreCoreInternal { uint256 deleteCount = byteLengthToPop; // Emit event to notify indexers - emit StoreCore.StoreSpliceDynamicRecord( + emit StoreCore.StoreSpliceDynamicData( tableId, key, uint48(start), @@ -794,7 +794,7 @@ library StoreCoreInternal { uint256 deleteCount = dataToSet.length; // Emit event to notify indexers - emit StoreCore.StoreSpliceDynamicRecord( + emit StoreCore.StoreSpliceDynamicData( tableId, key, uint48(start), diff --git a/packages/store/test/StoreCore.t.sol b/packages/store/test/StoreCore.t.sol index 1d725d10c6..b875834e20 100644 --- a/packages/store/test/StoreCore.t.sol +++ b/packages/store/test/StoreCore.t.sol @@ -382,9 +382,9 @@ contract StoreCoreTest is Test, StoreMock { bytes memory firstDataPacked = abi.encodePacked(firstDataBytes); - // Expect a StoreSpliceStaticRecord event to be emitted + // Expect a StoreSpliceStaticData event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceStaticRecord(table, key, 0, uint40(firstDataPacked.length), firstDataPacked); + emit StoreSpliceStaticData(table, key, 0, uint40(firstDataPacked.length), firstDataPacked); // Set first field IStore(this).setField(table, key, 0, firstDataPacked, fieldLayout); @@ -410,7 +410,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceStaticRecord( + emit StoreSpliceStaticData( table, key, uint48(firstDataPacked.length), @@ -463,7 +463,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceDynamicRecord( + emit StoreSpliceDynamicData( table, key, uint48(0), @@ -492,7 +492,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceDynamicRecord( + emit StoreSpliceDynamicData( table, key, uint48(thirdDataBytes.length), @@ -525,7 +525,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceDynamicRecord( + emit StoreSpliceDynamicData( table, key, uint48(thirdDataBytes.length), @@ -687,9 +687,9 @@ contract StoreCoreTest is Test, StoreMock { } data.newSecondDataBytes = abi.encodePacked(data.secondDataBytes, data.secondDataToPush); - // Expect a StoreSpliceDynamicRecord event to be emitted + // Expect a StoreSpliceDynamicData event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceDynamicRecord( + emit StoreSpliceDynamicData( data.table, data.key, uint48(data.secondDataBytes.length), @@ -732,7 +732,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceDynamicRecord( + emit StoreSpliceDynamicData( data.table, data.key, uint48(data.newSecondDataBytes.length + data.thirdDataBytes.length), @@ -842,7 +842,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceDynamicRecord( + emit StoreSpliceDynamicData( data.table, data.key, uint48(4 * 1), @@ -887,7 +887,7 @@ contract StoreCoreTest is Test, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceDynamicRecord( + emit StoreSpliceDynamicData( data.table, data.key, uint48(data.newSecondDataBytes.length + 8 * 1), diff --git a/packages/store/test/StoreCoreDynamic.t.sol b/packages/store/test/StoreCoreDynamic.t.sol index 95a5df7a74..ac5dea2b45 100644 --- a/packages/store/test/StoreCoreDynamic.t.sol +++ b/packages/store/test/StoreCoreDynamic.t.sol @@ -93,7 +93,7 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreMock { // Expect a StoreSpliceRecord event to be emitted vm.expectEmit(true, true, true, true); - emit StoreSpliceDynamicRecord( + emit StoreSpliceDynamicData( _table, _key, uint48(secondDataBytes.length - byteLengthToPop), @@ -139,7 +139,7 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreMock { // Expect a StoreSpliceRecord event to be emitted after pop vm.expectEmit(true, true, true, true); - emit StoreSpliceDynamicRecord( + emit StoreSpliceDynamicData( _table, _key, uint48(secondDataBytes.length + thirdDataBytes.length - byteLengthToPop), diff --git a/packages/store/ts/storeEvents.ts b/packages/store/ts/storeEvents.ts index 7b4d0ccef4..d3d813b016 100644 --- a/packages/store/ts/storeEvents.ts +++ b/packages/store/ts/storeEvents.ts @@ -1,7 +1,7 @@ export const storeEvents = [ "event StoreSetRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData)", - "event StoreSpliceStaticRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", - "event StoreSpliceDynamicRecord(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths)", + "event StoreSpliceStaticData(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data)", + "event StoreSpliceDynamicData(bytes32 table, bytes32[] key, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths)", "event StoreEphemeralRecord(bytes32 table, bytes32[] key, bytes staticData, bytes32 encodedLengths, bytes dynamicData)", "event StoreDeleteRecord(bytes32 table, bytes32[] key)", ] as const; diff --git a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json index f899603972..9c2fa62b92 100644 --- a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json +++ b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json @@ -411,7 +411,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -448,7 +448,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json.d.ts b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json.d.ts index 613b01b362..c1226ddb23 100644 --- a/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json.d.ts +++ b/packages/world/abi/IBaseWorld.sol/IBaseWorld.abi.json.d.ts @@ -411,7 +411,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -448,7 +448,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/world/abi/IStore.sol/IStore.abi.json b/packages/world/abi/IStore.sol/IStore.abi.json index 988980e56c..d7113e99f3 100644 --- a/packages/world/abi/IStore.sol/IStore.abi.json +++ b/packages/world/abi/IStore.sol/IStore.abi.json @@ -270,7 +270,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -307,7 +307,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/world/abi/IStore.sol/IStore.abi.json.d.ts b/packages/world/abi/IStore.sol/IStore.abi.json.d.ts index 737075f9f2..8cf6aae7dc 100644 --- a/packages/world/abi/IStore.sol/IStore.abi.json.d.ts +++ b/packages/world/abi/IStore.sol/IStore.abi.json.d.ts @@ -270,7 +270,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -307,7 +307,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/world/abi/IStore.sol/IStoreData.abi.json b/packages/world/abi/IStore.sol/IStoreData.abi.json index 42e1a33d7a..fbc42e426b 100644 --- a/packages/world/abi/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/IStore.sol/IStoreData.abi.json @@ -95,7 +95,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -132,7 +132,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/world/abi/IStore.sol/IStoreData.abi.json.d.ts b/packages/world/abi/IStore.sol/IStoreData.abi.json.d.ts index aa9d9f1b20..9c80fe8e60 100644 --- a/packages/world/abi/IStore.sol/IStoreData.abi.json.d.ts +++ b/packages/world/abi/IStore.sol/IStoreData.abi.json.d.ts @@ -95,7 +95,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -132,7 +132,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/world/abi/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/IStore.sol/IStoreWrite.abi.json index 79ca52d499..dd1af51fbe 100644 --- a/packages/world/abi/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/IStore.sol/IStoreWrite.abi.json @@ -95,7 +95,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -132,7 +132,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/world/abi/IStore.sol/IStoreWrite.abi.json.d.ts b/packages/world/abi/IStore.sol/IStoreWrite.abi.json.d.ts index c520422689..2a2011ae3f 100644 --- a/packages/world/abi/IStore.sol/IStoreWrite.abi.json.d.ts +++ b/packages/world/abi/IStore.sol/IStoreWrite.abi.json.d.ts @@ -95,7 +95,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -132,7 +132,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/world/abi/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/StoreCore.sol/StoreCore.abi.json index f7d07e59ba..78c4d54a7f 100644 --- a/packages/world/abi/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/StoreCore.sol/StoreCore.abi.json @@ -132,7 +132,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -169,7 +169,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" } ] \ No newline at end of file diff --git a/packages/world/abi/StoreCore.sol/StoreCore.abi.json.d.ts b/packages/world/abi/StoreCore.sol/StoreCore.abi.json.d.ts index e976253f94..34161ca69b 100644 --- a/packages/world/abi/StoreCore.sol/StoreCore.abi.json.d.ts +++ b/packages/world/abi/StoreCore.sol/StoreCore.abi.json.d.ts @@ -132,7 +132,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -169,7 +169,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; } ]; diff --git a/packages/world/abi/World.sol/World.abi.json b/packages/world/abi/World.sol/World.abi.json index 61c4ff754c..bd4d333696 100644 --- a/packages/world/abi/World.sol/World.abi.json +++ b/packages/world/abi/World.sol/World.abi.json @@ -363,7 +363,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -400,7 +400,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/world/abi/World.sol/World.abi.json.d.ts b/packages/world/abi/World.sol/World.abi.json.d.ts index 32bb5c8bce..5640e846e6 100644 --- a/packages/world/abi/World.sol/World.abi.json.d.ts +++ b/packages/world/abi/World.sol/World.abi.json.d.ts @@ -363,7 +363,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -400,7 +400,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/world/abi/src/IStore.sol/IStore.abi.json b/packages/world/abi/src/IStore.sol/IStore.abi.json index 988980e56c..d7113e99f3 100644 --- a/packages/world/abi/src/IStore.sol/IStore.abi.json +++ b/packages/world/abi/src/IStore.sol/IStore.abi.json @@ -270,7 +270,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -307,7 +307,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/world/abi/src/IStore.sol/IStore.abi.json.d.ts b/packages/world/abi/src/IStore.sol/IStore.abi.json.d.ts index 737075f9f2..8cf6aae7dc 100644 --- a/packages/world/abi/src/IStore.sol/IStore.abi.json.d.ts +++ b/packages/world/abi/src/IStore.sol/IStore.abi.json.d.ts @@ -270,7 +270,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -307,7 +307,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreData.abi.json b/packages/world/abi/src/IStore.sol/IStoreData.abi.json index 42e1a33d7a..fbc42e426b 100644 --- a/packages/world/abi/src/IStore.sol/IStoreData.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreData.abi.json @@ -95,7 +95,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -132,7 +132,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreData.abi.json.d.ts b/packages/world/abi/src/IStore.sol/IStoreData.abi.json.d.ts index aa9d9f1b20..9c80fe8e60 100644 --- a/packages/world/abi/src/IStore.sol/IStoreData.abi.json.d.ts +++ b/packages/world/abi/src/IStore.sol/IStoreData.abi.json.d.ts @@ -95,7 +95,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -132,7 +132,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json index 79ca52d499..dd1af51fbe 100644 --- a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json +++ b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json @@ -95,7 +95,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -132,7 +132,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" }, { diff --git a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json.d.ts b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json.d.ts index c520422689..2a2011ae3f 100644 --- a/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json.d.ts +++ b/packages/world/abi/src/IStore.sol/IStoreWrite.abi.json.d.ts @@ -95,7 +95,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -132,7 +132,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; }, { diff --git a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json index f7d07e59ba..78c4d54a7f 100644 --- a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json +++ b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json @@ -132,7 +132,7 @@ "type": "bytes32" } ], - "name": "StoreSpliceDynamicRecord", + "name": "StoreSpliceDynamicData", "type": "event" }, { @@ -169,7 +169,7 @@ "type": "bytes" } ], - "name": "StoreSpliceStaticRecord", + "name": "StoreSpliceStaticData", "type": "event" } ] \ No newline at end of file diff --git a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json.d.ts b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json.d.ts index e976253f94..34161ca69b 100644 --- a/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json.d.ts +++ b/packages/world/abi/src/StoreCore.sol/StoreCore.abi.json.d.ts @@ -132,7 +132,7 @@ declare const abi: [ type: "bytes32"; } ]; - name: "StoreSpliceDynamicRecord"; + name: "StoreSpliceDynamicData"; type: "event"; }, { @@ -169,7 +169,7 @@ declare const abi: [ type: "bytes"; } ]; - name: "StoreSpliceStaticRecord"; + name: "StoreSpliceStaticData"; type: "event"; } ]; From 6b59547fc274f5818e150a2c3918a025f5465b19 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 20:50:48 +0100 Subject: [PATCH 54/69] that snuck in again --- packages/store-sync/src/blockLogsToStorage.ts | 192 ------------------ 1 file changed, 192 deletions(-) delete mode 100644 packages/store-sync/src/blockLogsToStorage.ts diff --git a/packages/store-sync/src/blockLogsToStorage.ts b/packages/store-sync/src/blockLogsToStorage.ts deleted file mode 100644 index 70f07276a6..0000000000 --- a/packages/store-sync/src/blockLogsToStorage.ts +++ /dev/null @@ -1,192 +0,0 @@ -import { decodeField, decodeKeyTuple, decodeRecord, abiTypesToSchema, hexToSchema } from "@latticexyz/protocol-parser"; -import { - StoreConfig, - ConfigToKeyPrimitives as Key, - ConfigToValuePrimitives as Value, - ConfigToValuePrimitives, -} from "@latticexyz/store"; -import { decodeAbiParameters, getAddress, parseAbiParameters } from "viem"; -import { debug } from "./debug"; -import { isDefined } from "@latticexyz/common/utils"; -import { BlockLogs, StorageAdapter, StorageOperation, Table } from "./common"; -import { hexToTableId, tableIdToHex } from "@latticexyz/common"; -import storeConfig from "@latticexyz/store/mud.config"; - -// TODO: adjust when we get namespace support (https://github.com/latticexyz/mud/issues/994) and when table has namespace key (https://github.com/latticexyz/mud/issues/1201) -const schemasTable = storeConfig.tables.Tables; -const schemasTableId = tableIdToHex(storeConfig.namespace, schemasTable.name); - -export type BlockStorageOperations = { - blockNumber: BlockLogs["blockNumber"]; - operations: StorageOperation[]; -}; - -export type BlockLogsToStorageResult = ( - block: BlockLogs -) => Promise>; - -export function blockLogsToStorage({ - registerTables, - getTables, - storeOperations, -}: StorageAdapter): BlockLogsToStorageResult { - return async (block) => { - // Find table schema registration events - const newTables = block.logs - .map((log) => { - try { - if (log.eventName !== "StoreSetRecord") return; - if (log.args.table !== schemasTableId) return; - - // TODO: refactor encode/decode to use Record schemas - // TODO: refactor to decode key with protocol-parser utils - - const [tableId, ...otherKeys] = log.args.key; - if (otherKeys.length) { - console.warn("registerSchema event is expected to have only one key in key tuple, but got multiple", log); - } - - const table = hexToTableId(tableId); - - const valueTuple = decodeRecord(abiTypesToSchema(Object.values(schemasTable.schema)), log.args.data); - const value = Object.fromEntries( - Object.keys(schemasTable.schema).map((name, i) => [name, valueTuple[i]]) - ) as ConfigToValuePrimitives; - - const keySchema = hexToSchema(value.keySchema); - const valueSchema = hexToSchema(value.valueSchema); - const keyNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedKeyNames)[0]; - const fieldNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedFieldNames)[0]; - - const valueAbiTypes = [...valueSchema.staticFields, ...valueSchema.dynamicFields]; - - return { - address: log.address, - tableId, - namespace: table.namespace, - name: table.name, - keySchema: Object.fromEntries(keySchema.staticFields.map((abiType, i) => [keyNames[i], abiType])), - valueSchema: Object.fromEntries(valueAbiTypes.map((abiType, i) => [fieldNames[i], abiType])), - }; - } catch (error: unknown) { - console.error("Failed to get table from log", log, error); - } - }) - .filter(isDefined); - - // Then register tables before we start storing data in them - if (newTables.length > 0) { - await registerTables({ - blockNumber: block.blockNumber, - tables: newTables, - }); - } - - const tablesToFetch = Array.from( - new Set( - block.logs.map((log) => - JSON.stringify({ - address: getAddress(log.address), - tableId: log.args.table, - ...hexToTableId(log.args.table), - }) - ) - ) - ).map((json) => JSON.parse(json)); - - const tables = Object.fromEntries( - ( - await getTables({ - blockNumber: block.blockNumber, - tables: tablesToFetch, - }) - ).map((table) => [`${getAddress(table.address)}:${table.tableId}`, table]) - ) as Record; - - const operations = block.logs - .map((log): StorageOperation | undefined => { - try { - const table = tables[`${getAddress(log.address)}:${log.args.table}`]; - if (!table) { - debug("no table found for event, skipping", hexToTableId(log.args.table), log); - return; - } - - const keyNames = Object.keys(table.keySchema); - const keyValues = decodeKeyTuple( - { staticFields: Object.values(table.keySchema), dynamicFields: [] }, - log.args.key - ); - const key = Object.fromEntries(keyValues.map((value, i) => [keyNames[i], value])) as Key< - TConfig, - keyof TConfig["tables"] - >; - - const valueAbiTypes = Object.values(table.valueSchema); - const valueSchema = abiTypesToSchema(valueAbiTypes); - const fieldNames = Object.keys(table.valueSchema); - - // TODO: decide if we should split these up into distinct operations so the storage adapter can decide whether to combine or not - if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { - const valueTuple = decodeRecord(valueSchema, log.args.data); - const value = Object.fromEntries(fieldNames.map((name, i) => [name, valueTuple[i]])) as Value< - TConfig, - keyof TConfig["tables"] - >; - return { - log, - address: getAddress(log.address), - namespace: table.namespace, - name: table.name, - type: "SetRecord", - key, - value, - }; - } - - if (log.eventName === "StoreSetField") { - const fieldName = fieldNames[log.args.schemaIndex] as string & - keyof Value; - const fieldValue = decodeField(valueAbiTypes[log.args.schemaIndex], log.args.data) as Value< - TConfig, - keyof TConfig["tables"] - >[typeof fieldName]; - return { - log, - address: getAddress(log.address), - namespace: table.namespace, - name: table.name, - type: "SetField", - key, - fieldName, - fieldValue, - }; - } - - if (log.eventName === "StoreDeleteRecord") { - return { - log, - address: getAddress(log.address), - namespace: table.namespace, - name: table.name, - type: "DeleteRecord", - key, - }; - } - - debug("unknown store event or log, skipping", log); - return; - } catch (error: unknown) { - console.error("Failed to translate log to storage operation", log, error); - } - }) - .filter(isDefined); - - await storeOperations({ blockNumber: block.blockNumber, operations }); - - return { - blockNumber: block.blockNumber, - operations, - }; - }; -} From 5bf1d3595cc634761d9a513627344c28ce25ccfe Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 20:56:05 +0100 Subject: [PATCH 55/69] fix ts error --- packages/store-sync/src/logToTable.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/store-sync/src/logToTable.ts b/packages/store-sync/src/logToTable.ts index 08c55ba94c..16e176853f 100644 --- a/packages/store-sync/src/logToTable.ts +++ b/packages/store-sync/src/logToTable.ts @@ -1,5 +1,5 @@ import { hexToSchema, decodeValue } from "@latticexyz/protocol-parser"; -import { concatHex, decodeAbiParameters } from "viem"; +import { concatHex, decodeAbiParameters, parseAbiParameters } from "viem"; import { StorageAdapterLog, Table, schemasTable } from "./common"; import { hexToTableId } from "@latticexyz/common"; @@ -21,8 +21,8 @@ export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord const keySchema = hexToSchema(value.keySchema); const valueSchema = hexToSchema(value.valueSchema); - const keyNames = decodeAbiParameters([{ type: "string[]" }], value.abiEncodedKeyNames)[0]; - const fieldNames = decodeAbiParameters([{ type: "string[]" }], value.abiEncodedFieldNames)[0]; + const keyNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedKeyNames)[0]; + const fieldNames = decodeAbiParameters(parseAbiParameters("string[]"), value.abiEncodedFieldNames)[0]; const valueAbiTypes = [...valueSchema.staticFields, ...valueSchema.dynamicFields]; From df76123c05f10c2e530a5a7c1c6148a36c11834f Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Thu, 14 Sep 2023 21:13:38 +0100 Subject: [PATCH 56/69] update test data --- .../src/postgres/postgresStorage.test.ts | 8 +- .../src/sqlite/sqliteStorage.test.ts | 8 +- test-data/world-logs.json | 346 +++++++++--------- 3 files changed, 181 insertions(+), 181 deletions(-) diff --git a/packages/store-sync/src/postgres/postgresStorage.test.ts b/packages/store-sync/src/postgres/postgresStorage.test.ts index 8aa0548082..8f72a2ee76 100644 --- a/packages/store-sync/src/postgres/postgresStorage.test.ts +++ b/packages/store-sync/src/postgres/postgresStorage.test.ts @@ -56,7 +56,7 @@ describe("postgresStorage", async () => { { "chainId": 31337, "lastError": null, - "lastUpdatedBlockNumber": 5n, + "lastUpdatedBlockNumber": 4n, "schemaVersion": 1, }, ] @@ -74,7 +74,7 @@ describe("postgresStorage", async () => { "key": "0x5FbDB2315678afecb367f032d93F642f64180aa3::NumberList", "keySchema": {}, "lastError": null, - "lastUpdatedBlockNumber": 5n, + "lastUpdatedBlockNumber": 4n, "name": "NumberList", "namespace": "", "schemaVersion": 1, @@ -92,7 +92,7 @@ describe("postgresStorage", async () => { { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "keySchema": {}, - "lastUpdatedBlockNumber": 5n, + "lastUpdatedBlockNumber": 4n, "name": "NumberList", "namespace": "", "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", @@ -111,7 +111,7 @@ describe("postgresStorage", async () => { "__encodedLengths": "0x0000000000000000000000000000000000000000000000000800000000000008", "__isDeleted": false, "__key": "0x", - "__lastUpdatedBlockNumber": 5n, + "__lastUpdatedBlockNumber": 4n, "__staticData": null, "value": [ 420, diff --git a/packages/store-sync/src/sqlite/sqliteStorage.test.ts b/packages/store-sync/src/sqlite/sqliteStorage.test.ts index 1c8845f37c..4e3fad9e77 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.test.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.test.ts @@ -64,7 +64,7 @@ describe("sqliteStorage", async () => { { "chainId": 31337, "lastError": null, - "lastUpdatedBlockNumber": 5n, + "lastUpdatedBlockNumber": 4n, "schemaVersion": 1, }, ] @@ -77,7 +77,7 @@ describe("sqliteStorage", async () => { "id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____NumberList", "keySchema": {}, "lastError": null, - "lastUpdatedBlockNumber": 5n, + "lastUpdatedBlockNumber": 4n, "name": "NumberList", "namespace": "", "schemaVersion": 1, @@ -96,7 +96,7 @@ describe("sqliteStorage", async () => { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____NumberList", "keySchema": {}, - "lastUpdatedBlockNumber": 5n, + "lastUpdatedBlockNumber": 4n, "name": "NumberList", "namespace": "", "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", @@ -115,7 +115,7 @@ describe("sqliteStorage", async () => { "__encodedLengths": "0x0000000000000000000000000000000000000000000000000800000000000008", "__isDeleted": false, "__key": "0x", - "__lastUpdatedBlockNumber": 5n, + "__lastUpdatedBlockNumber": 4n, "__staticData": null, "value": [ 420, diff --git a/test-data/world-logs.json b/test-data/world-logs.json index 3b9319cab6..902c96eff1 100644 --- a/test-data/world-logs.json +++ b/test-data/world-logs.json @@ -5,8 +5,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000022000000000a0000000000002c0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000016d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000600060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077461626c654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000b6669656c644c61796f757400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096b6579536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76616c7565536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012616269456e636f6465644b65794e616d657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014616269456e636f6465644669656c644e616d6573000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1", @@ -19,8 +19,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000016d756473746f7265000000000000000053746f7265486f6f6b7300000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x2", @@ -33,8 +33,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000001001004f0000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d657370616365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000056f776e6572000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x3", @@ -47,8 +47,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000042616c616e636573000000000000000000000000000000000000000000000000000000000000000000000000000000600020010020000000000000000000000000000000000000000000000000000000001001004f000000000000000000000000000000000000000000000000000000002001001f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d6573706163650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000762616c616e636500000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x4", @@ -61,8 +61,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000003002004f5f0000000000000000000000000000000000000000000000000000001401006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a6d6f64756c654e616d6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d617267756d656e74734861736800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6d6f64756c654164647265737300000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x5", @@ -75,8 +75,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000044656c65676174696f6e730000000000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000028020061610000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000964656c656761746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000964656c6567617465650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001364656c65676174696f6e436f6e74726f6c496400000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x6", @@ -89,8 +89,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000003402005f610000000000000000000000000000000000000000000000000000000101006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663616c6c6572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066163636573730000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x7", @@ -103,8 +103,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000600015020014010000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000001502006160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000673797374656d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c7075626c69634163636573730000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x8", @@ -117,8 +117,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000240200200400000000000000000000000000000000000000000000000000000004010043000000000000000000000000000000000000000000000000000000002402005f43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001066756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001673797374656d46756e6374696f6e53656c6563746f7200000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x9", @@ -131,8 +131,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d486f6f6b73000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xa", @@ -145,8 +145,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d52656769737472790000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000673797374656d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xb", @@ -159,8 +159,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c7265736f75726365547970650000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xc", @@ -170,11 +170,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xd", @@ -184,11 +184,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xe", @@ -198,11 +198,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0xf", @@ -212,11 +212,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e730000000000000000000000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x10", @@ -229,8 +229,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e73000000000000000000000000000000000000000000000000000000000000000000000000000000000015cafac3dd18ac6c6e92c921884f9e4176737c052c0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x11", @@ -240,11 +240,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000636f72652e7300000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x12", @@ -254,11 +254,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x13", @@ -271,8 +271,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000140554c3a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000040554c3a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x14", @@ -285,8 +285,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000018d53b20800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008d53b208000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x15", @@ -299,8 +299,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000125f6221000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000025f62210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x16", @@ -313,8 +313,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000012bfaa27400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000002bfaa274000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x17", @@ -327,8 +327,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000121293ca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000021293ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x18", @@ -341,8 +341,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013ea8492200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003ea84922000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x19", @@ -355,8 +355,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000018da798da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008da798da000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1a", @@ -369,8 +369,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010ba51f4900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000000ba51f49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1b", @@ -383,8 +383,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001530f4b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000530f4b60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1c", @@ -397,8 +397,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010560912900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000005609129000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1d", @@ -411,8 +411,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a886545e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a886545e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1e", @@ -425,8 +425,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001d5f8337f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000d5f8337f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x1f", @@ -439,8 +439,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a92813ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a92813ad000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x20", @@ -453,8 +453,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013350b6a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003350b6a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x21", @@ -467,8 +467,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013c03a51c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003c03a51c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x22", @@ -481,8 +481,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b7a3c75600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000b7a3c756000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x23", @@ -495,8 +495,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000011d2257ba00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000001d2257ba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x24", @@ -509,8 +509,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x00000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000002636f72652e6d0000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4700000000000000000000000000000000000000000000000000000000000000014e7f1725e7734ce288f8367e1bb143e90bb3f05120000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x7", "logIndex": "0x25", @@ -520,11 +520,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x6e2aab704607203c7b30d7116e7885affc7be5e9c54cdd50b58f6a2ff2850bbf", "transactionIndex": "0x8", "logIndex": "0x26", @@ -537,8 +537,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000040000000000000e000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c697374000000000000000000000000000000000000000000000000000000000000000000000000006000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x6e2aab704607203c7b30d7116e7885affc7be5e9c54cdd50b58f6a2ff2850bbf", "transactionIndex": "0x8", "logIndex": "0x27", @@ -548,11 +548,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x641e0226df365dd94c678ee05cd3e82901463bc96c369fc863400ae4795b4757", "transactionIndex": "0x9", "logIndex": "0x28", @@ -565,8 +565,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d626572000000000000000000000000000000000000000000000000000000000000000000000000000000000060000401000400000000000000000000000000000000000000000000000000000000040100030000000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x641e0226df365dd94c678ee05cd3e82901463bc96c369fc863400ae4795b4757", "transactionIndex": "0x9", "logIndex": "0x29", @@ -576,12 +576,12 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], - "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0xffe26db1e7c989f47f2943adc4ef1f7b756e0171e098403aa328f9e62f361bad", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", "transactionIndex": "0xa", "logIndex": "0x2a", "transactionLogIndex": "0x0", @@ -592,10 +592,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000006000080200040400000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000802002323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b6579000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0xffe26db1e7c989f47f2943adc4ef1f7b756e0171e098403aa328f9e62f361bad", + "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000150165878a594ca255338adfa4d48449f69242eb8f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", "transactionIndex": "0xa", "logIndex": "0x2b", "transactionLogIndex": "0x1", @@ -604,68 +604,68 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], - "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", - "transactionIndex": "0xb", + "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000004e756d6265724c69737453797374656d", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", + "transactionIndex": "0xa", "logIndex": "0x2c", - "transactionLogIndex": "0x0", + "transactionLogIndex": "0x2", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], - "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000155fc8d32690cc91d4c39d9d3abcbd16989f8757070100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", - "transactionIndex": "0xb", + "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0x7b18efc40e1ebdfeea162bbfa5f1a5c2096c546493b82ecf6e3dfdaca32a7ce9", + "transactionIndex": "0xa", "logIndex": "0x2d", - "transactionLogIndex": "0x1", + "transactionLogIndex": "0x3", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], - "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000437573746f6d4572726f727353797374", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0xc94a9d66a10ba4412b00d7555471fbcb6a2b05057d11e338ae7ca1e9ffe9063f", "transactionIndex": "0xb", "logIndex": "0x2e", - "transactionLogIndex": "0x2", + "transactionLogIndex": "0x0", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f87570700000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x6927ede34d3c0e69a0713e693189d02edfb7d6e8a3960adab74c33a5808a731c", + "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000006000080200040400000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000802002323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b6579000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0xc94a9d66a10ba4412b00d7555471fbcb6a2b05057d11e338ae7ca1e9ffe9063f", "transactionIndex": "0xb", "logIndex": "0x2f", - "transactionLogIndex": "0x3", + "transactionLogIndex": "0x1", "removed": false }, { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], - "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x7b42490b840b0a1f6d87a853852f9115f7925d7a0e6c86a5526c7ef9e03cb211", + "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0xfb5bf0734dca864b8b13107223cb02facd6803ef1a03f39b325cd96a5ab4fd02", "transactionIndex": "0xc", "logIndex": "0x30", "transactionLogIndex": "0x0", @@ -676,10 +676,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000150165878a594ca255338adfa4d48449f69242eb8f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x7b42490b840b0a1f6d87a853852f9115f7925d7a0e6c86a5526c7ef9e03cb211", + "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000155fc8d32690cc91d4c39d9d3abcbd16989f8757070100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0xfb5bf0734dca864b8b13107223cb02facd6803ef1a03f39b325cd96a5ab4fd02", "transactionIndex": "0xc", "logIndex": "0x31", "transactionLogIndex": "0x1", @@ -688,12 +688,12 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], - "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000004e756d6265724c69737453797374656d", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x7b42490b840b0a1f6d87a853852f9115f7925d7a0e6c86a5526c7ef9e03cb211", + "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000437573746f6d4572726f727353797374", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0xfb5bf0734dca864b8b13107223cb02facd6803ef1a03f39b325cd96a5ab4fd02", "transactionIndex": "0xc", "logIndex": "0x32", "transactionLogIndex": "0x2", @@ -702,12 +702,12 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], - "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x7b42490b840b0a1f6d87a853852f9115f7925d7a0e6c86a5526c7ef9e03cb211", + "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f87570700000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0xfb5bf0734dca864b8b13107223cb02facd6803ef1a03f39b325cd96a5ab4fd02", "transactionIndex": "0xc", "logIndex": "0x33", "transactionLogIndex": "0x3", @@ -716,11 +716,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x8bb7ab1f6067da0c10fcfb8051bacf60d415931c3d1f76db093d0088abba1fd7" + "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c7469000000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x2d3fb06c20276d48f9a04f14d92f70e31011b23f5fcecc6721fb5598360a4c75", "transactionIndex": "0xd", "logIndex": "0x34", @@ -733,8 +733,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000001c0000000000002c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c74690000000000000000000000000000000000000000000000000000000000000000000000000000000000006000210200200100000000000000000000000000000000000000000000000000000034040003601f2e000000000000000000000000000000000000000000000000002102003f60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000162000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000036e756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x2d3fb06c20276d48f9a04f14d92f70e31011b23f5fcecc6721fb5598360a4c75", "transactionIndex": "0xd", "logIndex": "0x35", @@ -746,10 +746,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656db8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x17709682bdb642bbf64843410b3392ce5df745f502f7b0f55d8b783212bfb809", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656da4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0x9d21ec923cfc66bc0b7fc283fd5c90fca31fbca1c881fa4afb1dd4884e6cb2d1", "transactionIndex": "0xe", "logIndex": "0x36", "transactionLogIndex": "0x0", @@ -760,10 +760,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656d306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x8a7c23ef1cf049955cdd85d056a394bf2394943dd22d65ca472629041d0fa4bc", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000015f644e3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000437573746f6d4572726f7273537973745f644e3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0x4497e69aa63fb7f7d6ecd27f0bef6dae0717c941e5c691ce8d44d2cfcae50cdc", "transactionIndex": "0xf", "logIndex": "0x37", "transactionLogIndex": "0x0", @@ -775,8 +775,8 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001f7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656df7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", "transactionHash": "0x77b03de8eef7f084dea0958f5f69c881d3ff3ae5df88d32110e9095536640b66", "transactionIndex": "0x10", "logIndex": "0x38", @@ -788,10 +788,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000015f644e3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000437573746f6d4572726f7273537973745f644e3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0x52057dfd4f9e6818f5565203a1e5a7abe7c1e242d91ca32c9353d5a88002b99e", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656d306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0x6be14198e38f5635f834446da7a3594826ce7a404ae5e238b24c5a9cac751a74", "transactionIndex": "0x11", "logIndex": "0x39", "transactionLogIndex": "0x0", @@ -802,10 +802,10 @@ "topics": [ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], - "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656da4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0x4d449138758d99481ebf03227d30e9651b308117c8a01d83ad9cf540666256ff", - "blockNumber": "0x5", - "transactionHash": "0xa72dbc5ed7514936419e040084824db63d3e7ff6977f67cf529fcc3b5218d4da", + "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656db8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x973043f5af4d5db630564f3ff6305444c6300bf7e46696684a8165c0a2acab2e", + "blockNumber": "0x2", + "transactionHash": "0xbe213a215bd71f17f867b8129a24630241f970e1cf5231f8a3bb2ba412b68a70", "transactionIndex": "0x12", "logIndex": "0x3a", "transactionLogIndex": "0x0", @@ -814,11 +814,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x9ded3a5a78199a737f59213ee5817f193988e67d8f197b17314f1804fe6715c8" + "0x5599f2052ade9808af7738adc73853c23894a2f1e944c827f7f6b8e948c4e885" ], "data": "0x000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000040000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000001a400000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5c1a5dd8edcae0be59abf8a4c25608a77b9ee96ea698373d0a8259fcbd49c2ae", - "blockNumber": "0x6", + "blockHash": "0x3dbc0ef9e85a1b5a5c8ddf17d77c9413bd3ea21be8ebca734145b0b05f0ae830", + "blockNumber": "0x4", "transactionHash": "0x913934c3603cedb30d6ec5131ca347ce5f3906f6146f7fdfe39ad6008e6e0a94", "transactionIndex": "0x0", "logIndex": "0x0", @@ -828,11 +828,11 @@ { "address": "0x5fbdb2315678afecb367f032d93f642f64180aa3", "topics": [ - "0x9ded3a5a78199a737f59213ee5817f193988e67d8f197b17314f1804fe6715c8" + "0x5599f2052ade9808af7738adc73853c23894a2f1e944c827f7f6b8e948c4e885" ], "data": "0x000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000800000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000004500000000000000000000000000000000000000000000000000000000", - "blockHash": "0x5c1a5dd8edcae0be59abf8a4c25608a77b9ee96ea698373d0a8259fcbd49c2ae", - "blockNumber": "0x6", + "blockHash": "0x3dbc0ef9e85a1b5a5c8ddf17d77c9413bd3ea21be8ebca734145b0b05f0ae830", + "blockNumber": "0x4", "transactionHash": "0xa5e0a4df59ae785eb7f2abc61ab104cbd97db921a61ad3a5a34b7a959d543ca6", "transactionIndex": "0x1", "logIndex": "0x1", From 4a07239ce85d50cf294a9473e362724c24a5301f Mon Sep 17 00:00:00 2001 From: alvrs Date: Fri, 15 Sep 2023 21:14:52 +0100 Subject: [PATCH 57/69] fixes --- packages/store-sync/src/createStoreSync.ts | 4 +- .../store-sync/src/isTableRegistrationLog.ts | 2 +- packages/store-sync/src/logToTable.ts | 4 +- .../src/postgres/postgresStorage.ts | 12 +- packages/store-sync/src/recs/recsStorage.ts | 4 +- .../store-sync/src/sqlite/sqliteStorage.ts | 10 +- test-data/world-logs.json | 120 +++++++++--------- 7 files changed, 78 insertions(+), 78 deletions(-) diff --git a/packages/store-sync/src/createStoreSync.ts b/packages/store-sync/src/createStoreSync.ts index 206090ef77..dcd8852df4 100644 --- a/packages/store-sync/src/createStoreSync.ts +++ b/packages/store-sync/src/createStoreSync.ts @@ -136,8 +136,8 @@ export async function createStoreSync eventName: "StoreSetRecord", address: table.address, args: { - table: table.tableId, - key: encodeKey(table.keySchema, record.key), + tableId: table.tableId, + keyTuple: encodeKey(table.keySchema, record.key), ...encodeValueArgs(table.valueSchema, record.value), }, }) diff --git a/packages/store-sync/src/isTableRegistrationLog.ts b/packages/store-sync/src/isTableRegistrationLog.ts index ef327e3158..ca937f8030 100644 --- a/packages/store-sync/src/isTableRegistrationLog.ts +++ b/packages/store-sync/src/isTableRegistrationLog.ts @@ -3,5 +3,5 @@ import { StorageAdapterLog, schemasTableId } from "./common"; export function isTableRegistrationLog( log: StorageAdapterLog ): log is StorageAdapterLog & { eventName: "StoreSetRecord" } { - return log.eventName === "StoreSetRecord" && log.args.table === schemasTableId; + return log.eventName === "StoreSetRecord" && log.args.tableId === schemasTableId; } diff --git a/packages/store-sync/src/logToTable.ts b/packages/store-sync/src/logToTable.ts index 16e176853f..72f7f01d47 100644 --- a/packages/store-sync/src/logToTable.ts +++ b/packages/store-sync/src/logToTable.ts @@ -6,7 +6,7 @@ import { hexToTableId } from "@latticexyz/common"; // TODO: add tableToLog export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord" }): Table { - const [tableId, ...otherKeys] = log.args.key; + const [tableId, ...otherKeys] = log.args.keyTuple; if (otherKeys.length) { console.warn("registerSchema event is expected to have only one key in key tuple, but got multiple", log); } @@ -14,7 +14,7 @@ export function logToTable(log: StorageAdapterLog & { eventName: "StoreSetRecord const table = hexToTableId(tableId); const value = decodeValue( - schemasTable.schema, + schemasTable.valueSchema, concatHex([log.args.staticData, log.args.encodedLengths, log.args.dynamicData]) ); diff --git a/packages/store-sync/src/postgres/postgresStorage.ts b/packages/store-sync/src/postgres/postgresStorage.ts index ec011b1d53..7e61e5f5d7 100644 --- a/packages/store-sync/src/postgres/postgresStorage.ts +++ b/packages/store-sync/src/postgres/postgresStorage.ts @@ -74,7 +74,7 @@ export async function postgresStorage const tables = await getTables( database, - logs.map((log) => getTableKey({ address: log.address, tableId: log.args.table })) + logs.map((log) => getTableKey({ address: log.address, tableId: log.args.tableId })) ); // This is currently parallelized per world (each world has its own database). @@ -83,7 +83,7 @@ export async function postgresStorage await database.transaction(async (tx) => { const tablesWithOperations = tables.filter((table) => - logs.some((log) => getTableKey({ address: log.address, tableId: log.args.table }) === getTableKey(table)) + logs.some((log) => getTableKey({ address: log.address, tableId: log.args.tableId }) === getTableKey(table)) ); if (tablesWithOperations.length) { await tx @@ -95,17 +95,17 @@ export async function postgresStorage for (const log of logs) { const table = tables.find( - (table) => getTableKey(table) === getTableKey({ address: log.address, tableId: log.args.table }) + (table) => getTableKey(table) === getTableKey({ address: log.address, tableId: log.args.tableId }) ); if (!table) { - const { namespace, name } = hexToTableId(log.args.table); + const { namespace, name } = hexToTableId(log.args.tableId); debug(`table ${namespace}:${name} not found, skipping log`, log); continue; } const sqlTable = buildTable(table); - const uniqueKey = concatHex(log.args.key as Hex[]); - const key = decodeKey(table.keySchema, log.args.key); + const uniqueKey = concatHex(log.args.keyTuple as Hex[]); + const key = decodeKey(table.keySchema, log.args.keyTuple); debug(log.eventName, log); diff --git a/packages/store-sync/src/recs/recsStorage.ts b/packages/store-sync/src/recs/recsStorage.ts index a2b6a9cbfb..457eb88793 100644 --- a/packages/store-sync/src/recs/recsStorage.ts +++ b/packages/store-sync/src/recs/recsStorage.ts @@ -58,7 +58,7 @@ export function recsStorage({ } for (const log of logs) { - const { namespace, name } = hexToTableId(log.args.table); + const { namespace, name } = hexToTableId(log.args.tableId); const table = getComponentValue( components.RegisteredTables, getTableEntity({ address: log.address, namespace, name }) @@ -78,7 +78,7 @@ export function recsStorage({ continue; } - const entity = hexKeyTupleToEntity(log.args.key); + const entity = hexKeyTupleToEntity(log.args.keyTuple); if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { const value = decodeValueArgs(table.valueSchema, log.args); diff --git a/packages/store-sync/src/sqlite/sqliteStorage.ts b/packages/store-sync/src/sqlite/sqliteStorage.ts index 94d7030c7d..08ca78f547 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.ts @@ -72,7 +72,7 @@ export async function sqliteStorage({ logs.map((log) => JSON.stringify({ address: getAddress(log.address), - ...hexToTableId(log.args.table), + ...hexToTableId(log.args.tableId), }) ) ) @@ -95,17 +95,17 @@ export async function sqliteStorage({ for (const log of logs) { const table = tables.find( - (table) => table.address === getAddress(log.address) && table.tableId === log.args.table + (table) => table.address === getAddress(log.address) && table.tableId === log.args.tableId ); if (!table) { - const tableId = hexToTableId(log.args.table); + const tableId = hexToTableId(log.args.tableId); debug(`table ${tableId.namespace}:${tableId.name} not found, skipping log`, log); continue; } const sqlTable = buildTable(table); - const uniqueKey = concatHex(log.args.key as Hex[]); - const key = decodeKey(table.keySchema, log.args.key); + const uniqueKey = concatHex(log.args.keyTuple as Hex[]); + const key = decodeKey(table.keySchema, log.args.keyTuple); if (log.eventName === "StoreSetRecord" || log.eventName === "StoreEphemeralRecord") { const value = decodeValueArgs(table.valueSchema, log.args); diff --git a/test-data/world-logs.json b/test-data/world-logs.json index 1447770586..15e99ba751 100644 --- a/test-data/world-logs.json +++ b/test-data/world-logs.json @@ -5,7 +5,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000022000000000a0000000000002c0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000016d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000600060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c4000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000077461626c654964000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000000b6669656c644c61796f757400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000096b6579536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b76616c7565536368656d610000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012616269456e636f6465644b65794e616d657300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014616269456e636f6465644669656c644e616d6573000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -19,7 +19,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000016d756473746f7265000000000000000053746f7265486f6f6b7300000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -33,7 +33,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000001001004f0000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d657370616365000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000056f776e6572000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -47,7 +47,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000042616c616e636573000000000000000000000000000000000000000000000000000000000000000000000000000000600020010020000000000000000000000000000000000000000000000000000000001001004f000000000000000000000000000000000000000000000000000000002001001f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000096e616d6573706163650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000762616c616e636500000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -61,7 +61,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000600014010014000000000000000000000000000000000000000000000000000000003002004f5f0000000000000000000000000000000000000000000000000000001401006100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000a6d6f64756c654e616d6500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000d617267756d656e74734861736800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000d6d6f64756c654164647265737300000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -75,7 +75,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000044656c65676174696f6e730000000000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000028020061610000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000964656c656761746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000964656c6567617465650000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001364656c65676174696f6e436f6e74726f6c496400000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -89,7 +89,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000100000000000001a000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000003402005f610000000000000000000000000000000000000000000000000000000101006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000663616c6c6572000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000066163636573730000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -103,7 +103,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000600015020014010000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000001502006160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f72000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000673797374656d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c7075626c69634163636573730000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -117,7 +117,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a0000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000046756e6374696f6e53656c6563746f72000000000000000000000000000000000000000000000000000000000000006000240200200400000000000000000000000000000000000000000000000000000004010043000000000000000000000000000000000000000000000000000000002402005f43000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001066756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001673797374656d46756e6374696f6e53656c6563746f7200000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -131,7 +131,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d486f6f6b73000000000000000000000000000000000000000000000000000000000000000000000000600000000100000000000000000000000000000000000000000000000000000000002001005f00000000000000000000000000000000000000000000000000000000000001b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -145,7 +145,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a000000000000140000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000053797374656d52656769737472790000000000000000000000000000000000000000000000000000000000000000006000200100200000000000000000000000000000000000000000000000000000000014010061000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000673797374656d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -159,7 +159,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000600001010001000000000000000000000000000000000000000000000000000000002001005f0000000000000000000000000000000000000000000000000000000001010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000107265736f7572636553656c6563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c7265736f75726365547970650000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -173,7 +173,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000004e616d6573706163654f776e6572000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014f39fd6e51aad88f6f4ce6ab8827279cfffb92266000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -187,7 +187,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb9226600000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -201,7 +201,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -215,7 +215,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e730000000000000000000000000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -229,7 +229,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000636f72652e73000000000000000000000000000000000000000000000000000000000000000000000000000000000015cafac3dd18ac6c6e92c921884f9e4176737c052c0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -243,7 +243,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000636f72652e7300000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -257,7 +257,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000cafac3dd18ac6c6e92c921884f9e4176737c052c00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -271,7 +271,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000140554c3a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000040554c3a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -285,7 +285,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000018d53b20800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008d53b208000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -299,7 +299,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000125f6221000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000025f62210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -313,7 +313,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000012bfaa27400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000002bfaa274000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -327,7 +327,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000121293ca000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000021293ca0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -341,7 +341,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013ea8492200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003ea84922000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -355,7 +355,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000018da798da00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000008da798da000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -369,7 +369,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010ba51f4900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000000ba51f49000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -383,7 +383,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001530f4b6000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000530f4b60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -397,7 +397,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000010560912900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e730000000000000000000005609129000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -411,7 +411,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a886545e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a886545e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -425,7 +425,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001d5f8337f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000d5f8337f000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -439,7 +439,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a92813ad00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000a92813ad000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -453,7 +453,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013350b6a900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003350b6a9000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -467,7 +467,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000013c03a51c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000003c03a51c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -481,7 +481,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b7a3c75600000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e7300000000000000000000b7a3c756000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -495,7 +495,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000011d2257ba00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000636f72652e73000000000000000000001d2257ba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -509,7 +509,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x00000000000000000000000000000000496e7374616c6c65644d6f64756c657300000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000002636f72652e6d0000000000000000000000000000000000000000000000000000c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4700000000000000000000000000000000000000000000000000000000000000014e7f1725e7734ce288f8367e1bb143e90bb3f0512000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x73080a3dddb1f96bc5a4d0b9b7a7f00555b7c11e68683d796252c9a71de6fdfc", "transactionIndex": "0x0", @@ -523,7 +523,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x607b94e53ff6d14c8af149f742239040a26773006b3916fca7403ab56bc1addf", "transactionIndex": "0x1", @@ -537,7 +537,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a000000000a00000000000014000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d626572000000000000000000000000000000000000000000000000000000000000000000000000000000000060000401000400000000000000000000000000000000000000000000000000000000040100030000000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b65790000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x607b94e53ff6d14c8af149f742239040a26773006b3916fca7403ab56bc1addf", "transactionIndex": "0x1", @@ -551,7 +551,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f720000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x5a88a5686556db275ec64403ada8ee92a761403bfd712f21b6746aabb0029f12", "transactionIndex": "0x2", @@ -565,7 +565,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000000a0000000000001a00000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000566563746f7200000000000000000000000000000000000000000000000000000000000000000000000000000000006000080200040400000000000000000000000000000000000000000000000000000004010003000000000000000000000000000000000000000000000000000000000802002323000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000036b6579000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000017900000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x5a88a5686556db275ec64403ada8ee92a761403bfd712f21b6746aabb0029f12", "transactionIndex": "0x2", @@ -579,7 +579,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0xaed15d9b279865d827e86039036fcc9d86c5467e36441834ba1f78991785229d", "transactionIndex": "0x3", @@ -593,7 +593,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000a00000000040000000000000e000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c697374000000000000000000000000000000000000000000000000000000000000000000000000006000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0xaed15d9b279865d827e86039036fcc9d86c5467e36441834ba1f78991785229d", "transactionIndex": "0x3", @@ -607,7 +607,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c7469000000000000000000000000000000000000000000000000000000000000000000000000000000000000010200000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x126a9b9fbea2e94295dfd3b380c2f43f4fc96fe1ee732e4d3df29b2433ac5dc1", "transactionIndex": "0x4", @@ -621,7 +621,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x6d756473746f726500000000000000005461626c65730000000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000010000000001c0000000000002c000000000000000000000000000000000000000000000000000000000000001600000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004d756c74690000000000000000000000000000000000000000000000000000000000000000000000000000000000006000210200200100000000000000000000000000000000000000000000000000000034040003601f2e000000000000000000000000000000000000000000000000002102003f60000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002c000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000016100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000162000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001630000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000016400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000036e756d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000576616c7565000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x126a9b9fbea2e94295dfd3b380c2f43f4fc96fe1ee732e4d3df29b2433ac5dc1", "transactionIndex": "0x4", @@ -635,7 +635,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0xfb5bf0734dca864b8b13107223cb02facd6803ef1a03f39b325cd96a5ab4fd02", "transactionIndex": "0x5", @@ -649,7 +649,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000437573746f6d4572726f72735379737400000000000000000000000000000000000000000000000000000000000000155fc8d32690cc91d4c39d9d3abcbd16989f8757070100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0xfb5bf0734dca864b8b13107223cb02facd6803ef1a03f39b325cd96a5ab4fd02", "transactionIndex": "0x5", @@ -663,7 +663,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f875707000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000437573746f6d4572726f727353797374", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0xfb5bf0734dca864b8b13107223cb02facd6803ef1a03f39b325cd96a5ab4fd02", "transactionIndex": "0x5", @@ -677,7 +677,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000005fc8d32690cc91d4c39d9d3abcbd16989f87570700000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0xfb5bf0734dca864b8b13107223cb02facd6803ef1a03f39b325cd96a5ab4fd02", "transactionIndex": "0x5", @@ -691,7 +691,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365547970650000000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000010300000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x3a45c7867bdaafbebbfe02dc2eb9c7dedd4b6fd27f2540febb2fb49c8caa6ea5", "transactionIndex": "0x6", @@ -705,7 +705,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000053797374656d7300000000000000000000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001200000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004e756d6265724c69737453797374656d00000000000000000000000000000000000000000000000000000000000000150165878a594ca255338adfa4d48449f69242eb8f0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x3a45c7867bdaafbebbfe02dc2eb9c7dedd4b6fd27f2540febb2fb49c8caa6ea5", "transactionIndex": "0x6", @@ -719,7 +719,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x0000000000000000000000000000000053797374656d5265676973747279000000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000004e756d6265724c69737453797374656d", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x3a45c7867bdaafbebbfe02dc2eb9c7dedd4b6fd27f2540febb2fb49c8caa6ea5", "transactionIndex": "0x6", @@ -733,7 +733,7 @@ "0xe7b614a59a30dff5ea0536e50c4019312e856b636126e1b2d19a7c2872798735" ], "data": "0x000000000000000000000000000000005265736f75726365416363657373000000000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f00000000000000000000000000000000000000000000000000000000000000010100000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x3a45c7867bdaafbebbfe02dc2eb9c7dedd4b6fd27f2540febb2fb49c8caa6ea5", "transactionIndex": "0x6", @@ -747,7 +747,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000015f644e3c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000437573746f6d4572726f7273537973745f644e3c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x99183c2ecbd4300f807d9903e3a0048eb27d80386fd655ff4b3bdf4aea5d5208", "transactionIndex": "0x7", @@ -761,7 +761,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001a4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656da4ece52c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0xa96d498c47174e6315617f6ef8e0fd6e93974a63c77152d173803f070f8023a6", "transactionIndex": "0x8", @@ -775,7 +775,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001f7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656df7f0e440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x77b03de8eef7f084dea0958f5f69c881d3ff3ae5df88d32110e9095536640b66", "transactionIndex": "0x9", @@ -789,7 +789,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656d306d61a5000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0x6be14198e38f5635f834446da7a3594826ce7a404ae5e238b24c5a9cac751a74", "transactionIndex": "0xa", @@ -803,7 +803,7 @@ "0xc851f86da4b2f7d69c86fc8dc136b05aa9805e49c225918a8856af392597a34f" ], "data": "0x0000000000000000000000000000000046756e6374696f6e53656c6563746f7200000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001400000000000000000000000000000000000000000000000000000000000000001b8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000000000000000000000004e756d6265724c69737453797374656db8a44c7c000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "blockHash": "0xee82f1d4bff2d7aa5d9ffe2dbc1688d433140e39ea125f63350e763e382d7010", + "blockHash": "0xc67f4cbf009a2ede672e0fff1e8bcc4b1e46db4145886d6942308d0d3b985941", "blockNumber": "0x5", "transactionHash": "0xbe213a215bd71f17f867b8129a24630241f970e1cf5231f8a3bb2ba412b68a70", "transactionIndex": "0xb", @@ -817,7 +817,7 @@ "0x5599f2052ade9808af7738adc73853c23894a2f1e944c827f7f6b8e948c4e885" ], "data": "0x000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000040000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000001a400000000000000000000000000000000000000000000000000000000", - "blockHash": "0x3c93968782dadadb870b43773ba34b7925716b46b892b832092033fbcdab6d17", + "blockHash": "0xbca51e861d5bfa7243f5c4b4dd5bf4e38874df40b4489bd87e14e0dca7fb434d", "blockNumber": "0x6", "transactionHash": "0x913934c3603cedb30d6ec5131ca347ce5f3906f6146f7fdfe39ad6008e6e0a94", "transactionIndex": "0x0", @@ -831,7 +831,7 @@ "0x5599f2052ade9808af7738adc73853c23894a2f1e944c827f7f6b8e948c4e885" ], "data": "0x000000000000000000000000000000004e756d6265724c69737400000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000800000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000004500000000000000000000000000000000000000000000000000000000", - "blockHash": "0x3c93968782dadadb870b43773ba34b7925716b46b892b832092033fbcdab6d17", + "blockHash": "0xbca51e861d5bfa7243f5c4b4dd5bf4e38874df40b4489bd87e14e0dca7fb434d", "blockNumber": "0x6", "transactionHash": "0xa5e0a4df59ae785eb7f2abc61ab104cbd97db921a61ad3a5a34b7a959d543ca6", "transactionIndex": "0x1", From 14e785ad100bac5cac65c015fab29049a279c2c4 Mon Sep 17 00:00:00 2001 From: alvrs Date: Fri, 15 Sep 2023 21:18:59 +0100 Subject: [PATCH 58/69] fixes --- packages/store-sync/src/logToTable.test.ts | 4 ++-- packages/store-sync/src/postgres/postgresStorage.test.ts | 8 ++++---- packages/store-sync/src/sqlite/sqliteStorage.test.ts | 8 ++++---- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/store-sync/src/logToTable.test.ts b/packages/store-sync/src/logToTable.test.ts index 0a03ae498a..53ec2a6a5e 100644 --- a/packages/store-sync/src/logToTable.test.ts +++ b/packages/store-sync/src/logToTable.test.ts @@ -8,8 +8,8 @@ describe("logToTable", () => { address: "0x3Aa5ebB10DC797CAC828524e59A333d0A371443c", eventName: "StoreSetRecord", args: { - table: "0x6d756473746f726500000000000000005461626c657300000000000000000000", - key: ["0x6d756473746f726500000000000000005461626c657300000000000000000000"], + tableId: "0x6d756473746f726500000000000000005461626c657300000000000000000000", + keyTuple: ["0x6d756473746f726500000000000000005461626c657300000000000000000000"], staticData: "0x0060030220202000000000000000000000000000000000000000000000000000002001005f000000000000000000000000000000000000000000000000000000006003025f5f5fc4c40000000000000000000000000000000000000000000000", encodedLengths: "0x000000000000000000000000000000000000022000000000a0000000000002c0", // "0x00000000000000000000000000000000000000a00000000220000000000002c0", diff --git a/packages/store-sync/src/postgres/postgresStorage.test.ts b/packages/store-sync/src/postgres/postgresStorage.test.ts index 8f72a2ee76..341546978a 100644 --- a/packages/store-sync/src/postgres/postgresStorage.test.ts +++ b/packages/store-sync/src/postgres/postgresStorage.test.ts @@ -56,7 +56,7 @@ describe("postgresStorage", async () => { { "chainId": 31337, "lastError": null, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 6n, "schemaVersion": 1, }, ] @@ -74,7 +74,7 @@ describe("postgresStorage", async () => { "key": "0x5FbDB2315678afecb367f032d93F642f64180aa3::NumberList", "keySchema": {}, "lastError": null, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 6n, "name": "NumberList", "namespace": "", "schemaVersion": 1, @@ -92,7 +92,7 @@ describe("postgresStorage", async () => { { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "keySchema": {}, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 6n, "name": "NumberList", "namespace": "", "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", @@ -111,7 +111,7 @@ describe("postgresStorage", async () => { "__encodedLengths": "0x0000000000000000000000000000000000000000000000000800000000000008", "__isDeleted": false, "__key": "0x", - "__lastUpdatedBlockNumber": 4n, + "__lastUpdatedBlockNumber": 6n, "__staticData": null, "value": [ 420, diff --git a/packages/store-sync/src/sqlite/sqliteStorage.test.ts b/packages/store-sync/src/sqlite/sqliteStorage.test.ts index 4e3fad9e77..2834fa73eb 100644 --- a/packages/store-sync/src/sqlite/sqliteStorage.test.ts +++ b/packages/store-sync/src/sqlite/sqliteStorage.test.ts @@ -64,7 +64,7 @@ describe("sqliteStorage", async () => { { "chainId": 31337, "lastError": null, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 6n, "schemaVersion": 1, }, ] @@ -77,7 +77,7 @@ describe("sqliteStorage", async () => { "id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____NumberList", "keySchema": {}, "lastError": null, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 6n, "name": "NumberList", "namespace": "", "schemaVersion": 1, @@ -96,7 +96,7 @@ describe("sqliteStorage", async () => { "address": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "id": "0x5FbDB2315678afecb367f032d93F642f64180aa3____NumberList", "keySchema": {}, - "lastUpdatedBlockNumber": 4n, + "lastUpdatedBlockNumber": 6n, "name": "NumberList", "namespace": "", "tableId": "0x000000000000000000000000000000004e756d6265724c697374000000000000", @@ -115,7 +115,7 @@ describe("sqliteStorage", async () => { "__encodedLengths": "0x0000000000000000000000000000000000000000000000000800000000000008", "__isDeleted": false, "__key": "0x", - "__lastUpdatedBlockNumber": 4n, + "__lastUpdatedBlockNumber": 6n, "__staticData": null, "value": [ 420, From 31d3a4467f7680a974f7639a5f9e1fc837f6c5a9 Mon Sep 17 00:00:00 2001 From: alvrs Date: Fri, 15 Sep 2023 21:28:01 +0100 Subject: [PATCH 59/69] mo fixes --- packages/dev-tools/src/events/LogsTable.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/dev-tools/src/events/LogsTable.tsx b/packages/dev-tools/src/events/LogsTable.tsx index 0ea450e91c..ac4779fb2b 100644 --- a/packages/dev-tools/src/events/LogsTable.tsx +++ b/packages/dev-tools/src/events/LogsTable.tsx @@ -22,13 +22,13 @@ export function LogsTable({ logs }: Props) { {logs.map((log) => { - const { namespace, name } = hexToTableId(log.args.table); + const { namespace, name } = hexToTableId(log.args.tableId); return ( @@ -38,7 +38,7 @@ export function LogsTable({ logs }: Props) { - + From 297b5aad21f842868a3e332000b96f158a3760ae Mon Sep 17 00:00:00 2001 From: alvrs Date: Fri, 15 Sep 2023 22:25:17 +0100 Subject: [PATCH 60/69] add gas tests for encoding --- packages/store/gas-report.json | 42 +++++++++++++++++++++++++++++----- packages/store/test/Gas.t.sol | 32 ++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/packages/store/gas-report.json b/packages/store/gas-report.json index c44cac99c6..b8a2b2ec64 100644 --- a/packages/store/gas-report.json +++ b/packages/store/gas-report.json @@ -119,41 +119,71 @@ "name": "validate field layout", "gasUsed": 3944 }, + { + "file": "test/Gas.t.sol", + "test": "testCompareAbiEncodeVsCustom", + "name": "abi encode (static)", + "gasUsed": 133 + }, + { + "file": "test/Gas.t.sol", + "test": "testCompareAbiEncodeVsCustom", + "name": "abi encode (dynamic)", + "gasUsed": 849 + }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "abi encode", - "gasUsed": 949 + "gasUsed": 943 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "abi decode", - "gasUsed": 1738 + "gasUsed": 1741 + }, + { + "file": "test/Gas.t.sol", + "test": "testCompareAbiEncodeVsCustom", + "name": "custom encode (static)", + "gasUsed": 191 + }, + { + "file": "test/Gas.t.sol", + "test": "testCompareAbiEncodeVsCustom", + "name": "custom encode (length)", + "gasUsed": 141 + }, + { + "file": "test/Gas.t.sol", + "test": "testCompareAbiEncodeVsCustom", + "name": "custom encode (dynamic)", + "gasUsed": 1152 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "custom encode", - "gasUsed": 2060 + "gasUsed": 2065 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "custom decode", - "gasUsed": 1975 + "gasUsed": 1981 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "pass abi encoded bytes to external contract", - "gasUsed": 6551 + "gasUsed": 6562 }, { "file": "test/Gas.t.sol", "test": "testCompareAbiEncodeVsCustom", "name": "pass custom encoded bytes to external contract", - "gasUsed": 1445 + "gasUsed": 1451 }, { "file": "test/Gas.t.sol", diff --git a/packages/store/test/Gas.t.sol b/packages/store/test/Gas.t.sol index 884b019ebd..ea0a6299e9 100644 --- a/packages/store/test/Gas.t.sol +++ b/packages/store/test/Gas.t.sol @@ -6,6 +6,7 @@ import { GasReporter } from "@latticexyz/gas-report/src/GasReporter.sol"; import { Bytes } from "../src/Bytes.sol"; import { SliceLib } from "../src/Slice.sol"; import { Storage } from "../src/Storage.sol"; +import { PackedCounter } from "../src/PackedCounter.sol"; import { Mixed, MixedData } from "../src/codegen/Tables.sol"; contract SomeContract { @@ -21,6 +22,14 @@ contract GasTest is Test, GasReporter { mixed.a32[1] = 2; mixed.a32[2] = 3; + startGasReport("abi encode (static)"); + bytes memory abiEncodedStatic = abi.encode(mixed.u32, mixed.u128); + endGasReport(); + + startGasReport("abi encode (dynamic)"); + bytes memory abiEncodedDynamic = abi.encode(mixed.a32, mixed.s); + endGasReport(); + startGasReport("abi encode"); bytes memory abiEncoded = abi.encode(mixed); endGasReport(); @@ -29,6 +38,19 @@ contract GasTest is Test, GasReporter { MixedData memory abiDecoded = abi.decode(abiEncoded, (MixedData)); endGasReport(); + startGasReport("custom encode (static)"); + bytes memory customEncodedStatic = Mixed.encodeStatic(mixed.u32, mixed.u128); + endGasReport(); + + startGasReport("custom encode (length)"); + PackedCounter packedCounter = Mixed.encodeLengths(mixed.a32, mixed.s); + endGasReport(); + PackedCounter.unwrap(packedCounter); + + startGasReport("custom encode (dynamic)"); + bytes memory customEncodedDynamic = Mixed.encodeDynamic(mixed.a32, mixed.s); + endGasReport(); + startGasReport("custom encode"); bytes memory customEncoded = Mixed.encode(mixed.u32, mixed.u128, mixed.a32, mixed.s); endGasReport(); @@ -38,6 +60,16 @@ contract GasTest is Test, GasReporter { endGasReport(); console.log("Length comparison: abi encode %s, custom %s", abiEncoded.length, customEncoded.length); + console.log( + "Length comparison (static): abi encode %s, custom %s", + abiEncodedStatic.length, + customEncodedStatic.length + ); + console.log( + "Length comparison (dynamic): abi encode %s, custom %s", + abiEncodedDynamic.length, + customEncodedDynamic.length + ); startGasReport("pass abi encoded bytes to external contract"); someContract.doSomethingWithBytes(abiEncoded); From 1efdfbd693724d4d13ed9b231421c50149a37564 Mon Sep 17 00:00:00 2001 From: alvrs Date: Fri, 15 Sep 2023 23:00:44 +0100 Subject: [PATCH 61/69] review changes --- packages/store/src/IStore.sol | 14 +- packages/store/src/StoreCore.sol | 207 +++++++++++---------- packages/store/src/StoreRead.sol | 12 +- packages/store/src/StoreReadWithStubs.sol | 102 ---------- packages/store/test/EchoSubscriber.sol | 8 +- packages/store/test/MirrorSubscriber.sol | 4 +- packages/store/test/StoreCoreDynamic.t.sol | 4 +- packages/store/test/StoreHook.t.sol | 2 +- packages/store/test/StoreMock.sol | 16 +- packages/world/src/World.sol | 16 +- 10 files changed, 145 insertions(+), 240 deletions(-) delete mode 100644 packages/store/src/StoreReadWithStubs.sol diff --git a/packages/store/src/IStore.sol b/packages/store/src/IStore.sol index d833f1f6a8..95bf0e301f 100644 --- a/packages/store/src/IStore.sol +++ b/packages/store/src/IStore.sol @@ -25,7 +25,7 @@ interface IStoreRead { function getField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout ) external view returns (bytes memory data); @@ -33,7 +33,7 @@ interface IStoreRead { function getFieldLength( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout ) external view returns (uint256); @@ -41,7 +41,7 @@ interface IStoreRead { function getFieldSlice( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout, uint256 start, uint256 end @@ -82,7 +82,7 @@ interface IStoreWrite { function setField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes calldata data, FieldLayout fieldLayout ) external; @@ -91,7 +91,7 @@ interface IStoreWrite { function pushToField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes calldata dataToPush, FieldLayout fieldLayout ) external; @@ -100,7 +100,7 @@ interface IStoreWrite { function popFromField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, uint256 byteLengthToPop, FieldLayout fieldLayout ) external; @@ -109,7 +109,7 @@ interface IStoreWrite { function updateInField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, uint256 startByteIndex, bytes calldata dataToSet, FieldLayout fieldLayout diff --git a/packages/store/src/StoreCore.sol b/packages/store/src/StoreCore.sol index 03b060dd2a..6187beb974 100644 --- a/packages/store/src/StoreCore.sol +++ b/packages/store/src/StoreCore.sol @@ -121,6 +121,7 @@ library StoreCore { ) internal { // Verify the field layout is valid fieldLayout.validate({ allowEmpty: false }); + // Verify the schema is valid keySchema.validate({ allowEmpty: true }); valueSchema.validate({ allowEmpty: false }); @@ -134,6 +135,7 @@ library StoreCore { if (fieldNames.length != fieldLayout.numFields()) { revert IStoreErrors.StoreCore_InvalidFieldNamesLength(fieldLayout.numFields(), fieldNames.length); } + // Verify the number of value schema types if (valueSchema.numFields() != fieldLayout.numFields()) { revert IStoreErrors.StoreCore_InvalidValueSchemaLength(fieldLayout.numFields(), valueSchema.numFields()); @@ -277,7 +279,7 @@ library StoreCore { function setField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes memory data, FieldLayout fieldLayout ) internal { @@ -286,21 +288,21 @@ library StoreCore { for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(uint8(StoreHookType.BEFORE_SET_FIELD))) { - IStoreHook(hook.getAddress()).onBeforeSetField(tableId, keyTuple, schemaIndex, data, fieldLayout); + IStoreHook(hook.getAddress()).onBeforeSetField(tableId, keyTuple, fieldIndex, data, fieldLayout); } } - if (schemaIndex < fieldLayout.numStaticFields()) { - StoreCoreInternal._setStaticField(tableId, keyTuple, fieldLayout, schemaIndex, data); + if (fieldIndex < fieldLayout.numStaticFields()) { + StoreCoreInternal._setStaticField(tableId, keyTuple, fieldLayout, fieldIndex, data); } else { - StoreCoreInternal._setDynamicField(tableId, keyTuple, fieldLayout, schemaIndex, data); + StoreCoreInternal._setDynamicField(tableId, keyTuple, fieldLayout, fieldIndex, data); } // Call onAfterSetField hooks (after modifying the state) for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(uint8(StoreHookType.AFTER_SET_FIELD))) { - IStoreHook(hook.getAddress()).onAfterSetField(tableId, keyTuple, schemaIndex, data, fieldLayout); + IStoreHook(hook.getAddress()).onAfterSetField(tableId, keyTuple, fieldIndex, data, fieldLayout); } } } @@ -346,17 +348,17 @@ library StoreCore { function pushToField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes memory dataToPush, FieldLayout fieldLayout ) internal { - if (schemaIndex < fieldLayout.numStaticFields()) { + if (fieldIndex < fieldLayout.numStaticFields()) { revert IStoreErrors.StoreCore_NotDynamicField(); } // TODO add push-specific hook to avoid the storage read? (https://github.com/latticexyz/mud/issues/444) bytes memory fullData = abi.encodePacked( - StoreCoreInternal._getDynamicField(tableId, keyTuple, schemaIndex, fieldLayout), + StoreCoreInternal._getDynamicField(tableId, keyTuple, fieldIndex, fieldLayout), dataToPush ); @@ -365,17 +367,17 @@ library StoreCore { for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(uint8(StoreHookType.BEFORE_SET_FIELD))) { - IStoreHook(hook.getAddress()).onBeforeSetField(tableId, keyTuple, schemaIndex, fullData, fieldLayout); + IStoreHook(hook.getAddress()).onBeforeSetField(tableId, keyTuple, fieldIndex, fullData, fieldLayout); } } - StoreCoreInternal._pushToDynamicField(tableId, keyTuple, fieldLayout, schemaIndex, dataToPush); + StoreCoreInternal._pushToDynamicField(tableId, keyTuple, fieldLayout, fieldIndex, dataToPush); // Call onAfterSetField hooks (after modifying the state) for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(uint8(StoreHookType.AFTER_SET_FIELD))) { - IStoreHook(hook.getAddress()).onAfterSetField(tableId, keyTuple, schemaIndex, fullData, fieldLayout); + IStoreHook(hook.getAddress()).onAfterSetField(tableId, keyTuple, fieldIndex, fullData, fieldLayout); } } } @@ -386,18 +388,18 @@ library StoreCore { function popFromField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, uint256 byteLengthToPop, FieldLayout fieldLayout ) internal { - if (schemaIndex < fieldLayout.numStaticFields()) { + if (fieldIndex < fieldLayout.numStaticFields()) { revert IStoreErrors.StoreCore_NotDynamicField(); } // TODO add pop-specific hook to avoid the storage read? (https://github.com/latticexyz/mud/issues/444) bytes memory fullData; { - bytes memory oldData = StoreCoreInternal._getDynamicField(tableId, keyTuple, schemaIndex, fieldLayout); + bytes memory oldData = StoreCoreInternal._getDynamicField(tableId, keyTuple, fieldIndex, fieldLayout); fullData = SliceLib.getSubslice(oldData, 0, oldData.length - byteLengthToPop).toBytes(); } @@ -406,17 +408,17 @@ library StoreCore { for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(uint8(StoreHookType.BEFORE_SET_FIELD))) { - IStoreHook(hook.getAddress()).onBeforeSetField(tableId, keyTuple, schemaIndex, fullData, fieldLayout); + IStoreHook(hook.getAddress()).onBeforeSetField(tableId, keyTuple, fieldIndex, fullData, fieldLayout); } } - StoreCoreInternal._popFromDynamicField(tableId, keyTuple, fieldLayout, schemaIndex, byteLengthToPop); + StoreCoreInternal._popFromDynamicField(tableId, keyTuple, fieldLayout, fieldIndex, byteLengthToPop); // Call onAfterSetField hooks (after modifying the state) for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(uint8(StoreHookType.AFTER_SET_FIELD))) { - IStoreHook(hook.getAddress()).onAfterSetField(tableId, keyTuple, schemaIndex, fullData, fieldLayout); + IStoreHook(hook.getAddress()).onAfterSetField(tableId, keyTuple, fieldIndex, fullData, fieldLayout); } } } @@ -427,14 +429,15 @@ library StoreCore { function updateInField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, uint256 startByteIndex, bytes memory dataToSet, FieldLayout fieldLayout ) internal { - if (schemaIndex < fieldLayout.numStaticFields()) { + if (fieldIndex < fieldLayout.numStaticFields()) { revert IStoreErrors.StoreCore_NotDynamicField(); } + // index must be checked because it could be arbitrarily large // (but dataToSet.length can be unchecked - it won't overflow into another slot due to gas costs and hashed slots) if (startByteIndex > type(uint40).max) { @@ -444,7 +447,7 @@ library StoreCore { // TODO add setItem-specific hook to avoid the storage read? (https://github.com/latticexyz/mud/issues/444) bytes memory fullData; { - bytes memory oldData = StoreCoreInternal._getDynamicField(tableId, keyTuple, schemaIndex, fieldLayout); + bytes memory oldData = StoreCoreInternal._getDynamicField(tableId, keyTuple, fieldIndex, fieldLayout); fullData = abi.encodePacked( SliceLib.getSubslice(oldData, 0, startByteIndex).toBytes(), dataToSet, @@ -457,17 +460,17 @@ library StoreCore { for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(uint8(StoreHookType.BEFORE_SET_FIELD))) { - IStoreHook(hook.getAddress()).onBeforeSetField(tableId, keyTuple, schemaIndex, fullData, fieldLayout); + IStoreHook(hook.getAddress()).onBeforeSetField(tableId, keyTuple, fieldIndex, fullData, fieldLayout); } } - StoreCoreInternal._setDynamicFieldItem(tableId, keyTuple, fieldLayout, schemaIndex, startByteIndex, dataToSet); + StoreCoreInternal._setDynamicFieldItem(tableId, keyTuple, fieldLayout, fieldIndex, startByteIndex, dataToSet); // Call onAfterSetField hooks (after modifying the state) for (uint256 i; i < hooks.length; i++) { Hook hook = Hook.wrap(hooks[i]); if (hook.isEnabled(uint8(StoreHookType.AFTER_SET_FIELD))) { - IStoreHook(hook.getAddress()).onAfterSetField(tableId, keyTuple, schemaIndex, fullData, fieldLayout); + IStoreHook(hook.getAddress()).onAfterSetField(tableId, keyTuple, fieldIndex, fullData, fieldLayout); } } } @@ -534,6 +537,7 @@ library StoreCore { // Early return if there are no dynamic fields if (dynamicDataLength.total() == 0) return data; + // Advance memoryPointer to the dynamic data section memoryPointer += staticLength; @@ -549,6 +553,7 @@ library StoreCore { uint256 dynamicDataLocation = StoreCoreInternal._getDynamicDataLocation(tableId, keyTuple, i); uint256 length = dynamicDataLength.atIndex(i); Storage.load({ storagePointer: dynamicDataLocation, length: length, offset: 0, memoryPointer: memoryPointer }); + // Advance memoryPointer by the length of this dynamic field memoryPointer += length; } @@ -563,13 +568,13 @@ library StoreCore { function getField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout ) internal view returns (bytes memory) { - if (schemaIndex < fieldLayout.numStaticFields()) { - return StoreCoreInternal._getStaticField(tableId, keyTuple, schemaIndex, fieldLayout); + if (fieldIndex < fieldLayout.numStaticFields()) { + return StoreCoreInternal._getStaticField(tableId, keyTuple, fieldIndex, fieldLayout); } else { - return StoreCoreInternal._getDynamicField(tableId, keyTuple, schemaIndex, fieldLayout); + return StoreCoreInternal._getDynamicField(tableId, keyTuple, fieldIndex, fieldLayout); } } @@ -579,15 +584,15 @@ library StoreCore { function getFieldLength( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout ) internal view returns (uint256) { uint8 numStaticFields = uint8(fieldLayout.numStaticFields()); - if (schemaIndex < numStaticFields) { - return fieldLayout.atIndex(schemaIndex); + if (fieldIndex < numStaticFields) { + return fieldLayout.atIndex(fieldIndex); } else { // Get the length and storage location of the dynamic field - uint8 dynamicFieldLayoutIndex = schemaIndex - numStaticFields; + uint8 dynamicFieldLayoutIndex = fieldIndex - numStaticFields; return StoreCoreInternal._loadEncodedDynamicDataLength(tableId, keyTuple).atIndex(dynamicFieldLayoutIndex); } } @@ -599,18 +604,18 @@ library StoreCore { function getFieldSlice( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout, uint256 start, uint256 end ) internal view returns (bytes memory) { uint8 numStaticFields = uint8(fieldLayout.numStaticFields()); - if (schemaIndex < fieldLayout.numStaticFields()) { + if (fieldIndex < fieldLayout.numStaticFields()) { revert IStoreErrors.StoreCore_NotDynamicField(); } // Get the length and storage location of the dynamic field - uint8 dynamicSchemaIndex = schemaIndex - numStaticFields; + uint8 dynamicSchemaIndex = fieldIndex - numStaticFields; uint256 location = StoreCoreInternal._getDynamicDataLocation(tableId, keyTuple, dynamicSchemaIndex); return Storage.load({ storagePointer: location, length: end - start, offset: start }); @@ -630,30 +635,32 @@ library StoreCoreInternal { bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout, - uint8 schemaIndex, + uint8 fieldIndex, bytes memory data ) internal { uint256 location = _getStaticDataLocation(tableId, keyTuple); - uint256 offset = _getStaticDataOffset(fieldLayout, schemaIndex); + uint256 offset = _getStaticDataOffset(fieldLayout, fieldIndex); Storage.store({ storagePointer: location, offset: offset, data: data }); - // Prepare data for the splice event - uint256 start = offset; - uint256 deleteCount = fieldLayout.atIndex(schemaIndex); - // Emit event to notify indexers - emit StoreCore.StoreSpliceStaticData(tableId, keyTuple, uint48(start), uint40(deleteCount), data); + emit StoreCore.StoreSpliceStaticData({ + tableId: tableId, + keyTuple: keyTuple, + start: uint48(offset), + deleteCount: uint40(fieldLayout.atIndex(fieldIndex)), + data: data + }); } function _setDynamicField( bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout, - uint8 schemaIndex, + uint8 fieldIndex, bytes memory data ) internal { - uint8 dynamicSchemaIndex = schemaIndex - uint8(fieldLayout.numStaticFields()); + uint8 dynamicSchemaIndex = fieldIndex - uint8(fieldLayout.numStaticFields()); // Load dynamic data length from storage uint256 dynamicSchemaLengthSlot = _getDynamicDataLengthLocation(tableId, keyTuple); @@ -670,7 +677,7 @@ library StoreCoreInternal { uint256 dynamicDataLocation = _getDynamicDataLocation(tableId, keyTuple, dynamicSchemaIndex); Storage.store({ storagePointer: dynamicDataLocation, offset: 0, data: data }); - // Prepare data for the splice event + // Compute start index for the splice event uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) @@ -678,26 +685,26 @@ library StoreCoreInternal { start += encodedLengths.atIndex(i); } } - uint256 deleteCount = oldFieldLength; + // Emit event to notify indexers - emit StoreCore.StoreSpliceDynamicData( - tableId, - keyTuple, - uint48(start), - uint40(deleteCount), - data, - encodedLengths.unwrap() - ); + emit StoreCore.StoreSpliceDynamicData({ + tableId: tableId, + keyTuple: keyTuple, + start: uint48(start), + deleteCount: uint40(oldFieldLength), + data: data, + encodedLengths: encodedLengths.unwrap() + }); } function _pushToDynamicField( bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout, - uint8 schemaIndex, + uint8 fieldIndex, bytes memory dataToPush ) internal { - uint8 dynamicSchemaIndex = schemaIndex - uint8(fieldLayout.numStaticFields()); + uint8 dynamicSchemaIndex = fieldIndex - uint8(fieldLayout.numStaticFields()); // Load dynamic data length from storage uint256 dynamicDataLengthSlot = _getDynamicDataLengthLocation(tableId, keyTuple); @@ -706,13 +713,14 @@ library StoreCoreInternal { // Update the encoded length uint256 oldFieldLength = encodedLengths.atIndex(dynamicSchemaIndex); encodedLengths = encodedLengths.setAtIndex(dynamicSchemaIndex, oldFieldLength + dataToPush.length); + // Set the new length Storage.store({ storagePointer: dynamicDataLengthSlot, data: encodedLengths.unwrap() }); // Append `dataToPush` to the end of the data in storage _setPartialDynamicData(tableId, keyTuple, dynamicSchemaIndex, oldFieldLength, dataToPush); - // Prepare data for the splice event + // Compute start index for the splice event uint256 start = oldFieldLength; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) @@ -720,26 +728,26 @@ library StoreCoreInternal { start += encodedLengths.atIndex(i); } } - uint256 deleteCount = 0; + // Emit event to notify indexers - emit StoreCore.StoreSpliceDynamicData( - tableId, - keyTuple, - uint48(start), - uint40(deleteCount), - dataToPush, - encodedLengths.unwrap() - ); + emit StoreCore.StoreSpliceDynamicData({ + tableId: tableId, + keyTuple: keyTuple, + start: uint48(start), + deleteCount: uint40(0), + data: dataToPush, + encodedLengths: encodedLengths.unwrap() + }); } function _popFromDynamicField( bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout, - uint8 schemaIndex, + uint8 fieldIndex, uint256 byteLengthToPop ) internal { - uint8 dynamicSchemaIndex = schemaIndex - uint8(fieldLayout.numStaticFields()); + uint8 dynamicSchemaIndex = fieldIndex - uint8(fieldLayout.numStaticFields()); // Load dynamic data length from storage uint256 dynamicDataLengthSlot = _getDynamicDataLengthLocation(tableId, keyTuple); @@ -754,7 +762,7 @@ library StoreCoreInternal { // Data can be left unchanged, push/set do not assume storage to be 0s - // Prepare data for the splice event + // Compute start index for the splice event uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) @@ -764,17 +772,16 @@ library StoreCoreInternal { } start -= byteLengthToPop; } - uint256 deleteCount = byteLengthToPop; // Emit event to notify indexers - emit StoreCore.StoreSpliceDynamicData( - tableId, - keyTuple, - uint48(start), - uint40(deleteCount), - new bytes(0), - encodedLengths.unwrap() - ); + emit StoreCore.StoreSpliceDynamicData({ + tableId: tableId, + keyTuple: keyTuple, + start: uint48(start), + deleteCount: uint40(byteLengthToPop), + data: new bytes(0), + encodedLengths: encodedLengths.unwrap() + }); } // startOffset is measured in bytes @@ -782,11 +789,11 @@ library StoreCoreInternal { bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout, - uint8 schemaIndex, + uint8 fieldIndex, uint256 startByteIndex, bytes memory dataToSet ) internal { - uint8 dynamicSchemaIndex = schemaIndex - uint8(fieldLayout.numStaticFields()); + uint8 dynamicSchemaIndex = fieldIndex - uint8(fieldLayout.numStaticFields()); // Load dynamic data length from storage uint256 dynamicSchemaLengthSlot = _getDynamicDataLengthLocation(tableId, keyTuple); @@ -795,7 +802,7 @@ library StoreCoreInternal { // Set `dataToSet` at the given index _setPartialDynamicData(tableId, keyTuple, dynamicSchemaIndex, startByteIndex, dataToSet); - // Prepare data for the splice event + // Compute start index for the splice event uint256 start; unchecked { // (safe because it's a few uint40 values, which can't overflow uint48) @@ -804,17 +811,16 @@ library StoreCoreInternal { start += encodedLengths.atIndex(i); } } - uint256 deleteCount = dataToSet.length; // Emit event to notify indexers - emit StoreCore.StoreSpliceDynamicData( - tableId, - keyTuple, - uint48(start), - uint40(deleteCount), - dataToSet, - encodedLengths.unwrap() - ); + emit StoreCore.StoreSpliceDynamicData({ + tableId: tableId, + keyTuple: keyTuple, + start: uint48(start), + deleteCount: uint40(dataToSet.length), + data: dataToSet, + encodedLengths: encodedLengths.unwrap() + }); } /************************************************************************ @@ -845,13 +851,13 @@ library StoreCoreInternal { function _getStaticField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout ) internal view returns (bytes memory) { // Get the length, storage location and offset of the static field - uint256 staticByteLength = fieldLayout.atIndex(schemaIndex); + uint256 staticByteLength = fieldLayout.atIndex(fieldIndex); uint256 location = _getStaticDataLocation(tableId, keyTuple); - uint256 offset = _getStaticDataOffset(fieldLayout, schemaIndex); + uint256 offset = _getStaticDataOffset(fieldLayout, fieldIndex); // Load the data from storage return Storage.load({ storagePointer: location, length: staticByteLength, offset: offset }); @@ -863,11 +869,11 @@ library StoreCoreInternal { function _getDynamicField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout ) internal view returns (bytes memory) { // Get the length and storage location of the dynamic field - uint8 dynamicSchemaIndex = schemaIndex - uint8(fieldLayout.numStaticFields()); + uint8 dynamicSchemaIndex = fieldIndex - uint8(fieldLayout.numStaticFields()); uint256 location = _getDynamicDataLocation(tableId, keyTuple, dynamicSchemaIndex); uint256 dataLength = _loadEncodedDynamicDataLength(tableId, keyTuple).atIndex(dynamicSchemaIndex); @@ -912,9 +918,9 @@ library StoreCoreInternal { /** * Get storage offset for the given value field layout and (static length) index */ - function _getStaticDataOffset(FieldLayout fieldLayout, uint8 schemaIndex) internal pure returns (uint256) { + function _getStaticDataOffset(FieldLayout fieldLayout, uint8 fieldIndex) internal pure returns (uint256) { uint256 offset = 0; - for (uint256 i; i < schemaIndex; i++) { + for (uint256 i; i < fieldIndex; i++) { offset += fieldLayout.atIndex(i); } return offset; @@ -930,9 +936,9 @@ library StoreCoreInternal { function _getDynamicDataLocation( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex + uint8 fieldIndex ) internal pure returns (uint256) { - return uint256(keccak256(abi.encode(SLOT, tableId, keyTuple, schemaIndex))); + return uint256(keccak256(abi.encode(SLOT, tableId, keyTuple, fieldIndex))); } /** @@ -960,7 +966,7 @@ library StoreCoreInternal { function _setDynamicDataLengthAtIndex( bytes32 tableId, bytes32[] memory keyTuple, - uint8 dynamicSchemaIndex, // schemaIndex - numStaticFields + uint8 dynamicSchemaIndex, // fieldIndex - numStaticFields uint256 newLengthAtIndex ) internal { // Load dynamic data length from storage @@ -987,6 +993,7 @@ library StoreCoreInternal { uint256 dynamicDataLocation = _getDynamicDataLocation(tableId, keyTuple, dynamicSchemaIndex); // start index is in bytes, whereas storage slots are in 32-byte words dynamicDataLocation += startByteIndex / 32; + // partial storage slot offset (there is no inherent offset, as each dynamic field starts at its own storage slot) uint256 offset = startByteIndex % 32; Storage.store({ storagePointer: dynamicDataLocation, offset: offset, data: partialData }); diff --git a/packages/store/src/StoreRead.sol b/packages/store/src/StoreRead.sol index ced24eb297..92125f5bd0 100644 --- a/packages/store/src/StoreRead.sol +++ b/packages/store/src/StoreRead.sol @@ -32,29 +32,29 @@ contract StoreRead is IStoreRead { function getField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout ) public view virtual returns (bytes memory data) { - data = StoreCore.getField(tableId, keyTuple, schemaIndex, fieldLayout); + data = StoreCore.getField(tableId, keyTuple, fieldIndex, fieldLayout); } function getFieldLength( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout ) public view virtual returns (uint256) { - return StoreCore.getFieldLength(tableId, keyTuple, schemaIndex, fieldLayout); + return StoreCore.getFieldLength(tableId, keyTuple, fieldIndex, fieldLayout); } function getFieldSlice( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, FieldLayout fieldLayout, uint256 start, uint256 end ) public view virtual returns (bytes memory) { - return StoreCore.getFieldSlice(tableId, keyTuple, schemaIndex, fieldLayout, start, end); + return StoreCore.getFieldSlice(tableId, keyTuple, fieldIndex, fieldLayout, start, end); } } diff --git a/packages/store/src/StoreReadWithStubs.sol b/packages/store/src/StoreReadWithStubs.sol deleted file mode 100644 index 0aed5a0ca0..0000000000 --- a/packages/store/src/StoreReadWithStubs.sol +++ /dev/null @@ -1,102 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.8.0; - -import { IStore, IStoreHook } from "./IStore.sol"; -import { PackedCounter } from "./PackedCounter.sol"; -import { StoreCore } from "./StoreCore.sol"; -import { FieldLayout } from "./FieldLayout.sol"; -import { Schema } from "./Schema.sol"; -import { StoreRead } from "./StoreRead.sol"; - -/** - * StoreReadWithStubs is not abstract and has signatures for all IStore methods, - * but only implements read methods (inheriting from StoreRead), - * so it can be used as IStore mock for testing or when write methods are not needed. - */ -contract StoreReadWithStubs is IStore, StoreRead { - error StoreReadWithStubs_NotImplemented(); - - /** - * Not implemented in StoreReadWithStubs - */ - function registerTable(bytes32, FieldLayout, Schema, Schema, string[] calldata, string[] calldata) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } - - /** - * Not implemented in StoreReadWithStubs - */ - function setRecord( - bytes32, - bytes32[] calldata, - bytes calldata, - PackedCounter, - bytes calldata, - FieldLayout - ) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } - - /** - * Not implemented in StoreReadWithStubs - */ - function setField(bytes32, bytes32[] calldata, uint8, bytes calldata, FieldLayout) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } - - /** - * Not implemented in StoreReadWithStubs - */ - function pushToField(bytes32, bytes32[] calldata, uint8, bytes calldata, FieldLayout) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } - - /** - * Not implemented in StoreReadWithStubs - */ - function popFromField(bytes32, bytes32[] calldata, uint8, uint256, FieldLayout) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } - - /** - * Not implemented in StoreReadWithStubs - */ - function updateInField(bytes32, bytes32[] calldata, uint8, uint256, bytes calldata, FieldLayout) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } - - /** - * Not implemented in StoreReadWithStubs - */ - function registerStoreHook(bytes32, IStoreHook, uint8) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } - - /** - * Not implemented in StoreReadWithStubs - */ - function unregisterStoreHook(bytes32, IStoreHook) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } - - /** - * Not implemented in StoreReadWithStubs - */ - function deleteRecord(bytes32, bytes32[] calldata, FieldLayout) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } - - /** - * Not implemented in StoreReadWithStubs - */ - function emitEphemeralRecord( - bytes32, - bytes32[] calldata, - bytes calldata, - PackedCounter, - bytes calldata, - FieldLayout - ) public virtual { - revert StoreReadWithStubs_NotImplemented(); - } -} diff --git a/packages/store/test/EchoSubscriber.sol b/packages/store/test/EchoSubscriber.sol index 375fa1c4da..e416d1753c 100644 --- a/packages/store/test/EchoSubscriber.sol +++ b/packages/store/test/EchoSubscriber.sol @@ -33,21 +33,21 @@ contract EchoSubscriber is StoreHook { function onBeforeSetField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes memory data, FieldLayout fieldLayout ) public { - emit HookCalled(abi.encode(tableId, keyTuple, schemaIndex, data, fieldLayout)); + emit HookCalled(abi.encode(tableId, keyTuple, fieldIndex, data, fieldLayout)); } function onAfterSetField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes memory data, FieldLayout fieldLayout ) public { - emit HookCalled(abi.encode(tableId, keyTuple, schemaIndex, data, fieldLayout)); + emit HookCalled(abi.encode(tableId, keyTuple, fieldIndex, data, fieldLayout)); } function onBeforeDeleteRecord(bytes32 tableId, bytes32[] memory keyTuple, FieldLayout fieldLayout) public { diff --git a/packages/store/test/MirrorSubscriber.sol b/packages/store/test/MirrorSubscriber.sol index 9116631b53..38681feb23 100644 --- a/packages/store/test/MirrorSubscriber.sol +++ b/packages/store/test/MirrorSubscriber.sol @@ -51,12 +51,12 @@ contract MirrorSubscriber is StoreHook { function onBeforeSetField( bytes32 tableId, bytes32[] memory keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes memory data, FieldLayout fieldLayout ) public { if (tableId != tableId) revert("invalid tableId"); - StoreSwitch.setField(indexerTableId, keyTuple, schemaIndex, data, fieldLayout); + StoreSwitch.setField(indexerTableId, keyTuple, fieldIndex, data, fieldLayout); } function onAfterSetField(bytes32, bytes32[] memory, uint8, bytes memory, FieldLayout) public { diff --git a/packages/store/test/StoreCoreDynamic.t.sol b/packages/store/test/StoreCoreDynamic.t.sol index ac29488407..d5979239c3 100644 --- a/packages/store/test/StoreCoreDynamic.t.sol +++ b/packages/store/test/StoreCoreDynamic.t.sol @@ -30,11 +30,11 @@ contract StoreCoreDynamicTest is Test, GasReporter, StoreMock { function popFromField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, uint256 byteLengthToPop, FieldLayout fieldLayout ) public override { - StoreCore.popFromField(tableId, keyTuple, schemaIndex, byteLengthToPop, fieldLayout); + StoreCore.popFromField(tableId, keyTuple, fieldIndex, byteLengthToPop, fieldLayout); } function setUp() public { diff --git a/packages/store/test/StoreHook.t.sol b/packages/store/test/StoreHook.t.sol index 68e1384689..311dcbc90a 100644 --- a/packages/store/test/StoreHook.t.sol +++ b/packages/store/test/StoreHook.t.sol @@ -25,7 +25,7 @@ contract StoreHookTest is Test, GasReporter { bytes private staticData = abi.encodePacked(bytes32(0)); PackedCounter private encodedLengths = PackedCounter.wrap(bytes32(0)); bytes private dynamicData = new bytes(0); - uint8 private schemaIndex = 1; + uint8 private fieldIndex = 1; FieldLayout private fieldLayout = FieldLayout.wrap(0); function testEncodeBitmap() public { diff --git a/packages/store/test/StoreMock.sol b/packages/store/test/StoreMock.sol index 9402c6e12a..9b515b4af5 100644 --- a/packages/store/test/StoreMock.sol +++ b/packages/store/test/StoreMock.sol @@ -33,45 +33,45 @@ contract StoreMock is IStore, StoreRead { function setField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes calldata data, FieldLayout fieldLayout ) public virtual { - StoreCore.setField(tableId, keyTuple, schemaIndex, data, fieldLayout); + StoreCore.setField(tableId, keyTuple, fieldIndex, data, fieldLayout); } // Push encoded items to the dynamic field at schema index function pushToField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes calldata dataToPush, FieldLayout fieldLayout ) public virtual { - StoreCore.pushToField(tableId, keyTuple, schemaIndex, dataToPush, fieldLayout); + StoreCore.pushToField(tableId, keyTuple, fieldIndex, dataToPush, fieldLayout); } // Pop byte length from the dynamic field at schema index function popFromField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, uint256 byteLengthToPop, FieldLayout fieldLayout ) public virtual { - StoreCore.popFromField(tableId, keyTuple, schemaIndex, byteLengthToPop, fieldLayout); + StoreCore.popFromField(tableId, keyTuple, fieldIndex, byteLengthToPop, fieldLayout); } // Change encoded items within the dynamic field at schema index function updateInField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, uint256 startByteIndex, bytes calldata dataToSet, FieldLayout fieldLayout ) public virtual { - StoreCore.updateInField(tableId, keyTuple, schemaIndex, startByteIndex, dataToSet, fieldLayout); + StoreCore.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); } // Set full record (including full dynamic data) diff --git a/packages/world/src/World.sol b/packages/world/src/World.sol index 9e25caf6b7..f813a96f46 100644 --- a/packages/world/src/World.sol +++ b/packages/world/src/World.sol @@ -119,7 +119,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { function setField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes calldata data, FieldLayout fieldLayout ) public virtual { @@ -127,7 +127,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { AccessControl.requireAccess(tableId, msg.sender); // Set the field - StoreCore.setField(tableId, keyTuple, schemaIndex, data, fieldLayout); + StoreCore.setField(tableId, keyTuple, fieldIndex, data, fieldLayout); } /** @@ -137,7 +137,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { function pushToField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, bytes calldata dataToPush, FieldLayout fieldLayout ) public virtual { @@ -145,7 +145,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { AccessControl.requireAccess(tableId, msg.sender); // Push to the field - StoreCore.pushToField(tableId, keyTuple, schemaIndex, dataToPush, fieldLayout); + StoreCore.pushToField(tableId, keyTuple, fieldIndex, dataToPush, fieldLayout); } /** @@ -155,7 +155,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { function popFromField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, uint256 byteLengthToPop, FieldLayout fieldLayout ) public virtual { @@ -163,7 +163,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { AccessControl.requireAccess(tableId, msg.sender); // Push to the field - StoreCore.popFromField(tableId, keyTuple, schemaIndex, byteLengthToPop, fieldLayout); + StoreCore.popFromField(tableId, keyTuple, fieldIndex, byteLengthToPop, fieldLayout); } /** @@ -173,7 +173,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { function updateInField( bytes32 tableId, bytes32[] calldata keyTuple, - uint8 schemaIndex, + uint8 fieldIndex, uint256 startByteIndex, bytes calldata dataToSet, FieldLayout fieldLayout @@ -182,7 +182,7 @@ contract World is StoreRead, IStoreData, IWorldKernel { AccessControl.requireAccess(tableId, msg.sender); // Update data in the field - StoreCore.updateInField(tableId, keyTuple, schemaIndex, startByteIndex, dataToSet, fieldLayout); + StoreCore.updateInField(tableId, keyTuple, fieldIndex, startByteIndex, dataToSet, fieldLayout); } /** From 83831d05000fb016265a181e253553640ba1437b Mon Sep 17 00:00:00 2001 From: alvrs Date: Fri, 15 Sep 2023 23:02:53 +0100 Subject: [PATCH 62/69] gas report --- packages/store/gas-report.json | 58 +++++++++++++++--------------- packages/world/gas-report.json | 64 +++++++++++++++++----------------- 2 files changed, 61 insertions(+), 61 deletions(-) diff --git a/packages/store/gas-report.json b/packages/store/gas-report.json index b8a2b2ec64..68427b3528 100644 --- a/packages/store/gas-report.json +++ b/packages/store/gas-report.json @@ -597,25 +597,25 @@ "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (cold, 1 slot, 1 uint32 item)", - "gasUsed": 23308 + "gasUsed": 23281 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromSecondField", "name": "pop from field (warm, 1 slot, 1 uint32 item)", - "gasUsed": 17344 + "gasUsed": 17317 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (cold, 2 slots, 10 uint32 items)", - "gasUsed": 25505 + "gasUsed": 25478 }, { "file": "test/StoreCoreDynamic.t.sol", "test": "testPopFromThirdField", "name": "pop from field (warm, 2 slots, 10 uint32 items)", - "gasUsed": 17541 + "gasUsed": 17514 }, { "file": "test/StoreCoreGas.t.sol", @@ -669,7 +669,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "register subscriber", - "gasUsed": 62557 + "gasUsed": 62552 }, { "file": "test/StoreCoreGas.t.sol", @@ -681,7 +681,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooks", "name": "set static field on table with subscriber", - "gasUsed": 25978 + "gasUsed": 25942 }, { "file": "test/StoreCoreGas.t.sol", @@ -693,7 +693,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "register subscriber", - "gasUsed": 62557 + "gasUsed": 62552 }, { "file": "test/StoreCoreGas.t.sol", @@ -705,7 +705,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testHooksDynamicData", "name": "set (dynamic) field on table with subscriber", - "gasUsed": 29589 + "gasUsed": 29579 }, { "file": "test/StoreCoreGas.t.sol", @@ -717,13 +717,13 @@ "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (1 slot, 1 uint32 item)", - "gasUsed": 15228 + "gasUsed": 15223 }, { "file": "test/StoreCoreGas.t.sol", "test": "testPushToField", "name": "push to field (2 slots, 10 uint32 items)", - "gasUsed": 38002 + "gasUsed": 37997 }, { "file": "test/StoreCoreGas.t.sol", @@ -795,7 +795,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set static field (1 slot)", - "gasUsed": 34132 + "gasUsed": 34114 }, { "file": "test/StoreCoreGas.t.sol", @@ -807,7 +807,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set static field (overlap 2 slot)", - "gasUsed": 32779 + "gasUsed": 32761 }, { "file": "test/StoreCoreGas.t.sol", @@ -819,7 +819,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set dynamic field (1 slot, first dynamic field)", - "gasUsed": 55899 + "gasUsed": 55894 }, { "file": "test/StoreCoreGas.t.sol", @@ -831,7 +831,7 @@ "file": "test/StoreCoreGas.t.sol", "test": "testSetAndGetField", "name": "set dynamic field (1 slot, second dynamic field)", - "gasUsed": 34139 + "gasUsed": 34134 }, { "file": "test/StoreCoreGas.t.sol", @@ -867,13 +867,13 @@ "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "update in field (1 slot, 1 uint32 item)", - "gasUsed": 16263 + "gasUsed": 16261 }, { "file": "test/StoreCoreGas.t.sol", "test": "testUpdateInField", "name": "push to field (2 slots, 6 uint64 items)", - "gasUsed": 17084 + "gasUsed": 17082 }, { "file": "test/StoreHook.t.sol", @@ -921,7 +921,7 @@ "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: set field", - "gasUsed": 60020 + "gasUsed": 60015 }, { "file": "test/tables/Callbacks.t.sol", @@ -933,19 +933,19 @@ "file": "test/tables/Callbacks.t.sol", "test": "testSetAndGet", "name": "Callbacks: push 1 element", - "gasUsed": 39350 + "gasUsed": 39345 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testOneSlot", "name": "StoreHooks: set field with one elements (cold)", - "gasUsed": 62002 + "gasUsed": 61997 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: set field (cold)", - "gasUsed": 62002 + "gasUsed": 61997 }, { "file": "test/tables/StoreHooks.t.sol", @@ -957,25 +957,25 @@ "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: push 1 element (cold)", - "gasUsed": 19415 + "gasUsed": 19410 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: pop 1 element (warm)", - "gasUsed": 15871 + "gasUsed": 15844 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: push 1 element (warm)", - "gasUsed": 17484 + "gasUsed": 17479 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: update 1 element (warm)", - "gasUsed": 38605 + "gasUsed": 38603 }, { "file": "test/tables/StoreHooks.t.sol", @@ -987,19 +987,19 @@ "file": "test/tables/StoreHooks.t.sol", "test": "testTable", "name": "StoreHooks: set field (warm)", - "gasUsed": 34255 + "gasUsed": 34250 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testThreeSlots", "name": "StoreHooks: set field with three elements (cold)", - "gasUsed": 84693 + "gasUsed": 84688 }, { "file": "test/tables/StoreHooks.t.sol", "test": "testTwoSlots", "name": "StoreHooks: set field with two elements (cold)", - "gasUsed": 84605 + "gasUsed": 84600 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", @@ -1029,13 +1029,13 @@ "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testPop", "name": "StoreHooks: pop 1 element (cold)", - "gasUsed": 26318 + "gasUsed": 26291 }, { "file": "test/tables/StoreHooksColdLoad.t.sol", "test": "testUpdate", "name": "StoreHooks: update 1 element (cold)", - "gasUsed": 28567 + "gasUsed": 28565 }, { "file": "test/tightcoder/DecodeSlice.t.sol", diff --git a/packages/world/gas-report.json b/packages/world/gas-report.json index a09125716e..64b6bfac8c 100644 --- a/packages/world/gas-report.json +++ b/packages/world/gas-report.json @@ -39,31 +39,31 @@ "file": "test/KeysInTableModule.t.sol", "test": "testInstallComposite", "name": "install keys in table module", - "gasUsed": 1521810 + "gasUsed": 1521715 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "install keys in table module", - "gasUsed": 1521810 + "gasUsed": 1521715 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallGas", "name": "set a record on a table with keysInTableModule installed", - "gasUsed": 187192 + "gasUsed": 187187 }, { "file": "test/KeysInTableModule.t.sol", "test": "testInstallSingleton", "name": "install keys in table module", - "gasUsed": 1521810 + "gasUsed": 1521715 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "install keys in table module", - "gasUsed": 1521810 + "gasUsed": 1521715 }, { "file": "test/KeysInTableModule.t.sol", @@ -75,13 +75,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookCompositeGas", "name": "delete a composite record on a table with keysInTableModule installed", - "gasUsed": 256797 + "gasUsed": 256692 }, { "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "install keys in table module", - "gasUsed": 1521810 + "gasUsed": 1521715 }, { "file": "test/KeysInTableModule.t.sol", @@ -93,13 +93,13 @@ "file": "test/KeysInTableModule.t.sol", "test": "testSetAndDeleteRecordHookGas", "name": "delete a record on a table with keysInTableModule installed", - "gasUsed": 134598 + "gasUsed": 134551 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testGetKeysWithValueGas", "name": "install keys with value module", - "gasUsed": 730916 + "gasUsed": 730803 }, { "file": "test/KeysWithValueModule.t.sol", @@ -117,25 +117,25 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "install keys with value module", - "gasUsed": 730916 + "gasUsed": 730803 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testInstall", "name": "set a record on a table with KeysWithValueModule installed", - "gasUsed": 159938 + "gasUsed": 159933 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "install keys with value module", - "gasUsed": 730916 + "gasUsed": 730803 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetAndDeleteRecordHook", "name": "change a record on a table with KeysWithValueModule installed", - "gasUsed": 129545 + "gasUsed": 129535 }, { "file": "test/KeysWithValueModule.t.sol", @@ -147,19 +147,19 @@ "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "install keys with value module", - "gasUsed": 730916 + "gasUsed": 730803 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "set a field on a table with KeysWithValueModule installed", - "gasUsed": 164701 + "gasUsed": 164678 }, { "file": "test/KeysWithValueModule.t.sol", "test": "testSetField", "name": "change a field on a table with KeysWithValueModule installed", - "gasUsed": 129460 + "gasUsed": 129437 }, { "file": "test/query.t.sol", @@ -231,7 +231,7 @@ "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromCallboundDelegation", "name": "register a callbound delegation", - "gasUsed": 133892 + "gasUsed": 133856 }, { "file": "test/StandardDelegationsModule.t.sol", @@ -243,7 +243,7 @@ "file": "test/StandardDelegationsModule.t.sol", "test": "testCallFromTimeboundDelegation", "name": "register a timebound delegation", - "gasUsed": 128241 + "gasUsed": 128205 }, { "file": "test/StandardDelegationsModule.t.sol", @@ -255,25 +255,25 @@ "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "install unique entity module", - "gasUsed": 791107 + "gasUsed": 790963 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstall", "name": "get a unique entity nonce (non-root module)", - "gasUsed": 67745 + "gasUsed": 67727 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "installRoot unique entity module", - "gasUsed": 774651 + "gasUsed": 774507 }, { "file": "test/UniqueEntityModule.t.sol", "test": "testInstallRoot", "name": "get a unique entity nonce (root module)", - "gasUsed": 67745 + "gasUsed": 67727 }, { "file": "test/World.t.sol", @@ -285,7 +285,7 @@ "file": "test/World.t.sol", "test": "testCallFromUnlimitedDelegation", "name": "register an unlimited delegation", - "gasUsed": 59330 + "gasUsed": 59312 }, { "file": "test/World.t.sol", @@ -303,7 +303,7 @@ "file": "test/World.t.sol", "test": "testPushToField", "name": "Push data to the table", - "gasUsed": 93924 + "gasUsed": 93919 }, { "file": "test/World.t.sol", @@ -327,7 +327,7 @@ "file": "test/World.t.sol", "test": "testRegisterNamespace", "name": "Register a new namespace", - "gasUsed": 147209 + "gasUsed": 147155 }, { "file": "test/World.t.sol", @@ -339,42 +339,42 @@ "file": "test/World.t.sol", "test": "testRegisterTable", "name": "Register a new table in the namespace", - "gasUsed": 686589 + "gasUsed": 686517 }, { "file": "test/World.t.sol", "test": "testSetField", "name": "Write data to a table field", - "gasUsed": 42192 + "gasUsed": 42174 }, { "file": "test/World.t.sol", "test": "testSetRecord", "name": "Write data to the table", - "gasUsed": 41637 + "gasUsed": 41619 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (cold)", - "gasUsed": 32960 + "gasUsed": 32933 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testPopFromField", "name": "pop 1 address (warm)", - "gasUsed": 20073 + "gasUsed": 20046 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (cold)", - "gasUsed": 36458 + "gasUsed": 36456 }, { "file": "test/WorldDynamicUpdate.t.sol", "test": "testUpdateInField", "name": "updateInField 1 item (warm)", - "gasUsed": 23663 + "gasUsed": 23661 } ] From 65eb79400d43ee01f04bda162115505a63b0e15f Mon Sep 17 00:00:00 2001 From: alvrs Date: Fri, 15 Sep 2023 23:04:54 +0100 Subject: [PATCH 63/69] remove unused variable --- packages/protocol-parser/src/common.ts | 4 +--- packages/store/src/PackedCounter.sol | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/packages/protocol-parser/src/common.ts b/packages/protocol-parser/src/common.ts index 17f7622687..377e6e9267 100644 --- a/packages/protocol-parser/src/common.ts +++ b/packages/protocol-parser/src/common.ts @@ -1,7 +1,5 @@ import { DynamicAbiType, SchemaAbiType, SchemaAbiTypeToPrimitiveType, StaticAbiType } from "@latticexyz/schema-type"; -import { Hex, numberToHex } from "viem"; - -export const UNCHANGED_PACKED_COUNTER = numberToHex(1, { size: 32 }); +import { Hex } from "viem"; /** @deprecated use `KeySchema` or `ValueSchema` instead */ export type Schema = { diff --git a/packages/store/src/PackedCounter.sol b/packages/store/src/PackedCounter.sol index 370c08bb87..32f0aa2a7a 100644 --- a/packages/store/src/PackedCounter.sol +++ b/packages/store/src/PackedCounter.sol @@ -14,9 +14,6 @@ uint256 constant VAL_BITS = 5 * 8; // Maximum value of a 5-byte section uint256 constant MAX_VAL = type(uint40).max; -// We use a specific, invalid packed counter (total length != sum of lengths) to represent "unchanged" for the purpose of events and off-chain indexing -bytes32 constant UNCHANGED_PACKED_COUNTER = bytes32(uint256(1)); - /** * Static functions for PackedCounter * The caller must ensure that the value arguments are <= MAX_VAL From 3e3060d898f932b4e80602be35d6700fd107bae7 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 15 Sep 2023 15:44:59 -0700 Subject: [PATCH 64/69] Create shy-sheep-wait.md --- .changeset/shy-sheep-wait.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 .changeset/shy-sheep-wait.md diff --git a/.changeset/shy-sheep-wait.md b/.changeset/shy-sheep-wait.md new file mode 100644 index 0000000000..3d0a9aa7f3 --- /dev/null +++ b/.changeset/shy-sheep-wait.md @@ -0,0 +1,8 @@ +--- +"@latticexyz/store-sync": major +"create-mud": minor +--- + +We've updated the Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexer and sync strategies that are more "stateless". + +As such, we've replaced `blockStorageOperations$` with `storedBlockLogs$`, a stream of simplified Store event logs after they've been synced to the configured storage adapter. These logs may not reflect exactly the events that are on chain when e.g. hydrating from an indexer, but they will still allow the client to "catch up" to the on-chain state of your tables. From eea61a209ab3564f6f1d75c0ac7a2bc139a3d860 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 15 Sep 2023 15:46:36 -0700 Subject: [PATCH 65/69] Update shy-sheep-wait.md --- .changeset/shy-sheep-wait.md | 1 + 1 file changed, 1 insertion(+) diff --git a/.changeset/shy-sheep-wait.md b/.changeset/shy-sheep-wait.md index 3d0a9aa7f3..e952457e83 100644 --- a/.changeset/shy-sheep-wait.md +++ b/.changeset/shy-sheep-wait.md @@ -1,4 +1,5 @@ --- +"@latticexyz/dev-tools": major "@latticexyz/store-sync": major "create-mud": minor --- From 6ad6fa758ef56c259f682dde02c3388ad2e6c26d Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 15 Sep 2023 15:48:20 -0700 Subject: [PATCH 66/69] Create fast-zebras-promise.md --- .changeset/fast-zebras-promise.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/fast-zebras-promise.md diff --git a/.changeset/fast-zebras-promise.md b/.changeset/fast-zebras-promise.md new file mode 100644 index 0000000000..f7d1cef47e --- /dev/null +++ b/.changeset/fast-zebras-promise.md @@ -0,0 +1,6 @@ +--- +"@latticexyz/common": minor +"@latticexyz/protocol-parser": major +--- + +`readHex` was moved from `@latticexyz/protocol-parser` to `@latticexyz/common` From 596fb15b9eccedcb2a970ca3cc28b83e0c30550d Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 15 Sep 2023 15:51:26 -0700 Subject: [PATCH 67/69] Create rotten-cats-lay.md --- .changeset/rotten-cats-lay.md | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 .changeset/rotten-cats-lay.md diff --git a/.changeset/rotten-cats-lay.md b/.changeset/rotten-cats-lay.md new file mode 100644 index 0000000000..021154c423 --- /dev/null +++ b/.changeset/rotten-cats-lay.md @@ -0,0 +1,9 @@ +--- +"@latticexyz/common": minor +--- + +`spliceHex` was added, which has a similar API as JavaScript's [`Array.prototype.splice`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice), but for `Hex` strings. + +```ts +spliceHex("0x123456", 1, 1, "0x0000"); // "0x12000056" +``` From 0086bf9e86c431ea0cd9f8d29d61a5db75085fd7 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 16 Sep 2023 05:14:16 -0700 Subject: [PATCH 68/69] Create cyan-hats-try.md --- .changeset/cyan-hats-try.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .changeset/cyan-hats-try.md diff --git a/.changeset/cyan-hats-try.md b/.changeset/cyan-hats-try.md new file mode 100644 index 0000000000..877a795bba --- /dev/null +++ b/.changeset/cyan-hats-try.md @@ -0,0 +1,30 @@ +--- +"@latticexyz/store": major +"@latticexyz/world": major +--- + +We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies. + +If you've written your own sync logic or are interacting with Store calls directly, this is a breaking change. We have a few more breaking protocol changes upcoming, so you may hold off on upgrading until those land. + +If you are using MUD's built-in tooling (table codegen, indexer, store sync, etc.), you don't have to make any changes except upgrading to the latest versions and deploying a fresh World. + +- The `data` field in each `StoreSetRecord` and `StoreEphemeralRecord` has been replaced with three new fields: `staticData`, `encodedLengths`, and `dynamicData`. This better reflects the on-chain state and makes it easier to perform modifications to the raw bytes. We recommend storing each of these fields individually in your off-chain storage of choice (indexer, client, etc.). + + ```diff + - event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes data); + + event StoreSetRecord(bytes32 tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData); + + - event StoreEphemeralRecord(bytes32 tableId, bytes32[] keyTuple, bytes data); + + event StoreEphemeralRecord(bytes32 tableId, bytes32[] keyTuple, bytes staticData, bytes32 encodedLengths, bytes dynamicData); + ``` + +- The `StoreSetField` event is now replaced by two new events: `StoreSpliceStaticData` and `StoreSpliceDynamicData`. Splicing allows us to perform efficient operations like push and pop, in addition to replacing a field value. We use two events because updating a dynamic-length field also requires updating the record's `encodedLengths` (aka PackedCounter). + + ```diff + - event StoreSetField(bytes32 tableId, bytes32[] keyTuple, uint8 fieldIndex, bytes data); + + event StoreSpliceStaticData(bytes32 tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data); + + event StoreSpliceDynamicData(bytes32 tableId, bytes32[] keyTuple, uint48 start, uint40 deleteCount, bytes data, bytes32 encodedLengths); + ``` + +Similarly, Store setter methods (e.g. `setRecord`) have been updated to reflect the `data` to `staticData`, `encodedLengths`, and `dynamicData` changes. We'll be following up shortly with Store getter method changes for more gas efficient storage reads. From 9a2382c3b966a5916cff8c023f29289aaa903b6d Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Sat, 16 Sep 2023 05:14:46 -0700 Subject: [PATCH 69/69] Update shy-sheep-wait.md --- .changeset/shy-sheep-wait.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/shy-sheep-wait.md b/.changeset/shy-sheep-wait.md index e952457e83..baabf2b946 100644 --- a/.changeset/shy-sheep-wait.md +++ b/.changeset/shy-sheep-wait.md @@ -4,6 +4,6 @@ "create-mud": minor --- -We've updated the Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexer and sync strategies that are more "stateless". +We've updated Store events to be "schemaless", meaning there is enough information in each event to only need to operate on the bytes of each record to make an update to that record without having to first decode the record by its schema. This enables new kinds of indexers and sync strategies. As such, we've replaced `blockStorageOperations$` with `storedBlockLogs$`, a stream of simplified Store event logs after they've been synced to the configured storage adapter. These logs may not reflect exactly the events that are on chain when e.g. hydrating from an indexer, but they will still allow the client to "catch up" to the on-chain state of your tables.
{namespace}:{name} {log.args.key.join(",")}{log.args.keyTuple.join(",")}