@@ -745,10 +745,35 @@ impl<M: Memory + Clone> Storage<M> {
745745 Ok ( ( ) )
746746 }
747747
748+ /// Reads the data of the specified anchor from legacy stable memory.
749+ fn read_legacy ( & self , anchor_number : AnchorNumber ) -> Result < Anchor , StorageError > {
750+ // Read fixed 4KB anchor
751+ let record_number = self . anchor_number_to_record_number ( anchor_number) ?;
752+
753+ let address = self . record_address ( record_number) ;
754+
755+ let mut reader = Reader :: new ( & self . anchor_memory , address) ;
756+ let mut buf = vec ! [ 0 ; self . header. entry_size as usize ] ;
757+
758+ reader. read_exact ( & mut buf) . expect ( "failed to read memory" ) ;
759+
760+ // Anchors that are allocated but have never been written to, due to a previously missing
761+ // allocation cleanup implementation, are handled as if they don't exist.
762+ if buf. iter ( ) . all ( |& b| b == 0 ) {
763+ return Err ( StorageError :: AnchorNotFound { anchor_number } ) ;
764+ }
765+
766+ // Read unbounded stable structures anchor
767+ let storable_fixed_anchor = StorableFixedAnchor :: from_bytes ( Cow :: Owned ( buf) ) ;
768+
769+ Ok ( Anchor :: from ( ( anchor_number, storable_fixed_anchor, None ) ) )
770+ }
771+
748772 /// Reads the data of the specified anchor from stable memory.
749773 pub fn read ( & self , anchor_number : AnchorNumber ) -> Result < Anchor , StorageError > {
750774 let record_number = self . anchor_number_to_record_number ( anchor_number) ?;
751775
776+ // This value is no longer used for reading, but we keep the check for consistency.
752777 let num_anchors = self . header . num_anchors ;
753778
754779 if record_number >= num_anchors {
@@ -763,7 +788,11 @@ impl<M: Memory + Clone> Storage<M> {
763788 }
764789
765790 let Some ( storable_anchor) = self . stable_anchor_memory . get ( & anchor_number) else {
766- return Err ( StorageError :: AnchorNotFound { anchor_number } ) ;
791+ ic_cdk:: println!(
792+ "Falling back to legacy read for anchor number {}" ,
793+ anchor_number
794+ ) ;
795+ return self . read_legacy ( anchor_number) ;
767796 } ;
768797
769798 Ok ( Anchor :: from ( ( anchor_number, storable_anchor) ) )
0 commit comments