Skip to content

blockifier: introduce EntryPointExecutionErrorWithMetadata wrapper#14259

Open
ron-starkware wants to merge 1 commit into
main-v0.14.3from
ron/blockifier-entry-point-execution-error-with-metadata
Open

blockifier: introduce EntryPointExecutionErrorWithMetadata wrapper#14259
ron-starkware wants to merge 1 commit into
main-v0.14.3from
ron/blockifier-entry-point-execution-error-with-metadata

Conversation

@ron-starkware
Copy link
Copy Markdown
Contributor

Wrap EntryPointExecutionError in a new outer enum currently carrying
only an UnAnnotated variant, and thread the wrapper through the
EntryPointExecutionResult alias, syscall error variants,
ConstructorEntryPointExecutionError::new, and the TransactionExecutionError
ExecutionError / ValidateTransactionError fields. A blanket
From<E: Into> impl on the wrapper preserves ?
propagation for all existing source errors.

No behavioral change. A follow-up will add an Annotated variant carrying
per-frame rendering metadata for the stack-trace formatter.

Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com

@reviewable-StarkWare
Copy link
Copy Markdown

This change is Reviewable

Copy link
Copy Markdown
Contributor Author

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 30, 2026

@ron-starkware ron-starkware force-pushed the ron/blockifier-entry-point-execution-error-with-metadata branch from 1fbab0a to 54143ab Compare May 30, 2026 17:09
@ron-starkware ron-starkware self-assigned this May 30, 2026
@ron-starkware ron-starkware marked this pull request as ready for review May 30, 2026 17:11
@cursor
Copy link
Copy Markdown

cursor Bot commented May 30, 2026

PR Summary

Low Risk
Refactor-only error typing and explicit conversions; execution semantics unchanged aside from matching on the new wrapper in tests and trace formatting.

Overview
Introduces EntryPointExecutionErrorWithMetadata as a thin wrapper around EntryPointExecutionError (currently only an UnAnnotated variant) and makes it the error type for EntryPointExecutionResult, transaction execution/validation/fee-transfer errors, and constructor/syscall error chains.

Call sites now explicitly wrap bare entry-point errors with .into() / EntryPointExecutionError::from(...).into() instead of relying on broad From impls; execute_entry_point_call_wrapper peels the wrapper via into_unannotated() when handling revert-enabled pre-execution failures. Stack traces and test helpers use unannotated() / into_unannotated() so behavior stays the same until a future annotated variant exists.

Reviewed by Cursor Bugbot for commit 57923dd. Bugbot is set up for automated code reviews on this repo. Configure here.

Copy link
Copy Markdown
Collaborator

@dorimedini-starkware dorimedini-starkware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dorimedini-starkware reviewed 14 files and all commit messages, and made 4 comments.
Reviewable status: all files reviewed, 4 unresolved discussions (waiting on matanl-starkware, ron-starkware, and Yoni-Starkware).


a discussion (no related file):
some more locations that may need updating, PTAL and see which ones should have the metadata variant?

  1. maybe_fill_holes function (it still returns the "no metadata" error type)
  2. StakingContractError::EntryPointExecutionError

crates/blockifier/src/execution/errors.rs line 148 at r1 (raw file):

        EntryPointExecutionErrorWithMetadata::UnAnnotated(e.into())
    }
}

non-blocking

Suggestion:

impl EntryPointExecutionErrorWithMetadata {
    pub fn unannotated(&self) -> &EntryPointExecutionError {
        match self {
            Self::UnAnnotated(e) => e,
        }
    }

    pub fn into_unannotated(self) -> EntryPointExecutionError {
        match self {
            Self::UnAnnotated(e) => e,
        }
    }
}

/// Blanket impl so `?` works for any source already convertible to `EntryPointExecutionError`.
impl<E> From<E> for EntryPointExecutionErrorWithMetadata
where
    E: Into<EntryPointExecutionError>,
{
    fn from(e: E) -> Self {
        Self::UnAnnotated(e.into())
    }
}

crates/blockifier/src/execution/errors.rs line 148 at r1 (raw file):

        EntryPointExecutionErrorWithMetadata::UnAnnotated(e.into())
    }
}

will you remove this in the next PR? because this will protect you from missing out on annotating errors where you intend to, or explicitly propagating an unannotated variant

Code quote:

/// Blanket impl so `?` works for any source already convertible to `EntryPointExecutionError`.
impl<E> From<E> for EntryPointExecutionErrorWithMetadata
where
    E: Into<EntryPointExecutionError>,
{
    fn from(e: E) -> Self {
        EntryPointExecutionErrorWithMetadata::UnAnnotated(e.into())
    }
}

crates/blockifier/src/execution/native/entry_point_execution.rs line 78 at r1 (raw file):

    }

    create_callinfo(call_result, syscall_handler).map_err(Into::into)

this could also work, right?

Suggestion:

Ok(create_callinfo(call_result, syscall_handler)?)

@ron-starkware ron-starkware force-pushed the ron/blockifier-entry-point-execution-error-with-metadata branch from 54143ab to f695155 Compare May 30, 2026 18:00
Copy link
Copy Markdown
Contributor Author

@ron-starkware ron-starkware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ron-starkware made 4 comments and resolved 1 discussion.
Reviewable status: 12 of 14 files reviewed, 3 unresolved discussions (waiting on dorimedini-starkware, matanl-starkware, and Yoni-Starkware).


a discussion (no related file):

Previously, dorimedini-starkware wrote…

some more locations that may need updating, PTAL and see which ones should have the metadata variant?

  1. maybe_fill_holes function (it still returns the "no metadata" error type)
  2. StakingContractError::EntryPointExecutionError

It looks like:

  • maybe_fill_holes returns Result<(), EntryPointExecutionError> and is called by ? from run_entry_point which returns EntryPointExecutionResult<()>. The propagation works via the blanket: inner type → UnAnnotated at the ? boundary → wrapper annotates further up. maybe_fill_holes is well below the wrapper boundary; making it return the envelope would just inflate signatures of internal helpers with no behavioral benefit.
  • StakingContractError::EntryPointExecutionError(#[from] EntryPointExecutionError) - Claude checked for sites that actually construct this variant: there are none. The only flow that touches the staking contract is through BatcherClient::call_contract, which
    serializes the underlying error to BatcherError::ContractCallFailed { reason: String }. So this variant is dormant, no concrete EntryPointExecutionError value ever reaches it today.

crates/blockifier/src/execution/errors.rs line 148 at r1 (raw file):

Previously, dorimedini-starkware wrote…

non-blocking

Done


crates/blockifier/src/execution/errors.rs line 148 at r1 (raw file):

Previously, dorimedini-starkware wrote…

will you remove this in the next PR? because this will protect you from missing out on annotating errors where you intend to, or explicitly propagating an unannotated variant

It isn't removed. If we want to drop it, then

  • All the state.get_compiled_class()? / state.something()? style sites that propagate StateError, PreExecutionError, Box>CairoRunError>, etc. through ? into a function returning EntryPointExecutionResult<_> stop compiling (Rust doesn't chain From impls transitively).
  • Each such site either needs an explicit .map_err(EntryPointExecutionError::from)? chain, or each individual source type needs its own From>X> for WithMetadata impl.
    What do you think, should it still be done?

crates/blockifier/src/execution/native/entry_point_execution.rs line 78 at r1 (raw file):

Previously, dorimedini-starkware wrote…

this could also work, right?

Yes, done.

Wrap EntryPointExecutionError in a new outer enum currently carrying
only an UnAnnotated variant, and thread the wrapper through the
EntryPointExecutionResult alias, syscall error variants,
ConstructorEntryPointExecutionError::new, and the TransactionExecutionError
ExecutionError / ValidateTransactionError fields. A blanket
From<E: Into<EntryPointExecutionError>> impl on the wrapper preserves `?`
propagation for all existing source errors.

No behavioral change. A follow-up will add an Annotated variant carrying
per-frame rendering metadata for the stack-trace formatter.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ron-starkware ron-starkware force-pushed the ron/blockifier-entry-point-execution-error-with-metadata branch from f695155 to 57923dd Compare May 30, 2026 18:47
Copy link
Copy Markdown
Contributor Author

@ron-starkware ron-starkware left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ron-starkware made 1 comment.
Reviewable status: 10 of 16 files reviewed, 3 unresolved discussions (waiting on dorimedini-starkware, matanl-starkware, and Yoni-Starkware).


crates/blockifier/src/execution/errors.rs line 148 at r1 (raw file):

Previously, ron-starkware wrote…

It isn't removed. If we want to drop it, then

  • All the state.get_compiled_class()? / state.something()? style sites that propagate StateError, PreExecutionError, Box>CairoRunError>, etc. through ? into a function returning EntryPointExecutionResult<_> stop compiling (Rust doesn't chain From impls transitively).
  • Each such site either needs an explicit .map_err(EntryPointExecutionError::from)? chain, or each individual source type needs its own From>X> for WithMetadata impl.
    What do you think, should it still be done?

I decided to do it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants