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 }