github.com/koko1123/flow-go-1@v0.29.6/fvm/environment/derived_data_invalidator.go (about) 1 package environment 2 3 import ( 4 "github.com/onflow/cadence/runtime/common" 5 6 "github.com/koko1123/flow-go-1/fvm/derived" 7 "github.com/koko1123/flow-go-1/fvm/state" 8 ) 9 10 type ContractUpdateKey struct { 11 Address common.Address 12 Name string 13 } 14 15 type ContractUpdate struct { 16 ContractUpdateKey 17 Code []byte 18 } 19 20 type DerivedDataInvalidator struct { 21 ContractUpdateKeys []ContractUpdateKey 22 FrozenAccounts []common.Address 23 24 MeterParamOverridesUpdated bool 25 } 26 27 var _ derived.TransactionInvalidator = DerivedDataInvalidator{} 28 29 func NewDerivedDataInvalidator( 30 contractKeys []ContractUpdateKey, 31 env *facadeEnvironment, 32 ) DerivedDataInvalidator { 33 return DerivedDataInvalidator{ 34 ContractUpdateKeys: contractKeys, 35 FrozenAccounts: env.FrozenAccounts(), 36 MeterParamOverridesUpdated: meterParamOverridesUpdated(env), 37 } 38 } 39 40 func meterParamOverridesUpdated(env *facadeEnvironment) bool { 41 updatedRegisterIds, _ := env.txnState.RegisterUpdates() 42 43 serviceAccount := string(env.chain.ServiceAddress().Bytes()) 44 storageDomain := common.PathDomainStorage.Identifier() 45 for _, registerId := range updatedRegisterIds { 46 // The meter param override values are stored in the service account. 47 if registerId.Owner != serviceAccount { 48 continue 49 } 50 51 // NOTE: This condition is empirically generated by running the 52 // MeterParamOverridesComputer to capture touched registers. 53 // 54 // The paramater settings are stored as regular fields in the service 55 // account. In general, each account's regular fields are stored in 56 // ordered map known only to cadence. Cadence encodes this map into 57 // bytes and split the bytes into slab chunks before storing the slabs 58 // into the ledger. Hence any changes to the stabs indicate changes 59 // the ordered map. 60 // 61 // The meter param overrides use storageDomain as input, so any 62 // changes to it must also invalidate the values. 63 if registerId.Key == storageDomain || 64 state.IsSlabIndex(registerId.Key) { 65 return true 66 } 67 } 68 69 return false 70 } 71 72 func (invalidator DerivedDataInvalidator) ProgramInvalidator() derived.ProgramInvalidator { 73 return ProgramInvalidator{invalidator} 74 } 75 76 func (invalidator DerivedDataInvalidator) MeterParamOverridesInvalidator() derived.MeterParamOverridesInvalidator { 77 return MeterParamOverridesInvalidator{invalidator} 78 } 79 80 type ProgramInvalidator struct { 81 DerivedDataInvalidator 82 } 83 84 func (invalidator ProgramInvalidator) ShouldInvalidateEntries() bool { 85 return invalidator.MeterParamOverridesUpdated || 86 len(invalidator.ContractUpdateKeys) > 0 || 87 len(invalidator.FrozenAccounts) > 0 88 } 89 90 func (invalidator ProgramInvalidator) ShouldInvalidateEntry( 91 location common.AddressLocation, 92 program *derived.Program, 93 state *state.State, 94 ) bool { 95 if invalidator.MeterParamOverridesUpdated { 96 // if meter parameters changed we need to invalidate all programs 97 return true 98 } 99 100 // if an account was (un)frozen we need to invalidate all 101 // programs that depend on any contract on that address. 102 for _, frozenAccount := range invalidator.FrozenAccounts { 103 _, ok := program.Dependencies[frozenAccount] 104 if ok { 105 return true 106 } 107 } 108 109 // invalidate all programs depending on any of the contracts that were updated 110 // A program has itself listed as a dependency, so that this simpler. 111 for _, key := range invalidator.ContractUpdateKeys { 112 _, ok := program.Dependencies[key.Address] 113 if ok { 114 return true 115 } 116 } 117 return false 118 } 119 120 type MeterParamOverridesInvalidator struct { 121 DerivedDataInvalidator 122 } 123 124 func (invalidator MeterParamOverridesInvalidator) ShouldInvalidateEntries() bool { 125 return invalidator.MeterParamOverridesUpdated 126 } 127 128 func (invalidator MeterParamOverridesInvalidator) ShouldInvalidateEntry( 129 _ struct{}, 130 _ derived.MeterParamOverrides, 131 _ *state.State, 132 ) bool { 133 return invalidator.MeterParamOverridesUpdated 134 }