Skip to content

Commit 706c993

Browse files
committed
[replay-verify] Add an option to re-validate all move modules in the snapshot.
1 parent 1118252 commit 706c993

File tree

11 files changed

+60
-9
lines changed

11 files changed

+60
-9
lines changed

Cargo.lock

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aptos-move/aptos-vm/src/move_vm_ext/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,6 @@ mod vm;
1010
pub use crate::move_vm_ext::{
1111
resolver::MoveResolverExt,
1212
session::{SessionExt, SessionId, SessionOutput},
13+
vm::verifier_config,
1314
vm::MoveVmExt,
1415
};

aptos-move/aptos-vm/src/move_vm_ext/vm.rs

+16-9
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,17 @@ impl MoveVmExt {
3030
treat_friend_as_private: bool,
3131
chain_id: u8,
3232
) -> VMResult<Self> {
33+
let mut config = verifier_config();
34+
config.treat_friend_as_private = treat_friend_as_private;
35+
3336
Ok(Self {
3437
inner: MoveVM::new_with_configs(
3538
aptos_natives(
3639
native_gas_params,
3740
abs_val_size_gas_params,
3841
gas_feature_version,
3942
),
40-
VerifierConfig {
41-
max_loop_depth: Some(5),
42-
treat_friend_as_private,
43-
max_generic_instantiation_length: Some(32),
44-
max_function_parameters: Some(128),
45-
max_basic_blocks: Some(1024),
46-
max_value_stack_size: 1024,
47-
max_type_nodes: Some(256),
48-
},
43+
config,
4944
crate::AptosVM::get_runtime_config(),
5045
)?,
5146
chain_id,
@@ -96,3 +91,15 @@ impl Deref for MoveVmExt {
9691
&self.inner
9792
}
9893
}
94+
95+
pub fn verifier_config() -> VerifierConfig {
96+
VerifierConfig {
97+
max_loop_depth: Some(5),
98+
treat_friend_as_private: false,
99+
max_generic_instantiation_length: Some(32),
100+
max_function_parameters: Some(128),
101+
max_basic_blocks: Some(1024),
102+
max_value_stack_size: 1024,
103+
max_type_nodes: Some(256),
104+
}
105+
}

storage/backup/backup-cli/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ storage-interface = { workspace = true }
4747
tokio = { workspace = true }
4848
tokio-stream = { workspace = true }
4949
tokio-util = { workspace = true }
50+
move-binary-format = { workspace = true }
51+
move-bytecode-verifier = { workspace = true }
5052

5153
[dev-dependencies]
5254
aptos-config = { workspace = true }

storage/backup/backup-cli/src/backup_types/state_snapshot/restore.rs

+28
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,17 @@ use anyhow::{anyhow, ensure, Result};
2626
use aptos_infallible::Mutex;
2727
use aptos_logger::prelude::*;
2828
use aptos_types::{
29+
access_path::Path,
2930
ledger_info::LedgerInfoWithSignatures,
3031
proof::TransactionInfoWithProof,
3132
state_store::{state_key::StateKey, state_value::StateValue},
3233
transaction::Version,
3334
};
35+
use aptos_vm::move_vm_ext::verifier_config;
3436
use clap::Parser;
3537
use futures::{stream, TryStreamExt};
38+
use move_binary_format::CompiledModule;
39+
use move_bytecode_verifier::verify_module_with_config;
3640
use std::sync::Arc;
3741
use storage_interface::StateSnapshotReceiver;
3842
use tokio::time::Instant;
@@ -43,6 +47,8 @@ pub struct StateSnapshotRestoreOpt {
4347
pub manifest_handle: FileHandle,
4448
#[clap(long = "state-into-version")]
4549
pub version: Version,
50+
#[clap(long)]
51+
pub validate_modules: bool,
4652
}
4753

4854
pub struct StateSnapshotRestoreController {
@@ -56,6 +62,7 @@ pub struct StateSnapshotRestoreController {
5662
target_version: Version,
5763
epoch_history: Option<Arc<EpochHistory>>,
5864
concurrent_downloads: usize,
65+
validate_modules: bool,
5966
}
6067

6168
impl StateSnapshotRestoreController {
@@ -73,6 +80,7 @@ impl StateSnapshotRestoreController {
7380
target_version: global_opt.target_version,
7481
epoch_history,
7582
concurrent_downloads: global_opt.concurrent_downloads,
83+
validate_modules: opt.validate_modules,
7684
}
7785
}
7886

@@ -186,6 +194,9 @@ impl StateSnapshotRestoreController {
186194
.with_label_values(&["add_state_chunk"])
187195
.start_timer();
188196
let receiver = receiver.clone();
197+
if self.validate_modules {
198+
Self::validate_modules(&blobs);
199+
}
189200
tokio::task::spawn_blocking(move || {
190201
receiver.lock().as_mut().unwrap().add_chunk(blobs, proof)
191202
})
@@ -207,6 +218,23 @@ impl StateSnapshotRestoreController {
207218
Ok(())
208219
}
209220

221+
fn validate_modules(blob: &[(StateKey, StateValue)]) {
222+
let config = verifier_config();
223+
for (key, value) in blob {
224+
if let StateKey::AccessPath(p) = key {
225+
if let Path::Code(module_id) = p.get_path() {
226+
if let Ok(module) = CompiledModule::deserialize(value.bytes()) {
227+
if let Err(err) = verify_module_with_config(&config, &module) {
228+
error!("Module {:?} failed validation: {:?}", module_id, err);
229+
}
230+
} else {
231+
error!("Module {:?} failed to deserialize", module_id);
232+
}
233+
}
234+
}
235+
}
236+
}
237+
210238
async fn read_state_value(
211239
storage: &Arc<dyn BackupStorage>,
212240
file_handle: FileHandle,

storage/backup/backup-cli/src/backup_types/state_snapshot/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ fn end_to_end() {
7676
StateSnapshotRestoreOpt {
7777
manifest_handle,
7878
version,
79+
validate_modules: false,
7980
},
8081
GlobalRestoreOpt {
8182
dry_run: false,

storage/backup/backup-cli/src/backup_types/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ fn test_end_to_end_impl(d: TestData) {
133133
StateSnapshotRestoreOpt {
134134
manifest_handle: state_snapshot_manifest.unwrap(),
135135
version,
136+
validate_modules: false,
136137
},
137138
global_restore_opt.clone(),
138139
Arc::clone(&store),

storage/backup/backup-cli/src/bin/replay-verify.rs

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ struct Opt {
4646
in the backup). [Defaults to the latest version available] "
4747
)]
4848
end_version: Option<Version>,
49+
#[clap(long)]
50+
validate_modules: bool,
4951
}
5052

5153
#[tokio::main]
@@ -79,6 +81,7 @@ async fn main_impl() -> Result<()> {
7981
restore_handler,
8082
opt.start_version.unwrap_or(0),
8183
opt.end_version.unwrap_or(Version::MAX),
84+
opt.validate_modules,
8285
)?
8386
.run()
8487
.await

storage/backup/backup-cli/src/coordinators/replay_verify.rs

+4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ pub struct ReplayVerifyCoordinator {
2727
restore_handler: RestoreHandler,
2828
start_version: Version,
2929
end_version: Version,
30+
validate_modules: bool,
3031
}
3132

3233
impl ReplayVerifyCoordinator {
@@ -39,6 +40,7 @@ impl ReplayVerifyCoordinator {
3940
restore_handler: RestoreHandler,
4041
start_version: Version,
4142
end_version: Version,
43+
validate_modules: bool,
4244
) -> Result<Self> {
4345
Ok(Self {
4446
storage,
@@ -49,6 +51,7 @@ impl ReplayVerifyCoordinator {
4951
restore_handler,
5052
start_version,
5153
end_version,
54+
validate_modules,
5255
})
5356
}
5457

@@ -112,6 +115,7 @@ impl ReplayVerifyCoordinator {
112115
StateSnapshotRestoreOpt {
113116
manifest_handle: backup.manifest,
114117
version: backup.version,
118+
validate_modules: self.validate_modules,
115119
},
116120
global_opt.clone(),
117121
Arc::clone(&self.storage),

storage/backup/backup-cli/src/coordinators/restore.rs

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ impl RestoreCoordinator {
170170
StateSnapshotRestoreOpt {
171171
manifest_handle: state_snapshot_backup.manifest,
172172
version,
173+
validate_modules: false,
173174
},
174175
self.global_opt.clone(),
175176
Arc::clone(&self.storage),

storage/backup/backup-cli/src/coordinators/verify.rs

+1
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ impl VerifyCoordinator {
100100
StateSnapshotRestoreOpt {
101101
manifest_handle: backup.manifest,
102102
version: backup.version,
103+
validate_modules: false,
103104
},
104105
global_opt.clone(),
105106
Arc::clone(&self.storage),

0 commit comments

Comments
 (0)