github.com/onflow/flow-go@v0.35.7-crescendo-preview.23-atree-inlining/utils/unittest/generator/events.go (about) 1 package generator 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/onflow/cadence" 8 "github.com/onflow/cadence/encoding/ccf" 9 jsoncdc "github.com/onflow/cadence/encoding/json" 10 "github.com/onflow/cadence/runtime/common" 11 "github.com/onflow/cadence/runtime/stdlib" 12 "github.com/onflow/flow/protobuf/go/flow/entities" 13 "github.com/stretchr/testify/require" 14 15 "github.com/onflow/flow-go/fvm/evm/testutils" 16 "github.com/onflow/flow-go/model/flow" 17 "github.com/onflow/flow-go/utils/unittest" 18 ) 19 20 type EventGeneratorOption func(*Events) 21 22 func WithEncoding(encoding entities.EventEncodingVersion) EventGeneratorOption { 23 return func(g *Events) { 24 g.encoding = encoding 25 } 26 } 27 28 type Events struct { 29 count uint32 30 ids *Identifiers 31 encoding entities.EventEncodingVersion 32 } 33 34 func EventGenerator(opts ...EventGeneratorOption) *Events { 35 g := &Events{ 36 count: 1, 37 ids: IdentifierGenerator(), 38 encoding: entities.EventEncodingVersion_CCF_V0, 39 } 40 41 for _, opt := range opts { 42 opt(g) 43 } 44 45 return g 46 } 47 48 func (g *Events) New() flow.Event { 49 address, err := common.BytesToAddress(unittest.RandomAddressFixture().Bytes()) 50 if err != nil { 51 panic(fmt.Sprintf("unexpected error while creating random address: %s", err)) 52 } 53 54 location := common.NewAddressLocation(nil, address, "TestContract") 55 identifier := fmt.Sprintf("TestContract.FooEvent%d", g.count) 56 typeID := location.TypeID(nil, identifier) 57 58 testEventType := &cadence.EventType{ 59 Location: location, 60 QualifiedIdentifier: identifier, 61 Fields: []cadence.Field{ 62 { 63 Identifier: "a", 64 Type: cadence.IntType, 65 }, 66 { 67 Identifier: "b", 68 Type: cadence.StringType, 69 }, 70 }, 71 } 72 73 fooString, err := cadence.NewString("foo") 74 if err != nil { 75 panic(fmt.Sprintf("unexpected error while creating cadence string: %s", err)) 76 } 77 78 testEvent := cadence.NewEvent( 79 []cadence.Value{ 80 cadence.NewInt(int(g.count)), 81 fooString, 82 }).WithType(testEventType) 83 84 var payload []byte 85 switch g.encoding { 86 case entities.EventEncodingVersion_CCF_V0: 87 payload, err = ccf.Encode(testEvent) 88 if err != nil { 89 panic(fmt.Sprintf("unexpected error while ccf encoding events: %s", err)) 90 } 91 case entities.EventEncodingVersion_JSON_CDC_V0: 92 payload, err = jsoncdc.Encode(testEvent) 93 if err != nil { 94 panic(fmt.Sprintf("unexpected error while json encoding events: %s", err)) 95 } 96 } 97 98 event := flow.Event{ 99 Type: flow.EventType(typeID), 100 TransactionID: g.ids.New(), 101 TransactionIndex: g.count, 102 EventIndex: g.count, 103 Payload: payload, 104 } 105 106 g.count++ 107 108 return event 109 } 110 111 // GetEventsWithEncoding generates a specified number of events with a given encoding version. 112 func GetEventsWithEncoding(n int, version entities.EventEncodingVersion) []flow.Event { 113 eventGenerator := EventGenerator(WithEncoding(version)) 114 events := make([]flow.Event, 0, n) 115 for i := 0; i < n; i++ { 116 events = append(events, eventGenerator.New()) 117 } 118 return events 119 } 120 121 // GenerateAccountCreateEvent returns a mock account creation event. 122 func GenerateAccountCreateEvent(t *testing.T, address flow.Address) flow.Event { 123 cadenceEvent := cadence.NewEvent( 124 []cadence.Value{ 125 cadence.NewAddress(address), 126 }).WithType(&cadence.EventType{ 127 Location: stdlib.FlowLocation{}, 128 QualifiedIdentifier: "AccountCreated", 129 Fields: []cadence.Field{ 130 { 131 Identifier: "address", 132 Type: cadence.AddressType, 133 }, 134 }, 135 }) 136 137 payload, err := ccf.Encode(cadenceEvent) 138 require.NoError(t, err) 139 140 event := unittest.EventFixture( 141 flow.EventType(cadenceEvent.EventType.Location.TypeID(nil, cadenceEvent.EventType.QualifiedIdentifier)), 142 0, 143 0, 144 unittest.IdentifierFixture(), 145 0, 146 ) 147 148 event.Payload = payload 149 150 return event 151 } 152 153 // GenerateAccountContractEvent returns a mock account contract event. 154 func GenerateAccountContractEvent(t *testing.T, qualifiedIdentifier string, address flow.Address) flow.Event { 155 contractName, err := cadence.NewString("EventContract") 156 require.NoError(t, err) 157 158 cadenceEvent := cadence.NewEvent( 159 []cadence.Value{ 160 cadence.NewAddress(address), 161 cadence.NewArray( 162 testutils.ConvertToCadence([]byte{111, 43, 164, 202, 220, 174, 148, 17, 253, 161, 9, 124, 237, 83, 227, 75, 115, 149, 141, 83, 129, 145, 252, 68, 122, 137, 80, 155, 89, 233, 136, 213}), 163 ).WithType(cadence.NewConstantSizedArrayType(32, cadence.UInt8Type)), 164 contractName, 165 }).WithType(&cadence.EventType{ 166 Location: stdlib.FlowLocation{}, 167 QualifiedIdentifier: qualifiedIdentifier, 168 Fields: []cadence.Field{ 169 { 170 Identifier: "address", 171 Type: cadence.AddressType, 172 }, 173 { 174 Identifier: "codeHash", 175 Type: cadence.NewConstantSizedArrayType(32, cadence.UInt8Type), 176 }, 177 { 178 Identifier: "contract", 179 Type: cadence.StringType, 180 }, 181 }, 182 }) 183 184 payload, err := ccf.Encode(cadenceEvent) 185 require.NoError(t, err) 186 187 event := unittest.EventFixture( 188 flow.EventType(cadenceEvent.EventType.Location.TypeID(nil, cadenceEvent.EventType.QualifiedIdentifier)), 189 0, 190 0, 191 unittest.IdentifierFixture(), 192 0, 193 ) 194 195 event.Payload = payload 196 197 return event 198 }