@@ -60,8 +60,8 @@ type transactionExecutor struct {
6060
6161 errs * errors.ErrorsCollector
6262
63- nestedTxnId state. NestedTransactionId
64- pausedState * state.ExecutionState
63+ startedTransactionBodyExecution bool
64+ nestedTxnId state.NestedTransactionId
6565
6666 cadenceRuntime * reusableRuntime.ReusableCadenceRuntime
6767 txnBodyExecutor runtime.Executor
@@ -91,13 +91,14 @@ func newTransactionExecutor(
9191 TransactionVerifier : TransactionVerifier {
9292 VerificationConcurrency : 4 ,
9393 },
94- ctx : ctx ,
95- proc : proc ,
96- txnState : txnState ,
97- span : span ,
98- env : env ,
99- errs : errors .NewErrorsCollector (),
100- cadenceRuntime : env .BorrowCadenceRuntime (),
94+ ctx : ctx ,
95+ proc : proc ,
96+ txnState : txnState ,
97+ span : span ,
98+ env : env ,
99+ errs : errors .NewErrorsCollector (),
100+ startedTransactionBodyExecution : false ,
101+ cadenceRuntime : env .BorrowCadenceRuntime (),
101102 }
102103}
103104
@@ -131,22 +132,53 @@ func (executor *transactionExecutor) handleError(
131132}
132133
133134func (executor * transactionExecutor ) Preprocess () error {
135+ return executor .handleError (executor .preprocess (), "preprocess" )
136+ }
137+
138+ func (executor * transactionExecutor ) Execute () error {
139+ return executor .handleError (executor .execute (), "executing" )
140+ }
141+
142+ func (executor * transactionExecutor ) preprocess () error {
143+ if executor .AuthorizationChecksEnabled {
144+ err := executor .CheckAuthorization (
145+ executor .ctx .TracerSpan ,
146+ executor .proc ,
147+ executor .txnState ,
148+ executor .AccountKeyWeightThreshold )
149+ if err != nil {
150+ executor .errs .Collect (err )
151+ return executor .errs .ErrorOrNil ()
152+ }
153+ }
154+
155+ if executor .SequenceNumberCheckAndIncrementEnabled {
156+ err := executor .CheckAndIncrementSequenceNumber (
157+ executor .ctx .TracerSpan ,
158+ executor .proc ,
159+ executor .txnState )
160+ if err != nil {
161+ executor .errs .Collect (err )
162+ return executor .errs .ErrorOrNil ()
163+ }
164+ }
165+
134166 if ! executor .TransactionBodyExecutionEnabled {
135167 return nil
136168 }
137169
138- err := executor .PreprocessTransactionBody ()
139- return executor .handleError (err , "preprocessing" )
140- }
170+ executor .errs .Collect (executor .preprocessTransactionBody ())
171+ if executor .errs .CollectedFailure () {
172+ return executor .errs .ErrorOrNil ()
173+ }
141174
142- func (executor * transactionExecutor ) Execute () error {
143- return executor .handleError (executor .execute (), "executing" )
175+ return nil
144176}
145177
146- // PreprocessTransactionBody preprocess parts of a transaction body that are
178+ // preprocessTransactionBody preprocess parts of a transaction body that are
147179// infrequently modified and are expensive to compute. For now this includes
148180// reading meter parameter overrides and parsing programs.
149- func (executor * transactionExecutor ) PreprocessTransactionBody () error {
181+ func (executor * transactionExecutor ) preprocessTransactionBody () error {
150182 meterParams , err := getBodyMeterParameters (
151183 executor .ctx ,
152184 executor .proc ,
@@ -160,6 +192,7 @@ func (executor *transactionExecutor) PreprocessTransactionBody() error {
160192 if err != nil {
161193 return err
162194 }
195+ executor .startedTransactionBodyExecution = true
163196 executor .nestedTxnId = txnId
164197
165198 executor .txnBodyExecutor = executor .cadenceRuntime .NewTransactionExecutor (
@@ -173,93 +206,23 @@ func (executor *transactionExecutor) PreprocessTransactionBody() error {
173206 // by the transaction body.
174207 err = executor .txnBodyExecutor .Preprocess ()
175208 if err != nil {
176- executor .errs .Collect (
177- fmt .Errorf (
178- "transaction preprocess failed: %w" ,
179- err ))
180-
181- // We shouldn't early exit on non-failure since we need to deduct fees.
182- if executor .errs .CollectedFailure () {
183- return executor .errs .ErrorOrNil ()
184- }
185-
186- // NOTE: We need to restart the nested transaction in order to pause
187- // for fees deduction.
188- err = executor .txnState .RestartNestedTransaction (txnId )
189- if err != nil {
190- return err
191- }
192- }
193-
194- // Pause the transaction body's nested transaction in order to interleave
195- // auth and seq num checks.
196- pausedState , err := executor .txnState .PauseNestedTransaction (txnId )
197- if err != nil {
198- return err
209+ return fmt .Errorf (
210+ "transaction preprocess failed: %w" ,
211+ err )
199212 }
200- executor .pausedState = pausedState
201213
202214 return nil
203215}
204216
205217func (executor * transactionExecutor ) execute () error {
206- if executor .AuthorizationChecksEnabled {
207- err := executor .CheckAuthorization (
208- executor .ctx .TracerSpan ,
209- executor .proc ,
210- executor .txnState ,
211- executor .AccountKeyWeightThreshold )
212- if err != nil {
213- executor .errs .Collect (err )
214- executor .errs .Collect (executor .abortPreprocessed ())
215- return executor .errs .ErrorOrNil ()
216- }
218+ if ! executor .startedTransactionBodyExecution {
219+ return executor .errs .ErrorOrNil ()
217220 }
218221
219- if executor .SequenceNumberCheckAndIncrementEnabled {
220- err := executor .CheckAndIncrementSequenceNumber (
221- executor .ctx .TracerSpan ,
222- executor .proc ,
223- executor .txnState )
224- if err != nil {
225- executor .errs .Collect (err )
226- executor .errs .Collect (executor .abortPreprocessed ())
227- return executor .errs .ErrorOrNil ()
228- }
229- }
230-
231- if executor .TransactionBodyExecutionEnabled {
232- err := executor .ExecuteTransactionBody ()
233- if err != nil {
234- return err
235- }
236- }
237-
238- return nil
239- }
240-
241- func (executor * transactionExecutor ) abortPreprocessed () error {
242- if ! executor .TransactionBodyExecutionEnabled {
243- return nil
244- }
245-
246- executor .txnState .ResumeNestedTransaction (executor .pausedState )
247-
248- // There shouldn't be any update, but drop all updates just in case.
249- err := executor .txnState .RestartNestedTransaction (executor .nestedTxnId )
250- if err != nil {
251- return err
252- }
253-
254- // We need to commit the aborted state unconditionally to include
255- // the touched registers in the execution receipt.
256- _ , err = executor .txnState .CommitNestedTransaction (executor .nestedTxnId )
257- return err
222+ return executor .ExecuteTransactionBody ()
258223}
259224
260225func (executor * transactionExecutor ) ExecuteTransactionBody () error {
261- executor .txnState .ResumeNestedTransaction (executor .pausedState )
262-
263226 var invalidator derived.TransactionInvalidator
264227 if ! executor .errs .CollectedError () {
265228
0 commit comments