Module 0x7::large_packages
Aptos Large Packages Framework
This module provides a framework for uploading large packages to the Aptos network, under standard
accounts or objects.
To publish using this API, you must divide your metadata and modules across multiple calls
into large_packages::stage_code_chunk.
In each pass, the caller pushes more code by calling stage_code_chunk.
In the final call, the caller can use stage_code_chunk_and_publish_to_account, stage_code_chunk_and_publish_to_object, or
stage_code_chunk_and_upgrade_object_code to upload the final data chunk and publish or upgrade the package on-chain.
The above logic is currently implemented in the Python
SDK: aptos-python-sdk.
Aptos CLI supports this as well with –chunked-publish flag:
aptos move publish [OPTIONS] –chunked-publishaptos move create-object-and-publish-package [OPTIONS] –address-name <ADDRESS_NAME> –chunked-publishaptos move upgrade-object-package [OPTIONS] –address-name <ADDRESS_NAME> –chunked-publish
Usage
- Stage Code Chunks:
- Call
stage_code_chunkwith the appropriate metadata and code chunks. - Ensure that
code_indicesare provided from0tolast_module_idx, without any gaps.
- Publish or Upgrade:
-
In order to upload the last data chunk and publish the package, call
stage_code_chunk_and_publish_to_accountorstage_code_chunk_and_publish_to_object. -
For object code upgrades, call
stage_code_chunk_and_upgrade_object_codewith the argumentcode_objectprovided.
- Cleanup:
- In order to remove
StagingArearesource from an account, callcleanup_staging_area.
Notes
- Make sure LargePackages is deployed to your network of choice, you can currently find it both on
mainnet and testnet at
0xa29df848eebfe5d981f708c2a5b06d31af2be53bbd8ddc94c8523f4b903f7adb, and in 0x7 (aptos-experimental) on devnet/localnet. - Ensure that
code_indiceshave no gaps. For example, if code_indices are provided as [0, 1, 3] (skipping index 2), the inline functionassemble_module_codewill abort sinceStagingArea.last_module_idxis set as the max value of the provided index fromcode_indices, andassemble_module_codewill lookup theStagingArea.codeSmartTable from 0 toStagingArea.last_module_idxin turn.
- Aptos Large Packages Framework
- Usage
- Notes
- Resource
StagingArea - Constants
- Function
stage_code_chunk - Function
stage_code_chunk_and_publish_to_account - Function
stage_code_chunk_and_publish_to_object - Function
stage_code_chunk_and_upgrade_object_code - Function
stage_code_chunk_internal - Function
publish_to_account - Function
publish_to_object - Function
upgrade_object_code - Function
assemble_module_code - Function
cleanup_staging_area
use 0x1::code;
use 0x1::error;
use 0x1::object;
use 0x1::object_code_deployment;
use 0x1::signer;
use 0x1::smart_table;
use 0x1::vector;
Resource StagingArea
struct StagingArea has key
Fields
-
metadata_serialized: vector<u8> -
code: smart_table::SmartTable<u64, vector<u8>> -
last_module_idx: u64
Constants
code_indices and code_chunks should be the same length.
const ECODE_MISMATCH: u64 = 1;
Object reference should be provided when upgrading object code.
const EMISSING_OBJECT_REFERENCE: u64 = 2;
Function stage_code_chunk
public entry fun stage_code_chunk(owner: &signer, metadata_chunk: vector<u8>, code_indices: vector<u16>, code_chunks: vector<vector<u8>>)
Implementation
public entry fun stage_code_chunk(
owner: &signer,
metadata_chunk: vector<u8>,
code_indices: vector<u16>,
code_chunks: vector<vector<u8>>
) acquires StagingArea {
stage_code_chunk_internal(
owner,
metadata_chunk,
code_indices,
code_chunks
);
}
Function stage_code_chunk_and_publish_to_account
public entry fun stage_code_chunk_and_publish_to_account(owner: &signer, metadata_chunk: vector<u8>, code_indices: vector<u16>, code_chunks: vector<vector<u8>>)
Implementation
public entry fun stage_code_chunk_and_publish_to_account(
owner: &signer,
metadata_chunk: vector<u8>,
code_indices: vector<u16>,
code_chunks: vector<vector<u8>>
) acquires StagingArea {
let staging_area =
stage_code_chunk_internal(
owner,
metadata_chunk,
code_indices,
code_chunks
);
publish_to_account(owner, staging_area);
cleanup_staging_area(owner);
}
Function stage_code_chunk_and_publish_to_object
public entry fun stage_code_chunk_and_publish_to_object(owner: &signer, metadata_chunk: vector<u8>, code_indices: vector<u16>, code_chunks: vector<vector<u8>>)
Implementation
public entry fun stage_code_chunk_and_publish_to_object(
owner: &signer,
metadata_chunk: vector<u8>,
code_indices: vector<u16>,
code_chunks: vector<vector<u8>>
) acquires StagingArea {
let staging_area =
stage_code_chunk_internal(
owner,
metadata_chunk,
code_indices,
code_chunks
);
publish_to_object(owner, staging_area);
cleanup_staging_area(owner);
}
Function stage_code_chunk_and_upgrade_object_code
public entry fun stage_code_chunk_and_upgrade_object_code(owner: &signer, metadata_chunk: vector<u8>, code_indices: vector<u16>, code_chunks: vector<vector<u8>>, code_object: object::Object<code::PackageRegistry>)
Implementation
public entry fun stage_code_chunk_and_upgrade_object_code(
owner: &signer,
metadata_chunk: vector<u8>,
code_indices: vector<u16>,
code_chunks: vector<vector<u8>>,
code_object: Object<PackageRegistry>
) acquires StagingArea {
let staging_area =
stage_code_chunk_internal(
owner,
metadata_chunk,
code_indices,
code_chunks
);
upgrade_object_code(owner, staging_area, code_object);
cleanup_staging_area(owner);
}
Function stage_code_chunk_internal
fun stage_code_chunk_internal(owner: &signer, metadata_chunk: vector<u8>, code_indices: vector<u16>, code_chunks: vector<vector<u8>>): &mut large_packages::StagingArea
Implementation
inline fun stage_code_chunk_internal(
owner: &signer,
metadata_chunk: vector<u8>,
code_indices: vector<u16>,
code_chunks: vector<vector<u8>>
): &mut StagingArea {
assert!(
code_indices.length() == code_chunks.length(),
error::invalid_argument(ECODE_MISMATCH)
);
let owner_address = signer::address_of(owner);
if (!exists<StagingArea>(owner_address)) {
move_to(
owner,
StagingArea {
metadata_serialized: vector[],
code: smart_table::new(),
last_module_idx: 0
}
);
};
let staging_area = borrow_global_mut<StagingArea>(owner_address);
if (!metadata_chunk.is_empty()) {
staging_area.metadata_serialized.append(metadata_chunk);
};
let i = 0;
while (i < code_chunks.length()) {
let inner_code = code_chunks[i];
let idx = (code_indices[i] as u64);
if (staging_area.code.contains(idx)) {
staging_area.code.borrow_mut(idx).append(inner_code);
} else {
staging_area.code.add(idx, inner_code);
if (idx > staging_area.last_module_idx) {
staging_area.last_module_idx = idx;
}
};
i += 1;
};
staging_area
}
Function publish_to_account
fun publish_to_account(publisher: &signer, staging_area: &mut large_packages::StagingArea)
Implementation
inline fun publish_to_account(
publisher: &signer, staging_area: &mut StagingArea
) {
let code = assemble_module_code(staging_area);
code::publish_package_txn(publisher, staging_area.metadata_serialized, code);
}
Function publish_to_object
fun publish_to_object(publisher: &signer, staging_area: &mut large_packages::StagingArea)
Implementation
inline fun publish_to_object(
publisher: &signer, staging_area: &mut StagingArea
) {
let code = assemble_module_code(staging_area);
object_code_deployment::publish(
publisher, staging_area.metadata_serialized, code
);
}
Function upgrade_object_code
fun upgrade_object_code(publisher: &signer, staging_area: &mut large_packages::StagingArea, code_object: object::Object<code::PackageRegistry>)
Implementation
inline fun upgrade_object_code(
publisher: &signer,
staging_area: &mut StagingArea,
code_object: Object<PackageRegistry>
) {
let code = assemble_module_code(staging_area);
object_code_deployment::upgrade(
publisher,
staging_area.metadata_serialized,
code,
code_object
);
}
Function assemble_module_code
fun assemble_module_code(staging_area: &mut large_packages::StagingArea): vector<vector<u8>>
Implementation
inline fun assemble_module_code(staging_area: &mut StagingArea): vector<vector<u8>> {
let last_module_idx = staging_area.last_module_idx;
let code = vector[];
let i = 0;
while (i <= last_module_idx) {
code.push_back(*staging_area.code.borrow(i));
i += 1;
};
code
}
Function cleanup_staging_area
public entry fun cleanup_staging_area(owner: &signer)
Implementation
public entry fun cleanup_staging_area(owner: &signer) acquires StagingArea {
let StagingArea { metadata_serialized: _, code, last_module_idx: _ } =
move_from<StagingArea>(signer::address_of(owner));
code.destroy();
}