@@ -36,7 +36,7 @@ use sp_core::{
3636 } ,
3737} ;
3838use sp_runtime:: {
39- traits:: { Block as BlockT , Hash , HashingFor } ,
39+ traits:: { Block as BlockT , HashingFor } ,
4040 StateVersion ,
4141} ;
4242use sp_state_machine:: TestExternalities ;
@@ -58,37 +58,39 @@ type ChildKeyValues = Vec<(ChildInfo, Vec<KeyValue>)>;
5858type SnapshotVersion = Compact < u16 > ;
5959
6060const LOG_TARGET : & str = "remote-ext" ;
61- const DEFAULT_HTTP_ENDPOINT : & str = "https://rpc. polkadot.io:443" ;
62- const SNAPSHOT_VERSION : SnapshotVersion = Compact ( 3 ) ;
61+ const DEFAULT_HTTP_ENDPOINT : & str = "https://polkadot-try-runtime-node.parity-chains.parity .io:443" ;
62+ const SNAPSHOT_VERSION : SnapshotVersion = Compact ( 4 ) ;
6363
6464/// The snapshot that we store on disk.
6565#[ derive( Decode , Encode ) ]
66- struct Snapshot < H > {
66+ struct Snapshot < B : BlockT > {
6767 snapshot_version : SnapshotVersion ,
6868 state_version : StateVersion ,
69- block_hash : H ,
7069 // <Vec<Key, (Value, MemoryDbRefCount)>>
7170 raw_storage : Vec < ( Vec < u8 > , ( Vec < u8 > , i32 ) ) > ,
72- storage_root : H ,
71+ // The storage root of the state. This may vary from the storage root in the header, if not the
72+ // entire state was fetched.
73+ storage_root : B :: Hash ,
74+ header : B :: Header ,
7375}
7476
75- impl < H : Decode > Snapshot < H > {
77+ impl < B : BlockT > Snapshot < B > {
7678 pub fn new (
7779 state_version : StateVersion ,
78- block_hash : H ,
7980 raw_storage : Vec < ( Vec < u8 > , ( Vec < u8 > , i32 ) ) > ,
80- storage_root : H ,
81+ storage_root : B :: Hash ,
82+ header : B :: Header ,
8183 ) -> Self {
8284 Self {
8385 snapshot_version : SNAPSHOT_VERSION ,
8486 state_version,
85- block_hash,
8687 raw_storage,
8788 storage_root,
89+ header,
8890 }
8991 }
9092
91- fn load ( path : & PathBuf ) -> Result < Snapshot < H > , & ' static str > {
93+ fn load ( path : & PathBuf ) -> Result < Snapshot < B > , & ' static str > {
9294 let bytes = fs:: read ( path) . map_err ( |_| "fs::read failed." ) ?;
9395 // The first item in the SCALE encoded struct bytes is the snapshot version. We decode and
9496 // check that first, before proceeding to decode the rest of the snapshot.
@@ -105,21 +107,21 @@ impl<H: Decode> Snapshot<H> {
105107
106108/// An externalities that acts exactly the same as [`sp_io::TestExternalities`] but has a few extra
107109/// bits and pieces to it, and can be loaded remotely.
108- pub struct RemoteExternalities < H : Hash > {
110+ pub struct RemoteExternalities < B : BlockT > {
109111 /// The inner externalities.
110- pub inner_ext : TestExternalities < H > ,
111- /// The block hash with which we created this externality env.
112- pub block_hash : H :: Out ,
112+ pub inner_ext : TestExternalities < HashingFor < B > > ,
113+ /// The block header which we created this externality env.
114+ pub header : B :: Header ,
113115}
114116
115- impl < H : Hash > Deref for RemoteExternalities < H > {
116- type Target = TestExternalities < H > ;
117+ impl < B : BlockT > Deref for RemoteExternalities < B > {
118+ type Target = TestExternalities < HashingFor < B > > ;
117119 fn deref ( & self ) -> & Self :: Target {
118120 & self . inner_ext
119121 }
120122}
121123
122- impl < H : Hash > DerefMut for RemoteExternalities < H > {
124+ impl < B : BlockT > DerefMut for RemoteExternalities < B > {
123125 fn deref_mut ( & mut self ) -> & mut Self :: Target {
124126 & mut self . inner_ext
125127 }
@@ -859,7 +861,7 @@ where
859861 }
860862}
861863
862- impl < B : BlockT + DeserializeOwned > Builder < B >
864+ impl < B : BlockT > Builder < B >
863865where
864866 B :: Hash : DeserializeOwned ,
865867 B :: Header : DeserializeOwned ,
@@ -1030,6 +1032,21 @@ where
10301032 Ok ( ( ) )
10311033 }
10321034
1035+ async fn load_header ( & self ) -> Result < B :: Header , & ' static str > {
1036+ let retry_strategy =
1037+ FixedInterval :: new ( Self :: KEYS_PAGE_RETRY_INTERVAL ) . take ( Self :: MAX_RETRIES ) ;
1038+ let get_header_closure = || {
1039+ ChainApi :: < ( ) , _ , B :: Header , ( ) > :: header (
1040+ self . as_online ( ) . rpc_client ( ) ,
1041+ Some ( self . as_online ( ) . at_expected ( ) ) ,
1042+ )
1043+ } ;
1044+ Retry :: spawn ( retry_strategy, get_header_closure)
1045+ . await
1046+ . map_err ( |_| "Failed to fetch header for block from network" ) ?
1047+ . ok_or ( "Network returned None block header" )
1048+ }
1049+
10331050 /// Load the data from a remote server. The main code path is calling into `load_top_remote` and
10341051 /// `load_child_remote`.
10351052 ///
@@ -1058,13 +1075,11 @@ where
10581075 // If we need to save a snapshot, save the raw storage and root hash to the snapshot.
10591076 if let Some ( path) = self . as_online ( ) . state_snapshot . clone ( ) . map ( |c| c. path ) {
10601077 let ( raw_storage, storage_root) = pending_ext. into_raw_snapshot ( ) ;
1061- let snapshot = Snapshot :: < B :: Hash > :: new (
1078+ let snapshot = Snapshot :: < B > :: new (
10621079 state_version,
1063- self . as_online ( )
1064- . at
1065- . expect ( "set to `Some` in `init_remote_client`; must be called before; qed" ) ,
10661080 raw_storage. clone ( ) ,
10671081 storage_root,
1082+ self . load_header ( ) . await ?,
10681083 ) ;
10691084 let encoded = snapshot. encode ( ) ;
10701085 log:: info!(
@@ -1086,22 +1101,21 @@ where
10861101 Ok ( pending_ext)
10871102 }
10881103
1089- async fn do_load_remote ( & mut self ) -> Result < RemoteExternalities < HashingFor < B > > , & ' static str > {
1104+ async fn do_load_remote ( & mut self ) -> Result < RemoteExternalities < B > , & ' static str > {
10901105 self . init_remote_client ( ) . await ?;
1091- let block_hash = self . as_online ( ) . at_expected ( ) ;
10921106 let inner_ext = self . load_remote_and_maybe_save ( ) . await ?;
1093- Ok ( RemoteExternalities { block_hash , inner_ext } )
1107+ Ok ( RemoteExternalities { header : self . load_header ( ) . await ? , inner_ext } )
10941108 }
10951109
10961110 fn do_load_offline (
10971111 & mut self ,
10981112 config : OfflineConfig ,
1099- ) -> Result < RemoteExternalities < HashingFor < B > > , & ' static str > {
1113+ ) -> Result < RemoteExternalities < B > , & ' static str > {
11001114 let mut sp = Spinner :: with_timer ( Spinners :: Dots , "Loading snapshot..." . into ( ) ) ;
11011115 let start = Instant :: now ( ) ;
11021116 info ! ( target: LOG_TARGET , "Loading snapshot from {:?}" , & config. state_snapshot. path) ;
1103- let Snapshot { snapshot_version : _, block_hash , state_version, raw_storage, storage_root } =
1104- Snapshot :: < B :: Hash > :: load ( & config. state_snapshot . path ) ?;
1117+ let Snapshot { snapshot_version : _, header , state_version, raw_storage, storage_root } =
1118+ Snapshot :: < B > :: load ( & config. state_snapshot . path ) ?;
11051119
11061120 let inner_ext = TestExternalities :: from_raw_snapshot (
11071121 raw_storage,
@@ -1110,12 +1124,10 @@ where
11101124 ) ;
11111125 sp. stop_with_message ( format ! ( "✅ Loaded snapshot ({:.2}s)" , start. elapsed( ) . as_secs_f32( ) ) ) ;
11121126
1113- Ok ( RemoteExternalities { inner_ext, block_hash } )
1127+ Ok ( RemoteExternalities { inner_ext, header } )
11141128 }
11151129
1116- pub ( crate ) async fn pre_build (
1117- mut self ,
1118- ) -> Result < RemoteExternalities < HashingFor < B > > , & ' static str > {
1130+ pub ( crate ) async fn pre_build ( mut self ) -> Result < RemoteExternalities < B > , & ' static str > {
11191131 let mut ext = match self . mode . clone ( ) {
11201132 Mode :: Offline ( config) => self . do_load_offline ( config) ?,
11211133 Mode :: Online ( _) => self . do_load_remote ( ) . await ?,
@@ -1154,7 +1166,7 @@ where
11541166}
11551167
11561168// Public methods
1157- impl < B : BlockT + DeserializeOwned > Builder < B >
1169+ impl < B : BlockT > Builder < B >
11581170where
11591171 B :: Hash : DeserializeOwned ,
11601172 B :: Header : DeserializeOwned ,
@@ -1191,7 +1203,7 @@ where
11911203 self
11921204 }
11931205
1194- pub async fn build ( self ) -> Result < RemoteExternalities < HashingFor < B > > , & ' static str > {
1206+ pub async fn build ( self ) -> Result < RemoteExternalities < B > , & ' static str > {
11951207 let mut ext = self . pre_build ( ) . await ?;
11961208 ext. commit_all ( ) . unwrap ( ) ;
11971209
@@ -1226,7 +1238,7 @@ mod tests {
12261238 init_logger ( ) ;
12271239 Builder :: < Block > :: new ( )
12281240 . mode ( Mode :: Offline ( OfflineConfig {
1229- state_snapshot : SnapshotConfig :: new ( "test_data/proxy_test " ) ,
1241+ state_snapshot : SnapshotConfig :: new ( "test_data/test.snap " ) ,
12301242 } ) )
12311243 . build ( )
12321244 . await
@@ -1241,7 +1253,7 @@ mod tests {
12411253 // get the first key from the snapshot file.
12421254 let some_key = Builder :: < Block > :: new ( )
12431255 . mode ( Mode :: Offline ( OfflineConfig {
1244- state_snapshot : SnapshotConfig :: new ( "test_data/proxy_test " ) ,
1256+ state_snapshot : SnapshotConfig :: new ( "test_data/test.snap " ) ,
12451257 } ) )
12461258 . build ( )
12471259 . await
@@ -1255,7 +1267,7 @@ mod tests {
12551267
12561268 Builder :: < Block > :: new ( )
12571269 . mode ( Mode :: Offline ( OfflineConfig {
1258- state_snapshot : SnapshotConfig :: new ( "test_data/proxy_test " ) ,
1270+ state_snapshot : SnapshotConfig :: new ( "test_data/test.snap " ) ,
12591271 } ) )
12601272 . blacklist_hashed_key ( & some_key)
12611273 . build ( )
@@ -1341,7 +1353,7 @@ mod remote_tests {
13411353 . await
13421354 . unwrap ( ) ;
13431355
1344- assert_eq ! ( ext. block_hash , cached_ext. block_hash ) ;
1356+ assert_eq ! ( ext. header . hash ( ) , cached_ext. header . hash ( ) ) ;
13451357 }
13461358
13471359 #[ tokio:: test]
0 commit comments