-
Notifications
You must be signed in to change notification settings - Fork 84
feat(SIP-57): allow for better observability into package upgrades #57
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
Open
admin-aftermath
wants to merge
1
commit into
sui-foundation:main
Choose a base branch
from
AftermathFinance:sip/upgraded-package-event
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| | SIP-Number | 57 | | ||
| | ---: | :--- | | ||
| | Title | `UpgradedPackageEvent` | | ||
| | Description | Introduces adding `UpgradedPackageEvent` to the Sui Framework | | ||
| | Author | Kevin \<github@aftermath.finance, @admin-aftermath\>, Aftermath Finance \<[aftermath.finance](https://aftermath.finance/)\> | | ||
| | Editor | TBD | | ||
| | Type | Standard | | ||
| | Category | Framework | | ||
| | Created | 2024-05-10 | | ||
| | Comments-URI | TBD | | ||
| | Status | Draft | | ||
| | Requires | N/A | | ||
|
|
||
| ## Abstract | ||
|
|
||
| This SIP proposes adding a new event--`UpgradePackageEvent`--to the Sui framework that is emitted whenever a package is upgraded. This event would provide better observability into package upgrades, allowing developers to better monitor and prepare for the versioning of packages they depend on. | ||
|
|
||
| > As Sui will continue to evolve over time, a snapshot of the Sui repo will be used when referencing Sui Framework code. This SIP uses the latest stable version of mainnet: `mainnet-v1.47.1`.<sup>[1](https://github.com/MystenLabs/sui/tree/mainnet-v1.47.1)</sup> | ||
|
|
||
| ## Background | ||
|
|
||
| **Upgrading.** On Sui, smart contracts are encapsulated into Sui Move packages and published as singular, immutable objects. The publisher of a package receives an `UpgradeCap` granting them the authority to control the package's upgrade cycle. Packages themselves can be marked as: | ||
| 1. mutable, | ||
| 1. immutable w/ mutable dependencies, or | ||
| 1. immutable. | ||
|
|
||
| **Versioning.** Every time a package is upgraded, a new immutable object is created; the previous package is ***not*** modified and remains callable. For this reason, Sui Move best practices recommend versioning packages to allow disabling interaction with outdated package versions. This creates two distinct events during a package's upgrade cycle: | ||
| 1. **Upgrade Event.** The moment when the package is upgraded (e.g., from a call to `sui client upgrade`), | ||
| 1. **Versioning Event.** The moment when the package is versioned (e.g., from a call to the package's `upgrade_version` function), disabling interaction with previous versions. | ||
|
|
||
| Any amount of time can exist in between events (1) and (2), with (2) being the event that can brick your own package. There is no native way of handling versioning, leading to it being an opt-in "feature" for each package. As such, observability on (2) is dependent on each package individually. | ||
|
|
||
| ## Motivation | ||
|
|
||
| **Limitations.** As a developer with many third-party dependencies, you need to be aware of and prepared for a versioning event ahead of time. If a depended-on package allows for it (e.g., by filtering for `PackageVersionedEvent`s), you can observe the moment the package is versioned. This is not enough, however, as this will likely alert that a piece of your Move package is no longer functioning as it is now attempting to interact with an outdated dependency version; you need to be aware of the moment a package is upgraded in order to begin preparing for the versioning event. | ||
|
|
||
| Currently, when a package is upgraded on Sui, there is no native event that is emitted to notify that the upgrade occurred. While the upgrade is recorded through the mutation of the `UpgradeCap` object, it is not always possible to build observability behind the `UpgradeCap` itself. | ||
| > For example, afSUI's `UpgradeCap` has been wrapped into a `QuorumUpgradeCap`<sup>[2](https://github.com/MystenLabs/apps/blob/main/upgrade_policy/quorum_upgrade/sources/quorum_upgrade_policy.move#L67-L80)</sup> object, which gives the appearance that it has been deleted.<sup>[3](https://suivision.xyz/object/0xaa2ed7faaea34db19acd21f5d6ba009f71e5ccc7e934a37d2ec72088af547784)</sup> | ||
|
|
||
| **Observability.** Adding a native event that is emitted upon package upgrades would allow developers to build better observability behind the packages they depend on, leading to the creation of more robust products on Sui and alleviating the need for strict communication between projects before package upgrades. | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| There are no prerequisites for this SIP. | ||
|
|
||
| ## Specification | ||
|
|
||
| The `UpgradedPackageEvent` will be added to the `sui::package` module of the Sui framework. | ||
|
|
||
| ```Rust | ||
| public struct UpgradedPackageEvent has copy, drop { | ||
| /// The address of the original package (the first version that was published). | ||
| original: address, | ||
| /// The address of the previous package version that is being upgraded. | ||
| previous: address, | ||
| /// The address of the newly created package resulting from the upgrade. | ||
| new: address, | ||
| /// The number of upgrades that have been applied successively to the original package. | ||
| version: u64, | ||
| } | ||
| ``` | ||
|
|
||
| This event will be emitted from within the `commit_upgrade`<sup>[4](https://github.com/MystenLabs/sui/blob/mainnet-v1.47.1/crates/sui-framework/packages/sui-framework/sources/package.move#L296-L306)</sup> function in the `sui::package` module. | ||
|
|
||
| A `native` function--`to_original_package_address`--will be added to the `sui::address` module to allow querying the original `published-at` address for a provided package address. | ||
|
|
||
| ```Rust | ||
| /// Returns the original `published-at` address of the provided package. | ||
| public native fun to_original_package_address(cap: &UpgradeCap): ID; | ||
| ``` | ||
|
|
||
| ## Rationale | ||
|
|
||
| By adding the `UpgradedPackageEvent`, developers will be able to build generalized observability behind the packages they depend on. | ||
|
|
||
| ## Backwards Compatibility | ||
|
|
||
| This SIP presents no issues with backwards compatibility. | ||
|
|
||
| ## Reference Implementation | ||
|
|
||
| This SIP requires two general changes, the changes to the Sui Framework's `package` + `address` modules and the required native function implementation. The relevant changes are detailed below. | ||
|
|
||
| ### ia. `sui::package` Module | ||
|
|
||
| ```Rust | ||
| public struct UpgradedPackageEvent has copy, drop { | ||
| /// The address of the original package (the first version that was published). | ||
| original: address, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same concern about "original" field name as above |
||
| /// The address of the previous package version that is being upgraded. | ||
| previous: address, | ||
| /// The address of the newly created package resulting from the upgrade. | ||
| new: address, | ||
| /// The number of upgrades that have been applied successively to the original package. | ||
| version: u64, | ||
| } | ||
|
|
||
| ... | ||
|
|
||
| /// Consume an `UpgradeReceipt` to update its `UpgradeCap`, finalizing | ||
| /// the upgrade. | ||
| public fun commit_upgrade(cap: &mut UpgradeCap, receipt: UpgradeReceipt) { | ||
| use sui::event::emit; | ||
|
|
||
| let UpgradeReceipt { cap: cap_id, package: new_package } = receipt; | ||
|
|
||
| assert!(object::id(cap) == cap_id, EWrongUpgradeCap); | ||
| assert!(cap.package.to_address() == @0x0, ENotAuthorized); | ||
|
|
||
| let previous_package = cap.package.to_address(); | ||
| let new_version = cap.version + 1; | ||
| emit(UpgradedPackageEvent { | ||
| original: previous_package.to_original_package_address(), | ||
| previous: previous_package, | ||
| new: new_package, | ||
| version: new_version, | ||
| }); | ||
|
|
||
| cap.package = new_package; | ||
| cap.version = new_version; | ||
| } | ||
| ``` | ||
|
|
||
| ### ib. `sui::address` Module | ||
|
|
||
| ```Rust | ||
| /// Returns the original `published-at` address of the provided package. | ||
| public native fun to_original_package_address(package: address): address; | ||
|
|
||
| ``` | ||
|
|
||
| ### ii. `to_original_package_address` Function Implementation | ||
|
|
||
| The implementation of `to_original_package_address` is left out of the first version of this SIP. | ||
|
|
||
| ## Security Considerations | ||
|
|
||
| This SIP is non-invasive and presents no security considerations. | ||
|
|
||
| ## References | ||
|
|
||
| 1. [[Sui Repo] mainnet-v1.47.1](https://github.com/MystenLabs/sui/tree/mainnet-v1.47.1) | ||
| 1. [[MystenLabs Apps] `QuorumUpgradeCap`](https://github.com/MystenLabs/apps/blob/main/upgrade_policy/quorum_upgrade/sources/quorum_upgrade_policy.move#L67-L80) | ||
| 1. [[Explorer] afSUI `UpgradeCap`](https://suivision.xyz/object/0xaa2ed7faaea34db19acd21f5d6ba009f71e5ccc7e934a37d2ec72088af547784) | ||
| 1. [[Sui Repo] `sui::package::commit_upgrade`](https://github.com/MystenLabs/sui/blob/mainnet-v1.47.1/crates/sui-framework/packages/sui-framework/sources/package.move#L296-L306) | ||
|
|
||
| ## Copyright | ||
|
|
||
| [CC0 1.0](../LICENSE.md). | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
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.
maybe "genesis" or "initial" or something else will be a better name? "original" is a bit vague
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.
Original as in the package address that is created during
sui client publish.previous+newwould be dynamic off of what version of the contract is being upgraded, butoriginalwill always point to a package's initial address.