-
Notifications
You must be signed in to change notification settings - Fork 11.3k
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
[Package management] add implicit system package dependencies (dvx-197) #21204
base: main
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎
2 Skipped Deployments
|
@@ -43,6 +43,7 @@ fn no_dep_graph() { | |||
/* skip_fetch_latest_git_deps */ true, | |||
std::io::sink(), | |||
tempfile::tempdir().unwrap().path().to_path_buf(), | |||
/* implicit deps */ Dependencies::default(), |
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.
/* implicit deps */ Dependencies::default(), | |
Dependencies::default() /* implicit deps */ , |
let protocol_version = protocol_config.protocol_version; | ||
|
||
build_config.implicit_dependencies = implicit_deps_for_protocol_version(protocol_version)?; |
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.
let protocol_version = protocol_config.protocol_version; | |
build_config.implicit_dependencies = implicit_deps_for_protocol_version(protocol_version)?; | |
build_config.implicit_dependencies = implicit_deps_for_protocol_version(protocol_config.protocol_version)?; |
"[{}]: The network is using protocol version {:?}, which is newer than this binary; \ | ||
the system packages used for compilation (e.g. MoveStdlib) may be out of date.", | ||
"warning".bold().yellow(), |
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.
Do we want to include a bit more details here along the lines:
- protocol version in the binary, protocol version in the network, including which network is being active
- may be out of date is a bit vague, but I think it's fine if we include some suggestion on what could go wrong or what to do.
- while this is a warning, I am suggesting to add information on what to do if a user would want to get rid of this warning.
From a high level looks good to me, I left one comment about previous tests that use local dependency. I assume that means that this is an explicit dependency, and therefore it is ignored by the implicit deps feature, so nothing needs to happen there. A nit: not sure if it's too late to try to split this PR into smaller ones, would make it easier to review + rebasing + managing the change with all the tests going on:
|
with_unpublished_deps: bool, | ||
dump_bytecode_as_base64: bool, | ||
generate_struct_layouts: bool, | ||
chain_id: Option<String>, | ||
) -> anyhow::Result<()> { | ||
config.implicit_dependencies = implicit_deps(latest_system_packages()); |
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.
I am not sure I follow why we call the latest system packages here. Is it because the sui move build
is chain-agnostic and does not connect to a network, so we need to get the last known system packages that are available in the binary?
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.
Yes, exactly
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.
Perhaps I'm not following the logic here fully (or maybe this is handled elsewhere?), but I'm somewhat worried about this and the behavior it introduces.
My understanding of what this is doing (and please correct me if I'm wrong) is that this is setting the implicit dependencies to be the system packages at the time the Sui CLI (/binary) is built. However this then fixes the system packages that will be used implicitly to be frozen at build time of the CLI binary, so if someone is using an old(er) Sui CLI to test or publish they will be getting possibly stale dependencies unless they specify the dep explicitly or upgrade their CLI?
install_dir: Some(install_dir), | ||
silence_warnings: true, | ||
lint_flag: move_package::LintFlag::LEVEL_NONE, | ||
// TODO: in the future this should probably be changed to a set of local deps: |
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.
Not sure I understand this TODO comment.
}) | ||
} | ||
|
||
/// Returns the deps from `resolution_graph` that have no source code |
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.
/// Returns the deps from `resolution_graph` that have no source code | |
/// Returns the bytecode deps from `resolution_graph` that have no source code |
fn verify_bytecode(package: &MoveCompiledPackage, fn_info: &FnInfoMap) -> SuiResult<()> { | ||
let compiled_modules = package.root_modules_map(); | ||
let verifier_config = ProtocolConfig::get_for_version(ProtocolVersion::MAX, Chain::Unknown) | ||
.verifier_config(/* signing_limits */ None); | ||
|
||
if run_bytecode_verifier { | ||
let verifier_config = ProtocolConfig::get_for_version(ProtocolVersion::MAX, Chain::Unknown) | ||
.verifier_config(/* signing_limits */ None); | ||
|
||
let compiled_modules = package.root_modules_map(); | ||
for m in compiled_modules.iter_modules() { | ||
move_bytecode_verifier::verify_module_unmetered(m).map_err(|err| { | ||
SuiError::ModuleVerificationFailure { | ||
error: err.to_string(), | ||
} | ||
})?; | ||
sui_bytecode_verifier::sui_verify_module_unmetered(m, &fn_info, &verifier_config)?; | ||
} | ||
// TODO(https://github.com/MystenLabs/sui/issues/69): Run Move linker | ||
for m in compiled_modules.iter_modules() { | ||
move_bytecode_verifier::verify_module_unmetered(m).map_err(|err| { | ||
SuiError::ModuleVerificationFailure { | ||
error: err.to_string(), | ||
} | ||
})?; | ||
sui_bytecode_verifier::sui_verify_module_unmetered(m, fn_info, &verifier_config)?; | ||
} | ||
// TODO(https://github.com/MystenLabs/sui/issues/69): Run Move linker |
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.
ditto, might want to have a separate PR just for this change (bundled with the one above)
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.
Overall looking good to me! Two main questions/comments:
- What are your thoughts on including implicit deps even if some of the members are explicitly mentioned (and just not adding those). This feels like the "least surprising" option to me, but maybe there's a cornercase I'm missing with it.
- It seems like we're fixing the versions of the implicit system packages on the Sui side to be the greatest version at the time the CLI was built. This seems like it may lead to a frustrating experience for folks as in order to use a more up-to-date version of the system packages that are provided implicitly is to either explicitly depend on them, or to update their CLI (which with our release cycle I could see being a bit annoying). I'm wondering if using a tagged branch for this (e.g.,
main
, ortestnet
/mainnet
depending on chain identifier possibly?) would allow us to insert the most recent and/or current correct version of the system packages when testing/publishing packages to a given network.
/// Additional dependencies on [self.implicit_dependencies] are added to all nodes of the | ||
/// returned graph, except for nodes that are themselves in [self.implicit_dependencies] or | ||
/// that have an explicit dependency on one of the implicit packages (note that having just one | ||
/// explicit dep from a node disables all implicit deps for that node!) |
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.
2 questions on this here:
-
I'm guessing that the expectation is that all transitive dependencies will be explicitly mentioned in the
implicit_deps
? If so, might be helpful to add as a comment. -
Should we only filter out the implicit deps that are explicitly mentioned, but insert the others? I'm just wondering if the semantics here could lead to unexpected behavior of e.g., I'm using some Sui Framework code implicitly in my package (e.g.,
object
), I then add a dep on theMoveStdlib
for some reason, and now I no longer have access to myobject
module even though I didn't mention anything explicitly about it.
/// Return the dependencies contained in the file at `path`, if any | ||
fn load_implicits(path: &Path) -> Dependencies { | ||
let deps_toml = fs::read_to_string(path).unwrap_or("# no implicit deps".to_string()); | ||
toml::from_str(&deps_toml) |
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.
IMO I think it's fine to derive Serialize
/Deserialize
on the types as they are saved off in the OnDiskPackage
(since the BuildConfig
is currently). We could maybe get away with not deriving it if we add a #[serde(skip, default)]
on the field, but as long as we are saving the BuildConfig
off in the build
it makes sense to me to include the implicit deps in there as well.
I do think using the manifest parser here would be nice though (but don't have super strong opinions on it).
Expected: `a` should not have any implicit deps because any explicits should | ||
turn off implicits |
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.
Phrasing this in terms of my question in dependency_graph.rs
; what if this also included i1
but with I2 = i2'
?
} | ||
/// Create a set of [Dependencies] from a [SystemPackagesVersion]; the dependencies are override git | ||
/// dependencies to the specific revision given by the [SystemPackagesVersion] | ||
pub fn implicit_deps(packages: &SystemPackagesVersion) -> Dependencies { |
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.
Does this include other system packages? I would have a preference not to include the deepbook package here (and possibly even the bridge package) as that seems maybe a bit too much. "it's a system package, deal with it" will make me sad, but is an acceptable answer here too...
with_unpublished_deps: bool, | ||
dump_bytecode_as_base64: bool, | ||
generate_struct_layouts: bool, | ||
chain_id: Option<String>, | ||
) -> anyhow::Result<()> { | ||
config.implicit_dependencies = implicit_deps(latest_system_packages()); |
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.
Perhaps I'm not following the logic here fully (or maybe this is handled elsewhere?), but I'm somewhat worried about this and the behavior it introduces.
My understanding of what this is doing (and please correct me if I'm wrong) is that this is setting the implicit dependencies to be the system packages at the time the Sui CLI (/binary) is built. However this then fixes the system packages that will be used implicitly to be frozen at build time of the CLI binary, so if someone is using an old(er) Sui CLI to test or publish they will be getting possibly stale dependencies unless they specify the dep explicitly or upgrade their CLI?
Description
This PR enables you to use system packages (e.g.
MoveStdlib
,Sui
,DeepBook
) without explicitly adding them to yourMove.toml
. It works by querying the network during publication / upgrade for the protocol version and using that information to determine the correct version of the system dependencies. During build, the latest known version is used.Test plan
TODO
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.