iota_framework_snapshot/
lib.rs1use std::{
6 collections::{BTreeMap, BTreeSet},
7 fs,
8 io::Read,
9 path::PathBuf,
10};
11
12use iota_framework::{SystemPackage, SystemPackageMetadata};
13use iota_types::{
14 IOTA_FRAMEWORK_PACKAGE_ID, IOTA_SYSTEM_PACKAGE_ID, MOVE_STDLIB_PACKAGE_ID, STARDUST_PACKAGE_ID,
15 base_types::ObjectID,
16};
17use serde::{Deserialize, Serialize};
18
19pub type SnapshotManifest = BTreeMap<u64, Snapshot>;
20
21#[derive(Serialize, Deserialize)]
35pub struct Snapshot {
36 pub git_revision: String,
38
39 pub packages: Vec<SnapshotPackage>,
41}
42
43#[derive(Serialize, Deserialize)]
46pub struct SnapshotPackage {
47 pub name: String,
49 pub path: String,
52 pub id: ObjectID,
54}
55
56impl Snapshot {
57 pub fn package_ids(&self) -> impl Iterator<Item = ObjectID> + '_ {
58 self.packages.iter().map(|p| p.id)
59 }
60}
61
62impl SnapshotPackage {
63 pub fn from_system_package_metadata(value: &SystemPackageMetadata) -> Self {
64 Self {
65 name: value.name.clone(),
66 path: value.path.clone(),
67 id: value.compiled.id,
68 }
69 }
70}
71
72const SYSTEM_PACKAGE_PUBLISH_ORDER: &[ObjectID] = &[
73 MOVE_STDLIB_PACKAGE_ID,
74 IOTA_FRAMEWORK_PACKAGE_ID,
75 IOTA_SYSTEM_PACKAGE_ID,
76 STARDUST_PACKAGE_ID,
77];
78
79pub fn get_system_package_publish_order(protocol_version: u64) -> Vec<ObjectID> {
82 let mut publish_order = SYSTEM_PACKAGE_PUBLISH_ORDER.to_vec();
83 if protocol_version < 9 {
84 publish_order.insert(3, iota_types::GENESIS_BRIDGE_PACKAGE_ID);
85 }
86 publish_order
87}
88
89pub fn load_bytecode_snapshot_manifest() -> SnapshotManifest {
90 let Ok(bytes) = fs::read(manifest_path()) else {
91 return SnapshotManifest::default();
92 };
93 serde_json::from_slice::<SnapshotManifest>(&bytes)
94 .expect("Could not deserialize SnapshotManifest")
95}
96
97pub fn update_bytecode_snapshot_manifest(
98 git_revision: &str,
99 version: u64,
100 files: Vec<SnapshotPackage>,
101) {
102 let mut snapshot = load_bytecode_snapshot_manifest();
103
104 snapshot.insert(
105 version,
106 Snapshot {
107 git_revision: git_revision.to_string(),
108 packages: files,
109 },
110 );
111
112 let json =
113 serde_json::to_string_pretty(&snapshot).expect("Could not serialize SnapshotManifest");
114 fs::write(manifest_path(), json).expect("Could not update manifest file");
115}
116
117pub fn load_bytecode_snapshot(protocol_version: u64) -> anyhow::Result<Vec<SystemPackage>> {
118 let snapshot_path = snapshot_path_for_version(protocol_version)?;
119 let mut snapshots: BTreeMap<ObjectID, SystemPackage> = fs::read_dir(&snapshot_path)?
120 .flatten()
121 .map(|entry| {
122 let file_name = entry.file_name().to_str().unwrap().to_string();
123 let mut file = fs::File::open(snapshot_path.clone().join(file_name))?;
124 let mut buffer = Vec::new();
125 file.read_to_end(&mut buffer)?;
126 let package: SystemPackage = bcs::from_bytes(&buffer)?;
127 Ok((package.id, package))
128 })
129 .collect::<anyhow::Result<_>>()?;
130
131 let snapshots_publish_order = get_system_package_publish_order(protocol_version);
133 assert!(snapshots.len() <= snapshots_publish_order.len());
134 let mut snapshot_objects = Vec::new();
135 for package_id in &snapshots_publish_order {
136 if let Some(object) = snapshots.remove(package_id) {
137 snapshot_objects.push(object);
138 }
139 }
140 Ok(snapshot_objects)
141}
142
143pub fn manifest_path() -> PathBuf {
144 PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("manifest.json")
145}
146
147fn snapshot_path_for_version(version: u64) -> anyhow::Result<PathBuf> {
156 let snapshot_dir = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("bytecode_snapshot");
157 let mut snapshots = BTreeSet::new();
158
159 for entry in fs::read_dir(&snapshot_dir)? {
160 let entry = entry?;
161 let path = entry.path();
162 if path.is_dir() {
163 if let Some(snapshot_number) = path
164 .file_name()
165 .and_then(|n| n.to_str())
166 .and_then(|n| n.parse::<u64>().ok())
167 {
168 snapshots.insert(snapshot_number);
169 }
170 }
171 }
172
173 snapshots
174 .range(version..)
175 .next()
176 .map(|v| snapshot_dir.join(v.to_string()))
177 .ok_or_else(|| anyhow::anyhow!("No snapshot found for version {}", version))
178}