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

     1  package environment
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/onflow/cadence/runtime/common"
     7  	"github.com/onflow/cadence/runtime/interpreter"
     8  
     9  	"github.com/onflow/flow-go/fvm/storage"
    10  	"github.com/onflow/flow-go/fvm/storage/snapshot"
    11  	"github.com/onflow/flow-go/fvm/storage/state"
    12  	"github.com/onflow/flow-go/fvm/tracing"
    13  )
    14  
    15  var _ Environment = &facadeEnvironment{}
    16  
    17  // facadeEnvironment exposes various fvm business logic as a single interface.
    18  type facadeEnvironment struct {
    19  	*Runtime
    20  
    21  	tracing.TracerSpan
    22  	Meter
    23  
    24  	*ProgramLogger
    25  	EventEmitter
    26  
    27  	RandomGenerator
    28  	CryptoLibrary
    29  	RandomSourceHistoryProvider
    30  
    31  	BlockInfo
    32  	AccountInfo
    33  	TransactionInfo
    34  
    35  	ValueStore
    36  
    37  	*SystemContracts
    38  
    39  	UUIDGenerator
    40  	AccountLocalIDGenerator
    41  
    42  	AccountCreator
    43  
    44  	AccountKeyReader
    45  	AccountKeyUpdater
    46  
    47  	*ContractReader
    48  	ContractUpdater
    49  	*Programs
    50  
    51  	accounts Accounts
    52  	txnState storage.TransactionPreparer
    53  }
    54  
    55  func newFacadeEnvironment(
    56  	tracer tracing.TracerSpan,
    57  	params EnvironmentParams,
    58  	txnState storage.TransactionPreparer,
    59  	meter Meter,
    60  ) *facadeEnvironment {
    61  	accounts := NewAccounts(txnState)
    62  	logger := NewProgramLogger(tracer, params.ProgramLoggerParams)
    63  	runtime := NewRuntime(params.RuntimeParams)
    64  	systemContracts := NewSystemContracts(
    65  		params.Chain,
    66  		tracer,
    67  		logger,
    68  		runtime)
    69  
    70  	env := &facadeEnvironment{
    71  		Runtime: runtime,
    72  
    73  		TracerSpan: tracer,
    74  		Meter:      meter,
    75  
    76  		ProgramLogger: logger,
    77  		EventEmitter:  NoEventEmitter{},
    78  
    79  		CryptoLibrary:               NewCryptoLibrary(tracer, meter),
    80  		RandomSourceHistoryProvider: NewForbiddenRandomSourceHistoryProvider(),
    81  
    82  		BlockInfo: NewBlockInfo(
    83  			tracer,
    84  			meter,
    85  			params.BlockHeader,
    86  			params.Blocks,
    87  		),
    88  		AccountInfo: NewAccountInfo(
    89  			tracer,
    90  			meter,
    91  			accounts,
    92  			systemContracts,
    93  			params.ServiceAccountEnabled,
    94  		),
    95  		TransactionInfo: NoTransactionInfo{},
    96  
    97  		ValueStore: NewValueStore(
    98  			tracer,
    99  			meter,
   100  			accounts,
   101  		),
   102  
   103  		SystemContracts: systemContracts,
   104  
   105  		UUIDGenerator: NewUUIDGenerator(
   106  			tracer,
   107  			params.Logger,
   108  			meter,
   109  			txnState,
   110  			params.BlockHeader,
   111  			params.TxIndex),
   112  		AccountLocalIDGenerator: NewAccountLocalIDGenerator(
   113  			tracer,
   114  			meter,
   115  			accounts,
   116  		),
   117  
   118  		AccountCreator: NoAccountCreator{},
   119  
   120  		AccountKeyReader: NewAccountKeyReader(
   121  			tracer,
   122  			meter,
   123  			accounts,
   124  		),
   125  		AccountKeyUpdater: NoAccountKeyUpdater{},
   126  
   127  		ContractReader: NewContractReader(
   128  			tracer,
   129  			meter,
   130  			accounts,
   131  		),
   132  		ContractUpdater: NoContractUpdater{},
   133  		Programs: NewPrograms(
   134  			tracer,
   135  			meter,
   136  			params.MetricsReporter,
   137  			txnState,
   138  			accounts),
   139  
   140  		accounts: accounts,
   141  		txnState: txnState,
   142  	}
   143  
   144  	env.Runtime.SetEnvironment(env)
   145  
   146  	return env
   147  }
   148  
   149  // This is mainly used by command line tools, the emulator, and cadence tools
   150  // testing.
   151  func NewScriptEnvironmentFromStorageSnapshot(
   152  	params EnvironmentParams,
   153  	storageSnapshot snapshot.StorageSnapshot,
   154  ) *facadeEnvironment {
   155  	blockDatabase := storage.NewBlockDatabase(storageSnapshot, 0, nil)
   156  
   157  	return NewScriptEnv(
   158  		context.Background(),
   159  		tracing.NewTracerSpan(),
   160  		params,
   161  		blockDatabase.NewSnapshotReadTransaction(state.DefaultParameters()))
   162  }
   163  
   164  func NewScriptEnv(
   165  	ctx context.Context,
   166  	tracer tracing.TracerSpan,
   167  	params EnvironmentParams,
   168  	txnState storage.TransactionPreparer,
   169  ) *facadeEnvironment {
   170  	env := newFacadeEnvironment(
   171  		tracer,
   172  		params,
   173  		txnState,
   174  		NewCancellableMeter(ctx, txnState))
   175  	env.RandomGenerator = NewRandomGenerator(
   176  		tracer,
   177  		params.EntropyProvider,
   178  		params.ScriptInfoParams.ID[:],
   179  	)
   180  	env.addParseRestrictedChecks()
   181  	return env
   182  }
   183  
   184  func NewTransactionEnvironment(
   185  	tracer tracing.TracerSpan,
   186  	params EnvironmentParams,
   187  	txnState storage.TransactionPreparer,
   188  ) *facadeEnvironment {
   189  	env := newFacadeEnvironment(
   190  		tracer,
   191  		params,
   192  		txnState,
   193  		NewMeter(txnState),
   194  	)
   195  
   196  	env.TransactionInfo = NewTransactionInfo(
   197  		params.TransactionInfoParams,
   198  		tracer,
   199  		params.Chain.ServiceAddress(),
   200  	)
   201  	env.EventEmitter = NewEventEmitter(
   202  		tracer,
   203  		env.Meter,
   204  		params.Chain,
   205  		params.TransactionInfoParams,
   206  		params.EventEmitterParams,
   207  	)
   208  	env.AccountCreator = NewAccountCreator(
   209  		txnState,
   210  		params.Chain,
   211  		env.accounts,
   212  		params.ServiceAccountEnabled,
   213  		tracer,
   214  		env.Meter,
   215  		params.MetricsReporter,
   216  		env.SystemContracts)
   217  	env.ContractUpdater = NewContractUpdater(
   218  		tracer,
   219  		env.Meter,
   220  		env.accounts,
   221  		params.TransactionInfoParams.TxBody.Authorizers,
   222  		params.Chain,
   223  		params.ContractUpdaterParams,
   224  		env.ProgramLogger,
   225  		env.SystemContracts,
   226  		env.Runtime)
   227  
   228  	env.AccountKeyUpdater = NewAccountKeyUpdater(
   229  		tracer,
   230  		env.Meter,
   231  		env.accounts,
   232  		txnState,
   233  		env)
   234  
   235  	env.RandomGenerator = NewRandomGenerator(
   236  		tracer,
   237  		params.EntropyProvider,
   238  		params.TxId[:],
   239  	)
   240  
   241  	env.RandomSourceHistoryProvider = NewRandomSourceHistoryProvider(
   242  		tracer,
   243  		env.Meter,
   244  		params.EntropyProvider,
   245  		params.TransactionInfoParams.RandomSourceHistoryCallAllowed,
   246  	)
   247  
   248  	env.addParseRestrictedChecks()
   249  
   250  	return env
   251  }
   252  
   253  func (env *facadeEnvironment) addParseRestrictedChecks() {
   254  	// NOTE: Cadence can access Programs, ContractReader, Meter and
   255  	// ProgramLogger while it is parsing programs; all other access are
   256  	// unexpected and are potentially program cache invalidation bugs.
   257  	//
   258  	// Also note that Tracer and SystemContracts are unguarded since these are
   259  	// not accessible by Cadence.
   260  
   261  	env.AccountCreator = NewParseRestrictedAccountCreator(
   262  		env.txnState,
   263  		env.AccountCreator)
   264  	env.AccountInfo = NewParseRestrictedAccountInfo(
   265  		env.txnState,
   266  		env.AccountInfo)
   267  	env.AccountKeyReader = NewParseRestrictedAccountKeyReader(
   268  		env.txnState,
   269  		env.AccountKeyReader)
   270  	env.AccountKeyUpdater = NewParseRestrictedAccountKeyUpdater(
   271  		env.txnState,
   272  		env.AccountKeyUpdater)
   273  	env.BlockInfo = NewParseRestrictedBlockInfo(
   274  		env.txnState,
   275  		env.BlockInfo)
   276  	env.ContractUpdater = NewParseRestrictedContractUpdater(
   277  		env.txnState,
   278  		env.ContractUpdater)
   279  	env.CryptoLibrary = NewParseRestrictedCryptoLibrary(
   280  		env.txnState,
   281  		env.CryptoLibrary)
   282  	env.EventEmitter = NewParseRestrictedEventEmitter(
   283  		env.txnState,
   284  		env.EventEmitter)
   285  	env.TransactionInfo = NewParseRestrictedTransactionInfo(
   286  		env.txnState,
   287  		env.TransactionInfo)
   288  	env.RandomGenerator = NewParseRestrictedRandomGenerator(
   289  		env.txnState,
   290  		env.RandomGenerator)
   291  	env.RandomSourceHistoryProvider = NewParseRestrictedRandomSourceHistoryProvider(
   292  		env.txnState,
   293  		env.RandomSourceHistoryProvider)
   294  	env.UUIDGenerator = NewParseRestrictedUUIDGenerator(
   295  		env.txnState,
   296  		env.UUIDGenerator)
   297  	env.AccountLocalIDGenerator = NewParseRestrictedAccountLocalIDGenerator(
   298  		env.txnState,
   299  		env.AccountLocalIDGenerator)
   300  	env.ValueStore = NewParseRestrictedValueStore(
   301  		env.txnState,
   302  		env.ValueStore)
   303  }
   304  
   305  func (env *facadeEnvironment) FlushPendingUpdates() (
   306  	ContractUpdates,
   307  	error,
   308  ) {
   309  	return env.ContractUpdater.Commit()
   310  }
   311  
   312  func (env *facadeEnvironment) Reset() {
   313  	env.ContractUpdater.Reset()
   314  	env.EventEmitter.Reset()
   315  	env.Programs.Reset()
   316  }
   317  
   318  // Miscellaneous cadence runtime.Interface API.
   319  func (facadeEnvironment) ResourceOwnerChanged(
   320  	*interpreter.Interpreter,
   321  	*interpreter.CompositeValue,
   322  	common.Address,
   323  	common.Address,
   324  ) {
   325  }
   326  
   327  func (env *facadeEnvironment) SetInterpreterSharedState(state *interpreter.SharedState) {
   328  	// NO-OP
   329  }
   330  
   331  func (env *facadeEnvironment) GetInterpreterSharedState() *interpreter.SharedState {
   332  	return nil
   333  }