Skip to content

Commit

Permalink
[docs] Added documentation for package versioning (MystenLabs#11527)
Browse files Browse the repository at this point in the history
## Description 

As a follow-up to MystenLabs#11253, added
some additional info on package upgrades/versioning that (I believe) is
not yet covered anywhere.

I feel like perhaps we should pull some introductory material on upgrade
policies from
https://github.com/MystenLabs/sui/blob/main/doc/src/build/custom-upgrade-policy.md
(@amnn?) but I did not want to make changes that are too disruptive at
this point.

@tzakian - please chime in if the description of the compatibility
checks, admittedly pretty short, is sufficient or if we should
add/change something right away.

---
If your changes are not user-facing and not a breaking change, you can
skip the following section. Otherwise, please indicate what changed, and
then add to the Release Notes section as highlighted during the release
process.

### Type of Change (Check all that apply)

- [x] user-visible impact
- [ ] breaking change for a client SDKs
- [ ] breaking change for FNs (FN binary must upgrade)
- [ ] breaking change for validators or node operators (must upgrade
binaries)
- [ ] breaking change for on-chain data layout
- [ ] necessitate either a data wipe or data migration

### Release notes

---------

Co-authored-by: Ashok Menon <ashok@mystenlabs.com>
Co-authored-by: Ronny Roland <ronmilton@mystenlabs.com>
  • Loading branch information
3 people authored May 2, 2023
1 parent 78d7385 commit baeee8c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 7 deletions.
19 changes: 18 additions & 1 deletion doc/src/build/custom-upgrade-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,23 @@ You can make a package *immutable* when it goes live to mitigate this risk using

To address the security risk a single key poses while still providing the opportunity to upgrade live packages, Sui offers *custom upgrade policies*. These policies protect `UpgradeCap` access behind arbitrary Sui Move code and issue `UpgradeTicket` objects that authorize upgrades on a case-by-case basis.

## Compatibility

Sui comes with a set of built-in package compatibility policies, listed here from most to least strict:

| Policy | Description |
| --- | --- |
| Immutable | No one can upgrade the package. |
| Dependency-only | You can modify the dependencies of the package only.|
| Additive | You can add new functionality to the package (e.g., new public functions or structs) but you can't change any of the existing functionality (e.g., the code in existing public functions cannot change). |
| Compatible | The most relaxed policy. In addition to what the more restrictive policies allow, in an upgraded version of the package: <ul><li>You can change all function implementations.</li><li>You can remove the ability constraints on generic type parameters in function signatures.</li><li>You can change, remove, or make `public` any `private`, `public(friend)`, and `entry` function signatures.</li><li>You cannot change `public` function signatures (except in the case of ability constraints mentioned previously).</li><li>You cannot change existing types.</li></ul> |

Each of these policies, in the order listed, is a superset of the previous one in the type of changes allowed in the upgraded package.

When you publish a package, by default it adopts the most relaxed, compatible policy. You can publish a package as part of a transaction block that can change the policy before the transaction block successfully completes, making the package available on chain for the first time at the desired policy level, rather than at the default one.

You can change the current policy by calling one of the functions in `sui::package` (`only_additive_upgrades`, `only_dep_upgrades`, `make_immutable`) on the package's [`UpgradeCap`](./custom-upgrade-policy.md#upgradecap) and a policy can become only more restrictive. For example, after you call `sui::package::only_dep_upgrades` to restrict the policy to become additive, calling `sui::package::only_additive_upgrades` on the `UpgradeCap` of the same package results in an error.

## Upgrade overview

Package upgrades must occur end-to-end in a single transaction block and are composed of three commands:
Expand Down Expand Up @@ -1015,4 +1032,4 @@ status: {
error: 'MoveAbort(MoveLocation { module: ModuleId { address: <POLICY-PACKAGE>, name: Identifier("day_of_week") }, function: 1, instruction: 11, function_name: Some("authorize_upgrade") }, 2) in command 0'
},
...
```
```
8 changes: 4 additions & 4 deletions doc/src/build/dependency-overrides.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ A package might depend on another package _directly_ or _indirectly_ (also calle

As long as all versions of all (directly or indirectly) dependent packages are the same, no further action on the side of the "user" package's developer is required. Unfortunately, this is not always the case. Consider the following example of the `user` package directly depending on two "library" packages: `vault` and `currency` (these are not real packages and their URLs do not exist). The (simplified) manifest file of the `user` package would then resemble the following:

```move
```toml
[package]
name = "user"
version = "1.0.0"
Expand All @@ -21,7 +21,7 @@ currency = { git = "https://github.com/currency_org/currency.git" }

Further consider that both `vault` and `currency` depend on another "library" package, `crypto`, but each of them depends on a different version (`crypto` becomes an indirect dependency of the `user` package). Their respective manifest files could then resemble the following:

```move
```toml
[package]
name = "vault"
version = "1.0.0"
Expand All @@ -30,7 +30,7 @@ version = "1.0.0"
crypto = { git = "https://github.com/crypto.org/crypto.git" , rev = "v1.0.0"}
```

```move
```toml
[package]
name = "currency"
version = "2.0.0"
Expand All @@ -43,7 +43,7 @@ This situation represents the [_diamond dependency conflict_](https://jlbp.dev/w

To resolve these types of problems, developers can _override_ indirect dependencies of the packages they develop. In other words, we provide a mechanism that the developer can use to specify a single version of a dependent package to be used during the build process. This can be done by introducing a _dependency override_ in the manifest file of the developed package. In the case of our running example, developer of the `user` package might decide that all dependent packages should use version `2.0.0` of the `crypto` package (note that it is the same as specified in the manifest file of the `currency` package but could be a version not used by any of the dependencies, for example `3.0.0`). At a technical level, in order to enforce a dependency override, a developer of a "user" package has to put a dependency with a chosen version in their own manifest file, with the addition of the `override` flag set to `true`. The manifest file of the `user` package correcting the diamond dependency conflict in our running example would resemble the following:

```move
```toml
[package]
name = "user"
version = "1.0.0"
Expand Down
2 changes: 1 addition & 1 deletion doc/src/build/package-upgrades.md
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ When you use the Sui Client CLI, the `upgrade` command handles generating the up

You develop a package named `sui_package`. Its manifest looks like the following:

```move
```toml
[package]
name = "sui_package"
version = "0.0.0"
Expand Down
19 changes: 18 additions & 1 deletion doc/src/learn/object-package-versions.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,21 @@ Framework packages (such as the Move standard library at `0x1` and the Sui Frame
(0x1, 3) => MoveStdlib v3
```

The prior example shows the on-chain representation of the first three versions of the Move standard library.
The prior example shows the on-chain representation of the first three versions of the Move standard library.

### Package versions

Sui smart contracts are organized into [upgradeable](../build/package-upgrades.md) packages and, as a result, multiple versions of any given package can exist on chain. Before someone can use an on-chain package, you must [publish](../build/move/debug-publish.md#publishing-a-package) its first, original version. When you upgrade a package, you create a new version of that package. Each upgrade of a package is based on the immediately preceding version of that package in the versions history. In other words, you can upgrade the _n_th version of a package from only the _n_th - 1 version. For example, you can upgrade a package from version 1 to 2, but afterwards you can upgrade that package only from version 2 to 3; you're not allowed to upgrade from version 1 to 3.

There is a notion of versioning in package [manifest](../build/move/manifest.md) files, existing in both the [package section](../build/move/manifest.md#package-section) and in the [dependencies section](../build/move/manifest.md#dependencies-section). For example, consider the manifest code that follows:

```toml
[package]
name = "some_pkg"
version = "1.0.0"

[dependencies]
another_pkg = { git = "https://github.com/another_pkg/another_pkg.git" , version = "2.0.0"}
```

At this point, the version references in the manifest are used only for user-level documentation as the `publish` and `upgrade` commands do not leverage this information. If you publish a package with a certain package version in the manifest file and then modify and re-publish the same package with a different version (using `publish` command rather than `upgrade` command), the two are considered different packages, rather than on-chain versions of the same package. You should not use any of these packages as a [dependency override](../build/dependency-overrides.md) to stand in for the other one. While you can specify this type of override when building a package, it results in an error when publishing or upgrading on chain.

0 comments on commit baeee8c

Please sign in to comment.