From 7e21caae6e2b675985249312395acdb3b312a200 Mon Sep 17 00:00:00 2001 From: Andrii Date: Fri, 5 Apr 2024 14:49:34 +0300 Subject: [PATCH 01/10] Changed error type --- engine/access/rpc/backend/backend_stream_blocks.go | 4 ++-- engine/access/state_stream/backend/backend.go | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/engine/access/rpc/backend/backend_stream_blocks.go b/engine/access/rpc/backend/backend_stream_blocks.go index a2ce866137b..1082d0b0357 100644 --- a/engine/access/rpc/backend/backend_stream_blocks.go +++ b/engine/access/rpc/backend/backend_stream_blocks.go @@ -339,7 +339,7 @@ func (b *backendSubscribeBlocks) getBlock(height uint64, expectedBlockStatus flo // validateHeight checks if the given block height is valid and available based on the expected block status. // Expected errors during normal operation: -// - storage.ErrNotFound: block for the given block height is not available. +// - subscription.ErrBlockNotReady when unable to retrieve the block by height func (b *backendSubscribeBlocks) validateHeight(height uint64, expectedBlockStatus flow.BlockStatus) error { highestHeight, err := b.blockTracker.GetHighestHeight(expectedBlockStatus) if err != nil { @@ -350,7 +350,7 @@ func (b *backendSubscribeBlocks) validateHeight(height uint64, expectedBlockStat // note: it's possible for the data to exist in the data store before the notification is // received. this ensures a consistent view is available to all streams. if height > highestHeight { - return fmt.Errorf("block %d is not available yet: %w", height, storage.ErrNotFound) + return fmt.Errorf("block %d is not available yet: %w", height, subscription.ErrBlockNotReady) } return nil diff --git a/engine/access/state_stream/backend/backend.go b/engine/access/state_stream/backend/backend.go index d82daad8a7f..a49dd9bd23f 100644 --- a/engine/access/state_stream/backend/backend.go +++ b/engine/access/state_stream/backend/backend.go @@ -156,14 +156,14 @@ func New( // getExecutionData returns the execution data for the given block height. // Expected errors during normal operation: -// - storage.ErrNotFound or execution_data.BlobNotFoundError: execution data for the given block height is not available. +// - subscription.ErrBlockNotReady or execution_data.BlobNotFoundError: execution data for the given block height is not available. func (b *StateStreamBackend) getExecutionData(ctx context.Context, height uint64) (*execution_data.BlockExecutionDataEntity, error) { highestHeight := b.ExecutionDataTracker.GetHighestHeight() // fail early if no notification has been received for the given block height. // note: it's possible for the data to exist in the data store before the notification is // received. this ensures a consistent view is available to all streams. if height > highestHeight { - return nil, fmt.Errorf("execution data for block %d is not available yet: %w", height, storage.ErrNotFound) + return nil, fmt.Errorf("execution data for block %d is not available yet: %w", height, subscription.ErrBlockNotReady) } execData, err := b.execDataCache.ByHeight(ctx, height) From 05f9293bb5381252bc2d1121dfcea85453ac2fc1 Mon Sep 17 00:00:00 2001 From: Andrii Date: Fri, 5 Apr 2024 16:40:36 +0300 Subject: [PATCH 02/10] Added dot --- engine/access/rpc/backend/backend_stream_blocks.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/engine/access/rpc/backend/backend_stream_blocks.go b/engine/access/rpc/backend/backend_stream_blocks.go index 1082d0b0357..3d349221fdd 100644 --- a/engine/access/rpc/backend/backend_stream_blocks.go +++ b/engine/access/rpc/backend/backend_stream_blocks.go @@ -339,7 +339,7 @@ func (b *backendSubscribeBlocks) getBlock(height uint64, expectedBlockStatus flo // validateHeight checks if the given block height is valid and available based on the expected block status. // Expected errors during normal operation: -// - subscription.ErrBlockNotReady when unable to retrieve the block by height +// - subscription.ErrBlockNotReady when unable to retrieve the block by height. func (b *backendSubscribeBlocks) validateHeight(height uint64, expectedBlockStatus flow.BlockStatus) error { highestHeight, err := b.blockTracker.GetHighestHeight(expectedBlockStatus) if err != nil { From 3aca83a0c9f7bca4508bbe790ed188d9aa12cfa7 Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 10 Apr 2024 16:01:45 +0300 Subject: [PATCH 03/10] Added error check in getExecutionData function --- engine/access/state_stream/backend/backend.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/engine/access/state_stream/backend/backend.go b/engine/access/state_stream/backend/backend.go index 9bebc0cc922..4fd3b33e6ce 100644 --- a/engine/access/state_stream/backend/backend.go +++ b/engine/access/state_stream/backend/backend.go @@ -156,7 +156,15 @@ func (b *StateStreamBackend) getExecutionData(ctx context.Context, height uint64 execData, err := b.execDataCache.ByHeight(ctx, height) if err != nil { - return nil, fmt.Errorf("could not get execution data for block %d: %w", height, err) + var errMsg error + if errors.Is(err, storage.ErrNotFound) || + errors.Is(err, storage.ErrHeightNotIndexed) || + execution_data.IsBlobNotFoundError(err) { + errMsg = subscription.ErrBlockNotReady + } else { + errMsg = err + } + return nil, fmt.Errorf("could not get execution data for block %d: %w", height, errMsg) } return execData, nil From 8290b0c00805df80c57f953c940f6e1083c76b9d Mon Sep 17 00:00:00 2001 From: Andrii Date: Thu, 11 Apr 2024 13:56:18 +0300 Subject: [PATCH 04/10] Changed error for other streaming endpoints --- engine/access/rpc/backend/backend_stream_blocks.go | 7 +++++++ engine/access/state_stream/backend/backend.go | 3 +-- .../state_stream/backend/backend_account_statuses.go | 7 +++++++ engine/access/state_stream/backend/backend_events.go | 11 +++++++++-- .../state_stream/backend/backend_executiondata.go | 7 +++++-- 5 files changed, 29 insertions(+), 6 deletions(-) diff --git a/engine/access/rpc/backend/backend_stream_blocks.go b/engine/access/rpc/backend/backend_stream_blocks.go index 842bddd9d05..c31afb7f7fc 100644 --- a/engine/access/rpc/backend/backend_stream_blocks.go +++ b/engine/access/rpc/backend/backend_stream_blocks.go @@ -2,6 +2,7 @@ package backend import ( "context" + "errors" "fmt" "github.com/rs/zerolog" @@ -293,6 +294,9 @@ func (b *backendSubscribeBlocks) getBlockHeader(height uint64, expectedBlockStat // since we are querying a finalized or sealed block header, we can use the height index and save an ID computation header, err := b.headers.ByHeight(height) if err != nil { + if errors.Is(err, storage.ErrNotFound) { + return nil, fmt.Errorf("failed to retrieve block ID for height %d: %w", height, subscription.ErrBlockNotReady) + } return nil, err } @@ -311,6 +315,9 @@ func (b *backendSubscribeBlocks) getBlock(height uint64, expectedBlockStatus flo // since we are querying a finalized or sealed block, we can use the height index and save an ID computation block, err := b.blocks.ByHeight(height) if err != nil { + if errors.Is(err, storage.ErrNotFound) { + return nil, fmt.Errorf("failed to retrieve block ID for height %d: %w", height, subscription.ErrBlockNotReady) + } return nil, err } diff --git a/engine/access/state_stream/backend/backend.go b/engine/access/state_stream/backend/backend.go index 4fd3b33e6ce..13ec8bd33ce 100644 --- a/engine/access/state_stream/backend/backend.go +++ b/engine/access/state_stream/backend/backend.go @@ -144,7 +144,7 @@ func New( // getExecutionData returns the execution data for the given block height. // Expected errors during normal operation: -// - subscription.ErrBlockNotReady or execution_data.BlobNotFoundError: execution data for the given block height is not available. +// - subscription.ErrBlockNotReady: execution data for the given block height is not available. func (b *StateStreamBackend) getExecutionData(ctx context.Context, height uint64) (*execution_data.BlockExecutionDataEntity, error) { highestHeight := b.ExecutionDataTracker.GetHighestHeight() // fail early if no notification has been received for the given block height. @@ -158,7 +158,6 @@ func (b *StateStreamBackend) getExecutionData(ctx context.Context, height uint64 if err != nil { var errMsg error if errors.Is(err, storage.ErrNotFound) || - errors.Is(err, storage.ErrHeightNotIndexed) || execution_data.IsBlobNotFoundError(err) { errMsg = subscription.ErrBlockNotReady } else { diff --git a/engine/access/state_stream/backend/backend_account_statuses.go b/engine/access/state_stream/backend/backend_account_statuses.go index 3e408f02f96..4accbe26bdf 100644 --- a/engine/access/state_stream/backend/backend_account_statuses.go +++ b/engine/access/state_stream/backend/backend_account_statuses.go @@ -2,12 +2,15 @@ package backend import ( "context" + "fmt" "github.com/rs/zerolog" "github.com/onflow/flow-go/engine/access/state_stream" "github.com/onflow/flow-go/engine/access/subscription" + "github.com/onflow/flow-go/fvm/errors" "github.com/onflow/flow-go/model/flow" + "github.com/onflow/flow-go/storage" ) type AccountStatusesResponse struct { @@ -90,6 +93,10 @@ func (b *AccountStatusesBackend) getAccountStatusResponseFactory( return func(ctx context.Context, height uint64) (interface{}, error) { eventsResponse, err := b.eventsRetriever.GetAllEventsResponse(ctx, height) if err != nil { + if errors.Is(err, storage.ErrNotFound) || + errors.Is(err, storage.ErrHeightNotIndexed) { + return nil, fmt.Errorf("block %d is not available yet: %w", height, subscription.ErrBlockNotReady) + } return nil, err } filteredProtocolEvents := filter.Filter(eventsResponse.Events) diff --git a/engine/access/state_stream/backend/backend_events.go b/engine/access/state_stream/backend/backend_events.go index 4c9818402dd..b02673749bb 100644 --- a/engine/access/state_stream/backend/backend_events.go +++ b/engine/access/state_stream/backend/backend_events.go @@ -2,12 +2,15 @@ package backend import ( "context" + "fmt" "github.com/rs/zerolog" "github.com/onflow/flow-go/engine/access/state_stream" "github.com/onflow/flow-go/engine/access/subscription" + "github.com/onflow/flow-go/fvm/errors" "github.com/onflow/flow-go/model/flow" + "github.com/onflow/flow-go/storage" ) type EventsBackend struct { @@ -126,12 +129,16 @@ func (b *EventsBackend) SubscribeEventsFromLatest(ctx context.Context, filter st // - filter: The event filter used to filter events. // // Expected errors during normal operation: -// - codes.NotFound: If block header for the specified block height is not found, if events for the specified block height are not found. +// - subscription.ErrBlockNotReady: execution data for the given block height is not available. func (b *EventsBackend) getResponseFactory(filter state_stream.EventFilter) subscription.GetDataByHeightFunc { return func(ctx context.Context, height uint64) (response interface{}, err error) { eventsResponse, err := b.eventsRetriever.GetAllEventsResponse(ctx, height) if err != nil { - return nil, err + if errors.Is(err, storage.ErrNotFound) || + errors.Is(err, storage.ErrHeightNotIndexed) { + return nil, subscription.ErrBlockNotReady + } + return nil, fmt.Errorf("block %d is not available yet: %w", height, subscription.ErrBlockNotReady) } eventsResponse.Events = filter.Filter(eventsResponse.Events) diff --git a/engine/access/state_stream/backend/backend_executiondata.go b/engine/access/state_stream/backend/backend_executiondata.go index c1821593ffd..fb161a126f6 100644 --- a/engine/access/state_stream/backend/backend_executiondata.go +++ b/engine/access/state_stream/backend/backend_executiondata.go @@ -34,6 +34,9 @@ type ExecutionDataBackend struct { func (b *ExecutionDataBackend) GetExecutionDataByBlockID(ctx context.Context, blockID flow.Identifier) (*execution_data.BlockExecutionData, error) { header, err := b.headers.ByBlockID(blockID) if err != nil { + if errors.Is(err, storage.ErrNotFound) { + return nil, fmt.Errorf("could not get block header for %s: %w", blockID, subscription.ErrBlockNotReady) + } return nil, fmt.Errorf("could not get block header for %s: %w", blockID, err) } @@ -41,8 +44,8 @@ func (b *ExecutionDataBackend) GetExecutionDataByBlockID(ctx context.Context, bl if err != nil { // need custom not found handler due to blob not found error - if errors.Is(err, storage.ErrNotFound) || execution_data.IsBlobNotFoundError(err) { - return nil, status.Errorf(codes.NotFound, "could not find execution data: %v", err) + if errors.Is(err, subscription.ErrBlockNotReady) { + return nil, status.Errorf(codes.NotFound, "could not find execution data: %v", subscription.ErrBlockNotReady) } return nil, rpc.ConvertError(err, "could not get execution data", codes.Internal) From 57f0f89ee051d5a0c66216089b8e33732cc6b133 Mon Sep 17 00:00:00 2001 From: Andrii Date: Thu, 11 Apr 2024 15:16:26 +0300 Subject: [PATCH 05/10] Changed if statements --- .../access/state_stream/backend/backend_executiondata.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/engine/access/state_stream/backend/backend_executiondata.go b/engine/access/state_stream/backend/backend_executiondata.go index fb161a126f6..4fdad151df5 100644 --- a/engine/access/state_stream/backend/backend_executiondata.go +++ b/engine/access/state_stream/backend/backend_executiondata.go @@ -43,12 +43,11 @@ func (b *ExecutionDataBackend) GetExecutionDataByBlockID(ctx context.Context, bl executionData, err := b.getExecutionData(ctx, header.Height) if err != nil { - // need custom not found handler due to blob not found error - if errors.Is(err, subscription.ErrBlockNotReady) { - return nil, status.Errorf(codes.NotFound, "could not find execution data: %v", subscription.ErrBlockNotReady) + if !errors.Is(err, subscription.ErrBlockNotReady) { + return nil, rpc.ConvertError(err, "could not get execution data", codes.Internal) } - return nil, rpc.ConvertError(err, "could not get execution data", codes.Internal) + return nil, status.Errorf(codes.NotFound, "could not find execution data: %v", subscription.ErrBlockNotReady) } return executionData.BlockExecutionData, nil From 070a5a3dcf5baca310a7cd6b9aa63cdbe35f7fc1 Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 17 Apr 2024 14:12:50 +0300 Subject: [PATCH 06/10] Fixed comments: --- engine/access/rpc/backend/backend_network.go | 2 +- .../access/rpc/backend/backend_stream_blocks.go | 4 ++-- engine/access/state_stream/backend/backend.go | 15 +++++---------- .../backend/backend_executiondata.go | 16 +++------------- engine/access/subscription/streamer.go | 7 +------ 5 files changed, 12 insertions(+), 32 deletions(-) diff --git a/engine/access/rpc/backend/backend_network.go b/engine/access/rpc/backend/backend_network.go index 1a1c87722be..a91483519b3 100644 --- a/engine/access/rpc/backend/backend_network.go +++ b/engine/access/rpc/backend/backend_network.go @@ -146,7 +146,7 @@ func (b *backendNetwork) GetProtocolStateSnapshotByBlockID(_ context.Context, bl // The block must be finalized (otherwise the by-height query is ambiguous). // Expected errors during normal operation: // - status.Error[codes.NotFound] - No block with the given height was found. -// The block height may or may not be finalized in the future; the client can retry later. +// The block height may or may not be finalized in the future; the client can r etry later. // - status.Error[codes.InvalidArgument] - A block was found, however its sealing segment spans an epoch phase transition, // yielding an invalid snapshot. Therefore we will never return a snapshot for this block height. func (b *backendNetwork) GetProtocolStateSnapshotByHeight(_ context.Context, blockHeight uint64) ([]byte, error) { diff --git a/engine/access/rpc/backend/backend_stream_blocks.go b/engine/access/rpc/backend/backend_stream_blocks.go index c31afb7f7fc..85b522b2d2c 100644 --- a/engine/access/rpc/backend/backend_stream_blocks.go +++ b/engine/access/rpc/backend/backend_stream_blocks.go @@ -295,7 +295,7 @@ func (b *backendSubscribeBlocks) getBlockHeader(height uint64, expectedBlockStat header, err := b.headers.ByHeight(height) if err != nil { if errors.Is(err, storage.ErrNotFound) { - return nil, fmt.Errorf("failed to retrieve block ID for height %d: %w", height, subscription.ErrBlockNotReady) + return nil, fmt.Errorf("failed to retrieve block header for height %d: %w", height, subscription.ErrBlockNotReady) } return nil, err } @@ -316,7 +316,7 @@ func (b *backendSubscribeBlocks) getBlock(height uint64, expectedBlockStatus flo block, err := b.blocks.ByHeight(height) if err != nil { if errors.Is(err, storage.ErrNotFound) { - return nil, fmt.Errorf("failed to retrieve block ID for height %d: %w", height, subscription.ErrBlockNotReady) + return nil, fmt.Errorf("failed to retrieve block for height %d: %w", height, subscription.ErrBlockNotReady) } return nil, err } diff --git a/engine/access/state_stream/backend/backend.go b/engine/access/state_stream/backend/backend.go index 13ec8bd33ce..78a4f788577 100644 --- a/engine/access/state_stream/backend/backend.go +++ b/engine/access/state_stream/backend/backend.go @@ -2,6 +2,7 @@ package backend import ( "context" + "errors" "fmt" "time" @@ -12,7 +13,6 @@ import ( "github.com/onflow/flow-go/engine/access/index" "github.com/onflow/flow-go/engine/access/state_stream" "github.com/onflow/flow-go/engine/access/subscription" - "github.com/onflow/flow-go/fvm/errors" "github.com/onflow/flow-go/model/flow" "github.com/onflow/flow-go/module/execution" "github.com/onflow/flow-go/module/executiondatasync/execution_data" @@ -155,16 +155,11 @@ func (b *StateStreamBackend) getExecutionData(ctx context.Context, height uint64 } execData, err := b.execDataCache.ByHeight(ctx, height) - if err != nil { - var errMsg error - if errors.Is(err, storage.ErrNotFound) || - execution_data.IsBlobNotFoundError(err) { - errMsg = subscription.ErrBlockNotReady - } else { - errMsg = err - } - return nil, fmt.Errorf("could not get execution data for block %d: %w", height, errMsg) + if errors.Is(err, storage.ErrNotFound) || + execution_data.IsBlobNotFoundError(err) { + err = errors.Join(err, subscription.ErrBlockNotReady) } + return nil, fmt.Errorf("could not get execution data for block %d: %w", height, err) return execData, nil } diff --git a/engine/access/state_stream/backend/backend_executiondata.go b/engine/access/state_stream/backend/backend_executiondata.go index 4fdad151df5..3807d93fd9c 100644 --- a/engine/access/state_stream/backend/backend_executiondata.go +++ b/engine/access/state_stream/backend/backend_executiondata.go @@ -2,18 +2,15 @@ package backend import ( "context" - "errors" "fmt" - "github.com/rs/zerolog" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/status" - "github.com/onflow/flow-go/engine/access/subscription" "github.com/onflow/flow-go/engine/common/rpc" "github.com/onflow/flow-go/model/flow" "github.com/onflow/flow-go/module/executiondatasync/execution_data" "github.com/onflow/flow-go/storage" + "github.com/rs/zerolog" + "google.golang.org/grpc/codes" ) type ExecutionDataResponse struct { @@ -34,20 +31,13 @@ type ExecutionDataBackend struct { func (b *ExecutionDataBackend) GetExecutionDataByBlockID(ctx context.Context, blockID flow.Identifier) (*execution_data.BlockExecutionData, error) { header, err := b.headers.ByBlockID(blockID) if err != nil { - if errors.Is(err, storage.ErrNotFound) { - return nil, fmt.Errorf("could not get block header for %s: %w", blockID, subscription.ErrBlockNotReady) - } return nil, fmt.Errorf("could not get block header for %s: %w", blockID, err) } executionData, err := b.getExecutionData(ctx, header.Height) if err != nil { - if !errors.Is(err, subscription.ErrBlockNotReady) { - return nil, rpc.ConvertError(err, "could not get execution data", codes.Internal) - } - - return nil, status.Errorf(codes.NotFound, "could not find execution data: %v", subscription.ErrBlockNotReady) + return nil, rpc.ConvertError(err, "could not get execution data", codes.Internal) } return executionData.BlockExecutionData, nil diff --git a/engine/access/subscription/streamer.go b/engine/access/subscription/streamer.go index 11531387200..40c8166a0c6 100644 --- a/engine/access/subscription/streamer.go +++ b/engine/access/subscription/streamer.go @@ -10,8 +10,6 @@ import ( "golang.org/x/time/rate" "github.com/onflow/flow-go/engine" - "github.com/onflow/flow-go/module/executiondatasync/execution_data" - "github.com/onflow/flow-go/storage" ) // ErrBlockNotReady represents an error indicating that a block is not yet available or ready. @@ -105,10 +103,7 @@ func (s *Streamer) sendAllAvailable(ctx context.Context) error { } if err != nil { - if errors.Is(err, storage.ErrNotFound) || - errors.Is(err, storage.ErrHeightNotIndexed) || - execution_data.IsBlobNotFoundError(err) || - errors.Is(err, ErrBlockNotReady) { + if errors.Is(err, ErrBlockNotReady) { // no more available return nil } From 57f4e09218490f1dfa9385967e635568e045e33a Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 17 Apr 2024 14:47:11 +0300 Subject: [PATCH 07/10] Linted --- engine/access/state_stream/backend/backend.go | 11 +++++++---- .../state_stream/backend/backend_executiondata.go | 5 +++-- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/engine/access/state_stream/backend/backend.go b/engine/access/state_stream/backend/backend.go index 78a4f788577..2515cabb32b 100644 --- a/engine/access/state_stream/backend/backend.go +++ b/engine/access/state_stream/backend/backend.go @@ -155,11 +155,14 @@ func (b *StateStreamBackend) getExecutionData(ctx context.Context, height uint64 } execData, err := b.execDataCache.ByHeight(ctx, height) - if errors.Is(err, storage.ErrNotFound) || - execution_data.IsBlobNotFoundError(err) { - err = errors.Join(err, subscription.ErrBlockNotReady) + if err != nil { + if errors.Is(err, storage.ErrNotFound) || + execution_data.IsBlobNotFoundError(err) { + err = errors.Join(err, subscription.ErrBlockNotReady) + return nil, fmt.Errorf("could not get execution data for block %d: %w", height, err) + } + return nil, fmt.Errorf("could not get execution data for block %d: %w", height, err) } - return nil, fmt.Errorf("could not get execution data for block %d: %w", height, err) return execData, nil } diff --git a/engine/access/state_stream/backend/backend_executiondata.go b/engine/access/state_stream/backend/backend_executiondata.go index 3807d93fd9c..085f7944f2a 100644 --- a/engine/access/state_stream/backend/backend_executiondata.go +++ b/engine/access/state_stream/backend/backend_executiondata.go @@ -4,13 +4,14 @@ import ( "context" "fmt" + "github.com/rs/zerolog" + "google.golang.org/grpc/codes" + "github.com/onflow/flow-go/engine/access/subscription" "github.com/onflow/flow-go/engine/common/rpc" "github.com/onflow/flow-go/model/flow" "github.com/onflow/flow-go/module/executiondatasync/execution_data" "github.com/onflow/flow-go/storage" - "github.com/rs/zerolog" - "google.golang.org/grpc/codes" ) type ExecutionDataResponse struct { From 23acd32b1e1829af8e617451010ba244287353a3 Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 17 Apr 2024 15:25:36 +0300 Subject: [PATCH 08/10] Added removed part --- engine/access/rpc/backend/backend_network.go | 2 +- engine/access/state_stream/backend/backend_executiondata.go | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/engine/access/rpc/backend/backend_network.go b/engine/access/rpc/backend/backend_network.go index a91483519b3..1a1c87722be 100644 --- a/engine/access/rpc/backend/backend_network.go +++ b/engine/access/rpc/backend/backend_network.go @@ -146,7 +146,7 @@ func (b *backendNetwork) GetProtocolStateSnapshotByBlockID(_ context.Context, bl // The block must be finalized (otherwise the by-height query is ambiguous). // Expected errors during normal operation: // - status.Error[codes.NotFound] - No block with the given height was found. -// The block height may or may not be finalized in the future; the client can r etry later. +// The block height may or may not be finalized in the future; the client can retry later. // - status.Error[codes.InvalidArgument] - A block was found, however its sealing segment spans an epoch phase transition, // yielding an invalid snapshot. Therefore we will never return a snapshot for this block height. func (b *backendNetwork) GetProtocolStateSnapshotByHeight(_ context.Context, blockHeight uint64) ([]byte, error) { diff --git a/engine/access/state_stream/backend/backend_executiondata.go b/engine/access/state_stream/backend/backend_executiondata.go index 085f7944f2a..34627007273 100644 --- a/engine/access/state_stream/backend/backend_executiondata.go +++ b/engine/access/state_stream/backend/backend_executiondata.go @@ -2,10 +2,12 @@ package backend import ( "context" + "errors" "fmt" "github.com/rs/zerolog" "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" "github.com/onflow/flow-go/engine/access/subscription" "github.com/onflow/flow-go/engine/common/rpc" @@ -38,6 +40,9 @@ func (b *ExecutionDataBackend) GetExecutionDataByBlockID(ctx context.Context, bl executionData, err := b.getExecutionData(ctx, header.Height) if err != nil { + if errors.Is(err, storage.ErrNotFound) || execution_data.IsBlobNotFoundError(err) { + return nil, status.Errorf(codes.NotFound, "could not find execution data: %v", err) + } return nil, rpc.ConvertError(err, "could not get execution data", codes.Internal) } From 8a572be51dc6a215e8c9f6c9f247b3637febfd33 Mon Sep 17 00:00:00 2001 From: Andrii Date: Wed, 17 Apr 2024 15:26:40 +0300 Subject: [PATCH 09/10] Added back comment --- engine/access/state_stream/backend/backend_executiondata.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/engine/access/state_stream/backend/backend_executiondata.go b/engine/access/state_stream/backend/backend_executiondata.go index 34627007273..c1821593ffd 100644 --- a/engine/access/state_stream/backend/backend_executiondata.go +++ b/engine/access/state_stream/backend/backend_executiondata.go @@ -40,9 +40,11 @@ func (b *ExecutionDataBackend) GetExecutionDataByBlockID(ctx context.Context, bl executionData, err := b.getExecutionData(ctx, header.Height) if err != nil { + // need custom not found handler due to blob not found error if errors.Is(err, storage.ErrNotFound) || execution_data.IsBlobNotFoundError(err) { return nil, status.Errorf(codes.NotFound, "could not find execution data: %v", err) } + return nil, rpc.ConvertError(err, "could not get execution data", codes.Internal) } From 868474d295247df6c486f28003652b13c05d76c9 Mon Sep 17 00:00:00 2001 From: Andrii Date: Thu, 18 Apr 2024 12:40:15 +0300 Subject: [PATCH 10/10] Changed godoc --- engine/access/rpc/backend/backend_stream_blocks.go | 4 ++-- .../access/state_stream/backend/backend_account_statuses.go | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/engine/access/rpc/backend/backend_stream_blocks.go b/engine/access/rpc/backend/backend_stream_blocks.go index 85b522b2d2c..cddd59a63ef 100644 --- a/engine/access/rpc/backend/backend_stream_blocks.go +++ b/engine/access/rpc/backend/backend_stream_blocks.go @@ -284,7 +284,7 @@ func (b *backendSubscribeBlocks) getBlockDigestResponse(blockStatus flow.BlockSt // getBlockHeader returns the block header for the given block height. // Expected errors during normal operation: -// - storage.ErrNotFound: block for the given block height is not available. +// - subscription.ErrBlockNotReady: block for the given block height is not available. func (b *backendSubscribeBlocks) getBlockHeader(height uint64, expectedBlockStatus flow.BlockStatus) (*flow.Header, error) { err := b.validateHeight(height, expectedBlockStatus) if err != nil { @@ -305,7 +305,7 @@ func (b *backendSubscribeBlocks) getBlockHeader(height uint64, expectedBlockStat // getBlock returns the block for the given block height. // Expected errors during normal operation: -// - storage.ErrNotFound: block for the given block height is not available. +// - subscription.ErrBlockNotReady: block for the given block height is not available. func (b *backendSubscribeBlocks) getBlock(height uint64, expectedBlockStatus flow.BlockStatus) (*flow.Block, error) { err := b.validateHeight(height, expectedBlockStatus) if err != nil { diff --git a/engine/access/state_stream/backend/backend_account_statuses.go b/engine/access/state_stream/backend/backend_account_statuses.go index 4accbe26bdf..98a52619ede 100644 --- a/engine/access/state_stream/backend/backend_account_statuses.go +++ b/engine/access/state_stream/backend/backend_account_statuses.go @@ -57,7 +57,7 @@ func (b *AccountStatusesBackend) SubscribeAccountStatusesFromStartBlockID( // SubscribeAccountStatusesFromStartHeight subscribes to the streaming of account status changes starting from // a specific block height, with an optional status filter. // Errors: -// - codes.ErrNotFound if could not get block by start height. +// - codes.ErrNotFound if could not get block by start height. // - codes.Internal if there is an internal error. func (b *AccountStatusesBackend) SubscribeAccountStatusesFromStartHeight( ctx context.Context, @@ -87,6 +87,10 @@ func (b *AccountStatusesBackend) SubscribeAccountStatusesFromLatestBlock( } // getAccountStatusResponseFactory returns a function that returns the account statuses response for a given height. +// +// Errors: +// - subscription.ErrBlockNotReady: If block header for the specified block height is not found. +// - error: An error, if any, encountered during getting events from storage or execution data. func (b *AccountStatusesBackend) getAccountStatusResponseFactory( filter state_stream.AccountStatusFilter, ) subscription.GetDataByHeightFunc {