Skip to content

Commit 3713978

Browse files
authored
Fix subtree meta NOT_FOUND when block assembly creates subtree without metadata (#480)
1 parent db543fe commit 3713978

File tree

1 file changed

+45
-41
lines changed

1 file changed

+45
-41
lines changed

services/legacy/netsync/handle_block.go

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)