@@ -43,7 +43,11 @@ use serde::{Deserialize, Serialize};
4343use sha2:: Sha256 ;
4444use std:: convert:: Infallible ;
4545use std:: fs:: File ;
46- use std:: { collections:: VecDeque , path:: PathBuf , sync:: LazyLock } ;
46+ use std:: {
47+ collections:: VecDeque ,
48+ path:: { Path , PathBuf } ,
49+ sync:: LazyLock ,
50+ } ;
4751use tokio:: sync:: broadcast:: { self , Receiver as Subscriber } ;
4852
4953const HEAD_CHANNEL_CAPACITY : usize = 10 ;
@@ -286,6 +290,25 @@ impl RpcMethod<1> for ForestChainExport {
286290 ( params, ) : Self :: Params ,
287291 _: & http:: Extensions ,
288292 ) -> Result < Self :: Ok , ServerError > {
293+ fn save_checksum (
294+ checksum : digest:: Output < Sha256 > ,
295+ snapshot_output_path : & Path ,
296+ ) -> anyhow:: Result < ( ) > {
297+ let path = forest_car_sha256sum_path ( snapshot_output_path) ;
298+ std:: fs:: write (
299+ path,
300+ format ! (
301+ "{} {}\n " ,
302+ checksum. encode_hex:: <String >( ) ,
303+ snapshot_output_path
304+ . file_name( )
305+ . and_then( std:: ffi:: OsStr :: to_str)
306+ . context( "Failed to retrieve file name while saving checksum" ) ?
307+ ) ,
308+ ) ?;
309+ Ok ( ( ) )
310+ }
311+
289312 // Spawn a task so it's not cancelled when CLI client is disconnected
290313 let handle = tokio:: spawn ( async move {
291314 let ForestChainExportParams {
@@ -324,39 +347,16 @@ impl RpcMethod<1> for ForestChainExport {
324347 } else {
325348 tokio_util:: either:: Either :: Right ( tokio:: fs:: File :: create ( & tmp_path) . await ?)
326349 } ;
327- let result = match version {
328- FilecoinSnapshotVersion :: V1 => {
329- let db = ctx. db_owned ( ) ;
330-
331- let chain_export = crate :: chain:: export :: < Sha256 , _ > (
332- & db,
333- & start_ts,
334- recent_roots,
335- writer,
336- options,
337- ) ;
338-
339- tokio:: select! {
340- result = chain_export => {
341- if let Some ( checksum) = result? {
342- let path = forest_car_sha256sum_path( & output_path) ;
343- std:: fs:: write( path, format!( "{} {}\n " ,
344- checksum. encode_hex:: <String >( ) ,
345- output_path. file_name( ) . and_then( std:: ffi:: OsStr :: to_str)
346- . context( "Failed to retrieve file name while saving checksum" ) ?) ) ?;
347- }
348- tmp_path. persist( & output_path) ?;
349- } ,
350- _ = chain_export_guard. cancellation_token( ) . cancelled( ) => {
351- chain_export_guard. cancel_export( ) ;
352- tracing:: warn!( "Snapshot export was cancelled" ) ;
353- Ok ( ApiExportResult :: Cancelled )
354- } ,
355- }
356- }
350+ let chain_export = match version {
351+ FilecoinSnapshotVersion :: V1 => crate :: chain:: export :: < Sha256 , _ > (
352+ ctx. db ( ) ,
353+ & start_ts,
354+ recent_roots,
355+ writer,
356+ options,
357+ )
358+ . boxed ( ) ,
357359 FilecoinSnapshotVersion :: V2 => {
358- let db = ctx. db_owned ( ) ;
359-
360360 let f3_snap_tmp_path = {
361361 let mut f3_snap_dir = output_path. clone ( ) ;
362362 let mut builder = tempfile:: Builder :: new ( ) ;
@@ -379,37 +379,31 @@ impl RpcMethod<1> for ForestChainExport {
379379 }
380380 }
381381 } ;
382-
383- let chain_export = crate :: chain:: export_v2 :: < Sha256 , _ , _ > (
384- & db,
382+ crate :: chain:: export_v2 :: < Sha256 , _ , _ > (
383+ ctx. db ( ) ,
385384 f3_snap,
386385 & start_ts,
387386 recent_roots,
388387 writer,
389388 options,
390- ) ;
391-
392- tokio:: select! {
393- result = chain_export => {
394- if let Some ( checksum) = result? {
395- let path = forest_car_sha256sum_path( & output_path) ;
396- std:: fs:: write( path, format!( "{} {}\n " ,
397- checksum. encode_hex:: <String >( ) ,
398- output_path. file_name( ) . and_then( std:: ffi:: OsStr :: to_str)
399- . context( "Failed to retrieve file name while saving checksum" ) ?) ) ?;
400- }
401- tmp_path. persist( & output_path) ?;
402- Ok ( ApiExportResult :: Done )
403- } ,
404- _ = chain_export_guard. cancellation_token( ) . cancelled( ) => {
405- chain_export_guard. cancel_export( ) ;
406- tracing:: warn!( "Snapshot export was cancelled" ) ;
407- Ok ( ApiExportResult :: Cancelled )
408- } ,
409- }
389+ )
390+ . boxed ( )
410391 }
411392 } ;
412- anyhow:: Ok ( result?)
393+ tokio:: select! {
394+ result = chain_export => {
395+ if let Some ( checksum) = result? {
396+ save_checksum( checksum, & output_path) ?;
397+ }
398+ tmp_path. persist( & output_path) ?;
399+ anyhow:: Ok ( ApiExportResult :: Done )
400+ } ,
401+ _ = chain_export_guard. cancellation_token( ) . cancelled( ) => {
402+ chain_export_guard. cancel_export( ) ;
403+ tracing:: warn!( "Snapshot export was cancelled" ) ;
404+ anyhow:: Ok ( ApiExportResult :: Cancelled )
405+ } ,
406+ }
413407 } ) ;
414408 Ok ( handle. await ??)
415409 }
0 commit comments