@@ -53,6 +53,7 @@ use fvm_ipld_blockstore::Blockstore;
5353use indicatif:: ProgressIterator ;
5454use itertools:: Itertools ;
5555use sha2:: Sha256 ;
56+ use std:: ops:: Range ;
5657use std:: path:: PathBuf ;
5758use std:: sync:: Arc ;
5859use tokio:: io:: { AsyncWriteExt , BufWriter } ;
@@ -138,7 +139,7 @@ impl ArchiveCommands {
138139 Self :: Info { snapshot } => {
139140 println ! (
140141 "{}" ,
141- ArchiveInfo :: from_store( AnyCar :: try_from( snapshot. as_path( ) ) ?) ?
142+ ArchiveInfo :: from_store( & AnyCar :: try_from( snapshot. as_path( ) ) ?) ?
142143 ) ;
143144 Ok ( ( ) )
144145 }
@@ -179,6 +180,7 @@ impl ArchiveCommands {
179180 depth,
180181 } => show_tipset_diff ( snapshot_files, epoch, depth) . await ,
181182 Self :: SyncBucket { snapshot_files } => sync_bucket ( snapshot_files) . await ,
183+ }
182184 }
183185}
184186
@@ -213,15 +215,15 @@ impl std::fmt::Display for ArchiveInfo {
213215impl ArchiveInfo {
214216 // Scan a CAR archive to identify which network it belongs to and how many
215217 // tipsets/messages are available. Progress is rendered to stdout.
216- fn from_store ( store : AnyCar < impl RandomAccessFileReader > ) -> anyhow:: Result < Self > {
218+ fn from_store ( store : & AnyCar < impl RandomAccessFileReader > ) -> anyhow:: Result < Self > {
217219 Self :: from_store_with ( store, true )
218220 }
219221
220222 // Scan a CAR archive to identify which network it belongs to and how many
221223 // tipsets/messages are available. Progress is optionally rendered to
222224 // stdout.
223225 fn from_store_with (
224- store : AnyCar < impl RandomAccessFileReader > ,
226+ store : & AnyCar < impl RandomAccessFileReader > ,
225227 progress : bool ,
226228 ) -> anyhow:: Result < Self > {
227229 let root = store. heaviest_tipset ( ) ?;
@@ -299,6 +301,10 @@ impl ArchiveInfo {
299301 root,
300302 } )
301303 }
304+
305+ fn epoch_range ( & self ) -> Range < ChainEpoch > {
306+ self . tipsets ..self . epoch
307+ }
302308}
303309
304310// Print a mapping of epochs to block headers in yaml format. This mapping can
@@ -592,12 +598,49 @@ async fn show_tipset_diff(
592598// bucket.
593599async fn sync_bucket ( snapshot_files : Vec < PathBuf > ) -> anyhow:: Result < ( ) > {
594600 // Compute the range of epochs that are covered by the input snapshot files.
595- let store = ManyCar :: try_from ( snapshot_files) ?;
596- let heaviest_tipset = store. heaviest_tipset ( ) ?;
597- let genesis = heaviest_tipset. genesis ( & store) ?;
598- let network = NetworkChain :: from_genesis_or_devnet_placeholder ( genesis. cid ( ) ) ;
599-
601+ let infos = snapshot_files
602+ . iter ( )
603+ . map ( |snapshot_file| {
604+ let store = AnyCar :: try_from ( snapshot_file. as_path ( ) ) ?;
605+ let info = ArchiveInfo :: from_store ( & store) ?;
606+ Ok ( info)
607+ } )
608+ . collect :: < anyhow:: Result < Vec < ArchiveInfo > > > ( ) ?;
609+
610+ let first_info = infos. first ( ) . context ( "no snapshot files provided" ) ?;
611+ let network = & first_info. network ;
612+
613+ for info in & infos {
614+ if & info. network != network {
615+ bail ! (
616+ "Snapshot files are from different networks, {} != {}" ,
617+ network,
618+ info. network
619+ ) ;
620+ }
621+ }
600622
623+ let mut ranges = infos
624+ . iter ( )
625+ . map ( |info| info. epoch_range ( ) )
626+ . collect :: < Vec < _ > > ( ) ;
627+ ranges. sort_by_key ( |range| range. end ) ;
628+ let mut merged_range = ranges. first ( ) . cloned ( ) . expect ( "No ranges to merge" ) ;
629+ for range in & ranges[ 1 ..] {
630+ if !merged_range. contains ( & range. end ) {
631+ bail ! (
632+ "Gap detected between ranges {:?} and {:?}" ,
633+ merged_range,
634+ range
635+ ) ;
636+ }
637+ merged_range. start = range. start ;
638+ }
639+ println ! ( "Network: {}" , network) ;
640+ println ! (
641+ "Merged Range: {} to {}" ,
642+ merged_range. start, merged_range. end
643+ ) ;
601644 Ok ( ( ) )
602645}
603646
@@ -646,7 +689,7 @@ mod tests {
646689 #[ test]
647690 fn archive_info_calibnet ( ) {
648691 let info = ArchiveInfo :: from_store_with (
649- AnyCar :: try_from ( calibnet:: DEFAULT_GENESIS ) . unwrap ( ) ,
692+ & AnyCar :: try_from ( calibnet:: DEFAULT_GENESIS ) . unwrap ( ) ,
650693 false ,
651694 )
652695 . unwrap ( ) ;
@@ -657,7 +700,7 @@ mod tests {
657700 #[ test]
658701 fn archive_info_mainnet ( ) {
659702 let info = ArchiveInfo :: from_store_with (
660- AnyCar :: try_from ( mainnet:: DEFAULT_GENESIS ) . unwrap ( ) ,
703+ & AnyCar :: try_from ( mainnet:: DEFAULT_GENESIS ) . unwrap ( ) ,
661704 false ,
662705 )
663706 . unwrap ( ) ;
0 commit comments