github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/fvm/environment/transaction_info.go (about)

     1  package environment
     2  
     3  import (
     4  	"github.com/onflow/cadence/runtime/common"
     5  
     6  	"github.com/onflow/flow-go/fvm/errors"
     7  	"github.com/onflow/flow-go/fvm/storage/state"
     8  	"github.com/onflow/flow-go/fvm/tracing"
     9  	"github.com/onflow/flow-go/model/flow"
    10  	"github.com/onflow/flow-go/module/trace"
    11  )
    12  
    13  type TransactionInfoParams struct {
    14  	TxIndex uint32
    15  	TxId    flow.Identifier
    16  	TxBody  *flow.TransactionBody
    17  
    18  	TransactionFeesEnabled bool
    19  	LimitAccountStorage    bool
    20  	// RandomSourceHistoryCallAllowed is true if the transaction is allowed to call the `entropy`
    21  	// cadence function to get the entropy of that block.
    22  	RandomSourceHistoryCallAllowed bool
    23  }
    24  
    25  func DefaultTransactionInfoParams() TransactionInfoParams {
    26  	// NOTE: TxIndex, TxId and TxBody are populated by NewTransactionEnv rather
    27  	// than by Context.
    28  	return TransactionInfoParams{
    29  		TransactionFeesEnabled:         false,
    30  		LimitAccountStorage:            false,
    31  		RandomSourceHistoryCallAllowed: false,
    32  	}
    33  }
    34  
    35  // TransactionInfo exposes information associated with the executing
    36  // transaction.
    37  //
    38  // Note that scripts have no associated transaction information, but must expose
    39  // the API in compliance with the runtime environment interface.
    40  type TransactionInfo interface {
    41  	TxIndex() uint32
    42  	TxID() flow.Identifier
    43  
    44  	TransactionFeesEnabled() bool
    45  	LimitAccountStorage() bool
    46  
    47  	IsServiceAccountAuthorizer() bool
    48  
    49  	// Cadence's runtime API.  Note that the script variant will return
    50  	// OperationNotSupportedError.
    51  	GetSigningAccounts() ([]common.Address, error)
    52  }
    53  
    54  type ParseRestrictedTransactionInfo struct {
    55  	txnState state.NestedTransactionPreparer
    56  	impl     TransactionInfo
    57  }
    58  
    59  func NewParseRestrictedTransactionInfo(
    60  	txnState state.NestedTransactionPreparer,
    61  	impl TransactionInfo,
    62  ) TransactionInfo {
    63  	return ParseRestrictedTransactionInfo{
    64  		txnState: txnState,
    65  		impl:     impl,
    66  	}
    67  }
    68  
    69  func (info ParseRestrictedTransactionInfo) TxIndex() uint32 {
    70  	return info.impl.TxIndex()
    71  }
    72  
    73  func (info ParseRestrictedTransactionInfo) TxID() flow.Identifier {
    74  	return info.impl.TxID()
    75  }
    76  
    77  func (info ParseRestrictedTransactionInfo) TransactionFeesEnabled() bool {
    78  	return info.impl.TransactionFeesEnabled()
    79  }
    80  
    81  func (info ParseRestrictedTransactionInfo) LimitAccountStorage() bool {
    82  	return info.impl.LimitAccountStorage()
    83  }
    84  
    85  func (info ParseRestrictedTransactionInfo) IsServiceAccountAuthorizer() bool {
    86  	return info.impl.IsServiceAccountAuthorizer()
    87  }
    88  
    89  func (info ParseRestrictedTransactionInfo) GetSigningAccounts() (
    90  	[]common.Address,
    91  	error,
    92  ) {
    93  	return parseRestrict1Ret(
    94  		info.txnState,
    95  		trace.FVMEnvGetSigningAccounts,
    96  		info.impl.GetSigningAccounts)
    97  }
    98  
    99  var _ TransactionInfo = &transactionInfo{}
   100  
   101  type transactionInfo struct {
   102  	params TransactionInfoParams
   103  
   104  	tracer tracing.TracerSpan
   105  
   106  	runtimeAuthorizers         []common.Address
   107  	isServiceAccountAuthorizer bool
   108  }
   109  
   110  func NewTransactionInfo(
   111  	params TransactionInfoParams,
   112  	tracer tracing.TracerSpan,
   113  	serviceAccount flow.Address,
   114  ) TransactionInfo {
   115  
   116  	isServiceAccountAuthorizer := false
   117  	runtimeAddresses := make(
   118  		[]common.Address,
   119  		0,
   120  		len(params.TxBody.Authorizers))
   121  
   122  	for _, auth := range params.TxBody.Authorizers {
   123  		runtimeAddresses = append(
   124  			runtimeAddresses,
   125  			common.MustBytesToAddress(auth.Bytes()))
   126  		if auth == serviceAccount {
   127  			isServiceAccountAuthorizer = true
   128  		}
   129  	}
   130  
   131  	return &transactionInfo{
   132  		params:                     params,
   133  		tracer:                     tracer,
   134  		runtimeAuthorizers:         runtimeAddresses,
   135  		isServiceAccountAuthorizer: isServiceAccountAuthorizer,
   136  	}
   137  }
   138  
   139  func (info *transactionInfo) TxIndex() uint32 {
   140  	return info.params.TxIndex
   141  }
   142  
   143  func (info *transactionInfo) TxID() flow.Identifier {
   144  	return info.params.TxId
   145  }
   146  
   147  func (info *transactionInfo) TransactionFeesEnabled() bool {
   148  	return info.params.TransactionFeesEnabled
   149  }
   150  
   151  func (info *transactionInfo) LimitAccountStorage() bool {
   152  	return info.params.LimitAccountStorage
   153  }
   154  
   155  func (info *transactionInfo) IsServiceAccountAuthorizer() bool {
   156  	return info.isServiceAccountAuthorizer
   157  }
   158  
   159  func (info *transactionInfo) GetSigningAccounts() ([]common.Address, error) {
   160  	defer info.tracer.StartExtensiveTracingChildSpan(
   161  		trace.FVMEnvGetSigningAccounts).End()
   162  
   163  	return info.runtimeAuthorizers, nil
   164  }
   165  
   166  var _ TransactionInfo = NoTransactionInfo{}
   167  
   168  // Scripts have no associated transaction information.
   169  type NoTransactionInfo struct {
   170  }
   171  
   172  func (NoTransactionInfo) TxIndex() uint32 {
   173  	return 0
   174  }
   175  
   176  func (NoTransactionInfo) TxID() flow.Identifier {
   177  	return flow.ZeroID
   178  }
   179  
   180  func (NoTransactionInfo) TransactionFeesEnabled() bool {
   181  	return false
   182  }
   183  
   184  func (NoTransactionInfo) LimitAccountStorage() bool {
   185  	return false
   186  }
   187  
   188  func (NoTransactionInfo) IsServiceAccountAuthorizer() bool {
   189  	return false
   190  }
   191  
   192  func (NoTransactionInfo) GetSigningAccounts() ([]common.Address, error) {
   193  	return nil, errors.NewOperationNotSupportedError("GetSigningAccounts")
   194  }