Skip to content
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

Merged
merged 12 commits into from
Apr 4, 2023
Merged

feat(world,store): add updateInField #525

merged 12 commits into from
Apr 4, 2023

Conversation

dk1a
Copy link
Contributor

@dk1a dk1a commented Mar 28, 2023

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

@dk1a dk1a requested review from alvrs and holic as code owners March 28, 2023 14:27
@holic
Copy link
Member

holic commented Mar 28, 2023

Is this blocking anything for v1 parity prior to hackathon? Otherwise, it might make sense to hold off on this until next week.

@dk1a
Copy link
Contributor Author

dk1a commented Mar 28, 2023

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

uint256 table,
bytes32[] calldata key,
uint8 schemaIndex,
uint256 startIndex,
Copy link
Member

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?

Copy link
Contributor Author

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?

Copy link
Member

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.

Copy link
Member

@holic holic Mar 28, 2023

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(
Copy link
Member

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?

Copy link
Contributor Author

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 ...?

Copy link
Contributor Author

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

alvrs
alvrs previously approved these changes Mar 30, 2023
Copy link
Member

@alvrs alvrs left a 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)

@dk1a dk1a force-pushed the dk1a/store-update-dynamic branch from 00a4151 to 38597b1 Compare March 31, 2023 16:24
@dk1a
Copy link
Contributor Author

dk1a commented Mar 31, 2023

World 20.726 -> 22.201 kB
I suppose we have enough space for maybe 1-2 more methods

@alvrs
Copy link
Member

alvrs commented Apr 2, 2023

22.201

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?)

@dk1a
Copy link
Contributor Author

dk1a commented Apr 3, 2023

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)

@dk1a
Copy link
Contributor Author

dk1a commented Apr 3, 2023

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

@alvrs alvrs changed the title feat: add updateInField feat(world,store): add updateInField Apr 4, 2023
@alvrs
Copy link
Member

alvrs commented Apr 4, 2023

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.

@dk1a
Copy link
Contributor Author

dk1a commented Apr 4, 2023

Generally I think the Store methods should be part of World's bytecode, because they're a hot path for system's internal logic

if intra-array methods are separated at the level of Store, then the intra-array system inherits StoreDynamic and should be entirely self-contained, and then gets registered on World

@dk1a dk1a merged commit 0ac76fd into main Apr 4, 2023
@dk1a dk1a deleted the dk1a/store-update-dynamic branch April 4, 2023 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants