-
Notifications
You must be signed in to change notification settings - Fork 202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(world,store): add updateInField #525
Conversation
Is this blocking anything for v1 parity prior to hackathon? Otherwise, it might make sense to hold off on this until next week. |
Not blocking or critical, but without it dealing with dynamic tables gets extremely annoying as you have to get the full data, change an item, then set the full data |
packages/store/src/IStore.sol
Outdated
uint256 table, | ||
bytes32[] calldata key, | ||
uint8 schemaIndex, | ||
uint256 startIndex, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this the field index or byte index?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
byte index. I've considered startByteIndex
but that seems long, and is abstracted by tablegen anyways. wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I generally always prefer longer, clearer variables where it's otherwise hard to glean from context. I think it would make sense here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
another option is just byteIndex
(to match schemaIndex
) or byteOffset
(Uint8Array
constructor and our decoding code calls it byteOffset
, fwiw)
@@ -28,6 +28,15 @@ interface IStore { | |||
// Push encoded items to the dynamic field at schema index | |||
function pushToField(uint256 table, bytes32[] calldata key, uint8 schemaIndex, bytes calldata dataToPush) external; | |||
|
|||
// Change encoded items within the dynamic field at schema index | |||
function updateInField( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a better name for this? spliceField
or setFieldSlice
or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to make splice actually, but the proper startIndex->delete->push can't work well in solidity, and update-only splice looks kinda misleading.
setFieldSlice
isn't bad but I'd also want to consider its tablegen pair as well. So we have get
, set
, push
, and:
update
/ slice
/ setSlice
/ setItem
...
updateCol1
/ sliceCol1
/ setSliceCol1
/ setItemCol1
...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added this to v2 tracker so we can come back to it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! I'd be curious to see how this additional method in StoreCore and World affects the World contract size. Could you add a quick benchmark for that here for reference? (Since we're already really tight on the limit in the World contract due to all the inlined libraries)
00a4151
to
38597b1
Compare
World |
Oh damn that's getting really close - i've experienced the bytecode being slightly larger in consuming projects (eg v2sandbox) for some reason, 22 might already push it over the limit there. We should make finding a way to "tree shake" the included libraries a priority (eg by using free functions instead of libs?) |
After some brief testing I think solidity already does this, using free functions doesn't seem to change anything (I could've missed something, tried it only on a couple libs) |
I could separate the array stuff (push, update, pop) from StoreCore (StoreDynamic?) and World (install another system in CoreModule?), then it should go back to ~20 |
Happy to merge this as is and find a way to reduce World's byte code in a follow up (high prio though). Generally I think the Store methods should be part of World's bytecode, because they're a hot path for system's internal logic (we probably wouldn't want to add overhead for forwarding to another system to handle store methods). Would be interesting to measure how big StoreCore itself is right now. |
if intra-array methods are separated at the level of Store, then the intra-array system inherits |
Like pushToField, but only updates existing values. Same as push this does not yet introduce any new events and won't break networking.
I've considered merging them into some kind of splice, but that'd be very clunky and inefficient in solidity; a single splice event might make sense though.
A questionable decision here is to silently ignore non-existent indexes (technically they revert because of
fullData
, but that's only for event compatibility), that's because with an update/splice event I wouldn't need to ever read the length, so not checking against it saves a storage read