@@ -26,13 +26,17 @@ use anyhow::{anyhow, ensure, Result};
26
26
use aptos_infallible:: Mutex ;
27
27
use aptos_logger:: prelude:: * ;
28
28
use aptos_types:: {
29
+ access_path:: Path ,
29
30
ledger_info:: LedgerInfoWithSignatures ,
30
31
proof:: TransactionInfoWithProof ,
31
32
state_store:: { state_key:: StateKey , state_value:: StateValue } ,
32
33
transaction:: Version ,
33
34
} ;
35
+ use aptos_vm:: move_vm_ext:: verifier_config;
34
36
use clap:: Parser ;
35
37
use futures:: { stream, TryStreamExt } ;
38
+ use move_binary_format:: CompiledModule ;
39
+ use move_bytecode_verifier:: verify_module_with_config;
36
40
use std:: sync:: Arc ;
37
41
use storage_interface:: StateSnapshotReceiver ;
38
42
use tokio:: time:: Instant ;
@@ -43,6 +47,8 @@ pub struct StateSnapshotRestoreOpt {
43
47
pub manifest_handle : FileHandle ,
44
48
#[ clap( long = "state-into-version" ) ]
45
49
pub version : Version ,
50
+ #[ clap( long) ]
51
+ pub validate_modules : bool ,
46
52
}
47
53
48
54
pub struct StateSnapshotRestoreController {
@@ -56,6 +62,7 @@ pub struct StateSnapshotRestoreController {
56
62
target_version : Version ,
57
63
epoch_history : Option < Arc < EpochHistory > > ,
58
64
concurrent_downloads : usize ,
65
+ validate_modules : bool ,
59
66
}
60
67
61
68
impl StateSnapshotRestoreController {
@@ -73,6 +80,7 @@ impl StateSnapshotRestoreController {
73
80
target_version : global_opt. target_version ,
74
81
epoch_history,
75
82
concurrent_downloads : global_opt. concurrent_downloads ,
83
+ validate_modules : opt. validate_modules ,
76
84
}
77
85
}
78
86
@@ -186,6 +194,9 @@ impl StateSnapshotRestoreController {
186
194
. with_label_values ( & [ "add_state_chunk" ] )
187
195
. start_timer ( ) ;
188
196
let receiver = receiver. clone ( ) ;
197
+ if self . validate_modules {
198
+ Self :: validate_modules ( & blobs) ;
199
+ }
189
200
tokio:: task:: spawn_blocking ( move || {
190
201
receiver. lock ( ) . as_mut ( ) . unwrap ( ) . add_chunk ( blobs, proof)
191
202
} )
@@ -207,6 +218,23 @@ impl StateSnapshotRestoreController {
207
218
Ok ( ( ) )
208
219
}
209
220
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
+
210
238
async fn read_state_value (
211
239
storage : & Arc < dyn BackupStorage > ,
212
240
file_handle : FileHandle ,
0 commit comments