@@ -445,57 +445,61 @@ func (sm *SyncManager) writeSubtree(ctx context.Context, block *bsvutil.Block, s
445445 return nil
446446 })
447447
448- // if we are not in quickValidationMode, we don't need to store the subtree meta data
449- // it will be stored by the subtree validation service
450- if quickValidationMode {
451- g .Go (func () error {
452- subtreeBytes , err := subtreeMetaData . Serialize ()
453- if err != nil {
454- return errors . NewStorageError ( "[writeSubtree][%s] failed to serialize subtree data" , subtree . RootHash (). String (), err )
455- }
448+ // Always store subtree meta data - even when not in quickValidationMode, we need to ensure
449+ // metadata exists because checkSubtreeFromBlock may return early if the subtree already exists
450+ // (e.g., created by block assembly) without creating the metadata
451+ g .Go (func () error {
452+ // Check if metadata already exists (e.g., came in via P2P) to avoid unnecessary work
453+ if exists , _ := sm . subtreeStore . Exists ( gCtx , subtreeData . RootHash ()[:], fileformat . FileTypeSubtreeMeta ); exists {
454+ return nil
455+ }
456456
457- dah := uint32 (block .Height ()) + sm .settings .GlobalBlockHeightRetention // nolint: gosec
457+ subtreeBytes , err := subtreeMetaData .Serialize ()
458+ if err != nil {
459+ return errors .NewStorageError ("[writeSubtree][%s] failed to serialize subtree data" , subtree .RootHash ().String (), err )
460+ }
458461
459- storer , err := filestorer .NewFileStorer (
460- gCtx ,
461- sm .logger ,
462- sm .settings ,
463- sm .subtreeStore ,
464- subtreeData .RootHash ()[:],
465- fileformat .FileTypeSubtreeMeta ,
466- options .WithDeleteAt (dah ),
467- )
468- if err != nil {
469- if errors .Is (err , errors .ErrBlobAlreadyExists ) {
470- return nil
471- }
462+ dah := uint32 (block .Height ()) + sm .settings .GlobalBlockHeightRetention // nolint: gosec
472463
473- return errors .NewStorageError ("[writeSubtree][%s] failed to store subtree meta data" , subtree .RootHash ().String (), err )
464+ storer , err := filestorer .NewFileStorer (
465+ gCtx ,
466+ sm .logger ,
467+ sm .settings ,
468+ sm .subtreeStore ,
469+ subtreeData .RootHash ()[:],
470+ fileformat .FileTypeSubtreeMeta ,
471+ options .WithDeleteAt (dah ),
472+ )
473+ if err != nil {
474+ if errors .Is (err , errors .ErrBlobAlreadyExists ) {
475+ return nil
474476 }
475477
476- // Track whether write succeeded to determine whether to close or abort
477- var writeSucceeded bool
478- defer func () {
479- if ! writeSucceeded {
480- storer .Abort (errors .NewProcessingError ("[writeSubtree] write failed for subtree meta %s" , subtree .RootHash ().String ()))
481- }
482- }()
483-
484- // TODO Write header extra - , *subtree.RootHash(), uint32(block.Height())
478+ return errors .NewStorageError ("[writeSubtree][%s] failed to store subtree meta data" , subtree .RootHash ().String (), err )
479+ }
485480
486- if _ , err = storer .Write (subtreeBytes ); err != nil {
487- return errors .NewStorageError ("error writing subtree meta to disk" , err )
481+ // Track whether write succeeded to determine whether to close or abort
482+ var writeSucceeded bool
483+ defer func () {
484+ if ! writeSucceeded {
485+ storer .Abort (errors .NewProcessingError ("[writeSubtree] write failed for subtree meta %s" , subtree .RootHash ().String ()))
488486 }
487+ }()
489488
490- if err = storer .Close (gCtx ); err != nil {
491- return errors .NewStorageError ("error closing subtree meta file" , err )
492- }
489+ // TODO Write header extra - , *subtree.RootHash(), uint32(block.Height())
493490
494- writeSucceeded = true
491+ if _ , err = storer .Write (subtreeBytes ); err != nil {
492+ return errors .NewStorageError ("error writing subtree meta to disk" , err )
493+ }
495494
496- return nil
497- })
498- }
495+ if err = storer .Close (gCtx ); err != nil {
496+ return errors .NewStorageError ("error closing subtree meta file" , err )
497+ }
498+
499+ writeSucceeded = true
500+
501+ return nil
502+ })
499503
500504 return g .Wait ()
501505}
0 commit comments