@@ -68,8 +68,8 @@ type transactionExecutor struct {
6868
6969 errs * errors.ErrorsCollector
7070
71- nestedTxnId state. NestedTransactionId
72- pausedState * state.ExecutionState
71+ startedTransactionBodyExecution bool
72+ nestedTxnId state.NestedTransactionId
7373
7474 cadenceRuntime * reusableRuntime.ReusableCadenceRuntime
7575 txnBodyExecutor runtime.Executor
@@ -99,13 +99,14 @@ func newTransactionExecutor(
9999 TransactionVerifier : TransactionVerifier {
100100 VerificationConcurrency : 4 ,
101101 },
102- ctx : ctx ,
103- proc : proc ,
104- txnState : txnState ,
105- span : span ,
106- env : env ,
107- errs : errors .NewErrorsCollector (),
108- cadenceRuntime : env .BorrowCadenceRuntime (),
102+ ctx : ctx ,
103+ proc : proc ,
104+ txnState : txnState ,
105+ span : span ,
106+ env : env ,
107+ errs : errors .NewErrorsCollector (),
108+ startedTransactionBodyExecution : false ,
109+ cadenceRuntime : env .BorrowCadenceRuntime (),
109110 }
110111}
111112
@@ -139,22 +140,53 @@ func (executor *transactionExecutor) handleError(
139140}
140141
141142func (executor * transactionExecutor ) Preprocess () error {
143+ return executor .handleError (executor .preprocess (), "preprocess" )
144+ }
145+
146+ func (executor * transactionExecutor ) Execute () error {
147+ return executor .handleError (executor .execute (), "executing" )
148+ }
149+
150+ func (executor * transactionExecutor ) preprocess () error {
151+ if executor .AuthorizationChecksEnabled {
152+ err := executor .CheckAuthorization (
153+ executor .ctx .TracerSpan ,
154+ executor .proc ,
155+ executor .txnState ,
156+ executor .AccountKeyWeightThreshold )
157+ if err != nil {
158+ executor .errs .Collect (err )
159+ return executor .errs .ErrorOrNil ()
160+ }
161+ }
162+
163+ if executor .SequenceNumberCheckAndIncrementEnabled {
164+ err := executor .CheckAndIncrementSequenceNumber (
165+ executor .ctx .TracerSpan ,
166+ executor .proc ,
167+ executor .txnState )
168+ if err != nil {
169+ executor .errs .Collect (err )
170+ return executor .errs .ErrorOrNil ()
171+ }
172+ }
173+
142174 if ! executor .TransactionBodyExecutionEnabled {
143175 return nil
144176 }
145177
146- err := executor .PreprocessTransactionBody ()
147- return executor .handleError (err , "preprocessing" )
148- }
178+ executor .errs .Collect (executor .preprocessTransactionBody ())
179+ if executor .errs .CollectedFailure () {
180+ return executor .errs .ErrorOrNil ()
181+ }
149182
150- func (executor * transactionExecutor ) Execute () error {
151- return executor .handleError (executor .execute (), "executing" )
183+ return nil
152184}
153185
154- // PreprocessTransactionBody preprocess parts of a transaction body that are
186+ // preprocessTransactionBody preprocess parts of a transaction body that are
155187// infrequently modified and are expensive to compute. For now this includes
156188// reading meter parameter overrides and parsing programs.
157- func (executor * transactionExecutor ) PreprocessTransactionBody () error {
189+ func (executor * transactionExecutor ) preprocessTransactionBody () error {
158190 meterParams , err := getBodyMeterParameters (
159191 executor .ctx ,
160192 executor .proc ,
@@ -168,6 +200,7 @@ func (executor *transactionExecutor) PreprocessTransactionBody() error {
168200 if err != nil {
169201 return err
170202 }
203+ executor .startedTransactionBodyExecution = true
171204 executor .nestedTxnId = txnId
172205
173206 executor .txnBodyExecutor = executor .cadenceRuntime .NewTransactionExecutor (
@@ -181,93 +214,23 @@ func (executor *transactionExecutor) PreprocessTransactionBody() error {
181214 // by the transaction body.
182215 err = executor .txnBodyExecutor .Preprocess ()
183216 if err != nil {
184- executor .errs .Collect (
185- fmt .Errorf (
186- "transaction preprocess failed: %w" ,
187- err ))
188-
189- // We shouldn't early exit on non-failure since we need to deduct fees.
190- if executor .errs .CollectedFailure () {
191- return executor .errs .ErrorOrNil ()
192- }
193-
194- // NOTE: We need to restart the nested transaction in order to pause
195- // for fees deduction.
196- err = executor .txnState .RestartNestedTransaction (txnId )
197- if err != nil {
198- return err
199- }
200- }
201-
202- // Pause the transaction body's nested transaction in order to interleave
203- // auth and seq num checks.
204- pausedState , err := executor .txnState .PauseNestedTransaction (txnId )
205- if err != nil {
206- return err
217+ return fmt .Errorf (
218+ "transaction preprocess failed: %w" ,
219+ err )
207220 }
208- executor .pausedState = pausedState
209221
210222 return nil
211223}
212224
213225func (executor * transactionExecutor ) execute () error {
214- if executor .AuthorizationChecksEnabled {
215- err := executor .CheckAuthorization (
216- executor .ctx .TracerSpan ,
217- executor .proc ,
218- executor .txnState ,
219- executor .AccountKeyWeightThreshold )
220- if err != nil {
221- executor .errs .Collect (err )
222- executor .errs .Collect (executor .abortPreprocessed ())
223- return executor .errs .ErrorOrNil ()
224- }
226+ if ! executor .startedTransactionBodyExecution {
227+ return executor .errs .ErrorOrNil ()
225228 }
226229
227- if executor .SequenceNumberCheckAndIncrementEnabled {
228- err := executor .CheckAndIncrementSequenceNumber (
229- executor .ctx .TracerSpan ,
230- executor .proc ,
231- executor .txnState )
232- if err != nil {
233- executor .errs .Collect (err )
234- executor .errs .Collect (executor .abortPreprocessed ())
235- return executor .errs .ErrorOrNil ()
236- }
237- }
238-
239- if executor .TransactionBodyExecutionEnabled {
240- err := executor .ExecuteTransactionBody ()
241- if err != nil {
242- return err
243- }
244- }
245-
246- return nil
247- }
248-
249- func (executor * transactionExecutor ) abortPreprocessed () error {
250- if ! executor .TransactionBodyExecutionEnabled {
251- return nil
252- }
253-
254- executor .txnState .ResumeNestedTransaction (executor .pausedState )
255-
256- // There shouldn't be any update, but drop all updates just in case.
257- err := executor .txnState .RestartNestedTransaction (executor .nestedTxnId )
258- if err != nil {
259- return err
260- }
261-
262- // We need to commit the aborted state unconditionally to include
263- // the touched registers in the execution receipt.
264- _ , err = executor .txnState .CommitNestedTransaction (executor .nestedTxnId )
265- return err
230+ return executor .ExecuteTransactionBody ()
266231}
267232
268233func (executor * transactionExecutor ) ExecuteTransactionBody () error {
269- executor .txnState .ResumeNestedTransaction (executor .pausedState )
270-
271234 var invalidator derived.TransactionInvalidator
272235 if ! executor .errs .CollectedError () {
273236
0 commit comments