@@ -112,6 +112,34 @@ fn to_confirmed_transaction<N: Network>(
112112 }
113113}
114114
115+ pub ( crate ) fn block_tree_cache_path < N : Network , B : BlockStorage < N > > ( storage : & B ) -> Option < std:: path:: PathBuf > {
116+ #[ cfg( feature = "rocks" ) ]
117+ {
118+ let mut path = aleo_ledger_dir ( N :: ID , storage. storage_mode ( ) ) ;
119+ path. push ( "block_tree" ) ;
120+ Some ( path)
121+ }
122+ #[ cfg( not( feature = "rocks" ) ) ]
123+ {
124+ let _ = storage;
125+ None
126+ }
127+ }
128+
129+ fn missing_block_in_tree_error ( height : u32 , block_tree_cache_path : Option < & std:: path:: Path > ) -> String {
130+ match block_tree_cache_path {
131+ Some ( path) => format ! (
132+ "Block {height} exists in tree but not in storage;\
133+ perhaps you used a wrong block tree cache file at '{}'?",
134+ path. display( )
135+ ) ,
136+ None => format ! (
137+ "Block {height} exists in tree but not in storage;\
138+ perhaps you used a wrong block tree cache file?"
139+ ) ,
140+ }
141+ }
142+
115143/// A trait for block storage.
116144pub trait BlockStorage < N : Network > : ' static + Clone + Send + Sync {
117145 /// The mapping of `block height` to `state root`.
@@ -1038,6 +1066,7 @@ impl<N: Network, B: BlockStorage<N>> BlockStore<N, B> {
10381066 let storage = B :: open ( storage) ?;
10391067
10401068 let tree = storage. create_block_tree ( ) ?;
1069+ let block_tree_cache_path = block_tree_cache_path :: < N , _ > ( & storage) ;
10411070
10421071 let mut initial_cache = Vec :: new ( ) ;
10431072 let cache_end_height = u32:: try_from ( tree. number_of_leaves ( ) ) ?;
@@ -1050,12 +1079,10 @@ impl<N: Network, B: BlockStorage<N>> BlockStore<N, B> {
10501079 }
10511080
10521081 // Get the hash for the next block to add to the cache.
1053- let hash = storage. id_map ( ) . get_confirmed ( & height) ?. with_context ( || {
1054- format ! (
1055- "Block {height} exists in tree but not in storage;\
1056- perhaps you used a wrong block tree cache file?"
1057- )
1058- } ) ?;
1082+ let hash = storage
1083+ . id_map ( )
1084+ . get_confirmed ( & height) ?
1085+ . with_context ( || missing_block_in_tree_error ( height, block_tree_cache_path. as_deref ( ) ) ) ?;
10591086
10601087 initial_cache. push (
10611088 storage. get_block ( & hash) ?. with_context ( || format ! ( "Block {hash} exists in tree but not in storage" ) ) ?,
@@ -1231,8 +1258,9 @@ impl<N: Network, B: BlockStorage<N>> BlockStore<N, B> {
12311258 #[ cfg( feature = "rocks" ) ]
12321259 pub fn cache_block_tree ( & self ) -> Result < ( ) > {
12331260 // Prepare the path for the target file.
1234- let mut path = aleo_ledger_dir ( N :: ID , self . storage . storage_mode ( ) ) ;
1235- path. push ( "block_tree" ) ;
1261+ let Some ( path) = block_tree_cache_path :: < N , _ > ( & self . storage ) else {
1262+ bail ! ( "Failed to determine the block tree cache path" ) ;
1263+ } ;
12361264
12371265 // Create the target file.
12381266 let file = fs:: File :: create ( & path) ?;
@@ -1563,6 +1591,7 @@ impl<N: Network, B: BlockStorage<N>> BlockStore<N, B> {
15631591mod tests {
15641592 use super :: * ;
15651593 use crate :: helpers:: memory:: BlockMemory ;
1594+ use std:: path:: Path ;
15661595
15671596 type CurrentNetwork = console:: network:: MainnetV0 ;
15681597
@@ -1763,4 +1792,13 @@ mod tests {
17631792 assert_ne ! ( txn1, txn3) ;
17641793 assert_eq ! ( txn3, txn4) ;
17651794 }
1795+
1796+ #[ test]
1797+ fn test_missing_block_in_tree_error_includes_block_tree_path ( ) {
1798+ let error = missing_block_in_tree_error ( 42 , Some ( Path :: new ( "/tmp/snarkvm/ledger/block_tree" ) ) ) ;
1799+
1800+ assert ! ( error. contains( "Block 42 exists in tree but not in storage" ) ) ;
1801+ assert ! ( error. contains( "wrong block tree cache file" ) ) ;
1802+ assert ! ( error. contains( "/tmp/snarkvm/ledger/block_tree" ) ) ;
1803+ }
17661804}
0 commit comments