github.com/koko1123/flow-go-1@v0.29.6/fvm/transactionSequenceNum.go (about)

     1  package fvm
     2  
     3  import (
     4  	"fmt"
     5  
     6  	"github.com/koko1123/flow-go-1/fvm/environment"
     7  	"github.com/koko1123/flow-go-1/fvm/errors"
     8  	"github.com/koko1123/flow-go-1/fvm/state"
     9  	"github.com/koko1123/flow-go-1/fvm/tracing"
    10  	"github.com/koko1123/flow-go-1/model/flow"
    11  	"github.com/koko1123/flow-go-1/module/trace"
    12  )
    13  
    14  type TransactionSequenceNumberChecker struct{}
    15  
    16  func (c TransactionSequenceNumberChecker) CheckAndIncrementSequenceNumber(
    17  	tracer tracing.TracerSpan,
    18  	proc *TransactionProcedure,
    19  	txnState *state.TransactionState,
    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 *state.TransactionState,
    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.Commit(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  }