@@ -35,12 +35,7 @@ func CallFunction(env environment, tree *ast.Tree, name string, args proto.Argum
35
35
if err != nil {
36
36
// Evaluation failed we have to return a DAppResult that contains spent execution complexity
37
37
// Produced actions are not stored for failed transactions, no need to return them here
38
- et := GetEvaluationErrorType (err )
39
- complexity := complexityInCaseOfEvaluationError (et , e , env )
40
- if et == Undefined {
41
- return nil , EvaluationErrorAddComplexity (et .Wrap (err , "unhandled error" ), complexity )
42
- }
43
- return nil , EvaluationErrorAddComplexity (err , complexity )
38
+ return nil , handleComplexityInCaseOfEvaluationError (err , e , env )
44
39
}
45
40
dAppResult , ok := rideResult .(DAppResult )
46
41
if ! ok { // Unexpected result type
@@ -88,21 +83,36 @@ func wrappedStateActions(state types.SmartState) []proto.ScriptAction {
88
83
return ws .act
89
84
}
90
85
91
- func complexityInCaseOfEvaluationError (et EvaluationError , e * treeEvaluator , env environment ) int {
86
+ func evaluationErrorSetComplexity (err error , complexity int ) error {
87
+ if ee , ok := err .(evaluationError ); ok {
88
+ ee .spentComplexity = complexity
89
+ return ee
90
+ }
91
+ return err
92
+ }
93
+
94
+ func handleComplexityInCaseOfEvaluationError (err error , e * treeEvaluator , env environment ) error {
92
95
// Error was not handled in wrapped state properly,
93
- // so we need to add both complexity from current evaluation and from internal invokes
94
- complexity := e .complexity () + wrappedStateComplexity (env .state ())
95
- // reproduce scala's node buggy behaviour
96
- if ws , ok := env .state ().(* WrappedState ); ok && env .rideV5Activated () && ! env .rideV6Activated () && et == InternalInvocationError {
97
- // if invoke script tx depth level is 2 or less ==> complexity should be set to 0
98
- // invCount() is calls count of invoke() or reentrantInvoke() functions ==> txDepthLevel = 1 + invCount()
99
- if txDepthLevel := 1 + ws .invCount (); txDepthLevel <= 2 {
100
- complexity = 0
101
- } else {
102
- // if depth level is 3 or greater, then we should sub last two invoke complexities plus
103
- // cost of the last invoke() or reentrantInvoke() function call
104
- complexity -= ws .lastTwoInvokeComplexities .sum () + invokeCallComplexityV5
96
+ // so we need to add complexities from current evaluation, from internal invokes and from internal failed invoke
97
+ totalComplexity := e .complexity () + wrappedStateComplexity (env .state ()) + EvaluationErrorSpentComplexity (err )
98
+ switch et := GetEvaluationErrorType (err ); et {
99
+ case Undefined :
100
+ return evaluationErrorSetComplexity (et .Wrap (err , "unhandled error" ), totalComplexity )
101
+ case InternalInvocationError :
102
+ // reproduce scala's node buggy behaviour
103
+ if ws , ok := env .state ().(* WrappedState ); ok && env .rideV5Activated () && ! env .rideV6Activated () {
104
+ // if invoke script tx depth level is 2 or less ==> complexity should be set to 0
105
+ // invCount() is calls count of invoke() or reentrantInvoke() functions ==> txDepthLevel = 1 + invCount()
106
+ if txDepthLevel := 1 + ws .invCount (); txDepthLevel <= 2 {
107
+ totalComplexity = 0
108
+ } else {
109
+ // if depth level is 3 or greater, then we should sub last two invoke complexities plus
110
+ // cost of the last invoke() or reentrantInvoke() function call
111
+ totalComplexity -= ws .lastTwoInvokeComplexities .sum () + invokeCallComplexityV5
112
+ }
105
113
}
114
+ return evaluationErrorSetComplexity (err , totalComplexity )
115
+ default :
116
+ return evaluationErrorSetComplexity (err , totalComplexity )
106
117
}
107
- return complexity
108
118
}
0 commit comments