github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/module/state_synchronization/indexer/util.go (about) 1 package indexer 2 3 import ( 4 "fmt" 5 6 "github.com/onflow/cadence" 7 "github.com/onflow/cadence/encoding/ccf" 8 "github.com/onflow/cadence/runtime/common" 9 "github.com/onflow/cadence/runtime/stdlib" 10 11 "github.com/onflow/flow-go/fvm/storage/derived" 12 "github.com/onflow/flow-go/fvm/storage/snapshot" 13 "github.com/onflow/flow-go/model/flow" 14 ) 15 16 var ( 17 accountContractUpdated = flow.EventType(stdlib.AccountContractUpdatedEventType.ID()) 18 ) 19 20 // hasAuthorizedTransaction checks if the provided account was an authorizer in any of the transactions 21 // within the provided collections. 22 func hasAuthorizedTransaction(collections []*flow.Collection, address flow.Address) bool { 23 for _, collection := range collections { 24 for _, tx := range collection.Transactions { 25 for _, authorizer := range tx.Authorizers { 26 if authorizer == address { 27 return true 28 } 29 } 30 } 31 } 32 33 return false 34 } 35 36 // findContractUpdates returns a map of common.AddressLocation for all contracts updated within the 37 // provided events. 38 // No errors are expected during normal operation and indicate an invalid protocol event was encountered 39 func findContractUpdates(events []flow.Event) (map[common.Location]struct{}, error) { 40 invalidatedPrograms := make(map[common.Location]struct{}) 41 for _, event := range events { 42 if event.Type == accountContractUpdated { 43 location, err := parseAccountContractUpdated(&event) 44 if err != nil { 45 return nil, fmt.Errorf("could not parse account contract updated event: %w", err) 46 } 47 invalidatedPrograms[location] = struct{}{} 48 } 49 } 50 return invalidatedPrograms, nil 51 } 52 53 // parseAccountContractUpdated parses an account contract updated event and returns the address location. 54 // No errors are expected during normal operation and indicate an invalid protocol event was encountered 55 func parseAccountContractUpdated(event *flow.Event) (common.AddressLocation, error) { 56 payload, err := ccf.Decode(nil, event.Payload) 57 if err != nil { 58 return common.AddressLocation{}, fmt.Errorf("could not unmarshal event payload: %w", err) 59 } 60 61 cdcEvent, ok := payload.(cadence.Event) 62 if !ok { 63 return common.AddressLocation{}, fmt.Errorf("invalid event payload type: %T", payload) 64 } 65 66 fields := cadence.FieldsMappedByName(cdcEvent) 67 68 addressField := fields[stdlib.AccountEventAddressParameter.Identifier] 69 address, ok := addressField.(cadence.Address) 70 if !ok { 71 return common.AddressLocation{}, fmt.Errorf("invalid Cadence type for address field: %T", addressField) 72 } 73 74 contractNameField := fields[stdlib.AccountEventContractParameter.Identifier] 75 contractName, ok := contractNameField.(cadence.String) 76 if !ok { 77 return common.AddressLocation{}, fmt.Errorf( 78 "invalid Cadence type for contract name field: %T", 79 contractNameField, 80 ) 81 } 82 83 return common.NewAddressLocation( 84 nil, 85 common.Address(address), 86 string(contractName), 87 ), nil 88 } 89 90 var _ derived.TransactionInvalidator = (*accessInvalidator)(nil) 91 92 // accessInvalidator is a derived.TransactionInvalidator that invalidates programs and meter param overrides. 93 type accessInvalidator struct { 94 programs *programInvalidator 95 meterParamOverrides *meterParamOverridesInvalidator 96 } 97 98 func (inv *accessInvalidator) ProgramInvalidator() derived.ProgramInvalidator { 99 return inv.programs 100 } 101 102 func (inv *accessInvalidator) MeterParamOverridesInvalidator() derived.MeterParamOverridesInvalidator { 103 return inv.meterParamOverrides 104 } 105 106 var _ derived.ProgramInvalidator = (*programInvalidator)(nil) 107 108 // programInvalidator is a derived.ProgramInvalidator that invalidates all programs or a specific set of programs. 109 // this is used to invalidate all programs who's code was updated in a specific block. 110 type programInvalidator struct { 111 invalidateAll bool 112 invalidated map[common.Location]struct{} 113 } 114 115 func (inv *programInvalidator) ShouldInvalidateEntries() bool { 116 return inv.invalidateAll 117 } 118 119 func (inv *programInvalidator) ShouldInvalidateEntry(location common.AddressLocation, _ *derived.Program, _ *snapshot.ExecutionSnapshot) bool { 120 _, ok := inv.invalidated[location] 121 return inv.invalidateAll || ok 122 } 123 124 var _ derived.MeterParamOverridesInvalidator = (*meterParamOverridesInvalidator)(nil) 125 126 // meterParamOverridesInvalidator is a derived.MeterParamOverridesInvalidator that invalidates meter param overrides. 127 type meterParamOverridesInvalidator struct { 128 invalidateAll bool 129 } 130 131 func (inv *meterParamOverridesInvalidator) ShouldInvalidateEntries() bool { 132 return inv.invalidateAll 133 } 134 135 func (inv *meterParamOverridesInvalidator) ShouldInvalidateEntry(_ struct{}, _ derived.MeterParamOverrides, _ *snapshot.ExecutionSnapshot) bool { 136 return inv.invalidateAll 137 }