Background
In "normal" Move, a module is uniquely identified by ModuleId
derived from its "self address" and its name. E.g., module 0x1::MyModule
has the module Id 0x1::MyModule
, where 0x
is the self address.
However, in fastX we need the module's self address to be the same as its object ID, both to prevent duplicate publishing of modules and to enable lookups of a module and its dependencies by ID. The natural solution is to ask a user to update a module with its self address set to its ObjectID
. However, ObjectID
's are derived from the hash of the transaction that creates the object (which itself contains the module and its self ID!), so we have a circularity...
This problem is known, and already solved by the following (unfortunate, but necessary) workaround: before actually publishing the module, we mutate its self address to the correct ObjectID
.
The Problem
However, this workaround creates its own problems (e.g., the one described in #56). The big one is that if you are publishing module 0x1:Parent
and dependent module 0x2::Child
in the same transaction, the current publishing logic will:
- overwrite
0x1
with a fresh object ID in Parent
- overwrite
0x2
with a fresh object ID in Child
The problem is that Child
will use the module handle 0x1::Parent
(because it depends on Parent
!), but steps (1) and (2) do not update that handle to Parent
's new address. The resulting modules will fail to link, and publishing will fail.
The Proposed Solution
Both this issue and #56 can be solved by more careful (and more complex) bytecode rewriting on the publish
codepath. The rewrites that we do should be both semantics-preserving (e.g., not cause problems like #56) and ensure that if the input modules linked before rewriting, they should also link after rewriting.