Skip to content

Commit

Permalink
Merge bytecode snapshots (MystenLabs#11955)
Browse files Browse the repository at this point in the history
## Description 

This PR simplifies the framework snapshot flow:
1. Merges the snapsnot between mainnet and testnet. This will require us
to always ship unique protocol version bytecode globally.
2. Move the GIT_REVISION related code to a shared file in sui-types so
that all files can use it directly.
3. Remove the need to pass any arguments to sui-framework-snapshot

## Test Plan 
CI

How did you test the new or updated feature?

---
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)

- [ ] 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
  • Loading branch information
lxfind authored May 12, 2023
1 parent 14996e3 commit 1328670
Show file tree
Hide file tree
Showing 51 changed files with 163 additions and 265 deletions.
8 changes: 2 additions & 6 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 6 additions & 21 deletions crates/sui-benchmark/tests/simtest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,16 +254,16 @@ mod test {
}

#[sim_test(config = "test_config()")]
async fn test_testnet_upgrade_compatibility() {
async fn test_upgrade_compatibility() {
// This test is intended to test the compatibility of the latest protocol version with
// the previous protocol version on testnet. It does this by starting a testnet with
// the previous protocol version. It does this by starting a network with
// the previous protocol version that this binary supports, and then upgrading the network
// to the latest protocol version.
let max_ver = ProtocolVersion::MAX.as_u64();
let min_ver = max_ver - 1;
let timeout = tokio::time::timeout(
Duration::from_secs(1000),
test_protocol_upgrade_compatibility_impl(min_ver, "testnet"),
test_protocol_upgrade_compatibility_impl(min_ver),
)
.await;
match timeout {
Expand All @@ -274,24 +274,10 @@ mod test {
}
}

#[sim_test(config = "test_config()")]
async fn test_mainnet_upgrade_compatibility() {
// This test is intended to test the compatibility of the latest protocol version with
// the previous protocol version on mainnet. It does this by starting a network with
// the previous protocol version that this binary supports, and then upgrading the network
// to the latest protocol version.
let max_ver = ProtocolVersion::MAX.as_u64();
let min_ver = max_ver - 1;
test_protocol_upgrade_compatibility_impl(min_ver, "mainnet").await;
}

async fn test_protocol_upgrade_compatibility_impl(
starting_version: u64,
network: &'static str,
) {
async fn test_protocol_upgrade_compatibility_impl(starting_version: u64) {
let max_ver = ProtocolVersion::MAX.as_u64();
let init_framework =
sui_framework_snapshot::load_bytecode_snapshot(network, starting_version).unwrap();
sui_framework_snapshot::load_bytecode_snapshot(starting_version).unwrap();
let mut test_cluster = init_test_cluster_builder(7, 5000)
.with_protocol_version(ProtocolVersion::new(starting_version))
.with_supported_protocol_versions(SupportedProtocolVersions::new_for_testing(
Expand Down Expand Up @@ -331,8 +317,7 @@ mod test {
break;
}
let next_version = version + 1;
let new_framework =
sui_framework_snapshot::load_bytecode_snapshot(network, next_version);
let new_framework = sui_framework_snapshot::load_bytecode_snapshot(next_version);
let new_framework_ref: Vec<_> = match &new_framework {
Ok(f) => f.iter().collect(),
Err(_) => {
Expand Down
4 changes: 3 additions & 1 deletion crates/sui-framework-snapshot/README.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
Whenever we release a new binary that has a new protocol version to a network, we should go to the tip of that network's branch, and run this command:
```
cargo run --bin sui-framework-snapshot -- testnet `git rev-parse HEAD`
cargo run --bin sui-framework-snapshot
```
And the commit the changes to `main` branch to record it.
It's important to ensure that each protocol version should correspond to a unique snapshot among all networks,
i.e. for the same protocol version, testnet and mainnet should contain identical framework bytecode.
Binary file not shown.
Binary file not shown.
Binary file not shown.
85 changes: 0 additions & 85 deletions crates/sui-framework-snapshot/bytecode_snapshot/manifest.json

This file was deleted.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
72 changes: 72 additions & 0 deletions crates/sui-framework-snapshot/manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
{
"3": {
"git_revision": "de632da6adf673d746155a1624c60a761567c215",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000003"
]
},
"4": {
"git_revision": "f5d26f1b3ae89f68cb66f3a007e90065e5286905",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000003"
]
},
"5": {
"git_revision": "3a70c4374090b020b95465787f3220a95d8ab0ba",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000003",
"0x000000000000000000000000000000000000000000000000000000000000dee9"
]
},
"6": {
"git_revision": "b7f6c8e5fcc73eb85ce230e3a9d490366daedefe",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000003",
"0x000000000000000000000000000000000000000000000000000000000000dee9"
]
},
"7": {
"git_revision": "16e0132840a6b77a7077feb0df99b07cf3bd0a69",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000003",
"0x000000000000000000000000000000000000000000000000000000000000dee9"
]
},
"8": {
"git_revision": "415994bf864c634680bcc89c7de9ee9fa10715b3",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000003",
"0x000000000000000000000000000000000000000000000000000000000000dee9"
]
},
"9": {
"git_revision": "09b2081498366df936abae26eea4b2d5cafb2788",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000003",
"0x000000000000000000000000000000000000000000000000000000000000dee9"
]
},
"10": {
"git_revision": "e4fe9f5ed5e240a718571f23bc75e12e60445288",
"package_ids": [
"0x0000000000000000000000000000000000000000000000000000000000000001",
"0x0000000000000000000000000000000000000000000000000000000000000002",
"0x0000000000000000000000000000000000000000000000000000000000000003",
"0x000000000000000000000000000000000000000000000000000000000000dee9"
]
}
}
35 changes: 9 additions & 26 deletions crates/sui-framework-snapshot/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use std::{fs, io::Read, path::PathBuf};
use sui_framework::SystemPackage;
use sui_types::base_types::ObjectID;

pub type SnapshotManifest = BTreeMap<String, BTreeMap<u64, SingleSnapshot>>;
pub type SnapshotManifest = BTreeMap<u64, SingleSnapshot>;

#[derive(Serialize, Deserialize)]
pub struct SingleSnapshot {
Expand All @@ -25,21 +25,13 @@ pub fn load_bytecode_snapshot_manifest() -> SnapshotManifest {
.expect("Could not deserialize SnapshotManifest")
}

pub fn update_bytecode_snapshot_manifest(
network: &str,
git_revision: String,
version: u64,
files: Vec<ObjectID>,
) {
pub fn update_bytecode_snapshot_manifest(git_revision: &str, version: u64, files: Vec<ObjectID>) {
let mut snapshot = load_bytecode_snapshot_manifest();

let entry = snapshot
.entry(network.to_owned())
.or_insert_with(BTreeMap::new);
entry.insert(
snapshot.insert(
version,
SingleSnapshot {
git_revision,
git_revision: git_revision.to_string(),
package_ids: files,
},
);
Expand All @@ -49,21 +41,14 @@ pub fn update_bytecode_snapshot_manifest(
fs::write(manifest_path(), json).expect("Could not update manifest file");
}

pub fn load_bytecode_snapshot(
network: &str,
protocol_version: u64,
) -> anyhow::Result<Vec<SystemPackage>> {
pub fn load_bytecode_snapshot(protocol_version: u64) -> anyhow::Result<Vec<SystemPackage>> {
let mut snapshot_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
snapshot_path.extend([
"bytecode_snapshot",
network,
protocol_version.to_string().as_str(),
]);
let snapshot_objects: anyhow::Result<Vec<_>> = std::fs::read_dir(&snapshot_path)?
snapshot_path.extend(["bytecode_snapshot", protocol_version.to_string().as_str()]);
let snapshot_objects: anyhow::Result<Vec<_>> = fs::read_dir(&snapshot_path)?
.flatten()
.map(|entry| {
let file_name = entry.file_name().to_str().unwrap().to_string();
let mut file = std::fs::File::open(snapshot_path.clone().join(file_name))?;
let mut file = fs::File::open(snapshot_path.clone().join(file_name))?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
let package: SystemPackage = bcs::from_bytes(&buffer)?;
Expand All @@ -74,7 +59,5 @@ pub fn load_bytecode_snapshot(
}

fn manifest_path() -> PathBuf {
PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("bytecode_snapshot")
.join("manifest.json")
PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("manifest.json")
}
31 changes: 5 additions & 26 deletions crates/sui-framework-snapshot/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,43 +7,22 @@ use std::path::PathBuf;
use sui_framework::{BuiltInFramework, SystemPackage};
use sui_framework_snapshot::update_bytecode_snapshot_manifest;
use sui_protocol_config::ProtocolVersion;
use sui_types::software_version::GIT_REVISION;

fn main() {
let (network, git_version) = parse_args();
// Always generate snapshot for the latest version.
let version = ProtocolVersion::MAX.as_u64();
let mut files = vec![];
for package in BuiltInFramework::iter_system_packages() {
write_package_to_file(&network, version, package);
write_package_to_file(version, package);
files.push(*package.id());
}
update_bytecode_snapshot_manifest(&network, git_version, version, files);
update_bytecode_snapshot_manifest(GIT_REVISION, version, files);
}

/// Parse args and return network name and git revision.
fn parse_args() -> (String, String) {
let args: Vec<String> = env::args().collect();
if args.len() != 3 {
eprintln!("Usage: {} <devnet|testnet|mainnet> <git_version>", args[0]);
std::process::exit(1);
}

// Check if the argument is one of the allowed values
let allowed_values = ["devnet", "testnet", "mainnet"];
let arg = args[1].as_str();
if !allowed_values.contains(&arg) {
eprintln!(
"Error: argument must be one of {}",
allowed_values.join(", ")
);
std::process::exit(1);
}
(args[1].clone(), args[2].clone())
}

fn write_package_to_file(network: &str, version: u64, package: &SystemPackage) {
fn write_package_to_file(version: u64, package: &SystemPackage) {
let mut path = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
path.extend(["bytecode_snapshot", network, version.to_string().as_str()]);
path.extend(["bytecode_snapshot", version.to_string().as_str()]);
fs::create_dir_all(&path)
.or_else(|e| match e.kind() {
std::io::ErrorKind::AlreadyExists => Ok(()),
Expand Down
Loading

0 comments on commit 1328670

Please sign in to comment.