Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
0038065
Added validation checks for required executors IDs for optimistic sync
UlyanaAndrukhiv Dec 4, 2025
dab8852
Added error handing. Added tests
UlyanaAndrukhiv Dec 5, 2025
aecdd15
Added error handling when criteria for exec result for optimistic syn…
UlyanaAndrukhiv Dec 5, 2025
c4f1593
Moved errors from common rpc to optimistic sync package
UlyanaAndrukhiv Dec 5, 2025
1382a76
Fixed info provider test
UlyanaAndrukhiv Dec 5, 2025
6c9e292
Small format and godoc refactoring
UlyanaAndrukhiv Dec 5, 2025
55f89ee
Merge branch 'feature/optimistic-sync' into UlianaAndrukhiv/8204-add-…
UlyanaAndrukhiv Dec 5, 2025
1491961
Udded Unwrap method to optimistic_sync errors
UlyanaAndrukhiv Dec 8, 2025
b6ff05d
Merge branch 'UlianaAndrukhiv/8204-add-executors-checks' of github.co…
UlyanaAndrukhiv Dec 8, 2025
79c056b
Updated execution result info impl for optimistic_sync by using all e…
UlyanaAndrukhiv Dec 8, 2025
9addcea
Added additional check for agreeing executors count. Updated error ha…
UlyanaAndrukhiv Dec 8, 2025
708500a
Refactored CriteriaNotMetError, added BlockFinalityMismatchError acco…
UlyanaAndrukhiv Dec 8, 2025
ed4f7d0
Updated godocs
UlyanaAndrukhiv Dec 8, 2025
c26a53e
Refactored check for Criteria not met, updated tests
UlyanaAndrukhiv Dec 10, 2025
440903f
Removed the validation check for required executors count
UlyanaAndrukhiv Dec 10, 2025
8e2e7e1
Moved is sealed logic for fork-aware execution result info into separ…
UlyanaAndrukhiv Dec 11, 2025
80888e7
Updated godocs
UlyanaAndrukhiv Dec 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/access/node_builder/access_node_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1784,6 +1784,7 @@ func (builder *FlowAccessNodeBuilder) buildExecutionResultInfoProvider() *FlowAc
node.Logger,
node.State,
node.Storage.Receipts,
node.Storage.Headers,
execNodeSelector,
operatorCriteria,
)
Expand Down
1 change: 1 addition & 0 deletions cmd/observer/node_builder/observer_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -1141,6 +1141,7 @@ func (builder *ObserverServiceBuilder) buildExecutionResultInfoProvider() *Obser
node.Logger,
node.State,
node.Storage.Receipts,
node.Storage.Headers,
execNodeSelector,
operatorCriteria,
)
Expand Down
48 changes: 48 additions & 0 deletions engine/access/rpc/backend/accounts/accounts.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ func (a *Accounts) GetAccountAtLatestBlock(ctx context.Context, address flow.Add
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down Expand Up @@ -181,6 +187,12 @@ func (a *Accounts) GetAccountAtBlockHeight(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down Expand Up @@ -231,6 +243,12 @@ func (a *Accounts) GetAccountBalanceAtLatestBlock(ctx context.Context, address f
return 0, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return 0, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return 0, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return 0, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return 0, nil, access.NewInvalidRequestError(err)
default:
return 0, nil, access.RequireNoError(ctx, err)
}
Expand Down Expand Up @@ -285,6 +303,12 @@ func (a *Accounts) GetAccountBalanceAtBlockHeight(
return 0, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return 0, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return 0, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return 0, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return 0, nil, access.NewInvalidRequestError(err)
default:
return 0, nil, access.RequireNoError(ctx, err)
}
Expand Down Expand Up @@ -339,6 +363,12 @@ func (a *Accounts) GetAccountKeyAtLatestBlock(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down Expand Up @@ -394,6 +424,12 @@ func (a *Accounts) GetAccountKeyAtBlockHeight(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down Expand Up @@ -447,6 +483,12 @@ func (a *Accounts) GetAccountKeysAtLatestBlock(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down Expand Up @@ -501,6 +543,12 @@ func (a *Accounts) GetAccountKeysAtBlockHeight(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down
18 changes: 18 additions & 0 deletions engine/access/rpc/backend/scripts/scripts.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,12 @@ func (b *Scripts) ExecuteScriptAtLatestBlock(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down Expand Up @@ -221,6 +227,12 @@ func (b *Scripts) ExecuteScriptAtBlockID(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down Expand Up @@ -284,6 +296,12 @@ func (b *Scripts) ExecuteScriptAtBlockHeight(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down
6 changes: 6 additions & 0 deletions engine/access/state_stream/backend/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,12 @@ func (b *StateStreamBackend) GetRegisterValues(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down
6 changes: 6 additions & 0 deletions engine/access/state_stream/backend/backend_executiondata.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@ func (b *ExecutionDataBackend) GetExecutionDataByBlockID(
return nil, nil, access.NewDataNotFoundError("execution data", err)
case common.IsInsufficientExecutionReceipts(err):
return nil, nil, access.NewDataNotFoundError("execution data", err)
case optimistic_sync.IsAgreeingExecutorsCountExceededError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsUnknownRequiredExecutorError(err):
return nil, nil, access.NewInvalidRequestError(err)
case optimistic_sync.IsCriteriaNotMetError(err):
return nil, nil, access.NewInvalidRequestError(err)
default:
return nil, nil, access.RequireNoError(ctx, err)
}
Expand Down
73 changes: 73 additions & 0 deletions module/executiondatasync/optimistic_sync/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package optimistic_sync

import (
"errors"
"fmt"

"github.com/onflow/flow-go/model/flow"
)

// AgreeingExecutorsCountExceededError indicates that the requested number of agreeing executors
// exceeds the total available execution nodes.
type AgreeingExecutorsCountExceededError struct {
agreeingExecutorsCount uint
availableExecutorsCount int
}

func NewAgreeingExecutorsCountExceededError(agreeingExecutorsCount uint, availableExecutorsCount int) *AgreeingExecutorsCountExceededError {
return &AgreeingExecutorsCountExceededError{
agreeingExecutorsCount: agreeingExecutorsCount,
availableExecutorsCount: availableExecutorsCount,
}
}

func (e *AgreeingExecutorsCountExceededError) Error() string {
return fmt.Sprintf("agreeing executors count exceeded: provided %d, available %d", e.agreeingExecutorsCount, e.availableExecutorsCount)
}

func IsAgreeingExecutorsCountExceededError(err error) bool {
var agreeingExecutorsCountExceededError *AgreeingExecutorsCountExceededError
return errors.As(err, &agreeingExecutorsCountExceededError)
}

// UnknownRequiredExecutorError indicates that a required executor ID is not present
// in the list of active execution nodes.
type UnknownRequiredExecutorError struct {
executorID flow.Identifier
}

func NewUnknownRequiredExecutorError(executorID flow.Identifier) *UnknownRequiredExecutorError {
return &UnknownRequiredExecutorError{
executorID: executorID,
}
}

func (e *UnknownRequiredExecutorError) Error() string {
return fmt.Sprintf("unknown required executor ID: %s", e.executorID.String())
}

func IsUnknownRequiredExecutorError(err error) bool {
var unknownRequiredExecutor *UnknownRequiredExecutorError
return errors.As(err, &unknownRequiredExecutor)
}

// CriteriaNotMetError indicates that the execution result criteria could not be
// satisfied for a given block, when the block is already sealed.
type CriteriaNotMetError struct {
blockID flow.Identifier
}

func NewCriteriaNotMetError(blockID flow.Identifier) *CriteriaNotMetError {
return &CriteriaNotMetError{
blockID: blockID,
}
}

func (e *CriteriaNotMetError) Error() string {
return fmt.Sprintf("block %s is already sealed and no execution result satisfies the criteria", e.blockID)
}

func IsCriteriaNotMetError(err error) bool {
var criteriaNotMetError *CriteriaNotMetError
return errors.As(err, &criteriaNotMetError)
}
Loading