-
Notifications
You must be signed in to change notification settings - Fork 11.4k
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
indexer(visitor): avoid fully deserializing dynamic field #19520
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
3 Skipped Deployments
|
bae595b
to
f3fc2fb
Compare
1df6815
to
cea9a46
Compare
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.
good move! btw I plan to further simplify codes around as now most meat of df_info are not longer needed.
@gegaowp -- I noticed that -- this needs to be simplified for |
f3fc2fb
to
0cde0cc
Compare
cea9a46
to
93d3887
Compare
0cde0cc
to
4a39049
Compare
93d3887
to
2a8bfcb
Compare
4a39049
to
eb49b74
Compare
2a8bfcb
to
2fa3ab4
Compare
eb49b74
to
b11004c
Compare
2fa3ab4
to
ed6d3da
Compare
## Description Use `FieldVisitor` to extract necessary information from a dynamic field object, rather than fully expanding it, which can fail if the overall size is too large. Unfortunately, because `DynamicFieldInfo` includes a structured representation of the field name, this operation can still fail if the name alone is too large to deserialize using `BoundedVisitor`, but we can at least avoid deserializing the value. ## Test plan Build and run the indexer reader against a mainnet DB, and check for `0x5`: ``` sui$ cargo run --bin sui-indexer -- --database-url "$DB" --pool-size 10 \ json-rpc-service --rpc-client-url "https://fullnode.mainnet.sui.io:443" ``` Make the request: ``` $ curl -LX POST "https:/fullnode.mainnet.sui.io:443" \ --header 'Content-Type: application/json' \ --data-raw '{ "jsonrpc": "2.0", "method": "suix_getDynamicFields", "id": 1, "params": ["0x5"] }' | jq -C . | less -r ``` Expects a response like: ``` { "jsonrpc": "2.0", "result": { "data": [ { "name": { "type": "u64", "value": "2" }, "bcsName": "LQM2cdzDY3", "type": "DynamicField", "objectType": "0x3::sui_system_state_inner::SuiSystemStateInnerV2", "objectId": "0x5b890eaf2abcfa2ab90b77b8e6f3d5d8609586c3e583baf3dccd5af17edf48d1", "version": 339253281, "digest": "89nPMzp31fiSy39a7fg6TBzALdm3xA4Byd4hWr2QLahg" } ], "nextCursor": "0x5b890eaf2abcfa2ab90b77b8e6f3d5d8609586c3e583baf3dccd5af17edf48d1", "hasNextPage": false }, "id": 1 } ```
ed6d3da
to
dc89159
Compare
## Description Make it so that deserializing dynamic field info does not inflate the whole field -- just the outer struct -- which in turn means that this operation cannot fail. ## Test plan ``` sui$ cargo simtest sui-adapter-transactional-tests$ cargo simtest ``` ## Stack - #19517 - #19518 - #19519 - #19520 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
## Description Make it so that deserializing dynamic field info does not inflate the whole field -- just the outer struct -- which in turn means that this operation cannot fail. ## Test plan ``` sui-core$ cargo simtest sui-adapter-transactional-tests$ cargo simtest ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
…th (#19565) ## Description Use `FieldVisitor` to extract the dynamic field kind from a serialized MoveObject without deserializing the whole thing. This makes it so that the indexing process cannot fail if presented with an overly large dynamic field. This PR also simplifies dynamic field indexing, taking advantage of the fact that we now only store the `df_kind`, and not any other part of `df_info`. ## Test plan ``` sui-indexer$ cargo nextest run sui-graphql-e2e-tests$ cargo nextest run ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Timothy Zakian <tim@mystenlabs.com>
## Description Replace the legacy implementations of `get_all_uids` with the one that has been used in `latest` for some time now. This version avoids inflating the whole struct just to read its UIDs. The main motivation in making the switch is to reduce the number of call-sites that use `simple_deserialize`, so that we can eventually get rid of it entirely, and replace it with a visitor based ipmplementation that includes the appropriate caveats around inflating a whole struct in memory. ## Test plan ``` sui$ cargo simtest ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 - #19565 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Timothy Zakian <tim@mystenlabs.com>
## Description Use a custom annotated visitor to implement detecting wrapped objects in test scenario. Unlike other instances where we have switched to a custom visitor, there isn't an OOM risk or risk of failure at this call site, because it is only used in Move tests, which are only run locally, but the motivation for this change is to avoid a reliance on `simple_deserialize` in the codebase, as it is too easy to copy this pattern and introduce a vulnerability elsewhere. Eventually `simple_deserialize` will go away and be replaced by something that is based on the new annotated visitor, but looks scary enough to use that people think twice before reaching for it. ## Test plan ``` sui$ cargo nextest run -p sui-framework-tests ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 - #19565 - #19576 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Timothy Zakian <tim@mystenlabs.com>
## Description Further simplification to dynamic field indexing, where we avoid deserializing dynamic fields altogether and extract the only piece of information we need (whether the DF is a dynamic field or a dynamic object field) from its type. DF deserialization was also the only reason to perform package resolution during indexing, so this change also means we can remove the package resolver, package buffer and logic to keep those up-to-date (pushing in new packages before indexing a checkpoint, and "evicting" packages after a checkpoint had been processed). ## Test plan ``` sui$ cargo nextest run -p sui-graphql-e2e-tests ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 - #19565 - #19576 - #19621 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
…th (#19565) ## Description Use `FieldVisitor` to extract the dynamic field kind from a serialized MoveObject without deserializing the whole thing. This makes it so that the indexing process cannot fail if presented with an overly large dynamic field. This PR also simplifies dynamic field indexing, taking advantage of the fact that we now only store the `df_kind`, and not any other part of `df_info`. ## Test plan ``` sui-indexer$ cargo nextest run sui-graphql-e2e-tests$ cargo nextest run ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Timothy Zakian <tim@mystenlabs.com>
## Description Replace the legacy implementations of `get_all_uids` with the one that has been used in `latest` for some time now. This version avoids inflating the whole struct just to read its UIDs. The main motivation in making the switch is to reduce the number of call-sites that use `simple_deserialize`, so that we can eventually get rid of it entirely, and replace it with a visitor based ipmplementation that includes the appropriate caveats around inflating a whole struct in memory. ## Test plan ``` sui$ cargo simtest ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 - #19565 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Timothy Zakian <tim@mystenlabs.com>
## Description Use a custom annotated visitor to implement detecting wrapped objects in test scenario. Unlike other instances where we have switched to a custom visitor, there isn't an OOM risk or risk of failure at this call site, because it is only used in Move tests, which are only run locally, but the motivation for this change is to avoid a reliance on `simple_deserialize` in the codebase, as it is too easy to copy this pattern and introduce a vulnerability elsewhere. Eventually `simple_deserialize` will go away and be replaced by something that is based on the new annotated visitor, but looks scary enough to use that people think twice before reaching for it. ## Test plan ``` sui$ cargo nextest run -p sui-framework-tests ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 - #19565 - #19576 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Timothy Zakian <tim@mystenlabs.com>
## Description Further simplification to dynamic field indexing, where we avoid deserializing dynamic fields altogether and extract the only piece of information we need (whether the DF is a dynamic field or a dynamic object field) from its type. DF deserialization was also the only reason to perform package resolution during indexing, so this change also means we can remove the package resolver, package buffer and logic to keep those up-to-date (pushing in new packages before indexing a checkpoint, and "evicting" packages after a checkpoint had been processed). ## Test plan ``` sui$ cargo nextest run -p sui-graphql-e2e-tests ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 - #19565 - #19576 - #19621 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
## Description Use `FieldVisitor` to extract necessary information from a dynamic field object, rather than fully expanding it, which can fail if the overall size is too large. Unfortunately, because `DynamicFieldInfo` includes a structured representation of the field name, this operation can still fail if the name alone is too large to deserialize using `BoundedVisitor`, but we can at least avoid deserializing the value. ## Test plan Build and run the indexer reader against a mainnet DB, and check for `0x5`: ``` sui$ cargo run --bin sui-indexer -- --database-url "$DB" --pool-size 10 \ json-rpc-service --rpc-client-url "https://fullnode.mainnet.sui.io:443" ``` Make the request: ``` $ curl -LX POST "https:/fullnode.mainnet.sui.io:443" \ --header 'Content-Type: application/json' \ --data-raw '{ "jsonrpc": "2.0", "method": "suix_getDynamicFields", "id": 1, "params": ["0x5"] }' | jq -C . | less -r ``` Expects a response like: ``` { "jsonrpc": "2.0", "result": { "data": [ { "name": { "type": "u64", "value": "2" }, "bcsName": "LQM2cdzDY3", "type": "DynamicField", "objectType": "0x3::sui_system_state_inner::SuiSystemStateInnerV2", "objectId": "0x5b890eaf2abcfa2ab90b77b8e6f3d5d8609586c3e583baf3dccd5af17edf48d1", "version": 339253281, "digest": "89nPMzp31fiSy39a7fg6TBzALdm3xA4Byd4hWr2QLahg" } ], "nextCursor": "0x5b890eaf2abcfa2ab90b77b8e6f3d5d8609586c3e583baf3dccd5af17edf48d1", "hasNextPage": false }, "id": 1 } ``` ## Stack - #19517 - #19518 - #19519 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
## Description Make it so that deserializing dynamic field info does not inflate the whole field -- just the outer struct -- which in turn means that this operation cannot fail. ## Test plan ``` sui$ cargo simtest sui-adapter-transactional-tests$ cargo simtest ``` ## Stack - #19517 - #19518 - #19519 - #19520 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
## Description Make it so that deserializing dynamic field info does not inflate the whole field -- just the outer struct -- which in turn means that this operation cannot fail. ## Test plan ``` sui-core$ cargo simtest sui-adapter-transactional-tests$ cargo simtest ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
…th (#19565) ## Description Use `FieldVisitor` to extract the dynamic field kind from a serialized MoveObject without deserializing the whole thing. This makes it so that the indexing process cannot fail if presented with an overly large dynamic field. This PR also simplifies dynamic field indexing, taking advantage of the fact that we now only store the `df_kind`, and not any other part of `df_info`. ## Test plan ``` sui-indexer$ cargo nextest run sui-graphql-e2e-tests$ cargo nextest run ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Timothy Zakian <tim@mystenlabs.com>
## Description Replace the legacy implementations of `get_all_uids` with the one that has been used in `latest` for some time now. This version avoids inflating the whole struct just to read its UIDs. The main motivation in making the switch is to reduce the number of call-sites that use `simple_deserialize`, so that we can eventually get rid of it entirely, and replace it with a visitor based ipmplementation that includes the appropriate caveats around inflating a whole struct in memory. ## Test plan ``` sui$ cargo simtest ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 - #19565 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Timothy Zakian <tim@mystenlabs.com>
## Description Use a custom annotated visitor to implement detecting wrapped objects in test scenario. Unlike other instances where we have switched to a custom visitor, there isn't an OOM risk or risk of failure at this call site, because it is only used in Move tests, which are only run locally, but the motivation for this change is to avoid a reliance on `simple_deserialize` in the codebase, as it is too easy to copy this pattern and introduce a vulnerability elsewhere. Eventually `simple_deserialize` will go away and be replaced by something that is based on the new annotated visitor, but looks scary enough to use that people think twice before reaching for it. ## Test plan ``` sui$ cargo nextest run -p sui-framework-tests ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 - #19565 - #19576 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API: --------- Co-authored-by: Timothy Zakian <tim@mystenlabs.com>
## Description Further simplification to dynamic field indexing, where we avoid deserializing dynamic fields altogether and extract the only piece of information we need (whether the DF is a dynamic field or a dynamic object field) from its type. DF deserialization was also the only reason to perform package resolution during indexing, so this change also means we can remove the package resolver, package buffer and logic to keep those up-to-date (pushing in new packages before indexing a checkpoint, and "evicting" packages after a checkpoint had been processed). ## Test plan ``` sui$ cargo nextest run -p sui-graphql-e2e-tests ``` ## Stack - #19517 - #19518 - #19519 - #19520 - #19521 - #19548 - #19554 - #19565 - #19576 - #19621 --- ## Release notes Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required. For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates. - [ ] Protocol: - [ ] Nodes (Validators and Full nodes): - [ ] Indexer: - [ ] JSON-RPC: - [ ] GraphQL: - [ ] CLI: - [ ] Rust SDK: - [ ] REST API:
Description
Use
FieldVisitor
to extract necessary information from a dynamic field object, rather than fully expanding it, which can fail if the overall size is too large.Unfortunately, because
DynamicFieldInfo
includes a structured representation of the field name, this operation can still fail if the name alone is too large to deserialize usingBoundedVisitor
, but we can at least avoid deserializing the value.Test plan
Build and run the indexer reader against a mainnet DB, and check for
0x5
:Make the request:
Expects a response like:
Stack
Release notes
Check each box that your changes affect. If none of the boxes relate to your changes, release notes aren't required.
For each box you select, include information after the relevant heading that describes the impact of your changes that a user might notice and any actions they must take to implement updates.