Skip to content
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
45 changes: 45 additions & 0 deletions mocks/mock_vm.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

50 changes: 50 additions & 0 deletions node/throttled_vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,53 @@ func (tvm *ThrottledVM) Execute(
return err
})
}

func (tvm *ThrottledVM) runExec(
fn func(inner vm.VM) (vm.ExecutionResults, error),
) (vm.ExecutionResults, error) {
var result vm.ExecutionResults
return result, tvm.Do(func(inner *vm.VM) error {
var err error
result, err = fn(*inner)
return err
})
}

func (tvm *ThrottledVM) Simulate(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
paidFeesOnL1 []*felt.Felt,
blockInfo *vm.BlockInfo,
state core.StateReader,
opts vm.SimulateOptions,
) (vm.ExecutionResults, error) {
return tvm.runExec(func(inner vm.VM) (vm.ExecutionResults, error) {
return inner.Simulate(txns, declaredClasses, paidFeesOnL1, blockInfo, state, opts)
})
}

func (tvm *ThrottledVM) Trace(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
paidFeesOnL1 []*felt.Felt,
blockInfo *vm.BlockInfo,
state core.StateReader,
opts vm.TraceOptions,
) (vm.ExecutionResults, error) {
return tvm.runExec(func(inner vm.VM) (vm.ExecutionResults, error) {
return inner.Trace(txns, declaredClasses, paidFeesOnL1, blockInfo, state, opts)
})
}

func (tvm *ThrottledVM) BuildBlock(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
paidFeesOnL1 []*felt.Felt,
blockInfo *vm.BlockInfo,
state core.StateReader,
opts vm.BuildBlockOptions,
) (vm.ExecutionResults, error) {
return tvm.runExec(func(inner vm.VM) (vm.ExecutionResults, error) {
return inner.BuildBlock(txns, declaredClasses, paidFeesOnL1, blockInfo, state, opts)
})
}
116 changes: 116 additions & 0 deletions vm/vm.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,32 @@ type CallResult struct {
ExecutionFailed bool
}

// SimulateOptions carries the per-request flags relevant to RPC simulate /
// estimateFee. errStack and allowBinarySearch are constants for this path
// and are set internally.
Comment on lines +48 to +50
Copy link
Copy Markdown
Contributor Author

@RafaelGranza RafaelGranza May 1, 2026

Choose a reason for hiding this comment

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

The documentation talking about flags that are constants or pre-defined will be removed after these methods stop depending on Execute

type SimulateOptions struct {
SkipChargeFee bool
SkipValidate bool
ErrOnRevert bool
IsEstimateFee bool
ReturnInitialReads bool
}

// TraceOptions carries the per-request flags relevant to replaying an
// existing block. All execution flags are off; only errStack is on.
type TraceOptions struct {
ReturnInitialReads bool
}
Comment on lines +59 to +63
Copy link
Copy Markdown
Contributor Author

@RafaelGranza RafaelGranza May 1, 2026

Choose a reason for hiding this comment

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

I know it could be a single bollean, but I decided to keep this as a struct, for 2 reasons:

  • it keeps the same signature pattern as the other wrappers
  • if we ever need extra flags, adding a field to this struct is less conflicting than adding and extra argument to a method.


// BuildBlockOptions carries flags used when producing a block (builder or
// genesis bootstrap). errStack is hardcoded true; the trace/estimate flags
// don't apply here.
type BuildBlockOptions struct {
SkipChargeFee bool
SkipValidate bool
ErrOnRevert bool
}

//go:generate mockgen -destination=../mocks/mock_vm.go -package=mocks github.com/NethermindEth/juno/vm VM
type VM interface {
Call(
Expand All @@ -70,6 +96,30 @@ type VM interface {
isEstimateFee bool,
returnInitialReads bool,
) (ExecutionResults, error)
Simulate(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
paidFeesOnL1 []*felt.Felt,
blockInfo *BlockInfo,
state core.StateReader,
opts SimulateOptions,
) (ExecutionResults, error)
Trace(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
paidFeesOnL1 []*felt.Felt,
blockInfo *BlockInfo,
state core.StateReader,
opts TraceOptions,
) (ExecutionResults, error)
BuildBlock(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
paidFeesOnL1 []*felt.Felt,
blockInfo *BlockInfo,
state core.StateReader,
opts BuildBlockOptions,
) (ExecutionResults, error)
}

type vm struct {
Expand Down Expand Up @@ -444,6 +494,72 @@ func (v *vm) Execute(
}, nil
}

// Simulate runs the txn set under RPC simulate / estimateFee semantics:
// errStack and allowBinarySearch are always on.
func (v *vm) Simulate(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
paidFeesOnL1 []*felt.Felt,
blockInfo *BlockInfo,
state core.StateReader,
opts SimulateOptions,
) (ExecutionResults, error) {
return v.Execute(
txns, declaredClasses, paidFeesOnL1, blockInfo, state,
opts.SkipChargeFee,
opts.SkipValidate,
opts.ErrOnRevert,
true, // errStack
true, // allowBinarySearch
opts.IsEstimateFee,
opts.ReturnInitialReads,
)
}

// Trace replays an existing block. All exec flags are off; only errStack
// is on so we get structured error frames if anything goes wrong.
func (v *vm) Trace(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
paidFeesOnL1 []*felt.Felt,
blockInfo *BlockInfo,
state core.StateReader,
opts TraceOptions,
) (ExecutionResults, error) {
return v.Execute(
txns, declaredClasses, paidFeesOnL1, blockInfo, state,
false, // skipChargeFee
false, // skipValidate
false, // errOnRevert
true, // errStack
false, // allowBinarySearch
false, // isEstimateFee
opts.ReturnInitialReads,
)
}

// BuildBlock executes txns in block-production mode (builder or genesis).
// errStack is on; trace/estimate flags don't apply.
func (v *vm) BuildBlock(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
paidFeesOnL1 []*felt.Felt,
blockInfo *BlockInfo,
state core.StateReader,
opts BuildBlockOptions,
) (ExecutionResults, error) {
return v.Execute(
txns, declaredClasses, paidFeesOnL1, blockInfo, state,
opts.SkipChargeFee,
opts.SkipValidate,
opts.ErrOnRevert,
true, // errStack
false, // allowBinarySearch
false, // isEstimateFee
false, // returnInitialReads
)
}

func marshalTxnsAndDeclaredClasses(
txns []core.Transaction,
declaredClasses []core.ClassDefinition,
Expand Down
Loading