Skip to content
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

[move-vm] allow multi-module publication #8555

Merged
merged 2 commits into from
Jul 17, 2021
Merged

Conversation

meng-xu-cs
Copy link
Contributor

@meng-xu-cs meng-xu-cs commented Jun 16, 2021

The first commit updates the Move VM API
This commit allows the Move VM to take a vector of modules (for lacking
of a better name, this vector of modules is called a bundle for now) and
publish them together.

Modules in the bundle vector must follow a topological order, i.e., if
there is a dependency relation (usage or friend) between two modules
A and B, via either 1) B uses A or 2) A declares B as a friend. Then,
A must appear before B in the bundle vector in order to be published
together. Putting B in front of A in this case will lead to a
MISSING_DEPENDENCY error or other linker errors.

All modules in the bundle will have to pass the bytecode verifier and
will be linker-checked with existing modules and all other modules in
the same bundle. Either all modules in the bundle are published/updated
or none is published/updated. Publication of the whole bundle fails as
long as one module in the bundle fail the bytecode verifier or the
linker checks (i.e., dependency and cyclic dependency check).

There is also a very informal argument in the code comments on why
the current implementation might seem plausible. Please check that
as well. I am hoping to come up with a much stronger argument (or
even paper proof) why this is correct, but I haven't reached there yet.

The second commit adds support for multi-module publishing the Move CLI
The move-cli sandbox publish command now accepts a new optional
command line argument -m/--override-ordering that allows manual
specification of which compiled modules to be published and in what
order.

Specifying any of the -m/--override-ordering flag will invoke the
multi-module publishing flow in the Move VM (compared with the
traditional one-module-at-a-time flow).

For example: sandbox publish -m A -m B will prepare a module vector
[A, B] to be sent for publication while -m B -m A will create a vector
[B, A]. And depending on the relationship between module A and B, it is
possible that only one particular ordering can be allowed. For more
detailed use cases, see the test case multi_module_publish.

It is possible to request publication of a subset of the compiled modules. For
example, if three modules A, B, C are compiled and only -m A -m B is
specified, then only A and B will be sent to Move VM for publication.

It is also possible to specify one module multiple times, e.g.,
-m A -m A. The Move CLI will not complain about it but the Move VM
will as it checks for no duplication in the vector of modules.

It is, however, not possible to specify a non-compiled module (e.g.,
module D which is not compiled) for publication. An error will be raised
in this case.

Motivation

Partially address #8512

Have you read the Contributing Guidelines on pull requests?

Yes

Test Plan

CI for existing code
new test cases being added to Move CLI, under multi_module_publish dir.


data_store.publish_module(&module_id, module)
// NOTE: we want to (informally) argue that all modules pass the linking check before being
Copy link
Contributor

@sblackshear sblackshear Jun 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't had time to digest this in detail yet, but there are two tests that would greatly increase my confidence:

  • publish a module A that contains friend B in a vec that does not also contain B
  • publish list [A, B] where B creates cyclic dependencies, but only if A is published first

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, test case coming up

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests added in Move CLI testsuite, under dir multi_module_publish.

We cannot use functional-tests or e2e-tests yet because we don't have support for multi-module publishing at the TransactionPayload level (TransactionPayload::Module(<single-module-here>)). So Move CLI becomes really helpful in this case.

@meng-xu-cs meng-xu-cs force-pushed the multi-pub branch 5 times, most recently from 8a5f4d4 to 472ba86 Compare June 23, 2021 17:53
@meng-xu-cs meng-xu-cs marked this pull request as ready for review June 23, 2021 17:53
);
if let Err(err) = res {
// TODO (mengxu): explain publish errors in multi-module publishing
println!("Invalid multi-module publishing: {}", err);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This requires some non-trivial changes to the explain_publish_error function. In order not to mess-up with this PR, I prefer to have a separate PR to address this TODO item.

Copy link
Contributor

@sblackshear sblackshear left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for taking so long to get to this!

language/move-vm/runtime/src/loader.rs Outdated Show resolved Hide resolved
language/move-vm/runtime/src/loader.rs Show resolved Hide resolved
language/move-vm/runtime/src/loader.rs Show resolved Hide resolved
@@ -96,6 +96,9 @@ pub enum SandboxCommand {
/// Set this flag to ignore breaking changes checks and publish anyway
#[structopt(long = "ignore-breaking-changes")]
ignore_breaking_changes: bool,
/// fix publishign order
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compile with no additional arguments compiles everything in the current directory, whereas specifying a list of files will compile only those files. I think it might make sense to file that same convention here, especially since sandbox publish with no other arguments already publishes everything. We could do this by using modules: Vec<String> as an anonymous argument instead of adding override-ordering.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, that would help us eliminate an additional argument. The only issue is that we could have a single Move file containing multiple modules, if we specify at the file granularity, we lose two capabilities

  1. the capability of publishing a subset of the modules in the same file,
  2. the capability of publishing the modules at a different ordering.

These issue can be addressed with the override-ordering flag, but at the cost of one extra flag in the command line

@meng-xu-cs meng-xu-cs force-pushed the multi-pub branch 2 times, most recently from b9a8dab to 254f48f Compare July 16, 2021 22:23
@meng-xu-cs
Copy link
Contributor Author

Sorry that it took me a while to address the comments. The PR is brought up to date again so feel free to take another look @sblackshear

sblackshear
sblackshear previously approved these changes Jul 17, 2021
Copy link
Contributor

@sblackshear sblackshear left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@meng-xu-cs
Copy link
Contributor Author

/land

@bors-libra bors-libra moved this from In Review to Queued in bors Jul 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants