extend MovePackageService.GetPackage - #27762
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
b14c030 to
5faa45c
Compare
5faa45c to
6c6e0ed
Compare
MovePackageService.GetPackage
6c6e0ed to
3b28c69
Compare
3b28c69 to
d3fa039
Compare
nickvikeras
left a comment
There was a problem hiding this comment.
-
You will need to add the package pipeline here. These are the pipelines kv-rpc's GetServiceInfo uses to determine its checkpoint height which graphql uses for its retention window. As far as I know all clusters that exist have backfilled this pipeline so i'd just add it to the default const unconditionally (as opposed to what I did with
LIST_API_SERVICE_INFO_WATERMARK_PIPELINES). -
My AI Review agent found a couple issues that look like a real bugs to me. Pasting verbatim:
### [P1] Bounded lookups return the latest system-package version
crates/sui-rpc-api/src/grpc/v2/move_package_service/get_package.rs:57-62
(crates/sui-rpc-api/src/grpc/v2/move_package_service/get_package.rs#L57-L62) and
:91-96
(crates/sui-rpc-api/src/grpc/v2/move_package_service/get_package.rs#L91-L96)
Both bounded paths resolve an index entry to storage_id, then call
load_package_by_id. That function uses get_object(&package_id), which reads the
latest object at that ID.
This is correct for user packages because each upgrade has a distinct storage ID.
System packages are upgraded in place: versions of 0x1, 0x2, 0x3, etc. share the
same object ID while their object version increments. Consequently:
- GetPackage(0x2, version=1) resolves the version-1 index entry to 0x2, then
returns the latest framework version.
- GetPackage(0x2, at_checkpoint=<before an upgrade>) discards the resolved
version and likewise returns the latest version.
Both requests succeed with data newer than the requested bound. The new e2e test
only queries a fresh version-1 system package and therefore does not cover this.
Fetch by (storage_id, resolved_version), or at minimum reject a fetched package
whose version does not match the resolved version.
### [P2] Checkpoint lookup fails after 50 later upgrades
crates/sui-kv-rpc/src/v2/get_package.rs:62-66
(crates/sui-kv-rpc/src/v2/get_package.rs#L62-L66)
The new checkpoint path delegates to BigTableClient::get_package_latest. That
helper reverse-scans at most 50 versions and only then filters them by
cp_sequence_number <= cp_bound.
If a package has more than 50 upgrades after the requested checkpoint, none of
the scanned rows qualify. The helper returns None, and this handler reports
NotFound even though an older version exists at the requested checkpoint. The
two-version fixture cannot expose this.
The BigTable lookup must continue paging backward until it finds a qualifying
version or exhausts the lineage.
The 2nd issue just looks like AI slop I let into the code base by mistake when I was initially working on the indexing side of this. I had the AI add these readers so I could generate some unit tests and didn't catch this. I recently checked and I think the maximum package lineage length was a couple hundred versions, so it should be safe to just do full table scans of the package table without the cursor-resumption stuff we do for the bitmap indexes.
- There's a bunch of kv-rpc e2e tests in here. It wouldn't hurt to have the LLM generate some coverage for this new API.
| (Some(_), Some(_)) => { | ||
| return Err(FieldViolation::new("at_checkpoint") | ||
| .with_description("at most one of `version` and `at_checkpoint` may be set") | ||
| .with_reason(ErrorReason::FieldInvalid) | ||
| .into()); | ||
| } |
There was a problem hiding this comment.
Should we make this a oneof on the proto to make this impossible to express? Something like:
message GetPackageRequest {
optional string package_id = 1;
oneof bound {
uint64 version = 2;
uint64 at_checkpoint = 3;
}
}
| checkpoint is {lowest_available}", | ||
| ), | ||
| )); | ||
| } |
There was a problem hiding this comment.
Should we also be validating that the at_checkpoint is <= the current checkpoint height? Otherwise you could end up returning the wrong answer if the package version changes between the current checkpoint height and the requested checkpoint.
d3fa039 to
7681705
Compare
19103c3 to
b275b7a
Compare
b275b7a to
888b1a9
Compare
e75f9d0 to
e94d9a4
Compare
exact storage-id lookup if only package_id is provided if either version or checkpoint, first retrieve original_id, then fetch at version or <= at_checkpoint
47ff683 to
c29e54c
Compare
Description
Extend
MovePackageService.GetPackageso that graphql can move to grpc and deprecatekv_packageson postgresCalling with package_id still fetches the exact package.
Additionally, only one of the two can be provided:
NOT_FOUNDrather than clamped, so a successful answer is exact as of that checkpoint (Packagecarries no checkpoint, so a client could not detect a clamped answer). Contract docs: move_package: make GetPackage at_checkpoint fail closed above the indexed tip sui-apis#35, sui-rpc: vendor fail-closed at_checkpoint doc for GetPackageRequest sui-rust-sdk#315.Implement on sui-rpc-api and sui-kv-rpc
MystenLabs/sui-rust-sdk#305
Test plan
unit tests in relevant files and e2e tests
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.