github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/transactionSequenceNum.go (about) 1 package fvm 2 3 import ( 4 "fmt" 5 6 "github.com/onflow/flow-go/fvm/environment" 7 "github.com/onflow/flow-go/fvm/errors" 8 "github.com/onflow/flow-go/fvm/storage" 9 "github.com/onflow/flow-go/fvm/tracing" 10 "github.com/onflow/flow-go/model/flow" 11 "github.com/onflow/flow-go/module/trace" 12 ) 13 14 type TransactionSequenceNumberChecker struct{} 15 16 func (c TransactionSequenceNumberChecker) CheckAndIncrementSequenceNumber( 17 tracer tracing.TracerSpan, 18 proc *TransactionProcedure, 19 txnState storage.TransactionPreparer, 20 ) error { 21 // TODO(Janez): verification is part of inclusion fees, not execution fees. 22 var err error 23 txnState.RunWithAllLimitsDisabled(func() { 24 err = c.checkAndIncrementSequenceNumber(tracer, proc, txnState) 25 }) 26 27 if err != nil { 28 return fmt.Errorf("checking sequence number failed: %w", err) 29 } 30 31 return nil 32 } 33 34 func (c TransactionSequenceNumberChecker) checkAndIncrementSequenceNumber( 35 tracer tracing.TracerSpan, 36 proc *TransactionProcedure, 37 txnState storage.TransactionPreparer, 38 ) error { 39 40 defer tracer.StartChildSpan(trace.FVMSeqNumCheckTransaction).End() 41 42 nestedTxnId, err := txnState.BeginNestedTransaction() 43 if err != nil { 44 return err 45 } 46 47 defer func() { 48 _, commitError := txnState.CommitNestedTransaction(nestedTxnId) 49 if commitError != nil { 50 panic(commitError) 51 } 52 }() 53 54 accounts := environment.NewAccounts(txnState) 55 proposalKey := proc.Transaction.ProposalKey 56 57 var accountKey flow.AccountPublicKey 58 59 accountKey, err = accounts.GetPublicKey(proposalKey.Address, proposalKey.KeyIndex) 60 if err != nil { 61 return errors.NewInvalidProposalSignatureError(proposalKey, err) 62 } 63 64 if accountKey.Revoked { 65 return errors.NewInvalidProposalSignatureError( 66 proposalKey, 67 fmt.Errorf("proposal key has been revoked")) 68 } 69 70 // Note that proposal key verification happens at the txVerifier and not here. 71 valid := accountKey.SeqNumber == proposalKey.SequenceNumber 72 73 if !valid { 74 return errors.NewInvalidProposalSeqNumberError(proposalKey, accountKey.SeqNumber) 75 } 76 77 accountKey.SeqNumber++ 78 79 _, err = accounts.SetPublicKey(proposalKey.Address, proposalKey.KeyIndex, accountKey) 80 if err != nil { 81 restartError := txnState.RestartNestedTransaction(nestedTxnId) 82 if restartError != nil { 83 panic(restartError) 84 } 85 return err 86 } 87 88 return nil 89 }