Conversation
🦋 Changeset detectedLatest commit: 9a2382c The changes in this PR will be included in the next version bump. This PR includes changesets to release 28 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
StoreSpliceField eventStoreSpliceRecord event
| data: log.args.data, | ||
| start: log.args.start, | ||
| deleteCount: log.args.deleteCount, |
There was a problem hiding this comment.
Is there a way we could perform the steps to combine the new bytes with an existing record in here? Or would that prevent some optimizations we can do downstream (like encode+splice+decode in a single db tx)?
packages/store/gas-report.json
Outdated
| "test": "testSetAndGetField", | ||
| "name": "set static field (1 slot)", | ||
| "gasUsed": 33280 | ||
| "gasUsed": 33581 |
There was a problem hiding this comment.
+300 in gas; some increase is expected, is there anything we can do to further optimize this or is this as good as it gets?
There was a problem hiding this comment.
I didn't intentionally spend time optimizing gas here, probably can do better when I get to StoreCore
packages/store/src/StoreCore.sol
Outdated
| // 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); |
There was a problem hiding this comment.
Is it worth generalizing this in an internal util function, since very similar logic is used for _setDynamicField, _pushToDynamicField, _popFromDynamicField and _setDynamicFieldItem? I feel like might declutter the code a bit, make it easier to audit and easier to write tests for this logic in isolation
There was a problem hiding this comment.
I've been thinking about this for a while now. I think the only efficient way to declutter is generalize it in a renderer function, and render StoreCore. Using solidity functions means more gas because the optimizer won't inline any of it and we'll need to return many vars
There was a problem hiding this comment.
Or we could not worry about gas I guess, it's probably less than 1000 (haven't tested specifics). Though a bunch of return vars may still be ugly compared to a renderer with conditionals in the relevant places
There was a problem hiding this comment.
Unfortunately I think a renderer would make auditing harder (because auditors have less experience with codegen). I'd be curious about the gas implications of moving it to a helper function, if it's a significant increase i'm also fine with keeping it inline
There was a problem hiding this comment.
@alvrs do you want declutter in this PR? it feels like it'd be better in a separate one for easier reverts and gas comparisons
There was a problem hiding this comment.
can try to refactor in a separate PR
packages/store/src/PackedCounter.sol
Outdated
| // 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)); | ||
|
|
There was a problem hiding this comment.
do we still need this? doesn't seem like it's used
There was a problem hiding this comment.
we're not using it yet so feel free to trash (which I see you've already done), can add later
|
added follow up issue for splice tests: #1515 |
fixes #1222
fixes #1296
TODO:
bytes16fromSchema.staticDataLength()? since that's what it's actually stored as?figure out if its gas efficient enough to remove total length from encoded lengthsmoved to explore removing total length from PackedCounter #1420